dynlink.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <stdint.h>
  6. #include <elf.h>
  7. #include <sys/mman.h>
  8. #include <limits.h>
  9. #include <stdint.h>
  10. #include <fcntl.h>
  11. #include <sys/stat.h>
  12. #include <errno.h>
  13. #include <limits.h>
  14. #include <elf.h>
  15. #include <setjmp.h>
  16. #include <pthread.h>
  17. #include <ctype.h>
  18. #include <dlfcn.h>
  19. static int errflag;
  20. static char errbuf[128];
  21. #ifdef SHARED
  22. #if ULONG_MAX == 0xffffffff
  23. typedef Elf32_Ehdr Ehdr;
  24. typedef Elf32_Phdr Phdr;
  25. typedef Elf32_Sym Sym;
  26. #define R_TYPE(x) ((x)&255)
  27. #define R_SYM(x) ((x)>>8)
  28. #else
  29. typedef Elf64_Ehdr Ehdr;
  30. typedef Elf64_Phdr Phdr;
  31. typedef Elf64_Sym Sym;
  32. #define R_TYPE(x) ((x)&0xffffffff)
  33. #define R_SYM(x) ((x)>>32)
  34. #endif
  35. struct debug {
  36. int ver;
  37. void *head;
  38. void (*bp)(void);
  39. int state;
  40. void *base;
  41. };
  42. struct dso {
  43. unsigned char *base;
  44. char *name;
  45. size_t *dynv;
  46. struct dso *next, *prev;
  47. int refcnt;
  48. Sym *syms;
  49. uint32_t *hashtab;
  50. uint32_t *ghashtab;
  51. char *strings;
  52. unsigned char *map;
  53. size_t map_len;
  54. dev_t dev;
  55. ino_t ino;
  56. signed char global;
  57. char relocated;
  58. char constructed;
  59. struct dso **deps;
  60. char *shortname;
  61. char buf[];
  62. };
  63. #include "reloc.h"
  64. void __init_ssp(size_t *);
  65. static struct dso *head, *tail, *libc;
  66. static char *env_path, *sys_path, *r_path;
  67. static int rtld_used;
  68. static int ssp_used;
  69. static int runtime;
  70. static int ldd_mode;
  71. static int ldso_fail;
  72. static jmp_buf rtld_fail;
  73. static pthread_rwlock_t lock;
  74. static struct debug debug;
  75. static size_t *auxv;
  76. struct debug *_dl_debug_addr = &debug;
  77. #define AUX_CNT 24
  78. #define DYN_CNT 34
  79. static void decode_vec(size_t *v, size_t *a, size_t cnt)
  80. {
  81. memset(a, 0, cnt*sizeof(size_t));
  82. for (; v[0]; v+=2) if (v[0]<cnt) {
  83. a[0] |= 1ULL<<v[0];
  84. a[v[0]] = v[1];
  85. }
  86. }
  87. static int search_vec(size_t *v, size_t *r, size_t key)
  88. {
  89. for (; v[0]!=key; v+=2)
  90. if (!v[0]) return 0;
  91. *r = v[1];
  92. return 1;
  93. }
  94. static uint32_t sysv_hash(const char *s0)
  95. {
  96. const unsigned char *s = (void *)s0;
  97. uint_fast32_t h = 0;
  98. while (*s) {
  99. h = 16*h + *s++;
  100. h ^= h>>24 & 0xf0;
  101. }
  102. return h & 0xfffffff;
  103. }
  104. static uint32_t gnu_hash(const char *s0)
  105. {
  106. const unsigned char *s = (void *)s0;
  107. uint_fast32_t h = 5381;
  108. for (; *s; s++)
  109. h = h*33 + *s;
  110. return h;
  111. }
  112. static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)
  113. {
  114. size_t i;
  115. Sym *syms = dso->syms;
  116. uint32_t *hashtab = dso->hashtab;
  117. char *strings = dso->strings;
  118. for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
  119. if (!strcmp(s, strings+syms[i].st_name))
  120. return syms+i;
  121. }
  122. return 0;
  123. }
  124. static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
  125. {
  126. Sym *sym;
  127. char *strings;
  128. uint32_t *hashtab = dso->ghashtab;
  129. uint32_t nbuckets = hashtab[0];
  130. uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
  131. uint32_t h2;
  132. uint32_t *hashval;
  133. uint32_t n = buckets[h1 % nbuckets];
  134. if (!n) return 0;
  135. strings = dso->strings;
  136. sym = dso->syms + n;
  137. hashval = buckets + nbuckets + (n - hashtab[1]);
  138. for (h1 |= 1; ; sym++) {
  139. h2 = *hashval++;
  140. if ((h1 == (h2|1)) && !strcmp(s, strings + sym->st_name))
  141. return sym;
  142. if (h2 & 1) break;
  143. }
  144. return 0;
  145. }
  146. #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON)
  147. #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK)
  148. static void *find_sym(struct dso *dso, const char *s, int need_def)
  149. {
  150. uint32_t h = 0, gh = 0;
  151. void *def = 0;
  152. if (dso->ghashtab) {
  153. gh = gnu_hash(s);
  154. if (gh == 0xf9040207 && !strcmp(s, "dlopen")) rtld_used = 1;
  155. if (gh == 0xf4dc4ae && !strcmp(s, "dlsym")) rtld_used = 1;
  156. if (gh == 0x1f4039c9 && !strcmp(s, "__stack_chk_fail")) ssp_used = 1;
  157. } else {
  158. h = sysv_hash(s);
  159. if (h == 0x6b366be && !strcmp(s, "dlopen")) rtld_used = 1;
  160. if (h == 0x6b3afd && !strcmp(s, "dlsym")) rtld_used = 1;
  161. if (h == 0x595a4cc && !strcmp(s, "__stack_chk_fail")) ssp_used = 1;
  162. }
  163. for (; dso; dso=dso->next) {
  164. Sym *sym;
  165. if (!dso->global) continue;
  166. if (dso->ghashtab) {
  167. if (!gh) gh = gnu_hash(s);
  168. sym = gnu_lookup(s, gh, dso);
  169. } else {
  170. if (!h) h = sysv_hash(s);
  171. sym = sysv_lookup(s, h, dso);
  172. }
  173. if (sym && (!need_def || sym->st_shndx) && sym->st_value
  174. && (1<<(sym->st_info&0xf) & OK_TYPES)
  175. && (1<<(sym->st_info>>4) & OK_BINDS)) {
  176. if (def && sym->st_info>>4 == STB_WEAK) continue;
  177. def = dso->base + sym->st_value;
  178. if (sym->st_info>>4 == STB_GLOBAL) break;
  179. }
  180. }
  181. return def;
  182. }
  183. static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
  184. {
  185. unsigned char *base = dso->base;
  186. Sym *syms = dso->syms;
  187. char *strings = dso->strings;
  188. Sym *sym;
  189. const char *name;
  190. size_t sym_val, sym_size;
  191. size_t *reloc_addr;
  192. void *ctx;
  193. int type;
  194. int sym_index;
  195. for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
  196. reloc_addr = (void *)(base + rel[0]);
  197. type = R_TYPE(rel[1]);
  198. sym_index = R_SYM(rel[1]);
  199. if (sym_index) {
  200. sym = syms + sym_index;
  201. name = strings + sym->st_name;
  202. ctx = IS_COPY(type) ? head->next : head;
  203. sym_val = (size_t)find_sym(ctx, name, IS_PLT(type));
  204. if (!sym_val && sym->st_info>>4 != STB_WEAK) {
  205. snprintf(errbuf, sizeof errbuf,
  206. "Error relocating %s: %s: symbol not found",
  207. dso->name, name);
  208. if (runtime) longjmp(rtld_fail, 1);
  209. dprintf(2, "%s\n", errbuf);
  210. ldso_fail = 1;
  211. continue;
  212. }
  213. sym_size = sym->st_size;
  214. } else {
  215. sym_val = sym_size = 0;
  216. }
  217. do_single_reloc(reloc_addr, type, sym_val, sym_size, base, rel[2]);
  218. }
  219. }
  220. /* A huge hack: to make up for the wastefulness of shared libraries
  221. * needing at least a page of dirty memory even if they have no global
  222. * data, we reclaim the gaps at the beginning and end of writable maps
  223. * and "donate" them to the heap by setting up minimal malloc
  224. * structures and then freeing them. */
  225. static void reclaim(unsigned char *base, size_t start, size_t end)
  226. {
  227. size_t *a, *z;
  228. start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t);
  229. end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t);
  230. if (start>end || end-start < 4*sizeof(size_t)) return;
  231. a = (size_t *)(base + start);
  232. z = (size_t *)(base + end);
  233. a[-2] = 1;
  234. a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1;
  235. z[1] = 1;
  236. free(a);
  237. }
  238. static void reclaim_gaps(unsigned char *base, Phdr *ph, size_t phent, size_t phcnt)
  239. {
  240. for (; phcnt--; ph=(void *)((char *)ph+phent)) {
  241. if (ph->p_type!=PT_LOAD) continue;
  242. if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;
  243. reclaim(base, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);
  244. reclaim(base, ph->p_vaddr+ph->p_memsz,
  245. ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);
  246. }
  247. }
  248. static void *map_library(int fd, size_t *lenp, unsigned char **basep, size_t *dynp)
  249. {
  250. Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
  251. size_t phsize;
  252. size_t addr_min=SIZE_MAX, addr_max=0, map_len;
  253. size_t this_min, this_max;
  254. off_t off_start;
  255. Ehdr *eh;
  256. Phdr *ph;
  257. unsigned prot;
  258. unsigned char *map, *base;
  259. size_t dyn;
  260. size_t i;
  261. ssize_t l = read(fd, buf, sizeof buf);
  262. if (l<sizeof *eh) return 0;
  263. eh = buf;
  264. phsize = eh->e_phentsize * eh->e_phnum;
  265. if (phsize + sizeof *eh > l) return 0;
  266. if (eh->e_phoff + phsize > l) {
  267. l = pread(fd, buf+1, phsize, eh->e_phoff);
  268. if (l != phsize) return 0;
  269. eh->e_phoff = sizeof *eh;
  270. }
  271. ph = (void *)((char *)buf + eh->e_phoff);
  272. for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
  273. if (ph->p_type == PT_DYNAMIC)
  274. dyn = ph->p_vaddr;
  275. if (ph->p_type != PT_LOAD) continue;
  276. if (ph->p_vaddr < addr_min) {
  277. addr_min = ph->p_vaddr;
  278. off_start = ph->p_offset;
  279. prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
  280. ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
  281. ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
  282. }
  283. if (ph->p_vaddr+ph->p_memsz > addr_max) {
  284. addr_max = ph->p_vaddr+ph->p_memsz;
  285. }
  286. }
  287. if (!dyn) return 0;
  288. addr_max += PAGE_SIZE-1;
  289. addr_max &= -PAGE_SIZE;
  290. addr_min &= -PAGE_SIZE;
  291. off_start &= -PAGE_SIZE;
  292. map_len = addr_max - addr_min + off_start;
  293. /* The first time, we map too much, possibly even more than
  294. * the length of the file. This is okay because we will not
  295. * use the invalid part; we just need to reserve the right
  296. * amount of virtual address space to map over later. */
  297. map = mmap((void *)addr_min, map_len, prot, MAP_PRIVATE, fd, off_start);
  298. if (map==MAP_FAILED) return 0;
  299. base = map - addr_min;
  300. ph = (void *)((char *)buf + eh->e_phoff);
  301. for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
  302. if (ph->p_type != PT_LOAD) continue;
  303. /* Reuse the existing mapping for the lowest-address LOAD */
  304. if ((ph->p_vaddr & -PAGE_SIZE) == addr_min) continue;
  305. this_min = ph->p_vaddr & -PAGE_SIZE;
  306. this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
  307. off_start = ph->p_offset & -PAGE_SIZE;
  308. prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
  309. ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
  310. ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
  311. if (mmap(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
  312. goto error;
  313. if (ph->p_memsz > ph->p_filesz) {
  314. size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
  315. size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
  316. memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
  317. if (pgbrk-(size_t)base < this_max && mmap((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
  318. goto error;
  319. }
  320. }
  321. for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
  322. if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
  323. if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC) < 0)
  324. goto error;
  325. break;
  326. }
  327. if (!runtime) reclaim_gaps(base, (void *)((char *)buf + eh->e_phoff),
  328. eh->e_phentsize, eh->e_phnum);
  329. *lenp = map_len;
  330. *basep = base;
  331. *dynp = dyn;
  332. return map;
  333. error:
  334. munmap(map, map_len);
  335. return 0;
  336. }
  337. static int path_open(const char *name, const char *search, char *buf, size_t buf_size)
  338. {
  339. const char *s=search, *z;
  340. int l, fd;
  341. for (;;) {
  342. while (*s==':') s++;
  343. if (!*s) return -1;
  344. z = strchr(s, ':');
  345. l = z ? z-s : strlen(s);
  346. snprintf(buf, buf_size, "%.*s/%s", l, s, name);
  347. if ((fd = open(buf, O_RDONLY))>=0) return fd;
  348. s += l;
  349. }
  350. }
  351. static void decode_dyn(struct dso *p)
  352. {
  353. size_t dyn[DYN_CNT] = {0};
  354. decode_vec(p->dynv, dyn, DYN_CNT);
  355. p->syms = (void *)(p->base + dyn[DT_SYMTAB]);
  356. p->strings = (void *)(p->base + dyn[DT_STRTAB]);
  357. if (dyn[0]&(1<<DT_HASH))
  358. p->hashtab = (void *)(p->base + dyn[DT_HASH]);
  359. if (search_vec(p->dynv, dyn, DT_GNU_HASH))
  360. p->ghashtab = (void *)(p->base + *dyn);
  361. }
  362. static struct dso *load_library(const char *name)
  363. {
  364. char buf[2*NAME_MAX+2];
  365. const char *pathname;
  366. unsigned char *base, *map;
  367. size_t dyno, map_len;
  368. struct dso *p;
  369. int fd;
  370. struct stat st;
  371. /* Catch and block attempts to reload the implementation itself */
  372. if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
  373. static const char *rp, reserved[] =
  374. "c\0pthread\0rt\0m\0dl\0util\0xnet\0";
  375. char *z = strchr(name, '.');
  376. if (z) {
  377. size_t l = z-name;
  378. for (rp=reserved; *rp && memcmp(name+3, rp, l-3); rp+=strlen(rp)+1);
  379. if (*rp) {
  380. if (!libc->prev) {
  381. tail->next = libc;
  382. libc->prev = tail;
  383. tail = libc->next ? libc->next : libc;
  384. }
  385. return libc;
  386. }
  387. }
  388. }
  389. if (strchr(name, '/')) {
  390. pathname = name;
  391. fd = open(name, O_RDONLY);
  392. } else {
  393. /* Search for the name to see if it's already loaded */
  394. for (p=head->next; p; p=p->next) {
  395. if (p->shortname && !strcmp(p->shortname, name)) {
  396. p->refcnt++;
  397. return p;
  398. }
  399. }
  400. if (strlen(name) > NAME_MAX) return 0;
  401. fd = -1;
  402. if (r_path) fd = path_open(name, r_path, buf, sizeof buf);
  403. if (fd < 0 && env_path) fd = path_open(name, env_path, buf, sizeof buf);
  404. if (fd < 0) {
  405. if (!sys_path) {
  406. FILE *f = fopen(ETC_LDSO_PATH, "r");
  407. if (f) {
  408. if (getline(&sys_path, (size_t[1]){0}, f) > 0)
  409. sys_path[strlen(sys_path)-1]=0;
  410. fclose(f);
  411. }
  412. }
  413. if (sys_path) fd = path_open(name, sys_path, buf, sizeof buf);
  414. else fd = path_open(name, "/lib:/usr/local/lib:/usr/lib", buf, sizeof buf);
  415. }
  416. pathname = buf;
  417. }
  418. if (fd < 0) return 0;
  419. if (fstat(fd, &st) < 0) {
  420. close(fd);
  421. return 0;
  422. }
  423. for (p=head->next; p; p=p->next) {
  424. if (p->dev == st.st_dev && p->ino == st.st_ino) {
  425. /* If this library was previously loaded with a
  426. * pathname but a search found the same inode,
  427. * setup its shortname so it can be found by name. */
  428. if (!p->shortname) p->shortname = strrchr(p->name, '/')+1;
  429. close(fd);
  430. p->refcnt++;
  431. return p;
  432. }
  433. }
  434. map = map_library(fd, &map_len, &base, &dyno);
  435. close(fd);
  436. if (!map) return 0;
  437. p = calloc(1, sizeof *p + strlen(pathname) + 1);
  438. if (!p) {
  439. munmap(map, map_len);
  440. return 0;
  441. }
  442. p->map = map;
  443. p->map_len = map_len;
  444. p->base = base;
  445. p->dynv = (void *)(base + dyno);
  446. decode_dyn(p);
  447. p->dev = st.st_dev;
  448. p->ino = st.st_ino;
  449. p->refcnt = 1;
  450. p->name = p->buf;
  451. strcpy(p->name, pathname);
  452. /* Add a shortname only if name arg was not an explicit pathname. */
  453. if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
  454. tail->next = p;
  455. p->prev = tail;
  456. tail = p;
  457. if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, base);
  458. return p;
  459. }
  460. static void load_deps(struct dso *p)
  461. {
  462. size_t i, ndeps=0;
  463. struct dso ***deps = &p->deps, **tmp, *dep;
  464. for (; p; p=p->next) {
  465. for (i=0; p->dynv[i]; i+=2) {
  466. if (p->dynv[i] != DT_RPATH) continue;
  467. r_path = (void *)(p->strings + p->dynv[i+1]);
  468. }
  469. for (i=0; p->dynv[i]; i+=2) {
  470. if (p->dynv[i] != DT_NEEDED) continue;
  471. dep = load_library(p->strings + p->dynv[i+1]);
  472. if (!dep) {
  473. snprintf(errbuf, sizeof errbuf,
  474. "Error loading shared library %s: %m (needed by %s)",
  475. p->strings + p->dynv[i+1], p->name);
  476. if (runtime) longjmp(rtld_fail, 1);
  477. dprintf(2, "%s\n", errbuf);
  478. ldso_fail = 1;
  479. continue;
  480. }
  481. if (runtime) {
  482. tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2));
  483. if (!tmp) longjmp(rtld_fail, 1);
  484. tmp[ndeps++] = dep;
  485. tmp[ndeps] = 0;
  486. *deps = tmp;
  487. }
  488. }
  489. r_path = 0;
  490. }
  491. }
  492. static void load_preload(char *s)
  493. {
  494. int tmp;
  495. char *z;
  496. for (z=s; *z; s=z) {
  497. for ( ; *s && isspace(*s); s++);
  498. for (z=s; *z && !isspace(*z); z++);
  499. tmp = *z;
  500. *z = 0;
  501. load_library(s);
  502. *z = tmp;
  503. }
  504. }
  505. static void make_global(struct dso *p)
  506. {
  507. for (; p; p=p->next) p->global = 1;
  508. }
  509. static void reloc_all(struct dso *p)
  510. {
  511. size_t dyn[DYN_CNT] = {0};
  512. for (; p; p=p->next) {
  513. if (p->relocated) continue;
  514. decode_vec(p->dynv, dyn, DYN_CNT);
  515. #ifdef NEED_ARCH_RELOCS
  516. do_arch_relocs(p, head);
  517. #endif
  518. do_relocs(p, (void *)(p->base+dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],
  519. 2+(dyn[DT_PLTREL]==DT_RELA));
  520. do_relocs(p, (void *)(p->base+dyn[DT_REL]), dyn[DT_RELSZ], 2);
  521. do_relocs(p, (void *)(p->base+dyn[DT_RELA]), dyn[DT_RELASZ], 3);
  522. p->relocated = 1;
  523. }
  524. }
  525. static void free_all(struct dso *p)
  526. {
  527. struct dso *n;
  528. while (p) {
  529. n = p->next;
  530. if (p->map) free(p);
  531. p = n;
  532. }
  533. }
  534. static size_t find_dyn(Phdr *ph, size_t cnt, size_t stride)
  535. {
  536. for (; cnt--; ph = (void *)((char *)ph + stride))
  537. if (ph->p_type == PT_DYNAMIC)
  538. return ph->p_vaddr;
  539. return 0;
  540. }
  541. static void do_init_fini(struct dso *p)
  542. {
  543. size_t dyn[DYN_CNT] = {0};
  544. for (; p; p=p->prev) {
  545. if (p->constructed) return;
  546. decode_vec(p->dynv, dyn, DYN_CNT);
  547. if (dyn[0] & (1<<DT_FINI))
  548. atexit((void (*)(void))(p->base + dyn[DT_FINI]));
  549. if (dyn[0] & (1<<DT_INIT))
  550. ((void (*)(void))(p->base + dyn[DT_INIT]))();
  551. p->constructed = 1;
  552. }
  553. }
  554. void _dl_debug_state(void)
  555. {
  556. }
  557. void *__dynlink(int argc, char **argv)
  558. {
  559. size_t aux[AUX_CNT] = {0};
  560. size_t i;
  561. Phdr *phdr;
  562. Ehdr *ehdr;
  563. static struct dso builtin_dsos[3];
  564. struct dso *const app = builtin_dsos+0;
  565. struct dso *const lib = builtin_dsos+1;
  566. struct dso *const vdso = builtin_dsos+2;
  567. char *env_preload=0;
  568. /* Find aux vector just past environ[] */
  569. for (i=argc+1; argv[i]; i++)
  570. if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16))
  571. env_path = argv[i]+16;
  572. else if (!memcmp(argv[i], "LD_PRELOAD=", 11))
  573. env_preload = argv[i]+11;
  574. auxv = (void *)(argv+i+1);
  575. decode_vec(auxv, aux, AUX_CNT);
  576. /* Only trust user/env if kernel says we're not suid/sgid */
  577. if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
  578. || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]) {
  579. env_path = 0;
  580. env_preload = 0;
  581. }
  582. /* If the dynamic linker was invoked as a program itself, AT_BASE
  583. * will not be set. In that case, we assume the base address is
  584. * the start of the page containing the PHDRs; I don't know any
  585. * better approach... */
  586. if (!aux[AT_BASE]) {
  587. aux[AT_BASE] = aux[AT_PHDR] & -PAGE_SIZE;
  588. aux[AT_PHDR] = aux[AT_PHENT] = aux[AT_PHNUM] = 0;
  589. }
  590. /* The dynamic linker load address is passed by the kernel
  591. * in the AUX vector, so this is easy. */
  592. lib->base = (void *)aux[AT_BASE];
  593. lib->name = lib->shortname = "libc.so";
  594. lib->global = 1;
  595. ehdr = (void *)lib->base;
  596. lib->dynv = (void *)(lib->base + find_dyn(
  597. (void *)(aux[AT_BASE]+ehdr->e_phoff),
  598. ehdr->e_phnum, ehdr->e_phentsize));
  599. decode_dyn(lib);
  600. if (aux[AT_PHDR]) {
  601. size_t interp_off = 0;
  602. /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
  603. phdr = (void *)aux[AT_PHDR];
  604. for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
  605. if (phdr->p_type == PT_PHDR)
  606. app->base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);
  607. else if (phdr->p_type == PT_INTERP)
  608. interp_off = (size_t)phdr->p_vaddr;
  609. }
  610. if (interp_off) lib->name = (char *)app->base + interp_off;
  611. app->name = argv[0];
  612. app->dynv = (void *)(app->base + find_dyn(
  613. (void *)aux[AT_PHDR], aux[AT_PHNUM], aux[AT_PHENT]));
  614. } else {
  615. int fd;
  616. char *ldname = argv[0];
  617. size_t dyno, l = strlen(ldname);
  618. if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;
  619. *argv++ = (void *)-1;
  620. if (argv[0] && !strcmp(argv[0], "--")) *argv++ = (void *)-1;
  621. if (!argv[0]) {
  622. dprintf(2, "musl libc/dynamic program loader\n");
  623. dprintf(2, "usage: %s pathname%s\n", ldname,
  624. ldd_mode ? "" : " [args]");
  625. _exit(1);
  626. }
  627. fd = open(argv[0], O_RDONLY);
  628. if (fd < 0) {
  629. dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));
  630. _exit(1);
  631. }
  632. runtime = 1;
  633. ehdr = (void *)map_library(fd, &app->map_len, &app->base, &dyno);
  634. if (!ehdr) {
  635. dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
  636. _exit(1);
  637. }
  638. runtime = 0;
  639. close(fd);
  640. lib->name = ldname;
  641. app->name = argv[0];
  642. app->dynv = (void *)(app->base + dyno);
  643. aux[AT_ENTRY] = ehdr->e_entry;
  644. }
  645. app->global = 1;
  646. app->constructed = 1;
  647. decode_dyn(app);
  648. /* Attach to vdso, if provided by the kernel */
  649. if (search_vec(auxv, aux, AT_SYSINFO_EHDR)) {
  650. size_t vdso_base = *aux;
  651. ehdr = (void *)vdso_base;
  652. phdr = (void *)(vdso_base + ehdr->e_phoff);
  653. for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
  654. if (phdr->p_type == PT_DYNAMIC)
  655. vdso->dynv = (void *)(vdso_base + phdr->p_offset);
  656. if (phdr->p_type == PT_LOAD)
  657. vdso->base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
  658. }
  659. vdso->name = vdso->shortname = "linux-gate.so.1";
  660. vdso->global = 1;
  661. decode_dyn(vdso);
  662. vdso->prev = lib;
  663. lib->next = vdso;
  664. }
  665. /* Initial dso chain consists only of the app. We temporarily
  666. * append the dynamic linker/libc so we can relocate it, then
  667. * restore the initial chain in preparation for loading third
  668. * party libraries (preload/needed). */
  669. head = tail = app;
  670. libc = lib;
  671. app->next = lib;
  672. reloc_all(lib);
  673. app->next = 0;
  674. /* PAST THIS POINT, ALL LIBC INTERFACES ARE FULLY USABLE. */
  675. /* Donate unused parts of app and library mapping to malloc */
  676. reclaim_gaps(app->base, (void *)aux[AT_PHDR], aux[AT_PHENT], aux[AT_PHNUM]);
  677. ehdr = (void *)lib->base;
  678. reclaim_gaps(lib->base, (void *)(lib->base+ehdr->e_phoff),
  679. ehdr->e_phentsize, ehdr->e_phnum);
  680. /* Load preload/needed libraries, add their symbols to the global
  681. * namespace, and perform all remaining relocations. The main
  682. * program must be relocated LAST since it may contain copy
  683. * relocations which depend on libraries' relocations. */
  684. if (env_preload) load_preload(env_preload);
  685. load_deps(app);
  686. make_global(app);
  687. reloc_all(app->next);
  688. reloc_all(app);
  689. if (ldso_fail) _exit(127);
  690. if (ldd_mode) _exit(0);
  691. /* Switch to runtime mode: any further failures in the dynamic
  692. * linker are a reportable failure rather than a fatal startup
  693. * error. If the dynamic loader (dlopen) will not be used, free
  694. * all memory used by the dynamic linker. */
  695. runtime = 1;
  696. #ifndef DYNAMIC_IS_RO
  697. for (i=0; app->dynv[i]; i+=2)
  698. if (app->dynv[i]==DT_DEBUG)
  699. app->dynv[i+1] = (size_t)&debug;
  700. #endif
  701. debug.ver = 1;
  702. debug.bp = _dl_debug_state;
  703. debug.head = head;
  704. debug.base = lib->base;
  705. debug.state = 0;
  706. _dl_debug_state();
  707. if (ssp_used) __init_ssp(auxv);
  708. do_init_fini(tail);
  709. if (!rtld_used) {
  710. free_all(head);
  711. free(sys_path);
  712. reclaim((void *)builtin_dsos, 0, sizeof builtin_dsos);
  713. }
  714. errno = 0;
  715. return (void *)aux[AT_ENTRY];
  716. }
  717. void *dlopen(const char *file, int mode)
  718. {
  719. struct dso *volatile p, *orig_tail = tail, *next;
  720. size_t i;
  721. int cs;
  722. if (!file) return head;
  723. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
  724. pthread_rwlock_wrlock(&lock);
  725. if (setjmp(rtld_fail)) {
  726. /* Clean up anything new that was (partially) loaded */
  727. if (p->deps) for (i=0; p->deps[i]; i++)
  728. if (p->deps[i]->global < 0)
  729. p->deps[i]->global = 0;
  730. for (p=orig_tail->next; p; p=next) {
  731. next = p->next;
  732. munmap(p->map, p->map_len);
  733. free(p->deps);
  734. free(p);
  735. }
  736. tail = orig_tail;
  737. tail->next = 0;
  738. p = 0;
  739. errflag = 1;
  740. goto end;
  741. } else p = load_library(file);
  742. if (!p) {
  743. snprintf(errbuf, sizeof errbuf,
  744. "Error loading shared library %s: %m", file);
  745. errflag = 1;
  746. goto end;
  747. }
  748. /* First load handling */
  749. if (!p->deps) {
  750. load_deps(p);
  751. if (p->deps) for (i=0; p->deps[i]; i++)
  752. if (!p->deps[i]->global)
  753. p->deps[i]->global = -1;
  754. if (!p->global) p->global = -1;
  755. reloc_all(p);
  756. if (p->deps) for (i=0; p->deps[i]; i++)
  757. if (p->deps[i]->global < 0)
  758. p->deps[i]->global = 0;
  759. if (p->global < 0) p->global = 0;
  760. }
  761. if (mode & RTLD_GLOBAL) {
  762. if (p->deps) for (i=0; p->deps[i]; i++)
  763. p->deps[i]->global = 1;
  764. p->global = 1;
  765. }
  766. if (ssp_used) __init_ssp(auxv);
  767. _dl_debug_state();
  768. do_init_fini(tail);
  769. end:
  770. pthread_rwlock_unlock(&lock);
  771. pthread_setcancelstate(cs, 0);
  772. return p;
  773. }
  774. static void *do_dlsym(struct dso *p, const char *s, void *ra)
  775. {
  776. size_t i;
  777. uint32_t h = 0, gh = 0;
  778. Sym *sym;
  779. if (p == RTLD_NEXT) {
  780. for (p=head; p && (unsigned char *)ra-p->map>p->map_len; p=p->next);
  781. if (!p) p=head;
  782. void *res = find_sym(p->next, s, 0);
  783. if (!res) goto failed;
  784. return res;
  785. }
  786. if (p == head || p == RTLD_DEFAULT) {
  787. void *res = find_sym(head, s, 0);
  788. if (!res) goto failed;
  789. return res;
  790. }
  791. if (p->ghashtab) {
  792. gh = gnu_hash(s);
  793. sym = gnu_lookup(s, gh, p);
  794. } else {
  795. h = sysv_hash(s);
  796. sym = sysv_lookup(s, h, p);
  797. }
  798. if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
  799. return p->base + sym->st_value;
  800. if (p->deps) for (i=0; p->deps[i]; i++) {
  801. if (p->deps[i]->ghashtab) {
  802. if (!gh) gh = gnu_hash(s);
  803. sym = gnu_lookup(s, h, p->deps[i]);
  804. } else {
  805. if (!h) h = sysv_hash(s);
  806. sym = sysv_lookup(s, h, p->deps[i]);
  807. }
  808. if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
  809. return p->deps[i]->base + sym->st_value;
  810. }
  811. failed:
  812. errflag = 1;
  813. snprintf(errbuf, sizeof errbuf, "Symbol not found: %s", s);
  814. return 0;
  815. }
  816. void *__dlsym(void *p, const char *s, void *ra)
  817. {
  818. void *res;
  819. pthread_rwlock_rdlock(&lock);
  820. res = do_dlsym(p, s, ra);
  821. pthread_rwlock_unlock(&lock);
  822. return res;
  823. }
  824. #else
  825. void *dlopen(const char *file, int mode)
  826. {
  827. return 0;
  828. }
  829. void *__dlsym(void *p, const char *s, void *ra)
  830. {
  831. return 0;
  832. }
  833. #endif
  834. char *dlerror()
  835. {
  836. if (!errflag) return 0;
  837. errflag = 0;
  838. return errbuf;
  839. }
  840. int dlclose(void *p)
  841. {
  842. return 0;
  843. }