ldso.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  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. #include "ldso.h"
  32. #define ALLOW_ZERO_PLTGOT
  33. /* Pull in the value of _dl_progname */
  34. #include "dl-progname.h"
  35. /* Global variables used within the shared library loader */
  36. char *_dl_library_path = 0; /* Where we look for libraries */
  37. char *_dl_preload = 0; /* Things to be loaded before the libs */
  38. char *_dl_ldsopath = 0; /* Location of the shared lib loader */
  39. unsigned long *_dl_brkp = 0; /* The end of the data segment for brk and sbrk */
  40. unsigned long *_dl_envp = 0; /* The environment address */
  41. int _dl_secure = 1; /* Are we dealing with setuid stuff? */
  42. int _dl_errno = 0; /* We can't use the real errno in ldso */
  43. size_t _dl_pagesize = 0; /* Store the page size for use later */
  44. struct r_debug *_dl_debug_addr = NULL; /* Used to communicate with the gdb debugger */
  45. #ifdef __SUPPORT_LD_DEBUG__
  46. char *_dl_debug = 0;
  47. char *_dl_debug_symbols = 0;
  48. char *_dl_debug_move = 0;
  49. char *_dl_debug_reloc = 0;
  50. char *_dl_debug_detail = 0;
  51. char *_dl_debug_nofixups = 0;
  52. char *_dl_debug_bindings = 0;
  53. int _dl_debug_file = 2;
  54. #endif
  55. /* Forward function declarations */
  56. static int _dl_suid_ok(void);
  57. /*
  58. * This stub function is used by some debuggers. The idea is that they
  59. * can set an internal breakpoint on it, so that we are notified when the
  60. * address mapping is changed in some way.
  61. */
  62. void _dl_debug_state(void)
  63. {
  64. }
  65. static unsigned char *_dl_malloc_addr = 0; /* Lets _dl_malloc use the already allocated memory page */
  66. static unsigned char *_dl_mmap_zero = 0; /* Also used by _dl_malloc */
  67. #if defined (__SUPPORT_LD_DEBUG__)
  68. static void debug_fini (int status, void *arg)
  69. {
  70. (void)status;
  71. _dl_dprintf(_dl_debug_file,"\ncalling fini: %s\n\n", (const char*)arg);
  72. }
  73. #endif
  74. void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt,
  75. unsigned long load_addr, unsigned long *hash_addr,
  76. Elf32_auxv_t auxvt[AT_EGID + 1], char **envp, struct r_debug *debug_addr,
  77. unsigned char *malloc_buffer, unsigned char *mmap_zero, char **argv)
  78. {
  79. ElfW(Phdr) *ppnt;
  80. char *lpntstr;
  81. int i, goof = 0, be_lazy = RTLD_LAZY, trace_loaded_objects = 0;
  82. struct dyn_elf *rpnt;
  83. struct elf_resolve *tcurr;
  84. struct elf_resolve *tpnt1;
  85. unsigned long brk_addr, *lpnt;
  86. int (*_dl_atexit) (void *);
  87. #if defined (__SUPPORT_LD_DEBUG__)
  88. int (*_dl_on_exit) (void (*FUNCTION)(int STATUS, void *ARG),void*);
  89. #endif
  90. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  91. /* Wahoo!!! */
  92. SEND_STDERR("Cool, we managed to make a function call.\n");
  93. #endif
  94. /* Make it so _dl_malloc can use the page of memory we have already
  95. * allocated. We shouldn't need to grab any more memory. This must
  96. * be first since things like _dl_dprintf() use _dl_malloc().... */
  97. _dl_malloc_addr = malloc_buffer;
  98. _dl_mmap_zero = mmap_zero;
  99. /* Store the page size for later use */
  100. _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val)? auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
  101. /* Now we have done the mandatory linking of some things. We are now
  102. * free to start using global variables, since these things have all been
  103. * fixed up by now. Still no function calls outside of this library ,
  104. * since the dynamic resolver is not yet ready. */
  105. if (argv[0]) {
  106. _dl_progname = argv[0];
  107. }
  108. /* Start to build the tables of the modules that are required for
  109. * this beast to run. We start with the basic executable, and then
  110. * go from there. Eventually we will run across ourself, and we
  111. * will need to properly deal with that as well. */
  112. lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
  113. tpnt->chains = hash_addr;
  114. tpnt->next = 0;
  115. tpnt->libname = 0;
  116. tpnt->libtype = program_interpreter;
  117. tpnt->loadaddr = (ElfW(Addr)) load_addr;
  118. #ifdef ALLOW_ZERO_PLTGOT
  119. if (tpnt->dynamic_info[DT_PLTGOT])
  120. #endif
  121. {
  122. INIT_GOT(lpnt, tpnt);
  123. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  124. _dl_dprintf(_dl_debug_file, "GOT found at %x\n", lpnt);
  125. #endif
  126. }
  127. /* OK, this was a big step, now we need to scan all of the user images
  128. and load them properly. */
  129. {
  130. ElfW(Ehdr) *epnt;
  131. ElfW(Phdr) *myppnt;
  132. int j;
  133. epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
  134. tpnt->n_phent = epnt->e_phnum;
  135. tpnt->ppnt = myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
  136. for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
  137. if (myppnt->p_type == PT_DYNAMIC) {
  138. tpnt->dynamic_addr = (ElfW(Dyn) *)myppnt->p_vaddr + load_addr;
  139. tpnt->dynamic_size = myppnt->p_filesz;
  140. }
  141. }
  142. }
  143. brk_addr = 0;
  144. rpnt = NULL;
  145. /* At this point we are now free to examine the user application,
  146. and figure out which libraries are supposed to be called. Until
  147. we have this list, we will not be completely ready for dynamic linking */
  148. ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
  149. for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
  150. if (ppnt->p_type == PT_LOAD) {
  151. if (ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz > brk_addr)
  152. brk_addr = ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz;
  153. }
  154. if (ppnt->p_type == PT_DYNAMIC) {
  155. #ifndef ALLOW_ZERO_PLTGOT
  156. /* make sure it's really there. */
  157. if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
  158. continue;
  159. #endif
  160. /* OK, we have what we need - slip this one into the list. */
  161. app_tpnt = _dl_add_elf_hash_table("", (char *)app_tpnt->loadaddr,
  162. app_tpnt->dynamic_info, ppnt->p_vaddr + app_tpnt->loadaddr, ppnt->p_filesz);
  163. _dl_loaded_modules->libtype = elf_executable;
  164. _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
  165. _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
  166. _dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
  167. _dl_memset(rpnt, 0, sizeof(struct dyn_elf));
  168. rpnt->dyn = _dl_loaded_modules;
  169. app_tpnt->usage_count++;
  170. app_tpnt->symbol_scope = _dl_symbol_tables;
  171. lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT] + app_tpnt->loadaddr);
  172. #ifdef ALLOW_ZERO_PLTGOT
  173. if (lpnt)
  174. #endif
  175. INIT_GOT(lpnt, _dl_loaded_modules);
  176. }
  177. /* OK, fill this in - we did not have this before */
  178. if (ppnt->p_type == PT_INTERP) {
  179. int readsize = 0;
  180. char *pnt, *pnt1, buf[1024];
  181. tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
  182. (auxvt[AT_PHDR].a_un.a_val & PAGE_ALIGN));
  183. /* Determine if the shared lib loader is a symlink */
  184. _dl_memset(buf, 0, sizeof(buf));
  185. readsize = _dl_readlink(tpnt->libname, buf, sizeof(buf));
  186. if (readsize > 0 && readsize < (int)(sizeof(buf)-1)) {
  187. pnt1 = _dl_strrchr(buf, '/');
  188. if (pnt1 && buf != pnt1) {
  189. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  190. _dl_dprintf(_dl_debug_file, "changing tpnt->libname from '%s' to '%s'\n", tpnt->libname, buf);
  191. #endif
  192. tpnt->libname = _dl_strdup(buf);
  193. }
  194. }
  195. /* Store the path where the shared lib loader was found for
  196. * later use */
  197. pnt = _dl_strdup(tpnt->libname);
  198. pnt1 = _dl_strrchr(pnt, '/');
  199. if (pnt != pnt1) {
  200. *pnt1 = '\0';
  201. _dl_ldsopath = pnt;
  202. } else {
  203. _dl_ldsopath = tpnt->libname;
  204. }
  205. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  206. _dl_dprintf(_dl_debug_file, "Lib Loader:\t(%x) %s\n", tpnt->loadaddr, tpnt->libname);
  207. #endif
  208. }
  209. }
  210. /* Now we need to figure out what kind of options are selected.
  211. Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
  212. {
  213. if (_dl_getenv("LD_BIND_NOW", envp))
  214. be_lazy = 0;
  215. if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
  216. (auxvt[AT_UID].a_un.a_val != -1 &&
  217. auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val
  218. && auxvt[AT_GID].a_un.a_val== auxvt[AT_EGID].a_un.a_val)) {
  219. _dl_secure = 0;
  220. _dl_preload = _dl_getenv("LD_PRELOAD", envp);
  221. _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
  222. } else {
  223. _dl_secure = 1;
  224. _dl_preload = _dl_getenv("LD_PRELOAD", envp);
  225. _dl_unsetenv("LD_AOUT_PRELOAD", envp);
  226. _dl_unsetenv("LD_LIBRARY_PATH", envp);
  227. _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
  228. _dl_library_path = NULL;
  229. }
  230. }
  231. #ifdef __SUPPORT_LD_DEBUG__
  232. _dl_debug = _dl_getenv("LD_DEBUG", envp);
  233. if (_dl_debug)
  234. {
  235. if (_dl_strstr(_dl_debug, "all")) {
  236. _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
  237. = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = _dl_strstr(_dl_debug, "all");
  238. }
  239. else {
  240. _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
  241. _dl_debug_move = _dl_strstr(_dl_debug, "move");
  242. _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
  243. _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
  244. _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
  245. _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
  246. }
  247. }
  248. {
  249. const char *dl_debug_output;
  250. dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
  251. if (dl_debug_output)
  252. {
  253. char tmp[22], *tmp1, *filename;
  254. int len1, len2;
  255. _dl_memset(tmp, 0, sizeof(tmp));
  256. tmp1=_dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
  257. len1 = _dl_strlen(dl_debug_output);
  258. len2 = _dl_strlen(tmp1);
  259. filename = _dl_malloc(len1+len2+2);
  260. if (filename)
  261. {
  262. _dl_strcpy (filename, dl_debug_output);
  263. filename[len1] = '.';
  264. _dl_strcpy (&filename[len1+1], tmp1);
  265. _dl_debug_file= _dl_open(filename, O_WRONLY|O_CREAT, 0644);
  266. if (_dl_debug_file<0)
  267. {
  268. _dl_debug_file = 2;
  269. _dl_dprintf (2, "can't open file: '%s'\n",filename);
  270. }
  271. }
  272. }
  273. }
  274. #endif
  275. if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
  276. trace_loaded_objects++;
  277. }
  278. #ifndef __LDSO_LDD_SUPPORT__
  279. if (trace_loaded_objects) {
  280. _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
  281. _dl_exit(1);
  282. }
  283. #endif
  284. /*
  285. * OK, fix one more thing - set up debug_addr so it will point
  286. * to our chain. Later we may need to fill in more fields, but this
  287. * should be enough for now.
  288. */
  289. debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
  290. debug_addr->r_version = 1;
  291. debug_addr->r_ldbase = load_addr;
  292. debug_addr->r_brk = (unsigned long) &_dl_debug_state;
  293. _dl_debug_addr = debug_addr;
  294. /* Notify the debugger we are in a consistant state */
  295. _dl_debug_addr->r_state = RT_CONSISTENT;
  296. _dl_debug_state();
  297. /* OK, we now have the application in the list, and we have some
  298. basic stuff in place. Now search through the list for other shared
  299. libraries that should be loaded, and insert them on the list in the
  300. correct order. */
  301. _dl_map_cache();
  302. if (_dl_preload)
  303. {
  304. char c, *str, *str2;
  305. str = _dl_preload;
  306. while (*str == ':' || *str == ' ' || *str == '\t')
  307. str++;
  308. while (*str)
  309. {
  310. str2 = str;
  311. while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
  312. str2++;
  313. c = *str2;
  314. *str2 = '\0';
  315. if (!_dl_secure || _dl_strchr(str, '/') == NULL)
  316. {
  317. if ((tpnt1 = _dl_check_if_named_library_is_loaded(str, trace_loaded_objects)))
  318. {
  319. continue;
  320. }
  321. #if defined (__SUPPORT_LD_DEBUG__)
  322. if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s'; needed by '%s'\n",
  323. str, _dl_progname);
  324. #endif
  325. tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
  326. if (!tpnt1) {
  327. #ifdef __LDSO_LDD_SUPPORT__
  328. if (trace_loaded_objects)
  329. _dl_dprintf(1, "\t%s => not found\n", str);
  330. else
  331. #endif
  332. {
  333. _dl_dprintf(2, "%s: can't load " "library '%s'\n", _dl_progname, str);
  334. _dl_exit(15);
  335. }
  336. } else {
  337. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  338. _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
  339. #endif
  340. #ifdef __LDSO_LDD_SUPPORT__
  341. if (trace_loaded_objects && tpnt1->usage_count==1) {
  342. /* this is a real hack to make ldd not print
  343. * the library itself when run on a library. */
  344. if (_dl_strcmp(_dl_progname, str) != 0)
  345. _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
  346. (unsigned) tpnt1->loadaddr);
  347. }
  348. #endif
  349. }
  350. }
  351. *str2 = c;
  352. str = str2;
  353. while (*str == ':' || *str == ' ' || *str == '\t')
  354. str++;
  355. }
  356. }
  357. #ifdef SUPPORT_LDSO_PRELOAD_FILE
  358. {
  359. int fd;
  360. struct stat st;
  361. char *preload;
  362. if (!_dl_stat(LDSO_PRELOAD, &st) && st.st_size > 0) {
  363. if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
  364. _dl_dprintf(2, "%s: can't open file '%s'\n",
  365. _dl_progname, LDSO_PRELOAD);
  366. } else {
  367. preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
  368. PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
  369. _dl_close(fd);
  370. if (preload == (caddr_t) - 1) {
  371. _dl_dprintf(2, "%s: can't map file '%s'\n",
  372. _dl_progname, LDSO_PRELOAD);
  373. } else {
  374. char c, *cp, *cp2;
  375. /* convert all separators and comments to spaces */
  376. for (cp = preload; *cp; /*nada */ ) {
  377. if (*cp == ':' || *cp == '\t' || *cp == '\n') {
  378. *cp++ = ' ';
  379. } else if (*cp == '#') {
  380. do
  381. *cp++ = ' ';
  382. while (*cp != '\n' && *cp != '\0');
  383. } else {
  384. cp++;
  385. }
  386. }
  387. /* find start of first library */
  388. for (cp = preload; *cp && *cp == ' '; cp++)
  389. /*nada */ ;
  390. while (*cp) {
  391. /* find end of library */
  392. for (cp2 = cp; *cp && *cp != ' '; cp++)
  393. /*nada */ ;
  394. c = *cp;
  395. *cp = '\0';
  396. if ((tpnt1 = _dl_check_if_named_library_is_loaded(cp2, trace_loaded_objects)))
  397. {
  398. continue;
  399. }
  400. #if defined (__SUPPORT_LD_DEBUG__)
  401. if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s'; needed by '%s'\n",
  402. cp2, _dl_progname);
  403. #endif
  404. tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
  405. if (!tpnt1) {
  406. #ifdef __LDSO_LDD_SUPPORT__
  407. if (trace_loaded_objects)
  408. _dl_dprintf(1, "\t%s => not found\n", cp2);
  409. else
  410. #endif
  411. {
  412. _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, cp2);
  413. _dl_exit(15);
  414. }
  415. } else {
  416. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  417. _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
  418. #endif
  419. #ifdef __LDSO_LDD_SUPPORT__
  420. if (trace_loaded_objects && tpnt1->usage_count==1) {
  421. _dl_dprintf(1, "\t%s => %s (%x)\n", cp2,
  422. tpnt1->libname, (unsigned) tpnt1->loadaddr);
  423. }
  424. #endif
  425. }
  426. /* find start of next library */
  427. *cp = c;
  428. for ( /*nada */ ; *cp && *cp == ' '; cp++)
  429. /*nada */ ;
  430. }
  431. _dl_munmap(preload, st.st_size + 1);
  432. }
  433. }
  434. }
  435. }
  436. #endif
  437. for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
  438. {
  439. Elf32_Dyn *dpnt;
  440. for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++)
  441. {
  442. if (dpnt->d_tag == DT_NEEDED)
  443. {
  444. char *name;
  445. lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
  446. name = _dl_get_last_path_component(lpntstr);
  447. if ((tpnt1 = _dl_check_if_named_library_is_loaded(name, trace_loaded_objects)))
  448. {
  449. continue;
  450. }
  451. #if defined (__SUPPORT_LD_DEBUG__)
  452. if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s'; needed by '%s'\n",
  453. lpntstr, _dl_progname);
  454. #endif
  455. if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects)))
  456. {
  457. #ifdef __LDSO_LDD_SUPPORT__
  458. if (trace_loaded_objects) {
  459. _dl_dprintf(1, "\t%s => not found\n", lpntstr);
  460. continue;
  461. } else
  462. #endif
  463. {
  464. _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
  465. _dl_exit(16);
  466. }
  467. } else {
  468. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  469. _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
  470. #endif
  471. #ifdef __LDSO_LDD_SUPPORT__
  472. if (trace_loaded_objects && tpnt1->usage_count==1) {
  473. _dl_dprintf(1, "\t%s => %s (%x)\n", lpntstr, tpnt1->libname,
  474. (unsigned) tpnt1->loadaddr);
  475. }
  476. #endif
  477. }
  478. }
  479. }
  480. }
  481. _dl_unmap_cache();
  482. /*
  483. * If the program interpreter is not in the module chain, add it. This will
  484. * be required for dlopen to be able to access the internal functions in the
  485. * dynamic linker.
  486. */
  487. if (tpnt) {
  488. tcurr = _dl_loaded_modules;
  489. if (tcurr)
  490. while (tcurr->next)
  491. tcurr = tcurr->next;
  492. tpnt->next = NULL;
  493. tpnt->usage_count++;
  494. if (tcurr) {
  495. tcurr->next = tpnt;
  496. tpnt->prev = tcurr;
  497. } else {
  498. _dl_loaded_modules = tpnt;
  499. tpnt->prev = NULL;
  500. }
  501. if (rpnt) {
  502. rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
  503. _dl_memset(rpnt->next, 0, sizeof(struct dyn_elf));
  504. rpnt->next->prev = rpnt;
  505. rpnt = rpnt->next;
  506. } else {
  507. rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
  508. _dl_memset(rpnt, 0, sizeof(struct dyn_elf));
  509. }
  510. rpnt->dyn = tpnt;
  511. tpnt = NULL;
  512. }
  513. #ifdef __LDSO_LDD_SUPPORT__
  514. /* End of the line for ldd.... */
  515. if (trace_loaded_objects) {
  516. _dl_dprintf(1, "\t%s => %s (%x)\n", rpnt->dyn->libname + (_dl_strlen(_dl_ldsopath)) + 1,
  517. rpnt->dyn->libname, rpnt->dyn->loadaddr);
  518. _dl_exit(0);
  519. }
  520. #endif
  521. #ifdef __mips__
  522. /*
  523. * Relocation of the GOT entries for MIPS have to be done
  524. * after all the libraries have been loaded.
  525. */
  526. _dl_perform_mips_global_got_relocations(_dl_loaded_modules);
  527. #endif
  528. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  529. _dl_dprintf(_dl_debug_file, "Beginning relocation fixups\n");
  530. #endif
  531. /*
  532. * OK, now all of the kids are tucked into bed in their proper addresses.
  533. * Now we go through and look for REL and RELA records that indicate fixups
  534. * to the GOT tables. We need to do this in reverse order so that COPY
  535. * directives work correctly */
  536. if (_dl_symbol_tables)
  537. goof += _dl_fixup(_dl_symbol_tables, be_lazy);
  538. /* OK, at this point things are pretty much ready to run. Now we
  539. need to touch up a few items that are required, and then
  540. we can let the user application have at it. Note that
  541. the dynamic linker itself is not guaranteed to be fully
  542. dynamicly linked if we are using ld.so.1, so we have to look
  543. up each symbol individually. */
  544. _dl_brkp = (unsigned long *) (intptr_t) _dl_find_hash("__curbrk", NULL, 0);
  545. if (_dl_brkp) {
  546. *_dl_brkp = brk_addr;
  547. }
  548. _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", NULL, 0);
  549. if (_dl_envp) {
  550. *_dl_envp = (unsigned long) envp;
  551. }
  552. #ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
  553. {
  554. unsigned int j;
  555. ElfW(Phdr) *myppnt;
  556. /* We had to set the protections of all pages to R/W for dynamic linking.
  557. Set text pages back to R/O */
  558. for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
  559. for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
  560. if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
  561. _dl_mprotect((void *) (tpnt->loadaddr + (myppnt->p_vaddr & PAGE_ALIGN)),
  562. (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
  563. }
  564. }
  565. }
  566. }
  567. #endif
  568. _dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", NULL, ELF_RTYPE_CLASS_PLT);
  569. #if defined (__SUPPORT_LD_DEBUG__)
  570. _dl_on_exit = (int (*)(void (*)(int, void *),void*))
  571. (intptr_t) _dl_find_hash("on_exit", NULL, ELF_RTYPE_CLASS_PLT);
  572. #endif
  573. /* Notify the debugger we have added some objects. */
  574. _dl_debug_addr->r_state = RT_ADD;
  575. _dl_debug_state();
  576. for (rpnt = _dl_symbol_tables; rpnt!=NULL&& rpnt->next!=NULL; rpnt=rpnt->next)
  577. ;
  578. for (;rpnt!=NULL; rpnt=rpnt->prev)
  579. {
  580. tpnt = rpnt->dyn;
  581. if (tpnt->libtype == program_interpreter)
  582. continue;
  583. /* Apparently crt0/1 for the application is responsible for handling this.
  584. * We only need to run the init/fini for shared libraries
  585. */
  586. if (tpnt->libtype == elf_executable)
  587. break; /* at this point all shared libs are initialized !! */
  588. if (tpnt->init_flag & INIT_FUNCS_CALLED)
  589. continue;
  590. tpnt->init_flag |= INIT_FUNCS_CALLED;
  591. if (tpnt->dynamic_info[DT_INIT]) {
  592. void (*dl_elf_func) (void);
  593. dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
  594. #if defined (__SUPPORT_LD_DEBUG__)
  595. if(_dl_debug) _dl_dprintf(_dl_debug_file,"\ncalling init: %s\n\n", tpnt->libname);
  596. #endif
  597. (*dl_elf_func) ();
  598. }
  599. if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {
  600. void (*dl_elf_func) (void);
  601. dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
  602. (*_dl_atexit) (dl_elf_func);
  603. #if defined (__SUPPORT_LD_DEBUG__)
  604. if(_dl_debug && _dl_on_exit)
  605. {
  606. (*_dl_on_exit)(debug_fini, tpnt->libname);
  607. }
  608. #endif
  609. }
  610. #if defined (__SUPPORT_LD_DEBUG__)
  611. else {
  612. if (!_dl_atexit)
  613. _dl_dprintf(_dl_debug_file, "%s: The address of atexit () is 0x0.\n", tpnt->libname);
  614. #if 0
  615. if (!tpnt->dynamic_info[DT_FINI])
  616. _dl_dprintf(_dl_debug_file, "%s: Invalid .fini section.\n", tpnt->libname);
  617. #endif
  618. }
  619. #endif
  620. }
  621. /* Notify the debugger that all objects are now mapped in. */
  622. _dl_debug_addr->r_state = RT_CONSISTENT;
  623. _dl_debug_state();
  624. }
  625. char *_dl_getenv(const char *symbol, char **envp)
  626. {
  627. char *pnt;
  628. const char *pnt1;
  629. while ((pnt = *envp++)) {
  630. pnt1 = symbol;
  631. while (*pnt && *pnt == *pnt1)
  632. pnt1++, pnt++;
  633. if (!*pnt || *pnt != '=' || *pnt1)
  634. continue;
  635. return pnt + 1;
  636. }
  637. return 0;
  638. }
  639. void _dl_unsetenv(const char *symbol, char **envp)
  640. {
  641. char *pnt;
  642. const char *pnt1;
  643. char **newenvp = envp;
  644. for (pnt = *envp; pnt; pnt = *++envp) {
  645. pnt1 = symbol;
  646. while (*pnt && *pnt == *pnt1)
  647. pnt1++, pnt++;
  648. if (!*pnt || *pnt != '=' || *pnt1)
  649. *newenvp++ = *envp;
  650. }
  651. *newenvp++ = *envp;
  652. return;
  653. }
  654. static int _dl_suid_ok(void)
  655. {
  656. __kernel_uid_t uid, euid;
  657. __kernel_gid_t gid, egid;
  658. uid = _dl_getuid();
  659. euid = _dl_geteuid();
  660. gid = _dl_getgid();
  661. egid = _dl_getegid();
  662. if(uid == euid && gid == egid) {
  663. return 1;
  664. }
  665. return 0;
  666. }
  667. void *(*_dl_malloc_function) (size_t size) = NULL;
  668. void *_dl_malloc(int size)
  669. {
  670. void *retval;
  671. #if 0
  672. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  673. _dl_dprintf(2, "malloc: request for %d bytes\n", size);
  674. #endif
  675. #endif
  676. if (_dl_malloc_function)
  677. return (*_dl_malloc_function) (size);
  678. if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
  679. #ifdef __SUPPORT_LD_DEBUG_EARLY__
  680. _dl_dprintf(2, "malloc: mmapping more memory\n");
  681. #endif
  682. _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size,
  683. PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  684. if (_dl_mmap_check_error(_dl_mmap_zero)) {
  685. _dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);
  686. _dl_exit(20);
  687. }
  688. }
  689. retval = _dl_malloc_addr;
  690. _dl_malloc_addr += size;
  691. /*
  692. * Align memory to 4 byte boundary. Some platforms require this, others
  693. * simply get better performance.
  694. */
  695. _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));
  696. return retval;
  697. }
  698. #include "dl-hash.c"
  699. #include "dl-elf.c"