dynlink.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <stdint.h>
  7. #include <elf.h>
  8. #include <sys/mman.h>
  9. #include <limits.h>
  10. #include <stdint.h>
  11. #include <fcntl.h>
  12. #include <sys/stat.h>
  13. #include <errno.h>
  14. #include <limits.h>
  15. #include <elf.h>
  16. #include <link.h>
  17. #include <setjmp.h>
  18. #include <pthread.h>
  19. #include <ctype.h>
  20. #include <dlfcn.h>
  21. #include "pthread_impl.h"
  22. #include "libc.h"
  23. static int errflag;
  24. static char errbuf[128];
  25. #ifdef SHARED
  26. #if ULONG_MAX == 0xffffffff
  27. typedef Elf32_Ehdr Ehdr;
  28. typedef Elf32_Phdr Phdr;
  29. typedef Elf32_Sym Sym;
  30. #define R_TYPE(x) ((x)&255)
  31. #define R_SYM(x) ((x)>>8)
  32. #else
  33. typedef Elf64_Ehdr Ehdr;
  34. typedef Elf64_Phdr Phdr;
  35. typedef Elf64_Sym Sym;
  36. #define R_TYPE(x) ((x)&0xffffffff)
  37. #define R_SYM(x) ((x)>>32)
  38. #endif
  39. #define MAXP2(a,b) (-(-(a)&-(b)))
  40. #define ALIGN(x,y) ((x)+(y)-1 & -(y))
  41. struct debug {
  42. int ver;
  43. void *head;
  44. void (*bp)(void);
  45. int state;
  46. void *base;
  47. };
  48. struct dso {
  49. unsigned char *base;
  50. char *name;
  51. size_t *dynv;
  52. struct dso *next, *prev;
  53. Phdr *phdr;
  54. int phnum;
  55. int refcnt;
  56. Sym *syms;
  57. uint32_t *hashtab;
  58. uint32_t *ghashtab;
  59. char *strings;
  60. unsigned char *map;
  61. size_t map_len;
  62. dev_t dev;
  63. ino_t ino;
  64. signed char global;
  65. char relocated;
  66. char constructed;
  67. struct dso **deps;
  68. void *tls_image;
  69. size_t tls_len, tls_size, tls_align, tls_id, tls_offset;
  70. void **new_dtv;
  71. unsigned char *new_tls;
  72. int new_dtv_idx, new_tls_idx;
  73. struct dso *fini_next;
  74. char *shortname;
  75. char buf[];
  76. };
  77. struct symdef {
  78. Sym *sym;
  79. struct dso *dso;
  80. };
  81. #include "reloc.h"
  82. void __init_ssp(size_t *);
  83. void *__install_initial_tls(void *);
  84. static struct dso *head, *tail, *ldso, *fini_head;
  85. static char *env_path, *sys_path, *r_path;
  86. static unsigned long long gencnt;
  87. static int ssp_used;
  88. static int runtime;
  89. static int ldd_mode;
  90. static int ldso_fail;
  91. static jmp_buf rtld_fail;
  92. static pthread_rwlock_t lock;
  93. static struct debug debug;
  94. static size_t tls_cnt, tls_offset, tls_align = 4*sizeof(size_t);
  95. static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
  96. struct debug *_dl_debug_addr = &debug;
  97. #define AUX_CNT 38
  98. #define DYN_CNT 34
  99. static void decode_vec(size_t *v, size_t *a, size_t cnt)
  100. {
  101. memset(a, 0, cnt*sizeof(size_t));
  102. for (; v[0]; v+=2) if (v[0]<cnt) {
  103. a[0] |= 1ULL<<v[0];
  104. a[v[0]] = v[1];
  105. }
  106. }
  107. static int search_vec(size_t *v, size_t *r, size_t key)
  108. {
  109. for (; v[0]!=key; v+=2)
  110. if (!v[0]) return 0;
  111. *r = v[1];
  112. return 1;
  113. }
  114. static uint32_t sysv_hash(const char *s0)
  115. {
  116. const unsigned char *s = (void *)s0;
  117. uint_fast32_t h = 0;
  118. while (*s) {
  119. h = 16*h + *s++;
  120. h ^= h>>24 & 0xf0;
  121. }
  122. return h & 0xfffffff;
  123. }
  124. static uint32_t gnu_hash(const char *s0)
  125. {
  126. const unsigned char *s = (void *)s0;
  127. uint_fast32_t h = 5381;
  128. for (; *s; s++)
  129. h = h*33 + *s;
  130. return h;
  131. }
  132. static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)
  133. {
  134. size_t i;
  135. Sym *syms = dso->syms;
  136. uint32_t *hashtab = dso->hashtab;
  137. char *strings = dso->strings;
  138. for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
  139. if (!strcmp(s, strings+syms[i].st_name))
  140. return syms+i;
  141. }
  142. return 0;
  143. }
  144. static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
  145. {
  146. Sym *sym;
  147. char *strings;
  148. uint32_t *hashtab = dso->ghashtab;
  149. uint32_t nbuckets = hashtab[0];
  150. uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
  151. uint32_t h2;
  152. uint32_t *hashval;
  153. uint32_t n = buckets[h1 % nbuckets];
  154. if (!n) return 0;
  155. strings = dso->strings;
  156. sym = dso->syms + n;
  157. hashval = buckets + nbuckets + (n - hashtab[1]);
  158. for (h1 |= 1; ; sym++) {
  159. h2 = *hashval++;
  160. if ((h1 == (h2|1)) && !strcmp(s, strings + sym->st_name))
  161. return sym;
  162. if (h2 & 1) break;
  163. }
  164. return 0;
  165. }
  166. #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
  167. #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK)
  168. static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
  169. {
  170. uint32_t h = 0, gh = 0;
  171. struct symdef def = {0};
  172. if (dso->ghashtab) {
  173. gh = gnu_hash(s);
  174. if (gh == 0x1f4039c9 && !strcmp(s, "__stack_chk_fail")) ssp_used = 1;
  175. } else {
  176. h = sysv_hash(s);
  177. if (h == 0x595a4cc && !strcmp(s, "__stack_chk_fail")) ssp_used = 1;
  178. }
  179. for (; dso; dso=dso->next) {
  180. Sym *sym;
  181. if (!dso->global) continue;
  182. if (dso->ghashtab) {
  183. if (!gh) gh = gnu_hash(s);
  184. sym = gnu_lookup(s, gh, dso);
  185. } else {
  186. if (!h) h = sysv_hash(s);
  187. sym = sysv_lookup(s, h, dso);
  188. }
  189. if (!sym) continue;
  190. if (!sym->st_shndx)
  191. if (need_def || (sym->st_info&0xf) == STT_TLS)
  192. continue;
  193. if (!sym->st_value)
  194. if ((sym->st_info&0xf) != STT_TLS)
  195. continue;
  196. if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
  197. if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
  198. if (def.sym && sym->st_info>>4 == STB_WEAK) continue;
  199. def.sym = sym;
  200. def.dso = dso;
  201. if (sym->st_info>>4 == STB_GLOBAL) break;
  202. }
  203. return def;
  204. }
  205. static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
  206. {
  207. unsigned char *base = dso->base;
  208. Sym *syms = dso->syms;
  209. char *strings = dso->strings;
  210. Sym *sym;
  211. const char *name;
  212. void *ctx;
  213. int type;
  214. int sym_index;
  215. struct symdef def;
  216. for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
  217. type = R_TYPE(rel[1]);
  218. sym_index = R_SYM(rel[1]);
  219. if (sym_index) {
  220. sym = syms + sym_index;
  221. name = strings + sym->st_name;
  222. ctx = IS_COPY(type) ? head->next : head;
  223. def = find_sym(ctx, name, IS_PLT(type));
  224. if (!def.sym && sym->st_info>>4 != STB_WEAK) {
  225. snprintf(errbuf, sizeof errbuf,
  226. "Error relocating %s: %s: symbol not found",
  227. dso->name, name);
  228. if (runtime) longjmp(rtld_fail, 1);
  229. dprintf(2, "%s\n", errbuf);
  230. ldso_fail = 1;
  231. continue;
  232. }
  233. } else {
  234. sym = 0;
  235. def.sym = 0;
  236. def.dso = 0;
  237. }
  238. do_single_reloc(dso, base, (void *)(base + rel[0]), type,
  239. stride>2 ? rel[2] : 0, sym, sym?sym->st_size:0, def,
  240. def.sym?(size_t)(def.dso->base+def.sym->st_value):0);
  241. }
  242. }
  243. /* A huge hack: to make up for the wastefulness of shared libraries
  244. * needing at least a page of dirty memory even if they have no global
  245. * data, we reclaim the gaps at the beginning and end of writable maps
  246. * and "donate" them to the heap by setting up minimal malloc
  247. * structures and then freeing them. */
  248. static void reclaim(unsigned char *base, size_t start, size_t end)
  249. {
  250. size_t *a, *z;
  251. start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t);
  252. end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t);
  253. if (start>end || end-start < 4*sizeof(size_t)) return;
  254. a = (size_t *)(base + start);
  255. z = (size_t *)(base + end);
  256. a[-2] = 1;
  257. a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1;
  258. z[1] = 1;
  259. free(a);
  260. }
  261. static void reclaim_gaps(unsigned char *base, Phdr *ph, size_t phent, size_t phcnt)
  262. {
  263. for (; phcnt--; ph=(void *)((char *)ph+phent)) {
  264. if (ph->p_type!=PT_LOAD) continue;
  265. if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;
  266. reclaim(base, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);
  267. reclaim(base, ph->p_vaddr+ph->p_memsz,
  268. ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);
  269. }
  270. }
  271. static void *map_library(int fd, struct dso *dso)
  272. {
  273. Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
  274. size_t phsize;
  275. size_t addr_min=SIZE_MAX, addr_max=0, map_len;
  276. size_t this_min, this_max;
  277. off_t off_start;
  278. Ehdr *eh;
  279. Phdr *ph;
  280. unsigned prot;
  281. unsigned char *map, *base;
  282. size_t dyn;
  283. size_t tls_image=0;
  284. size_t i;
  285. ssize_t l = read(fd, buf, sizeof buf);
  286. if (l<sizeof *eh) return 0;
  287. eh = buf;
  288. phsize = eh->e_phentsize * eh->e_phnum;
  289. if (phsize + sizeof *eh > l) return 0;
  290. if (eh->e_phoff + phsize > l) {
  291. l = pread(fd, buf+1, phsize, eh->e_phoff);
  292. if (l != phsize) return 0;
  293. eh->e_phoff = sizeof *eh;
  294. }
  295. ph = (void *)((char *)buf + eh->e_phoff);
  296. dso->phdr = ph;
  297. dso->phnum = eh->e_phnum;
  298. for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
  299. if (ph->p_type == PT_DYNAMIC)
  300. dyn = ph->p_vaddr;
  301. if (ph->p_type == PT_TLS) {
  302. tls_image = ph->p_vaddr;
  303. dso->tls_align = ph->p_align;
  304. dso->tls_len = ph->p_filesz;
  305. dso->tls_size = ph->p_memsz;
  306. }
  307. if (ph->p_type != PT_LOAD) continue;
  308. if (ph->p_vaddr < addr_min) {
  309. addr_min = ph->p_vaddr;
  310. off_start = ph->p_offset;
  311. prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
  312. ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
  313. ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
  314. }
  315. if (ph->p_vaddr+ph->p_memsz > addr_max) {
  316. addr_max = ph->p_vaddr+ph->p_memsz;
  317. }
  318. }
  319. if (!dyn) return 0;
  320. addr_max += PAGE_SIZE-1;
  321. addr_max &= -PAGE_SIZE;
  322. addr_min &= -PAGE_SIZE;
  323. off_start &= -PAGE_SIZE;
  324. map_len = addr_max - addr_min + off_start;
  325. /* The first time, we map too much, possibly even more than
  326. * the length of the file. This is okay because we will not
  327. * use the invalid part; we just need to reserve the right
  328. * amount of virtual address space to map over later. */
  329. map = mmap((void *)addr_min, map_len, prot, MAP_PRIVATE, fd, off_start);
  330. if (map==MAP_FAILED) return 0;
  331. base = map - addr_min;
  332. ph = (void *)((char *)buf + eh->e_phoff);
  333. for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
  334. if (ph->p_type != PT_LOAD) continue;
  335. /* Reuse the existing mapping for the lowest-address LOAD */
  336. if ((ph->p_vaddr & -PAGE_SIZE) == addr_min) continue;
  337. this_min = ph->p_vaddr & -PAGE_SIZE;
  338. this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
  339. off_start = ph->p_offset & -PAGE_SIZE;
  340. prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
  341. ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
  342. ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
  343. if (mmap(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
  344. goto error;
  345. if (ph->p_memsz > ph->p_filesz) {
  346. size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
  347. size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
  348. memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
  349. 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)
  350. goto error;
  351. }
  352. }
  353. for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
  354. if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
  355. if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC) < 0)
  356. goto error;
  357. break;
  358. }
  359. if (!runtime) reclaim_gaps(base, (void *)((char *)buf + eh->e_phoff),
  360. eh->e_phentsize, eh->e_phnum);
  361. dso->map = map;
  362. dso->map_len = map_len;
  363. dso->base = base;
  364. dso->dynv = (void *)(base+dyn);
  365. if (dso->tls_size) dso->tls_image = (void *)(base+tls_image);
  366. return map;
  367. error:
  368. munmap(map, map_len);
  369. return 0;
  370. }
  371. static int path_open(const char *name, const char *search, char *buf, size_t buf_size)
  372. {
  373. const char *s=search, *z;
  374. int l, fd;
  375. for (;;) {
  376. while (*s==':') s++;
  377. if (!*s) return -1;
  378. z = strchr(s, ':');
  379. l = z ? z-s : strlen(s);
  380. snprintf(buf, buf_size, "%.*s/%s", l, s, name);
  381. if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;
  382. s += l;
  383. }
  384. }
  385. static void decode_dyn(struct dso *p)
  386. {
  387. size_t dyn[DYN_CNT] = {0};
  388. decode_vec(p->dynv, dyn, DYN_CNT);
  389. p->syms = (void *)(p->base + dyn[DT_SYMTAB]);
  390. p->strings = (void *)(p->base + dyn[DT_STRTAB]);
  391. if (dyn[0]&(1<<DT_HASH))
  392. p->hashtab = (void *)(p->base + dyn[DT_HASH]);
  393. if (search_vec(p->dynv, dyn, DT_GNU_HASH))
  394. p->ghashtab = (void *)(p->base + *dyn);
  395. }
  396. static struct dso *load_library(const char *name)
  397. {
  398. char buf[2*NAME_MAX+2];
  399. const char *pathname;
  400. unsigned char *base, *map;
  401. size_t map_len;
  402. struct dso *p, temp_dso = {0};
  403. int fd;
  404. struct stat st;
  405. size_t alloc_size;
  406. int n_th = 0;
  407. /* Catch and block attempts to reload the implementation itself */
  408. if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
  409. static const char *rp, reserved[] =
  410. "c\0pthread\0rt\0m\0dl\0util\0xnet\0";
  411. char *z = strchr(name, '.');
  412. if (z) {
  413. size_t l = z-name;
  414. for (rp=reserved; *rp && memcmp(name+3, rp, l-3); rp+=strlen(rp)+1);
  415. if (*rp) {
  416. if (!ldso->prev) {
  417. tail->next = ldso;
  418. ldso->prev = tail;
  419. tail = ldso->next ? ldso->next : ldso;
  420. }
  421. return ldso;
  422. }
  423. }
  424. }
  425. if (strchr(name, '/')) {
  426. pathname = name;
  427. fd = open(name, O_RDONLY|O_CLOEXEC);
  428. } else {
  429. /* Search for the name to see if it's already loaded */
  430. for (p=head->next; p; p=p->next) {
  431. if (p->shortname && !strcmp(p->shortname, name)) {
  432. p->refcnt++;
  433. return p;
  434. }
  435. }
  436. if (strlen(name) > NAME_MAX) return 0;
  437. fd = -1;
  438. if (r_path) fd = path_open(name, r_path, buf, sizeof buf);
  439. if (fd < 0 && env_path) fd = path_open(name, env_path, buf, sizeof buf);
  440. if (fd < 0) {
  441. if (!sys_path) {
  442. FILE *f = fopen(ETC_LDSO_PATH, "rbe");
  443. if (f) {
  444. if (getline(&sys_path, (size_t[1]){0}, f) > 0) {
  445. size_t l = strlen(sys_path);
  446. if (l && sys_path[l-1]=='\n')
  447. sys_path[l-1] = 0;
  448. }
  449. fclose(f);
  450. }
  451. }
  452. if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
  453. fd = path_open(name, sys_path, buf, sizeof buf);
  454. }
  455. pathname = buf;
  456. }
  457. if (fd < 0) return 0;
  458. if (fstat(fd, &st) < 0) {
  459. close(fd);
  460. return 0;
  461. }
  462. for (p=head->next; p; p=p->next) {
  463. if (p->dev == st.st_dev && p->ino == st.st_ino) {
  464. /* If this library was previously loaded with a
  465. * pathname but a search found the same inode,
  466. * setup its shortname so it can be found by name. */
  467. if (!p->shortname && pathname != name)
  468. p->shortname = strrchr(p->name, '/')+1;
  469. close(fd);
  470. p->refcnt++;
  471. return p;
  472. }
  473. }
  474. map = map_library(fd, &temp_dso);
  475. close(fd);
  476. if (!map) return 0;
  477. /* Allocate storage for the new DSO. When there is TLS, this
  478. * storage must include a reservation for all pre-existing
  479. * threads to obtain copies of both the new TLS, and an
  480. * extended DTV capable of storing an additional slot for
  481. * the newly-loaded DSO. */
  482. alloc_size = sizeof *p + strlen(pathname) + 1;
  483. if (runtime && temp_dso.tls_image) {
  484. size_t per_th = temp_dso.tls_size + temp_dso.tls_align
  485. + sizeof(void *) * (tls_cnt+3);
  486. n_th = libc.threads_minus_1 + 1;
  487. if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
  488. else alloc_size += n_th * per_th;
  489. }
  490. p = calloc(1, alloc_size);
  491. if (!p) {
  492. munmap(map, map_len);
  493. return 0;
  494. }
  495. memcpy(p, &temp_dso, sizeof temp_dso);
  496. decode_dyn(p);
  497. p->dev = st.st_dev;
  498. p->ino = st.st_ino;
  499. p->refcnt = 1;
  500. p->name = p->buf;
  501. strcpy(p->name, pathname);
  502. /* Add a shortname only if name arg was not an explicit pathname. */
  503. if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
  504. if (p->tls_image) {
  505. if (runtime && !__pthread_self_init()) {
  506. free(p);
  507. munmap(map, map_len);
  508. return 0;
  509. }
  510. p->tls_id = ++tls_cnt;
  511. tls_align = MAXP2(tls_align, p->tls_align);
  512. #ifdef TLS_ABOVE_TP
  513. p->tls_offset = tls_offset + ( (tls_align-1) &
  514. -(tls_offset + (uintptr_t)p->tls_image) );
  515. tls_offset += p->tls_size;
  516. #else
  517. tls_offset += p->tls_size + p->tls_align - 1;
  518. tls_offset -= (tls_offset + (uintptr_t)p->tls_image)
  519. & (p->tls_align-1);
  520. p->tls_offset = tls_offset;
  521. #endif
  522. p->new_dtv = (void *)(-sizeof(size_t) &
  523. (uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
  524. p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
  525. }
  526. tail->next = p;
  527. p->prev = tail;
  528. tail = p;
  529. if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, base);
  530. return p;
  531. }
  532. static void load_deps(struct dso *p)
  533. {
  534. size_t i, ndeps=0;
  535. struct dso ***deps = &p->deps, **tmp, *dep;
  536. for (; p; p=p->next) {
  537. for (i=0; p->dynv[i]; i+=2) {
  538. if (p->dynv[i] != DT_RPATH) continue;
  539. r_path = (void *)(p->strings + p->dynv[i+1]);
  540. }
  541. for (i=0; p->dynv[i]; i+=2) {
  542. if (p->dynv[i] != DT_NEEDED) continue;
  543. dep = load_library(p->strings + p->dynv[i+1]);
  544. if (!dep) {
  545. snprintf(errbuf, sizeof errbuf,
  546. "Error loading shared library %s: %m (needed by %s)",
  547. p->strings + p->dynv[i+1], p->name);
  548. if (runtime) longjmp(rtld_fail, 1);
  549. dprintf(2, "%s\n", errbuf);
  550. ldso_fail = 1;
  551. continue;
  552. }
  553. if (runtime) {
  554. tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2));
  555. if (!tmp) longjmp(rtld_fail, 1);
  556. tmp[ndeps++] = dep;
  557. tmp[ndeps] = 0;
  558. *deps = tmp;
  559. }
  560. }
  561. r_path = 0;
  562. }
  563. }
  564. static void load_preload(char *s)
  565. {
  566. int tmp;
  567. char *z;
  568. for (z=s; *z; s=z) {
  569. for ( ; *s && isspace(*s); s++);
  570. for (z=s; *z && !isspace(*z); z++);
  571. tmp = *z;
  572. *z = 0;
  573. load_library(s);
  574. *z = tmp;
  575. }
  576. }
  577. static void make_global(struct dso *p)
  578. {
  579. for (; p; p=p->next) p->global = 1;
  580. }
  581. static void reloc_all(struct dso *p)
  582. {
  583. size_t dyn[DYN_CNT] = {0};
  584. for (; p; p=p->next) {
  585. if (p->relocated) continue;
  586. decode_vec(p->dynv, dyn, DYN_CNT);
  587. #ifdef NEED_ARCH_RELOCS
  588. do_arch_relocs(p, head);
  589. #endif
  590. do_relocs(p, (void *)(p->base+dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],
  591. 2+(dyn[DT_PLTREL]==DT_RELA));
  592. do_relocs(p, (void *)(p->base+dyn[DT_REL]), dyn[DT_RELSZ], 2);
  593. do_relocs(p, (void *)(p->base+dyn[DT_RELA]), dyn[DT_RELASZ], 3);
  594. p->relocated = 1;
  595. }
  596. }
  597. static size_t find_dyn(Phdr *ph, size_t cnt, size_t stride)
  598. {
  599. for (; cnt--; ph = (void *)((char *)ph + stride))
  600. if (ph->p_type == PT_DYNAMIC)
  601. return ph->p_vaddr;
  602. return 0;
  603. }
  604. static void find_map_range(Phdr *ph, size_t cnt, size_t stride, struct dso *p)
  605. {
  606. size_t min_addr = -1, max_addr = 0;
  607. for (; cnt--; ph = (void *)((char *)ph + stride)) {
  608. if (ph->p_type != PT_LOAD) continue;
  609. if (ph->p_vaddr < min_addr)
  610. min_addr = ph->p_vaddr;
  611. if (ph->p_vaddr+ph->p_memsz > max_addr)
  612. max_addr = ph->p_vaddr+ph->p_memsz;
  613. }
  614. min_addr &= -PAGE_SIZE;
  615. max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;
  616. p->map = p->base + min_addr;
  617. p->map_len = max_addr - min_addr;
  618. }
  619. static void do_fini()
  620. {
  621. struct dso *p;
  622. size_t dyn[DYN_CNT] = {0};
  623. for (p=fini_head; p; p=p->fini_next) {
  624. if (!p->constructed) continue;
  625. decode_vec(p->dynv, dyn, DYN_CNT);
  626. ((void (*)(void))(p->base + dyn[DT_FINI]))();
  627. }
  628. }
  629. static void do_init_fini(struct dso *p)
  630. {
  631. size_t dyn[DYN_CNT] = {0};
  632. int need_locking = libc.threads_minus_1;
  633. /* Allow recursive calls that arise when a library calls
  634. * dlopen from one of its constructors, but block any
  635. * other threads until all ctors have finished. */
  636. if (need_locking) pthread_mutex_lock(&init_fini_lock);
  637. for (; p; p=p->prev) {
  638. if (p->constructed) continue;
  639. p->constructed = 1;
  640. decode_vec(p->dynv, dyn, DYN_CNT);
  641. if (dyn[0] & (1<<DT_FINI)) {
  642. p->fini_next = fini_head;
  643. fini_head = p;
  644. }
  645. if (dyn[0] & (1<<DT_INIT))
  646. ((void (*)(void))(p->base + dyn[DT_INIT]))();
  647. }
  648. if (need_locking) pthread_mutex_unlock(&init_fini_lock);
  649. }
  650. void _dl_debug_state(void)
  651. {
  652. }
  653. void *__copy_tls(unsigned char *mem)
  654. {
  655. pthread_t td;
  656. struct dso *p;
  657. if (!tls_cnt) return mem;
  658. void **dtv = (void *)mem;
  659. dtv[0] = (void *)tls_cnt;
  660. #ifdef TLS_ABOVE_TP
  661. mem += sizeof(void *) * (tls_cnt+1);
  662. mem += -((uintptr_t)mem + sizeof(struct pthread)) & (tls_align-1);
  663. td = (pthread_t)mem;
  664. mem += sizeof(struct pthread);
  665. for (p=head; p; p=p->next) {
  666. if (!p->tls_id) continue;
  667. dtv[p->tls_id] = mem + p->tls_offset;
  668. memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
  669. }
  670. #else
  671. mem += libc.tls_size - sizeof(struct pthread);
  672. mem -= (uintptr_t)mem & (tls_align-1);
  673. td = (pthread_t)mem;
  674. for (p=head; p; p=p->next) {
  675. if (!p->tls_id) continue;
  676. dtv[p->tls_id] = mem - p->tls_offset;
  677. memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
  678. }
  679. #endif
  680. td->dtv = dtv;
  681. return td;
  682. }
  683. void *__tls_get_addr(size_t *v)
  684. {
  685. pthread_t self = __pthread_self();
  686. if (self->dtv && v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]])
  687. return (char *)self->dtv[v[0]]+v[1];
  688. /* Block signals to make accessing new TLS async-signal-safe */
  689. sigset_t set;
  690. pthread_sigmask(SIG_BLOCK, SIGALL_SET, &set);
  691. if (self->dtv && v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) {
  692. pthread_sigmask(SIG_SETMASK, &set, 0);
  693. return (char *)self->dtv[v[0]]+v[1];
  694. }
  695. /* This is safe without any locks held because, if the caller
  696. * is able to request the Nth entry of the DTV, the DSO list
  697. * must be valid at least that far out and it was synchronized
  698. * at program startup or by an already-completed call to dlopen. */
  699. struct dso *p;
  700. for (p=head; p->tls_id != v[0]; p=p->next);
  701. /* Get new DTV space from new DSO if needed */
  702. if (!self->dtv || v[0] > (size_t)self->dtv[0]) {
  703. void **newdtv = p->new_dtv +
  704. (v[0]+1)*sizeof(void *)*a_fetch_add(&p->new_dtv_idx,1);
  705. if (self->dtv) memcpy(newdtv, self->dtv,
  706. ((size_t)self->dtv[0]+1) * sizeof(void *));
  707. newdtv[0] = (void *)v[0];
  708. self->dtv = newdtv;
  709. }
  710. /* Get new TLS memory from new DSO */
  711. unsigned char *mem = p->new_tls +
  712. (p->tls_size + p->tls_align) * a_fetch_add(&p->new_tls_idx,1);
  713. mem += ((uintptr_t)p->tls_image - (uintptr_t)mem) & (p->tls_align-1);
  714. self->dtv[v[0]] = mem;
  715. memcpy(mem, p->tls_image, p->tls_len);
  716. pthread_sigmask(SIG_SETMASK, &set, 0);
  717. return mem + v[1];
  718. }
  719. static void update_tls_size()
  720. {
  721. libc.tls_size = ALIGN(
  722. (1+tls_cnt) * sizeof(void *) +
  723. tls_offset +
  724. sizeof(struct pthread) +
  725. tls_align * 2,
  726. tls_align);
  727. }
  728. void *__dynlink(int argc, char **argv)
  729. {
  730. size_t aux[AUX_CNT] = {0};
  731. size_t i;
  732. Phdr *phdr;
  733. Ehdr *ehdr;
  734. static struct dso builtin_dsos[3];
  735. struct dso *const app = builtin_dsos+0;
  736. struct dso *const lib = builtin_dsos+1;
  737. struct dso *const vdso = builtin_dsos+2;
  738. char *env_preload=0;
  739. size_t vdso_base;
  740. size_t *auxv;
  741. /* Find aux vector just past environ[] */
  742. for (i=argc+1; argv[i]; i++)
  743. if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16))
  744. env_path = argv[i]+16;
  745. else if (!memcmp(argv[i], "LD_PRELOAD=", 11))
  746. env_preload = argv[i]+11;
  747. auxv = (void *)(argv+i+1);
  748. decode_vec(auxv, aux, AUX_CNT);
  749. /* Only trust user/env if kernel says we're not suid/sgid */
  750. if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
  751. || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]) {
  752. env_path = 0;
  753. env_preload = 0;
  754. }
  755. /* If the dynamic linker was invoked as a program itself, AT_BASE
  756. * will not be set. In that case, we assume the base address is
  757. * the start of the page containing the PHDRs; I don't know any
  758. * better approach... */
  759. if (!aux[AT_BASE]) {
  760. aux[AT_BASE] = aux[AT_PHDR] & -PAGE_SIZE;
  761. aux[AT_PHDR] = aux[AT_PHENT] = aux[AT_PHNUM] = 0;
  762. }
  763. /* The dynamic linker load address is passed by the kernel
  764. * in the AUX vector, so this is easy. */
  765. lib->base = (void *)aux[AT_BASE];
  766. lib->name = lib->shortname = "libc.so";
  767. lib->global = 1;
  768. ehdr = (void *)lib->base;
  769. lib->phnum = ehdr->e_phnum;
  770. lib->phdr = (void *)(aux[AT_BASE]+ehdr->e_phoff);
  771. find_map_range(lib->phdr, ehdr->e_phnum, ehdr->e_phentsize, lib);
  772. lib->dynv = (void *)(lib->base + find_dyn(lib->phdr,
  773. ehdr->e_phnum, ehdr->e_phentsize));
  774. decode_dyn(lib);
  775. if (aux[AT_PHDR]) {
  776. size_t interp_off = 0;
  777. size_t tls_image = 0;
  778. /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
  779. app->phdr = phdr = (void *)aux[AT_PHDR];
  780. app->phnum = aux[AT_PHNUM];
  781. for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
  782. if (phdr->p_type == PT_PHDR)
  783. app->base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);
  784. else if (phdr->p_type == PT_INTERP)
  785. interp_off = (size_t)phdr->p_vaddr;
  786. else if (phdr->p_type == PT_TLS) {
  787. tls_image = phdr->p_vaddr;
  788. app->tls_len = phdr->p_filesz;
  789. app->tls_size = phdr->p_memsz;
  790. app->tls_align = phdr->p_align;
  791. }
  792. }
  793. if (app->tls_size) app->tls_image = (char *)app->base + tls_image;
  794. if (interp_off) lib->name = (char *)app->base + interp_off;
  795. app->name = argv[0];
  796. app->dynv = (void *)(app->base + find_dyn(
  797. (void *)aux[AT_PHDR], aux[AT_PHNUM], aux[AT_PHENT]));
  798. find_map_range((void *)aux[AT_PHDR],
  799. aux[AT_PHNUM], aux[AT_PHENT], app);
  800. } else {
  801. int fd;
  802. char *ldname = argv[0];
  803. size_t l = strlen(ldname);
  804. if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;
  805. *argv++ = (void *)-1;
  806. if (argv[0] && !strcmp(argv[0], "--")) *argv++ = (void *)-1;
  807. if (!argv[0]) {
  808. dprintf(2, "musl libc/dynamic program loader\n");
  809. dprintf(2, "usage: %s pathname%s\n", ldname,
  810. ldd_mode ? "" : " [args]");
  811. _exit(1);
  812. }
  813. fd = open(argv[0], O_RDONLY);
  814. if (fd < 0) {
  815. dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));
  816. _exit(1);
  817. }
  818. runtime = 1;
  819. ehdr = (void *)map_library(fd, app);
  820. if (!ehdr) {
  821. dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
  822. _exit(1);
  823. }
  824. runtime = 0;
  825. close(fd);
  826. lib->name = ldname;
  827. app->name = argv[0];
  828. app->phnum = ehdr->e_phnum;
  829. app->phdr = (void *)(app->base + ehdr->e_phoff);
  830. aux[AT_ENTRY] = ehdr->e_entry;
  831. }
  832. if (app->tls_size) {
  833. app->tls_id = tls_cnt = 1;
  834. #ifdef TLS_ABOVE_TP
  835. app->tls_offset = 0;
  836. tls_offset = app->tls_size
  837. + ( -((uintptr_t)app->tls_image + app->tls_size)
  838. & (app->tls_align-1) );
  839. #else
  840. tls_offset = app->tls_offset = app->tls_size
  841. + ( -((uintptr_t)app->tls_image + app->tls_size)
  842. & (app->tls_align-1) );
  843. #endif
  844. tls_align = MAXP2(tls_align, app->tls_align);
  845. }
  846. app->global = 1;
  847. app->constructed = 1;
  848. decode_dyn(app);
  849. /* Attach to vdso, if provided by the kernel */
  850. if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR)) {
  851. ehdr = (void *)vdso_base;
  852. vdso->phdr = phdr = (void *)(vdso_base + ehdr->e_phoff);
  853. vdso->phnum = ehdr->e_phnum;
  854. for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
  855. if (phdr->p_type == PT_DYNAMIC)
  856. vdso->dynv = (void *)(vdso_base + phdr->p_offset);
  857. if (phdr->p_type == PT_LOAD)
  858. vdso->base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
  859. }
  860. vdso->name = "";
  861. vdso->shortname = "linux-gate.so.1";
  862. vdso->global = 1;
  863. decode_dyn(vdso);
  864. vdso->prev = lib;
  865. lib->next = vdso;
  866. }
  867. /* Initial dso chain consists only of the app. We temporarily
  868. * append the dynamic linker/libc so we can relocate it, then
  869. * restore the initial chain in preparation for loading third
  870. * party libraries (preload/needed). */
  871. head = tail = app;
  872. ldso = lib;
  873. app->next = lib;
  874. reloc_all(lib);
  875. app->next = 0;
  876. /* PAST THIS POINT, ALL LIBC INTERFACES ARE FULLY USABLE. */
  877. /* Donate unused parts of app and library mapping to malloc */
  878. reclaim_gaps(app->base, (void *)aux[AT_PHDR], aux[AT_PHENT], aux[AT_PHNUM]);
  879. ehdr = (void *)lib->base;
  880. reclaim_gaps(lib->base, (void *)(lib->base+ehdr->e_phoff),
  881. ehdr->e_phentsize, ehdr->e_phnum);
  882. /* Load preload/needed libraries, add their symbols to the global
  883. * namespace, and perform all remaining relocations. The main
  884. * program must be relocated LAST since it may contain copy
  885. * relocations which depend on libraries' relocations. */
  886. if (env_preload) load_preload(env_preload);
  887. load_deps(app);
  888. make_global(app);
  889. reloc_all(app->next);
  890. reloc_all(app);
  891. update_tls_size();
  892. if (tls_cnt) {
  893. void *mem = mmap(0, libc.tls_size, PROT_READ|PROT_WRITE,
  894. MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
  895. if (mem==MAP_FAILED ||
  896. !__install_initial_tls(__copy_tls(mem))) {
  897. dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
  898. argv[0], libc.tls_size);
  899. _exit(127);
  900. }
  901. }
  902. if (ldso_fail) _exit(127);
  903. if (ldd_mode) _exit(0);
  904. /* Switch to runtime mode: any further failures in the dynamic
  905. * linker are a reportable failure rather than a fatal startup
  906. * error. If the dynamic loader (dlopen) will not be used, free
  907. * all memory used by the dynamic linker. */
  908. runtime = 1;
  909. #ifndef DYNAMIC_IS_RO
  910. for (i=0; app->dynv[i]; i+=2)
  911. if (app->dynv[i]==DT_DEBUG)
  912. app->dynv[i+1] = (size_t)&debug;
  913. #endif
  914. debug.ver = 1;
  915. debug.bp = _dl_debug_state;
  916. debug.head = head;
  917. debug.base = lib->base;
  918. debug.state = 0;
  919. _dl_debug_state();
  920. if (ssp_used) __init_ssp((void *)aux[AT_RANDOM]);
  921. atexit(do_fini);
  922. do_init_fini(tail);
  923. errno = 0;
  924. return (void *)aux[AT_ENTRY];
  925. }
  926. void *dlopen(const char *file, int mode)
  927. {
  928. struct dso *volatile p, *orig_tail, *next;
  929. size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
  930. size_t i;
  931. int cs;
  932. if (!file) return head;
  933. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
  934. pthread_rwlock_wrlock(&lock);
  935. __inhibit_ptc();
  936. p = 0;
  937. orig_tls_cnt = tls_cnt;
  938. orig_tls_offset = tls_offset;
  939. orig_tls_align = tls_align;
  940. orig_tail = tail;
  941. if (setjmp(rtld_fail)) {
  942. /* Clean up anything new that was (partially) loaded */
  943. if (p && p->deps) for (i=0; p->deps[i]; i++)
  944. if (p->deps[i]->global < 0)
  945. p->deps[i]->global = 0;
  946. for (p=orig_tail->next; p; p=next) {
  947. next = p->next;
  948. munmap(p->map, p->map_len);
  949. free(p->deps);
  950. free(p);
  951. }
  952. tls_cnt = orig_tls_cnt;
  953. tls_offset = orig_tls_offset;
  954. tls_align = orig_tls_align;
  955. tail = orig_tail;
  956. tail->next = 0;
  957. p = 0;
  958. errflag = 1;
  959. goto end;
  960. } else p = load_library(file);
  961. if (!p) {
  962. snprintf(errbuf, sizeof errbuf,
  963. "Error loading shared library %s: %m", file);
  964. errflag = 1;
  965. goto end;
  966. }
  967. /* First load handling */
  968. if (!p->deps) {
  969. load_deps(p);
  970. if (p->deps) for (i=0; p->deps[i]; i++)
  971. if (!p->deps[i]->global)
  972. p->deps[i]->global = -1;
  973. if (!p->global) p->global = -1;
  974. reloc_all(p);
  975. if (p->deps) for (i=0; p->deps[i]; i++)
  976. if (p->deps[i]->global < 0)
  977. p->deps[i]->global = 0;
  978. if (p->global < 0) p->global = 0;
  979. }
  980. if (mode & RTLD_GLOBAL) {
  981. if (p->deps) for (i=0; p->deps[i]; i++)
  982. p->deps[i]->global = 1;
  983. p->global = 1;
  984. }
  985. update_tls_size();
  986. if (ssp_used) __init_ssp(libc.auxv);
  987. _dl_debug_state();
  988. orig_tail = tail;
  989. end:
  990. __release_ptc();
  991. if (p) gencnt++;
  992. pthread_rwlock_unlock(&lock);
  993. if (p) do_init_fini(orig_tail);
  994. pthread_setcancelstate(cs, 0);
  995. return p;
  996. }
  997. static void *do_dlsym(struct dso *p, const char *s, void *ra)
  998. {
  999. size_t i;
  1000. uint32_t h = 0, gh = 0;
  1001. Sym *sym;
  1002. if (p == head || p == RTLD_DEFAULT || p == RTLD_NEXT) {
  1003. if (p == RTLD_DEFAULT) {
  1004. p = head;
  1005. } else if (p == RTLD_NEXT) {
  1006. for (p=head; p && (unsigned char *)ra-p->map>p->map_len; p=p->next);
  1007. if (!p) p=head;
  1008. p = p->next;
  1009. }
  1010. struct symdef def = find_sym(p, s, 0);
  1011. if (!def.sym) goto failed;
  1012. if ((def.sym->st_info&0xf) == STT_TLS)
  1013. return __tls_get_addr((size_t []){def.dso->tls_id, def.sym->st_value});
  1014. return def.dso->base + def.sym->st_value;
  1015. }
  1016. if (p->ghashtab) {
  1017. gh = gnu_hash(s);
  1018. sym = gnu_lookup(s, gh, p);
  1019. } else {
  1020. h = sysv_hash(s);
  1021. sym = sysv_lookup(s, h, p);
  1022. }
  1023. if (sym && (sym->st_info&0xf) == STT_TLS)
  1024. return __tls_get_addr((size_t []){p->tls_id, sym->st_value});
  1025. if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
  1026. return p->base + sym->st_value;
  1027. if (p->deps) for (i=0; p->deps[i]; i++) {
  1028. if (p->deps[i]->ghashtab) {
  1029. if (!gh) gh = gnu_hash(s);
  1030. sym = gnu_lookup(s, gh, p->deps[i]);
  1031. } else {
  1032. if (!h) h = sysv_hash(s);
  1033. sym = sysv_lookup(s, h, p->deps[i]);
  1034. }
  1035. if (sym && (sym->st_info&0xf) == STT_TLS)
  1036. return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value});
  1037. if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
  1038. return p->deps[i]->base + sym->st_value;
  1039. }
  1040. failed:
  1041. errflag = 1;
  1042. snprintf(errbuf, sizeof errbuf, "Symbol not found: %s", s);
  1043. return 0;
  1044. }
  1045. int __dladdr(void *addr, Dl_info *info)
  1046. {
  1047. struct dso *p;
  1048. Sym *sym;
  1049. uint32_t nsym;
  1050. char *strings;
  1051. size_t i;
  1052. void *best = 0;
  1053. char *bestname;
  1054. pthread_rwlock_rdlock(&lock);
  1055. for (p=head; p && (unsigned char *)addr-p->map>p->map_len; p=p->next);
  1056. pthread_rwlock_unlock(&lock);
  1057. if (!p) return 0;
  1058. sym = p->syms;
  1059. strings = p->strings;
  1060. if (p->hashtab) {
  1061. nsym = p->hashtab[1];
  1062. } else {
  1063. uint32_t *buckets;
  1064. uint32_t *hashval;
  1065. buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
  1066. sym += p->ghashtab[1];
  1067. for (i = 0; i < p->ghashtab[0]; i++) {
  1068. if (buckets[i] > nsym)
  1069. nsym = buckets[i];
  1070. }
  1071. if (nsym) {
  1072. nsym -= p->ghashtab[1];
  1073. hashval = buckets + p->ghashtab[0] + nsym;
  1074. do nsym++;
  1075. while (!(*hashval++ & 1));
  1076. }
  1077. }
  1078. for (; nsym; nsym--, sym++) {
  1079. if (sym->st_shndx && sym->st_value
  1080. && (1<<(sym->st_info&0xf) & OK_TYPES)
  1081. && (1<<(sym->st_info>>4) & OK_BINDS)) {
  1082. void *symaddr = p->base + sym->st_value;
  1083. if (symaddr > addr || symaddr < best)
  1084. continue;
  1085. best = symaddr;
  1086. bestname = strings + sym->st_name;
  1087. if (addr == symaddr)
  1088. break;
  1089. }
  1090. }
  1091. if (!best) return 0;
  1092. info->dli_fname = p->name;
  1093. info->dli_fbase = p->base;
  1094. info->dli_sname = bestname;
  1095. info->dli_saddr = best;
  1096. return 1;
  1097. }
  1098. void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
  1099. {
  1100. void *res;
  1101. pthread_rwlock_rdlock(&lock);
  1102. res = do_dlsym(p, s, ra);
  1103. pthread_rwlock_unlock(&lock);
  1104. return res;
  1105. }
  1106. int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
  1107. {
  1108. struct dso *current;
  1109. struct dl_phdr_info info;
  1110. int ret = 0;
  1111. for(current = head; current;) {
  1112. info.dlpi_addr = (uintptr_t)current->base;
  1113. info.dlpi_name = current->name;
  1114. info.dlpi_phdr = current->phdr;
  1115. info.dlpi_phnum = current->phnum;
  1116. info.dlpi_adds = gencnt;
  1117. info.dlpi_subs = 0;
  1118. info.dlpi_tls_modid = current->tls_id;
  1119. info.dlpi_tls_data = current->tls_image;
  1120. ret = (callback)(&info, sizeof (info), data);
  1121. if (ret != 0) break;
  1122. pthread_rwlock_rdlock(&lock);
  1123. current = current->next;
  1124. pthread_rwlock_unlock(&lock);
  1125. }
  1126. return ret;
  1127. }
  1128. #else
  1129. void *dlopen(const char *file, int mode)
  1130. {
  1131. return 0;
  1132. }
  1133. void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
  1134. {
  1135. return 0;
  1136. }
  1137. int __dladdr (void *addr, Dl_info *info)
  1138. {
  1139. return 0;
  1140. }
  1141. #endif
  1142. char *dlerror()
  1143. {
  1144. if (!errflag) return 0;
  1145. errflag = 0;
  1146. return errbuf;
  1147. }
  1148. int dlclose(void *p)
  1149. {
  1150. return 0;
  1151. }