]> xenbits.xensource.com Git - qemu-xen.git/commitdiff
Fix confusions between host and target long types.
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 7 Oct 2007 15:59:45 +0000 (15:59 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 7 Oct 2007 15:59:45 +0000 (15:59 +0000)
Fix start_data computation.
Fix auxiliary infos setup.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3344 c046a42c-6fe2-441c-8c8c-71466251a162

linux-user/elfload.c

index 22e3283ae71401ff2ed50f972bc5a9be1e2aa343..79c1c4da6eb06613b34624924358afe57ce8be4d 100644 (file)
@@ -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 ! */
     regs->ARM_r0 = 0;
     /* For uClinux PIC binaries.  */
+    /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
     regs->ARM_r10 = infop->start_data;
 }
 
@@ -516,8 +517,8 @@ static void bswap_sym(struct elf_sym *sym)
  * to be put directly into the top of new user memory.
  *
  */
-static unsigned long copy_elf_strings(int argc,char ** argv, void **page,
-                                      target_ulong p)
+static target_ulong copy_elf_strings(int argc,char ** argv, void **page,
+                                     target_ulong p)
 {
     char *tmp, *tmp1, *pag = NULL;
     int len, offset = 0;
@@ -566,8 +567,8 @@ static unsigned long copy_elf_strings(int argc,char ** argv, void **page,
     return p;
 }
 
-unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
-                                             struct image_info * info)
+target_ulong setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
+                             struct image_info * info)
 {
     target_ulong stack_base, size, error;
     int i;
@@ -605,7 +606,7 @@ unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
     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... */
         start = HOST_PAGE_ALIGN(start);
@@ -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
    section (i.e. bss).  This would contain the junk from the file that
    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)
                return;
@@ -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
            size must be known */
         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) &
                 ~(qemu_real_host_page_size - 1);
             end_addr = HOST_PAGE_ALIGN(elf_bss);
             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,
                      MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
             }
@@ -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,
-                                       struct elfhdr * exec,
-                                       unsigned long load_addr,
-                                       unsigned long load_bias,
-                                       unsigned long interp_load_addr, int ibcs,
-                                       struct image_info *info)
+static target_ulong create_elf_tables(target_ulong p, int argc, int envc,
+                                      struct elfhdr * exec,
+                                      target_ulong load_addr,
+                                      target_ulong load_bias,
+                                      target_ulong interp_load_addr, int ibcs,
+                                      struct image_info *info)
 {
         target_ulong sp;
         int size;
         target_ulong u_platform;
         const char *k_platform;
-        const int n = sizeof(target_ulong);
+        const int n = sizeof(elf_addr_t);
 
         sp = p;
         u_platform = 0;
@@ -697,10 +698,20 @@ static unsigned long create_elf_tables(target_ulong p, int argc, int envc,
         if (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 { \
-            sp -= n; tputl(sp, val); \
-            sp -= n; tputl(sp, id); \
+            sp -= n; tput32(sp, val); \
+            sp -= n; tput32(sp, id); \
           } 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);
 
         /* 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,
 }
 
 
-static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
-                                    int interpreter_fd,
-                                    unsigned long *interp_load_addr)
+static target_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
+                                    int interpreter_fd,
+                                    target_ulong *interp_load_addr)
 {
        struct elf_phdr *elf_phdata  =  NULL;
        struct elf_phdr *eppnt;
-       unsigned long load_addr = 0;
+       target_ulong load_addr = 0;
        int load_addr_set = 0;
        int retval;
-       unsigned long last_bss, elf_bss;
-       unsigned long error;
+       target_ulong last_bss, elf_bss;
+       target_ulong error;
        int i;
 
        elf_bss = 0;
@@ -756,20 +767,20 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
        if ((interp_elf_ex->e_type != ET_EXEC &&
              interp_elf_ex->e_type != ET_DYN) ||
           !elf_check_arch(interp_elf_ex->e_machine)) {
-               return ~0UL;
+               return ~((target_ulong)0UL);
        }
 
 
        /* Now read in all of the header information */
 
        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
-           return ~0UL;
+           return ~(target_ulong)0UL;
 
        elf_phdata =  (struct elf_phdr *)
                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
 
        if (!elf_phdata)
-         return ~0UL;
+         return ~((target_ulong)0UL);
 
        /*
         * 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,
         */
        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
            free(elf_phdata);
-           return ~0UL;
+           return ~((target_ulong)0UL);
         }
 
        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,
          if (eppnt->p_type == PT_LOAD) {
            int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
            int elf_prot = 0;
-           unsigned long vaddr = 0;
-           unsigned long k;
+           target_ulong vaddr = 0;
+           target_ulong k;
 
            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ;
            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,
              /* Real error */
              close(interpreter_fd);
              free(elf_phdata);
-             return ~0UL;
+             return ~((target_ulong)0UL);
            }
 
            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,
        free(elf_phdata);
 
        *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. */
@@ -972,22 +983,22 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
     struct elfhdr interp_elf_ex;
     struct exec interp_ex;
     int interpreter_fd = -1; /* avoid warning */
-    unsigned long load_addr, load_bias;
+    target_ulong load_addr, load_bias;
     int load_addr_set = 0;
     unsigned int interpreter_type = INTERPRETER_NONE;
     unsigned char ibcs2_interpreter;
     int i;
-    unsigned long mapped_addr;
+    target_ulong mapped_addr;
     struct elf_phdr * elf_ppnt;
     struct elf_phdr *elf_phdata;
-    unsigned long elf_bss, k, elf_brk;
+    target_ulong elf_bss, k, elf_brk;
     int retval;
     char * elf_interpreter;
-    unsigned long elf_entry, interp_load_addr = 0;
+    target_ulong 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;
+    target_ulong start_code, end_code, start_data, end_data;
+    target_ulong reloc_func_desc = 0;
+    target_ulong elf_stack;
     char passed_fileno[6];
 
     ibcs2_interpreter = 0;
@@ -1043,10 +1054,11 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
     elf_brk = 0;
 
 
-    elf_stack = ~0UL;
+    elf_stack = ~((target_ulong)0UL);
     elf_interpreter = NULL;
-    start_code = ~0UL;
+    start_code = ~((target_ulong)0UL);
     end_code = 0;
+    start_data = 0;
     end_data = 0;
 
     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,
     /* OK, This is the point of no return */
     info->end_data = 0;
     info->end_code = 0;
-    info->start_mmap = (unsigned long)ELF_START_MMAP;
+    info->start_mmap = (target_ulong)ELF_START_MMAP;
     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
        change some of these later */
@@ -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++) {
         int elf_prot = 0;
         int elf_flags = 0;
-        unsigned long error;
+        target_ulong error;
 
        if (elf_ppnt->p_type != PT_LOAD)
             continue;
@@ -1257,6 +1269,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
         k = elf_ppnt->p_vaddr;
         if (k < start_code)
             start_code = k;
+        if (start_data < k)
+            start_data = k;
         k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
         if (k > elf_bss)
             elf_bss = k;
@@ -1273,7 +1287,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
     elf_brk += load_bias;
     start_code += load_bias;
     end_code += load_bias;
-    //    start_data += load_bias;
+    start_data += load_bias;
     end_data += load_bias;
 
     if (elf_interpreter) {
@@ -1289,7 +1303,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
        close(interpreter_fd);
        free(elf_interpreter);
 
-       if (elf_entry == ~0UL) {
+       if (elf_entry == ~((target_ulong)0UL)) {
            printf("Unable to load interpreter\n");
            free(elf_phdata);
            exit(-1);
@@ -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->end_code = end_code;
     info->start_code = start_code;
-    info->start_data = end_code;
+    info->start_data = start_data;
     info->end_data = end_data;
     info->start_stack = bprm->p;