It appears that the start_data is not well computed in Qemu:
it's set to the end_code value, which does not follow what the Linux
kernel does.
Here's a patch that fix this issue. But as it may affect ARM emulated
target (at least those with no MMU, as noticed in the patch), I prefer
to let people that do know ARM better check what this patch may break in
this case.

-- 
J. Mayer <[EMAIL PROTECTED]>
Never organized
Index: linux-user/elfload.c
===================================================================
RCS file: /sources/qemu/qemu/linux-user/elfload.c,v
retrieving revision 1.39
diff -u -d -d -p -r1.39 elfload.c
--- linux-user/elfload.c	5 Apr 2007 07:13:51 -0000	1.39
+++ linux-user/elfload.c	5 Apr 2007 19:58:35 -0000
@@ -106,6 +128,7 @@ static inline void init_thread(struct ta
     /* 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;
 }
 
@@ -916,7 +939,7 @@ int load_elf_binary(struct linux_binprm 
     char * elf_interpreter;
     unsigned long elf_entry, interp_load_addr = 0;
     int status;
-    unsigned long start_code, end_code, end_data;
+    unsigned long start_code, end_code, start_data, end_data;
     unsigned long elf_stack;
     char passed_fileno[6];
 
@@ -977,6 +1000,7 @@ int load_elf_binary(struct linux_binprm 
     elf_interpreter = NULL;
     start_code = ~0UL;
     end_code = 0;
+    start_data = 0;
     end_data = 0;
 
     for(i=0;i < elf_ex.e_phnum; i++) {
@@ -1186,6 +1210,8 @@ int load_elf_binary(struct linux_binprm 
         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;
@@ -1202,7 +1228,7 @@ int load_elf_binary(struct linux_binprm 
     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) {
@@ -1247,7 +1273,7 @@ int load_elf_binary(struct linux_binprm 
     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;
 

Reply via email to