提交 863cf0b7 编写于 作者: J j_mayer

Fix confusions between host and target long types.

Fix start_data computation.
Fix auxiliary infos setup.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3344 c046a42c-6fe2-441c-8c8c-71466251a162
上级 f2e63a42
...@@ -124,6 +124,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i ...@@ -124,6 +124,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
/* XXX: it seems that r0 is zeroed after ! */ /* XXX: it seems that r0 is zeroed after ! */
regs->ARM_r0 = 0; regs->ARM_r0 = 0;
/* For uClinux PIC binaries. */ /* For uClinux PIC binaries. */
/* XXX: Linux does this only on ARM with no MMU (do we care ?) */
regs->ARM_r10 = infop->start_data; regs->ARM_r10 = infop->start_data;
} }
...@@ -516,8 +517,8 @@ static void bswap_sym(struct elf_sym *sym) ...@@ -516,8 +517,8 @@ static void bswap_sym(struct elf_sym *sym)
* to be put directly into the top of new user memory. * to be put directly into the top of new user memory.
* *
*/ */
static unsigned long copy_elf_strings(int argc,char ** argv, void **page, static target_ulong copy_elf_strings(int argc,char ** argv, void **page,
target_ulong p) target_ulong p)
{ {
char *tmp, *tmp1, *pag = NULL; char *tmp, *tmp1, *pag = NULL;
int len, offset = 0; int len, offset = 0;
...@@ -566,8 +567,8 @@ static unsigned long copy_elf_strings(int argc,char ** argv, void **page, ...@@ -566,8 +567,8 @@ static unsigned long copy_elf_strings(int argc,char ** argv, void **page,
return p; return p;
} }
unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm, target_ulong setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
struct image_info * info) struct image_info * info)
{ {
target_ulong stack_base, size, error; target_ulong stack_base, size, error;
int i; int i;
...@@ -605,7 +606,7 @@ unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm, ...@@ -605,7 +606,7 @@ unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
return p; return p;
} }
static void set_brk(unsigned long start, unsigned long end) static void set_brk(target_ulong start, target_ulong end)
{ {
/* page-align the start and end addresses... */ /* page-align the start and end addresses... */
start = HOST_PAGE_ALIGN(start); start = HOST_PAGE_ALIGN(start);
...@@ -624,9 +625,9 @@ static void set_brk(unsigned long start, unsigned long end) ...@@ -624,9 +625,9 @@ static void set_brk(unsigned long start, unsigned long end)
/* We need to explicitly zero any fractional pages after the data /* We need to explicitly zero any fractional pages after the data
section (i.e. bss). This would contain the junk from the file that section (i.e. bss). This would contain the junk from the file that
should not be in memory. */ should not be in memory. */
static void padzero(unsigned long elf_bss, unsigned long last_bss) static void padzero(target_ulong elf_bss, target_ulong last_bss)
{ {
unsigned long nbyte; target_ulong nbyte;
if (elf_bss >= last_bss) if (elf_bss >= last_bss)
return; return;
...@@ -637,12 +638,12 @@ static void padzero(unsigned long elf_bss, unsigned long last_bss) ...@@ -637,12 +638,12 @@ static void padzero(unsigned long elf_bss, unsigned long last_bss)
patch target_mmap(), but it is more complicated as the file patch target_mmap(), but it is more complicated as the file
size must be known */ size must be known */
if (qemu_real_host_page_size < qemu_host_page_size) { if (qemu_real_host_page_size < qemu_host_page_size) {
unsigned long end_addr, end_addr1; target_ulong end_addr, end_addr1;
end_addr1 = (elf_bss + qemu_real_host_page_size - 1) & end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
~(qemu_real_host_page_size - 1); ~(qemu_real_host_page_size - 1);
end_addr = HOST_PAGE_ALIGN(elf_bss); end_addr = HOST_PAGE_ALIGN(elf_bss);
if (end_addr1 < end_addr) { if (end_addr1 < end_addr) {
mmap((void *)end_addr1, end_addr - end_addr1, mmap((void *)g2h(end_addr1), end_addr - end_addr1,
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
} }
...@@ -659,18 +660,18 @@ static void padzero(unsigned long elf_bss, unsigned long last_bss) ...@@ -659,18 +660,18 @@ static void padzero(unsigned long elf_bss, unsigned long last_bss)
} }
static unsigned long create_elf_tables(target_ulong p, int argc, int envc, static target_ulong create_elf_tables(target_ulong p, int argc, int envc,
struct elfhdr * exec, struct elfhdr * exec,
unsigned long load_addr, target_ulong load_addr,
unsigned long load_bias, target_ulong load_bias,
unsigned long interp_load_addr, int ibcs, target_ulong interp_load_addr, int ibcs,
struct image_info *info) struct image_info *info)
{ {
target_ulong sp; target_ulong sp;
int size; int size;
target_ulong u_platform; target_ulong u_platform;
const char *k_platform; const char *k_platform;
const int n = sizeof(target_ulong); const int n = sizeof(elf_addr_t);
sp = p; sp = p;
u_platform = 0; u_platform = 0;
...@@ -697,10 +698,20 @@ static unsigned long create_elf_tables(target_ulong p, int argc, int envc, ...@@ -697,10 +698,20 @@ static unsigned long create_elf_tables(target_ulong p, int argc, int envc,
if (size & 15) if (size & 15)
sp -= 16 - (size & 15); sp -= 16 - (size & 15);
/* This is correct because Linux defines
* elf_addr_t as Elf32_Off / Elf64_Off
*/
#if ELF_CLASS == ELFCLASS32
#define NEW_AUX_ENT(id, val) do { \ #define NEW_AUX_ENT(id, val) do { \
sp -= n; tputl(sp, val); \ sp -= n; tput32(sp, val); \
sp -= n; tputl(sp, id); \ sp -= n; tput32(sp, id); \
} while(0) } while(0)
#else
#define NEW_AUX_ENT(id, val) do { \
sp -= n; tput64(sp, val); \
sp -= n; tput64(sp, id); \
} while(0)
#endif
NEW_AUX_ENT (AT_NULL, 0); NEW_AUX_ENT (AT_NULL, 0);
/* There must be exactly DLINFO_ITEMS entries here. */ /* There must be exactly DLINFO_ITEMS entries here. */
...@@ -732,17 +743,17 @@ static unsigned long create_elf_tables(target_ulong p, int argc, int envc, ...@@ -732,17 +743,17 @@ static unsigned long create_elf_tables(target_ulong p, int argc, int envc,
} }
static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, static target_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
int interpreter_fd, int interpreter_fd,
unsigned long *interp_load_addr) target_ulong *interp_load_addr)
{ {
struct elf_phdr *elf_phdata = NULL; struct elf_phdr *elf_phdata = NULL;
struct elf_phdr *eppnt; struct elf_phdr *eppnt;
unsigned long load_addr = 0; target_ulong load_addr = 0;
int load_addr_set = 0; int load_addr_set = 0;
int retval; int retval;
unsigned long last_bss, elf_bss; target_ulong last_bss, elf_bss;
unsigned long error; target_ulong error;
int i; int i;
elf_bss = 0; elf_bss = 0;
...@@ -756,20 +767,20 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -756,20 +767,20 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
if ((interp_elf_ex->e_type != ET_EXEC && if ((interp_elf_ex->e_type != ET_EXEC &&
interp_elf_ex->e_type != ET_DYN) || interp_elf_ex->e_type != ET_DYN) ||
!elf_check_arch(interp_elf_ex->e_machine)) { !elf_check_arch(interp_elf_ex->e_machine)) {
return ~0UL; return ~((target_ulong)0UL);
} }
/* Now read in all of the header information */ /* Now read in all of the header information */
if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE) if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
return ~0UL; return ~(target_ulong)0UL;
elf_phdata = (struct elf_phdr *) elf_phdata = (struct elf_phdr *)
malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
if (!elf_phdata) if (!elf_phdata)
return ~0UL; return ~((target_ulong)0UL);
/* /*
* If the size of this structure has changed, then punt, since * If the size of this structure has changed, then punt, since
...@@ -777,7 +788,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -777,7 +788,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
*/ */
if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) { if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
free(elf_phdata); free(elf_phdata);
return ~0UL; return ~((target_ulong)0UL);
} }
retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET); retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
...@@ -818,8 +829,8 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -818,8 +829,8 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
if (eppnt->p_type == PT_LOAD) { if (eppnt->p_type == PT_LOAD) {
int elf_type = MAP_PRIVATE | MAP_DENYWRITE; int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
int elf_prot = 0; int elf_prot = 0;
unsigned long vaddr = 0; target_ulong vaddr = 0;
unsigned long k; target_ulong k;
if (eppnt->p_flags & PF_R) elf_prot = PROT_READ; if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
...@@ -839,7 +850,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -839,7 +850,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
/* Real error */ /* Real error */
close(interpreter_fd); close(interpreter_fd);
free(elf_phdata); free(elf_phdata);
return ~0UL; return ~((target_ulong)0UL);
} }
if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
...@@ -884,7 +895,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, ...@@ -884,7 +895,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
free(elf_phdata); free(elf_phdata);
*interp_load_addr = load_addr; *interp_load_addr = load_addr;
return ((unsigned long) interp_elf_ex->e_entry) + load_addr; return ((target_ulong) interp_elf_ex->e_entry) + load_addr;
} }
/* Best attempt to load symbols from this ELF object. */ /* Best attempt to load symbols from this ELF object. */
...@@ -972,22 +983,22 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, ...@@ -972,22 +983,22 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
struct elfhdr interp_elf_ex; struct elfhdr interp_elf_ex;
struct exec interp_ex; struct exec interp_ex;
int interpreter_fd = -1; /* avoid warning */ int interpreter_fd = -1; /* avoid warning */
unsigned long load_addr, load_bias; target_ulong load_addr, load_bias;
int load_addr_set = 0; int load_addr_set = 0;
unsigned int interpreter_type = INTERPRETER_NONE; unsigned int interpreter_type = INTERPRETER_NONE;
unsigned char ibcs2_interpreter; unsigned char ibcs2_interpreter;
int i; int i;
unsigned long mapped_addr; target_ulong mapped_addr;
struct elf_phdr * elf_ppnt; struct elf_phdr * elf_ppnt;
struct elf_phdr *elf_phdata; struct elf_phdr *elf_phdata;
unsigned long elf_bss, k, elf_brk; target_ulong elf_bss, k, elf_brk;
int retval; int retval;
char * elf_interpreter; char * elf_interpreter;
unsigned long elf_entry, interp_load_addr = 0; target_ulong elf_entry, interp_load_addr = 0;
int status; int status;
unsigned long start_code, end_code, end_data; target_ulong start_code, end_code, start_data, end_data;
unsigned long reloc_func_desc = 0; target_ulong reloc_func_desc = 0;
unsigned long elf_stack; target_ulong elf_stack;
char passed_fileno[6]; char passed_fileno[6];
ibcs2_interpreter = 0; ibcs2_interpreter = 0;
...@@ -1043,10 +1054,11 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, ...@@ -1043,10 +1054,11 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
elf_brk = 0; elf_brk = 0;
elf_stack = ~0UL; elf_stack = ~((target_ulong)0UL);
elf_interpreter = NULL; elf_interpreter = NULL;
start_code = ~0UL; start_code = ~((target_ulong)0UL);
end_code = 0; end_code = 0;
start_data = 0;
end_data = 0; end_data = 0;
for(i=0;i < elf_ex.e_phnum; i++) { for(i=0;i < elf_ex.e_phnum; i++) {
...@@ -1180,9 +1192,9 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, ...@@ -1180,9 +1192,9 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
/* OK, This is the point of no return */ /* OK, This is the point of no return */
info->end_data = 0; info->end_data = 0;
info->end_code = 0; info->end_code = 0;
info->start_mmap = (unsigned long)ELF_START_MMAP; info->start_mmap = (target_ulong)ELF_START_MMAP;
info->mmap = 0; info->mmap = 0;
elf_entry = (unsigned long) elf_ex.e_entry; elf_entry = (target_ulong) elf_ex.e_entry;
/* Do this so that we can load the interpreter, if need be. We will /* Do this so that we can load the interpreter, if need be. We will
change some of these later */ change some of these later */
...@@ -1199,7 +1211,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, ...@@ -1199,7 +1211,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
int elf_prot = 0; int elf_prot = 0;
int elf_flags = 0; int elf_flags = 0;
unsigned long error; target_ulong error;
if (elf_ppnt->p_type != PT_LOAD) if (elf_ppnt->p_type != PT_LOAD)
continue; continue;
...@@ -1257,6 +1269,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, ...@@ -1257,6 +1269,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
k = elf_ppnt->p_vaddr; k = elf_ppnt->p_vaddr;
if (k < start_code) if (k < start_code)
start_code = k; start_code = k;
if (start_data < k)
start_data = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz; k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
if (k > elf_bss) if (k > elf_bss)
elf_bss = k; elf_bss = k;
...@@ -1273,7 +1287,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, ...@@ -1273,7 +1287,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
elf_brk += load_bias; elf_brk += load_bias;
start_code += load_bias; start_code += load_bias;
end_code += load_bias; end_code += load_bias;
// start_data += load_bias; start_data += load_bias;
end_data += load_bias; end_data += load_bias;
if (elf_interpreter) { if (elf_interpreter) {
...@@ -1289,7 +1303,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, ...@@ -1289,7 +1303,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
close(interpreter_fd); close(interpreter_fd);
free(elf_interpreter); free(elf_interpreter);
if (elf_entry == ~0UL) { if (elf_entry == ~((target_ulong)0UL)) {
printf("Unable to load interpreter\n"); printf("Unable to load interpreter\n");
free(elf_phdata); free(elf_phdata);
exit(-1); exit(-1);
...@@ -1320,7 +1334,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, ...@@ -1320,7 +1334,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
info->start_brk = info->brk = elf_brk; info->start_brk = info->brk = elf_brk;
info->end_code = end_code; info->end_code = end_code;
info->start_code = start_code; info->start_code = start_code;
info->start_data = end_code; info->start_data = start_data;
info->end_data = end_data; info->end_data = end_data;
info->start_stack = bprm->p; info->start_stack = bprm->p;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册