X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=bsd-user%2Felfload.c;h=32378af7b2ec90c037f7517d8adee7925d9d3fe6;hb=11978f6f58f1d3d66429f7ff897524f693d823ce;hp=12888840a442f6f16749dc4f54a8c78e02ea8ff1;hpb=9bf4896e5d565785316d2c179be91fba11fbf3fb;p=mirror_qemu.git diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index 12888840a4..32378af7b2 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -1,16 +1,10 @@ /* This is the Linux kernel elf-loading code, ported into user space */ -#include -#include -#include -#include -#include -#include -#include -#include +#include "qemu/osdep.h" #include "qemu.h" -#include "disas.h" +#include "disas/disas.h" +#include "qemu/path.h" #ifdef _ARCH_PPC64 #undef ARCH_DLINFO @@ -98,7 +92,7 @@ enum { static const char *get_elf_platform(void) { static char elf_platform[] = "i386"; - int family = (thread_env->cpuid_version >> 8) & 0xff; + int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL); if (family > 6) family = 6; if (family >= 3) @@ -110,7 +104,9 @@ static const char *get_elf_platform(void) static uint32_t get_elf_hwcap(void) { - return thread_env->cpuid_features; + X86CPU *cpu = X86_CPU(thread_cpu); + + return cpu->env.features[FEAT_1_EDX]; } #ifdef TARGET_X86_64 @@ -349,8 +345,10 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * _regs->gpr[1] = infop->start_stack; #if defined(TARGET_PPC64) && !defined(TARGET_ABI32) - entry = ldq_raw(infop->entry) + infop->load_addr; - toc = ldq_raw(infop->entry + 8) + infop->load_addr; + get_user_u64(entry, infop->entry); + entry += infop->load_addr; + get_user_u64(toc, infop->entry + 8); + toc += infop->load_addr; _regs->gpr[2] = toc; infop->entry = entry; #endif @@ -363,8 +361,9 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * get_user_ual(_regs->gpr[3], pos); pos += sizeof(abi_ulong); _regs->gpr[4] = pos; - for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong)) - tmp = ldl(pos); + for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong)) { + get_user_ual(tmp, pos); + } _regs->gpr[5] = pos; } @@ -735,8 +734,7 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss) size must be known */ if (qemu_real_host_page_size < qemu_host_page_size) { abi_ulong end_addr, end_addr1; - end_addr1 = (elf_bss + qemu_real_host_page_size - 1) & - ~(qemu_real_host_page_size - 1); + end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss); end_addr = HOST_PAGE_ALIGN(elf_bss); if (end_addr1 < end_addr) { mmap((void *)g2h(end_addr1), end_addr - end_addr1, @@ -993,12 +991,12 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, static int symfind(const void *s0, const void *s1) { - struct elf_sym *key = (struct elf_sym *)s0; + target_ulong addr = *(target_ulong *)s0; struct elf_sym *sym = (struct elf_sym *)s1; int result = 0; - if (key->st_value < sym->st_value) { + if (addr < sym->st_value) { result = -1; - } else if (key->st_value > sym->st_value + sym->st_size) { + } else if (addr >= sym->st_value + sym->st_size) { result = 1; } return result; @@ -1013,12 +1011,9 @@ static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr) #endif // binary search - struct elf_sym key; struct elf_sym *sym; - key.st_value = orig_addr; - - sym = bsearch(&key, syms, s->disas_num_syms, sizeof(*syms), symfind); + sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms), symfind); if (sym != NULL) { return s->disas_strtab + sym->st_name; } @@ -1160,21 +1155,20 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, unsigned int interpreter_type = INTERPRETER_NONE; unsigned char ibcs2_interpreter; int i; - abi_ulong mapped_addr; struct elf_phdr * elf_ppnt; struct elf_phdr *elf_phdata; abi_ulong elf_bss, k, elf_brk; int retval; char * elf_interpreter; abi_ulong elf_entry, interp_load_addr = 0; - int status; abi_ulong start_code, end_code, start_data, end_data; abi_ulong reloc_func_desc = 0; - abi_ulong elf_stack; +#ifdef LOW_ELF_STACK + abi_ulong elf_stack = ~((abi_ulong)0UL); +#endif char passed_fileno[6]; ibcs2_interpreter = 0; - status = 0; load_addr = 0; load_bias = 0; elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ @@ -1226,7 +1220,6 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, elf_brk = 0; - elf_stack = ~((abi_ulong)0UL); elf_interpreter = NULL; start_code = ~((abi_ulong)0UL); end_code = 0; @@ -1353,9 +1346,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, } } if (!bprm->p) { - if (elf_interpreter) { - free(elf_interpreter); - } + free(elf_interpreter); free (elf_phdata); close(bprm->fd); return -E2BIG; @@ -1369,7 +1360,6 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, info->mmap = 0; elf_entry = (abi_ulong) elf_ex.e_entry; -#if defined(CONFIG_USE_GUEST_BASE) /* * In case where user has not explicitly set the guest_base, we * probe here that should we set it automatically. @@ -1377,7 +1367,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, if (!have_guest_base) { /* * Go through ELF program header table and find out whether - * any of the segments drop below our current mmap_min_addr and + * any of the segments drop below our current mmap_min_addr and * in that case set guest_base to corresponding address. */ for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; @@ -1390,7 +1380,6 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, } } } -#endif /* CONFIG_USE_GUEST_BASE */ /* Do this so that we can load the interpreter, if need be. We will change some of these later */ @@ -1555,7 +1544,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, and some applications "depend" upon this behavior. Since we do not have the power to recompile these, we emulate the SVr4 behavior. Sigh. */ - mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC, + target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, -1, 0); }