Bug Summary

File:ldso/dynlink.c
Warning:line 644, column 12
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage

Annotated Source Code

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(*__errno_location()).h>
15#include <link.h>
16#include <setjmpsetjmp.h>
17#include <pthread__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))) (-(-(a)&-(b)))
27#define ALIGN(x,y)((x)+(y)-1 & -(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_FDPIC0
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_FDPIC0
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__pthread pt;
108 void *space[16];
109} builtin_tls[1];
110#define MIN_TLS_ALIGN__builtin_offsetof(struct builtin_tls, pt) offsetof(struct builtin_tls, pt)__builtin_offsetof(struct builtin_tls, pt)
111
112#define ADDEND_LIMIT4096 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__builtin_offsetof(struct builtin_tls, pt);
128static size_t static_tls_cnt;
129static pthread_mutex_t init_fini_lock = { ._m_type__u.__i[0] = PTHREAD_MUTEX_RECURSIVE1 };
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)extern __typeof(__init_array_start) __init_array_end __attribute__
((weak, alias("__init_array_start")))
;
142weak_alias(__fini_array_start, __fini_array_end)extern __typeof(__fini_array_start) __fini_array_end __attribute__
((weak, alias("__fini_array_start")))
;
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) dl_strcmp(l,r)
150
151/* Compute load address for a virtual address in a given dso. */
152#if DL_FDPIC0
153static void *laddr(const struct dso *p, size_t v)(void *)((const struct dso *p)->base + (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 (*)())(void *)((p)->base + (v))) ((void (*)())&(struct funcdesc){ \
161 laddr(p, v)(void *)((p)->base + (v)), (p)->got })
162#else
163#define laddr(p, v)(void *)((p)->base + (v)) (void *)((p)->base + (v))
164#define fpaddr(p, v)((void (*)())(void *)((p)->base + (v))) ((void (*)())laddr(p, v)(void *)((p)->base + (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)dl_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)dl_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<<0 | 1<<1 | 1<<2 | 1<<5 | 1<<
6)
(1<<STT_NOTYPE0 | 1<<STT_OBJECT1 | 1<<STT_FUNC2 | 1<<STT_COMMON5 | 1<<STT_TLS6)
253#define OK_BINDS(1<<1 | 1<<2 | 1<<10) (1<<STB_GLOBAL1 | 1<<STB_WEAK2 | 1<<STB_GNU_UNIQUE10)
254
255#ifndef ARCH_SYM_REJECT_UND
256#define ARCH_SYM_REJECT_UND(s)0 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_TLS6
282 || ARCH_SYM_REJECT_UND(sym)0)
283 continue;
284 if (!sym->st_value)
285 if ((sym->st_info&0xf) != STT_TLS6)
286 continue;
287 if (!(1<<(sym->st_info&0xf) & OK_TYPES(1<<0 | 1<<1 | 1<<2 | 1<<5 | 1<<
6)
)) continue;
288 if (!(1<<(sym->st_info>>4) & OK_BINDS(1<<1 | 1<<2 | 1<<10))) continue;
289
290 if (def.sym && sym->st_info>>4 == STB_WEAK2) continue;
291 def.sym = sym;
292 def.dso = dso;
293 if (sym->st_info>>4 == STB_GLOBAL1) 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)( (((rel[1])&0x7fffffff) == 8) || (((rel[1])&0x7fffffff
) == REL_SYM_OR_REL && !((rel[1])>>32)) )
) continue;
327 type = R_TYPE(rel[1])((rel[1])&0x7fffffff);
328 if (type == REL_NONE) continue;
329 sym_index = R_SYM(rel[1])((rel[1])>>32);
330 reloc_addr = laddr(dso, rel[0])(void *)((dso)->base + (rel[0]));
331 if (sym_index) {
332 sym = syms + sym_index;
333 name = strings + sym->st_name;
334 ctx = type==REL_COPY5 ? head->next : head;
335 def = (sym->st_info&0xf) == STT_SECTION3
336 ? (struct symdef){ .dso = dso, .sym = sym }
337 : find_sym(ctx, name, type==REL_PLT7);
338 if (!def.sym && (sym->st_shndx != SHN_UNDEF0
339 || sym->st_info>>4 != STB_WEAK2)) {
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_GOT6 || type==REL_PLT7|| type==REL_COPY5) {
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)(void *)((def.dso)->base + (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_SYMBOLIC1:
375 case REL_GOT6:
376 case REL_PLT7:
377 *reloc_addr = sym_val + addend;
378 break;
379 case REL_RELATIVE8:
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_COPY5:
387 memcpy(reloc_addr, (void *)sym_val, sym->st_size);
388 break;
389 case REL_OFFSET322:
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_SECTION3) *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_DTPMOD16:
403 *reloc_addr = def.dso->tls_id;
404 break;
405 case REL_DTPOFF17:
406 *reloc_addr = tls_val + addend - DTP_OFFSET0;
407 break;
408#ifdef TLS_ABOVE_TP
409 case REL_TPOFF18:
410 *reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend;
411 break;
412#else
413 case REL_TPOFF18:
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_TLSDESC36:
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)(void *)((dso)->base + (start));
471 z = laddr(dso, end)(void *)((dso)->base + (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_FDPIC0) return; // FIXME
484 for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) {
485 if (ph->p_type!=PT_LOAD1) continue;
486 if ((ph->p_flags&(PF_R(1 << 2)|PF_W(1 << 1)))!=(PF_R(1 << 2)|PF_W(1 << 1))) continue;
487 reclaim(dso, ph->p_vaddr & -PAGE_SIZE4096, ph->p_vaddr);
488 reclaim(dso, ph->p_vaddr+ph->p_memsz,
489 ph->p_vaddr+ph->p_memsz+PAGE_SIZE4096-1 & -PAGE_SIZE4096);
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_FIXED0x10, fd, off);
499 if (!DL_NOMMU_SUPPORT0 || q != MAP_FAILED((void *) -1) || errno(*__errno_location()) != EINVAL22)
500 return q;
501 no_map_fixed = 1;
502 }
503 /* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
504 if (flags & MAP_ANONYMOUS0x20) {
505 memset(p, 0, n);
506 return p;
507 }
508 ssize_t r;
509 if (lseek(fd, off, SEEK_SET0) < 0) return MAP_FAILED((void *) -1);
510 for (q=p; n; q+=r, off+=r, n-=r) {
511 r = read(fd, q, n);
512 if (r < 0 && errno(*__errno_location()) != EINTR4) return MAP_FAILED((void *) -1);
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(0xffffffffffffffffu), addr_max=0, map_len;
543 size_t this_min, this_max;
544 size_t nsegs = 0;
545 off_t off_start;
1
'off_start' declared without an initial value
546 Ehdr *eh;
547 Phdr *ph, *ph0;
548 unsigned prot;
549 unsigned char *map=MAP_FAILED((void *) -1), *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;
2
Assuming 'l' is >= 0
3
Taking false branch
557 if (l<sizeof *eh || (eh->e_type != ET_DYN3 && eh->e_type != ET_EXEC2))
4
Assuming the condition is false
5
Assuming the condition is false
558 goto noexec;
559 phsize = eh->e_phentsize * eh->e_phnum;
560 if (phsize > sizeof buf - sizeof *eh) {
6
Assuming the condition is false
7
Taking false branch
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) {
8
Taking false branch
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)) {
9
Loop condition is true. Entering loop body
22
Loop condition is true. Entering loop body
35
Loop condition is true. Entering loop body
40
Loop condition is false. Execution continues on line 600
576 if (ph->p_type == PT_DYNAMIC2) {
10
Assuming the condition is false
11
Taking false branch
23
Assuming the condition is false
24
Taking false branch
36
Assuming the condition is true
37
Taking true branch
577 dyn = ph->p_vaddr;
578 } else if (ph->p_type == PT_TLS7) {
12
Assuming the condition is false
13
Taking false branch
25
Assuming the condition is false
26
Taking false branch
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_RELRO0x6474e552) {
14
Assuming the condition is false
15
Taking false branch
27
Assuming the condition is false
28
Taking false branch
584 dso->relro_start = ph->p_vaddr & -PAGE_SIZE4096;
585 dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE4096;
586 }
587 if (ph->p_type != PT_LOAD1) continue;
16
Assuming the condition is false
17
Taking false branch
29
Assuming the condition is false
30
Taking false branch
38
Taking true branch
39
Execution continues on line 575
588 nsegs++;
589 if (ph->p_vaddr < addr_min) {
18
Assuming the condition is false
19
Taking false branch
31
Assuming the condition is false
32
Taking false branch
590 addr_min = ph->p_vaddr;
591 off_start = ph->p_offset;
592 prot = (((ph->p_flags&PF_R(1 << 2)) ? PROT_READ1 : 0) |
593 ((ph->p_flags&PF_W(1 << 1)) ? PROT_WRITE2: 0) |
594 ((ph->p_flags&PF_X(1 << 0)) ? PROT_EXEC4 : 0));
595 }
596 if (ph->p_vaddr+ph->p_memsz > addr_max) {
20
Assuming the condition is false
21
Taking false branch
33
Assuming the condition is false
34
Taking false branch
597 addr_max = ph->p_vaddr+ph->p_memsz;
598 }
599 }
600 if (!dyn) goto noexec;
41
Assuming 'dyn' is not equal to 0
42
Taking false branch
601 if (DL_FDPIC0 && !(eh->e_flags & FDPIC_CONSTDISP_FLAG0)) {
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_LOAD1) continue;
608 prot = (((ph->p_flags&PF_R(1 << 2)) ? PROT_READ1 : 0) |
609 ((ph->p_flags&PF_W(1 << 1)) ? PROT_WRITE2: 0) |
610 ((ph->p_flags&PF_X(1 << 0)) ? PROT_EXEC4 : 0));
611 map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE4096-1),
612 prot, MAP_PRIVATE0x02,
613 fd, ph->p_offset & -PAGE_SIZE4096);
614 if (map == MAP_FAILED((void *) -1)) {
615 unmap_library(dso);
616 goto error;
617 }
618 dso->loadmap->segs[i].addr = (size_t)map +
619 (ph->p_vaddr & PAGE_SIZE4096-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_WRITE2) {
624 size_t brk = (ph->p_vaddr & PAGE_SIZE4096-1)
625 + ph->p_filesz;
626 size_t pgbrk = brk + PAGE_SIZE4096-1 & -PAGE_SIZE4096;
627 size_t pgend = brk + ph->p_memsz - ph->p_filesz
628 + PAGE_SIZE4096-1 & -PAGE_SIZE4096;
629 if (pgend > pgbrk && mmap_fixed(map+pgbrk,
630 pgend-pgbrk, prot,
631 MAP_PRIVATE0x02|MAP_FIXED0x10|MAP_ANONYMOUS0x20,
632 -1, off_start) == MAP_FAILED((void *) -1))
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_SIZE4096-1;
642 addr_max &= -PAGE_SIZE4096;
643 addr_min &= -PAGE_SIZE4096;
644 off_start &= -PAGE_SIZE4096;
43
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage
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_SUPPORT0
651 ? mmap((void *)addr_min, map_len, PROT_READ1|PROT_WRITE2|PROT_EXEC4,
652 MAP_PRIVATE0x02|MAP_ANONYMOUS0x20, -1, 0)
653 : mmap((void *)addr_min, map_len, prot,
654 MAP_PRIVATE0x02, fd, off_start);
655 if (map==MAP_FAILED((void *) -1)) 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_DYN3 && addr_min && map!=(void *)addr_min) {
661 errno(*__errno_location()) = EBUSY16;
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_LOAD1) 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_SIZE4096) == addr_min && !DL_NOMMU_SUPPORT0)
680 continue;
681 this_min = ph->p_vaddr & -PAGE_SIZE4096;
682 this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE4096-1 & -PAGE_SIZE4096;
683 off_start = ph->p_offset & -PAGE_SIZE4096;
684 prot = (((ph->p_flags&PF_R(1 << 2)) ? PROT_READ1 : 0) |
685 ((ph->p_flags&PF_W(1 << 1)) ? PROT_WRITE2: 0) |
686 ((ph->p_flags&PF_X(1 << 0)) ? PROT_EXEC4 : 0));
687 if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE0x02|MAP_FIXED0x10, fd, off_start) == MAP_FAILED((void *) -1))
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_SIZE4096-1 & -PAGE_SIZE4096;
692 memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE4096-1);
693 if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE0x02|MAP_FIXED0x10|MAP_ANONYMOUS0x20, -1, 0) == MAP_FAILED((void *) -1))
694 goto error;
695 }
696 }
697 for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
698 if (((size_t *)(base+dyn))[i]==DT_TEXTREL22) {
699 if (mprotect(map, map_len, PROT_READ1|PROT_WRITE2|PROT_EXEC4)
700 && errno(*__errno_location()) != ENOSYS38)
701 goto error;
702 break;
703 }
704done_mapping:
705 dso->base = base;
706 dso->dynv = laddr(dso, dyn)(void *)((dso)->base + (dyn));
707 if (dso->tls.size) dso->tls.image = laddr(dso, tls_image)(void *)((dso)->base + (tls_image));
708 if (!runtime) reclaim_gaps(dso);
709 free(allocated_buf);
710 return map;
711noexec:
712 errno(*__errno_location()) = ENOEXEC8;
713error:
714 if (map!=MAP_FAILED((void *) -1)) 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_MAX0x7fffffff) return -1;
727 if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
728 if ((fd = open(buf, O_RDONLY00|O_CLOEXEC02000000))>=0) return fd;
729 switch (errno(*__errno_location())) {
730 case ENOENT2:
731 case ENOTDIR20:
732 case EACCES13:
733 case ENAMETOOLONG36:
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_MAX0x7fffffffffffffffL/PATH_MAX4096) 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__libc.secure)
773 return 0;
774 l = readlink("/proc/self/exe", buf, buf_size);
775 if (l == -1) switch (errno(*__errno_location())) {
776 case ENOENT2:
777 case ENOTDIR20:
778 case EACCES13:
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_CNT32];
813 decode_vec(p->dynv, dyn, DYN_CNT32);
814 p->syms = laddr(p, dyn[DT_SYMTAB])(void *)((p)->base + (dyn[6]));
815 p->strings = laddr(p, dyn[DT_STRTAB])(void *)((p)->base + (dyn[5]));
816 if (dyn[0]&(1<<DT_HASH4))
817 p->hashtab = laddr(p, dyn[DT_HASH])(void *)((p)->base + (dyn[4]));
818 if (dyn[0]&(1<<DT_RPATH15))
819 p->rpath_orig = p->strings + dyn[DT_RPATH15];
820 if (dyn[0]&(1<<DT_RUNPATH29))
821 p->rpath_orig = p->strings + dyn[DT_RUNPATH29];
822 if (dyn[0]&(1<<DT_PLTGOT3))
823 p->got = laddr(p, dyn[DT_PLTGOT])(void *)((p)->base + (dyn[3]));
824 if (search_vec(p->dynv, dyn, DT_GNU_HASH0x6ffffef5))
825 p->ghashtab = laddr(p, *dyn)(void *)((p)->base + (*dyn));
826 if (search_vec(p->dynv, dyn, DT_VERSYM0x6ffffff0))
827 p->versym = laddr(p, *dyn)(void *)((p)->base + (*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_READ1|PROT_WRITE2, flags = MAP_ANONYMOUS0x20|MAP_PRIVATE0x02;
853#ifdef SYS_mmap2
854 p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0)__syscall6(SYS_mmap2,((long) (0)),((long) (n)),((long) (prot)
),((long) (flags)),((long) (-1)),((long) (0)))
;
855#else
856 p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0)__syscall6(9,((long) (0)),((long) (n)),((long) (prot)),((long
) (flags)),((long) (-1)),((long) (0)))
;
857#endif
858 return p == MAP_FAILED((void *) -1) ? 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_crasha_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_FUNC2 && p->syms[i].st_shndx) {
880 p->funcdescs[i].addr = laddr(p, p->syms[i].st_value)(void *)((p)->base + (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_MAX255+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(*__errno_location()) = EINVAL22;
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)dl_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_RDONLY00|O_CLOEXEC02000000);
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)dl_strcmp(p->shortname,name)) {
948 p->refcnt++;
949 return p;
950 }
951 }
952 if (strlen(name) > NAME_MAX255) 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_MAX4096)
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"x86_64" ".path"];
979 snprintf(etc_ldso_path, sizeof etc_ldso_path,
980 "%.*s/etc/ld-musl-" LDSO_ARCH"x86_64" ".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(*__errno_location()) != ENOENT2) {
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__libc.threads_minus_1 + 1;
1029 if (n_th > SSIZE_MAX0x7fffffffffffffffL / per_th) alloc_size = SIZE_MAX(0xffffffffffffffffu);
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)(-(-(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__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_FDPIC0) 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_NEEDED1) 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)__isspace(*s) || *s==':'); s++);
1110 for (z=s; *z && !isspace(*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_GOTNO0x7000000a);
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_GOTSYM0x70000013);
1134 i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO0x70000011);
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)((((Elf64_Xword) (sym-p->syms)) << 32) + (127));
1139 do_relocs(p, rel, sizeof rel, 2);
1140 }
1141}
1142
1143static void reloc_all(struct dso *p)
1144{
1145 size_t dyn[DYN_CNT32];
1146 for (; p; p=p->next) {
1147 if (p->relocated) continue;
1148 decode_vec(p->dynv, dyn, DYN_CNT32);
1149 if (NEED_MIPS_GOT_RELOCS0)
1150 do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT])(void *)((p)->base + (dyn[3])));
1151 do_relocs(p, laddr(p, dyn[DT_JMPREL])(void *)((p)->base + (dyn[23])), dyn[DT_PLTRELSZ2],
1152 2+(dyn[DT_PLTREL20]==DT_RELA7));
1153 do_relocs(p, laddr(p, dyn[DT_REL])(void *)((p)->base + (dyn[17])), dyn[DT_RELSZ18], 2);
1154 do_relocs(p, laddr(p, dyn[DT_RELA])(void *)((p)->base + (dyn[7])), dyn[DT_RELASZ8], 3);
1155
1156 if (head != &ldso && p->relro_start != p->relro_end &&
1157 mprotect(laddr(p, p->relro_start)(void *)((p)->base + (p->relro_start)), p->relro_end-p->relro_start, PROT_READ1)
1158 && errno(*__errno_location()) != ENOSYS38) {
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_DYNAMIC2) {
1174 p->dynv = laddr(p, ph->p_vaddr)(void *)((p)->base + (ph->p_vaddr));
1175 } else if (ph->p_type == PT_GNU_RELRO0x6474e552) {
1176 p->relro_start = ph->p_vaddr & -PAGE_SIZE4096;
1177 p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE4096;
1178 }
1179 if (ph->p_type != PT_LOAD1) 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_SIZE4096;
1186 max_addr = (max_addr + PAGE_SIZE4096-1) & -PAGE_SIZE4096;
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_CNT32];
1196 for (p=fini_head; p; p=p->fini_next) {
1197 if (!p->constructed) continue;
1198 decode_vec(p->dynv, dyn, DYN_CNT32);
1199 if (dyn[0] & (1<<DT_FINI_ARRAY26)) {
1200 size_t n = dyn[DT_FINI_ARRAYSZ28]/sizeof(size_t);
1201 size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])(void *)((p)->base + (dyn[26]))+n;
1202 while (n--) ((void (*)(void))*--fn)();
1203 }
1204#ifndef NO_LEGACY_INITFINI
1205 if ((dyn[0] & (1<<DT_FINI13)) && dyn[DT_FINI13])
1206 fpaddr(p, dyn[DT_FINI])((void (*)())(void *)((p)->base + (dyn[13])))();
1207#endif
1208 }
1209}
1210
1211static void do_init_fini(struct dso *p)
1212{
1213 size_t dyn[DYN_CNT32];
1214 int need_locking = libc__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_CNT32);
1223 if (dyn[0] & ((1<<DT_FINI13) | (1<<DT_FINI_ARRAY26))) {
1224 p->fini_next = fini_head;
1225 fini_head = p;
1226 }
1227#ifndef NO_LEGACY_INITFINI
1228 if ((dyn[0] & (1<<DT_INIT12)) && dyn[DT_INIT12])
1229 fpaddr(p, dyn[DT_INIT])((void (*)())(void *)((p)->base + (dyn[12])))();
1230#endif
1231 if (dyn[0] & (1<<DT_INIT_ARRAY25)) {
1232 size_t n = dyn[DT_INIT_ARRAYSZ27]/sizeof(size_t);
1233 size_t *fn = laddr(p, dyn[DT_INIT_ARRAY])(void *)((p)->base + (dyn[25]));
1234 while (n--) ((void (*)(void))*fn++)();
1235 }
1236 if (!need_locking && libc__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)extern __typeof(dl_debug_state) _dl_debug_state __attribute__
((weak, alias("dl_debug_state")))
;
1254
1255void __init_tls(size_t *auxv)
1256{
1257}
1258
1259__attribute__((__visibility__("hidden")))
1260void *__tls_get_new(tls_mod_off_tsize_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_OFFSET0;
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_adda_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_adda_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_OFFSET0;
1303}
1304
1305static void update_tls_size()
1306{
1307 libc__libc.tls_cnt = tls_cnt;
1308 libc__libc.tls_align = tls_align;
1309 libc__libc.tls_size = ALIGN((((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1310 (1+tls_cnt) * sizeof(void *) +(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1311 tls_offset +(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1312 sizeof(struct pthread) +(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1313 tls_align * 2,(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1314 tls_align)(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(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_FDPIC0) {
1332 void *p1 = (void *)sp[-2];
1333 void *p2 = (void *)sp[-1];
1334 if (!p1) {
1335 size_t *auxv, aux[AUX_CNT32];
1336 for (auxv=sp+1+*sp+1; *auxv; auxv++); auxv++;
1337 decode_vec(auxv, aux, AUX_CNT32);
1338 if (aux[AT_BASE7]) ldso.base = (void *)aux[AT_BASE7];
1339 else ldso.base = (void *)(aux[AT_PHDR3] & -4096);
1340 }
1341 app_loadmap = p2 ? p1 : 0;
1342 ldso.loadmap = p2 ? p2 : p1;
1343 ldso.base = laddr(&ldso, 0)(void *)((&ldso)->base + (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)(void *)((&ldso)->base + (ehdr->e_phoff));
1352 ldso.phentsize = ehdr->e_phentsize;
1353 kernel_mapped_dso(&ldso);
1354 decode_dyn(&ldso);
1355
1356 if (DL_FDPIC0) 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_CNT32];
1363 decode_vec(ldso.dynv, dyn, DYN_CNT32);
1364 size_t *rel = laddr(&ldso, dyn[DT_REL])(void *)((&ldso)->base + (dyn[17]));
1365 size_t rel_size = dyn[DT_RELSZ18];
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)( (((rel[1])&0x7fffffff) == 8) || (((rel[1])&0x7fffffff
) == REL_SYM_OR_REL && !((rel[1])>>32)) )
) symbolic_rel_cnt++;
1370 if (symbolic_rel_cnt >= ADDEND_LIMIT4096) a_crasha_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_FDPIC0) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp);
1384 else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value)(void *)((&ldso)->base + (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__attribute__((__noreturn__)) void __dls3(size_t *sp)
1393{
1394 static struct dso app, vdso;
1395 size_t aux[AUX_CNT32], *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__libc.auxv = auxv = (void *)(argv+i+1);
1409 decode_vec(auxv, aux, AUX_CNT32);
1410 __hwcap = aux[AT_HWCAP16];
1411 libc__libc.page_size = aux[AT_PAGESZ6];
1412 libc__libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID11]!=aux[AT_EUID12]
1413 || aux[AT_GID13]!=aux[AT_EGID14] || aux[AT_SECURE23]);
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__libc.tls_size = sizeof builtin_tls;
1419 libc__libc.tls_align = tls_align;
1420 if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
1421 a_crasha_crash();
1422 }
1423
1424 /* Only trust user/env if kernel says we're not suid/sgid */
1425 if (!libc__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_PHDR3] != (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_PHDR3];
1438 app.phnum = aux[AT_PHNUM5];
1439 app.phentsize = aux[AT_PHENT4];
1440 for (i=aux[AT_PHNUM5]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT4])) {
1441 if (phdr->p_type == PT_PHDR6)
1442 app.base = (void *)(aux[AT_PHDR3] - phdr->p_vaddr);
1443 else if (phdr->p_type == PT_INTERP3)
1444 interp_off = (size_t)phdr->p_vaddr;
1445 else if (phdr->p_type == PT_TLS7) {
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_FDPIC0) app.loadmap = app_loadmap;
1453 if (app.tls.size) app.tls.image = laddr(&app, tls_image)(void *)((&app)->base + (tls_image));
1454 if (interp_off) ldso.name = laddr(&app, interp_off)(void *)((&app)->base + (interp_off));
1455 if ((aux[0] & (1UL<<AT_EXECFN31))
1456 && strncmp((char *)aux[AT_EXECFN31], "/proc/", 6))
1457 app.name = (char *)aux[AT_EXECFN31];
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")dl_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"x86_64" ")\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_RDONLY00);
1497 if (fd < 0) {
1498 dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno(*__errno_location())));
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_ENTRY9] = (size_t)laddr(&app, ehdr->e_entry)(void *)((&app)->base + (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_INTERP3)
1517 ldso.name = laddr(&app, app.phdr[i].p_vaddr)(void *)((&app)->base + (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__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)(-(-(tls_align)&-(app.tls.align)));
1536 }
1537 app.global = 1;
1538 decode_dyn(&app);
1539 if (DL_FDPIC0) {
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_EHDR33) && 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_DYNAMIC2)
1560 vdso.dynv = (void *)(vdso_base + phdr->p_offset);
1561 if (phdr->p_type == PT_LOAD1)
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_INDIRECT0 && app.dynv[i]==DT_DEBUG21)
1588 app.dynv[i+1] = (size_t)&debug;
1589 if (DT_DEBUG_INDIRECT0 && app.dynv[i]==DT_DEBUG_INDIRECT0) {
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__libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN__builtin_offsetof(struct builtin_tls, pt)) {
1602 void *initial_tls = calloc(libc__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__libc.tls_size);
1606 _exit(127);
1607 }
1608 if (__init_tp(__copy_tls(initial_tls)) < 0) {
1609 a_crasha_crash();
1610 }
1611 } else {
1612 size_t tmp_tls_size = libc__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__libc.tls_size = sizeof builtin_tls;
1618 if (__copy_tls((void*)builtin_tls) != self) a_crasha_crash();
1619 libc__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(*__errno_location()) = 0;
1639
1640 CRTJMP((void *)aux[AT_ENTRY], argv-1)__asm__ __volatile__( "mov %1,%%rsp ; jmp *%0" : : "r"((void *
)aux[9]), "r"(argv-1) : "memory" )
;
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_DISABLE1, &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_NOLOAD4;
1666
1667 rtld_fail = &jb;
1668 if (setjmpsetjmp(*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__libc.tls_head = 0;
1688 tls_tail = orig_tls_tail;
1689 if (tls_tail) tls_tail->next = 0;
1690 tls_cnt = orig_tls_cnt;
1691 tls_offset = orig_tls_offset;
1692 tls_align = orig_tls_align;
1693 tail = orig_tail;
1694 tail->next = 0;
1695 p = 0;
1696 goto end;
1697 } else p = load_library(file, head);
1698
1699 if (!p) {
1700 error(noload ?
1701 "Library %s is not already loaded" :
1702 "Error loading shared library %s: %m",
1703 file);
1704 goto end;
1705 }
1706
1707 /* First load handling */
1708 if (!p->deps) {
1709 load_deps(p);
1710 if (p->deps) for (i=0; p->deps[i]; i++)
1711 if (!p->deps[i]->global)
1712 p->deps[i]->global = -1;
1713 if (!p->global) p->global = -1;
1714 reloc_all(p);
1715 if (p->deps) for (i=0; p->deps[i]; i++)
1716 if (p->deps[i]->global < 0)
1717 p->deps[i]->global = 0;
1718 if (p->global < 0) p->global = 0;
1719 }
1720
1721 if (mode & RTLD_GLOBAL256) {
1722 if (p->deps) for (i=0; p->deps[i]; i++)
1723 p->deps[i]->global = 1;
1724 p->global = 1;
1725 }
1726
1727 update_tls_size();
1728 _dl_debug_state();
1729 orig_tail = tail;
1730end:
1731 __release_ptc();
1732 if (p) gencnt++;
1733 pthread_rwlock_unlock(&lock);
1734 if (p) do_init_fini(orig_tail);
1735 pthread_setcancelstate(cs, 0);
1736 return p;
1737}
1738
1739__attribute__((__visibility__("hidden")))
1740int __dl_invalid_handle(void *h)
1741{
1742 struct dso *p;
1743 for (p=head; p; p=p->next) if (h==p) return 0;
1744 error("Invalid library handle %p", (void *)h);
1745 return 1;
1746}
1747
1748static void *addr2dso(size_t a)
1749{
1750 struct dso *p;
1751 size_t i;
1752 if (DL_FDPIC0) for (p=head; p; p=p->next) {
1753 i = count_syms(p);
1754 if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))
1755 return p;
1756 }
1757 for (p=head; p; p=p->next) {
1758 if (DL_FDPIC0 && p->loadmap) {
1759 for (i=0; i<p->loadmap->nsegs; i++) {
1760 if (a-p->loadmap->segs[i].p_vaddr
1761 < p->loadmap->segs[i].p_memsz)
1762 return p;
1763 }
1764 } else {
1765 if (a-(size_t)p->map < p->map_len)
1766 return p;
1767 }
1768 }
1769 return 0;
1770}
1771
1772void *__tls_get_addr(tls_mod_off_tsize_t *);
1773
1774static void *do_dlsym(struct dso *p, const char *s, void *ra)
1775{
1776 size_t i;
1777 uint32_t h = 0, gh = 0, *ght;
1778 Sym *sym;
1779 if (p == head || p == RTLD_DEFAULT((void *)0) || p == RTLD_NEXT((void *)-1)) {
1780 if (p == RTLD_DEFAULT((void *)0)) {
1781 p = head;
1782 } else if (p == RTLD_NEXT((void *)-1)) {
1783 p = addr2dso((size_t)ra);
1784 if (!p) p=head;
1785 p = p->next;
1786 }
1787 struct symdef def = find_sym(p, s, 0);
1788 if (!def.sym) goto failed;
1789 if ((def.sym->st_info&0xf) == STT_TLS6)
1790 return __tls_get_addr((tls_mod_off_tsize_t []){def.dso->tls_id, def.sym->st_value});
1791 if (DL_FDPIC0 && (def.sym->st_info&0xf) == STT_FUNC2)
1792 return def.dso->funcdescs + (def.sym - def.dso->syms);
1793 return laddr(def.dso, def.sym->st_value)(void *)((def.dso)->base + (def.sym->st_value));
1794 }
1795 if (__dl_invalid_handle(p))
1796 return 0;
1797 if ((ght = p->ghashtab)) {
1798 gh = gnu_hash(s);
1799 sym = gnu_lookup(gh, ght, p, s);
1800 } else {
1801 h = sysv_hash(s);
1802 sym = sysv_lookup(s, h, p);
1803 }
1804 if (sym && (sym->st_info&0xf) == STT_TLS6)
1805 return __tls_get_addr((tls_mod_off_tsize_t []){p->tls_id, sym->st_value});
1806 if (DL_FDPIC0 && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC2)
1807 return p->funcdescs + (sym - p->syms);
1808 if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES(1<<0 | 1<<1 | 1<<2 | 1<<5 | 1<<
6)
))
1809 return laddr(p, sym->st_value)(void *)((p)->base + (sym->st_value));
1810 if (p->deps) for (i=0; p->deps[i]; i++) {
1811 if ((ght = p->deps[i]->ghashtab)) {
1812 if (!gh) gh = gnu_hash(s);
1813 sym = gnu_lookup(gh, ght, p->deps[i], s);
1814 } else {
1815 if (!h) h = sysv_hash(s);
1816 sym = sysv_lookup(s, h, p->deps[i]);
1817 }
1818 if (sym && (sym->st_info&0xf) == STT_TLS6)
1819 return __tls_get_addr((tls_mod_off_tsize_t []){p->deps[i]->tls_id, sym->st_value});
1820 if (DL_FDPIC0 && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC2)
1821 return p->deps[i]->funcdescs + (sym - p->deps[i]->syms);
1822 if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES(1<<0 | 1<<1 | 1<<2 | 1<<5 | 1<<
6)
))
1823 return laddr(p->deps[i], sym->st_value)(void *)((p->deps[i])->base + (sym->st_value));
1824 }
1825failed:
1826 error("Symbol not found: %s", s);
1827 return 0;
1828}
1829
1830int dladdr(const void *addr, Dl_info *info)
1831{
1832 struct dso *p;
1833 Sym *sym, *bestsym;
1834 uint32_t nsym;
1835 char *strings;
1836 void *best = 0;
1837
1838 pthread_rwlock_rdlock(&lock);
1839 p = addr2dso((size_t)addr);
1840 pthread_rwlock_unlock(&lock);
1841
1842 if (!p) return 0;
1843
1844 sym = p->syms;
1845 strings = p->strings;
1846 nsym = count_syms(p);
1847
1848 if (DL_FDPIC0) {
1849 size_t idx = ((size_t)addr-(size_t)p->funcdescs)
1850 / sizeof(*p->funcdescs);
1851 if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC2) {
1852 best = p->funcdescs + idx;
1853 bestsym = sym + idx;
1854 }
1855 }
1856
1857 if (!best) for (; nsym; nsym--, sym++) {
1858 if (sym->st_value
1859 && (1<<(sym->st_info&0xf) & OK_TYPES(1<<0 | 1<<1 | 1<<2 | 1<<5 | 1<<
6)
)
1860 && (1<<(sym->st_info>>4) & OK_BINDS(1<<1 | 1<<2 | 1<<10))) {
1861 void *symaddr = laddr(p, sym->st_value)(void *)((p)->base + (sym->st_value));
1862 if (symaddr > addr || symaddr < best)
1863 continue;
1864 best = symaddr;
1865 bestsym = sym;
1866 if (addr == symaddr)
1867 break;
1868 }
1869 }
1870
1871 if (!best) return 0;
1872
1873 if (DL_FDPIC0 && (bestsym->st_info&0xf) == STT_FUNC2)
1874 best = p->funcdescs + (bestsym - p->syms);
1875
1876 info->dli_fname = p->name;
1877 info->dli_fbase = p->base;
1878 info->dli_sname = strings + bestsym->st_name;
1879 info->dli_saddr = best;
1880
1881 return 1;
1882}
1883
1884__attribute__((__visibility__("hidden")))
1885void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
1886{
1887 void *res;
1888 pthread_rwlock_rdlock(&lock);
1889 res = do_dlsym(p, s, ra);
1890 pthread_rwlock_unlock(&lock);
1891 return res;
1892}
1893
1894int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
1895{
1896 struct dso *current;
1897 struct dl_phdr_info info;
1898 int ret = 0;
1899 for(current = head; current;) {
1900 info.dlpi_addr = (uintptr_t)current->base;
1901 info.dlpi_name = current->name;
1902 info.dlpi_phdr = current->phdr;
1903 info.dlpi_phnum = current->phnum;
1904 info.dlpi_adds = gencnt;
1905 info.dlpi_subs = 0;
1906 info.dlpi_tls_modid = current->tls_id;
1907 info.dlpi_tls_data = current->tls.image;
1908
1909 ret = (callback)(&info, sizeof (info), data);
1910
1911 if (ret != 0) break;
1912
1913 pthread_rwlock_rdlock(&lock);
1914 current = current->next;
1915 pthread_rwlock_unlock(&lock);
1916 }
1917 return ret;
1918}
1919
1920__attribute__((__visibility__("hidden")))
1921void __dl_vseterr(const char *, va_list);
1922
1923static void error(const char *fmt, ...)
1924{
1925 va_list ap;
1926 va_start(ap, fmt)__builtin_va_start(ap,fmt);
1927 if (!runtime) {
1928 vdprintf(2, fmt, ap);
1929 dprintf(2, "\n");
1930 ldso_fail = 1;
1931 va_end(ap)__builtin_va_end(ap);
1932 return;
1933 }
1934 __dl_vseterr(fmt, ap);
1935 va_end(ap)__builtin_va_end(ap);
1936}