Commit b92c47c1cc25bafd75d81f121e06b68b35d0beed
1 parent
fc0d441e
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
Showing
4 changed files
with
46 additions
and
3 deletions
Makefile.target
| ... | ... | @@ -259,7 +259,7 @@ main.o: BASE_CFLAGS+=-p |
| 259 | 259 | endif |
| 260 | 260 | |
| 261 | 261 | ifdef CONFIG_LINUX_USER |
| 262 | -OBJS= main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o \ | |
| 262 | +OBJS= main.o syscall.o strace.o mmap.o signal.o path.o osdep.o thunk.o \ | |
| 263 | 263 | elfload.o linuxload.o |
| 264 | 264 | LIBS+= $(AIOLIBS) |
| 265 | 265 | ifdef TARGET_HAS_BFLT | ... | ... |
linux-user/main.c
linux-user/qemu.h
| ... | ... | @@ -153,10 +153,18 @@ extern CPUState *global_env; |
| 153 | 153 | void cpu_loop(CPUState *env); |
| 154 | 154 | void init_paths(const char *prefix); |
| 155 | 155 | const char *path(const char *pathname); |
| 156 | +char *target_strerror(int err); | |
| 156 | 157 | |
| 157 | 158 | extern int loglevel; |
| 158 | 159 | extern FILE *logfile; |
| 159 | 160 | |
| 161 | +/* strace.c */ | |
| 162 | +void print_syscall(int num, | |
| 163 | + target_long arg1, target_long arg2, target_long arg3, | |
| 164 | + target_long arg4, target_long arg5, target_long arg6); | |
| 165 | +void print_syscall_ret(int num, target_long arg1); | |
| 166 | +extern int do_strace; | |
| 167 | + | |
| 160 | 168 | /* signal.c */ |
| 161 | 169 | void process_pending_signals(void *cpu_env); |
| 162 | 170 | void signal_init(void); | ... | ... |
linux-user/syscall.c
| ... | ... | @@ -251,11 +251,18 @@ extern int setresgid(gid_t, gid_t, gid_t); |
| 251 | 251 | extern int getresgid(gid_t *, gid_t *, gid_t *); |
| 252 | 252 | extern int setgroups(int, gid_t *); |
| 253 | 253 | |
| 254 | +#define ERRNO_TABLE_SIZE 1200 | |
| 255 | + | |
| 256 | +/* target_to_host_errno_table[] is initialized from | |
| 257 | + * host_to_target_errno_table[] in syscall_init(). */ | |
| 258 | +static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = { | |
| 259 | +}; | |
| 260 | + | |
| 254 | 261 | /* |
| 255 | 262 | * This list is the union of errno values overridden in asm-<arch>/errno.h |
| 256 | 263 | * minus the errnos that are not actually generic to all archs. |
| 257 | 264 | */ |
| 258 | -static uint16_t host_to_target_errno_table[1200] = { | |
| 265 | +static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = { | |
| 259 | 266 | [EIDRM] = TARGET_EIDRM, |
| 260 | 267 | [ECHRNG] = TARGET_ECHRNG, |
| 261 | 268 | [EL2NSYNC] = TARGET_EL2NSYNC, |
| ... | ... | @@ -361,7 +368,7 @@ static uint16_t host_to_target_errno_table[1200] = { |
| 361 | 368 | #ifdef ENOTRECOVERABLE |
| 362 | 369 | [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE, |
| 363 | 370 | #endif |
| 364 | - }; | |
| 371 | +}; | |
| 365 | 372 | |
| 366 | 373 | static inline int host_to_target_errno(int err) |
| 367 | 374 | { |
| ... | ... | @@ -370,6 +377,13 @@ static inline int host_to_target_errno(int err) |
| 370 | 377 | return err; |
| 371 | 378 | } |
| 372 | 379 | |
| 380 | +static inline int target_to_host_errno(int err) | |
| 381 | +{ | |
| 382 | + if (target_to_host_errno_table[err]) | |
| 383 | + return target_to_host_errno_table[err]; | |
| 384 | + return err; | |
| 385 | +} | |
| 386 | + | |
| 373 | 387 | static inline abi_long get_errno(abi_long ret) |
| 374 | 388 | { |
| 375 | 389 | if (ret == -1) |
| ... | ... | @@ -383,6 +397,11 @@ static inline int is_error(abi_long ret) |
| 383 | 397 | return (abi_ulong)ret >= (abi_ulong)(-4096); |
| 384 | 398 | } |
| 385 | 399 | |
| 400 | +char *target_strerror(int err) | |
| 401 | +{ | |
| 402 | + return strerror(target_to_host_errno(err)); | |
| 403 | +} | |
| 404 | + | |
| 386 | 405 | static abi_ulong target_brk; |
| 387 | 406 | static abi_ulong target_original_brk; |
| 388 | 407 | |
| ... | ... | @@ -2465,6 +2484,7 @@ void syscall_init(void) |
| 2465 | 2484 | IOCTLEntry *ie; |
| 2466 | 2485 | const argtype *arg_type; |
| 2467 | 2486 | int size; |
| 2487 | + int i; | |
| 2468 | 2488 | |
| 2469 | 2489 | #define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); |
| 2470 | 2490 | #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); |
| ... | ... | @@ -2490,6 +2510,12 @@ void syscall_init(void) |
| 2490 | 2510 | ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) | |
| 2491 | 2511 | (size << TARGET_IOC_SIZESHIFT); |
| 2492 | 2512 | } |
| 2513 | + | |
| 2514 | + /* Build target_to_host_errno_table[] table from | |
| 2515 | + * host_to_target_errno_table[]. */ | |
| 2516 | + for (i=0; i < ERRNO_TABLE_SIZE; i++) | |
| 2517 | + target_to_host_errno_table[host_to_target_errno_table[i]] = i; | |
| 2518 | + | |
| 2493 | 2519 | /* automatic consistency check if same arch */ |
| 2494 | 2520 | #if defined(__i386__) && defined(TARGET_I386) |
| 2495 | 2521 | if (ie->target_cmd != ie->host_cmd) { |
| ... | ... | @@ -2588,6 +2614,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 2588 | 2614 | #ifdef DEBUG |
| 2589 | 2615 | gemu_log("syscall %d", num); |
| 2590 | 2616 | #endif |
| 2617 | + if(do_strace) | |
| 2618 | + print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); | |
| 2619 | + | |
| 2591 | 2620 | switch(num) { |
| 2592 | 2621 | case TARGET_NR_exit: |
| 2593 | 2622 | #ifdef HAVE_GPROF |
| ... | ... | @@ -5025,5 +5054,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 5025 | 5054 | #ifdef DEBUG |
| 5026 | 5055 | gemu_log(" = %ld\n", ret); |
| 5027 | 5056 | #endif |
| 5057 | + if(do_strace) | |
| 5058 | + print_syscall_ret(num, ret); | |
| 5028 | 5059 | return ret; |
| 5029 | 5060 | } | ... | ... |