1#define _GNU_SOURCE 2#include <stdio.h> 3#include <stdlib.h> 4#include <stdarg.h> 5#include <stddef.h> 6#include <string.h> 7#include <unistd.h> 8#include <stdint.h> 9#include <elf.h> 10#include <sys/mman.h> 11#include <limits.h> 12#include <fcntl.h> 13#include <sys/stat.h> 14#include <errno.h> 15#include <link.h> 16#include <setjmp.h> 17#include <pthread.h> 18#include <ctype.h> 19#include <dlfcn.h> 20#include "pthread_impl.h" 21#include "libc.h" 22#include "dynlink.h" 23 24static void error(const char *, ...); 25 26#define MAXP2(a,b) (-(-(a)&-(b))) 27#define ALIGN(x,y) ((x)+(y)-1 & -(y)) 28 29struct debug { 30 int ver; 31 void *head; 32 void (*bp)(void); 33 int state; 34 void *base; 35}; 36 37struct td_index { 38 size_t args[2]; 39 struct td_index *next; 40}; 41 42struct dso { 43#if DL_FDPIC 44 struct fdpic_loadmap *loadmap; 45#else 46 unsigned char *base; 47#endif 48 char *name; 49 size_t *dynv; 50 struct dso *next, *prev; 51 52 Phdr *phdr; 53 int phnum; 54 size_t phentsize; 55 int refcnt; 56 Sym *syms; 57 Elf_Symndx *hashtab; 58 uint32_t *ghashtab; 59 int16_t *versym; 60 char *strings; 61 unsigned char *map; 62 size_t map_len; 63 dev_t dev; 64 ino_t ino; 65 signed char global; 66 char relocated; 67 char constructed; 68 char kernel_mapped; 69 struct dso **deps, *needed_by; 70 char *rpath_orig, *rpath; 71 struct tls_module tls; 72 size_t tls_id; 73 size_t relro_start, relro_end; 74 void **new_dtv; 75 unsigned char *new_tls; 76 volatile int new_dtv_idx, new_tls_idx; 77 struct td_index *td_index; 78 struct dso *fini_next; 79 char *shortname; 80#if DL_FDPIC 81 unsigned char *base; 82#else 83 struct fdpic_loadmap *loadmap; 84#endif 85 struct funcdesc { 86 void *addr; 87 size_t *got; 88 } *funcdescs; 89 size_t *got; 90 char buf[]; 91}; 92 93struct symdef { 94 Sym *sym; 95 struct dso *dso; 96}; 97 98int __init_tp(void *); 99void __init_libc(char **, char *); 100void *__copy_tls(unsigned char *); 101 102__attribute__((__visibility__("hidden"))) 103const char *__libc_get_version(void); 104 105static struct builtin_tls { 106 char c; 107 struct pthread pt; 108 void *space[16]; 109} builtin_tls[1]; 110#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt) 111 112#define ADDEND_LIMIT 4096 113static size_t *saved_addends, *apply_addends_to; 114 115static struct dso ldso; 116static struct dso *head, *tail, *fini_head; 117static char *env_path, *sys_path; 118static unsigned long long gencnt; 119static int runtime; 120static int ldd_mode; 121static int ldso_fail; 122static int noload; 123static jmp_buf *rtld_fail; 124static pthread_rwlock_t lock; 125static struct debug debug; 126static struct tls_module *tls_tail; 127static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN; 128static size_t static_tls_cnt; 129static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE }; 130static struct fdpic_loadmap *app_loadmap; 131static struct fdpic_dummy_loadmap app_dummy_loadmap; 132 133struct debug *_dl_debug_addr = &debug; 134 135__attribute__((__visibility__("hidden"))) 136void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0; 137 138__attribute__((__visibility__("hidden"))) 139extern void (*const __init_array_end)(void), (*const __fini_array_end)(void); 140 141weak_alias(__init_array_start, __init_array_end); 142weak_alias(__fini_array_start, __fini_array_end); 143 144static int dl_strcmp(const char *l, const char *r) 145{ 146 for (; *l==*r && *l; l++, r++); 147 return *(unsigned char *)l - *(unsigned char *)r; 148} 149#define strcmp(l,r) dl_strcmp(l,r) 150 151/* Compute load address for a virtual address in a given dso. */ 152#if DL_FDPIC 153static void *laddr(const struct dso *p, size_t v) 154{ 155 size_t j=0; 156 if (!p->loadmap) return p->base + v; 157 for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++); 158 return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr); 159} 160#define fpaddr(p, v) ((void (*)())&(struct funcdesc){ \ 161 laddr(p, v), (p)->got }) 162#else 163#define laddr(p, v) (void *)((p)->base + (v)) 164#define fpaddr(p, v) ((void (*)())laddr(p, v)) 165#endif 166 167static void decode_vec(size_t *v, size_t *a, size_t cnt) 168{ 169 size_t i; 170 for (i=0; i<cnt; i++) a[i] = 0; 171 for (; v[0]; v+=2) if (v[0]-1<cnt-1) { 172 a[0] |= 1UL<<v[0]; 173 a[v[0]] = v[1]; 174 } 175} 176 177static int search_vec(size_t *v, size_t *r, size_t key) 178{ 179 for (; v[0]!=key; v+=2) 180 if (!v[0]) return 0; 181 *r = v[1]; 182 return 1; 183} 184 185static uint32_t sysv_hash(const char *s0) 186{ 187 const unsigned char *s = (void *)s0; 188 uint_fast32_t h = 0; 189 while (*s) { 190 h = 16*h + *s++; 191 h ^= h>>24 & 0xf0; 192 } 193 return h & 0xfffffff; 194} 195 196static uint32_t gnu_hash(const char *s0) 197{ 198 const unsigned char *s = (void *)s0; 199 uint_fast32_t h = 5381; 200 for (; *s; s++) 201 h += h*32 + *s; 202 return h; 203} 204 205static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso) 206{ 207 size_t i; 208 Sym *syms = dso->syms; 209 Elf_Symndx *hashtab = dso->hashtab; 210 char *strings = dso->strings; 211 for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) { 212 if ((!dso->versym || dso->versym[i] >= 0) 213 && (!strcmp(s, strings+syms[i].st_name))) 214 return syms+i; 215 } 216 return 0; 217} 218 219static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s) 220{ 221 uint32_t nbuckets = hashtab[0]; 222 uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4); 223 uint32_t i = buckets[h1 % nbuckets]; 224 225 if (!i) return 0; 226 227 uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]); 228 229 for (h1 |= 1; ; i++) { 230 uint32_t h2 = *hashval++; 231 if ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0) 232 && !strcmp(s, dso->strings + dso->syms[i].st_name)) 233 return dso->syms+i; 234 if (h2 & 1) break; 235 } 236 237 return 0; 238} 239 240static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask) 241{ 242 const size_t *bloomwords = (const void *)(hashtab+4); 243 size_t f = bloomwords[fofs & (hashtab[2]-1)]; 244 if (!(f & fmask)) return 0; 245 246 f >>= (h1 >> hashtab[3]) % (8 * sizeof f); 247 if (!(f & 1)) return 0; 248 249 return gnu_lookup(h1, hashtab, dso, s); 250} 251 252#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS) 253#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE) 254 255#ifndef ARCH_SYM_REJECT_UND 256#define ARCH_SYM_REJECT_UND(s) 0 257#endif 258 259static struct symdef find_sym(struct dso *dso, const char *s, int need_def) 260{ 261 uint32_t h = 0, gh, gho, *ght; 262 size_t ghm = 0; 263 struct symdef def = {0}; 264 for (; dso; dso=dso->next) { 265 Sym *sym; 266 if (!dso->global) continue; 267 if ((ght = dso->ghashtab)) { 268 if (!ghm) { 269 gh = gnu_hash(s); 270 int maskbits = 8 * sizeof ghm; 271 gho = gh / maskbits; 272 ghm = 1ul << gh % maskbits; 273 } 274 sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm); 275 } else { 276 if (!h) h = sysv_hash(s); 277 sym = sysv_lookup(s, h, dso); 278 } 279 if (!sym) continue; 280 if (!sym->st_shndx) 281 if (need_def || (sym->st_info&0xf) == STT_TLS 282 || ARCH_SYM_REJECT_UND(sym)) 283 continue; 284 if (!sym->st_value) 285 if ((sym->st_info&0xf) != STT_TLS) 286 continue; 287 if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue; 288 if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue; 289 290 if (def.sym && sym->st_info>>4 == STB_WEAK) continue; 291 def.sym = sym; 292 def.dso = dso; 293 if (sym->st_info>>4 == STB_GLOBAL) break; 294 } 295 return def; 296} 297 298__attribute__((__visibility__("hidden"))) 299ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic(); 300 301static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride) 302{ 303 unsigned char *base = dso->base; 304 Sym *syms = dso->syms; 305 char *strings = dso->strings; 306 Sym *sym; 307 const char *name; 308 void *ctx; 309 int type; 310 int sym_index; 311 struct symdef def; 312 size_t *reloc_addr; 313 size_t sym_val; 314 size_t tls_val; 315 size_t addend; 316 int skip_relative = 0, reuse_addends = 0, save_slot = 0; 317 318 if (dso == &ldso) { 319 /* Only ldso's REL table needs addend saving/reuse. */ 320 if (rel == apply_addends_to) 321 reuse_addends = 1; 322 skip_relative = 1; 323 } 324 325 for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) { 326 if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue; 327 type = R_TYPE(rel[1]); 328 if (type == REL_NONE) continue; 329 sym_index = R_SYM(rel[1]); 330 reloc_addr = laddr(dso, rel[0]); 331 if (sym_index) { 332 sym = syms + sym_index; 333 name = strings + sym->st_name; 334 ctx = type==REL_COPY ? head->next : head; 335 def = (sym->st_info&0xf) == STT_SECTION 336 ? (struct symdef){ .dso = dso, .sym = sym } 337 : find_sym(ctx, name, type==REL_PLT); 338 if (!def.sym && (sym->st_shndx != SHN_UNDEF 339 || sym->st_info>>4 != STB_WEAK)) { 340 error("Error relocating %s: %s: symbol not found", 341 dso->name, name); 342 if (runtime) longjmp(*rtld_fail, 1); 343 continue; 344 } 345 } else { 346 sym = 0; 347 def.sym = 0; 348 def.dso = dso; 349 } 350 351 if (stride > 2) { 352 addend = rel[2]; 353 } else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) { 354 addend = 0; 355 } else if (reuse_addends) { 356 /* Save original addend in stage 2 where the dso 357 * chain consists of just ldso; otherwise read back 358 * saved addend since the inline one was clobbered. */ 359 if (head==&ldso) 360 saved_addends[save_slot] = *reloc_addr; 361 addend = saved_addends[save_slot++]; 362 } else { 363 addend = *reloc_addr; 364 } 365 366 sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0; 367 tls_val = def.sym ? def.sym->st_value : 0; 368 369 switch(type) { 370 case REL_NONE: 371 break; 372 case REL_OFFSET: 373 addend -= (size_t)reloc_addr; 374 case REL_SYMBOLIC: 375 case REL_GOT: 376 case REL_PLT: 377 *reloc_addr = sym_val + addend; 378 break; 379 case REL_RELATIVE: 380 *reloc_addr = (size_t)base + addend; 381 break; 382 case REL_SYM_OR_REL: 383 if (sym) *reloc_addr = sym_val + addend; 384 else *reloc_addr = (size_t)base + addend; 385 break; 386 case REL_COPY: 387 memcpy(reloc_addr, (void *)sym_val, sym->st_size); 388 break; 389 case REL_OFFSET32: 390 *(uint32_t *)reloc_addr = sym_val + addend 391 - (size_t)reloc_addr; 392 break; 393 case REL_FUNCDESC: 394 *reloc_addr = def.sym ? (size_t)(def.dso->funcdescs 395 + (def.sym - def.dso->syms)) : 0; 396 break; 397 case REL_FUNCDESC_VAL: 398 if ((sym->st_info&0xf) == STT_SECTION) *reloc_addr += sym_val; 399 else *reloc_addr = sym_val; 400 reloc_addr[1] = def.sym ? (size_t)def.dso->got : 0; 401 break; 402 case REL_DTPMOD: 403 *reloc_addr = def.dso->tls_id; 404 break; 405 case REL_DTPOFF: 406 *reloc_addr = tls_val + addend - DTP_OFFSET; 407 break; 408#ifdef TLS_ABOVE_TP 409 case REL_TPOFF: 410 *reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend; 411 break; 412#else 413 case REL_TPOFF: 414 *reloc_addr = tls_val - def.dso->tls.offset + addend; 415 break; 416 case REL_TPOFF_NEG: 417 *reloc_addr = def.dso->tls.offset - tls_val + addend; 418 break; 419#endif 420 case REL_TLSDESC: 421 if (stride<3) addend = reloc_addr[1]; 422 if (runtime && def.dso->tls_id >= static_tls_cnt) { 423 struct td_index *new = malloc(sizeof *new); 424 if (!new) { 425 error( 426 "Error relocating %s: cannot allocate TLSDESC for %s", 427 dso->name, sym ? name : "(local)" ); 428 longjmp(*rtld_fail, 1); 429 } 430 new->next = dso->td_index; 431 dso->td_index = new; 432 new->args[0] = def.dso->tls_id; 433 new->args[1] = tls_val + addend; 434 reloc_addr[0] = (size_t)__tlsdesc_dynamic; 435 reloc_addr[1] = (size_t)new; 436 } else { 437 reloc_addr[0] = (size_t)__tlsdesc_static; 438#ifdef TLS_ABOVE_TP 439 reloc_addr[1] = tls_val + def.dso->tls.offset 440 + TPOFF_K + addend; 441#else 442 reloc_addr[1] = tls_val - def.dso->tls.offset 443 + addend; 444#endif 445 } 446 break; 447 default: 448 error("Error relocating %s: unsupported relocation type %d", 449 dso->name, type); 450 if (runtime) longjmp(*rtld_fail, 1); 451 continue; 452 } 453 } 454} 455 456/* A huge hack: to make up for the wastefulness of shared libraries 457 * needing at least a page of dirty memory even if they have no global 458 * data, we reclaim the gaps at the beginning and end of writable maps 459 * and "donate" them to the heap by setting up minimal malloc 460 * structures and then freeing them. */ 461 462static void reclaim(struct dso *dso, size_t start, size_t end) 463{ 464 size_t *a, *z; 465 if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end; 466 if (end >= dso->relro_start && end < dso->relro_end) end = dso->relro_start; 467 start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t); 468 end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t); 469 if (start>end || end-start < 4*sizeof(size_t)) return; 470 a = laddr(dso, start); 471 z = laddr(dso, end); 472 a[-2] = 1; 473 a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1; 474 z[1] = 1; 475 free(a); 476} 477 478static void reclaim_gaps(struct dso *dso) 479{ 480 Phdr *ph = dso->phdr; 481 size_t phcnt = dso->phnum; 482 483 if (DL_FDPIC) return; // FIXME 484 for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) { 485 if (ph->p_type!=PT_LOAD) continue; 486 if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue; 487 reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr); 488 reclaim(dso, ph->p_vaddr+ph->p_memsz, 489 ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE); 490 } 491} 492 493static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off) 494{ 495 static int no_map_fixed; 496 char *q; 497 if (!no_map_fixed) { 498 q = mmap(p, n, prot, flags|MAP_FIXED, fd, off); 499 if (!DL_NOMMU_SUPPORT || q != MAP_FAILED || errno != EINVAL) 500 return q; 501 no_map_fixed = 1; 502 } 503 /* Fallbacks for MAP_FIXED failure on NOMMU kernels. */ 504 if (flags & MAP_ANONYMOUS) { 505 memset(p, 0, n); 506 return p; 507 } 508 ssize_t r; 509 if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED; 510 for (q=p; n; q+=r, off+=r, n-=r) { 511 r = read(fd, q, n); 512 if (r < 0 && errno != EINTR) return MAP_FAILED; 513 if (!r) { 514 memset(q, 0, n); 515 break; 516 } 517 } 518 return p; 519} 520 521static void unmap_library(struct dso *dso) 522{ 523 if (dso->loadmap) { 524 size_t i; 525 for (i=0; i<dso->loadmap->nsegs; i++) { 526 if (!dso->loadmap->segs[i].p_memsz) 527 continue; 528 munmap((void *)dso->loadmap->segs[i].addr, 529 dso->loadmap->segs[i].p_memsz); 530 } 531 free(dso->loadmap); 532 } else if (dso->map && dso->map_len) { 533 munmap(dso->map, dso->map_len); 534 } 535} 536 537static void *map_library(int fd, struct dso *dso) 538{ 539 Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)]; 540 void *allocated_buf=0; 541 size_t phsize; 542 size_t addr_min=SIZE_MAX, addr_max=0, map_len; 543 size_t this_min, this_max; 544 size_t nsegs = 0; 545 off_t off_start; 546 Ehdr *eh; 547 Phdr *ph, *ph0; 548 unsigned prot; 549 unsigned char *map=MAP_FAILED, *base; 550 size_t dyn=0; 551 size_t tls_image=0; 552 size_t i; 553 554 ssize_t l = read(fd, buf, sizeof buf); 555 eh = buf; 556 if (l<0) return 0; 557 if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC)) 558 goto noexec; 559 phsize = eh->e_phentsize * eh->e_phnum; 560 if (phsize > sizeof buf - sizeof *eh) { 561 allocated_buf = malloc(phsize); 562 if (!allocated_buf) return 0; 563 l = pread(fd, allocated_buf, phsize, eh->e_phoff); 564 if (l < 0) goto error; 565 if (l != phsize) goto noexec; 566 ph = ph0 = allocated_buf; 567 } else if (eh->e_phoff + phsize > l) { 568 l = pread(fd, buf+1, phsize, eh->e_phoff); 569 if (l < 0) goto error; 570 if (l != phsize) goto noexec; 571 ph = ph0 = (void *)(buf + 1); 572 } else { 573 ph = ph0 = (void *)((char *)buf + eh->e_phoff); 574 } 575 for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) { 576 if (ph->p_type == PT_DYNAMIC) { 577 dyn = ph->p_vaddr; 578 } else if (ph->p_type == PT_TLS) { 579 tls_image = ph->p_vaddr; 580 dso->tls.align = ph->p_align; 581 dso->tls.len = ph->p_filesz; 582 dso->tls.size = ph->p_memsz; 583 } else if (ph->p_type == PT_GNU_RELRO) { 584 dso->relro_start = ph->p_vaddr & -PAGE_SIZE; 585 dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE; 586 } 587 if (ph->p_type != PT_LOAD) continue; 588 nsegs++; 589 if (ph->p_vaddr < addr_min) { 590 addr_min = ph->p_vaddr; 591 off_start = ph->p_offset; 592 prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) | 593 ((ph->p_flags&PF_W) ? PROT_WRITE: 0) | 594 ((ph->p_flags&PF_X) ? PROT_EXEC : 0)); 595 } 596 if (ph->p_vaddr+ph->p_memsz > addr_max) { 597 addr_max = ph->p_vaddr+ph->p_memsz; 598 } 599 } 600 if (!dyn) goto noexec; 601 if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) { 602 dso->loadmap = calloc(1, sizeof *dso->loadmap 603 + nsegs * sizeof *dso->loadmap->segs); 604 if (!dso->loadmap) goto error; 605 dso->loadmap->nsegs = nsegs; 606 for (ph=ph0, i=0; i<nsegs; ph=(void *)((char *)ph+eh->e_phentsize)) { 607 if (ph->p_type != PT_LOAD) continue; 608 prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) | 609 ((ph->p_flags&PF_W) ? PROT_WRITE: 0) | 610 ((ph->p_flags&PF_X) ? PROT_EXEC : 0)); 611 map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1), 612 prot, MAP_PRIVATE, 613 fd, ph->p_offset & -PAGE_SIZE); 614 if (map == MAP_FAILED) { 615 unmap_library(dso); 616 goto error; 617 } 618 dso->loadmap->segs[i].addr = (size_t)map + 619 (ph->p_vaddr & PAGE_SIZE-1); 620 dso->loadmap->segs[i].p_vaddr = ph->p_vaddr; 621 dso->loadmap->segs[i].p_memsz = ph->p_memsz; 622 i++; 623 if (prot & PROT_WRITE) { 624 size_t brk = (ph->p_vaddr & PAGE_SIZE-1) 625 + ph->p_filesz; 626 size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE; 627 size_t pgend = brk + ph->p_memsz - ph->p_filesz 628 + PAGE_SIZE-1 & -PAGE_SIZE; 629 if (pgend > pgbrk && mmap_fixed(map+pgbrk, 630 pgend-pgbrk, prot, 631 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, 632 -1, off_start) == MAP_FAILED) 633 goto error; 634 memset(map + brk, 0, pgbrk-brk); 635 } 636 } 637 map = (void *)dso->loadmap->segs[0].addr; 638 map_len = 0; 639 goto done_mapping; 640 } 641 addr_max += PAGE_SIZE-1; 642 addr_max &= -PAGE_SIZE; 643 addr_min &= -PAGE_SIZE; 644 off_start &= -PAGE_SIZE; 645 map_len = addr_max - addr_min + off_start; 646 /* The first time, we map too much, possibly even more than 647 * the length of the file. This is okay because we will not 648 * use the invalid part; we just need to reserve the right 649 * amount of virtual address space to map over later. */ 650 map = DL_NOMMU_SUPPORT 651 ? mmap((void *)addr_min, map_len, PROT_READ|PROT_WRITE|PROT_EXEC, 652 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) 653 : mmap((void *)addr_min, map_len, prot, 654 MAP_PRIVATE, fd, off_start); 655 if (map==MAP_FAILED) goto error; 656 dso->map = map; 657 dso->map_len = map_len; 658 /* If the loaded file is not relocatable and the requested address is 659 * not available, then the load operation must fail. */ 660 if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) { 661 errno = EBUSY; 662 goto error; 663 } 664 base = map - addr_min; 665 dso->phdr = 0; 666 dso->phnum = 0; 667 for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) { 668 if (ph->p_type != PT_LOAD) continue; 669 /* Check if the programs headers are in this load segment, and 670 * if so, record the address for use by dl_iterate_phdr. */ 671 if (!dso->phdr && eh->e_phoff >= ph->p_offset 672 && eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) { 673 dso->phdr = (void *)(base + ph->p_vaddr 674 + (eh->e_phoff-ph->p_offset)); 675 dso->phnum = eh->e_phnum; 676 dso->phentsize = eh->e_phentsize; 677 } 678 /* Reuse the existing mapping for the lowest-address LOAD */ 679 if ((ph->p_vaddr & -PAGE_SIZE) == addr_min && !DL_NOMMU_SUPPORT) 680 continue; 681 this_min = ph->p_vaddr & -PAGE_SIZE; 682 this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE; 683 off_start = ph->p_offset & -PAGE_SIZE; 684 prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) | 685 ((ph->p_flags&PF_W) ? PROT_WRITE: 0) | 686 ((ph->p_flags&PF_X) ? PROT_EXEC : 0)); 687 if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED) 688 goto error; 689 if (ph->p_memsz > ph->p_filesz) { 690 size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz; 691 size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE; 692 memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1); 693 if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED) 694 goto error; 695 } 696 } 697 for (i=0; ((size_t *)(base+dyn))[i]; i+=2) 698 if (((size_t *)(base+dyn))[i]==DT_TEXTREL) { 699 if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC) 700 && errno != ENOSYS) 701 goto error; 702 break; 703 } 704done_mapping: 705 dso->base = base; 706 dso->dynv = laddr(dso, dyn); 707 if (dso->tls.size) dso->tls.image = laddr(dso, tls_image); 708 if (!runtime) reclaim_gaps(dso); 709 free(allocated_buf); 710 return map; 711noexec: 712 errno = ENOEXEC; 713error: 714 if (map!=MAP_FAILED) unmap_library(dso); 715 free(allocated_buf); 716 return 0; 717} 718 719static int path_open(const char *name, const char *s, char *buf, size_t buf_size) 720{ 721 size_t l; 722 int fd; 723 for (;;) { 724 s += strspn(s, ":\n"); 725 l = strcspn(s, ":\n"); 726 if (l-1 >= INT_MAX) return -1; 727 if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) { 728 if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd; 729 switch (errno) { 730 case ENOENT: 731 case ENOTDIR: 732 case EACCES: 733 case ENAMETOOLONG: 734 break; 735 default: 736 /* Any negative value but -1 will inhibit 737 * futher path search. */ 738 return -2; 739 } 740 } 741 s += l; 742 } 743} 744 745static int fixup_rpath(struct dso *p, char *buf, size_t buf_size) 746{ 747 size_t n, l; 748 const char *s, *t, *origin; 749 char *d; 750 if (p->rpath || !p->rpath_orig) return 0; 751 if (!strchr(p->rpath_orig, '$')) { 752 p->rpath = p->rpath_orig; 753 return 0; 754 } 755 n = 0; 756 s = p->rpath_orig; 757 while ((t=strchr(s, '$'))) { 758 if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9)) 759 return 0; 760 s = t+1; 761 n++; 762 } 763 if (n > SSIZE_MAX/PATH_MAX) return 0; 764 765 if (p->kernel_mapped) { 766 /* $ORIGIN searches cannot be performed for the main program 767 * when it is suid/sgid/AT_SECURE. This is because the 768 * pathname is under the control of the caller of execve. 769 * For libraries, however, $ORIGIN can be processed safely 770 * since the library's pathname came from a trusted source 771 * (either system paths or a call to dlopen). */ 772 if (libc.secure) 773 return 0; 774 l = readlink("/proc/self/exe", buf, buf_size); 775 if (l == -1) switch (errno) { 776 case ENOENT: 777 case ENOTDIR: 778 case EACCES: 779 break; 780 default: 781 return -1; 782 } 783 if (l >= buf_size) 784 return 0; 785 buf[l] = 0; 786 origin = buf; 787 } else { 788 origin = p->name; 789 } 790 t = strrchr(origin, '/'); 791 l = t ? t-origin : 0; 792 p->rpath = malloc(strlen(p->rpath_orig) + n*l + 1); 793 if (!p->rpath) return -1; 794 795 d = p->rpath; 796 s = p->rpath_orig; 797 while ((t=strchr(s, '$'))) { 798 memcpy(d, s, t-s); 799 d += t-s; 800 memcpy(d, origin, l); 801 d += l; 802 /* It was determined previously that the '$' is followed 803 * either by "ORIGIN" or "{ORIGIN}". */ 804 s = t + 7 + 2*(t[1]=='{'); 805 } 806 strcpy(d, s); 807 return 0; 808} 809 810static void decode_dyn(struct dso *p) 811{ 812 size_t dyn[DYN_CNT]; 813 decode_vec(p->dynv, dyn, DYN_CNT); 814 p->syms = laddr(p, dyn[DT_SYMTAB]); 815 p->strings = laddr(p, dyn[DT_STRTAB]); 816 if (dyn[0]&(1<<DT_HASH)) 817 p->hashtab = laddr(p, dyn[DT_HASH]); 818 if (dyn[0]&(1<<DT_RPATH)) 819 p->rpath_orig = p->strings + dyn[DT_RPATH]; 820 if (dyn[0]&(1<<DT_RUNPATH)) 821 p->rpath_orig = p->strings + dyn[DT_RUNPATH]; 822 if (dyn[0]&(1<<DT_PLTGOT)) 823 p->got = laddr(p, dyn[DT_PLTGOT]); 824 if (search_vec(p->dynv, dyn, DT_GNU_HASH)) 825 p->ghashtab = laddr(p, *dyn); 826 if (search_vec(p->dynv, dyn, DT_VERSYM)) 827 p->versym = laddr(p, *dyn); 828} 829 830static size_t count_syms(struct dso *p) 831{ 832 if (p->hashtab) return p->hashtab[1]; 833 834 size_t nsym, i; 835 uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4); 836 uint32_t *hashval; 837 for (i = nsym = 0; i < p->ghashtab[0]; i++) { 838 if (buckets[i] > nsym) 839 nsym = buckets[i]; 840 } 841 if (nsym) { 842 hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]); 843 do nsym++; 844 while (!(*hashval++ & 1)); 845 } 846 return nsym; 847} 848 849static void *dl_mmap(size_t n) 850{ 851 void *p; 852 int prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE; 853#ifdef SYS_mmap2 854 p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0); 855#else 856 p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0); 857#endif 858 return p == MAP_FAILED ? 0 : p; 859} 860 861static void makefuncdescs(struct dso *p) 862{ 863 static int self_done; 864 size_t nsym = count_syms(p); 865 size_t i, size = nsym * sizeof(*p->funcdescs); 866 867 if (!self_done) { 868 p->funcdescs = dl_mmap(size); 869 self_done = 1; 870 } else { 871 p->funcdescs = malloc(size); 872 } 873 if (!p->funcdescs) { 874 if (!runtime) a_crash(); 875 error("Error allocating function descriptors for %s", p->name); 876 longjmp(*rtld_fail, 1); 877 } 878 for (i=0; i<nsym; i++) { 879 if ((p->syms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) { 880 p->funcdescs[i].addr = laddr(p, p->syms[i].st_value); 881 p->funcdescs[i].got = p->got; 882 } else { 883 p->funcdescs[i].addr = 0; 884 p->funcdescs[i].got = 0; 885 } 886 } 887} 888 889static struct dso *load_library(const char *name, struct dso *needed_by) 890{ 891 char buf[2*NAME_MAX+2]; 892 const char *pathname; 893 unsigned char *map; 894 struct dso *p, temp_dso = {0}; 895 int fd; 896 struct stat st; 897 size_t alloc_size; 898 int n_th = 0; 899 int is_self = 0; 900 901 if (!*name) { 902 errno = EINVAL; 903 return 0; 904 } 905 906 /* Catch and block attempts to reload the implementation itself */ 907 if (name[0]=='l' && name[1]=='i' && name[2]=='b') { 908 static const char reserved[] = 909 "c.pthread.rt.m.dl.util.xnet."; 910 const char *rp, *next; 911 for (rp=reserved; *rp; rp=next) { 912 next = strchr(rp, '.') + 1; 913 if (strncmp(name+3, rp, next-rp) == 0) 914 break; 915 } 916 if (*rp) { 917 if (ldd_mode) { 918 /* Track which names have been resolved 919 * and only report each one once. */ 920 static unsigned reported; 921 unsigned mask = 1U<<(rp-reserved); 922 if (!(reported & mask)) { 923 reported |= mask; 924 dprintf(1, "\t%s => %s (%p)\n", 925 name, ldso.name, 926 ldso.base); 927 } 928 } 929 is_self = 1; 930 } 931 } 932 if (!strcmp(name, ldso.name)) is_self = 1; 933 if (is_self) { 934 if (!ldso.prev) { 935 tail->next = &ldso; 936 ldso.prev = tail; 937 tail = ldso.next ? ldso.next : &ldso; 938 } 939 return &ldso; 940 } 941 if (strchr(name, '/')) { 942 pathname = name; 943 fd = open(name, O_RDONLY|O_CLOEXEC); 944 } else { 945 /* Search for the name to see if it's already loaded */ 946 for (p=head->next; p; p=p->next) { 947 if (p->shortname && !strcmp(p->shortname, name)) { 948 p->refcnt++; 949 return p; 950 } 951 } 952 if (strlen(name) > NAME_MAX) return 0; 953 fd = -1; 954 if (env_path) fd = path_open(name, env_path, buf, sizeof buf); 955 for (p=needed_by; fd == -1 && p; p=p->needed_by) { 956 if (fixup_rpath(p, buf, sizeof buf) < 0) 957 fd = -2; /* Inhibit further search. */ 958 if (p->rpath) 959 fd = path_open(name, p->rpath, buf, sizeof buf); 960 } 961 if (fd == -1) { 962 if (!sys_path) { 963 char *prefix = 0; 964 size_t prefix_len; 965 if (ldso.name[0]=='/') { 966 char *s, *t, *z; 967 for (s=t=z=ldso.name; *s; s++) 968 if (*s=='/') z=t, t=s; 969 prefix_len = z-ldso.name; 970 if (prefix_len < PATH_MAX) 971 prefix = ldso.name; 972 } 973 if (!prefix) { 974 prefix = ""; 975 prefix_len = 0; 976 } 977 char etc_ldso_path[prefix_len + 1 978 + sizeof "/etc/ld-musl-" LDSO_ARCH ".path"]; 979 snprintf(etc_ldso_path, sizeof etc_ldso_path, 980 "%.*s/etc/ld-musl-" LDSO_ARCH ".path", 981 (int)prefix_len, prefix); 982 FILE *f = fopen(etc_ldso_path, "rbe"); 983 if (f) { 984 if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) { 985 free(sys_path); 986 sys_path = ""; 987 } 988 fclose(f); 989 } else if (errno != ENOENT) { 990 sys_path = ""; 991 } 992 } 993 if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib"; 994 fd = path_open(name, sys_path, buf, sizeof buf); 995 } 996 pathname = buf; 997 } 998 if (fd < 0) return 0; 999 if (fstat(fd, &st) < 0) { 1000 close(fd); 1001 return 0; 1002 } 1003 for (p=head->next; p; p=p->next) { 1004 if (p->dev == st.st_dev && p->ino == st.st_ino) { 1005 /* If this library was previously loaded with a 1006 * pathname but a search found the same inode, 1007 * setup its shortname so it can be found by name. */ 1008 if (!p->shortname && pathname != name) 1009 p->shortname = strrchr(p->name, '/')+1; 1010 close(fd); 1011 p->refcnt++; 1012 return p; 1013 } 1014 } 1015 map = noload ? 0 : map_library(fd, &temp_dso); 1016 close(fd); 1017 if (!map) return 0; 1018 1019 /* Allocate storage for the new DSO. When there is TLS, this 1020 * storage must include a reservation for all pre-existing 1021 * threads to obtain copies of both the new TLS, and an 1022 * extended DTV capable of storing an additional slot for 1023 * the newly-loaded DSO. */ 1024 alloc_size = sizeof *p + strlen(pathname) + 1; 1025 if (runtime && temp_dso.tls.image) { 1026 size_t per_th = temp_dso.tls.size + temp_dso.tls.align 1027 + sizeof(void *) * (tls_cnt+3); 1028 n_th = libc.threads_minus_1 + 1; 1029 if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX; 1030 else alloc_size += n_th * per_th; 1031 } 1032 p = calloc(1, alloc_size); 1033 if (!p) { 1034 unmap_library(&temp_dso); 1035 return 0; 1036 } 1037 memcpy(p, &temp_dso, sizeof temp_dso); 1038 decode_dyn(p); 1039 p->dev = st.st_dev; 1040 p->ino = st.st_ino; 1041 p->refcnt = 1; 1042 p->needed_by = needed_by; 1043 p->name = p->buf; 1044 strcpy(p->name, pathname); 1045 /* Add a shortname only if name arg was not an explicit pathname. */ 1046 if (pathname != name) p->shortname = strrchr(p->name, '/')+1; 1047 if (p->tls.image) { 1048 p->tls_id = ++tls_cnt; 1049 tls_align = MAXP2(tls_align, p->tls.align); 1050#ifdef TLS_ABOVE_TP 1051 p->tls.offset = tls_offset + ( (tls_align-1) & 1052 -(tls_offset + (uintptr_t)p->tls.image) ); 1053 tls_offset += p->tls.size; 1054#else 1055 tls_offset += p->tls.size + p->tls.align - 1; 1056 tls_offset -= (tls_offset + (uintptr_t)p->tls.image) 1057 & (p->tls.align-1); 1058 p->tls.offset = tls_offset; 1059#endif 1060 p->new_dtv = (void *)(-sizeof(size_t) & 1061 (uintptr_t)(p->name+strlen(p->name)+sizeof(size_t))); 1062 p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1)); 1063 if (tls_tail) tls_tail->next = &p->tls; 1064 else libc.tls_head = &p->tls; 1065 tls_tail = &p->tls; 1066 } 1067 1068 tail->next = p; 1069 p->prev = tail; 1070 tail = p; 1071 1072 if (DL_FDPIC) makefuncdescs(p); 1073 1074 if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base); 1075 1076 return p; 1077} 1078 1079static void load_deps(struct dso *p) 1080{ 1081 size_t i, ndeps=0; 1082 struct dso ***deps = &p->deps, **tmp, *dep; 1083 for (; p; p=p->next) { 1084 for (i=0; p->dynv[i]; i+=2) { 1085 if (p->dynv[i] != DT_NEEDED) continue; 1086 dep = load_library(p->strings + p->dynv[i+1], p); 1087 if (!dep) { 1088 error("Error loading shared library %s: %m (needed by %s)", 1089 p->strings + p->dynv[i+1], p->name); 1090 if (runtime) longjmp(*rtld_fail, 1); 1091 continue; 1092 } 1093 if (runtime) { 1094 tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2)); 1095 if (!tmp) longjmp(*rtld_fail, 1); 1096 tmp[ndeps++] = dep; 1097 tmp[ndeps] = 0; 1098 *deps = tmp; 1099 } 1100 } 1101 } 1102} 1103 1104static void load_preload(char *s) 1105{ 1106 int tmp; 1107 char *z; 1108 for (z=s; *z; s=z) { 1109 for ( ; *s && (isspace(*s) || *s==':'); s++); 1110 for (z=s; *z && !isspace(*z) && *z!=':'; z++); 1111 tmp = *z; 1112 *z = 0; 1113 load_library(s, 0); 1114 *z = tmp; 1115 } 1116} 1117 1118static void make_global(struct dso *p) 1119{ 1120 for (; p; p=p->next) p->global = 1; 1121} 1122 1123static void do_mips_relocs(struct dso *p, size_t *got) 1124{ 1125 size_t i, j, rel[2]; 1126 unsigned char *base = p->base; 1127 i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO); 1128 if (p==&ldso) { 1129 got += i; 1130 } else { 1131 while (i--) *got++ += (size_t)base; 1132 } 1133 j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM); 1134 i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO); 1135 Sym *sym = p->syms + j; 1136 rel[0] = (unsigned char *)got - base; 1137 for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) { 1138 rel[1] = R_INFO(sym-p->syms, R_MIPS_JUMP_SLOT); 1139 do_relocs(p, rel, sizeof rel, 2); 1140 } 1141} 1142 1143static void reloc_all(struct dso *p) 1144{ 1145 size_t dyn[DYN_CNT]; 1146 for (; p; p=p->next) { 1147 if (p->relocated) continue; 1148 decode_vec(p->dynv, dyn, DYN_CNT); 1149 if (NEED_MIPS_GOT_RELOCS) 1150 do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT])); 1151 do_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ], 1152 2+(dyn[DT_PLTREL]==DT_RELA)); 1153 do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2); 1154 do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3); 1155 1156 if (head != &ldso && p->relro_start != p->relro_end && 1157 mprotect(laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ) 1158 && errno != ENOSYS) { 1159 error("Error relocating %s: RELRO protection failed: %m", 1160 p->name); 1161 if (runtime) longjmp(*rtld_fail, 1); 1162 } 1163 1164 p->relocated = 1; 1165 } 1166} 1167 1168static void kernel_mapped_dso(struct dso *p) 1169{ 1170 size_t min_addr = -1, max_addr = 0, cnt; 1171 Phdr *ph = p->phdr; 1172 for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) { 1173 if (ph->p_type == PT_DYNAMIC) { 1174 p->dynv = laddr(p, ph->p_vaddr); 1175 } else if (ph->p_type == PT_GNU_RELRO) { 1176 p->relro_start = ph->p_vaddr & -PAGE_SIZE; 1177 p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE; 1178 } 1179 if (ph->p_type != PT_LOAD) continue; 1180 if (ph->p_vaddr < min_addr) 1181 min_addr = ph->p_vaddr; 1182 if (ph->p_vaddr+ph->p_memsz > max_addr) 1183 max_addr = ph->p_vaddr+ph->p_memsz; 1184 } 1185 min_addr &= -PAGE_SIZE; 1186 max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE; 1187 p->map = p->base + min_addr; 1188 p->map_len = max_addr - min_addr; 1189 p->kernel_mapped = 1; 1190} 1191 1192void __libc_exit_fini() 1193{ 1194 struct dso *p; 1195 size_t dyn[DYN_CNT]; 1196 for (p=fini_head; p; p=p->fini_next) { 1197 if (!p->constructed) continue; 1198 decode_vec(p->dynv, dyn, DYN_CNT); 1199 if (dyn[0] & (1<<DT_FINI_ARRAY)) { 1200 size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t); 1201 size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n; 1202 while (n--) ((void (*)(void))*--fn)(); 1203 } 1204#ifndef NO_LEGACY_INITFINI 1205 if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI]) 1206 fpaddr(p, dyn[DT_FINI])(); 1207#endif 1208 } 1209} 1210 1211static void do_init_fini(struct dso *p) 1212{ 1213 size_t dyn[DYN_CNT]; 1214 int need_locking = libc.threads_minus_1; 1215 /* Allow recursive calls that arise when a library calls 1216 * dlopen from one of its constructors, but block any 1217 * other threads until all ctors have finished. */ 1218 if (need_locking) pthread_mutex_lock(&init_fini_lock); 1219 for (; p; p=p->prev) { 1220 if (p->constructed) continue; 1221 p->constructed = 1; 1222 decode_vec(p->dynv, dyn, DYN_CNT); 1223 if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) { 1224 p->fini_next = fini_head; 1225 fini_head = p; 1226 } 1227#ifndef NO_LEGACY_INITFINI 1228 if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT]) 1229 fpaddr(p, dyn[DT_INIT])(); 1230#endif 1231 if (dyn[0] & (1<<DT_INIT_ARRAY)) { 1232 size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t); 1233 size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]); 1234 while (n--) ((void (*)(void))*fn++)(); 1235 } 1236 if (!need_locking && libc.threads_minus_1) { 1237 need_locking = 1; 1238 pthread_mutex_lock(&init_fini_lock); 1239 } 1240 } 1241 if (need_locking) pthread_mutex_unlock(&init_fini_lock); 1242} 1243 1244void __libc_start_init(void) 1245{ 1246 do_init_fini(tail); 1247} 1248 1249static void dl_debug_state(void) 1250{ 1251} 1252 1253weak_alias(dl_debug_state, _dl_debug_state); 1254 1255void __init_tls(size_t *auxv) 1256{ 1257} 1258 1259__attribute__((__visibility__("hidden"))) 1260void *__tls_get_new(size_t *v) 1261{ 1262 pthread_t self = __pthread_self(); 1263 1264 /* Block signals to make accessing new TLS async-signal-safe */ 1265 sigset_t set; 1266 __block_all_sigs(&set); 1267 if (v[0]<=(size_t)self->dtv[0]) { 1268 __restore_sigs(&set); 1269 return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET; 1270 } 1271 1272 /* This is safe without any locks held because, if the caller 1273 * is able to request the Nth entry of the DTV, the DSO list 1274 * must be valid at least that far out and it was synchronized 1275 * at program startup or by an already-completed call to dlopen. */ 1276 struct dso *p; 1277 for (p=head; p->tls_id != v[0]; p=p->next); 1278 1279 /* Get new DTV space from new DSO if needed */ 1280 if (v[0] > (size_t)self->dtv[0]) { 1281 void **newdtv = p->new_dtv + 1282 (v[0]+1)*a_fetch_add(&p->new_dtv_idx,1); 1283 memcpy(newdtv, self->dtv, 1284 ((size_t)self->dtv[0]+1) * sizeof(void *)); 1285 newdtv[0] = (void *)v[0]; 1286 self->dtv = self->dtv_copy = newdtv; 1287 } 1288 1289 /* Get new TLS memory from all new DSOs up to the requested one */ 1290 unsigned char *mem; 1291 for (p=head; ; p=p->next) { 1292 if (!p->tls_id || self->dtv[p->tls_id]) continue; 1293 mem = p->new_tls + (p->tls.size + p->tls.align) 1294 * a_fetch_add(&p->new_tls_idx,1); 1295 mem += ((uintptr_t)p->tls.image - (uintptr_t)mem) 1296 & (p->tls.align-1); 1297 self->dtv[p->tls_id] = mem; 1298 memcpy(mem, p->tls.image, p->tls.len); 1299 if (p->tls_id == v[0]) break; 1300 } 1301 __restore_sigs(&set); 1302 return mem + v[1] + DTP_OFFSET; 1303} 1304 1305static void update_tls_size() 1306{ 1307 libc.tls_cnt = tls_cnt; 1308 libc.tls_align = tls_align; 1309 libc.tls_size = ALIGN( 1310 (1+tls_cnt) * sizeof(void *) + 1311 tls_offset + 1312 sizeof(struct pthread) + 1313 tls_align * 2, 1314 tls_align); 1315} 1316 1317/* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the 1318 * following stage 2 and stage 3 functions via primitive symbolic lookup 1319 * since it does not have access to their addresses to begin with. */ 1320 1321/* Stage 2 of the dynamic linker is called after relative relocations 1322 * have been processed. It can make function calls to static functions 1323 * and access string literals and static data, but cannot use extern 1324 * symbols. Its job is to perform symbolic relocations on the dynamic 1325 * linker itself, but some of the relocations performed may need to be 1326 * replaced later due to copy relocations in the main program. */ 1327 1328__attribute__((__visibility__("hidden"))) 1329void __dls2(unsigned char *base, size_t *sp) 1330{ 1331 if (DL_FDPIC) { 1332 void *p1 = (void *)sp[-2]; 1333 void *p2 = (void *)sp[-1]; 1334 if (!p1) { 1335 size_t *auxv, aux[AUX_CNT]; 1336 for (auxv=sp+1+*sp+1; *auxv; auxv++); auxv++; 1337 decode_vec(auxv, aux, AUX_CNT); 1338 if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE]; 1339 else ldso.base = (void *)(aux[AT_PHDR] & -4096); 1340 } 1341 app_loadmap = p2 ? p1 : 0; 1342 ldso.loadmap = p2 ? p2 : p1; 1343 ldso.base = laddr(&ldso, 0); 1344 } else { 1345 ldso.base = base; 1346 } 1347 Ehdr *ehdr = (void *)ldso.base; 1348 ldso.name = ldso.shortname = "libc.so"; 1349 ldso.global = 1; 1350 ldso.phnum = ehdr->e_phnum; 1351 ldso.phdr = laddr(&ldso, ehdr->e_phoff); 1352 ldso.phentsize = ehdr->e_phentsize; 1353 kernel_mapped_dso(&ldso); 1354 decode_dyn(&ldso); 1355 1356 if (DL_FDPIC) makefuncdescs(&ldso); 1357 1358 /* Prepare storage for to save clobbered REL addends so they 1359 * can be reused in stage 3. There should be very few. If 1360 * something goes wrong and there are a huge number, abort 1361 * instead of risking stack overflow. */ 1362 size_t dyn[DYN_CNT]; 1363 decode_vec(ldso.dynv, dyn, DYN_CNT); 1364 size_t *rel = laddr(&ldso, dyn[DT_REL]); 1365 size_t rel_size = dyn[DT_RELSZ]; 1366 size_t symbolic_rel_cnt = 0; 1367 apply_addends_to = rel; 1368 for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) 1369 if (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++; 1370 if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash(); 1371 size_t addends[symbolic_rel_cnt+1]; 1372 saved_addends = addends; 1373 1374 head = &ldso; 1375 reloc_all(&ldso); 1376 1377 ldso.relocated = 0; 1378 1379 /* Call dynamic linker stage-3, __dls3, looking it up 1380 * symbolically as a barrier against moving the address 1381 * load across the above relocation processing. */ 1382 struct symdef dls3_def = find_sym(&ldso, "__dls3", 0); 1383 if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp); 1384 else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp); 1385} 1386 1387/* Stage 3 of the dynamic linker is called with the dynamic linker/libc 1388 * fully functional. Its job is to load (if not already loaded) and 1389 * process dependencies and relocations for the main application and 1390 * transfer control to its entry point. */ 1391 1392_Noreturn void __dls3(size_t *sp) 1393{ 1394 static struct dso app, vdso; 1395 size_t aux[AUX_CNT], *auxv; 1396 size_t i; 1397 char *env_preload=0; 1398 size_t vdso_base; 1399 int argc = *sp; 1400 char **argv = (void *)(sp+1); 1401 char **argv_orig = argv; 1402 char **envp = argv+argc+1; 1403 1404 /* Find aux vector just past environ[] and use it to initialize 1405 * global data that may be needed before we can make syscalls. */ 1406 __environ = envp; 1407 for (i=argc+1; argv[i]; i++); 1408 libc.auxv = auxv = (void *)(argv+i+1); 1409 decode_vec(auxv, aux, AUX_CNT); 1410 __hwcap = aux[AT_HWCAP]; 1411 libc.page_size = aux[AT_PAGESZ]; 1412 libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID] 1413 || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]); 1414 1415 /* Setup early thread pointer in builtin_tls for ldso/libc itself to 1416 * use during dynamic linking. If possible it will also serve as the 1417 * thread pointer at runtime. */ 1418 libc.tls_size = sizeof builtin_tls; 1419 libc.tls_align = tls_align; 1420 if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) { 1421 a_crash(); 1422 } 1423 1424 /* Only trust user/env if kernel says we're not suid/sgid */ 1425 if (!libc.secure) { 1426 env_path = getenv("LD_LIBRARY_PATH"); 1427 env_preload = getenv("LD_PRELOAD"); 1428 } 1429 1430 /* If the main program was already loaded by the kernel, 1431 * AT_PHDR will point to some location other than the dynamic 1432 * linker's program headers. */ 1433 if (aux[AT_PHDR] != (size_t)ldso.phdr) { 1434 size_t interp_off = 0; 1435 size_t tls_image = 0; 1436 /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */ 1437 Phdr *phdr = app.phdr = (void *)aux[AT_PHDR]; 1438 app.phnum = aux[AT_PHNUM]; 1439 app.phentsize = aux[AT_PHENT]; 1440 for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) { 1441 if (phdr->p_type == PT_PHDR) 1442 app.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr); 1443 else if (phdr->p_type == PT_INTERP) 1444 interp_off = (size_t)phdr->p_vaddr; 1445 else if (phdr->p_type == PT_TLS) { 1446 tls_image = phdr->p_vaddr; 1447 app.tls.len = phdr->p_filesz; 1448 app.tls.size = phdr->p_memsz; 1449 app.tls.align = phdr->p_align; 1450 } 1451 } 1452 if (DL_FDPIC) app.loadmap = app_loadmap; 1453 if (app.tls.size) app.tls.image = laddr(&app, tls_image); 1454 if (interp_off) ldso.name = laddr(&app, interp_off); 1455 if ((aux[0] & (1UL<<AT_EXECFN)) 1456 && strncmp((char *)aux[AT_EXECFN], "/proc/", 6)) 1457 app.name = (char *)aux[AT_EXECFN]; 1458 else 1459 app.name = argv[0]; 1460 kernel_mapped_dso(&app); 1461 } else { 1462 int fd; 1463 char *ldname = argv[0]; 1464 size_t l = strlen(ldname); 1465 if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1; 1466 argv++; 1467 while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') { 1468 char *opt = argv[0]+2; 1469 *argv++ = (void *)-1; 1470 if (!*opt) { 1471 break; 1472 } else if (!memcmp(opt, "list", 5)) { 1473 ldd_mode = 1; 1474 } else if (!memcmp(opt, "library-path", 12)) { 1475 if (opt[12]=='=') env_path = opt+13; 1476 else if (opt[12]) *argv = 0; 1477 else if (*argv) env_path = *argv++; 1478 } else if (!memcmp(opt, "preload", 7)) { 1479 if (opt[7]=='=') env_preload = opt+8; 1480 else if (opt[7]) *argv = 0; 1481 else if (*argv) env_preload = *argv++; 1482 } else { 1483 argv[0] = 0; 1484 } 1485 } 1486 argv[-1] = (void *)(argc - (argv-argv_orig)); 1487 if (!argv[0]) { 1488 dprintf(2, "musl libc (" LDSO_ARCH ")\n" 1489 "Version %s\n" 1490 "Dynamic Program Loader\n" 1491 "Usage: %s [options] [--] pathname%s\n", 1492 __libc_get_version(), ldname, 1493 ldd_mode ? "" : " [args]"); 1494 _exit(1); 1495 } 1496 fd = open(argv[0], O_RDONLY); 1497 if (fd < 0) { 1498 dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno)); 1499 _exit(1); 1500 } 1501 runtime = 1; 1502 Ehdr *ehdr = (void *)map_library(fd, &app); 1503 if (!ehdr) { 1504 dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]); 1505 _exit(1); 1506 } 1507 runtime = 0; 1508 close(fd); 1509 ldso.name = ldname; 1510 app.name = argv[0]; 1511 aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry); 1512 /* Find the name that would have been used for the dynamic 1513 * linker had ldd not taken its place. */ 1514 if (ldd_mode) { 1515 for (i=0; i<app.phnum; i++) { 1516 if (app.phdr[i].p_type == PT_INTERP) 1517 ldso.name = laddr(&app, app.phdr[i].p_vaddr); 1518 } 1519 dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base); 1520 } 1521 } 1522 if (app.tls.size) { 1523 libc.tls_head = tls_tail = &app.tls; 1524 app.tls_id = tls_cnt = 1; 1525#ifdef TLS_ABOVE_TP 1526 app.tls.offset = 0; 1527 tls_offset = app.tls.size 1528 + ( -((uintptr_t)app.tls.image + app.tls.size) 1529 & (app.tls.align-1) ); 1530#else 1531 tls_offset = app.tls.offset = app.tls.size 1532 + ( -((uintptr_t)app.tls.image + app.tls.size) 1533 & (app.tls.align-1) ); 1534#endif 1535 tls_align = MAXP2(tls_align, app.tls.align); 1536 } 1537 app.global = 1; 1538 decode_dyn(&app); 1539 if (DL_FDPIC) { 1540 makefuncdescs(&app); 1541 if (!app.loadmap) { 1542 app.loadmap = (void *)&app_dummy_loadmap; 1543 app.loadmap->nsegs = 1; 1544 app.loadmap->segs[0].addr = (size_t)app.map; 1545 app.loadmap->segs[0].p_vaddr = (size_t)app.map 1546 - (size_t)app.base; 1547 app.loadmap->segs[0].p_memsz = app.map_len; 1548 } 1549 argv[-3] = (void *)app.loadmap; 1550 } 1551 1552 /* Attach to vdso, if provided by the kernel */ 1553 if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) { 1554 Ehdr *ehdr = (void *)vdso_base; 1555 Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff); 1556 vdso.phnum = ehdr->e_phnum; 1557 vdso.phentsize = ehdr->e_phentsize; 1558 for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) { 1559 if (phdr->p_type == PT_DYNAMIC) 1560 vdso.dynv = (void *)(vdso_base + phdr->p_offset); 1561 if (phdr->p_type == PT_LOAD) 1562 vdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset); 1563 } 1564 vdso.name = ""; 1565 vdso.shortname = "linux-gate.so.1"; 1566 vdso.global = 1; 1567 vdso.relocated = 1; 1568 decode_dyn(&vdso); 1569 vdso.prev = &ldso; 1570 ldso.next = &vdso; 1571 } 1572 1573 /* Initial dso chain consists only of the app. */ 1574 head = tail = &app; 1575 1576 /* Donate unused parts of app and library mapping to malloc */ 1577 reclaim_gaps(&app); 1578 reclaim_gaps(&ldso); 1579 1580 /* Load preload/needed libraries, add their symbols to the global 1581 * namespace, and perform all remaining relocations. */ 1582 if (env_preload) load_preload(env_preload); 1583 load_deps(&app); 1584 make_global(&app); 1585 1586 for (i=0; app.dynv[i]; i+=2) { 1587 if (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG) 1588 app.dynv[i+1] = (size_t)&debug; 1589 if (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) { 1590 size_t *ptr = (size_t *) app.dynv[i+1]; 1591 *ptr = (size_t)&debug; 1592 } 1593 } 1594 1595 /* The main program must be relocated LAST since it may contin 1596 * copy relocations which depend on libraries' relocations. */ 1597 reloc_all(app.next); 1598 reloc_all(&app); 1599 1600 update_tls_size(); 1601 if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) { 1602 void *initial_tls = calloc(libc.tls_size, 1); 1603 if (!initial_tls) { 1604 dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n", 1605 argv[0], libc.tls_size); 1606 _exit(127); 1607 } 1608 if (__init_tp(__copy_tls(initial_tls)) < 0) { 1609 a_crash(); 1610 } 1611 } else { 1612 size_t tmp_tls_size = libc.tls_size; 1613 pthread_t self = __pthread_self(); 1614 /* Temporarily set the tls size to the full size of 1615 * builtin_tls so that __copy_tls will use the same layout 1616 * as it did for before. Then check, just to be safe. */ 1617 libc.tls_size = sizeof builtin_tls; 1618 if (__copy_tls((void*)builtin_tls) != self) a_crash(); 1619 libc.tls_size = tmp_tls_size; 1620 } 1621 static_tls_cnt = tls_cnt; 1622 1623 if (ldso_fail) _exit(127); 1624 if (ldd_mode) _exit(0); 1625 1626 /* Switch to runtime mode: any further failures in the dynamic 1627 * linker are a reportable failure rather than a fatal startup 1628 * error. */ 1629 runtime = 1; 1630 1631 debug.ver = 1; 1632 debug.bp = dl_debug_state; 1633 debug.head = head; 1634 debug.base = ldso.base; 1635 debug.state = 0; 1636 _dl_debug_state(); 1637 1638 errno = 0; 1639 1640 CRTJMP((void *)aux[AT_ENTRY], argv-1); 1641 for(;;); 1642} 1643 1644void *dlopen(const char *file, int mode) 1645{ 1646 struct dso *volatile p, *orig_tail, *next; 1647 struct tls_module *orig_tls_tail; 1648 size_t orig_tls_cnt, orig_tls_offset, orig_tls_align; 1649 size_t i; 1650 int cs; 1651 jmp_buf jb; 1652 1653 if (!file) return head; 1654 1655 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); 1656 pthread_rwlock_wrlock(&lock); 1657 __inhibit_ptc(); 1658 1659 p = 0; 1660 orig_tls_tail = tls_tail; 1661 orig_tls_cnt = tls_cnt; 1662 orig_tls_offset = tls_offset; 1663 orig_tls_align = tls_align; 1664 orig_tail = tail; 1665 noload = mode & RTLD_NOLOAD; 1666 1667 rtld_fail = &jb; 1668 if (setjmp(*rtld_fail)) { 1669 /* Clean up anything new that was (partially) loaded */ 1670 if (p && p->deps) for (i=0; p->deps[i]; i++) 1671 if (p->deps[i]->global < 0) 1672 p->deps[i]->global = 0; 1673 for (p=orig_tail->next; p; p=next) { 1674 next = p->next; 1675 while (p->td_index) { 1676 void *tmp = p->td_index->next; 1677 free(p->td_index); 1678 p->td_index = tmp; 1679 } 1680 free(p->funcdescs); 1681 if (p->rpath != p->rpath_orig) 1682 free(p->rpath); 1683 free(p->deps); 1684 unmap_library(p); 1685 free(p); 1686 } 1687 if (!orig_tls_tail) libc.tls_head = 0; 1688 tls_tail = orig_tls_tail; 1689 tls_cnt = orig_tls_cnt; 1690 tls_offset = orig_tls_offset; 1691 tls_align = orig_tls_align; 1692 tail = orig_tail; 1693 tail->next = 0; 1694 p = 0; 1695 goto end; 1696 } else p = load_library(file, head); 1697 1698 if (!p) { 1699 error(noload ? 1700 "Library %s is not already loaded" : 1701 "Error loading shared library %s: %m", 1702 file); 1703 goto end; 1704 } 1705 1706 /* First load handling */ 1707 if (!p->deps) { 1708 load_deps(p); 1709 if (p->deps) for (i=0; p->deps[i]; i++) 1710 if (!p->deps[i]->global) 1711 p->deps[i]->global = -1; 1712 if (!p->global) p->global = -1; 1713 reloc_all(p); 1714 if (p->deps) for (i=0; p->deps[i]; i++) 1715 if (p->deps[i]->global < 0) 1716 p->deps[i]->global = 0; 1717 if (p->global < 0) p->global = 0; 1718 } 1719 1720 if (mode & RTLD_GLOBAL) { 1721 if (p->deps) for (i=0; p->deps[i]; i++) 1722 p->deps[i]->global = 1; 1723 p->global = 1; 1724 } 1725 1726 update_tls_size(); 1727 _dl_debug_state(); 1728 orig_tail = tail; 1729end: 1730 __release_ptc(); 1731 if (p) gencnt++; 1732 pthread_rwlock_unlock(&lock); 1733 if (p) do_init_fini(orig_tail); 1734 pthread_setcancelstate(cs, 0); 1735 return p; 1736} 1737 1738__attribute__((__visibility__("hidden"))) 1739int __dl_invalid_handle(void *h) 1740{ 1741 struct dso *p; 1742 for (p=head; p; p=p->next) if (h==p) return 0; 1743 error("Invalid library handle %p", (void *)h); 1744 return 1; 1745} 1746 1747static void *addr2dso(size_t a) 1748{ 1749 struct dso *p; 1750 size_t i; 1751 if (DL_FDPIC) for (p=head; p; p=p->next) { 1752 i = count_syms(p); 1753 if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs)) 1754 return p; 1755 } 1756 for (p=head; p; p=p->next) { 1757 if (DL_FDPIC && p->loadmap) { 1758 for (i=0; i<p->loadmap->nsegs; i++) { 1759 if (a-p->loadmap->segs[i].p_vaddr 1760 < p->loadmap->segs[i].p_memsz) 1761 return p; 1762 } 1763 } else { 1764 if (a-(size_t)p->map < p->map_len) 1765 return p; 1766 } 1767 } 1768 return 0; 1769} 1770 1771void *__tls_get_addr(size_t *); 1772 1773static void *do_dlsym(struct dso *p, const char *s, void *ra) 1774{ 1775 size_t i; 1776 uint32_t h = 0, gh = 0, *ght; 1777 Sym *sym; 1778 if (p == head || p == RTLD_DEFAULT || p == RTLD_NEXT) { 1779 if (p == RTLD_DEFAULT) { 1780 p = head; 1781 } else if (p == RTLD_NEXT) { 1782 p = addr2dso((size_t)ra); 1783 if (!p) p=head; 1784 p = p->next; 1785 } 1786 struct symdef def = find_sym(p, s, 0); 1787 if (!def.sym) goto failed; 1788 if ((def.sym->st_info&0xf) == STT_TLS) 1789 return __tls_get_addr((size_t []){def.dso->tls_id, def.sym->st_value}); 1790 if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC) 1791 return def.dso->funcdescs + (def.sym - def.dso->syms); 1792 return laddr(def.dso, def.sym->st_value); 1793 } 1794 if (__dl_invalid_handle(p)) 1795 return 0; 1796 if ((ght = p->ghashtab)) { 1797 gh = gnu_hash(s); 1798 sym = gnu_lookup(gh, ght, p, s); 1799 } else { 1800 h = sysv_hash(s); 1801 sym = sysv_lookup(s, h, p); 1802 } 1803 if (sym && (sym->st_info&0xf) == STT_TLS) 1804 return __tls_get_addr((size_t []){p->tls_id, sym->st_value}); 1805 if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC) 1806 return p->funcdescs + (sym - p->syms); 1807 if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES)) 1808 return laddr(p, sym->st_value); 1809 if (p->deps) for (i=0; p->deps[i]; i++) { 1810 if ((ght = p->deps[i]->ghashtab)) { 1811 if (!gh) gh = gnu_hash(s); 1812 sym = gnu_lookup(gh, ght, p->deps[i], s); 1813 } else { 1814 if (!h) h = sysv_hash(s); 1815 sym = sysv_lookup(s, h, p->deps[i]); 1816 } 1817 if (sym && (sym->st_info&0xf) == STT_TLS) 1818 return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value}); 1819 if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC) 1820 return p->deps[i]->funcdescs + (sym - p->deps[i]->syms); 1821 if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES)) 1822 return laddr(p->deps[i], sym->st_value); 1823 } 1824failed: 1825 error("Symbol not found: %s", s); 1826 return 0; 1827} 1828 1829int dladdr(const void *addr, Dl_info *info) 1830{ 1831 struct dso *p; 1832 Sym *sym, *bestsym; 1833 uint32_t nsym; 1834 char *strings; 1835 void *best = 0; 1836 1837 pthread_rwlock_rdlock(&lock); 1838 p = addr2dso((size_t)addr); 1839 pthread_rwlock_unlock(&lock); 1840 1841 if (!p) return 0; 1842 1843 sym = p->syms; 1844 strings = p->strings; 1845 nsym = count_syms(p); 1846 1847 if (DL_FDPIC) { 1848 size_t idx = ((size_t)addr-(size_t)p->funcdescs) 1849 / sizeof(*p->funcdescs); 1850 if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) { 1851 best = p->funcdescs + idx; 1852 bestsym = sym + idx; 1853 } 1854 } 1855 1856 if (!best) for (; nsym; nsym--, sym++) { 1857 if (sym->st_value 1858 && (1<<(sym->st_info&0xf) & OK_TYPES) 1859 && (1<<(sym->st_info>>4) & OK_BINDS)) { 1860 void *symaddr = laddr(p, sym->st_value); 1861 if (symaddr > addr || symaddr < best) 1862 continue; 1863 best = symaddr; 1864 bestsym = sym; 1865 if (addr == symaddr) 1866 break; 1867 } 1868 } 1869 1870 if (!best) return 0; 1871 1872 if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC) 1873 best = p->funcdescs + (bestsym - p->syms); 1874 1875 info->dli_fname = p->name; 1876 info->dli_fbase = p->base; 1877 info->dli_sname = strings + bestsym->st_name; 1878 info->dli_saddr = best; 1879 1880 return 1; 1881} 1882 1883__attribute__((__visibility__("hidden"))) 1884void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra) 1885{ 1886 void *res; 1887 pthread_rwlock_rdlock(&lock); 1888 res = do_dlsym(p, s, ra); 1889 pthread_rwlock_unlock(&lock); 1890 return res; 1891} 1892 1893int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data) 1894{ 1895 struct dso *current; 1896 struct dl_phdr_info info; 1897 int ret = 0; 1898 for(current = head; current;) { 1899 info.dlpi_addr = (uintptr_t)current->base; 1900 info.dlpi_name = current->name; 1901 info.dlpi_phdr = current->phdr; 1902 info.dlpi_phnum = current->phnum; 1903 info.dlpi_adds = gencnt; 1904 info.dlpi_subs = 0; 1905 info.dlpi_tls_modid = current->tls_id; 1906 info.dlpi_tls_data = current->tls.image; 1907 1908 ret = (callback)(&info, sizeof (info), data); 1909 1910 if (ret != 0) break; 1911 1912 pthread_rwlock_rdlock(&lock); 1913 current = current->next; 1914 pthread_rwlock_unlock(&lock); 1915 } 1916 return ret; 1917} 1918 1919__attribute__((__visibility__("hidden"))) 1920void __dl_vseterr(const char *, va_list); 1921 1922static void error(const char *fmt, ...) 1923{ 1924 va_list ap; 1925 va_start(ap, fmt); 1926 if (!runtime) { 1927 vdprintf(2, fmt, ap); 1928 dprintf(2, "\n"); 1929 ldso_fail = 1; 1930 va_end(ap); 1931 return; 1932 } 1933 __dl_vseterr(fmt, ap); 1934 va_end(ap); 1935} 1936