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 124 /* XXX: it seems that r0 is zeroed after ! */
125 125 regs->ARM_r0 = 0;
126 126 /* For uClinux PIC binaries. */
  127 + /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
127 128 regs->ARM_r10 = infop->start_data;
128 129 }
129 130  
... ... @@ -516,8 +517,8 @@ static void bswap_sym(struct elf_sym *sym)
516 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 523 char *tmp, *tmp1, *pag = NULL;
523 524 int len, offset = 0;
... ... @@ -566,8 +567,8 @@ static unsigned long copy_elf_strings(int argc,char ** argv, void **page,
566 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 573 target_ulong stack_base, size, error;
573 574 int i;
... ... @@ -605,7 +606,7 @@ unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
605 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 611 /* page-align the start and end addresses... */
611 612 start = HOST_PAGE_ALIGN(start);
... ... @@ -624,9 +625,9 @@ static void set_brk(unsigned long start, unsigned long end)
624 625 /* We need to explicitly zero any fractional pages after the data
625 626 section (i.e. bss). This would contain the junk from the file that
626 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 632 if (elf_bss >= last_bss)
632 633 return;
... ... @@ -637,12 +638,12 @@ static void padzero(unsigned long elf_bss, unsigned long last_bss)
637 638 patch target_mmap(), but it is more complicated as the file
638 639 size must be known */
639 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 642 end_addr1 = (elf_bss + qemu_real_host_page_size - 1) &
642 643 ~(qemu_real_host_page_size - 1);
643 644 end_addr = HOST_PAGE_ALIGN(elf_bss);
644 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 647 PROT_READ|PROT_WRITE|PROT_EXEC,
647 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 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 670 target_ulong sp;
670 671 int size;
671 672 target_ulong u_platform;
672 673 const char *k_platform;
673   - const int n = sizeof(target_ulong);
  674 + const int n = sizeof(elf_addr_t);
674 675  
675 676 sp = p;
676 677 u_platform = 0;
... ... @@ -697,10 +698,20 @@ static unsigned long create_elf_tables(target_ulong p, int argc, int envc,
697 698 if (size & 15)
698 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 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 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 715 NEW_AUX_ENT (AT_NULL, 0);
705 716  
706 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 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 750 struct elf_phdr *elf_phdata = NULL;
740 751 struct elf_phdr *eppnt;
741   - unsigned long load_addr = 0;
  752 + target_ulong load_addr = 0;
742 753 int load_addr_set = 0;
743 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 757 int i;
747 758  
748 759 elf_bss = 0;
... ... @@ -756,20 +767,20 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
756 767 if ((interp_elf_ex->e_type != ET_EXEC &&
757 768 interp_elf_ex->e_type != ET_DYN) ||
758 769 !elf_check_arch(interp_elf_ex->e_machine)) {
759   - return ~0UL;
  770 + return ~((target_ulong)0UL);
760 771 }
761 772  
762 773  
763 774 /* Now read in all of the header information */
764 775  
765 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 779 elf_phdata = (struct elf_phdr *)
769 780 malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
770 781  
771 782 if (!elf_phdata)
772   - return ~0UL;
  783 + return ~((target_ulong)0UL);
773 784  
774 785 /*
775 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 788 */
778 789 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) {
779 790 free(elf_phdata);
780   - return ~0UL;
  791 + return ~((target_ulong)0UL);
781 792 }
782 793  
783 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 829 if (eppnt->p_type == PT_LOAD) {
819 830 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
820 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 835 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
825 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 850 /* Real error */
840 851 close(interpreter_fd);
841 852 free(elf_phdata);
842   - return ~0UL;
  853 + return ~((target_ulong)0UL);
843 854 }
844 855  
845 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 895 free(elf_phdata);
885 896  
886 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 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 983 struct elfhdr interp_elf_ex;
973 984 struct exec interp_ex;
974 985 int interpreter_fd = -1; /* avoid warning */
975   - unsigned long load_addr, load_bias;
  986 + target_ulong load_addr, load_bias;
976 987 int load_addr_set = 0;
977 988 unsigned int interpreter_type = INTERPRETER_NONE;
978 989 unsigned char ibcs2_interpreter;
979 990 int i;
980   - unsigned long mapped_addr;
  991 + target_ulong mapped_addr;
981 992 struct elf_phdr * elf_ppnt;
982 993 struct elf_phdr *elf_phdata;
983   - unsigned long elf_bss, k, elf_brk;
  994 + target_ulong elf_bss, k, elf_brk;
984 995 int retval;
985 996 char * elf_interpreter;
986   - unsigned long elf_entry, interp_load_addr = 0;
  997 + target_ulong elf_entry, interp_load_addr = 0;
987 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 1002 char passed_fileno[6];
992 1003  
993 1004 ibcs2_interpreter = 0;
... ... @@ -1043,10 +1054,11 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
1043 1054 elf_brk = 0;
1044 1055  
1045 1056  
1046   - elf_stack = ~0UL;
  1057 + elf_stack = ~((target_ulong)0UL);
1047 1058 elf_interpreter = NULL;
1048   - start_code = ~0UL;
  1059 + start_code = ~((target_ulong)0UL);
1049 1060 end_code = 0;
  1061 + start_data = 0;
1050 1062 end_data = 0;
1051 1063  
1052 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 1192 /* OK, This is the point of no return */
1181 1193 info->end_data = 0;
1182 1194 info->end_code = 0;
1183   - info->start_mmap = (unsigned long)ELF_START_MMAP;
  1195 + info->start_mmap = (target_ulong)ELF_START_MMAP;
1184 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 1199 /* Do this so that we can load the interpreter, if need be. We will
1188 1200 change some of these later */
... ... @@ -1199,7 +1211,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
1199 1211 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
1200 1212 int elf_prot = 0;
1201 1213 int elf_flags = 0;
1202   - unsigned long error;
  1214 + target_ulong error;
1203 1215  
1204 1216 if (elf_ppnt->p_type != PT_LOAD)
1205 1217 continue;
... ... @@ -1257,6 +1269,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
1257 1269 k = elf_ppnt->p_vaddr;
1258 1270 if (k < start_code)
1259 1271 start_code = k;
  1272 + if (start_data < k)
  1273 + start_data = k;
1260 1274 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
1261 1275 if (k > elf_bss)
1262 1276 elf_bss = k;
... ... @@ -1273,7 +1287,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
1273 1287 elf_brk += load_bias;
1274 1288 start_code += load_bias;
1275 1289 end_code += load_bias;
1276   - // start_data += load_bias;
  1290 + start_data += load_bias;
1277 1291 end_data += load_bias;
1278 1292  
1279 1293 if (elf_interpreter) {
... ... @@ -1289,7 +1303,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
1289 1303 close(interpreter_fd);
1290 1304 free(elf_interpreter);
1291 1305  
1292   - if (elf_entry == ~0UL) {
  1306 + if (elf_entry == ~((target_ulong)0UL)) {
1293 1307 printf("Unable to load interpreter\n");
1294 1308 free(elf_phdata);
1295 1309 exit(-1);
... ... @@ -1320,7 +1334,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
1320 1334 info->start_brk = info->brk = elf_brk;
1321 1335 info->end_code = end_code;
1322 1336 info->start_code = start_code;
1323   - info->start_data = end_code;
  1337 + info->start_data = start_data;
1324 1338 info->end_data = end_data;
1325 1339 info->start_stack = bprm->p;
1326 1340  
... ...