dynlink.c 38.5 KB
Newer Older
1
#define _GNU_SOURCE
R
Rich Felker 已提交
2 3 4 5 6 7 8 9 10 11 12
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <elf.h>
#include <sys/mman.h>
#include <limits.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
R
Rich Felker 已提交
13
#include <link.h>
R
Rich Felker 已提交
14
#include <setjmp.h>
15
#include <pthread.h>
R
Rich Felker 已提交
16
#include <ctype.h>
17
#include <dlfcn.h>
18 19
#include "pthread_impl.h"
#include "libc.h"
R
Rich Felker 已提交
20

R
Rich Felker 已提交
21
static int errflag;
22
static char errbuf[128];
R
Rich Felker 已提交
23

24
#ifdef SHARED
R
Rich Felker 已提交
25

R
Rich Felker 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39
#if ULONG_MAX == 0xffffffff
typedef Elf32_Ehdr Ehdr;
typedef Elf32_Phdr Phdr;
typedef Elf32_Sym Sym;
#define R_TYPE(x) ((x)&255)
#define R_SYM(x) ((x)>>8)
#else
typedef Elf64_Ehdr Ehdr;
typedef Elf64_Phdr Phdr;
typedef Elf64_Sym Sym;
#define R_TYPE(x) ((x)&0xffffffff)
#define R_SYM(x) ((x)>>32)
#endif

R
Rich Felker 已提交
40 41 42
#define MAXP2(a,b) (-(-(a)&-(b)))
#define ALIGN(x,y) ((x)+(y)-1 & -(y))

43 44 45 46 47 48 49 50 51 52 53 54
struct debug {
	int ver;
	void *head;
	void (*bp)(void);
	int state;
	void *base;
};

struct dso {
	unsigned char *base;
	char *name;
	size_t *dynv;
R
Rich Felker 已提交
55
	struct dso *next, *prev;
56

R
Rich Felker 已提交
57 58
	Phdr *phdr;
	int phnum;
R
Rich Felker 已提交
59 60
	int refcnt;
	Sym *syms;
61
	uint32_t *hashtab;
62
	uint32_t *ghashtab;
63
	int16_t *versym;
R
Rich Felker 已提交
64 65 66 67 68
	char *strings;
	unsigned char *map;
	size_t map_len;
	dev_t dev;
	ino_t ino;
69
	signed char global;
70 71
	char relocated;
	char constructed;
72
	char kernel_mapped;
73
	struct dso **deps, *needed_by;
74
	char *rpath_orig, *rpath;
75
	void *tls_image;
76
	size_t tls_len, tls_size, tls_align, tls_id, tls_offset;
77 78 79
	void **new_dtv;
	unsigned char *new_tls;
	int new_dtv_idx, new_tls_idx;
80
	struct dso *fini_next;
81
	char *shortname;
R
Rich Felker 已提交
82
	char buf[];
R
Rich Felker 已提交
83 84
};

85 86 87 88 89
struct symdef {
	Sym *sym;
	struct dso *dso;
};

90 91
#include "reloc.h"

92
void __init_ssp(size_t *);
93
int __init_tp(void *);
94
void __init_libc(char **, char *);
95

96 97
const char *__libc_get_version(void);

98
static struct dso *head, *tail, *ldso, *fini_head;
99
static char *env_path, *sys_path;
R
Rich Felker 已提交
100
static unsigned long long gencnt;
101
static int ssp_used;
R
Rich Felker 已提交
102
static int runtime;
103
static int ldd_mode;
104
static int ldso_fail;
105
static int noload;
106
static jmp_buf *rtld_fail;
107
static pthread_rwlock_t lock;
108
static struct debug debug;
109
static size_t tls_cnt, tls_offset, tls_align = 4*sizeof(size_t);
110
static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
111
static long long builtin_tls[(sizeof(struct pthread) + 64)/sizeof(long long)];
112 113

struct debug *_dl_debug_addr = &debug;
R
Rich Felker 已提交
114

115
#define AUX_CNT 38
R
Rich Felker 已提交
116 117 118 119 120 121 122 123 124 125 126
#define DYN_CNT 34

static void decode_vec(size_t *v, size_t *a, size_t cnt)
{
	memset(a, 0, cnt*sizeof(size_t));
	for (; v[0]; v+=2) if (v[0]<cnt) {
		a[0] |= 1ULL<<v[0];
		a[v[0]] = v[1];
	}
}

127 128 129 130 131 132 133 134 135
static int search_vec(size_t *v, size_t *r, size_t key)
{
	for (; v[0]!=key; v+=2)
		if (!v[0]) return 0;
	*r = v[1];
	return 1;
}

static uint32_t sysv_hash(const char *s0)
R
Rich Felker 已提交
136
{
137
	const unsigned char *s = (void *)s0;
R
Rich Felker 已提交
138 139 140 141 142 143 144 145
	uint_fast32_t h = 0;
	while (*s) {
		h = 16*h + *s++;
		h ^= h>>24 & 0xf0;
	}
	return h & 0xfffffff;
}

146 147 148 149 150 151 152 153 154 155
static uint32_t gnu_hash(const char *s0)
{
	const unsigned char *s = (void *)s0;
	uint_fast32_t h = 5381;
	for (; *s; s++)
		h = h*33 + *s;
	return h;
}

static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)
R
Rich Felker 已提交
156 157
{
	size_t i;
R
Rich Felker 已提交
158 159 160
	Sym *syms = dso->syms;
	uint32_t *hashtab = dso->hashtab;
	char *strings = dso->strings;
R
Rich Felker 已提交
161
	for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
162 163
		if ((!dso->versym || dso->versym[i] >= 0)
		    && (!strcmp(s, strings+syms[i].st_name)))
R
Rich Felker 已提交
164 165 166 167 168
			return syms+i;
	}
	return 0;
}

169 170
static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
{
171 172
	Sym *syms = dso->syms;
	char *strings = dso->strings;
173 174 175 176 177
	uint32_t *hashtab = dso->ghashtab;
	uint32_t nbuckets = hashtab[0];
	uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
	uint32_t h2;
	uint32_t *hashval;
178
	uint32_t i = buckets[h1 % nbuckets];
179

180
	if (!i) return 0;
181

182
	hashval = buckets + nbuckets + (i - hashtab[1]);
183

184
	for (h1 |= 1; ; i++) {
185
		h2 = *hashval++;
186 187 188
		if ((!dso->versym || dso->versym[i] >= 0)
		    && (h1 == (h2|1)) && !strcmp(s, strings + syms[i].st_name))
			return syms+i;
189 190 191 192 193 194
		if (h2 & 1) break;
	}

	return 0;
}

195
#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
196
#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
R
Rich Felker 已提交
197

198
static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
R
Rich Felker 已提交
199
{
200
	uint32_t h = 0, gh = 0;
201
	struct symdef def = {0};
202 203 204 205 206 207 208
	if (dso->ghashtab) {
		gh = gnu_hash(s);
		if (gh == 0x1f4039c9 && !strcmp(s, "__stack_chk_fail")) ssp_used = 1;
	} else {
		h = sysv_hash(s);
		if (h == 0x595a4cc && !strcmp(s, "__stack_chk_fail")) ssp_used = 1;
	}
R
Rich Felker 已提交
209
	for (; dso; dso=dso->next) {
210 211
		Sym *sym;
		if (!dso->global) continue;
212 213 214 215 216 217 218
		if (dso->ghashtab) {
			if (!gh) gh = gnu_hash(s);
			sym = gnu_lookup(s, gh, dso);
		} else {
			if (!h) h = sysv_hash(s);
			sym = sysv_lookup(s, h, dso);
		}
219 220 221 222 223 224 225 226 227 228 229 230 231 232
		if (!sym) continue;
		if (!sym->st_shndx)
			if (need_def || (sym->st_info&0xf) == STT_TLS)
				continue;
		if (!sym->st_value)
			if ((sym->st_info&0xf) != STT_TLS)
				continue;
		if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
		if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;

		if (def.sym && sym->st_info>>4 == STB_WEAK) continue;
		def.sym = sym;
		def.dso = dso;
		if (sym->st_info>>4 == STB_GLOBAL) break;
R
Rich Felker 已提交
233
	}
234
	return def;
R
Rich Felker 已提交
235 236
}

237
static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
R
Rich Felker 已提交
238
{
239 240 241
	unsigned char *base = dso->base;
	Sym *syms = dso->syms;
	char *strings = dso->strings;
R
Rich Felker 已提交
242 243 244 245 246
	Sym *sym;
	const char *name;
	void *ctx;
	int type;
	int sym_index;
247
	struct symdef def;
R
Rich Felker 已提交
248 249 250 251 252 253 254

	for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
		type = R_TYPE(rel[1]);
		sym_index = R_SYM(rel[1]);
		if (sym_index) {
			sym = syms + sym_index;
			name = strings + sym->st_name;
255
			ctx = IS_COPY(type) ? head->next : head;
256
			def = find_sym(ctx, name, IS_PLT(type));
257 258
			if (!def.sym && (sym->st_shndx != SHN_UNDEF
			    || sym->st_info>>4 != STB_WEAK)) {
259 260
				snprintf(errbuf, sizeof errbuf,
					"Error relocating %s: %s: symbol not found",
261
					dso->name, name);
262
				if (runtime) longjmp(*rtld_fail, 1);
263
				dprintf(2, "%s\n", errbuf);
264 265
				ldso_fail = 1;
				continue;
R
Rich Felker 已提交
266
			}
267
		} else {
268 269 270
			sym = 0;
			def.sym = 0;
			def.dso = 0;
R
Rich Felker 已提交
271
		}
272 273 274
		do_single_reloc(dso, base, (void *)(base + rel[0]), type,
			stride>2 ? rel[2] : 0, sym, sym?sym->st_size:0, def,
			def.sym?(size_t)(def.dso->base+def.sym->st_value):0);
R
Rich Felker 已提交
275 276 277
	}
}

278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
/* A huge hack: to make up for the wastefulness of shared libraries
 * needing at least a page of dirty memory even if they have no global
 * data, we reclaim the gaps at the beginning and end of writable maps
 * and "donate" them to the heap by setting up minimal malloc
 * structures and then freeing them. */

static void reclaim(unsigned char *base, size_t start, size_t end)
{
	size_t *a, *z;
	start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t);
	end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t);
	if (start>end || end-start < 4*sizeof(size_t)) return;
	a = (size_t *)(base + start);
	z = (size_t *)(base + end);
	a[-2] = 1;
	a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1;
	z[1] = 1;
	free(a);
}

static void reclaim_gaps(unsigned char *base, Phdr *ph, size_t phent, size_t phcnt)
{
	for (; phcnt--; ph=(void *)((char *)ph+phent)) {
		if (ph->p_type!=PT_LOAD) continue;
		if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;
		reclaim(base, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);
		reclaim(base, ph->p_vaddr+ph->p_memsz,
			ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);
	}
}

309
static void *map_library(int fd, struct dso *dso)
R
Rich Felker 已提交
310
{
311
	Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
312
	void *allocated_buf=0;
R
Rich Felker 已提交
313 314 315 316 317
	size_t phsize;
	size_t addr_min=SIZE_MAX, addr_max=0, map_len;
	size_t this_min, this_max;
	off_t off_start;
	Ehdr *eh;
318
	Phdr *ph, *ph0;
R
Rich Felker 已提交
319
	unsigned prot;
320
	unsigned char *map=MAP_FAILED, *base;
321
	size_t dyn=0;
322
	size_t tls_image=0;
R
Rich Felker 已提交
323 324 325
	size_t i;

	ssize_t l = read(fd, buf, sizeof buf);
326
	eh = buf;
327 328 329
	if (l<0) return 0;
	if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))
		goto noexec;
R
Rich Felker 已提交
330
	phsize = eh->e_phentsize * eh->e_phnum;
331 332 333 334 335 336 337 338
	if (phsize > sizeof buf - sizeof *eh) {
		allocated_buf = malloc(phsize);
		if (!allocated_buf) return 0;
		l = pread(fd, allocated_buf, phsize, eh->e_phoff);
		if (l < 0) goto error;
		if (l != phsize) goto noexec;
		ph = ph0 = allocated_buf;
	} else if (eh->e_phoff + phsize > l) {
339
		l = pread(fd, buf+1, phsize, eh->e_phoff);
340 341
		if (l < 0) goto error;
		if (l != phsize) goto noexec;
342 343 344
		ph = ph0 = (void *)(buf + 1);
	} else {
		ph = ph0 = (void *)((char *)buf + eh->e_phoff);
R
Rich Felker 已提交
345 346 347 348
	}
	for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
		if (ph->p_type == PT_DYNAMIC)
			dyn = ph->p_vaddr;
349 350 351 352 353 354
		if (ph->p_type == PT_TLS) {
			tls_image = ph->p_vaddr;
			dso->tls_align = ph->p_align;
			dso->tls_len = ph->p_filesz;
			dso->tls_size = ph->p_memsz;
		}
R
Rich Felker 已提交
355 356 357 358 359 360 361 362 363 364 365 366
		if (ph->p_type != PT_LOAD) continue;
		if (ph->p_vaddr < addr_min) {
			addr_min = ph->p_vaddr;
			off_start = ph->p_offset;
			prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
				((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
				((ph->p_flags&PF_X) ? PROT_EXEC : 0));
		}
		if (ph->p_vaddr+ph->p_memsz > addr_max) {
			addr_max = ph->p_vaddr+ph->p_memsz;
		}
	}
367
	if (!dyn) goto noexec;
R
Rich Felker 已提交
368 369 370 371 372 373 374 375 376
	addr_max += PAGE_SIZE-1;
	addr_max &= -PAGE_SIZE;
	addr_min &= -PAGE_SIZE;
	off_start &= -PAGE_SIZE;
	map_len = addr_max - addr_min + off_start;
	/* The first time, we map too much, possibly even more than
	 * the length of the file. This is okay because we will not
	 * use the invalid part; we just need to reserve the right
	 * amount of virtual address space to map over later. */
377
	map = mmap((void *)addr_min, map_len, prot, MAP_PRIVATE, fd, off_start);
378
	if (map==MAP_FAILED) goto error;
379 380 381 382 383 384
	/* If the loaded file is not relocatable and the requested address is
	 * not available, then the load operation must fail. */
	if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) {
		errno = EBUSY;
		goto error;
	}
R
Rich Felker 已提交
385
	base = map - addr_min;
386 387 388
	dso->phdr = 0;
	dso->phnum = 0;
	for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
R
Rich Felker 已提交
389
		if (ph->p_type != PT_LOAD) continue;
390 391 392 393 394 395 396 397
		/* Check if the programs headers are in this load segment, and
		 * if so, record the address for use by dl_iterate_phdr. */
		if (!dso->phdr && eh->e_phoff >= ph->p_offset
		    && eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) {
			dso->phdr = (void *)(base + ph->p_vaddr
				+ (eh->e_phoff-ph->p_offset));
			dso->phnum = eh->e_phnum;
		}
R
Rich Felker 已提交
398 399 400 401 402 403 404 405
		/* Reuse the existing mapping for the lowest-address LOAD */
		if ((ph->p_vaddr & -PAGE_SIZE) == addr_min) continue;
		this_min = ph->p_vaddr & -PAGE_SIZE;
		this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
		off_start = ph->p_offset & -PAGE_SIZE;
		prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
			((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
			((ph->p_flags&PF_X) ? PROT_EXEC : 0));
406 407
		if (mmap(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
			goto error;
R
Rich Felker 已提交
408 409 410 411
		if (ph->p_memsz > ph->p_filesz) {
			size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
			size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
			memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
412 413
			if (pgbrk-(size_t)base < this_max && mmap((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
				goto error;
R
Rich Felker 已提交
414 415
		}
	}
R
Rich Felker 已提交
416 417
	for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
		if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
418 419
			if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC) < 0)
				goto error;
R
Rich Felker 已提交
420 421
			break;
		}
422
	if (!runtime) reclaim_gaps(base, ph0, eh->e_phentsize, eh->e_phnum);
423 424 425 426 427
	dso->map = map;
	dso->map_len = map_len;
	dso->base = base;
	dso->dynv = (void *)(base+dyn);
	if (dso->tls_size) dso->tls_image = (void *)(base+tls_image);
428
	free(allocated_buf);
R
Rich Felker 已提交
429
	return map;
430 431
noexec:
	errno = ENOEXEC;
432
error:
433 434
	if (map!=MAP_FAILED) munmap(map, map_len);
	free(allocated_buf);
435
	return 0;
R
Rich Felker 已提交
436 437
}

438
static int path_open(const char *name, const char *s, char *buf, size_t buf_size)
439
{
440 441
	size_t l;
	int fd;
442
	for (;;) {
443 444 445 446 447
		s += strspn(s, ":\n");
		l = strcspn(s, ":\n");
		if (l-1 >= INT_MAX) return -1;
		if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) >= buf_size)
			continue;
448
		if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;
449
		s += l;
450 451 452
	}
}

453 454 455 456 457 458 459 460 461 462 463 464 465
static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
{
	size_t n, l;
	const char *s, *t, *origin;
	char *d;
	if (p->rpath) return 0;
	if (!p->rpath_orig) return -1;
	if (!strchr(p->rpath_orig, '$')) {
		p->rpath = p->rpath_orig;
		return 0;
	}
	n = 0;
	s = p->rpath_orig;
R
Rich Felker 已提交
466 467 468
	while ((t=strchr(s, '$'))) {
		if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
			return -1;
469 470 471 472 473 474 475 476 477 478 479 480 481 482
		s = t+1;
		n++;
	}
	if (n > SSIZE_MAX/PATH_MAX) return -1;

	if (p->kernel_mapped) {
		/* $ORIGIN searches cannot be performed for the main program
		 * when it is suid/sgid/AT_SECURE. This is because the
		 * pathname is under the control of the caller of execve.
		 * For libraries, however, $ORIGIN can be processed safely
		 * since the library's pathname came from a trusted source
		 * (either system paths or a call to dlopen). */
		if (libc.secure)
			return -1;
R
Rich Felker 已提交
483 484
		l = readlink("/proc/self/exe", buf, buf_size);
		if (l >= buf_size)
485
			return -1;
R
Rich Felker 已提交
486
		buf[l] = 0;
487 488 489 490 491 492 493 494 495 496 497
		origin = buf;
	} else {
		origin = p->name;
	}
	t = strrchr(origin, '/');
	l = t ? t-origin : 0;
	p->rpath = malloc(strlen(p->rpath_orig) + n*l + 1);
	if (!p->rpath) return -1;

	d = p->rpath;
	s = p->rpath_orig;
R
Rich Felker 已提交
498
	while ((t=strchr(s, '$'))) {
499 500 501 502
		memcpy(d, s, t-s);
		d += t-s;
		memcpy(d, origin, l);
		d += l;
R
Rich Felker 已提交
503 504
		/* It was determined previously that the '$' is followed
		 * either by "ORIGIN" or "{ORIGIN}". */
505 506 507 508 509 510
		s = t + 7 + 2*(t[1]=='{');
	}
	strcpy(d, s);
	return 0;
}

511 512 513 514 515 516
static void decode_dyn(struct dso *p)
{
	size_t dyn[DYN_CNT] = {0};
	decode_vec(p->dynv, dyn, DYN_CNT);
	p->syms = (void *)(p->base + dyn[DT_SYMTAB]);
	p->strings = (void *)(p->base + dyn[DT_STRTAB]);
517 518
	if (dyn[0]&(1<<DT_HASH))
		p->hashtab = (void *)(p->base + dyn[DT_HASH]);
519
	if (dyn[0]&(1<<DT_RPATH))
520
		p->rpath_orig = (void *)(p->strings + dyn[DT_RPATH]);
521 522
	if (search_vec(p->dynv, dyn, DT_GNU_HASH))
		p->ghashtab = (void *)(p->base + *dyn);
523 524
	if (search_vec(p->dynv, dyn, DT_VERSYM))
		p->versym = (void *)(p->base + *dyn);
525 526
}

527
static struct dso *load_library(const char *name, struct dso *needed_by)
R
Rich Felker 已提交
528
{
529
	char buf[2*NAME_MAX+2];
530
	const char *pathname;
531
	unsigned char *map;
532
	struct dso *p, temp_dso = {0};
R
Rich Felker 已提交
533 534
	int fd;
	struct stat st;
535 536
	size_t alloc_size;
	int n_th = 0;
537
	int is_self = 0;
R
Rich Felker 已提交
538 539 540 541 542 543 544 545

	/* Catch and block attempts to reload the implementation itself */
	if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
		static const char *rp, reserved[] =
			"c\0pthread\0rt\0m\0dl\0util\0xnet\0";
		char *z = strchr(name, '.');
		if (z) {
			size_t l = z-name;
546
			for (rp=reserved; *rp && strncmp(name+3, rp, l-3); rp+=strlen(rp)+1);
R
Rich Felker 已提交
547
			if (*rp) {
548 549 550 551 552 553 554 555 556 557 558 559
				if (ldd_mode) {
					/* Track which names have been resolved
					 * and only report each one once. */
					static unsigned reported;
					unsigned mask = 1U<<(rp-reserved);
					if (!(reported & mask)) {
						reported |= mask;
						dprintf(1, "\t%s => %s (%p)\n",
							name, ldso->name,
							ldso->base);
					}
				}
560
				is_self = 1;
R
Rich Felker 已提交
561 562 563
			}
		}
	}
564 565 566 567 568 569 570 571 572
	if (!strcmp(name, ldso->name)) is_self = 1;
	if (is_self) {
		if (!ldso->prev) {
			tail->next = ldso;
			ldso->prev = tail;
			tail = ldso->next ? ldso->next : ldso;
		}
		return ldso;
	}
573
	if (strchr(name, '/')) {
574
		pathname = name;
575
		fd = open(name, O_RDONLY|O_CLOEXEC);
R
Rich Felker 已提交
576
	} else {
577 578 579 580 581 582 583
		/* Search for the name to see if it's already loaded */
		for (p=head->next; p; p=p->next) {
			if (p->shortname && !strcmp(p->shortname, name)) {
				p->refcnt++;
				return p;
			}
		}
584
		if (strlen(name) > NAME_MAX) return 0;
585
		fd = -1;
586
		if (env_path) fd = path_open(name, env_path, buf, sizeof buf);
587
		for (p=needed_by; fd < 0 && p; p=p->needed_by)
588
			if (!fixup_rpath(p, buf, sizeof buf))
589
				fd = path_open(name, p->rpath, buf, sizeof buf);
590 591
		if (fd < 0) {
			if (!sys_path) {
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
				char *prefix = 0;
				size_t prefix_len;
				if (ldso->name[0]=='/') {
					char *s, *t, *z;
					for (s=t=z=ldso->name; *s; s++)
						if (*s=='/') z=t, t=s;
					prefix_len = z-ldso->name;
					if (prefix_len < PATH_MAX)
						prefix = ldso->name;
				}
				if (!prefix) {
					prefix = "";
					prefix_len = 0;
				}
				char etc_ldso_path[prefix_len + 1
					+ sizeof "/etc/ld-musl-" LDSO_ARCH ".path"];
				snprintf(etc_ldso_path, sizeof etc_ldso_path,
					"%.*s/etc/ld-musl-" LDSO_ARCH ".path",
					(int)prefix_len, prefix);
				FILE *f = fopen(etc_ldso_path, "rbe");
612
				if (f) {
613
					if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) {
614
						free(sys_path);
615
						sys_path = "";
616
					}
617
					fclose(f);
618 619
				} else if (errno != ENOENT) {
					sys_path = "";
620 621
				}
			}
622 623
			if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
			fd = path_open(name, sys_path, buf, sizeof buf);
R
Rich Felker 已提交
624
		}
625
		pathname = buf;
R
Rich Felker 已提交
626 627 628 629 630 631 632 633
	}
	if (fd < 0) return 0;
	if (fstat(fd, &st) < 0) {
		close(fd);
		return 0;
	}
	for (p=head->next; p; p=p->next) {
		if (p->dev == st.st_dev && p->ino == st.st_ino) {
634 635 636
			/* If this library was previously loaded with a
			 * pathname but a search found the same inode,
			 * setup its shortname so it can be found by name. */
637 638
			if (!p->shortname && pathname != name)
				p->shortname = strrchr(p->name, '/')+1;
R
Rich Felker 已提交
639 640 641 642 643
			close(fd);
			p->refcnt++;
			return p;
		}
	}
644
	map = noload ? 0 : map_library(fd, &temp_dso);
R
Rich Felker 已提交
645 646
	close(fd);
	if (!map) return 0;
647 648 649 650 651 652 653 654 655 656

	/* Allocate storage for the new DSO. When there is TLS, this
	 * storage must include a reservation for all pre-existing
	 * threads to obtain copies of both the new TLS, and an
	 * extended DTV capable of storing an additional slot for
	 * the newly-loaded DSO. */
	alloc_size = sizeof *p + strlen(pathname) + 1;
	if (runtime && temp_dso.tls_image) {
		size_t per_th = temp_dso.tls_size + temp_dso.tls_align
			+ sizeof(void *) * (tls_cnt+3);
657
		n_th = libc.threads_minus_1 + 1;
658 659 660 661
		if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
		else alloc_size += n_th * per_th;
	}
	p = calloc(1, alloc_size);
R
Rich Felker 已提交
662
	if (!p) {
663
		munmap(map, temp_dso.map_len);
R
Rich Felker 已提交
664 665
		return 0;
	}
666
	memcpy(p, &temp_dso, sizeof temp_dso);
667
	decode_dyn(p);
R
Rich Felker 已提交
668 669 670
	p->dev = st.st_dev;
	p->ino = st.st_ino;
	p->refcnt = 1;
671
	p->needed_by = needed_by;
R
Rich Felker 已提交
672
	p->name = p->buf;
673 674 675
	strcpy(p->name, pathname);
	/* Add a shortname only if name arg was not an explicit pathname. */
	if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
676
	if (p->tls_image) {
677
		if (runtime && !libc.has_thread_pointer) {
678
			munmap(map, p->map_len);
679
			free(p);
680
			errno = ENOSYS;
681 682
			return 0;
		}
683
		p->tls_id = ++tls_cnt;
R
Rich Felker 已提交
684
		tls_align = MAXP2(tls_align, p->tls_align);
685 686 687 688 689
#ifdef TLS_ABOVE_TP
		p->tls_offset = tls_offset + ( (tls_align-1) &
			-(tls_offset + (uintptr_t)p->tls_image) );
		tls_offset += p->tls_size;
#else
R
Rich Felker 已提交
690 691 692 693
		tls_offset += p->tls_size + p->tls_align - 1;
		tls_offset -= (tls_offset + (uintptr_t)p->tls_image)
			& (p->tls_align-1);
		p->tls_offset = tls_offset;
694
#endif
695 696 697 698
		p->new_dtv = (void *)(-sizeof(size_t) &
			(uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
		p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
	}
R
Rich Felker 已提交
699 700 701 702 703

	tail->next = p;
	p->prev = tail;
	tail = p;

704
	if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);
705

R
Rich Felker 已提交
706 707 708 709 710
	return p;
}

static void load_deps(struct dso *p)
{
711 712
	size_t i, ndeps=0;
	struct dso ***deps = &p->deps, **tmp, *dep;
R
Rich Felker 已提交
713 714 715
	for (; p; p=p->next) {
		for (i=0; p->dynv[i]; i+=2) {
			if (p->dynv[i] != DT_NEEDED) continue;
716
			dep = load_library(p->strings + p->dynv[i+1], p);
717
			if (!dep) {
718 719
				snprintf(errbuf, sizeof errbuf,
					"Error loading shared library %s: %m (needed by %s)",
R
Rich Felker 已提交
720
					p->strings + p->dynv[i+1], p->name);
721
				if (runtime) longjmp(*rtld_fail, 1);
722
				dprintf(2, "%s\n", errbuf);
723 724
				ldso_fail = 1;
				continue;
R
Rich Felker 已提交
725
			}
726 727
			if (runtime) {
				tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2));
728
				if (!tmp) longjmp(*rtld_fail, 1);
729 730 731 732
				tmp[ndeps++] = dep;
				tmp[ndeps] = 0;
				*deps = tmp;
			}
R
Rich Felker 已提交
733 734 735 736
		}
	}
}

R
Rich Felker 已提交
737 738 739 740 741 742 743 744 745
static void load_preload(char *s)
{
	int tmp;
	char *z;
	for (z=s; *z; s=z) {
		for (   ; *s && isspace(*s); s++);
		for (z=s; *z && !isspace(*z); z++);
		tmp = *z;
		*z = 0;
746
		load_library(s, 0);
R
Rich Felker 已提交
747 748 749 750
		*z = tmp;
	}
}

751 752 753 754 755
static void make_global(struct dso *p)
{
	for (; p; p=p->next) p->global = 1;
}

R
Rich Felker 已提交
756 757 758 759 760 761
static void reloc_all(struct dso *p)
{
	size_t dyn[DYN_CNT] = {0};
	for (; p; p=p->next) {
		if (p->relocated) continue;
		decode_vec(p->dynv, dyn, DYN_CNT);
R
Rich Felker 已提交
762 763 764
#ifdef NEED_ARCH_RELOCS
		do_arch_relocs(p, head);
#endif
765 766 767 768
		do_relocs(p, (void *)(p->base+dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],
			2+(dyn[DT_PLTREL]==DT_RELA));
		do_relocs(p, (void *)(p->base+dyn[DT_REL]), dyn[DT_RELSZ], 2);
		do_relocs(p, (void *)(p->base+dyn[DT_RELA]), dyn[DT_RELASZ], 3);
769
		p->relocated = 1;
R
Rich Felker 已提交
770 771 772
	}
}

773 774 775 776 777 778 779 780
static size_t find_dyn(Phdr *ph, size_t cnt, size_t stride)
{
	for (; cnt--; ph = (void *)((char *)ph + stride))
		if (ph->p_type == PT_DYNAMIC)
			return ph->p_vaddr;
	return 0;
}

781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
static void find_map_range(Phdr *ph, size_t cnt, size_t stride, struct dso *p)
{
	size_t min_addr = -1, max_addr = 0;
	for (; cnt--; ph = (void *)((char *)ph + stride)) {
		if (ph->p_type != PT_LOAD) continue;
		if (ph->p_vaddr < min_addr)
			min_addr = ph->p_vaddr;
		if (ph->p_vaddr+ph->p_memsz > max_addr)
			max_addr = ph->p_vaddr+ph->p_memsz;
	}
	min_addr &= -PAGE_SIZE;
	max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;
	p->map = p->base + min_addr;
	p->map_len = max_addr - min_addr;
}

797 798 799 800 801 802 803
static void do_fini()
{
	struct dso *p;
	size_t dyn[DYN_CNT] = {0};
	for (p=fini_head; p; p=p->fini_next) {
		if (!p->constructed) continue;
		decode_vec(p->dynv, dyn, DYN_CNT);
804 805
		if (dyn[0] & (1<<DT_FINI_ARRAY)) {
			size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
806 807
			size_t *fn = (size_t *)(p->base + dyn[DT_FINI_ARRAY])+n;
			while (n--) ((void (*)(void))*--fn)();
808
		}
809
#ifndef NO_LEGACY_INITFINI
810
		if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])
811
			((void (*)(void))(p->base + dyn[DT_FINI]))();
812
#endif
813 814 815
	}
}

816 817 818
static void do_init_fini(struct dso *p)
{
	size_t dyn[DYN_CNT] = {0};
819
	int need_locking = libc.threads_minus_1;
820 821 822 823
	/* Allow recursive calls that arise when a library calls
	 * dlopen from one of its constructors, but block any
	 * other threads until all ctors have finished. */
	if (need_locking) pthread_mutex_lock(&init_fini_lock);
824
	for (; p; p=p->prev) {
825 826
		if (p->constructed) continue;
		p->constructed = 1;
827
		decode_vec(p->dynv, dyn, DYN_CNT);
828
		if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {
829 830 831
			p->fini_next = fini_head;
			fini_head = p;
		}
832
#ifndef NO_LEGACY_INITFINI
833
		if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])
834
			((void (*)(void))(p->base + dyn[DT_INIT]))();
835
#endif
836 837 838 839 840
		if (dyn[0] & (1<<DT_INIT_ARRAY)) {
			size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);
			size_t *fn = (void *)(p->base + dyn[DT_INIT_ARRAY]);
			while (n--) ((void (*)(void))*fn++)();
		}
841 842 843 844
		if (!need_locking && libc.threads_minus_1) {
			need_locking = 1;
			pthread_mutex_lock(&init_fini_lock);
		}
845
	}
846
	if (need_locking) pthread_mutex_unlock(&init_fini_lock);
847 848
}

849 850 851 852
void _dl_debug_state(void)
{
}

853 854 855 856 857 858 859 860 861 862 863 864 865
void __reset_tls()
{
	pthread_t self = __pthread_self();
	struct dso *p;
	for (p=head; p; p=p->next) {
		if (!p->tls_id || !self->dtv[p->tls_id]) continue;
		memcpy(self->dtv[p->tls_id], p->tls_image, p->tls_len);
		memset((char *)self->dtv[p->tls_id]+p->tls_len, 0,
			p->tls_size - p->tls_len);
		if (p->tls_id == (size_t)self->dtv[0]) break;
	}
}

866
void *__copy_tls(unsigned char *mem)
867
{
R
Rich Felker 已提交
868
	pthread_t td;
869
	struct dso *p;
R
Rich Felker 已提交
870

871
	void **dtv = (void *)mem;
872
	dtv[0] = (void *)tls_cnt;
873 874 875 876 877
	if (!tls_cnt) {
		td = (void *)(dtv+1);
		td->dtv = dtv;
		return td;
	}
R
Rich Felker 已提交
878

879 880 881 882 883 884 885 886 887 888 889 890
#ifdef TLS_ABOVE_TP
	mem += sizeof(void *) * (tls_cnt+1);
	mem += -((uintptr_t)mem + sizeof(struct pthread)) & (tls_align-1);
	td = (pthread_t)mem;
	mem += sizeof(struct pthread);

	for (p=head; p; p=p->next) {
		if (!p->tls_id) continue;
		dtv[p->tls_id] = mem + p->tls_offset;
		memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
	}
#else
891
	mem += libc.tls_size - sizeof(struct pthread);
R
Rich Felker 已提交
892 893 894 895
	mem -= (uintptr_t)mem & (tls_align-1);
	td = (pthread_t)mem;

	for (p=head; p; p=p->next) {
896
		if (!p->tls_id) continue;
R
Rich Felker 已提交
897 898
		dtv[p->tls_id] = mem - p->tls_offset;
		memcpy(dtv[p->tls_id], p->tls_image, p->tls_len);
899
	}
900
#endif
R
Rich Felker 已提交
901 902
	td->dtv = dtv;
	return td;
903 904
}

905
void *__tls_get_addr(size_t *v)
906 907
{
	pthread_t self = __pthread_self();
908
	if (v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]])
909 910 911 912
		return (char *)self->dtv[v[0]]+v[1];

	/* Block signals to make accessing new TLS async-signal-safe */
	sigset_t set;
913
	pthread_sigmask(SIG_BLOCK, SIGALL_SET, &set);
914
	if (v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) {
915 916 917 918 919 920 921 922 923 924 925 926
		pthread_sigmask(SIG_SETMASK, &set, 0);
		return (char *)self->dtv[v[0]]+v[1];
	}

	/* This is safe without any locks held because, if the caller
	 * is able to request the Nth entry of the DTV, the DSO list
	 * must be valid at least that far out and it was synchronized
	 * at program startup or by an already-completed call to dlopen. */
	struct dso *p;
	for (p=head; p->tls_id != v[0]; p=p->next);

	/* Get new DTV space from new DSO if needed */
927
	if (v[0] > (size_t)self->dtv[0]) {
928 929
		void **newdtv = p->new_dtv +
			(v[0]+1)*sizeof(void *)*a_fetch_add(&p->new_dtv_idx,1);
930
		memcpy(newdtv, self->dtv,
931 932 933
			((size_t)self->dtv[0]+1) * sizeof(void *));
		newdtv[0] = (void *)v[0];
		self->dtv = newdtv;
934
	}
935 936 937 938 939 940

	/* Get new TLS memory from new DSO */
	unsigned char *mem = p->new_tls +
		(p->tls_size + p->tls_align) * a_fetch_add(&p->new_tls_idx,1);
	mem += ((uintptr_t)p->tls_image - (uintptr_t)mem) & (p->tls_align-1);
	self->dtv[v[0]] = mem;
R
Rich Felker 已提交
941
	memcpy(mem, p->tls_image, p->tls_len);
942 943
	pthread_sigmask(SIG_SETMASK, &set, 0);
	return mem + v[1];
944 945
}

R
Rich Felker 已提交
946 947
static void update_tls_size()
{
948 949 950 951 952 953
	libc.tls_size = ALIGN(
		(1+tls_cnt) * sizeof(void *) +
		tls_offset +
		sizeof(struct pthread) +
		tls_align * 2,
	tls_align);
R
Rich Felker 已提交
954 955
}

956
void *__dynlink(int argc, char **argv)
R
Rich Felker 已提交
957
{
958
	size_t aux[AUX_CNT] = {0};
R
Rich Felker 已提交
959 960
	size_t i;
	Phdr *phdr;
961
	Ehdr *ehdr;
962
	static struct dso builtin_dsos[3];
R
Rich Felker 已提交
963 964
	struct dso *const app = builtin_dsos+0;
	struct dso *const lib = builtin_dsos+1;
965
	struct dso *const vdso = builtin_dsos+2;
R
Rich Felker 已提交
966
	char *env_preload=0;
R
Rich Felker 已提交
967
	size_t vdso_base;
968
	size_t *auxv;
969
	char **envp = argv+argc+1;
970
	void *initial_tls;
R
Rich Felker 已提交
971 972

	/* Find aux vector just past environ[] */
973 974 975
	for (i=argc+1; argv[i]; i++)
		if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16))
			env_path = argv[i]+16;
R
Rich Felker 已提交
976 977
		else if (!memcmp(argv[i], "LD_PRELOAD=", 11))
			env_preload = argv[i]+11;
R
Rich Felker 已提交
978 979 980 981
	auxv = (void *)(argv+i+1);

	decode_vec(auxv, aux, AUX_CNT);

982 983
	/* Only trust user/env if kernel says we're not suid/sgid */
	if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
R
Rich Felker 已提交
984
	  || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]) {
985
		env_path = 0;
R
Rich Felker 已提交
986
		env_preload = 0;
987
		libc.secure = 1;
988
	}
989
	libc.page_size = aux[AT_PAGESZ];
990

991 992 993 994 995 996 997 998 999
	/* If the dynamic linker was invoked as a program itself, AT_BASE
	 * will not be set. In that case, we assume the base address is
	 * the start of the page containing the PHDRs; I don't know any
	 * better approach... */
	if (!aux[AT_BASE]) {
		aux[AT_BASE] = aux[AT_PHDR] & -PAGE_SIZE;
		aux[AT_PHDR] = aux[AT_PHENT] = aux[AT_PHNUM] = 0;
	}

1000 1001 1002
	/* The dynamic linker load address is passed by the kernel
	 * in the AUX vector, so this is easy. */
	lib->base = (void *)aux[AT_BASE];
1003
	lib->name = lib->shortname = "libc.so";
1004
	lib->global = 1;
1005
	lib->kernel_mapped = 1;
1006
	ehdr = (void *)lib->base;
R
Rich Felker 已提交
1007 1008 1009 1010
	lib->phnum = ehdr->e_phnum;
	lib->phdr = (void *)(aux[AT_BASE]+ehdr->e_phoff);
	find_map_range(lib->phdr, ehdr->e_phnum, ehdr->e_phentsize, lib);
	lib->dynv = (void *)(lib->base + find_dyn(lib->phdr,
R
Rich Felker 已提交
1011
		ehdr->e_phnum, ehdr->e_phentsize));
1012 1013
	decode_dyn(lib);

1014
	if (aux[AT_PHDR]) {
1015
		size_t interp_off = 0;
1016
		size_t tls_image = 0;
1017
		/* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
R
Rich Felker 已提交
1018 1019
		app->phdr = phdr = (void *)aux[AT_PHDR];
		app->phnum = aux[AT_PHNUM];
1020 1021 1022
		for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
			if (phdr->p_type == PT_PHDR)
				app->base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);
1023 1024
			else if (phdr->p_type == PT_INTERP)
				interp_off = (size_t)phdr->p_vaddr;
1025 1026 1027 1028 1029 1030
			else if (phdr->p_type == PT_TLS) {
				tls_image = phdr->p_vaddr;
				app->tls_len = phdr->p_filesz;
				app->tls_size = phdr->p_memsz;
				app->tls_align = phdr->p_align;
			}
1031
		}
1032
		if (app->tls_size) app->tls_image = (char *)app->base + tls_image;
1033
		if (interp_off) lib->name = (char *)app->base + interp_off;
1034 1035 1036 1037 1038
		if ((aux[0] & (1UL<<AT_EXECFN))
		    && strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
			app->name = (char *)aux[AT_EXECFN];
		else
			app->name = argv[0];
1039
		app->kernel_mapped = 1;
1040 1041
		app->dynv = (void *)(app->base + find_dyn(
			(void *)aux[AT_PHDR], aux[AT_PHNUM], aux[AT_PHENT]));
1042 1043
		find_map_range((void *)aux[AT_PHDR],
			aux[AT_PHNUM], aux[AT_PHENT], app);
1044 1045 1046
	} else {
		int fd;
		char *ldname = argv[0];
R
Rich Felker 已提交
1047
		size_t l = strlen(ldname);
1048 1049 1050 1051
		if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;
		*argv++ = (void *)-1;
		if (argv[0] && !strcmp(argv[0], "--")) *argv++ = (void *)-1;
		if (!argv[0]) {
1052 1053 1054 1055 1056
			dprintf(2, "musl libc\n"
				"Version %s\n"
				"Dynamic Program Loader\n"
				"Usage: %s [--] pathname%s\n",
				__libc_get_version(), ldname,
1057 1058 1059 1060 1061 1062 1063 1064 1065
				ldd_mode ? "" : " [args]");
			_exit(1);
		}
		fd = open(argv[0], O_RDONLY);
		if (fd < 0) {
			dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));
			_exit(1);
		}
		runtime = 1;
1066
		ehdr = (void *)map_library(fd, app);
1067 1068 1069 1070 1071 1072
		if (!ehdr) {
			dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
			_exit(1);
		}
		runtime = 0;
		close(fd);
1073
		lib->name = ldname;
1074
		app->name = argv[0];
1075
		aux[AT_ENTRY] = (size_t)app->base + ehdr->e_entry;
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
		/* Find the name that would have been used for the dynamic
		 * linker had ldd not taken its place. */
		if (ldd_mode) {
			for (i=0; i<app->phnum; i++) {
				if (app->phdr[i].p_type == PT_INTERP)
					lib->name = (void *)(app->base
						+ app->phdr[i].p_vaddr);
			}
			dprintf(1, "\t%s (%p)\n", lib->name, lib->base);
		}
1086
	}
1087
	if (app->tls_size) {
R
Rich Felker 已提交
1088
		app->tls_id = tls_cnt = 1;
1089 1090 1091 1092 1093 1094
#ifdef TLS_ABOVE_TP
		app->tls_offset = 0;
		tls_offset = app->tls_size
			+ ( -((uintptr_t)app->tls_image + app->tls_size)
			& (app->tls_align-1) );
#else
1095 1096 1097
		tls_offset = app->tls_offset = app->tls_size
			+ ( -((uintptr_t)app->tls_image + app->tls_size)
			& (app->tls_align-1) );
1098
#endif
R
Rich Felker 已提交
1099
		tls_align = MAXP2(tls_align, app->tls_align);
1100
	}
1101 1102 1103 1104
	app->global = 1;
	decode_dyn(app);

	/* Attach to vdso, if provided by the kernel */
R
Rich Felker 已提交
1105
	if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR)) {
1106
		ehdr = (void *)vdso_base;
R
Rich Felker 已提交
1107 1108
		vdso->phdr = phdr = (void *)(vdso_base + ehdr->e_phoff);
		vdso->phnum = ehdr->e_phnum;
1109 1110 1111 1112 1113 1114
		for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
			if (phdr->p_type == PT_DYNAMIC)
				vdso->dynv = (void *)(vdso_base + phdr->p_offset);
			if (phdr->p_type == PT_LOAD)
				vdso->base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
		}
1115 1116
		vdso->name = "";
		vdso->shortname = "linux-gate.so.1";
1117
		vdso->global = 1;
1118
		decode_dyn(vdso);
1119 1120 1121 1122
		vdso->prev = lib;
		lib->next = vdso;
	}

1123 1124 1125 1126 1127
	/* Initial dso chain consists only of the app. We temporarily
	 * append the dynamic linker/libc so we can relocate it, then
	 * restore the initial chain in preparation for loading third
	 * party libraries (preload/needed). */
	head = tail = app;
1128
	ldso = lib;
1129 1130 1131
	app->next = lib;
	reloc_all(lib);
	app->next = 0;
R
Rich Felker 已提交
1132

1133
	/* PAST THIS POINT, ALL LIBC INTERFACES ARE FULLY USABLE. */
R
Rich Felker 已提交
1134

1135
	/* Donate unused parts of app and library mapping to malloc */
R
Rich Felker 已提交
1136 1137 1138
	reclaim_gaps(app->base, (void *)aux[AT_PHDR], aux[AT_PHENT], aux[AT_PHNUM]);
	ehdr = (void *)lib->base;
	reclaim_gaps(lib->base, (void *)(lib->base+ehdr->e_phoff),
1139 1140
		ehdr->e_phentsize, ehdr->e_phnum);

1141
	/* Load preload/needed libraries, add their symbols to the global
1142 1143 1144
	 * namespace, and perform all remaining relocations. The main
	 * program must be relocated LAST since it may contain copy
	 * relocations which depend on libraries' relocations. */
R
Rich Felker 已提交
1145
	if (env_preload) load_preload(env_preload);
1146 1147
	load_deps(app);
	make_global(app);
1148

R
Rich Felker 已提交
1149 1150 1151 1152
	reloc_all(app->next);
	reloc_all(app);

	update_tls_size();
1153 1154 1155
	if (libc.tls_size > sizeof builtin_tls) {
		initial_tls = calloc(libc.tls_size, 1);
		if (!initial_tls) {
1156
			dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
1157
				argv[0], libc.tls_size);
1158 1159
			_exit(127);
		}
1160 1161 1162 1163 1164 1165
	} else {
		initial_tls = builtin_tls;
	}
	if (__init_tp(__copy_tls(initial_tls)) < 0 && tls_cnt) {
		dprintf(2, "%s: Thread-local storage not supported by kernel.\n", argv[0]);
		_exit(127);
1166 1167
	}

1168
	if (ldso_fail) _exit(127);
1169 1170
	if (ldd_mode) _exit(0);

1171 1172 1173 1174
	/* Switch to runtime mode: any further failures in the dynamic
	 * linker are a reportable failure rather than a fatal startup
	 * error. If the dynamic loader (dlopen) will not be used, free
	 * all memory used by the dynamic linker. */
R
Rich Felker 已提交
1175
	runtime = 1;
1176

1177
#ifndef DYNAMIC_IS_RO
1178 1179 1180
	for (i=0; app->dynv[i]; i+=2)
		if (app->dynv[i]==DT_DEBUG)
			app->dynv[i+1] = (size_t)&debug;
1181
#endif
1182 1183 1184 1185 1186 1187 1188
	debug.ver = 1;
	debug.bp = _dl_debug_state;
	debug.head = head;
	debug.base = lib->base;
	debug.state = 0;
	_dl_debug_state();

1189
	if (ssp_used) __init_ssp((void *)aux[AT_RANDOM]);
1190
	__init_libc(envp, argv[0]);
1191
	atexit(do_fini);
1192
	errno = 0;
1193
	do_init_fini(tail);
1194 1195

	return (void *)aux[AT_ENTRY];
1196 1197
}

1198 1199
void *dlopen(const char *file, int mode)
{
R
Rich Felker 已提交
1200
	struct dso *volatile p, *orig_tail, *next;
R
Rich Felker 已提交
1201
	size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
1202
	size_t i;
1203
	int cs;
1204
	jmp_buf jb;
1205 1206 1207

	if (!file) return head;

1208
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
1209
	pthread_rwlock_wrlock(&lock);
1210
	__inhibit_ptc();
1211

1212 1213
	p = 0;
	orig_tls_cnt = tls_cnt;
R
Rich Felker 已提交
1214 1215
	orig_tls_offset = tls_offset;
	orig_tls_align = tls_align;
R
Rich Felker 已提交
1216
	orig_tail = tail;
1217
	noload = mode & RTLD_NOLOAD;
R
Rich Felker 已提交
1218

1219 1220
	rtld_fail = &jb;
	if (setjmp(*rtld_fail)) {
1221
		/* Clean up anything new that was (partially) loaded */
1222
		if (p && p->deps) for (i=0; p->deps[i]; i++)
1223 1224
			if (p->deps[i]->global < 0)
				p->deps[i]->global = 0;
1225 1226 1227 1228 1229 1230
		for (p=orig_tail->next; p; p=next) {
			next = p->next;
			munmap(p->map, p->map_len);
			free(p->deps);
			free(p);
		}
1231
		tls_cnt = orig_tls_cnt;
R
Rich Felker 已提交
1232 1233
		tls_offset = orig_tls_offset;
		tls_align = orig_tls_align;
1234 1235
		tail = orig_tail;
		tail->next = 0;
1236
		p = 0;
1237 1238
		errflag = 1;
		goto end;
1239
	} else p = load_library(file, head);
R
Rich Felker 已提交
1240 1241

	if (!p) {
1242 1243 1244 1245
		snprintf(errbuf, sizeof errbuf, noload ?
			"Library %s is not already loaded" :
			"Error loading shared library %s: %m",
			file);
R
Rich Felker 已提交
1246
		errflag = 1;
1247
		goto end;
1248 1249 1250 1251 1252
	}

	/* First load handling */
	if (!p->deps) {
		load_deps(p);
R
Rich Felker 已提交
1253
		if (p->deps) for (i=0; p->deps[i]; i++)
1254 1255 1256
			if (!p->deps[i]->global)
				p->deps[i]->global = -1;
		if (!p->global) p->global = -1;
1257
		reloc_all(p);
R
Rich Felker 已提交
1258
		if (p->deps) for (i=0; p->deps[i]; i++)
1259 1260 1261
			if (p->deps[i]->global < 0)
				p->deps[i]->global = 0;
		if (p->global < 0) p->global = 0;
1262 1263 1264
	}

	if (mode & RTLD_GLOBAL) {
R
Rich Felker 已提交
1265
		if (p->deps) for (i=0; p->deps[i]; i++)
1266 1267 1268 1269
			p->deps[i]->global = 1;
		p->global = 1;
	}

R
Rich Felker 已提交
1270
	update_tls_size();
1271

1272
	if (ssp_used) __init_ssp(libc.auxv);
1273

1274
	_dl_debug_state();
1275
	orig_tail = tail;
1276
end:
1277
	__release_ptc();
R
Rich Felker 已提交
1278
	if (p) gencnt++;
1279
	pthread_rwlock_unlock(&lock);
1280
	if (p) do_init_fini(orig_tail);
1281
	pthread_setcancelstate(cs, 0);
1282 1283 1284
	return p;
}

1285
static int invalid_dso_handle(void *h)
1286 1287 1288 1289 1290 1291 1292 1293
{
	struct dso *p;
	for (p=head; p; p=p->next) if (h==p) return 0;
	snprintf(errbuf, sizeof errbuf, "Invalid library handle %p", (void *)h);
	errflag = 1;
	return 1;
}

R
Rich Felker 已提交
1294
static void *do_dlsym(struct dso *p, const char *s, void *ra)
1295 1296
{
	size_t i;
1297
	uint32_t h = 0, gh = 0;
1298
	Sym *sym;
1299
	if (p == head || p == RTLD_DEFAULT || p == RTLD_NEXT) {
1300 1301 1302
		if (p == RTLD_DEFAULT) {
			p = head;
		} else if (p == RTLD_NEXT) {
1303 1304
			for (p=head; p && (unsigned char *)ra-p->map>p->map_len; p=p->next);
			if (!p) p=head;
1305
			p = p->next;
1306
		}
1307
		struct symdef def = find_sym(p, s, 0);
1308
		if (!def.sym) goto failed;
1309 1310
		if ((def.sym->st_info&0xf) == STT_TLS)
			return __tls_get_addr((size_t []){def.dso->tls_id, def.sym->st_value});
1311
		return def.dso->base + def.sym->st_value;
R
Rich Felker 已提交
1312
	}
1313 1314
	if (p != RTLD_DEFAULT && p != RTLD_NEXT && invalid_dso_handle(p))
		return 0;
1315 1316 1317 1318 1319 1320 1321
	if (p->ghashtab) {
		gh = gnu_hash(s);
		sym = gnu_lookup(s, gh, p);
	} else {
		h = sysv_hash(s);
		sym = sysv_lookup(s, h, p);
	}
1322 1323
	if (sym && (sym->st_info&0xf) == STT_TLS)
		return __tls_get_addr((size_t []){p->tls_id, sym->st_value});
1324 1325 1326
	if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
		return p->base + sym->st_value;
	if (p->deps) for (i=0; p->deps[i]; i++) {
1327 1328
		if (p->deps[i]->ghashtab) {
			if (!gh) gh = gnu_hash(s);
1329
			sym = gnu_lookup(s, gh, p->deps[i]);
1330 1331 1332 1333
		} else {
			if (!h) h = sysv_hash(s);
			sym = sysv_lookup(s, h, p->deps[i]);
		}
1334 1335
		if (sym && (sym->st_info&0xf) == STT_TLS)
			return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value});
1336 1337 1338
		if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
			return p->deps[i]->base + sym->st_value;
	}
1339
failed:
R
Rich Felker 已提交
1340
	errflag = 1;
1341
	snprintf(errbuf, sizeof errbuf, "Symbol not found: %s", s);
1342 1343 1344
	return 0;
}

1345
int __dladdr(const void *addr, Dl_info *info)
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369
{
	struct dso *p;
	Sym *sym;
	uint32_t nsym;
	char *strings;
	size_t i;
	void *best = 0;
	char *bestname;

	pthread_rwlock_rdlock(&lock);
	for (p=head; p && (unsigned char *)addr-p->map>p->map_len; p=p->next);
	pthread_rwlock_unlock(&lock);

	if (!p) return 0;

	sym = p->syms;
	strings = p->strings;
	if (p->hashtab) {
		nsym = p->hashtab[1];
	} else {
		uint32_t *buckets;
		uint32_t *hashval;
		buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
		sym += p->ghashtab[1];
R
Rich Felker 已提交
1370
		for (i = nsym = 0; i < p->ghashtab[0]; i++) {
1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
			if (buckets[i] > nsym)
				nsym = buckets[i];
		}
		if (nsym) {
			nsym -= p->ghashtab[1];
			hashval = buckets + p->ghashtab[0] + nsym;
			do nsym++;
			while (!(*hashval++ & 1));
		}
	}

	for (; nsym; nsym--, sym++) {
1383
		if (sym->st_value
1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405
		 && (1<<(sym->st_info&0xf) & OK_TYPES)
		 && (1<<(sym->st_info>>4) & OK_BINDS)) {
			void *symaddr = p->base + sym->st_value;
			if (symaddr > addr || symaddr < best)
				continue;
			best = symaddr;
			bestname = strings + sym->st_name;
			if (addr == symaddr)
				break;
		}
	}

	if (!best) return 0;

	info->dli_fname = p->name;
	info->dli_fbase = p->base;
	info->dli_sname = bestname;
	info->dli_saddr = best;

	return 1;
}

1406
void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
1407 1408 1409
{
	void *res;
	pthread_rwlock_rdlock(&lock);
R
Rich Felker 已提交
1410
	res = do_dlsym(p, s, ra);
1411 1412 1413
	pthread_rwlock_unlock(&lock);
	return res;
}
R
Rich Felker 已提交
1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439

int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
{
	struct dso *current;
	struct dl_phdr_info info;
	int ret = 0;
	for(current = head; current;) {
		info.dlpi_addr      = (uintptr_t)current->base;
		info.dlpi_name      = current->name;
		info.dlpi_phdr      = current->phdr;
		info.dlpi_phnum     = current->phnum;
		info.dlpi_adds      = gencnt;
		info.dlpi_subs      = 0;
		info.dlpi_tls_modid = current->tls_id;
		info.dlpi_tls_data  = current->tls_image;

		ret = (callback)(&info, sizeof (info), data);

		if (ret != 0) break;

		pthread_rwlock_rdlock(&lock);
		current = current->next;
		pthread_rwlock_unlock(&lock);
	}
	return ret;
}
1440
#else
1441
static int invalid_dso_handle(void *h)
1442 1443 1444 1445 1446
{
	snprintf(errbuf, sizeof errbuf, "Invalid library handle %p", (void *)h);
	errflag = 1;
	return 1;
}
1447 1448 1449 1450
void *dlopen(const char *file, int mode)
{
	return 0;
}
1451
void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
1452 1453 1454
{
	return 0;
}
1455
int __dladdr (const void *addr, Dl_info *info)
1456 1457 1458
{
	return 0;
}
1459
#endif
1460

R
Rich Felker 已提交
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472
int __dlinfo(void *dso, int req, void *res)
{
	if (invalid_dso_handle(dso)) return -1;
	if (req != RTLD_DI_LINKMAP) {
		snprintf(errbuf, sizeof errbuf, "Unsupported request %d", req);
		errflag = 1;
		return -1;
	}
	*(struct link_map **)res = dso;
	return 0;
}

1473 1474
char *dlerror()
{
R
Rich Felker 已提交
1475 1476
	if (!errflag) return 0;
	errflag = 0;
1477
	return errbuf;
1478 1479 1480 1481
}

int dlclose(void *p)
{
1482
	return invalid_dso_handle(p);
1483
}