Commit 0899965f authored by Aurelien Jarno's avatar Aurelien Jarno
Browse files

Merge branch 'linux-user-for-upstream' of git://gitorious.org/qemu-maemo/qemu

* 'linux-user-for-upstream' of git://gitorious.org/qemu-maemo/qemu:
  linux-user: correct core dump format
  linux-user: Define target alignment size
  linux-user: Support the epoll syscalls
  linux-user: in linux-user/strace.c, tswap() is useless
  linux-user: add rmdir() strace
parents 64d7e9a4 80f5ce75
......@@ -2142,6 +2142,51 @@ if compile_prog "" "" ; then
dup3=yes
fi
# check for epoll support
epoll=no
cat > $TMPC << EOF
#include <sys/epoll.h>
int main(void)
{
epoll_create(0);
return 0;
}
EOF
if compile_prog "$ARCH_CFLAGS" "" ; then
epoll=yes
fi
# epoll_create1 and epoll_pwait are later additions
# so we must check separately for their presence
epoll_create1=no
cat > $TMPC << EOF
#include <sys/epoll.h>
int main(void)
{
epoll_create1(0);
return 0;
}
EOF
if compile_prog "$ARCH_CFLAGS" "" ; then
epoll_create1=yes
fi
epoll_pwait=no
cat > $TMPC << EOF
#include <sys/epoll.h>
int main(void)
{
epoll_pwait(0, 0, 0, 0, 0);
return 0;
}
EOF
if compile_prog "$ARCH_CFLAGS" "" ; then
epoll_pwait=yes
fi
# Check if tools are available to build documentation.
if test "$docs" != "no" ; then
if has makeinfo && has pod2man; then
......@@ -2674,6 +2719,15 @@ fi
if test "$dup3" = "yes" ; then
echo "CONFIG_DUP3=y" >> $config_host_mak
fi
if test "$epoll" = "yes" ; then
echo "CONFIG_EPOLL=y" >> $config_host_mak
fi
if test "$epoll_create1" = "yes" ; then
echo "CONFIG_EPOLL_CREATE1=y" >> $config_host_mak
fi
if test "$epoll_pwait" = "yes" ; then
echo "CONFIG_EPOLL_PWAIT=y" >> $config_host_mak
fi
if test "$inotify" = "yes" ; then
echo "CONFIG_INOTIFY=y" >> $config_host_mak
fi
......@@ -2908,6 +2962,10 @@ target_nptl="no"
interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_arch2/g"`
echo "CONFIG_QEMU_INTERP_PREFIX=\"$interp_prefix1\"" >> $config_target_mak
gdb_xml_files=""
target_short_alignment=2
target_int_alignment=4
target_long_alignment=4
target_llong_alignment=8
TARGET_ARCH="$target_arch2"
TARGET_BASE_ARCH=""
......@@ -2920,9 +2978,11 @@ case "$target_arch2" in
x86_64)
TARGET_BASE_ARCH=i386
target_phys_bits=64
target_long_alignment=8
;;
alpha)
target_phys_bits=64
target_long_alignment=8
target_nptl="yes"
;;
arm|armeb)
......@@ -2931,6 +2991,7 @@ case "$target_arch2" in
target_nptl="yes"
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
target_phys_bits=32
target_llong_alignment=4
;;
cris)
target_nptl="yes"
......@@ -2940,6 +3001,9 @@ case "$target_arch2" in
bflt="yes"
gdb_xml_files="cf-core.xml cf-fp.xml"
target_phys_bits=32
target_int_alignment=2
target_long_alignment=2
target_llong_alignment=2
;;
microblaze)
bflt="yes"
......@@ -2963,6 +3027,7 @@ case "$target_arch2" in
TARGET_BASE_ARCH=mips
echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
target_phys_bits=64
target_long_alignment=8
;;
ppc)
gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
......@@ -2981,6 +3046,7 @@ case "$target_arch2" in
TARGET_ABI_DIR=ppc
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
target_phys_bits=64
target_long_alignment=8
;;
ppc64abi32)
TARGET_ARCH=ppc64
......@@ -3002,6 +3068,7 @@ case "$target_arch2" in
sparc64)
TARGET_BASE_ARCH=sparc
target_phys_bits=64
target_long_alignment=8
;;
sparc32plus)
TARGET_ARCH=sparc64
......@@ -3018,6 +3085,10 @@ case "$target_arch2" in
exit 1
;;
esac
echo "TARGET_SHORT_ALIGNMENT=$target_short_alignment" >> $config_target_mak
echo "TARGET_INT_ALIGNMENT=$target_int_alignment" >> $config_target_mak
echo "TARGET_LONG_ALIGNMENT=$target_long_alignment" >> $config_target_mak
echo "TARGET_LLONG_ALIGNMENT=$target_llong_alignment" >> $config_target_mak
echo "TARGET_ARCH=$TARGET_ARCH" >> $config_target_mak
target_arch_name="`echo $TARGET_ARCH | tr '[:lower:]' '[:upper:]'`"
echo "TARGET_$target_arch_name=y" >> $config_target_mak
......
......@@ -37,16 +37,22 @@
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
typedef int16_t target_short __attribute__ ((aligned(TARGET_SHORT_ALIGNMENT)));
typedef uint16_t target_ushort __attribute__((aligned(TARGET_SHORT_ALIGNMENT)));
typedef int32_t target_int __attribute__((aligned(TARGET_INT_ALIGNMENT)));
typedef uint32_t target_uint __attribute__((aligned(TARGET_INT_ALIGNMENT)));
typedef int64_t target_llong __attribute__((aligned(TARGET_LLONG_ALIGNMENT)));
typedef uint64_t target_ullong __attribute__((aligned(TARGET_LLONG_ALIGNMENT)));
/* target_ulong is the type of a virtual address */
#if TARGET_LONG_SIZE == 4
typedef int32_t target_long;
typedef uint32_t target_ulong;
typedef int32_t target_long __attribute__((aligned(TARGET_LONG_ALIGNMENT)));
typedef uint32_t target_ulong __attribute__((aligned(TARGET_LONG_ALIGNMENT)));
#define TARGET_FMT_lx "%08x"
#define TARGET_FMT_ld "%d"
#define TARGET_FMT_lu "%u"
#elif TARGET_LONG_SIZE == 8
typedef int64_t target_long;
typedef uint64_t target_ulong;
typedef int64_t target_long __attribute__((aligned(TARGET_LONG_ALIGNMENT)));
typedef uint64_t target_ulong __attribute__((aligned(TARGET_LONG_ALIGNMENT)));
#define TARGET_FMT_lx "%016" PRIx64
#define TARGET_FMT_ld "%" PRId64
#define TARGET_FMT_lu "%" PRIu64
......
......@@ -103,13 +103,13 @@ enum {
typedef target_ulong target_elf_greg_t;
#ifdef USE_UID16
typedef uint16_t target_uid_t;
typedef uint16_t target_gid_t;
typedef target_ushort target_uid_t;
typedef target_ushort target_gid_t;
#else
typedef uint32_t target_uid_t;
typedef uint32_t target_gid_t;
typedef target_uint target_uid_t;
typedef target_uint target_gid_t;
#endif
typedef int32_t target_pid_t;
typedef target_int target_pid_t;
#ifdef TARGET_I386
......@@ -1761,19 +1761,20 @@ struct memelfnote {
size_t namesz_rounded;
int type;
size_t datasz;
size_t datasz_rounded;
void *data;
size_t notesz;
};
struct target_elf_siginfo {
int si_signo; /* signal number */
int si_code; /* extra code */
int si_errno; /* errno */
target_int si_signo; /* signal number */
target_int si_code; /* extra code */
target_int si_errno; /* errno */
};
struct target_elf_prstatus {
struct target_elf_siginfo pr_info; /* Info associated with signal */
short pr_cursig; /* Current signal */
target_short pr_cursig; /* Current signal */
target_ulong pr_sigpend; /* XXX */
target_ulong pr_sighold; /* XXX */
target_pid_t pr_pid;
......@@ -1785,7 +1786,7 @@ struct target_elf_prstatus {
struct target_timeval pr_cutime; /* XXX Cumulative user time */
struct target_timeval pr_cstime; /* XXX Cumulative system time */
target_elf_gregset_t pr_reg; /* GP registers */
int pr_fpvalid; /* XXX */
target_int pr_fpvalid; /* XXX */
};
#define ELF_PRARGSZ (80) /* Number of chars for args */
......@@ -2036,7 +2037,9 @@ static void fill_note(struct memelfnote *note, const char *name, int type,
note->namesz = namesz;
note->namesz_rounded = roundup(namesz, sizeof (int32_t));
note->type = type;
note->datasz = roundup(sz, sizeof (int32_t));;
note->datasz = sz;
note->datasz_rounded = roundup(sz, sizeof (int32_t));
note->data = data;
/*
......@@ -2044,7 +2047,7 @@ static void fill_note(struct memelfnote *note, const char *name, int type,
* ELF document.
*/
note->notesz = sizeof (struct elf_note) +
note->namesz_rounded + note->datasz;
note->namesz_rounded + note->datasz_rounded;
}
static void fill_elf_header(struct elfhdr *elf, int segs, uint16_t machine,
......@@ -2264,7 +2267,7 @@ static int write_note(struct memelfnote *men, int fd)
return (-1);
if (dump_write(fd, men->name, men->namesz_rounded) != 0)
return (-1);
if (dump_write(fd, men->data, men->datasz) != 0)
if (dump_write(fd, men->data, men->datasz_rounded) != 0)
return (-1);
return (0);
......@@ -2480,7 +2483,7 @@ static int elf_core_dump(int signr, const CPUState *env)
* ELF specification wants data to start at page boundary so
* we align it here.
*/
offset = roundup(offset, ELF_EXEC_PAGESIZE);
data_offset = offset = roundup(offset, ELF_EXEC_PAGESIZE);
/*
* Write program headers for memory regions mapped in
......@@ -2503,6 +2506,7 @@ static int elf_core_dump(int signr, const CPUState *env)
phdr.p_flags |= PF_X;
phdr.p_align = ELF_EXEC_PAGESIZE;
bswap_phdr(&phdr, 1);
dump_write(fd, &phdr, sizeof (phdr));
}
......@@ -2514,8 +2518,6 @@ static int elf_core_dump(int signr, const CPUState *env)
goto out;
/* align data to page boundary */
data_offset = lseek(fd, 0, SEEK_CUR);
data_offset = TARGET_PAGE_ALIGN(data_offset);
if (lseek(fd, data_offset, SEEK_SET) != data_offset)
goto out;
......
......@@ -441,14 +441,11 @@ get_comma(int last)
}
static void
print_flags(const struct flags *f, abi_long tflags, int last)
print_flags(const struct flags *f, abi_long flags, int last)
{
const char *sep = "";
int flags;
int n;
flags = (int)tswap32(tflags);
if ((flags == 0) && (f->f_value == 0)) {
gemu_log("%s%s", f->f_string, get_comma(last));
return;
......@@ -465,36 +462,33 @@ print_flags(const struct flags *f, abi_long tflags, int last)
if (n > 0) {
/* print rest of the flags as numeric */
if (flags != 0) {
gemu_log("%s%#x%s", sep, flags, get_comma(last));
gemu_log("%s%#x%s", sep, (unsigned int)flags, get_comma(last));
} else {
gemu_log("%s", get_comma(last));
}
} else {
/* no string version of flags found, print them in hex then */
gemu_log("%#x%s", flags, get_comma(last));
gemu_log("%#x%s", (unsigned int)flags, get_comma(last));
}
}
static void
print_at_dirfd(abi_long tdirfd, int last)
print_at_dirfd(abi_long dirfd, int last)
{
int dirfd = tswap32(tdirfd);
#ifdef AT_FDCWD
if (dirfd == AT_FDCWD) {
gemu_log("AT_FDCWD%s", get_comma(last));
return;
}
#endif
gemu_log("%d%s", dirfd, get_comma(last));
gemu_log("%d%s", (int)dirfd, get_comma(last));
}
static void
print_file_mode(abi_long tmode, int last)
print_file_mode(abi_long mode, int last)
{
const char *sep = "";
const struct flags *m;
mode_t mode = (mode_t)tswap32(tmode);
for (m = &mode_flags[0]; m->f_string != NULL; m++) {
if ((m->f_value & mode) == m->f_value) {
......@@ -508,16 +502,14 @@ print_file_mode(abi_long tmode, int last)
mode &= ~S_IFMT;
/* print rest of the mode as octal */
if (mode != 0)
gemu_log("%s%#o", sep, mode);
gemu_log("%s%#o", sep, (unsigned int)mode);
gemu_log("%s", get_comma(last));
}
static void
print_open_flags(abi_long tflags, int last)
print_open_flags(abi_long flags, int last)
{
int flags = tswap32(tflags);
print_flags(open_access_flags, flags & TARGET_O_ACCMODE, 1);
flags &= ~TARGET_O_ACCMODE;
if (flags == 0) {
......@@ -620,7 +612,7 @@ print_accept(const struct syscallname *name,
abi_long arg3, abi_long arg4, abi_long arg5)
{
print_syscall_prologue(name);
print_raw_param("%d", tswap32(arg0), 0);
print_raw_param("%d", arg0, 0);
print_pointer(arg1, 0);
print_number(arg2, 1);
print_syscall_epilogue(name);
......@@ -698,7 +690,7 @@ print_execv(const struct syscallname *name,
{
print_syscall_prologue(name);
print_string(arg0, 0);
print_raw_param("0x" TARGET_ABI_FMT_lx, tswapl(arg1), 1);
print_raw_param("0x" TARGET_ABI_FMT_lx, arg1, 1);
print_syscall_epilogue(name);
}
#endif
......@@ -742,13 +734,8 @@ print_fchownat(const struct syscallname *name,
print_syscall_prologue(name);
print_at_dirfd(arg0, 0);
print_string(arg1, 0);
#ifdef USE_UID16
print_raw_param("%d", tswap16(arg2), 0);
print_raw_param("%d", tswap16(arg3), 0);
#else
print_raw_param("%d", tswap32(arg2), 0);
print_raw_param("%d", tswap32(arg3), 0);
#endif
print_raw_param("%d", arg2, 0);
print_raw_param("%d", arg3, 0);
print_flags(at_file_flags, arg4, 1);
print_syscall_epilogue(name);
}
......@@ -761,7 +748,7 @@ print_fcntl(const struct syscallname *name,
abi_long arg3, abi_long arg4, abi_long arg5)
{
print_syscall_prologue(name);
print_raw_param("%d", tswap32(arg0), 0);
print_raw_param("%d", arg0, 0);
print_flags(fcntl_flags, arg1, 0);
/*
* TODO: check flags and print following argument only
......@@ -842,7 +829,7 @@ print_fstat(const struct syscallname *name,
abi_long arg3, abi_long arg4, abi_long arg5)
{
print_syscall_prologue(name);
print_raw_param("%d", tswap32(arg0), 0);
print_raw_param("%d", arg0, 0);
print_pointer(arg1, 1);
print_syscall_epilogue(name);
}
......@@ -876,20 +863,32 @@ print_mkdirat(const struct syscallname *name,
}
#endif
#ifdef TARGET_NR_rmdir
static void
print_rmdir(const struct syscallname *name,
abi_long arg0, abi_long arg1, abi_long arg2,
abi_long arg3, abi_long arg4, abi_long arg5)
{
print_syscall_prologue(name);
print_string(arg0, 0);
print_syscall_epilogue(name);
}
#endif
#ifdef TARGET_NR_mknod
static void
print_mknod(const struct syscallname *name,
abi_long arg0, abi_long arg1, abi_long arg2,
abi_long arg3, abi_long arg4, abi_long arg5)
{
int hasdev = (tswapl(arg1) & (S_IFCHR|S_IFBLK));
int hasdev = (arg1 & (S_IFCHR|S_IFBLK));
print_syscall_prologue(name);
print_string(arg0, 0);
print_file_mode(arg1, (hasdev == 0));
if (hasdev) {
print_raw_param("makedev(%d", major(tswapl(arg2)), 0);
print_raw_param("%d)", minor(tswapl(arg2)), 1);
print_raw_param("makedev(%d", major(arg2), 0);
print_raw_param("%d)", minor(arg2), 1);
}
print_syscall_epilogue(name);
}
......@@ -901,15 +900,15 @@ print_mknodat(const struct syscallname *name,
abi_long arg0, abi_long arg1, abi_long arg2,
abi_long arg3, abi_long arg4, abi_long arg5)
{
int hasdev = (tswapl(arg2) & (S_IFCHR|S_IFBLK));
int hasdev = (arg2 & (S_IFCHR|S_IFBLK));
print_syscall_prologue(name);
print_at_dirfd(arg0, 0);
print_string(arg1, 0);
print_file_mode(arg2, (hasdev == 0));
if (hasdev) {
print_raw_param("makedev(%d", major(tswapl(arg3)), 0);
print_raw_param("%d)", minor(tswapl(arg3)), 1);
print_raw_param("makedev(%d", major(arg3), 0);
print_raw_param("%d)", minor(arg3), 1);
}
print_syscall_epilogue(name);
}
......@@ -921,7 +920,7 @@ print_mq_open(const struct syscallname *name,
abi_long arg0, abi_long arg1, abi_long arg2,
abi_long arg3, abi_long arg4, abi_long arg5)
{
int is_creat = (tswapl(arg1) & TARGET_O_CREAT);
int is_creat = (arg1 & TARGET_O_CREAT);
print_syscall_prologue(name);
print_string(arg0, 0);
......@@ -940,7 +939,7 @@ print_open(const struct syscallname *name,
abi_long arg0, abi_long arg1, abi_long arg2,
abi_long arg3, abi_long arg4, abi_long arg5)
{
int is_creat = (tswap32(arg1) & TARGET_O_CREAT);
int is_creat = (arg1 & TARGET_O_CREAT);
print_syscall_prologue(name);
print_string(arg0, 0);
......@@ -957,7 +956,7 @@ print_openat(const struct syscallname *name,
abi_long arg0, abi_long arg1, abi_long arg2,
abi_long arg3, abi_long arg4, abi_long arg5)
{
int is_creat = (tswap32(arg2) & TARGET_O_CREAT);
int is_creat = (arg2 & TARGET_O_CREAT);
print_syscall_prologue(name);
print_at_dirfd(arg0, 0);
......@@ -1006,7 +1005,7 @@ print_readlink(const struct syscallname *name,
print_syscall_prologue(name);
print_string(arg0, 0);
print_pointer(arg1, 0);
print_raw_param("%u", tswapl(arg2), 1);
print_raw_param("%u", arg2, 1);
print_syscall_epilogue(name);
}
#endif
......@@ -1021,7 +1020,7 @@ print_readlinkat(const struct syscallname *name,
print_at_dirfd(arg0, 0);
print_string(arg1, 0);
print_pointer(arg2, 0);
print_raw_param("%u", tswapl(arg3), 1);
print_raw_param("%u", arg3, 1);
print_syscall_epilogue(name);
}
#endif
......@@ -1211,11 +1210,11 @@ print_mmap(const struct syscallname *name,
{
print_syscall_prologue(name);
print_pointer(arg0, 0);
print_raw_param("%d", tswapl(arg1), 0);
print_raw_param("%d", arg1, 0);
print_flags(mmap_prot_flags, arg2, 0);
print_flags(mmap_flags, arg3, 0);
print_raw_param("%d", tswapl(arg4), 0);
print_raw_param("%#x", tswapl(arg5), 1);
print_raw_param("%d", arg4, 0);
print_raw_param("%#x", arg5, 1);
print_syscall_epilogue(name);
}
#define print_mmap2 print_mmap
......@@ -1229,7 +1228,7 @@ print_mprotect(const struct syscallname *name,
{
print_syscall_prologue(name);
print_pointer(arg0, 0);
print_raw_param("%d", tswapl(arg1), 0);
print_raw_param("%d", arg1, 0);
print_flags(mmap_prot_flags, arg2, 1);
print_syscall_epilogue(name);
}
......@@ -1243,7 +1242,7 @@ print_munmap(const struct syscallname *name,
{
print_syscall_prologue(name);
print_pointer(arg0, 0);
print_raw_param("%d", tswapl(arg1), 1);
print_raw_param("%d", arg1, 1);
print_syscall_epilogue(name);
}
#endif
......@@ -1257,7 +1256,7 @@ if( cmd == val ) { \
return; \
}
int cmd = (int)tswap32(tflag);
int cmd = (int)tflag;
#ifdef FUTEX_PRIVATE_FLAG
if (cmd & FUTEX_PRIVATE_FLAG) {
gemu_log("FUTEX_PRIVATE_FLAG|");
......@@ -1291,10 +1290,10 @@ print_futex(const struct syscallname *name,
print_syscall_prologue(name);
print_pointer(arg0, 0);
print_futex_op(arg1, 0);
print_raw_param(",%d", tswapl(arg2), 0);
print_raw_param(",%d", arg2, 0);
print_pointer(arg3, 0); /* struct timespec */
print_pointer(arg4, 0);
print_raw_param("%d", tswapl(arg4), 1);
print_raw_param("%d", arg4, 1);
print_syscall_epilogue(name);
}
#endif
......
......@@ -495,6 +495,9 @@
#ifdef TARGET_NR_mkdirat
{ TARGET_NR_mkdirat, "mkdirat" , NULL, print_mkdirat, NULL },
#endif
#ifdef TARGET_NR_rmdir
{ TARGET_NR_rmdir, "rmdir" , NULL, print_rmdir, NULL },
#endif
#ifdef TARGET_NR_mknod
{ TARGET_NR_mknod, "mknod" , NULL, print_mknod, NULL },
#endif
......
......@@ -66,6 +66,9 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#ifdef CONFIG_EVENTFD
#include <sys/eventfd.h>
#endif
#ifdef CONFIG_EPOLL
#include <sys/epoll.h>
#endif
#define termios host_termios
#define winsize host_winsize
......@@ -7611,6 +7614,110 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#endif
break;
#endif
#endif
#if defined(CONFIG_EPOLL)
#if defined(TARGET_NR_epoll_create)
case TARGET_NR_epoll_create:
ret = get_errno(epoll_create(arg1));
break;
#endif
#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
case TARGET_NR_epoll_create1:
ret = get_errno(epoll_create1(arg1));
break;
#endif
#if defined(TARGET_NR_epoll_ctl)
case TARGET_NR_epoll_ctl:
{
struct epoll_event ep;
struct epoll_event *epp = 0;
if (arg4) {
struct target_epoll_event *target_ep;
if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
goto efault;
}
ep.events = tswap32(target_ep->events);
/* The epoll_data_t union is just opaque data to the kernel,
* so we transfer all 64 bits across and need not worry what
* actual data type it is.
*/
ep.data.u64 = tswap64(target_ep->data.u64);
unlock_user_struct(target_ep, arg4, 0);
epp = &ep;
}
ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
break;
}
#endif
#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
#define IMPLEMENT_EPOLL_PWAIT
#endif
#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
#if defined(TARGET_NR_epoll_wait)
case TARGET_NR_epoll_wait:
#endif
#if defined(IMPLEMENT_EPOLL_PWAIT)
case TARGET_NR_epoll_pwait:
#endif
{
struct target_epoll_event *target_ep;
struct epoll_event *ep;
int epfd = arg1;
int maxevents = arg3;
int timeout = arg4;
target_ep = lock_user(VERIFY_WRITE, arg2,
maxevents * sizeof(struct target_epoll_event), 1);
if (!target_ep) {
goto efault;
}
ep = alloca(maxevents * sizeof(struct epoll_event));
switch (num) {