diff options
author | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-11-01 00:07:38 +0000 |
---|---|---|
committer | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-11-01 00:07:38 +0000 |
commit | b92c47c1cc25bafd75d81f121e06b68b35d0beed (patch) | |
tree | a30c60d4769e2ca4185ead842b98157705d9ec39 /linux-user/syscall.c | |
parent | fc0d441e14f07a35f9ea67ac8ca032a2ea902b38 (diff) |
Strace for userland emulation, by Stuart Anderson and Thayne Harbaugh.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3502 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r-- | linux-user/syscall.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6d1997e09a..07e84d9632 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -251,11 +251,18 @@ extern int setresgid(gid_t, gid_t, gid_t); extern int getresgid(gid_t *, gid_t *, gid_t *); extern int setgroups(int, gid_t *); +#define ERRNO_TABLE_SIZE 1200 + +/* target_to_host_errno_table[] is initialized from + * host_to_target_errno_table[] in syscall_init(). */ +static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = { +}; + /* * This list is the union of errno values overridden in asm-<arch>/errno.h * minus the errnos that are not actually generic to all archs. */ -static uint16_t host_to_target_errno_table[1200] = { +static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = { [EIDRM] = TARGET_EIDRM, [ECHRNG] = TARGET_ECHRNG, [EL2NSYNC] = TARGET_EL2NSYNC, @@ -361,7 +368,7 @@ static uint16_t host_to_target_errno_table[1200] = { #ifdef ENOTRECOVERABLE [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE, #endif - }; +}; static inline int host_to_target_errno(int err) { @@ -370,6 +377,13 @@ static inline int host_to_target_errno(int err) return err; } +static inline int target_to_host_errno(int err) +{ + if (target_to_host_errno_table[err]) + return target_to_host_errno_table[err]; + return err; +} + static inline abi_long get_errno(abi_long ret) { if (ret == -1) @@ -383,6 +397,11 @@ static inline int is_error(abi_long ret) return (abi_ulong)ret >= (abi_ulong)(-4096); } +char *target_strerror(int err) +{ + return strerror(target_to_host_errno(err)); +} + static abi_ulong target_brk; static abi_ulong target_original_brk; @@ -2465,6 +2484,7 @@ void syscall_init(void) IOCTLEntry *ie; const argtype *arg_type; int size; + int i; #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); @@ -2490,6 +2510,12 @@ void syscall_init(void) ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) | (size << TARGET_IOC_SIZESHIFT); } + + /* Build target_to_host_errno_table[] table from + * host_to_target_errno_table[]. */ + for (i=0; i < ERRNO_TABLE_SIZE; i++) + target_to_host_errno_table[host_to_target_errno_table[i]] = i; + /* automatic consistency check if same arch */ #if defined(__i386__) && defined(TARGET_I386) if (ie->target_cmd != ie->host_cmd) { @@ -2588,6 +2614,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef DEBUG gemu_log("syscall %d", num); #endif + if(do_strace) + print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); + switch(num) { case TARGET_NR_exit: #ifdef HAVE_GPROF @@ -5025,5 +5054,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef DEBUG gemu_log(" = %ld\n", ret); #endif + if(do_strace) + print_syscall_ret(num, ret); return ret; } |