dl-startup.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Program to load an ELF binary on a linux system, and run it
  4. * after resolving ELF shared library symbols
  5. *
  6. * Copyright (C) 2000-2004 by Erik Andersen <andersen@codpoet.org>
  7. * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
  8. * David Engel, Hongjiu Lu and Mitch D'Souza
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. The name of the above contributors may not be
  16. * used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. */
  31. /*
  32. * The main trick with this program is that initially, we ourselves are not
  33. * dynamicly linked. This means that we cannot access any global variables or
  34. * call any functions. No globals initially, since the Global Offset Table
  35. * (GOT) is initialized by the linker assuming a virtual address of 0, and no
  36. * function calls initially since the Procedure Linkage Table (PLT) is not yet
  37. * initialized.
  38. *
  39. * There are additional initial restrictions - we cannot use large switch
  40. * statements, since the compiler generates tables of addresses and jumps
  41. * through them. We cannot use normal syscall stubs, because these all
  42. * reference the errno global variable which is not yet initialized. We _can_
  43. * use all of the local stack variables that we want. We _can_ use inline
  44. * functions, because these do not transfer control to a new address, but they
  45. * must be static so that they are not exported from the modules.
  46. *
  47. * Life is further complicated by the fact that initially we do not want to do
  48. * a complete dynamic linking. We want to allow the user to supply new
  49. * functions to override symbols (i.e. weak symbols and/or LD_PRELOAD). So
  50. * initially, we only perform relocations for variables that start with "_dl_"
  51. * since ANSI specifies that the user is not supposed to redefine any of these
  52. * variables.
  53. *
  54. * Fortunately, the linker itself leaves a few clues lying around, and when the
  55. * kernel starts the image, there are a few further clues. First of all, there
  56. * is Auxiliary Vector Table information sitting on which is provided to us by
  57. * the kernel, and which includes information about the load address that the
  58. * program interpreter was loaded at, the number of sections, the address the
  59. * application was loaded at and so forth. Here this information is stored in
  60. * the array auxvt. For details see linux/fs/binfmt_elf.c where it calls
  61. * NEW_AUX_ENT() a bunch of time....
  62. *
  63. * Next, we need to find the GOT. On most arches there is a register pointing
  64. * to the GOT, but just in case (and for new ports) I've added some (slow) C
  65. * code to locate the GOT for you.
  66. *
  67. * This code was originally written for SVr4, and there the kernel would load
  68. * all text pages R/O, so they needed to call mprotect a zillion times to mark
  69. * all text pages as writable so dynamic linking would succeed. Then when they
  70. * were done, they would change the protections for all the pages back again.
  71. * Well, under Linux everything is loaded writable (since Linux does copy on
  72. * write anyways) so all the mprotect stuff has been disabled.
  73. *
  74. * Initially, we do not have access to _dl_malloc since we can't yet make
  75. * function calls, so we mmap one page to use as scratch space. Later on, when
  76. * we can call _dl_malloc we reuse this this memory. This is also beneficial,
  77. * since we do not want to use the same memory pool as malloc anyway - esp if
  78. * the user redefines malloc to do something funky.
  79. *
  80. * Our first task is to perform a minimal linking so that we can call other
  81. * portions of the dynamic linker. Once we have done this, we then build the
  82. * list of modules that the application requires, using LD_LIBRARY_PATH if this
  83. * is not a suid program (/usr/lib otherwise). Once this is done, we can do
  84. * the dynamic linking as required, and we must omit the things we did to get
  85. * the dynamic linker up and running in the first place. After we have done
  86. * this, we just have a few housekeeping chores and we can transfer control to
  87. * the user's application.
  88. */
  89. #include "ldso.h"
  90. /* Some arches may need to override this in dl-startup.h */
  91. #define ELFMAGIC ELFMAG
  92. /* This is a poor man's malloc, used prior to resolving our internal poor man's malloc */
  93. #define LD_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE)) ; REALIGN();
  94. /* Make sure that the malloc buffer is aligned on 4 byte boundary. For 64 bit
  95. * platforms we may need to increase this to 8, but this is good enough for
  96. * now. This is typically called after LD_MALLOC. */
  97. #define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
  98. /* Pull in all the arch specific stuff */
  99. #include "dl-startup.h"
  100. /* Static declarations */
  101. int (*_dl_elf_main) (int, char **, char **);
  102. /* When we enter this piece of code, the program stack looks like this:
  103. argc argument counter (integer)
  104. argv[0] program name (pointer)
  105. argv[1...N] program args (pointers)
  106. argv[argc-1] end of args (integer)
  107. NULL
  108. env[0...N] environment variables (pointers)
  109. NULL
  110. auxvt[0...N] Auxiliary Vector Table elements (mixed types)
  111. */
  112. DL_BOOT(unsigned long args)
  113. {
  114. unsigned int argc;
  115. char **argv, **envp;
  116. unsigned long load_addr;
  117. unsigned long *got;
  118. unsigned long *aux_dat;
  119. int goof = 0;
  120. ElfW(Ehdr) *header;
  121. struct elf_resolve *tpnt;
  122. struct elf_resolve *app_tpnt;
  123. Elf32_auxv_t auxvt[AT_EGID + 1];
  124. unsigned char *malloc_buffer, *mmap_zero;
  125. Elf32_Dyn *dpnt;
  126. unsigned long *hash_addr;
  127. struct r_debug *debug_addr = NULL;
  128. int indx;
  129. #if defined(__i386__)
  130. int status = 0;
  131. #endif
  132. /* WARNING! -- we cannot make _any_ funtion calls until we have
  133. * taken care of fixing up our own relocations. Making static
  134. * inline calls is ok, but _no_ function calls. Not yet
  135. * anyways. */
  136. /* First obtain the information on the stack that tells us more about
  137. what binary is loaded, where it is loaded, etc, etc */
  138. GET_ARGV(aux_dat, args);
  139. #if defined (__arm__) || defined (__mips__) || defined (__cris__)
  140. aux_dat += 1;
  141. #endif
  142. argc = *(aux_dat - 1);
  143. argv = (char **) aux_dat;
  144. aux_dat += argc; /* Skip over the argv pointers */
  145. aux_dat++; /* Skip over NULL at end of argv */
  146. envp = (char **) aux_dat;
  147. while (*aux_dat)
  148. aux_dat++; /* Skip over the envp pointers */
  149. aux_dat++; /* Skip over NULL at end of envp */
  150. /* Place -1 here as a checkpoint. We later check if it was changed
  151. * when we read in the auxvt */
  152. auxvt[AT_UID].a_type = -1;
  153. /* The junk on the stack immediately following the environment is
  154. * the Auxiliary Vector Table. Read out the elements of the auxvt,
  155. * sort and store them in auxvt for later use. */
  156. while (*aux_dat) {
  157. Elf32_auxv_t *auxv_entry = (Elf32_auxv_t *) aux_dat;
  158. if (auxv_entry->a_type <= AT_EGID) {
  159. _dl_memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
  160. }
  161. aux_dat += 2;
  162. }
  163. /* locate the ELF header. We need this done as soon as possible
  164. * (esp since SEND_STDERR() needs this on some platforms... */
  165. load_addr = auxvt[AT_BASE].a_un.a_val;
  166. header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
  167. /* Check the ELF header to make sure everything looks ok. */
  168. if (!header || header->e_ident[EI_CLASS] != ELFCLASS32 ||
  169. header->e_ident[EI_VERSION] != EV_CURRENT
  170. #if !defined(__powerpc__) && !defined(__mips__) && !defined(__sh__)
  171. || _dl_strncmp((void *) header, ELFMAGIC, SELFMAG) != 0
  172. #else
  173. || header->e_ident[EI_MAG0] != ELFMAG0
  174. || header->e_ident[EI_MAG1] != ELFMAG1
  175. || header->e_ident[EI_MAG2] != ELFMAG2
  176. || header->e_ident[EI_MAG3] != ELFMAG3
  177. #endif
  178. ) {
  179. SEND_STDERR("Invalid ELF header\n");
  180. _dl_exit(0);
  181. }
  182. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  183. SEND_STDERR("ELF header=");
  184. SEND_ADDRESS_STDERR(load_addr, 1);
  185. #endif
  186. /* Locate the global offset table. Since this code must be PIC
  187. * we can take advantage of the magic offset register, if we
  188. * happen to know what that is for this architecture. If not,
  189. * we can always read stuff out of the ELF file to find it... */
  190. #if defined(__i386__)
  191. __asm__("\tmovl %%ebx,%0\n\t":"=a"(got));
  192. #elif defined(__m68k__)
  193. __asm__("movel %%a5,%0":"=g"(got));
  194. #elif defined(__sparc__)
  195. __asm__("\tmov %%l7,%0\n\t":"=r"(got));
  196. #elif defined(__arm__)
  197. __asm__("\tmov %0, r10\n\t":"=r"(got));
  198. #elif defined(__powerpc__)
  199. __asm__("\tbl _GLOBAL_OFFSET_TABLE_-4@local\n\t":"=l"(got));
  200. #elif defined(__mips__)
  201. __asm__("\tmove %0, $28\n\tsubu %0,%0,0x7ff0\n\t":"=r"(got));
  202. #elif defined(__sh__) && !defined(__SH5__)
  203. __asm__(
  204. " mov.l 1f, %0\n"
  205. " mova 1f, r0\n"
  206. " bra 2f\n"
  207. " add r0, %0\n"
  208. " .balign 4\n"
  209. "1: .long _GLOBAL_OFFSET_TABLE_\n"
  210. "2:" : "=r" (got) : : "r0");
  211. #elif defined(__cris__)
  212. __asm__("\tmove.d $pc,%0\n\tsub.d .:GOTOFF,%0\n\t":"=r"(got));
  213. #else
  214. /* Do things the slow way in C */
  215. {
  216. unsigned long tx_reloc;
  217. Elf32_Dyn *dynamic = NULL;
  218. Elf32_Shdr *shdr;
  219. Elf32_Phdr *pt_load;
  220. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  221. SEND_STDERR("Finding the GOT using C code to read the ELF file\n");
  222. #endif
  223. /* Find where the dynamic linking information section is hiding */
  224. shdr = (Elf32_Shdr *) (header->e_shoff + (char *) header);
  225. for (indx = header->e_shnum; --indx >= 0; ++shdr) {
  226. if (shdr->sh_type == SHT_DYNAMIC) {
  227. goto found_dynamic;
  228. }
  229. }
  230. SEND_STDERR("missing dynamic linking information section \n");
  231. _dl_exit(0);
  232. found_dynamic:
  233. dynamic = (Elf32_Dyn *) (shdr->sh_offset + (char *) header);
  234. /* Find where PT_LOAD is hiding */
  235. pt_load = (Elf32_Phdr *) (header->e_phoff + (char *) header);
  236. for (indx = header->e_phnum; --indx >= 0; ++pt_load) {
  237. if (pt_load->p_type == PT_LOAD) {
  238. goto found_pt_load;
  239. }
  240. }
  241. SEND_STDERR("missing loadable program segment\n");
  242. _dl_exit(0);
  243. found_pt_load:
  244. /* Now (finally) find where DT_PLTGOT is hiding */
  245. tx_reloc = pt_load->p_vaddr - pt_load->p_offset;
  246. for (; DT_NULL != dynamic->d_tag; ++dynamic) {
  247. if (dynamic->d_tag == DT_PLTGOT) {
  248. goto found_got;
  249. }
  250. }
  251. SEND_STDERR("missing global offset table\n");
  252. _dl_exit(0);
  253. found_got:
  254. got = (unsigned long *) (dynamic->d_un.d_val - tx_reloc +
  255. (char *) header);
  256. }
  257. #endif
  258. /* Now, finally, fix up the location of the dynamic stuff */
  259. dpnt = (Elf32_Dyn *) (*got + load_addr);
  260. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  261. SEND_STDERR("First Dynamic section entry=");
  262. SEND_ADDRESS_STDERR(dpnt, 1);
  263. #endif
  264. /* Call mmap to get a page of writable memory that can be used
  265. * for _dl_malloc throughout the shared lib loader. */
  266. mmap_zero = malloc_buffer = _dl_mmap((void *) 0, PAGE_SIZE,
  267. PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
  268. if (_dl_mmap_check_error(mmap_zero)) {
  269. SEND_STDERR("dl_boot: mmap of a spare page failed!\n");
  270. _dl_exit(13);
  271. }
  272. tpnt = LD_MALLOC(sizeof(struct elf_resolve));
  273. _dl_memset(tpnt, 0, sizeof(struct elf_resolve));
  274. app_tpnt = LD_MALLOC(sizeof(struct elf_resolve));
  275. _dl_memset(app_tpnt, 0, sizeof(struct elf_resolve));
  276. #ifdef __UCLIBC_PIE_SUPPORT__
  277. /* Find the runtime load address of the main executable, this may be
  278. * different from what the ELF header says for ET_DYN/PIE executables.
  279. */
  280. {
  281. ElfW(Phdr) *ppnt;
  282. int i;
  283. ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
  284. for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
  285. if (ppnt->p_type == PT_PHDR) {
  286. app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr);
  287. break;
  288. }
  289. }
  290. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  291. SEND_STDERR("app_tpnt->loadaddr=");
  292. SEND_ADDRESS_STDERR(app_tpnt->loadaddr, 1);
  293. #endif
  294. #endif
  295. /*
  296. * This is used by gdb to locate the chain of shared libraries that are currently loaded.
  297. */
  298. debug_addr = LD_MALLOC(sizeof(struct r_debug));
  299. _dl_memset(debug_addr, 0, sizeof(struct r_debug));
  300. /* OK, that was easy. Next scan the DYNAMIC section of the image.
  301. We are only doing ourself right now - we will have to do the rest later */
  302. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  303. SEND_STDERR("scanning DYNAMIC section\n");
  304. #endif
  305. while (dpnt->d_tag) {
  306. #if defined(__mips__)
  307. if (dpnt->d_tag == DT_MIPS_GOTSYM)
  308. tpnt->mips_gotsym = (unsigned long) dpnt->d_un.d_val;
  309. if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
  310. tpnt->mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
  311. if (dpnt->d_tag == DT_MIPS_SYMTABNO)
  312. tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val;
  313. #endif
  314. if (dpnt->d_tag < 24) {
  315. tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
  316. if (dpnt->d_tag == DT_TEXTREL) {
  317. tpnt->dynamic_info[DT_TEXTREL] = 1;
  318. }
  319. }
  320. dpnt++;
  321. }
  322. {
  323. ElfW(Phdr) *ppnt;
  324. int i;
  325. ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
  326. for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
  327. if (ppnt->p_type == PT_DYNAMIC) {
  328. #ifndef __UCLIBC_PIE_SUPPORT__
  329. dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
  330. #else
  331. dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + app_tpnt->loadaddr);
  332. #endif
  333. while (dpnt->d_tag) {
  334. #if defined(__mips__)
  335. if (dpnt->d_tag == DT_MIPS_GOTSYM)
  336. app_tpnt->mips_gotsym =
  337. (unsigned long) dpnt->d_un.d_val;
  338. if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
  339. app_tpnt->mips_local_gotno =
  340. (unsigned long) dpnt->d_un.d_val;
  341. if (dpnt->d_tag == DT_MIPS_SYMTABNO)
  342. app_tpnt->mips_symtabno =
  343. (unsigned long) dpnt->d_un.d_val;
  344. if (dpnt->d_tag > DT_JMPREL) {
  345. dpnt++;
  346. continue;
  347. }
  348. app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
  349. #warning "Debugging threads on mips won't work till someone fixes this..."
  350. #if 0
  351. if (dpnt->d_tag == DT_DEBUG) {
  352. dpnt->d_un.d_val = (unsigned long) debug_addr;
  353. }
  354. #endif
  355. #else
  356. if (dpnt->d_tag > DT_JMPREL) {
  357. dpnt++;
  358. continue;
  359. }
  360. app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
  361. if (dpnt->d_tag == DT_DEBUG) {
  362. dpnt->d_un.d_val = (unsigned long) debug_addr;
  363. }
  364. #endif
  365. if (dpnt->d_tag == DT_TEXTREL)
  366. app_tpnt->dynamic_info[DT_TEXTREL] = 1;
  367. dpnt++;
  368. }
  369. }
  370. }
  371. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  372. SEND_STDERR("done scanning DYNAMIC section\n");
  373. #endif
  374. /* Get some more of the information that we will need to dynamicly link
  375. this module to itself */
  376. hash_addr = (unsigned long *) (tpnt->dynamic_info[DT_HASH] + load_addr);
  377. tpnt->nbucket = *hash_addr++;
  378. tpnt->nchain = *hash_addr++;
  379. tpnt->elf_buckets = hash_addr;
  380. hash_addr += tpnt->nbucket;
  381. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  382. SEND_STDERR("done grabbing link information\n");
  383. #endif
  384. #ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
  385. /* Ugly, ugly. We need to call mprotect to change the protection of
  386. the text pages so that we can do the dynamic linking. We can set the
  387. protection back again once we are done */
  388. {
  389. ElfW(Phdr) *ppnt;
  390. int i;
  391. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  392. SEND_STDERR("calling mprotect on the shared library/dynamic linker\n");
  393. #endif
  394. /* First cover the shared library/dynamic linker. */
  395. if (tpnt->dynamic_info[DT_TEXTREL]) {
  396. header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
  397. ppnt = (ElfW(Phdr) *) ((int)auxvt[AT_BASE].a_un.a_ptr +
  398. header->e_phoff);
  399. for (i = 0; i < header->e_phnum; i++, ppnt++) {
  400. if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) {
  401. _dl_mprotect((void *) (load_addr + (ppnt->p_vaddr & PAGE_ALIGN)),
  402. (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz,
  403. PROT_READ | PROT_WRITE | PROT_EXEC);
  404. }
  405. }
  406. }
  407. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  408. SEND_STDERR("calling mprotect on the application program\n");
  409. #endif
  410. /* Now cover the application program. */
  411. if (app_tpnt->dynamic_info[DT_TEXTREL]) {
  412. ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
  413. for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
  414. if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
  415. #ifndef __UCLIBC_PIE_SUPPORT__
  416. _dl_mprotect((void *) (ppnt->p_vaddr & PAGE_ALIGN),
  417. (ppnt->p_vaddr & ADDR_ALIGN) +
  418. (unsigned long) ppnt->p_filesz,
  419. PROT_READ | PROT_WRITE | PROT_EXEC);
  420. #else
  421. _dl_mprotect((void *) ((ppnt->p_vaddr + app_tpnt->loadaddr) & PAGE_ALIGN),
  422. ((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) +
  423. (unsigned long) ppnt->p_filesz,
  424. PROT_READ | PROT_WRITE | PROT_EXEC);
  425. #endif
  426. }
  427. }
  428. }
  429. #endif
  430. #if defined(__mips__)
  431. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  432. SEND_STDERR("About to do MIPS specific GOT bootstrap\n");
  433. #endif
  434. /* For MIPS we have to do stuff to the GOT before we do relocations. */
  435. PERFORM_BOOTSTRAP_GOT(got);
  436. #endif
  437. /* OK, now do the relocations. We do not do a lazy binding here, so
  438. that once we are done, we have considerably more flexibility. */
  439. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  440. SEND_STDERR("About to do library loader relocations\n");
  441. #endif
  442. goof = 0;
  443. for (indx = 0; indx < 2; indx++) {
  444. unsigned int i;
  445. ELF_RELOC *rpnt;
  446. unsigned long *reloc_addr;
  447. unsigned long symbol_addr;
  448. int symtab_index;
  449. unsigned long rel_addr, rel_size;
  450. rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
  451. dynamic_info[DT_RELOC_TABLE_ADDR]);
  452. rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
  453. dynamic_info[DT_RELOC_TABLE_SIZE]);
  454. if (!rel_addr)
  455. continue;
  456. /* Now parse the relocation information */
  457. rpnt = (ELF_RELOC *) (rel_addr + load_addr);
  458. for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
  459. reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
  460. symtab_index = ELF32_R_SYM(rpnt->r_info);
  461. symbol_addr = 0;
  462. if (symtab_index) {
  463. char *strtab;
  464. char *symname;
  465. Elf32_Sym *symtab;
  466. symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + load_addr);
  467. strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + load_addr);
  468. symname = strtab + symtab[symtab_index].st_name;
  469. /* We only do a partial dynamic linking right now. The user
  470. is not supposed to define any symbols that start with a
  471. '_dl', so we can do this with confidence. */
  472. if (!symname || symname[0] != '_' ||
  473. symname[1] != 'd' || symname[2] != 'l' || symname[3] != '_')
  474. {
  475. continue;
  476. }
  477. symbol_addr = load_addr + symtab[symtab_index].st_value;
  478. if (!symbol_addr) {
  479. /* This will segfault - you cannot call a function until
  480. * we have finished the relocations.
  481. */
  482. SEND_STDERR("ELF dynamic loader - unable to self-bootstrap - symbol ");
  483. SEND_STDERR(symname);
  484. SEND_STDERR(" undefined.\n");
  485. goof++;
  486. }
  487. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  488. SEND_STDERR("relocating symbol: ");
  489. SEND_STDERR(symname);
  490. SEND_STDERR("\n");
  491. #endif
  492. PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, &symtab[symtab_index]);
  493. } else {
  494. /* Use this machine-specific macro to perform the actual relocation. */
  495. PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, NULL);
  496. }
  497. }
  498. }
  499. if (goof) {
  500. _dl_exit(14);
  501. }
  502. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  503. /* Wahoo!!! */
  504. SEND_STDERR("Done relocating library loader, so we can now\n"
  505. "\tuse globals and make function calls!\n");
  506. #endif
  507. /* Now we have done the mandatory linking of some things. We are now
  508. free to start using global variables, since these things have all been
  509. fixed up by now. Still no function calls outside of this library ,
  510. since the dynamic resolver is not yet ready. */
  511. _dl_get_ready_to_run(tpnt, app_tpnt, load_addr, hash_addr,
  512. auxvt, envp, debug_addr, malloc_buffer, mmap_zero, argv);
  513. /* Transfer control to the application. */
  514. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  515. SEND_STDERR("transfering control to application\n");
  516. #endif
  517. _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_fcn;
  518. START();
  519. }