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
This commit is contained in:
		@@ -259,7 +259,7 @@ main.o: BASE_CFLAGS+=-p
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifdef CONFIG_LINUX_USER
 | 
			
		||||
OBJS= main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o \
 | 
			
		||||
OBJS= main.o syscall.o strace.o mmap.o signal.o path.o osdep.o thunk.o \
 | 
			
		||||
      elfload.o linuxload.o
 | 
			
		||||
LIBS+= $(AIOLIBS)
 | 
			
		||||
ifdef TARGET_HAS_BFLT
 | 
			
		||||
 
 | 
			
		||||
@@ -1980,6 +1980,10 @@ int main(int argc, char **argv)
 | 
			
		||||
    env = cpu_init();
 | 
			
		||||
    global_env = env;
 | 
			
		||||
 | 
			
		||||
    if(getenv("QEMU_STRACE") ){
 | 
			
		||||
      do_strace=1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    wrk = environ;
 | 
			
		||||
    while (*(wrk++))
 | 
			
		||||
        environ_count++;
 | 
			
		||||
 
 | 
			
		||||
@@ -153,10 +153,18 @@ extern CPUState *global_env;
 | 
			
		||||
void cpu_loop(CPUState *env);
 | 
			
		||||
void init_paths(const char *prefix);
 | 
			
		||||
const char *path(const char *pathname);
 | 
			
		||||
char *target_strerror(int err);
 | 
			
		||||
 | 
			
		||||
extern int loglevel;
 | 
			
		||||
extern FILE *logfile;
 | 
			
		||||
 | 
			
		||||
/* strace.c */
 | 
			
		||||
void print_syscall(int num,
 | 
			
		||||
                   target_long arg1, target_long arg2, target_long arg3,
 | 
			
		||||
                   target_long arg4, target_long arg5, target_long arg6);
 | 
			
		||||
void print_syscall_ret(int num, target_long arg1);
 | 
			
		||||
extern int do_strace;
 | 
			
		||||
 | 
			
		||||
/* signal.c */
 | 
			
		||||
void process_pending_signals(void *cpu_env);
 | 
			
		||||
void signal_init(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user