/* This is the Linux kernel elf-loading code, ported into user space */
-#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <stdlib.h>
-#include <string.h>
+#include "qemu/osdep.h"
#include "qemu.h"
-#include "disas.h"
+#include "disas/disas.h"
+#include "qemu/path.h"
#ifdef _ARCH_PPC64
#undef ARCH_DLINFO
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)
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
_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
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;
}
offset = p % TARGET_PAGE_SIZE;
pag = (char *)page[p/TARGET_PAGE_SIZE];
if (!pag) {
- pag = (char *)malloc(TARGET_PAGE_SIZE);
- memset(pag, 0, TARGET_PAGE_SIZE);
+ pag = g_try_malloc0(TARGET_PAGE_SIZE);
page[p/TARGET_PAGE_SIZE] = pag;
if (!pag)
return 0;
info->rss++;
/* FIXME - check return value of memcpy_to_target() for failure */
memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
- free(bprm->page[i]);
+ g_free(bprm->page[i]);
}
stack_base += TARGET_PAGE_SIZE;
}
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,
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;
#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;
}
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 */
elf_brk = 0;
- elf_stack = ~((abi_ulong)0UL);
elf_interpreter = NULL;
start_code = ~((abi_ulong)0UL);
end_code = 0;
}
}
if (!bprm->p) {
- if (elf_interpreter) {
- free(elf_interpreter);
- }
+ free(elf_interpreter);
free (elf_phdata);
close(bprm->fd);
return -E2BIG;
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.
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;
}
}
}
-#endif /* CONFIG_USE_GUEST_BASE */
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
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);
}