Commit 863cf0b72cee98e42aa03403c38d5cac7fa535ca

Authored by j_mayer
1 parent f2e63a42

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
Showing 1 changed file with 61 additions and 47 deletions
linux-user/elfload.c
@@ -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
124 /* XXX: it seems that r0 is zeroed after ! */ 124 /* XXX: it seems that r0 is zeroed after ! */
125 regs->ARM_r0 = 0; 125 regs->ARM_r0 = 0;
126 /* For uClinux PIC binaries. */ 126 /* For uClinux PIC binaries. */
  127 + /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
127 regs->ARM_r10 = infop->start_data; 128 regs->ARM_r10 = infop->start_data;
128 } 129 }
129 130
@@ -516,8 +517,8 @@ static void bswap_sym(struct elf_sym *sym) @@ -516,8 +517,8 @@ static void bswap_sym(struct elf_sym *sym)
516 * to be put directly into the top of new user memory. 517 * to be put directly into the top of new user memory.
517 * 518 *
518 */ 519 */
519 -static unsigned long copy_elf_strings(int argc,char ** argv, void **page,  
520 - target_ulong p) 520 +static target_ulong copy_elf_strings(int argc,char ** argv, void **page,
  521 + target_ulong p)
521 { 522 {
522 char *tmp, *tmp1, *pag = NULL; 523 char *tmp, *tmp1, *pag = NULL;
523 int len, offset = 0; 524 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,
566 return p; 567 return p;
567 } 568 }
568 569
569 -unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm,  
570 - struct image_info * info) 570 +target_ulong setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
  571 + struct image_info * info)
571 { 572 {
572 target_ulong stack_base, size, error; 573 target_ulong stack_base, size, error;
573 int i; 574 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,
605 return p; 606 return p;
606 } 607 }
607 608
608 -static void set_brk(unsigned long start, unsigned long end) 609 +static void set_brk(target_ulong start, target_ulong end)
609 { 610 {
610 /* page-align the start and end addresses... */ 611 /* page-align the start and end addresses... */
611 start = HOST_PAGE_ALIGN(start); 612 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)
624 /* We need to explicitly zero any fractional pages after the data 625 /* We need to explicitly zero any fractional pages after the data
625 section (i.e. bss). This would contain the junk from the file that 626 section (i.e. bss). This would contain the junk from the file that
626 should not be in memory. */ 627 should not be in memory. */
627 -static void padzero(unsigned long elf_bss, unsigned long last_bss) 628 +static void padzero(target_ulong elf_bss, target_ulong last_bss)
628 { 629 {
629 - unsigned long nbyte; 630 + target_ulong nbyte;
630 631
631 if (elf_bss >= last_bss) 632 if (elf_bss >= last_bss)
632 return; 633 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)
637 patch target_mmap(), but it is more complicated as the file 638 patch target_mmap(), but it is more complicated as the file
638 size must be known */ 639 size must be known */
639 if (qemu_real_host_page_size < qemu_host_page_size) { 640 if (qemu_real_host_page_size < qemu_host_page_size) {
640 - unsigned long end_addr, end_addr1; 641 + target_ulong end_addr, end_addr1;
641 end_addr1 = (elf_bss + qemu_real_host_page_size - 1) & 642 end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
642 ~(qemu_real_host_page_size - 1); 643 ~(qemu_real_host_page_size - 1);
643 end_addr = HOST_PAGE_ALIGN(elf_bss); 644 end_addr = HOST_PAGE_ALIGN(elf_bss);
644 if (end_addr1 < end_addr) { 645 if (end_addr1 < end_addr) {
645 - mmap((void *)end_addr1, end_addr - end_addr1, 646 + mmap((void *)g2h(end_addr1), end_addr - end_addr1,
646 PROT_READ|PROT_WRITE|PROT_EXEC, 647 PROT_READ|PROT_WRITE|PROT_EXEC,
647 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 648 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
648 } 649 }
@@ -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)
659 } 660 }
660 661
661 662
662 -static unsigned long create_elf_tables(target_ulong p, int argc, int envc,  
663 - struct elfhdr * exec,  
664 - unsigned long load_addr,  
665 - unsigned long load_bias,  
666 - unsigned long interp_load_addr, int ibcs,  
667 - struct image_info *info) 663 +static target_ulong create_elf_tables(target_ulong p, int argc, int envc,
  664 + struct elfhdr * exec,
  665 + target_ulong load_addr,
  666 + target_ulong load_bias,
  667 + target_ulong interp_load_addr, int ibcs,
  668 + struct image_info *info)
668 { 669 {
669 target_ulong sp; 670 target_ulong sp;
670 int size; 671 int size;
671 target_ulong u_platform; 672 target_ulong u_platform;
672 const char *k_platform; 673 const char *k_platform;
673 - const int n = sizeof(target_ulong); 674 + const int n = sizeof(elf_addr_t);
674 675
675 sp = p; 676 sp = p;
676 u_platform = 0; 677 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,
697 if (size & 15) 698 if (size & 15)
698 sp -= 16 - (size & 15); 699 sp -= 16 - (size & 15);
699 700
  701 + /* This is correct because Linux defines
  702 + * elf_addr_t as Elf32_Off / Elf64_Off
  703 + */
  704 +#if ELF_CLASS == ELFCLASS32
700 #define NEW_AUX_ENT(id, val) do { \ 705 #define NEW_AUX_ENT(id, val) do { \
701 - sp -= n; tputl(sp, val); \  
702 - sp -= n; tputl(sp, id); \ 706 + sp -= n; tput32(sp, val); \
  707 + sp -= n; tput32(sp, id); \
703 } while(0) 708 } while(0)
  709 +#else
  710 +#define NEW_AUX_ENT(id, val) do { \
  711 + sp -= n; tput64(sp, val); \
  712 + sp -= n; tput64(sp, id); \
  713 + } while(0)
  714 +#endif
704 NEW_AUX_ENT (AT_NULL, 0); 715 NEW_AUX_ENT (AT_NULL, 0);
705 716
706 /* There must be exactly DLINFO_ITEMS entries here. */ 717 /* 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,
732 } 743 }
733 744
734 745
735 -static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,  
736 - int interpreter_fd,  
737 - unsigned long *interp_load_addr) 746 +static target_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
  747 + int interpreter_fd,
  748 + target_ulong *interp_load_addr)
738 { 749 {
739 struct elf_phdr *elf_phdata = NULL; 750 struct elf_phdr *elf_phdata = NULL;
740 struct elf_phdr *eppnt; 751 struct elf_phdr *eppnt;
741 - unsigned long load_addr = 0; 752 + target_ulong load_addr = 0;
742 int load_addr_set = 0; 753 int load_addr_set = 0;
743 int retval; 754 int retval;
744 - unsigned long last_bss, elf_bss;  
745 - unsigned long error; 755 + target_ulong last_bss, elf_bss;
  756 + target_ulong error;
746 int i; 757 int i;
747 758
748 elf_bss = 0; 759 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,
756 if ((interp_elf_ex->e_type != ET_EXEC && 767 if ((interp_elf_ex->e_type != ET_EXEC &&
757 interp_elf_ex->e_type != ET_DYN) || 768 interp_elf_ex->e_type != ET_DYN) ||
758 !elf_check_arch(interp_elf_ex->e_machine)) { 769 !elf_check_arch(interp_elf_ex->e_machine)) {
759 - return ~0UL; 770 + return ~((target_ulong)0UL);
760 } 771 }
761 772
762 773
763 /* Now read in all of the header information */ 774 /* Now read in all of the header information */
764 775
765 if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE) 776 if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
766 - return ~0UL; 777 + return ~(target_ulong)0UL;
767 778
768 elf_phdata = (struct elf_phdr *) 779 elf_phdata = (struct elf_phdr *)
769 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); 780 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
770 781
771 if (!elf_phdata) 782 if (!elf_phdata)
772 - return ~0UL; 783 + return ~((target_ulong)0UL);
773 784
774 /* 785 /*
775 * If the size of this structure has changed, then punt, since 786 * 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,
777 */ 788 */
778 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) { 789 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
779 free(elf_phdata); 790 free(elf_phdata);
780 - return ~0UL; 791 + return ~((target_ulong)0UL);
781 } 792 }
782 793
783 retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET); 794 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,
818 if (eppnt->p_type == PT_LOAD) { 829 if (eppnt->p_type == PT_LOAD) {
819 int elf_type = MAP_PRIVATE | MAP_DENYWRITE; 830 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
820 int elf_prot = 0; 831 int elf_prot = 0;
821 - unsigned long vaddr = 0;  
822 - unsigned long k; 832 + target_ulong vaddr = 0;
  833 + target_ulong k;
823 834
824 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ; 835 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
825 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; 836 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,
839 /* Real error */ 850 /* Real error */
840 close(interpreter_fd); 851 close(interpreter_fd);
841 free(elf_phdata); 852 free(elf_phdata);
842 - return ~0UL; 853 + return ~((target_ulong)0UL);
843 } 854 }
844 855
845 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { 856 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,
884 free(elf_phdata); 895 free(elf_phdata);
885 896
886 *interp_load_addr = load_addr; 897 *interp_load_addr = load_addr;
887 - return ((unsigned long) interp_elf_ex->e_entry) + load_addr; 898 + return ((target_ulong) interp_elf_ex->e_entry) + load_addr;
888 } 899 }
889 900
890 /* Best attempt to load symbols from this ELF object. */ 901 /* 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,
972 struct elfhdr interp_elf_ex; 983 struct elfhdr interp_elf_ex;
973 struct exec interp_ex; 984 struct exec interp_ex;
974 int interpreter_fd = -1; /* avoid warning */ 985 int interpreter_fd = -1; /* avoid warning */
975 - unsigned long load_addr, load_bias; 986 + target_ulong load_addr, load_bias;
976 int load_addr_set = 0; 987 int load_addr_set = 0;
977 unsigned int interpreter_type = INTERPRETER_NONE; 988 unsigned int interpreter_type = INTERPRETER_NONE;
978 unsigned char ibcs2_interpreter; 989 unsigned char ibcs2_interpreter;
979 int i; 990 int i;
980 - unsigned long mapped_addr; 991 + target_ulong mapped_addr;
981 struct elf_phdr * elf_ppnt; 992 struct elf_phdr * elf_ppnt;
982 struct elf_phdr *elf_phdata; 993 struct elf_phdr *elf_phdata;
983 - unsigned long elf_bss, k, elf_brk; 994 + target_ulong elf_bss, k, elf_brk;
984 int retval; 995 int retval;
985 char * elf_interpreter; 996 char * elf_interpreter;
986 - unsigned long elf_entry, interp_load_addr = 0; 997 + target_ulong elf_entry, interp_load_addr = 0;
987 int status; 998 int status;
988 - unsigned long start_code, end_code, end_data;  
989 - unsigned long reloc_func_desc = 0;  
990 - unsigned long elf_stack; 999 + target_ulong start_code, end_code, start_data, end_data;
  1000 + target_ulong reloc_func_desc = 0;
  1001 + target_ulong elf_stack;
991 char passed_fileno[6]; 1002 char passed_fileno[6];
992 1003
993 ibcs2_interpreter = 0; 1004 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,
1043 elf_brk = 0; 1054 elf_brk = 0;
1044 1055
1045 1056
1046 - elf_stack = ~0UL; 1057 + elf_stack = ~((target_ulong)0UL);
1047 elf_interpreter = NULL; 1058 elf_interpreter = NULL;
1048 - start_code = ~0UL; 1059 + start_code = ~((target_ulong)0UL);
1049 end_code = 0; 1060 end_code = 0;
  1061 + start_data = 0;
1050 end_data = 0; 1062 end_data = 0;
1051 1063
1052 for(i=0;i < elf_ex.e_phnum; i++) { 1064 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,
1180 /* OK, This is the point of no return */ 1192 /* OK, This is the point of no return */
1181 info->end_data = 0; 1193 info->end_data = 0;
1182 info->end_code = 0; 1194 info->end_code = 0;
1183 - info->start_mmap = (unsigned long)ELF_START_MMAP; 1195 + info->start_mmap = (target_ulong)ELF_START_MMAP;
1184 info->mmap = 0; 1196 info->mmap = 0;
1185 - elf_entry = (unsigned long) elf_ex.e_entry; 1197 + elf_entry = (target_ulong) elf_ex.e_entry;
1186 1198
1187 /* Do this so that we can load the interpreter, if need be. We will 1199 /* Do this so that we can load the interpreter, if need be. We will
1188 change some of these later */ 1200 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,
1199 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { 1211 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
1200 int elf_prot = 0; 1212 int elf_prot = 0;
1201 int elf_flags = 0; 1213 int elf_flags = 0;
1202 - unsigned long error; 1214 + target_ulong error;
1203 1215
1204 if (elf_ppnt->p_type != PT_LOAD) 1216 if (elf_ppnt->p_type != PT_LOAD)
1205 continue; 1217 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,
1257 k = elf_ppnt->p_vaddr; 1269 k = elf_ppnt->p_vaddr;
1258 if (k < start_code) 1270 if (k < start_code)
1259 start_code = k; 1271 start_code = k;
  1272 + if (start_data < k)
  1273 + start_data = k;
1260 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz; 1274 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1261 if (k > elf_bss) 1275 if (k > elf_bss)
1262 elf_bss = k; 1276 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,
1273 elf_brk += load_bias; 1287 elf_brk += load_bias;
1274 start_code += load_bias; 1288 start_code += load_bias;
1275 end_code += load_bias; 1289 end_code += load_bias;
1276 - // start_data += load_bias; 1290 + start_data += load_bias;
1277 end_data += load_bias; 1291 end_data += load_bias;
1278 1292
1279 if (elf_interpreter) { 1293 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,
1289 close(interpreter_fd); 1303 close(interpreter_fd);
1290 free(elf_interpreter); 1304 free(elf_interpreter);
1291 1305
1292 - if (elf_entry == ~0UL) { 1306 + if (elf_entry == ~((target_ulong)0UL)) {
1293 printf("Unable to load interpreter\n"); 1307 printf("Unable to load interpreter\n");
1294 free(elf_phdata); 1308 free(elf_phdata);
1295 exit(-1); 1309 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,
1320 info->start_brk = info->brk = elf_brk; 1334 info->start_brk = info->brk = elf_brk;
1321 info->end_code = end_code; 1335 info->end_code = end_code;
1322 info->start_code = start_code; 1336 info->start_code = start_code;
1323 - info->start_data = end_code; 1337 + info->start_data = start_data;
1324 info->end_data = end_data; 1338 info->end_data = end_data;
1325 info->start_stack = bprm->p; 1339 info->start_stack = bprm->p;
1326 1340