diff options
author | j_mayer <j_mayer> | 2007-04-06 08:56:50 +0000 |
---|---|---|
committer | j_mayer <j_mayer> | 2007-04-06 08:56:50 +0000 |
commit | 3ab273bdc8127f67ced6087403ea90627ddf133c (patch) | |
tree | 17f6e76dba5226a96b3bdc465c06d58552eb9749 /qemu/linux-user/elfload.c | |
parent | cf1277711e265d22bc451c572a20fed8624253a2 (diff) |
Code provision for x86_64 and PowerPC 64 linux user mode support.
Diffstat (limited to 'qemu/linux-user/elfload.c')
-rw-r--r-- | qemu/linux-user/elfload.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/qemu/linux-user/elfload.c b/qemu/linux-user/elfload.c index 5caa44ea..1256dba9 100644 --- a/qemu/linux-user/elfload.c +++ b/qemu/linux-user/elfload.c @@ -44,6 +44,23 @@ static uint32_t get_elf_hwcap(void) return global_env->cpuid_features; } +#ifdef TARGET_X86_64 +#define ELF_START_MMAP 0x2aaaaab000ULL +#define elf_check_arch(x) ( ((x) == ELF_ARCH) ) + +#define ELF_CLASS ELFCLASS64 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_X86_64 + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ + regs->rax = 0; + regs->rsp = infop->start_stack; + regs->rip = infop->entry; +} + +#else + #define ELF_START_MMAP 0x80000000 /* @@ -72,6 +89,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i A value of 0 tells we have no such handler. */ regs->edx = 0; } +#endif #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 @@ -177,9 +195,20 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i #define ELF_START_MMAP 0x80000000 +#ifdef TARGET_PPC64 + +#define elf_check_arch(x) ( (x) == EM_PPC64 ) + +#define ELF_CLASS ELFCLASS64 + +#else + #define elf_check_arch(x) ( (x) == EM_PPC ) #define ELF_CLASS ELFCLASS32 + +#endif + #ifdef TARGET_WORDS_BIGENDIAN #define ELF_DATA ELFDATA2MSB #else @@ -222,9 +251,18 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * { target_ulong pos = infop->start_stack; target_ulong tmp; +#ifdef TARGET_PPC64 + target_ulong entry, toc; +#endif _regs->msr = 1 << MSR_PR; /* Set user mode */ _regs->gpr[1] = infop->start_stack; +#ifdef TARGET_PPC64 + entry = ldq_raw(infop->entry) + infop->load_addr; + toc = ldq_raw(infop->entry + 8) + infop->load_addr; + _regs->gpr[2] = toc; + infop->entry = entry; +#endif _regs->nip = infop->entry; /* Note that isn't exactly what regular kernel does * but this is what the ABI wants and is needed to allow @@ -917,6 +955,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, unsigned long elf_entry, interp_load_addr = 0; int status; unsigned long start_code, end_code, end_data; + unsigned long reloc_func_desc = 0; unsigned long elf_stack; char passed_fileno[6]; @@ -1181,6 +1220,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, load_bias += error - TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr); load_addr += load_bias; + reloc_func_desc = load_bias; } } k = elf_ppnt->p_vaddr; @@ -1213,6 +1253,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd, &interp_load_addr); } + reloc_func_desc = interp_load_addr; close(interpreter_fd); free(elf_interpreter); |