Bug Summary

File:ldso/dynlink.c
Location:line 644, column 12
Description: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 uint32_t *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 uint32_t *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])&255) == 23) || (((rel[1])&255) == REL_SYM_OR_REL
&& !((rel[1])>>8)) )
) continue;
327 type = R_TYPE(rel[1])((rel[1])&255);
328 if (type == REL_NONE) continue;
329 sym_index = R_SYM(rel[1])((rel[1])>>8);
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_COPY20 ? 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_PLT22);
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_GOT21 || type==REL_PLT22|| type==REL_COPY20) {
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_SYMBOLIC2:
375 case REL_GOT21:
376 case REL_PLT22:
377 *reloc_addr = sym_val + addend;
378 break;
379 case REL_RELATIVE23:
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_COPY20:
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_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_DTPMOD17:
403 *reloc_addr = def.dso->tls_id;
404 break;
405 case REL_DTPOFF18:
406 *reloc_addr = tls_val + addend - DTP_OFFSET0;
407 break;
408#ifdef TLS_ABOVE_TP
409 case REL_TPOFF19:
410 *reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K8 + addend;
411 break;
412#else
413 case REL_TPOFF19:
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_K8 + 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(0xffffffffu), 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))
558 goto noexec;
559 phsize = eh->e_phentsize * eh->e_phnum;
560 if (phsize > sizeof buf - sizeof *eh) {
4
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) {
5
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)) {
6
Loop condition is true. Entering loop body
13
Loop condition is true. Entering loop body
20
Loop condition is true. Entering loop body
24
Loop condition is false. Execution continues on line 600
576 if (ph->p_type == PT_DYNAMIC2) {
7
Taking false branch
14
Taking false branch
21
Taking true branch
577 dyn = ph->p_vaddr;
578 } else if (ph->p_type == PT_TLS7) {
8
Taking false branch
15
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) {
9
Taking false branch
16
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;
10
Taking false branch
17
Taking false branch
22
Taking true branch
23
Execution continues on line 575
588 nsegs++;
589 if (ph->p_vaddr < addr_min) {
11
Taking false branch
18
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) {
12
Taking false branch
19
Taking false branch
597 addr_max = ph->p_vaddr+ph->p_memsz;
598 }
599 }
600 if (!dyn) goto noexec;
25
Assuming 'dyn' is not equal to 0
26
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;
27
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_MAX0x7fffffffL/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_mmap2192
854 p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0)__syscall6(192,((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(SYS_mmap,((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 *rp, reserved[] =
909 "c\0pthread\0rt\0m\0dl\0util\0xnet\0";
910 char *z = strchr(name, '.');
911 if (z) {
912 size_t l = z-name;
913 for (rp=reserved; *rp && strncmp(name+3, rp, l-3); rp+=strlen(rp)+1);
914 if (*rp) {
915 if (ldd_mode) {
916 /* Track which names have been resolved
917 * and only report each one once. */
918 static unsigned reported;
919 unsigned mask = 1U<<(rp-reserved);
920 if (!(reported & mask)) {
921 reported |= mask;
922 dprintf(1, "\t%s => %s (%p)\n",
923 name, ldso.name,
924 ldso.base);
925 }
926 }
927 is_self = 1;
928 }
929 }
930 }
931 if (!strcmp(name, ldso.name)dl_strcmp(name,ldso.name)) is_self = 1;
932 if (is_self) {
933 if (!ldso.prev) {
934 tail->next = &ldso;
935 ldso.prev = tail;
936 tail = ldso.next ? ldso.next : &ldso;
937 }
938 return &ldso;
939 }
940 if (strchr(name, '/')) {
941 pathname = name;
942 fd = open(name, O_RDONLY00|O_CLOEXEC02000000);
943 } else {
944 /* Search for the name to see if it's already loaded */
945 for (p=head->next; p; p=p->next) {
946 if (p->shortname && !strcmp(p->shortname, name)dl_strcmp(p->shortname,name)) {
947 p->refcnt++;
948 return p;
949 }
950 }
951 if (strlen(name) > NAME_MAX255) return 0;
952 fd = -1;
953 if (env_path) fd = path_open(name, env_path, buf, sizeof buf);
954 for (p=needed_by; fd == -1 && p; p=p->needed_by) {
955 if (fixup_rpath(p, buf, sizeof buf) < 0)
956 fd = -2; /* Inhibit further search. */
957 if (p->rpath)
958 fd = path_open(name, p->rpath, buf, sizeof buf);
959 }
960 if (fd == -1) {
961 if (!sys_path) {
962 char *prefix = 0;
963 size_t prefix_len;
964 if (ldso.name[0]=='/') {
965 char *s, *t, *z;
966 for (s=t=z=ldso.name; *s; s++)
967 if (*s=='/') z=t, t=s;
968 prefix_len = z-ldso.name;
969 if (prefix_len < PATH_MAX4096)
970 prefix = ldso.name;
971 }
972 if (!prefix) {
973 prefix = "";
974 prefix_len = 0;
975 }
976 char etc_ldso_path[prefix_len + 1
977 + sizeof "/etc/ld-musl-" LDSO_ARCH"arm" "" "" ".path"];
978 snprintf(etc_ldso_path, sizeof etc_ldso_path,
979 "%.*s/etc/ld-musl-" LDSO_ARCH"arm" "" "" ".path",
980 (int)prefix_len, prefix);
981 FILE *f = fopen(etc_ldso_path, "rbe");
982 if (f) {
983 if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) {
984 free(sys_path);
985 sys_path = "";
986 }
987 fclose(f);
988 } else if (errno(*__errno_location()) != ENOENT2) {
989 sys_path = "";
990 }
991 }
992 if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
993 fd = path_open(name, sys_path, buf, sizeof buf);
994 }
995 pathname = buf;
996 }
997 if (fd < 0) return 0;
998 if (fstat(fd, &st) < 0) {
999 close(fd);
1000 return 0;
1001 }
1002 for (p=head->next; p; p=p->next) {
1003 if (p->dev == st.st_dev && p->ino == st.st_ino) {
1004 /* If this library was previously loaded with a
1005 * pathname but a search found the same inode,
1006 * setup its shortname so it can be found by name. */
1007 if (!p->shortname && pathname != name)
1008 p->shortname = strrchr(p->name, '/')+1;
1009 close(fd);
1010 p->refcnt++;
1011 return p;
1012 }
1013 }
1014 map = noload ? 0 : map_library(fd, &temp_dso);
1015 close(fd);
1016 if (!map) return 0;
1017
1018 /* Allocate storage for the new DSO. When there is TLS, this
1019 * storage must include a reservation for all pre-existing
1020 * threads to obtain copies of both the new TLS, and an
1021 * extended DTV capable of storing an additional slot for
1022 * the newly-loaded DSO. */
1023 alloc_size = sizeof *p + strlen(pathname) + 1;
1024 if (runtime && temp_dso.tls.image) {
1025 size_t per_th = temp_dso.tls.size + temp_dso.tls.align
1026 + sizeof(void *) * (tls_cnt+3);
1027 n_th = libc__libc.threads_minus_1 + 1;
1028 if (n_th > SSIZE_MAX0x7fffffffL / per_th) alloc_size = SIZE_MAX(0xffffffffu);
1029 else alloc_size += n_th * per_th;
1030 }
1031 p = calloc(1, alloc_size);
1032 if (!p) {
1033 unmap_library(&temp_dso);
1034 return 0;
1035 }
1036 memcpy(p, &temp_dso, sizeof temp_dso);
1037 decode_dyn(p);
1038 p->dev = st.st_dev;
1039 p->ino = st.st_ino;
1040 p->refcnt = 1;
1041 p->needed_by = needed_by;
1042 p->name = p->buf;
1043 strcpy(p->name, pathname);
1044 /* Add a shortname only if name arg was not an explicit pathname. */
1045 if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
1046 if (p->tls.image) {
1047 p->tls_id = ++tls_cnt;
1048 tls_align = MAXP2(tls_align, p->tls.align)(-(-(tls_align)&-(p->tls.align)));
1049#ifdef TLS_ABOVE_TP
1050 p->tls.offset = tls_offset + ( (tls_align-1) &
1051 -(tls_offset + (uintptr_t)p->tls.image) );
1052 tls_offset += p->tls.size;
1053#else
1054 tls_offset += p->tls.size + p->tls.align - 1;
1055 tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
1056 & (p->tls.align-1);
1057 p->tls.offset = tls_offset;
1058#endif
1059 p->new_dtv = (void *)(-sizeof(size_t) &
1060 (uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
1061 p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
1062 if (tls_tail) tls_tail->next = &p->tls;
1063 else libc__libc.tls_head = &p->tls;
1064 tls_tail = &p->tls;
1065 }
1066
1067 tail->next = p;
1068 p->prev = tail;
1069 tail = p;
1070
1071 if (DL_FDPIC0) makefuncdescs(p);
1072
1073 if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);
1074
1075 return p;
1076}
1077
1078static void load_deps(struct dso *p)
1079{
1080 size_t i, ndeps=0;
1081 struct dso ***deps = &p->deps, **tmp, *dep;
1082 for (; p; p=p->next) {
1083 for (i=0; p->dynv[i]; i+=2) {
1084 if (p->dynv[i] != DT_NEEDED1) continue;
1085 dep = load_library(p->strings + p->dynv[i+1], p);
1086 if (!dep) {
1087 error("Error loading shared library %s: %m (needed by %s)",
1088 p->strings + p->dynv[i+1], p->name);
1089 if (runtime) longjmp(*rtld_fail, 1);
1090 continue;
1091 }
1092 if (runtime) {
1093 tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2));
1094 if (!tmp) longjmp(*rtld_fail, 1);
1095 tmp[ndeps++] = dep;
1096 tmp[ndeps] = 0;
1097 *deps = tmp;
1098 }
1099 }
1100 }
1101}
1102
1103static void load_preload(char *s)
1104{
1105 int tmp;
1106 char *z;
1107 for (z=s; *z; s=z) {
1108 for ( ; *s && (isspace(*s)__isspace(*s) || *s==':'); s++);
1109 for (z=s; *z && !isspace(*z)__isspace(*z) && *z!=':'; z++);
1110 tmp = *z;
1111 *z = 0;
1112 load_library(s, 0);
1113 *z = tmp;
1114 }
1115}
1116
1117static void make_global(struct dso *p)
1118{
1119 for (; p; p=p->next) p->global = 1;
1120}
1121
1122static void do_mips_relocs(struct dso *p, size_t *got)
1123{
1124 size_t i, j, rel[2];
1125 unsigned char *base = p->base;
1126 i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO0x7000000a);
1127 if (p==&ldso) {
1128 got += i;
1129 } else {
1130 while (i--) *got++ += (size_t)base;
1131 }
1132 j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM0x70000013);
1133 i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO0x70000011);
1134 Sym *sym = p->syms + j;
1135 rel[0] = (unsigned char *)got - base;
1136 for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {
1137 rel[1] = sym-p->syms << 8 | R_MIPS_JUMP_SLOT127;
1138 do_relocs(p, rel, sizeof rel, 2);
1139 }
1140}
1141
1142static void reloc_all(struct dso *p)
1143{
1144 size_t dyn[DYN_CNT32];
1145 for (; p; p=p->next) {
1146 if (p->relocated) continue;
1147 decode_vec(p->dynv, dyn, DYN_CNT32);
1148 if (NEED_MIPS_GOT_RELOCS0)
1149 do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT])(void *)((p)->base + (dyn[3])));
1150 do_relocs(p, laddr(p, dyn[DT_JMPREL])(void *)((p)->base + (dyn[23])), dyn[DT_PLTRELSZ2],
1151 2+(dyn[DT_PLTREL20]==DT_RELA7));
1152 do_relocs(p, laddr(p, dyn[DT_REL])(void *)((p)->base + (dyn[17])), dyn[DT_RELSZ18], 2);
1153 do_relocs(p, laddr(p, dyn[DT_RELA])(void *)((p)->base + (dyn[7])), dyn[DT_RELASZ8], 3);
1154
1155 if (head != &ldso && p->relro_start != p->relro_end &&
1156 mprotect(laddr(p, p->relro_start)(void *)((p)->base + (p->relro_start)), p->relro_end-p->relro_start, PROT_READ1)
1157 && errno(*__errno_location()) != ENOSYS38) {
1158 error("Error relocating %s: RELRO protection failed: %m",
1159 p->name);
1160 if (runtime) longjmp(*rtld_fail, 1);
1161 }
1162
1163 p->relocated = 1;
1164 }
1165}
1166
1167static void kernel_mapped_dso(struct dso *p)
1168{
1169 size_t min_addr = -1, max_addr = 0, cnt;
1170 Phdr *ph = p->phdr;
1171 for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {
1172 if (ph->p_type == PT_DYNAMIC2) {
1173 p->dynv = laddr(p, ph->p_vaddr)(void *)((p)->base + (ph->p_vaddr));
1174 } else if (ph->p_type == PT_GNU_RELRO0x6474e552) {
1175 p->relro_start = ph->p_vaddr & -PAGE_SIZE4096;
1176 p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE4096;
1177 }
1178 if (ph->p_type != PT_LOAD1) continue;
1179 if (ph->p_vaddr < min_addr)
1180 min_addr = ph->p_vaddr;
1181 if (ph->p_vaddr+ph->p_memsz > max_addr)
1182 max_addr = ph->p_vaddr+ph->p_memsz;
1183 }
1184 min_addr &= -PAGE_SIZE4096;
1185 max_addr = (max_addr + PAGE_SIZE4096-1) & -PAGE_SIZE4096;
1186 p->map = p->base + min_addr;
1187 p->map_len = max_addr - min_addr;
1188 p->kernel_mapped = 1;
1189}
1190
1191void __libc_exit_fini()
1192{
1193 struct dso *p;
1194 size_t dyn[DYN_CNT32];
1195 for (p=fini_head; p; p=p->fini_next) {
1196 if (!p->constructed) continue;
1197 decode_vec(p->dynv, dyn, DYN_CNT32);
1198 if (dyn[0] & (1<<DT_FINI_ARRAY26)) {
1199 size_t n = dyn[DT_FINI_ARRAYSZ28]/sizeof(size_t);
1200 size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])(void *)((p)->base + (dyn[26]))+n;
1201 while (n--) ((void (*)(void))*--fn)();
1202 }
1203#ifndef NO_LEGACY_INITFINI
1204 if ((dyn[0] & (1<<DT_FINI13)) && dyn[DT_FINI13])
1205 fpaddr(p, dyn[DT_FINI])((void (*)())(void *)((p)->base + (dyn[13])))();
1206#endif
1207 }
1208}
1209
1210static void do_init_fini(struct dso *p)
1211{
1212 size_t dyn[DYN_CNT32];
1213 int need_locking = libc__libc.threads_minus_1;
1214 /* Allow recursive calls that arise when a library calls
1215 * dlopen from one of its constructors, but block any
1216 * other threads until all ctors have finished. */
1217 if (need_locking) pthread_mutex_lock(&init_fini_lock);
1218 for (; p; p=p->prev) {
1219 if (p->constructed) continue;
1220 p->constructed = 1;
1221 decode_vec(p->dynv, dyn, DYN_CNT32);
1222 if (dyn[0] & ((1<<DT_FINI13) | (1<<DT_FINI_ARRAY26))) {
1223 p->fini_next = fini_head;
1224 fini_head = p;
1225 }
1226#ifndef NO_LEGACY_INITFINI
1227 if ((dyn[0] & (1<<DT_INIT12)) && dyn[DT_INIT12])
1228 fpaddr(p, dyn[DT_INIT])((void (*)())(void *)((p)->base + (dyn[12])))();
1229#endif
1230 if (dyn[0] & (1<<DT_INIT_ARRAY25)) {
1231 size_t n = dyn[DT_INIT_ARRAYSZ27]/sizeof(size_t);
1232 size_t *fn = laddr(p, dyn[DT_INIT_ARRAY])(void *)((p)->base + (dyn[25]));
1233 while (n--) ((void (*)(void))*fn++)();
1234 }
1235 if (!need_locking && libc__libc.threads_minus_1) {
1236 need_locking = 1;
1237 pthread_mutex_lock(&init_fini_lock);
1238 }
1239 }
1240 if (need_locking) pthread_mutex_unlock(&init_fini_lock);
1241}
1242
1243void __libc_start_init(void)
1244{
1245 do_init_fini(tail);
1246}
1247
1248static void dl_debug_state(void)
1249{
1250}
1251
1252weak_alias(dl_debug_state, _dl_debug_state)extern __typeof(dl_debug_state) _dl_debug_state __attribute__
((weak, alias("dl_debug_state")))
;
1253
1254void __init_tls(size_t *auxv)
1255{
1256}
1257
1258__attribute__((__visibility__("hidden")))
1259void *__tls_get_new(size_t *v)
1260{
1261 pthread_t self = __pthread_self();
1262
1263 /* Block signals to make accessing new TLS async-signal-safe */
1264 sigset_t set;
1265 __block_all_sigs(&set);
1266 if (v[0]<=(size_t)self->dtv[0]) {
1267 __restore_sigs(&set);
1268 return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET0;
1269 }
1270
1271 /* This is safe without any locks held because, if the caller
1272 * is able to request the Nth entry of the DTV, the DSO list
1273 * must be valid at least that far out and it was synchronized
1274 * at program startup or by an already-completed call to dlopen. */
1275 struct dso *p;
1276 for (p=head; p->tls_id != v[0]; p=p->next);
1277
1278 /* Get new DTV space from new DSO if needed */
1279 if (v[0] > (size_t)self->dtv[0]) {
1280 void **newdtv = p->new_dtv +
1281 (v[0]+1)*a_fetch_adda_fetch_add(&p->new_dtv_idx,1);
1282 memcpy(newdtv, self->dtv,
1283 ((size_t)self->dtv[0]+1) * sizeof(void *));
1284 newdtv[0] = (void *)v[0];
1285 self->dtv = self->dtv_copy = newdtv;
1286 }
1287
1288 /* Get new TLS memory from all new DSOs up to the requested one */
1289 unsigned char *mem;
1290 for (p=head; ; p=p->next) {
1291 if (!p->tls_id || self->dtv[p->tls_id]) continue;
1292 mem = p->new_tls + (p->tls.size + p->tls.align)
1293 * a_fetch_adda_fetch_add(&p->new_tls_idx,1);
1294 mem += ((uintptr_t)p->tls.image - (uintptr_t)mem)
1295 & (p->tls.align-1);
1296 self->dtv[p->tls_id] = mem;
1297 memcpy(mem, p->tls.image, p->tls.len);
1298 if (p->tls_id == v[0]) break;
1299 }
1300 __restore_sigs(&set);
1301 return mem + v[1] + DTP_OFFSET0;
1302}
1303
1304static void update_tls_size()
1305{
1306 libc__libc.tls_cnt = tls_cnt;
1307 libc__libc.tls_align = tls_align;
1308 libc__libc.tls_size = ALIGN((((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1309 (1+tls_cnt) * sizeof(void *) +(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1310 tls_offset +(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1311 sizeof(struct pthread) +(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1312 tls_align * 2,(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
1313 tls_align)(((1+tls_cnt) * sizeof(void *) + tls_offset + sizeof(struct __pthread
) + tls_align * 2)+(tls_align)-1 & -(tls_align))
;
1314}
1315
1316/* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the
1317 * following stage 2 and stage 3 functions via primitive symbolic lookup
1318 * since it does not have access to their addresses to begin with. */
1319
1320/* Stage 2 of the dynamic linker is called after relative relocations
1321 * have been processed. It can make function calls to static functions
1322 * and access string literals and static data, but cannot use extern
1323 * symbols. Its job is to perform symbolic relocations on the dynamic
1324 * linker itself, but some of the relocations performed may need to be
1325 * replaced later due to copy relocations in the main program. */
1326
1327__attribute__((__visibility__("hidden")))
1328void __dls2(unsigned char *base, size_t *sp)
1329{
1330 if (DL_FDPIC0) {
1331 void *p1 = (void *)sp[-2];
1332 void *p2 = (void *)sp[-1];
1333 if (!p1) {
1334 size_t *auxv, aux[AUX_CNT32];
1335 for (auxv=sp+1+*sp+1; *auxv; auxv++); auxv++;
1336 decode_vec(auxv, aux, AUX_CNT32);
1337 if (aux[AT_BASE7]) ldso.base = (void *)aux[AT_BASE7];
1338 else ldso.base = (void *)(aux[AT_PHDR3] & -4096);
1339 }
1340 app_loadmap = p2 ? p1 : 0;
1341 ldso.loadmap = p2 ? p2 : p1;
1342 ldso.base = laddr(&ldso, 0)(void *)((&ldso)->base + (0));
1343 } else {
1344 ldso.base = base;
1345 }
1346 Ehdr *ehdr = (void *)ldso.base;
1347 ldso.name = ldso.shortname = "libc.so";
1348 ldso.global = 1;
1349 ldso.phnum = ehdr->e_phnum;
1350 ldso.phdr = laddr(&ldso, ehdr->e_phoff)(void *)((&ldso)->base + (ehdr->e_phoff));
1351 ldso.phentsize = ehdr->e_phentsize;
1352 kernel_mapped_dso(&ldso);
1353 decode_dyn(&ldso);
1354
1355 if (DL_FDPIC0) makefuncdescs(&ldso);
1356
1357 /* Prepare storage for to save clobbered REL addends so they
1358 * can be reused in stage 3. There should be very few. If
1359 * something goes wrong and there are a huge number, abort
1360 * instead of risking stack overflow. */
1361 size_t dyn[DYN_CNT32];
1362 decode_vec(ldso.dynv, dyn, DYN_CNT32);
1363 size_t *rel = laddr(&ldso, dyn[DT_REL])(void *)((&ldso)->base + (dyn[17]));
1364 size_t rel_size = dyn[DT_RELSZ18];
1365 size_t symbolic_rel_cnt = 0;
1366 apply_addends_to = rel;
1367 for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))
1368 if (!IS_RELATIVE(rel[1], ldso.syms)( (((rel[1])&255) == 23) || (((rel[1])&255) == REL_SYM_OR_REL
&& !((rel[1])>>8)) )
) symbolic_rel_cnt++;
1369 if (symbolic_rel_cnt >= ADDEND_LIMIT4096) a_crasha_crash();
1370 size_t addends[symbolic_rel_cnt+1];
1371 saved_addends = addends;
1372
1373 head = &ldso;
1374 reloc_all(&ldso);
1375
1376 ldso.relocated = 0;
1377
1378 /* Call dynamic linker stage-3, __dls3, looking it up
1379 * symbolically as a barrier against moving the address
1380 * load across the above relocation processing. */
1381 struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
1382 if (DL_FDPIC0) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp);
1383 else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value)(void *)((&ldso)->base + (dls3_def.sym->st_value)))(sp);
1384}
1385
1386/* Stage 3 of the dynamic linker is called with the dynamic linker/libc
1387 * fully functional. Its job is to load (if not already loaded) and
1388 * process dependencies and relocations for the main application and
1389 * transfer control to its entry point. */
1390
1391_Noreturn__attribute__((__noreturn__)) void __dls3(size_t *sp)
1392{
1393 static struct dso app, vdso;
1394 size_t aux[AUX_CNT32], *auxv;
1395 size_t i;
1396 char *env_preload=0;
1397 size_t vdso_base;
1398 int argc = *sp;
1399 char **argv = (void *)(sp+1);
1400 char **argv_orig = argv;
1401 char **envp = argv+argc+1;
1402
1403 /* Find aux vector just past environ[] and use it to initialize
1404 * global data that may be needed before we can make syscalls. */
1405 __environ = envp;
1406 for (i=argc+1; argv[i]; i++);
1407 libc__libc.auxv = auxv = (void *)(argv+i+1);
1408 decode_vec(auxv, aux, AUX_CNT32);
1409 __hwcap = aux[AT_HWCAP16];
1410 libc__libc.page_size = aux[AT_PAGESZ6];
1411 libc__libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID11]!=aux[AT_EUID12]
1412 || aux[AT_GID13]!=aux[AT_EGID14] || aux[AT_SECURE23]);
1413
1414 /* Setup early thread pointer in builtin_tls for ldso/libc itself to
1415 * use during dynamic linking. If possible it will also serve as the
1416 * thread pointer at runtime. */
1417 libc__libc.tls_size = sizeof builtin_tls;
1418 libc__libc.tls_align = tls_align;
1419 if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
1420 a_crasha_crash();
1421 }
1422
1423 /* Only trust user/env if kernel says we're not suid/sgid */
1424 if (!libc__libc.secure) {
1425 env_path = getenv("LD_LIBRARY_PATH");
1426 env_preload = getenv("LD_PRELOAD");
1427 }
1428
1429 /* If the main program was already loaded by the kernel,
1430 * AT_PHDR will point to some location other than the dynamic
1431 * linker's program headers. */
1432 if (aux[AT_PHDR3] != (size_t)ldso.phdr) {
1433 size_t interp_off = 0;
1434 size_t tls_image = 0;
1435 /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
1436 Phdr *phdr = app.phdr = (void *)aux[AT_PHDR3];
1437 app.phnum = aux[AT_PHNUM5];
1438 app.phentsize = aux[AT_PHENT4];
1439 for (i=aux[AT_PHNUM5]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT4])) {
1440 if (phdr->p_type == PT_PHDR6)
1441 app.base = (void *)(aux[AT_PHDR3] - phdr->p_vaddr);
1442 else if (phdr->p_type == PT_INTERP3)
1443 interp_off = (size_t)phdr->p_vaddr;
1444 else if (phdr->p_type == PT_TLS7) {
1445 tls_image = phdr->p_vaddr;
1446 app.tls.len = phdr->p_filesz;
1447 app.tls.size = phdr->p_memsz;
1448 app.tls.align = phdr->p_align;
1449 }
1450 }
1451 if (DL_FDPIC0) app.loadmap = app_loadmap;
1452 if (app.tls.size) app.tls.image = laddr(&app, tls_image)(void *)((&app)->base + (tls_image));
1453 if (interp_off) ldso.name = laddr(&app, interp_off)(void *)((&app)->base + (interp_off));
1454 if ((aux[0] & (1UL<<AT_EXECFN31))
1455 && strncmp((char *)aux[AT_EXECFN31], "/proc/", 6))
1456 app.name = (char *)aux[AT_EXECFN31];
1457 else
1458 app.name = argv[0];
1459 kernel_mapped_dso(&app);
1460 } else {
1461 int fd;
1462 char *ldname = argv[0];
1463 size_t l = strlen(ldname);
1464 if (l >= 3 && !strcmp(ldname+l-3, "ldd")dl_strcmp(ldname+l-3,"ldd")) ldd_mode = 1;
1465 argv++;
1466 while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') {
1467 char *opt = argv[0]+2;
1468 *argv++ = (void *)-1;
1469 if (!*opt) {
1470 break;
1471 } else if (!memcmp(opt, "list", 5)) {
1472 ldd_mode = 1;
1473 } else if (!memcmp(opt, "library-path", 12)) {
1474 if (opt[12]=='=') env_path = opt+13;
1475 else if (opt[12]) *argv = 0;
1476 else if (*argv) env_path = *argv++;
1477 } else if (!memcmp(opt, "preload", 7)) {
1478 if (opt[7]=='=') env_preload = opt+8;
1479 else if (opt[7]) *argv = 0;
1480 else if (*argv) env_preload = *argv++;
1481 } else {
1482 argv[0] = 0;
1483 }
1484 }
1485 argv[-1] = (void *)(argc - (argv-argv_orig));
1486 if (!argv[0]) {
1487 dprintf(2, "musl libc (" LDSO_ARCH"arm" "" "" ")\n"
1488 "Version %s\n"
1489 "Dynamic Program Loader\n"
1490 "Usage: %s [options] [--] pathname%s\n",
1491 __libc_get_version(), ldname,
1492 ldd_mode ? "" : " [args]");
1493 _exit(1);
1494 }
1495 fd = open(argv[0], O_RDONLY00);
1496 if (fd < 0) {
1497 dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno(*__errno_location())));
1498 _exit(1);
1499 }
1500 runtime = 1;
1501 Ehdr *ehdr = (void *)map_library(fd, &app);
1502 if (!ehdr) {
1503 dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
1504 _exit(1);
1505 }
1506 runtime = 0;
1507 close(fd);
1508 ldso.name = ldname;
1509 app.name = argv[0];
1510 aux[AT_ENTRY9] = (size_t)laddr(&app, ehdr->e_entry)(void *)((&app)->base + (ehdr->e_entry));
1511 /* Find the name that would have been used for the dynamic
1512 * linker had ldd not taken its place. */
1513 if (ldd_mode) {
1514 for (i=0; i<app.phnum; i++) {
1515 if (app.phdr[i].p_type == PT_INTERP3)
1516 ldso.name = laddr(&app, app.phdr[i].p_vaddr)(void *)((&app)->base + (app.phdr[i].p_vaddr));
1517 }
1518 dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
1519 }
1520 }
1521 if (app.tls.size) {
1522 libc__libc.tls_head = tls_tail = &app.tls;
1523 app.tls_id = tls_cnt = 1;
1524#ifdef TLS_ABOVE_TP
1525 app.tls.offset = 0;
1526 tls_offset = app.tls.size
1527 + ( -((uintptr_t)app.tls.image + app.tls.size)
1528 & (app.tls.align-1) );
1529#else
1530 tls_offset = app.tls.offset = app.tls.size
1531 + ( -((uintptr_t)app.tls.image + app.tls.size)
1532 & (app.tls.align-1) );
1533#endif
1534 tls_align = MAXP2(tls_align, app.tls.align)(-(-(tls_align)&-(app.tls.align)));
1535 }
1536 app.global = 1;
1537 decode_dyn(&app);
1538 if (DL_FDPIC0) {
1539 makefuncdescs(&app);
1540 if (!app.loadmap) {
1541 app.loadmap = (void *)&app_dummy_loadmap;
1542 app.loadmap->nsegs = 1;
1543 app.loadmap->segs[0].addr = (size_t)app.map;
1544 app.loadmap->segs[0].p_vaddr = (size_t)app.map
1545 - (size_t)app.base;
1546 app.loadmap->segs[0].p_memsz = app.map_len;
1547 }
1548 argv[-3] = (void *)app.loadmap;
1549 }
1550
1551 /* Attach to vdso, if provided by the kernel */
1552 if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR33)) {
1553 Ehdr *ehdr = (void *)vdso_base;
1554 Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
1555 vdso.phnum = ehdr->e_phnum;
1556 vdso.phentsize = ehdr->e_phentsize;
1557 for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
1558 if (phdr->p_type == PT_DYNAMIC2)
1559 vdso.dynv = (void *)(vdso_base + phdr->p_offset);
1560 if (phdr->p_type == PT_LOAD1)
1561 vdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
1562 }
1563 vdso.name = "";
1564 vdso.shortname = "linux-gate.so.1";
1565 vdso.global = 1;
1566 vdso.relocated = 1;
1567 decode_dyn(&vdso);
1568 vdso.prev = &ldso;
1569 ldso.next = &vdso;
1570 }
1571
1572 /* Initial dso chain consists only of the app. */
1573 head = tail = &app;
1574
1575 /* Donate unused parts of app and library mapping to malloc */
1576 reclaim_gaps(&app);
1577 reclaim_gaps(&ldso);
1578
1579 /* Load preload/needed libraries, add their symbols to the global
1580 * namespace, and perform all remaining relocations. */
1581 if (env_preload) load_preload(env_preload);
1582 load_deps(&app);
1583 make_global(&app);
1584
1585 for (i=0; app.dynv[i]; i+=2) {
1586 if (!DT_DEBUG_INDIRECT0 && app.dynv[i]==DT_DEBUG21)
1587 app.dynv[i+1] = (size_t)&debug;
1588 if (DT_DEBUG_INDIRECT0 && app.dynv[i]==DT_DEBUG_INDIRECT0) {
1589 size_t *ptr = (size_t *) app.dynv[i+1];
1590 *ptr = (size_t)&debug;
1591 }
1592 }
1593
1594 /* The main program must be relocated LAST since it may contin
1595 * copy relocations which depend on libraries' relocations. */
1596 reloc_all(app.next);
1597 reloc_all(&app);
1598
1599 update_tls_size();
1600 if (libc__libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN__builtin_offsetof(struct builtin_tls, pt)) {
1601 void *initial_tls = calloc(libc__libc.tls_size, 1);
1602 if (!initial_tls) {
1603 dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
1604 argv[0], libc__libc.tls_size);
1605 _exit(127);
1606 }
1607 if (__init_tp(__copy_tls(initial_tls)) < 0) {
1608 a_crasha_crash();
1609 }
1610 } else {
1611 size_t tmp_tls_size = libc__libc.tls_size;
1612 pthread_t self = __pthread_self();
1613 /* Temporarily set the tls size to the full size of
1614 * builtin_tls so that __copy_tls will use the same layout
1615 * as it did for before. Then check, just to be safe. */
1616 libc__libc.tls_size = sizeof builtin_tls;
1617 if (__copy_tls((void*)builtin_tls) != self) a_crasha_crash();
1618 libc__libc.tls_size = tmp_tls_size;
1619 }
1620 static_tls_cnt = tls_cnt;
1621
1622 if (ldso_fail) _exit(127);
1623 if (ldd_mode) _exit(0);
1624
1625 /* Switch to runtime mode: any further failures in the dynamic
1626 * linker are a reportable failure rather than a fatal startup
1627 * error. */
1628 runtime = 1;
1629
1630 debug.ver = 1;
1631 debug.bp = dl_debug_state;
1632 debug.head = head;
1633 debug.base = ldso.base;
1634 debug.state = 0;
1635 _dl_debug_state();
1636
1637 errno(*__errno_location()) = 0;
1638
1639 CRTJMP((void *)aux[AT_ENTRY], argv-1)__asm__ __volatile__( "mov sp,%1 ; bx %0" : : "r"((void *)aux
[9]), "r"(argv-1) : "memory" )
;
1640 for(;;);
1641}
1642
1643void *dlopen(const char *file, int mode)
1644{
1645 struct dso *volatile p, *orig_tail, *next;
1646 struct tls_module *orig_tls_tail;
1647 size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
1648 size_t i;
1649 int cs;
1650 jmp_buf jb;
1651
1652 if (!file) return head;
1653
1654 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE1, &cs);
1655 pthread_rwlock_wrlock(&lock);
1656 __inhibit_ptc();
1657
1658 p = 0;
1659 orig_tls_tail = tls_tail;
1660 orig_tls_cnt = tls_cnt;
1661 orig_tls_offset = tls_offset;
1662 orig_tls_align = tls_align;
1663 orig_tail = tail;
1664 noload = mode & RTLD_NOLOAD4;
1665
1666 rtld_fail = &jb;
1667 if (setjmpsetjmp(*rtld_fail)) {
1668 /* Clean up anything new that was (partially) loaded */
1669 if (p && p->deps) for (i=0; p->deps[i]; i++)
1670 if (p->deps[i]->global < 0)
1671 p->deps[i]->global = 0;
1672 for (p=orig_tail->next; p; p=next) {
1673 next = p->next;
1674 while (p->td_index) {
1675 void *tmp = p->td_index->next;
1676 free(p->td_index);
1677 p->td_index = tmp;
1678 }
1679 free(p->funcdescs);
1680 if (p->rpath != p->rpath_orig)
1681 free(p->rpath);
1682 free(p->deps);
1683 unmap_library(p);
1684 free(p);
1685 }
1686 if (!orig_tls_tail) libc__libc.tls_head = 0;
1687 tls_tail = orig_tls_tail;
1688 tls_cnt = orig_tls_cnt;
1689 tls_offset = orig_tls_offset;
1690 tls_align = orig_tls_align;
1691 tail = orig_tail;
1692 tail->next = 0;
1693 p = 0;
1694 goto end;
1695 } else p = load_library(file, head);
1696
1697 if (!p) {
1698 error(noload ?
1699 "Library %s is not already loaded" :
1700 "Error loading shared library %s: %m",
1701 file);
1702 goto end;
1703 }
1704
1705 /* First load handling */
1706 if (!p->deps) {
1707 load_deps(p);
1708 if (p->deps) for (i=0; p->deps[i]; i++)
1709 if (!p->deps[i]->global)
1710 p->deps[i]->global = -1;
1711 if (!p->global) p->global = -1;
1712 reloc_all(p);
1713 if (p->deps) for (i=0; p->deps[i]; i++)
1714 if (p->deps[i]->global < 0)
1715 p->deps[i]->global = 0;
1716 if (p->global < 0) p->global = 0;
1717 }
1718
1719 if (mode & RTLD_GLOBAL256) {
1720 if (p->deps) for (i=0; p->deps[i]; i++)
1721 p->deps[i]->global = 1;
1722 p->global = 1;
1723 }
1724
1725 update_tls_size();
1726 _dl_debug_state();
1727 orig_tail = tail;
1728end:
1729 __release_ptc();
1730 if (p) gencnt++;
1731 pthread_rwlock_unlock(&lock);
1732 if (p) do_init_fini(orig_tail);
1733 pthread_setcancelstate(cs, 0);
1734 return p;
1735}
1736
1737__attribute__((__visibility__("hidden")))
1738int __dl_invalid_handle(void *h)
1739{
1740 struct dso *p;
1741 for (p=head; p; p=p->next) if (h==p) return 0;
1742 error("Invalid library handle %p", (void *)h);
1743 return 1;
1744}
1745
1746static void *addr2dso(size_t a)
1747{
1748 struct dso *p;
1749 size_t i;
1750 if (DL_FDPIC0) for (p=head; p; p=p->next) {
1751 i = count_syms(p);
1752 if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))
1753 return p;
1754 }
1755 for (p=head; p; p=p->next) {
1756 if (DL_FDPIC0 && p->loadmap) {
1757 for (i=0; i<p->loadmap->nsegs; i++) {
1758 if (a-p->loadmap->segs[i].p_vaddr
1759 < p->loadmap->segs[i].p_memsz)
1760 return p;
1761 }
1762 } else {
1763 if (a-(size_t)p->map < p->map_len)
1764 return p;
1765 }
1766 }
1767 return 0;
1768}
1769
1770void *__tls_get_addr(size_t *);
1771
1772static void *do_dlsym(struct dso *p, const char *s, void *ra)
1773{
1774 size_t i;
1775 uint32_t h = 0, gh = 0, *ght;
1776 Sym *sym;
1777 if (p == head || p == RTLD_DEFAULT((void *)0) || p == RTLD_NEXT((void *)-1)) {
1778 if (p == RTLD_DEFAULT((void *)0)) {
1779 p = head;
1780 } else if (p == RTLD_NEXT((void *)-1)) {
1781 p = addr2dso((size_t)ra);
1782 if (!p) p=head;
1783 p = p->next;
1784 }
1785 struct symdef def = find_sym(p, s, 0);
1786 if (!def.sym) goto failed;
1787 if ((def.sym->st_info&0xf) == STT_TLS6)
1788 return __tls_get_addr((size_t []){def.dso->tls_id, def.sym->st_value});
1789 if (DL_FDPIC0 && (def.sym->st_info&0xf) == STT_FUNC2)
1790 return def.dso->funcdescs + (def.sym - def.dso->syms);
1791 return laddr(def.dso, def.sym->st_value)(void *)((def.dso)->base + (def.sym->st_value));
1792 }
1793 if (__dl_invalid_handle(p))
1794 return 0;
1795 if ((ght = p->ghashtab)) {
1796 gh = gnu_hash(s);
1797 sym = gnu_lookup(gh, ght, p, s);
1798 } else {
1799 h = sysv_hash(s);
1800 sym = sysv_lookup(s, h, p);
1801 }
1802 if (sym && (sym->st_info&0xf) == STT_TLS6)
1803 return __tls_get_addr((size_t []){p->tls_id, sym->st_value});
1804 if (DL_FDPIC0 && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC2)
1805 return p->funcdescs + (sym - p->syms);
1806 if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES(1<<0 | 1<<1 | 1<<2 | 1<<5 | 1<<
6)
))
1807 return laddr(p, sym->st_value)(void *)((p)->base + (sym->st_value));
1808 if (p->deps) for (i=0; p->deps[i]; i++) {
1809 if ((ght = p->deps[i]->ghashtab)) {
1810 if (!gh) gh = gnu_hash(s);
1811 sym = gnu_lookup(gh, ght, p->deps[i], s);
1812 } else {
1813 if (!h) h = sysv_hash(s);
1814 sym = sysv_lookup(s, h, p->deps[i]);
1815 }
1816 if (sym && (sym->st_info&0xf) == STT_TLS6)
1817 return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value});
1818 if (DL_FDPIC0 && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC2)
1819 return p->deps[i]->funcdescs + (sym - p->deps[i]->syms);
1820 if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES(1<<0 | 1<<1 | 1<<2 | 1<<5 | 1<<
6)
))
1821 return laddr(p->deps[i], sym->st_value)(void *)((p->deps[i])->base + (sym->st_value));
1822 }
1823failed:
1824 error("Symbol not found: %s", s);
1825 return 0;
1826}
1827
1828int dladdr(const void *addr, Dl_info *info)
1829{
1830 struct dso *p;
1831 Sym *sym, *bestsym;
1832 uint32_t nsym;
1833 char *strings;
1834 void *best = 0;
1835
1836 pthread_rwlock_rdlock(&lock);
1837 p = addr2dso((size_t)addr);
1838 pthread_rwlock_unlock(&lock);
1839
1840 if (!p) return 0;
1841
1842 sym = p->syms;
1843 strings = p->strings;
1844 nsym = count_syms(p);
1845
1846 if (DL_FDPIC0) {
1847 size_t idx = ((size_t)addr-(size_t)p->funcdescs)
1848 / sizeof(*p->funcdescs);
1849 if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC2) {
1850 best = p->funcdescs + idx;
1851 bestsym = sym + idx;
1852 }
1853 }
1854
1855 if (!best) for (; nsym; nsym--, sym++) {
1856 if (sym->st_value
1857 && (1<<(sym->st_info&0xf) & OK_TYPES(1<<0 | 1<<1 | 1<<2 | 1<<5 | 1<<
6)
)
1858 && (1<<(sym->st_info>>4) & OK_BINDS(1<<1 | 1<<2 | 1<<10))) {
1859 void *symaddr = laddr(p, sym->st_value)(void *)((p)->base + (sym->st_value));
1860 if (symaddr > addr || symaddr < best)
1861 continue;
1862 best = symaddr;
1863 bestsym = sym;
1864 if (addr == symaddr)
1865 break;
1866 }
1867 }
1868
1869 if (!best) return 0;
1870
1871 if (DL_FDPIC0 && (bestsym->st_info&0xf) == STT_FUNC2)
1872 best = p->funcdescs + (bestsym - p->syms);
1873
1874 info->dli_fname = p->name;
1875 info->dli_fbase = p->base;
1876 info->dli_sname = strings + bestsym->st_name;
1877 info->dli_saddr = best;
1878
1879 return 1;
1880}
1881
1882__attribute__((__visibility__("hidden")))
1883void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
1884{
1885 void *res;
1886 pthread_rwlock_rdlock(&lock);
1887 res = do_dlsym(p, s, ra);
1888 pthread_rwlock_unlock(&lock);
1889 return res;
1890}
1891
1892int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
1893{
1894 struct dso *current;
1895 struct dl_phdr_info info;
1896 int ret = 0;
1897 for(current = head; current;) {
1898 info.dlpi_addr = (uintptr_t)current->base;
1899 info.dlpi_name = current->name;
1900 info.dlpi_phdr = current->phdr;
1901 info.dlpi_phnum = current->phnum;
1902 info.dlpi_adds = gencnt;
1903 info.dlpi_subs = 0;
1904 info.dlpi_tls_modid = current->tls_id;
1905 info.dlpi_tls_data = current->tls.image;
1906
1907 ret = (callback)(&info, sizeof (info), data);
1908
1909 if (ret != 0) break;
1910
1911 pthread_rwlock_rdlock(&lock);
1912 current = current->next;
1913 pthread_rwlock_unlock(&lock);
1914 }
1915 return ret;
1916}
1917
1918__attribute__((__visibility__("hidden")))
1919void __dl_vseterr(const char *, va_list);
1920
1921static void error(const char *fmt, ...)
1922{
1923 va_list ap;
1924 va_start(ap, fmt)__builtin_va_start(ap,fmt);
1925 if (!runtime) {
1926 vdprintf(2, fmt, ap);
1927 dprintf(2, "\n");
1928 ldso_fail = 1;
1929 va_end(ap)__builtin_va_end(ap);
1930 return;
1931 }
1932 __dl_vseterr(fmt, ap);
1933 va_end(ap)__builtin_va_end(ap);
1934}