From 1d91e63a1f83add3d4c317795888387dc313312b Mon Sep 17 00:00:00 2001 From: Stacey Son Date: Sun, 26 May 2013 09:53:52 -0500 Subject: [PATCH 05/23] bsd-user: add bsd_binprm to TaskState for core dumping emulation To: Cc: Add the bsd_binprm (formerly linux_binprm) structure to TaskState so it can be used to support core dumping emulation support in the future. Also, make freebsd the default bsd_type, if compiled on a FreeBSD system. Signed-off-by: Stacey Son --- bsd-user/bsdload.c | 36 ++++++++++++++++++------------------ bsd-user/elfload.c | 6 +++--- bsd-user/main.c | 19 ++++++++++++++++++- bsd-user/qemu.h | 22 +++++++++++++--------- bsd-user/signal.c | 6 ------ 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c index 637a217..cc4f534 100644 --- a/bsd-user/bsdload.c +++ b/bsd-user/bsdload.c @@ -68,7 +68,7 @@ static int count(char ** vec) return(i); } -static int prepare_binprm(struct linux_binprm *bprm) +static int prepare_binprm(struct bsd_binprm *bprm) { struct stat st; int mode; @@ -170,33 +170,33 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, } int loader_exec(const char * filename, char ** argv, char ** envp, - struct target_pt_regs * regs, struct image_info *infop) + struct target_pt_regs *regs, struct image_info *infop, + struct bsd_binprm *bprm) { - struct linux_binprm bprm; int retval; int i; - bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); + bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); for (i=0 ; ipage[i] = NULL; retval = open(filename, O_RDONLY); if (retval < 0) return retval; - bprm.fd = retval; - bprm.filename = (char *)filename; - bprm.argc = count(argv); - bprm.argv = argv; - bprm.envc = count(envp); - bprm.envp = envp; + bprm->fd = retval; + bprm->filename = (char *)filename; + bprm->argc = count(argv); + bprm->argv = argv; + bprm->envc = count(envp); + bprm->envp = envp; - retval = prepare_binprm(&bprm); + retval = prepare_binprm(bprm); if(retval>=0) { - if (bprm.buf[0] == 0x7f - && bprm.buf[1] == 'E' - && bprm.buf[2] == 'L' - && bprm.buf[3] == 'F') { - retval = load_elf_binary(&bprm,regs,infop); + if (bprm->buf[0] == 0x7f + && bprm->buf[1] == 'E' + && bprm->buf[2] == 'L' + && bprm->buf[3] == 'F') { + retval = load_elf_binary(bprm, regs, infop); } else { fprintf(stderr, "Unknown binary format\n"); return -1; @@ -211,7 +211,7 @@ int loader_exec(const char * filename, char ** argv, char ** envp, /* Something went wrong, return the inode and free the argument pages*/ for (i=0 ; ipage[i]); } return(retval); } diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index 035bcea..0f6c3db 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -679,7 +679,7 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page, return p; } -static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, +static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, struct image_info *info) { abi_ulong stack_base, size, error; @@ -1164,8 +1164,8 @@ static void load_symbols(struct elfhdr *hdr, int fd) syminfos = s; } -int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info) +int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs, + struct image_info *info) { struct elfhdr elf_ex; struct elfhdr interp_elf_ex; diff --git a/bsd-user/main.c b/bsd-user/main.c index 2eb4a1b..0442dbe 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -884,6 +884,15 @@ static void usage(void) THREAD CPUArchState *thread_env; +void stop_all_tasks(void) +{ + /* + * We trust when using NPTL (pthreads) start_exclusive() handles thread + * stopping correctly. + */ + start_exclusive(); +} + /* Assumes contents are already zeroed. */ void init_task_state(TaskState *ts) { @@ -905,6 +914,7 @@ int main(int argc, char **argv) const char *log_mask = NULL; struct target_pt_regs regs1, *regs = ®s1; struct image_info info1, *info = &info1; + struct bsd_binprm bprm; TaskState ts1, *ts = &ts1; CPUArchState *env; int optind; @@ -912,7 +922,11 @@ int main(int argc, char **argv) int gdbstub_port = 0; char **target_environ, **wrk; envlist_t *envlist = NULL; +#ifdef __FreeBSD__ + bsd_type = target_freebsd; +#else bsd_type = target_openbsd; +#endif if (argc <= 1) usage(); @@ -1054,6 +1068,8 @@ int main(int argc, char **argv) /* Zero out regs */ memset(regs, 0, sizeof(struct target_pt_regs)); + memset(&bprm, 0, sizeof(bprm)); + /* Zero out image_info */ memset(info, 0, sizeof(struct image_info)); @@ -1133,7 +1149,7 @@ int main(int argc, char **argv) } #endif /* CONFIG_USE_GUEST_BASE */ - if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) { + if (loader_exec(filename, argv+optind, target_environ, regs, info, &bprm)) { printf("Error loading %s\n", filename); _exit(1); } @@ -1178,6 +1194,7 @@ int main(int argc, char **argv) memset(ts, 0, sizeof(TaskState)); init_task_state(ts); ts->info = info; + ts->bprm = &bprm; env->opaque = ts; #if defined(TARGET_I386) diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index c0cdfcd..a36e9d2 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -90,6 +90,7 @@ typedef struct TaskState { struct TaskState *next; int used; /* non zero if used */ struct image_info *info; + struct bsd_binprm *bprm; struct emulated_sigtable sigtab[TARGET_NSIG]; struct qemu_sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ @@ -100,6 +101,7 @@ typedef struct TaskState { } __attribute__((aligned(16))) TaskState; void init_task_state(TaskState *ts); +void stop_all_tasks(void); extern const char *qemu_uname_release; #if defined(CONFIG_USE_GUEST_BASE) extern unsigned long mmap_min_addr; @@ -117,7 +119,7 @@ extern unsigned long mmap_min_addr; * This structure is used to hold the arguments that are * used when loading binaries. */ -struct linux_binprm { +struct bsd_binprm { char buf[128]; void *page[MAX_ARG_PAGES]; abi_ulong p; @@ -126,19 +128,21 @@ struct linux_binprm { int argc, envc; char **argv; char **envp; - char * filename; /* Name of binary */ + char *filename; /* Name of binary */ + int (*core_dump)(int, const CPUArchState *); }; void do_init_thread(struct target_pt_regs *regs, struct image_info *infop); abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, abi_ulong stringp, int push_ptr); -int loader_exec(const char * filename, char ** argv, char ** envp, - struct target_pt_regs * regs, struct image_info *infop); - -int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info); -int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info); +int loader_exec(const char *filename, char **argv, char **envp, + struct target_pt_regs *regs, struct image_info *infop, + struct bsd_binprm *bprm); + +int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs, + struct image_info *info); +int load_flt_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs, + struct image_info *info); abi_long memcpy_to_target(abi_ulong dest, const void *src, unsigned long len); diff --git a/bsd-user/signal.c b/bsd-user/signal.c index eb452fc..4ee97af 100644 --- a/bsd-user/signal.c +++ b/bsd-user/signal.c @@ -263,7 +263,6 @@ void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info) tswap_siginfo(tinfo, tinfo); } -#if 0 /* not yet */ /* Returns 1 if given signal should dump core if not handled. */ static int core_dump_signal(int sig) { @@ -280,7 +279,6 @@ static int core_dump_signal(int sig) return 0; } } -#endif /* not yet */ /* Signal queue handling. */ static inline struct qemu_sigqueue *alloc_sigqueue(CPUArchState *env) @@ -306,10 +304,8 @@ static inline void free_sigqueue(CPUArchState *env, struct qemu_sigqueue *q) /* Abort execution with signal. */ void QEMU_NORETURN force_sig(int target_sig) { -#if 0 /* not yet */ TaskState *ts = (TaskState *)thread_env->opaque; int core_dumped = 0; -#endif int host_sig; struct sigaction act; @@ -317,7 +313,6 @@ void QEMU_NORETURN force_sig(int target_sig) gdb_signalled(thread_env, target_sig); /* Dump core if supported by target binary format */ -#if 0 /* net yet */ if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) { stop_all_tasks(); core_dumped = @@ -335,7 +330,6 @@ void QEMU_NORETURN force_sig(int target_sig) (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) " "- %s\n", target_sig, strsignal(host_sig), "core dumped"); } -#endif /* not yet */ /* * The proper exit code for dying from an uncaught signal is -- 1.7.8