Revision 992f48a0 linux-user/elfload.c
b/linux-user/elfload.c | ||
---|---|---|
172 | 172 |
|
173 | 173 |
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) |
174 | 174 |
{ |
175 |
target_long stack = infop->start_stack;
|
|
175 |
abi_long stack = infop->start_stack;
|
|
176 | 176 |
memset(regs, 0, sizeof(*regs)); |
177 | 177 |
regs->ARM_cpsr = 0x10; |
178 | 178 |
if (infop->entry & 1) |
... | ... | |
214 | 214 |
|
215 | 215 |
#define ELF_START_MMAP 0x80000000 |
216 | 216 |
|
217 |
#ifndef TARGET_ABI32 |
|
217 | 218 |
#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS ) |
219 |
#else |
|
220 |
#define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC ) |
|
221 |
#endif |
|
218 | 222 |
|
219 | 223 |
#define ELF_CLASS ELFCLASS64 |
220 | 224 |
#define ELF_DATA ELFDATA2MSB |
... | ... | |
224 | 228 |
|
225 | 229 |
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) |
226 | 230 |
{ |
231 |
#ifndef TARGET_ABI32 |
|
227 | 232 |
regs->tstate = 0; |
233 |
#endif |
|
228 | 234 |
regs->pc = infop->entry; |
229 | 235 |
regs->npc = regs->pc + 4; |
230 | 236 |
regs->y = 0; |
237 |
#ifdef TARGET_ABI32 |
|
238 |
regs->u_regs[14] = infop->start_stack - 16 * 4; |
|
239 |
#else |
|
231 | 240 |
if (personality(infop->personality) == PER_LINUX32) |
232 | 241 |
regs->u_regs[14] = infop->start_stack - 16 * 4; |
233 | 242 |
else |
234 | 243 |
regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS; |
244 |
#endif |
|
235 | 245 |
} |
236 | 246 |
|
237 | 247 |
#else |
... | ... | |
313 | 323 |
|
314 | 324 |
static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop) |
315 | 325 |
{ |
316 |
target_ulong pos = infop->start_stack;
|
|
317 |
target_ulong tmp;
|
|
326 |
abi_ulong pos = infop->start_stack;
|
|
327 |
abi_ulong tmp;
|
|
318 | 328 |
#ifdef TARGET_PPC64 |
319 |
target_ulong entry, toc;
|
|
329 |
abi_ulong entry, toc;
|
|
320 | 330 |
#endif |
321 | 331 |
|
322 | 332 |
_regs->msr = 1 << MSR_PR; /* Set user mode */ |
... | ... | |
333 | 343 |
* execution of PPC BSD programs. |
334 | 344 |
*/ |
335 | 345 |
_regs->gpr[3] = tgetl(pos); |
336 |
pos += sizeof(target_ulong);
|
|
346 |
pos += sizeof(abi_ulong);
|
|
337 | 347 |
_regs->gpr[4] = pos; |
338 |
for (tmp = 1; tmp != 0; pos += sizeof(target_ulong))
|
|
348 |
for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong))
|
|
339 | 349 |
tmp = ldl(pos); |
340 | 350 |
_regs->gpr[5] = pos; |
341 | 351 |
} |
... | ... | |
475 | 485 |
#define ELF_HWCAP 0 |
476 | 486 |
#endif |
477 | 487 |
|
478 |
#ifdef OVERRIDE_ELF_CLASS
|
|
488 |
#ifdef TARGET_ABI32
|
|
479 | 489 |
#undef ELF_CLASS |
480 |
#define ELF_CLASS OVERRIDE_ELF_CLASS
|
|
490 |
#define ELF_CLASS ELFCLASS32
|
|
481 | 491 |
#undef bswaptls |
482 | 492 |
#define bswaptls(ptr) bswap32s(ptr) |
483 | 493 |
#endif |
... | ... | |
588 | 598 |
* to be put directly into the top of new user memory. |
589 | 599 |
* |
590 | 600 |
*/ |
591 |
static target_ulong copy_elf_strings(int argc,char ** argv, void **page,
|
|
592 |
target_ulong p)
|
|
601 |
static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
|
|
602 |
abi_ulong p)
|
|
593 | 603 |
{ |
594 | 604 |
char *tmp, *tmp1, *pag = NULL; |
595 | 605 |
int len, offset = 0; |
... | ... | |
638 | 648 |
return p; |
639 | 649 |
} |
640 | 650 |
|
641 |
static target_ulong setup_arg_pages(target_ulong p, struct linux_binprm *bprm,
|
|
642 |
struct image_info *info)
|
|
651 |
static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
|
|
652 |
struct image_info *info) |
|
643 | 653 |
{ |
644 |
target_ulong stack_base, size, error;
|
|
654 |
abi_ulong stack_base, size, error;
|
|
645 | 655 |
int i; |
646 | 656 |
|
647 | 657 |
/* Create enough stack to hold everything. If we don't use |
... | ... | |
677 | 687 |
return p; |
678 | 688 |
} |
679 | 689 |
|
680 |
static void set_brk(target_ulong start, target_ulong end)
|
|
690 |
static void set_brk(abi_ulong start, abi_ulong end)
|
|
681 | 691 |
{ |
682 | 692 |
/* page-align the start and end addresses... */ |
683 | 693 |
start = HOST_PAGE_ALIGN(start); |
... | ... | |
696 | 706 |
/* We need to explicitly zero any fractional pages after the data |
697 | 707 |
section (i.e. bss). This would contain the junk from the file that |
698 | 708 |
should not be in memory. */ |
699 |
static void padzero(target_ulong elf_bss, target_ulong last_bss)
|
|
709 |
static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
|
|
700 | 710 |
{ |
701 |
target_ulong nbyte;
|
|
711 |
abi_ulong nbyte;
|
|
702 | 712 |
|
703 | 713 |
if (elf_bss >= last_bss) |
704 | 714 |
return; |
... | ... | |
709 | 719 |
patch target_mmap(), but it is more complicated as the file |
710 | 720 |
size must be known */ |
711 | 721 |
if (qemu_real_host_page_size < qemu_host_page_size) { |
712 |
target_ulong end_addr, end_addr1;
|
|
722 |
abi_ulong end_addr, end_addr1;
|
|
713 | 723 |
end_addr1 = (elf_bss + qemu_real_host_page_size - 1) & |
714 | 724 |
~(qemu_real_host_page_size - 1); |
715 | 725 |
end_addr = HOST_PAGE_ALIGN(elf_bss); |
... | ... | |
731 | 741 |
} |
732 | 742 |
|
733 | 743 |
|
734 |
static target_ulong create_elf_tables(target_ulong p, int argc, int envc,
|
|
735 |
struct elfhdr * exec,
|
|
736 |
target_ulong load_addr,
|
|
737 |
target_ulong load_bias,
|
|
738 |
target_ulong interp_load_addr, int ibcs,
|
|
739 |
struct image_info *info)
|
|
744 |
static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
|
745 |
struct elfhdr * exec, |
|
746 |
abi_ulong load_addr,
|
|
747 |
abi_ulong load_bias,
|
|
748 |
abi_ulong interp_load_addr, int ibcs,
|
|
749 |
struct image_info *info) |
|
740 | 750 |
{ |
741 |
target_ulong sp;
|
|
751 |
abi_ulong sp;
|
|
742 | 752 |
int size; |
743 |
target_ulong u_platform;
|
|
753 |
abi_ulong u_platform;
|
|
744 | 754 |
const char *k_platform; |
745 | 755 |
const int n = sizeof(elf_addr_t); |
746 | 756 |
|
... | ... | |
756 | 766 |
/* |
757 | 767 |
* Force 16 byte _final_ alignment here for generality. |
758 | 768 |
*/ |
759 |
sp = sp &~ (target_ulong)15;
|
|
769 |
sp = sp &~ (abi_ulong)15;
|
|
760 | 770 |
size = (DLINFO_ITEMS + 1) * 2; |
761 | 771 |
if (k_platform) |
762 | 772 |
size += 2; |
... | ... | |
786 | 796 |
NEW_AUX_ENT (AT_NULL, 0); |
787 | 797 |
|
788 | 798 |
/* There must be exactly DLINFO_ITEMS entries here. */ |
789 |
NEW_AUX_ENT(AT_PHDR, (target_ulong)(load_addr + exec->e_phoff));
|
|
790 |
NEW_AUX_ENT(AT_PHENT, (target_ulong)(sizeof (struct elf_phdr)));
|
|
791 |
NEW_AUX_ENT(AT_PHNUM, (target_ulong)(exec->e_phnum));
|
|
792 |
NEW_AUX_ENT(AT_PAGESZ, (target_ulong)(TARGET_PAGE_SIZE));
|
|
793 |
NEW_AUX_ENT(AT_BASE, (target_ulong)(interp_load_addr));
|
|
794 |
NEW_AUX_ENT(AT_FLAGS, (target_ulong)0);
|
|
799 |
NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff));
|
|
800 |
NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));
|
|
801 |
NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));
|
|
802 |
NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE));
|
|
803 |
NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr));
|
|
804 |
NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
|
|
795 | 805 |
NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry); |
796 |
NEW_AUX_ENT(AT_UID, (target_ulong) getuid());
|
|
797 |
NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid());
|
|
798 |
NEW_AUX_ENT(AT_GID, (target_ulong) getgid());
|
|
799 |
NEW_AUX_ENT(AT_EGID, (target_ulong) getegid());
|
|
800 |
NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP);
|
|
806 |
NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());
|
|
807 |
NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());
|
|
808 |
NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());
|
|
809 |
NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
|
|
810 |
NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
|
|
801 | 811 |
if (k_platform) |
802 | 812 |
NEW_AUX_ENT(AT_PLATFORM, u_platform); |
803 | 813 |
#ifdef ARCH_DLINFO |
... | ... | |
814 | 824 |
} |
815 | 825 |
|
816 | 826 |
|
817 |
static target_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
|
|
818 |
int interpreter_fd,
|
|
819 |
target_ulong *interp_load_addr)
|
|
827 |
static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
|
|
828 |
int interpreter_fd, |
|
829 |
abi_ulong *interp_load_addr)
|
|
820 | 830 |
{ |
821 | 831 |
struct elf_phdr *elf_phdata = NULL; |
822 | 832 |
struct elf_phdr *eppnt; |
823 |
target_ulong load_addr = 0;
|
|
833 |
abi_ulong load_addr = 0;
|
|
824 | 834 |
int load_addr_set = 0; |
825 | 835 |
int retval; |
826 |
target_ulong last_bss, elf_bss;
|
|
827 |
target_ulong error;
|
|
836 |
abi_ulong last_bss, elf_bss;
|
|
837 |
abi_ulong error;
|
|
828 | 838 |
int i; |
829 | 839 |
|
830 | 840 |
elf_bss = 0; |
... | ... | |
838 | 848 |
if ((interp_elf_ex->e_type != ET_EXEC && |
839 | 849 |
interp_elf_ex->e_type != ET_DYN) || |
840 | 850 |
!elf_check_arch(interp_elf_ex->e_machine)) { |
841 |
return ~((target_ulong)0UL);
|
|
851 |
return ~((abi_ulong)0UL);
|
|
842 | 852 |
} |
843 | 853 |
|
844 | 854 |
|
845 | 855 |
/* Now read in all of the header information */ |
846 | 856 |
|
847 | 857 |
if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE) |
848 |
return ~(target_ulong)0UL;
|
|
858 |
return ~(abi_ulong)0UL;
|
|
849 | 859 |
|
850 | 860 |
elf_phdata = (struct elf_phdr *) |
851 | 861 |
malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); |
852 | 862 |
|
853 | 863 |
if (!elf_phdata) |
854 |
return ~((target_ulong)0UL);
|
|
864 |
return ~((abi_ulong)0UL);
|
|
855 | 865 |
|
856 | 866 |
/* |
857 | 867 |
* If the size of this structure has changed, then punt, since |
... | ... | |
859 | 869 |
*/ |
860 | 870 |
if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) { |
861 | 871 |
free(elf_phdata); |
862 |
return ~((target_ulong)0UL);
|
|
872 |
return ~((abi_ulong)0UL);
|
|
863 | 873 |
} |
864 | 874 |
|
865 | 875 |
retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET); |
... | ... | |
900 | 910 |
if (eppnt->p_type == PT_LOAD) { |
901 | 911 |
int elf_type = MAP_PRIVATE | MAP_DENYWRITE; |
902 | 912 |
int elf_prot = 0; |
903 |
target_ulong vaddr = 0;
|
|
904 |
target_ulong k;
|
|
913 |
abi_ulong vaddr = 0;
|
|
914 |
abi_ulong k;
|
|
905 | 915 |
|
906 | 916 |
if (eppnt->p_flags & PF_R) elf_prot = PROT_READ; |
907 | 917 |
if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; |
... | ... | |
921 | 931 |
/* Real error */ |
922 | 932 |
close(interpreter_fd); |
923 | 933 |
free(elf_phdata); |
924 |
return ~((target_ulong)0UL);
|
|
934 |
return ~((abi_ulong)0UL);
|
|
925 | 935 |
} |
926 | 936 |
|
927 | 937 |
if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { |
... | ... | |
966 | 976 |
free(elf_phdata); |
967 | 977 |
|
968 | 978 |
*interp_load_addr = load_addr; |
969 |
return ((target_ulong) interp_elf_ex->e_entry) + load_addr;
|
|
979 |
return ((abi_ulong) interp_elf_ex->e_entry) + load_addr;
|
|
970 | 980 |
} |
971 | 981 |
|
972 | 982 |
/* Best attempt to load symbols from this ELF object. */ |
... | ... | |
1054 | 1064 |
struct elfhdr interp_elf_ex; |
1055 | 1065 |
struct exec interp_ex; |
1056 | 1066 |
int interpreter_fd = -1; /* avoid warning */ |
1057 |
target_ulong load_addr, load_bias;
|
|
1067 |
abi_ulong load_addr, load_bias;
|
|
1058 | 1068 |
int load_addr_set = 0; |
1059 | 1069 |
unsigned int interpreter_type = INTERPRETER_NONE; |
1060 | 1070 |
unsigned char ibcs2_interpreter; |
1061 | 1071 |
int i; |
1062 |
target_ulong mapped_addr;
|
|
1072 |
abi_ulong mapped_addr;
|
|
1063 | 1073 |
struct elf_phdr * elf_ppnt; |
1064 | 1074 |
struct elf_phdr *elf_phdata; |
1065 |
target_ulong elf_bss, k, elf_brk;
|
|
1075 |
abi_ulong elf_bss, k, elf_brk;
|
|
1066 | 1076 |
int retval; |
1067 | 1077 |
char * elf_interpreter; |
1068 |
target_ulong elf_entry, interp_load_addr = 0;
|
|
1078 |
abi_ulong elf_entry, interp_load_addr = 0;
|
|
1069 | 1079 |
int status; |
1070 |
target_ulong start_code, end_code, start_data, end_data;
|
|
1071 |
target_ulong reloc_func_desc = 0;
|
|
1072 |
target_ulong elf_stack;
|
|
1080 |
abi_ulong start_code, end_code, start_data, end_data;
|
|
1081 |
abi_ulong reloc_func_desc = 0;
|
|
1082 |
abi_ulong elf_stack;
|
|
1073 | 1083 |
char passed_fileno[6]; |
1074 | 1084 |
|
1075 | 1085 |
ibcs2_interpreter = 0; |
... | ... | |
1125 | 1135 |
elf_brk = 0; |
1126 | 1136 |
|
1127 | 1137 |
|
1128 |
elf_stack = ~((target_ulong)0UL);
|
|
1138 |
elf_stack = ~((abi_ulong)0UL);
|
|
1129 | 1139 |
elf_interpreter = NULL; |
1130 |
start_code = ~((target_ulong)0UL);
|
|
1140 |
start_code = ~((abi_ulong)0UL);
|
|
1131 | 1141 |
end_code = 0; |
1132 | 1142 |
start_data = 0; |
1133 | 1143 |
end_data = 0; |
... | ... | |
1263 | 1273 |
/* OK, This is the point of no return */ |
1264 | 1274 |
info->end_data = 0; |
1265 | 1275 |
info->end_code = 0; |
1266 |
info->start_mmap = (target_ulong)ELF_START_MMAP;
|
|
1276 |
info->start_mmap = (abi_ulong)ELF_START_MMAP;
|
|
1267 | 1277 |
info->mmap = 0; |
1268 |
elf_entry = (target_ulong) elf_ex.e_entry;
|
|
1278 |
elf_entry = (abi_ulong) elf_ex.e_entry;
|
|
1269 | 1279 |
|
1270 | 1280 |
/* Do this so that we can load the interpreter, if need be. We will |
1271 | 1281 |
change some of these later */ |
... | ... | |
1282 | 1292 |
for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { |
1283 | 1293 |
int elf_prot = 0; |
1284 | 1294 |
int elf_flags = 0; |
1285 |
target_ulong error;
|
|
1295 |
abi_ulong error;
|
|
1286 | 1296 |
|
1287 | 1297 |
if (elf_ppnt->p_type != PT_LOAD) |
1288 | 1298 |
continue; |
... | ... | |
1374 | 1384 |
close(interpreter_fd); |
1375 | 1385 |
free(elf_interpreter); |
1376 | 1386 |
|
1377 |
if (elf_entry == ~((target_ulong)0UL)) {
|
|
1387 |
if (elf_entry == ~((abi_ulong)0UL)) {
|
|
1378 | 1388 |
printf("Unable to load interpreter\n"); |
1379 | 1389 |
free(elf_phdata); |
1380 | 1390 |
exit(-1); |
Also available in: Unified diff