Path: blob/main/system/lib/libc/musl/ldso/dynlink.c
6174 views
#define _GNU_SOURCE1#define SYSCALL_NO_TLS 12#include <stdlib.h>3#include <stdarg.h>4#include <stddef.h>5#include <string.h>6#include <unistd.h>7#include <stdint.h>8#include <elf.h>9#include <sys/mman.h>10#include <limits.h>11#include <fcntl.h>12#include <sys/stat.h>13#include <errno.h>14#include <link.h>15#include <setjmp.h>16#include <pthread.h>17#include <ctype.h>18#include <dlfcn.h>19#include <semaphore.h>20#include <sys/membarrier.h>21#include "pthread_impl.h"22#include "fork_impl.h"23#include "dynlink.h"2425static size_t ldso_page_size;26#ifndef PAGE_SIZE27#define PAGE_SIZE ldso_page_size28#endif2930#include "libc.h"3132#define malloc __libc_malloc33#define calloc __libc_calloc34#define realloc __libc_realloc35#define free __libc_free3637static void error_impl(const char *, ...);38static void error_noop(const char *, ...);39static void (*error)(const char *, ...) = error_noop;4041#define MAXP2(a,b) (-(-(a)&-(b)))42#define ALIGN(x,y) ((x)+(y)-1 & -(y))4344#define container_of(p,t,m) ((t*)((char *)(p)-offsetof(t,m)))45#define countof(a) ((sizeof (a))/(sizeof (a)[0]))4647struct debug {48int ver;49void *head;50void (*bp)(void);51int state;52void *base;53};5455struct td_index {56size_t args[2];57struct td_index *next;58};5960struct dso {61#if DL_FDPIC62struct fdpic_loadmap *loadmap;63#else64unsigned char *base;65#endif66char *name;67size_t *dynv;68struct dso *next, *prev;6970Phdr *phdr;71int phnum;72size_t phentsize;73Sym *syms;74Elf_Symndx *hashtab;75uint32_t *ghashtab;76int16_t *versym;77char *strings;78struct dso *syms_next, *lazy_next;79size_t *lazy, lazy_cnt;80unsigned char *map;81size_t map_len;82dev_t dev;83ino_t ino;84char relocated;85char constructed;86char kernel_mapped;87char mark;88char bfs_built;89char runtime_loaded;90struct dso **deps, *needed_by;91size_t ndeps_direct;92size_t next_dep;93pthread_t ctor_visitor;94char *rpath_orig, *rpath;95struct tls_module tls;96size_t tls_id;97size_t relro_start, relro_end;98uintptr_t *new_dtv;99unsigned char *new_tls;100struct td_index *td_index;101struct dso *fini_next;102char *shortname;103#if DL_FDPIC104unsigned char *base;105#else106struct fdpic_loadmap *loadmap;107#endif108struct funcdesc {109void *addr;110size_t *got;111} *funcdescs;112size_t *got;113char buf[];114};115116struct symdef {117Sym *sym;118struct dso *dso;119};120121typedef void (*stage3_func)(size_t *, size_t *);122123static struct builtin_tls {124char c;125struct pthread pt;126void *space[16];127} builtin_tls[1];128#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)129130#define ADDEND_LIMIT 4096131static size_t *saved_addends, *apply_addends_to;132133static struct dso ldso;134static struct dso *head, *tail, *fini_head, *syms_tail, *lazy_head;135static char *env_path, *sys_path;136static unsigned long long gencnt;137static int runtime;138static int ldd_mode;139static int ldso_fail;140static int noload;141static int shutting_down;142static jmp_buf *rtld_fail;143static pthread_rwlock_t lock;144static struct debug debug;145static struct tls_module *tls_tail;146static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;147static size_t static_tls_cnt;148static pthread_mutex_t init_fini_lock;149static pthread_cond_t ctor_cond;150static struct dso *builtin_deps[2];151static struct dso *const no_deps[1];152static struct dso *builtin_ctor_queue[4];153static struct dso **main_ctor_queue;154static struct fdpic_loadmap *app_loadmap;155static struct fdpic_dummy_loadmap app_dummy_loadmap;156157struct debug *_dl_debug_addr = &debug;158159extern weak hidden char __ehdr_start[];160161extern hidden int __malloc_replaced;162163hidden void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;164165extern hidden void (*const __init_array_end)(void), (*const __fini_array_end)(void);166167weak_alias(__init_array_start, __init_array_end);168weak_alias(__fini_array_start, __fini_array_end);169170static int dl_strcmp(const char *l, const char *r)171{172for (; *l==*r && *l; l++, r++);173return *(unsigned char *)l - *(unsigned char *)r;174}175#define strcmp(l,r) dl_strcmp(l,r)176177/* Compute load address for a virtual address in a given dso. */178#if DL_FDPIC179static void *laddr(const struct dso *p, size_t v)180{181size_t j=0;182if (!p->loadmap) return p->base + v;183for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++);184return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);185}186static void *laddr_pg(const struct dso *p, size_t v)187{188size_t j=0;189size_t pgsz = PAGE_SIZE;190if (!p->loadmap) return p->base + v;191for (j=0; ; j++) {192size_t a = p->loadmap->segs[j].p_vaddr;193size_t b = a + p->loadmap->segs[j].p_memsz;194a &= -pgsz;195b += pgsz-1;196b &= -pgsz;197if (v-a<b-a) break;198}199return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);200}201static void (*fdbarrier(void *p))()202{203void (*fd)();204__asm__("" : "=r"(fd) : "0"(p));205return fd;206}207#define fpaddr(p, v) fdbarrier((&(struct funcdesc){ \208laddr(p, v), (p)->got }))209#else210#define laddr(p, v) (void *)((p)->base + (v))211#define laddr_pg(p, v) laddr(p, v)212#define fpaddr(p, v) ((void (*)())laddr(p, v))213#endif214215static void decode_vec(size_t *v, size_t *a, size_t cnt)216{217size_t i;218for (i=0; i<cnt; i++) a[i] = 0;219for (; v[0]; v+=2) if (v[0]-1<cnt-1) {220if (v[0] < 8*sizeof(long))221a[0] |= 1UL<<v[0];222a[v[0]] = v[1];223}224}225226static int search_vec(size_t *v, size_t *r, size_t key)227{228for (; v[0]!=key; v+=2)229if (!v[0]) return 0;230*r = v[1];231return 1;232}233234static uint32_t sysv_hash(const char *s0)235{236const unsigned char *s = (void *)s0;237uint_fast32_t h = 0;238while (*s) {239h = 16*h + *s++;240h ^= h>>24 & 0xf0;241}242return h & 0xfffffff;243}244245static uint32_t gnu_hash(const char *s0)246{247const unsigned char *s = (void *)s0;248uint_fast32_t h = 5381;249for (; *s; s++)250h += h*32 + *s;251return h;252}253254static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)255{256size_t i;257Sym *syms = dso->syms;258Elf_Symndx *hashtab = dso->hashtab;259char *strings = dso->strings;260for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {261if ((!dso->versym || dso->versym[i] >= 0)262&& (!strcmp(s, strings+syms[i].st_name)))263return syms+i;264}265return 0;266}267268static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s)269{270uint32_t nbuckets = hashtab[0];271uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);272uint32_t i = buckets[h1 % nbuckets];273274if (!i) return 0;275276uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);277278for (h1 |= 1; ; i++) {279uint32_t h2 = *hashval++;280if ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0)281&& !strcmp(s, dso->strings + dso->syms[i].st_name))282return dso->syms+i;283if (h2 & 1) break;284}285286return 0;287}288289static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask)290{291const size_t *bloomwords = (const void *)(hashtab+4);292size_t f = bloomwords[fofs & (hashtab[2]-1)];293if (!(f & fmask)) return 0;294295f >>= (h1 >> hashtab[3]) % (8 * sizeof f);296if (!(f & 1)) return 0;297298return gnu_lookup(h1, hashtab, dso, s);299}300301#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)302#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)303304#ifndef ARCH_SYM_REJECT_UND305#define ARCH_SYM_REJECT_UND(s) 0306#endif307308#if defined(__GNUC__)309__attribute__((always_inline))310#endif311static inline struct symdef find_sym2(struct dso *dso, const char *s, int need_def, int use_deps)312{313uint32_t h = 0, gh = gnu_hash(s), gho = gh / (8*sizeof(size_t)), *ght;314size_t ghm = 1ul << gh % (8*sizeof(size_t));315struct symdef def = {0};316struct dso **deps = use_deps ? dso->deps : 0;317for (; dso; dso=use_deps ? *deps++ : dso->syms_next) {318Sym *sym;319if ((ght = dso->ghashtab)) {320sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm);321} else {322if (!h) h = sysv_hash(s);323sym = sysv_lookup(s, h, dso);324}325if (!sym) continue;326if (!sym->st_shndx)327if (need_def || (sym->st_info&0xf) == STT_TLS328|| ARCH_SYM_REJECT_UND(sym))329continue;330if (!sym->st_value)331if ((sym->st_info&0xf) != STT_TLS)332continue;333if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;334if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;335def.sym = sym;336def.dso = dso;337break;338}339return def;340}341342static struct symdef find_sym(struct dso *dso, const char *s, int need_def)343{344return find_sym2(dso, s, need_def, 0);345}346347static struct symdef get_lfs64(const char *name)348{349const char *p;350static const char lfs64_list[] =351"aio_cancel\0aio_error\0aio_fsync\0aio_read\0aio_return\0"352"aio_suspend\0aio_write\0alphasort\0creat\0fallocate\0"353"fgetpos\0fopen\0freopen\0fseeko\0fsetpos\0fstat\0"354"fstatat\0fstatfs\0fstatvfs\0ftello\0ftruncate\0ftw\0"355"getdents\0getrlimit\0glob\0globfree\0lio_listio\0"356"lockf\0lseek\0lstat\0mkostemp\0mkostemps\0mkstemp\0"357"mkstemps\0mmap\0nftw\0open\0openat\0posix_fadvise\0"358"posix_fallocate\0pread\0preadv\0prlimit\0pwrite\0"359"pwritev\0readdir\0scandir\0sendfile\0setrlimit\0"360"stat\0statfs\0statvfs\0tmpfile\0truncate\0versionsort\0"361"__fxstat\0__fxstatat\0__lxstat\0__xstat\0";362size_t l;363char buf[16];364for (l=0; name[l]; l++) {365if (l >= sizeof buf) goto nomatch;366buf[l] = name[l];367}368if (!strcmp(name, "readdir64_r"))369return find_sym(&ldso, "readdir_r", 1);370if (l<2 || name[l-2]!='6' || name[l-1]!='4')371goto nomatch;372buf[l-=2] = 0;373for (p=lfs64_list; *p; p++) {374if (!strcmp(buf, p)) return find_sym(&ldso, buf, 1);375while (*p) p++;376}377nomatch:378return (struct symdef){ 0 };379}380381static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)382{383unsigned char *base = dso->base;384Sym *syms = dso->syms;385char *strings = dso->strings;386Sym *sym;387const char *name;388void *ctx;389int type;390int sym_index;391struct symdef def;392size_t *reloc_addr;393size_t sym_val;394size_t tls_val;395size_t addend;396int skip_relative = 0, reuse_addends = 0, save_slot = 0;397398if (dso == &ldso) {399/* Only ldso's REL table needs addend saving/reuse. */400if (rel == apply_addends_to)401reuse_addends = 1;402skip_relative = 1;403}404405for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {406if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;407type = R_TYPE(rel[1]);408if (type == REL_NONE) continue;409reloc_addr = laddr(dso, rel[0]);410411if (stride > 2) {412addend = rel[2];413} else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {414addend = 0;415} else if (reuse_addends) {416/* Save original addend in stage 2 where the dso417* chain consists of just ldso; otherwise read back418* saved addend since the inline one was clobbered. */419if (head==&ldso)420saved_addends[save_slot] = *reloc_addr;421addend = saved_addends[save_slot++];422} else {423addend = *reloc_addr;424}425426sym_index = R_SYM(rel[1]);427if (sym_index) {428sym = syms + sym_index;429name = strings + sym->st_name;430ctx = type==REL_COPY ? head->syms_next : head;431def = (sym->st_info>>4) == STB_LOCAL432? (struct symdef){ .dso = dso, .sym = sym }433: find_sym(ctx, name, type==REL_PLT);434if (!def.sym) def = get_lfs64(name);435if (!def.sym && (sym->st_shndx != SHN_UNDEF436|| sym->st_info>>4 != STB_WEAK)) {437if (dso->lazy && (type==REL_PLT || type==REL_GOT)) {438dso->lazy[3*dso->lazy_cnt+0] = rel[0];439dso->lazy[3*dso->lazy_cnt+1] = rel[1];440dso->lazy[3*dso->lazy_cnt+2] = addend;441dso->lazy_cnt++;442continue;443}444error("Error relocating %s: %s: symbol not found",445dso->name, name);446if (runtime) longjmp(*rtld_fail, 1);447continue;448}449} else {450sym = 0;451def.sym = 0;452def.dso = dso;453}454455sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0;456tls_val = def.sym ? def.sym->st_value : 0;457458if ((type == REL_TPOFF || type == REL_TPOFF_NEG)459&& def.dso->tls_id > static_tls_cnt) {460error("Error relocating %s: %s: initial-exec TLS "461"resolves to dynamic definition in %s",462dso->name, name, def.dso->name);463longjmp(*rtld_fail, 1);464}465466switch(type) {467case REL_OFFSET:468addend -= (size_t)reloc_addr;469case REL_SYMBOLIC:470case REL_GOT:471case REL_PLT:472*reloc_addr = sym_val + addend;473break;474case REL_USYMBOLIC:475memcpy(reloc_addr, &(size_t){sym_val + addend}, sizeof(size_t));476break;477case REL_RELATIVE:478*reloc_addr = (size_t)base + addend;479break;480case REL_SYM_OR_REL:481if (sym) *reloc_addr = sym_val + addend;482else *reloc_addr = (size_t)base + addend;483break;484case REL_COPY:485memcpy(reloc_addr, (void *)sym_val, sym->st_size);486break;487case REL_OFFSET32:488*(uint32_t *)reloc_addr = sym_val + addend489- (size_t)reloc_addr;490break;491case REL_FUNCDESC:492*reloc_addr = def.sym ? (size_t)(def.dso->funcdescs493+ (def.sym - def.dso->syms)) : 0;494break;495case REL_FUNCDESC_VAL:496if ((sym->st_info&0xf) == STT_SECTION) *reloc_addr += sym_val;497else *reloc_addr = sym_val;498reloc_addr[1] = def.sym ? (size_t)def.dso->got : 0;499break;500case REL_DTPMOD:501*reloc_addr = def.dso->tls_id;502break;503case REL_DTPOFF:504*reloc_addr = tls_val + addend - DTP_OFFSET;505break;506#ifdef TLS_ABOVE_TP507case REL_TPOFF:508*reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend;509break;510#else511case REL_TPOFF:512*reloc_addr = tls_val - def.dso->tls.offset + addend;513break;514case REL_TPOFF_NEG:515*reloc_addr = def.dso->tls.offset - tls_val + addend;516break;517#endif518case REL_TLSDESC:519if (stride<3) addend = reloc_addr[!TLSDESC_BACKWARDS];520if (def.dso->tls_id > static_tls_cnt) {521struct td_index *new = malloc(sizeof *new);522if (!new) {523error(524"Error relocating %s: cannot allocate TLSDESC for %s",525dso->name, sym ? name : "(local)" );526longjmp(*rtld_fail, 1);527}528new->next = dso->td_index;529dso->td_index = new;530new->args[0] = def.dso->tls_id;531new->args[1] = tls_val + addend - DTP_OFFSET;532reloc_addr[0] = (size_t)__tlsdesc_dynamic;533reloc_addr[1] = (size_t)new;534} else {535reloc_addr[0] = (size_t)__tlsdesc_static;536#ifdef TLS_ABOVE_TP537reloc_addr[1] = tls_val + def.dso->tls.offset538+ TPOFF_K + addend;539#else540reloc_addr[1] = tls_val - def.dso->tls.offset541+ addend;542#endif543}544/* Some archs (32-bit ARM at least) invert the order of545* the descriptor members. Fix them up here. */546if (TLSDESC_BACKWARDS) {547size_t tmp = reloc_addr[0];548reloc_addr[0] = reloc_addr[1];549reloc_addr[1] = tmp;550}551break;552default:553error("Error relocating %s: unsupported relocation type %d",554dso->name, type);555if (runtime) longjmp(*rtld_fail, 1);556continue;557}558}559}560561static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size)562{563if (dso == &ldso) return; /* self-relocation was done in _dlstart */564unsigned char *base = dso->base;565size_t *reloc_addr;566for (; relr_size; relr++, relr_size-=sizeof(size_t))567if ((relr[0]&1) == 0) {568reloc_addr = laddr(dso, relr[0]);569*reloc_addr++ += (size_t)base;570} else {571int i = 0;572for (size_t bitmap=relr[0]; (bitmap>>=1); i++)573if (bitmap&1)574reloc_addr[i] += (size_t)base;575reloc_addr += 8*sizeof(size_t)-1;576}577}578579static void redo_lazy_relocs()580{581struct dso *p = lazy_head, *next;582lazy_head = 0;583for (; p; p=next) {584next = p->lazy_next;585size_t size = p->lazy_cnt*3*sizeof(size_t);586p->lazy_cnt = 0;587do_relocs(p, p->lazy, size, 3);588if (p->lazy_cnt) {589p->lazy_next = lazy_head;590lazy_head = p;591} else {592free(p->lazy);593p->lazy = 0;594p->lazy_next = 0;595}596}597}598599/* A huge hack: to make up for the wastefulness of shared libraries600* needing at least a page of dirty memory even if they have no global601* data, we reclaim the gaps at the beginning and end of writable maps602* and "donate" them to the heap. */603604static void reclaim(struct dso *dso, size_t start, size_t end)605{606if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end;607if (end >= dso->relro_start && end < dso->relro_end) end = dso->relro_start;608if (start >= end) return;609char *base = laddr_pg(dso, start);610__malloc_donate(base, base+(end-start));611}612613static void reclaim_gaps(struct dso *dso)614{615Phdr *ph = dso->phdr;616size_t phcnt = dso->phnum;617618for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) {619if (ph->p_type!=PT_LOAD) continue;620if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;621reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);622reclaim(dso, ph->p_vaddr+ph->p_memsz,623ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);624}625}626627static ssize_t read_loop(int fd, void *p, size_t n)628{629for (size_t i=0; i<n; ) {630ssize_t l = read(fd, (char *)p+i, n-i);631if (l<0) {632if (errno==EINTR) continue;633else return -1;634}635if (l==0) return i;636i += l;637}638return n;639}640641static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)642{643static int no_map_fixed;644char *q;645if (!n) return p;646if (!no_map_fixed) {647q = mmap(p, n, prot, flags|MAP_FIXED, fd, off);648if (!DL_NOMMU_SUPPORT || q != MAP_FAILED || errno != EINVAL)649return q;650no_map_fixed = 1;651}652/* Fallbacks for MAP_FIXED failure on NOMMU kernels. */653if (flags & MAP_ANONYMOUS) {654memset(p, 0, n);655return p;656}657ssize_t r;658if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;659for (q=p; n; q+=r, off+=r, n-=r) {660r = read(fd, q, n);661if (r < 0 && errno != EINTR) return MAP_FAILED;662if (!r) {663memset(q, 0, n);664break;665}666}667return p;668}669670static void unmap_library(struct dso *dso)671{672if (dso->loadmap) {673size_t i;674for (i=0; i<dso->loadmap->nsegs; i++) {675if (!dso->loadmap->segs[i].p_memsz)676continue;677munmap((void *)dso->loadmap->segs[i].addr,678dso->loadmap->segs[i].p_memsz);679}680free(dso->loadmap);681} else if (dso->map && dso->map_len) {682munmap(dso->map, dso->map_len);683}684}685686static void *map_library(int fd, struct dso *dso)687{688Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];689void *allocated_buf=0;690size_t phsize;691size_t addr_min=SIZE_MAX, addr_max=0, map_len;692size_t this_min, this_max;693size_t nsegs = 0;694off_t off_start;695Ehdr *eh;696Phdr *ph, *ph0;697unsigned prot;698unsigned char *map=MAP_FAILED, *base;699size_t dyn=0;700size_t tls_image=0;701size_t i;702703ssize_t l = read(fd, buf, sizeof buf);704eh = buf;705if (l<0) return 0;706if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))707goto noexec;708phsize = eh->e_phentsize * eh->e_phnum;709if (phsize > sizeof buf - sizeof *eh) {710allocated_buf = malloc(phsize);711if (!allocated_buf) return 0;712l = pread(fd, allocated_buf, phsize, eh->e_phoff);713if (l < 0) goto error;714if (l != phsize) goto noexec;715ph = ph0 = allocated_buf;716} else if (eh->e_phoff + phsize > l) {717l = pread(fd, buf+1, phsize, eh->e_phoff);718if (l < 0) goto error;719if (l != phsize) goto noexec;720ph = ph0 = (void *)(buf + 1);721} else {722ph = ph0 = (void *)((char *)buf + eh->e_phoff);723}724for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {725if (ph->p_type == PT_DYNAMIC) {726dyn = ph->p_vaddr;727} else if (ph->p_type == PT_TLS) {728tls_image = ph->p_vaddr;729dso->tls.align = ph->p_align;730dso->tls.len = ph->p_filesz;731dso->tls.size = ph->p_memsz;732} else if (ph->p_type == PT_GNU_RELRO) {733dso->relro_start = ph->p_vaddr & -PAGE_SIZE;734dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;735} else if (ph->p_type == PT_GNU_STACK) {736if (!runtime && ph->p_memsz > __default_stacksize) {737__default_stacksize =738ph->p_memsz < DEFAULT_STACK_MAX ?739ph->p_memsz : DEFAULT_STACK_MAX;740}741}742if (ph->p_type != PT_LOAD) continue;743nsegs++;744if (ph->p_vaddr < addr_min) {745addr_min = ph->p_vaddr;746off_start = ph->p_offset;747prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |748((ph->p_flags&PF_W) ? PROT_WRITE: 0) |749((ph->p_flags&PF_X) ? PROT_EXEC : 0));750}751if (ph->p_vaddr+ph->p_memsz > addr_max) {752addr_max = ph->p_vaddr+ph->p_memsz;753}754}755if (!dyn) goto noexec;756if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) {757dso->loadmap = calloc(1, sizeof *dso->loadmap758+ nsegs * sizeof *dso->loadmap->segs);759if (!dso->loadmap) goto error;760dso->loadmap->nsegs = nsegs;761for (ph=ph0, i=0; i<nsegs; ph=(void *)((char *)ph+eh->e_phentsize)) {762if (ph->p_type != PT_LOAD) continue;763prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |764((ph->p_flags&PF_W) ? PROT_WRITE: 0) |765((ph->p_flags&PF_X) ? PROT_EXEC : 0));766map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),767prot, MAP_PRIVATE,768fd, ph->p_offset & -PAGE_SIZE);769if (map == MAP_FAILED) {770unmap_library(dso);771goto error;772}773dso->loadmap->segs[i].addr = (size_t)map +774(ph->p_vaddr & PAGE_SIZE-1);775dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;776dso->loadmap->segs[i].p_memsz = ph->p_memsz;777i++;778if (prot & PROT_WRITE) {779size_t brk = (ph->p_vaddr & PAGE_SIZE-1)780+ ph->p_filesz;781size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE;782size_t pgend = brk + ph->p_memsz - ph->p_filesz783+ PAGE_SIZE-1 & -PAGE_SIZE;784if (pgend > pgbrk && mmap_fixed(map+pgbrk,785pgend-pgbrk, prot,786MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,787-1, off_start) == MAP_FAILED)788goto error;789memset(map + brk, 0, pgbrk-brk);790}791}792map = (void *)dso->loadmap->segs[0].addr;793map_len = 0;794goto done_mapping;795}796addr_max += PAGE_SIZE-1;797addr_max &= -PAGE_SIZE;798addr_min &= -PAGE_SIZE;799off_start &= -PAGE_SIZE;800map_len = addr_max - addr_min + off_start;801/* The first time, we map too much, possibly even more than802* the length of the file. This is okay because we will not803* use the invalid part; we just need to reserve the right804* amount of virtual address space to map over later. */805map = DL_NOMMU_SUPPORT806? mmap((void *)addr_min, map_len, PROT_READ|PROT_WRITE|PROT_EXEC,807MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)808: mmap((void *)addr_min, map_len, prot,809MAP_PRIVATE, fd, off_start);810if (map==MAP_FAILED) goto error;811dso->map = map;812dso->map_len = map_len;813/* If the loaded file is not relocatable and the requested address is814* not available, then the load operation must fail. */815if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) {816errno = EBUSY;817goto error;818}819base = map - addr_min;820dso->phdr = 0;821dso->phnum = 0;822for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {823if (ph->p_type != PT_LOAD) continue;824/* Check if the programs headers are in this load segment, and825* if so, record the address for use by dl_iterate_phdr. */826if (!dso->phdr && eh->e_phoff >= ph->p_offset827&& eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) {828dso->phdr = (void *)(base + ph->p_vaddr829+ (eh->e_phoff-ph->p_offset));830dso->phnum = eh->e_phnum;831dso->phentsize = eh->e_phentsize;832}833this_min = ph->p_vaddr & -PAGE_SIZE;834this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;835off_start = ph->p_offset & -PAGE_SIZE;836prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |837((ph->p_flags&PF_W) ? PROT_WRITE: 0) |838((ph->p_flags&PF_X) ? PROT_EXEC : 0));839/* Reuse the existing mapping for the lowest-address LOAD */840if ((ph->p_vaddr & -PAGE_SIZE) != addr_min || DL_NOMMU_SUPPORT)841if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)842goto error;843if (ph->p_memsz > ph->p_filesz && (ph->p_flags&PF_W)) {844size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;845size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;846memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);847if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)848goto error;849}850}851for (i=0; ((size_t *)(base+dyn))[i]; i+=2)852if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {853if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)854&& errno != ENOSYS)855goto error;856break;857}858done_mapping:859dso->base = base;860dso->dynv = laddr(dso, dyn);861if (dso->tls.size) dso->tls.image = laddr(dso, tls_image);862free(allocated_buf);863return map;864noexec:865errno = ENOEXEC;866error:867if (map!=MAP_FAILED) unmap_library(dso);868free(allocated_buf);869return 0;870}871872static int path_open(const char *name, const char *s, char *buf, size_t buf_size)873{874size_t l;875int fd;876for (;;) {877s += strspn(s, ":\n");878l = strcspn(s, ":\n");879if (l-1 >= INT_MAX) return -1;880if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {881if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;882switch (errno) {883case ENOENT:884case ENOTDIR:885case EACCES:886case ENAMETOOLONG:887break;888default:889/* Any negative value but -1 will inhibit890* futher path search. */891return -2;892}893}894s += l;895}896}897898static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)899{900size_t n, l;901const char *s, *t, *origin;902char *d;903if (p->rpath || !p->rpath_orig) return 0;904if (!strchr(p->rpath_orig, '$')) {905p->rpath = p->rpath_orig;906return 0;907}908n = 0;909s = p->rpath_orig;910while ((t=strchr(s, '$'))) {911if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))912return 0;913s = t+1;914n++;915}916if (n > SSIZE_MAX/PATH_MAX) return 0;917918if (p->kernel_mapped) {919/* $ORIGIN searches cannot be performed for the main program920* when it is suid/sgid/AT_SECURE. This is because the921* pathname is under the control of the caller of execve.922* For libraries, however, $ORIGIN can be processed safely923* since the library's pathname came from a trusted source924* (either system paths or a call to dlopen). */925if (libc.secure)926return 0;927l = readlink("/proc/self/exe", buf, buf_size);928if (l == -1) switch (errno) {929case ENOENT:930case ENOTDIR:931case EACCES:932return 0;933default:934return -1;935}936if (l >= buf_size)937return 0;938buf[l] = 0;939origin = buf;940} else {941origin = p->name;942}943t = strrchr(origin, '/');944if (t) {945l = t-origin;946} else {947/* Normally p->name will always be an absolute or relative948* pathname containing at least one '/' character, but in the949* case where ldso was invoked as a command to execute a950* program in the working directory, app.name may not. Fix. */951origin = ".";952l = 1;953}954/* Disallow non-absolute origins for suid/sgid/AT_SECURE. */955if (libc.secure && *origin != '/')956return 0;957p->rpath = malloc(strlen(p->rpath_orig) + n*l + 1);958if (!p->rpath) return -1;959960d = p->rpath;961s = p->rpath_orig;962while ((t=strchr(s, '$'))) {963memcpy(d, s, t-s);964d += t-s;965memcpy(d, origin, l);966d += l;967/* It was determined previously that the '$' is followed968* either by "ORIGIN" or "{ORIGIN}". */969s = t + 7 + 2*(t[1]=='{');970}971strcpy(d, s);972return 0;973}974975static void decode_dyn(struct dso *p)976{977size_t dyn[DYN_CNT];978decode_vec(p->dynv, dyn, DYN_CNT);979p->syms = laddr(p, dyn[DT_SYMTAB]);980p->strings = laddr(p, dyn[DT_STRTAB]);981if (dyn[0]&(1<<DT_HASH))982p->hashtab = laddr(p, dyn[DT_HASH]);983if (dyn[0]&(1<<DT_RPATH))984p->rpath_orig = p->strings + dyn[DT_RPATH];985if (dyn[0]&(1<<DT_RUNPATH))986p->rpath_orig = p->strings + dyn[DT_RUNPATH];987if (dyn[0]&(1<<DT_PLTGOT))988p->got = laddr(p, dyn[DT_PLTGOT]);989if (search_vec(p->dynv, dyn, DT_GNU_HASH))990p->ghashtab = laddr(p, *dyn);991if (search_vec(p->dynv, dyn, DT_VERSYM))992p->versym = laddr(p, *dyn);993}994995static size_t count_syms(struct dso *p)996{997if (p->hashtab) return p->hashtab[1];998999size_t nsym, i;1000uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);1001uint32_t *hashval;1002for (i = nsym = 0; i < p->ghashtab[0]; i++) {1003if (buckets[i] > nsym)1004nsym = buckets[i];1005}1006if (nsym) {1007hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]);1008do nsym++;1009while (!(*hashval++ & 1));1010}1011return nsym;1012}10131014static void *dl_mmap(size_t n)1015{1016void *p;1017int prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE;1018#ifdef SYS_mmap21019p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0);1020#else1021p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0);1022#endif1023return (unsigned long)p > -4096UL ? 0 : p;1024}10251026static void makefuncdescs(struct dso *p)1027{1028static int self_done;1029size_t nsym = count_syms(p);1030size_t i, size = nsym * sizeof(*p->funcdescs);10311032if (!self_done) {1033p->funcdescs = dl_mmap(size);1034self_done = 1;1035} else {1036p->funcdescs = malloc(size);1037}1038if (!p->funcdescs) {1039if (!runtime) a_crash();1040error("Error allocating function descriptors for %s", p->name);1041longjmp(*rtld_fail, 1);1042}1043for (i=0; i<nsym; i++) {1044if ((p->syms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) {1045p->funcdescs[i].addr = laddr(p, p->syms[i].st_value);1046p->funcdescs[i].got = p->got;1047} else {1048p->funcdescs[i].addr = 0;1049p->funcdescs[i].got = 0;1050}1051}1052}10531054static struct dso *load_library(const char *name, struct dso *needed_by)1055{1056char buf[2*NAME_MAX+2];1057const char *pathname;1058unsigned char *map;1059struct dso *p, temp_dso = {0};1060int fd;1061struct stat st;1062size_t alloc_size;1063int n_th = 0;1064int is_self = 0;10651066if (!*name) {1067errno = EINVAL;1068return 0;1069}10701071/* Catch and block attempts to reload the implementation itself */1072if (name[0]=='l' && name[1]=='i' && name[2]=='b') {1073static const char reserved[] =1074"c.pthread.rt.m.dl.util.xnet.";1075const char *rp, *next;1076for (rp=reserved; *rp; rp=next) {1077next = strchr(rp, '.') + 1;1078if (strncmp(name+3, rp, next-rp) == 0)1079break;1080}1081if (*rp) {1082if (ldd_mode) {1083/* Track which names have been resolved1084* and only report each one once. */1085static unsigned reported;1086unsigned mask = 1U<<(rp-reserved);1087if (!(reported & mask)) {1088reported |= mask;1089dprintf(1, "\t%s => %s (%p)\n",1090name, ldso.name,1091ldso.base);1092}1093}1094is_self = 1;1095}1096}1097if (!strcmp(name, ldso.name)) is_self = 1;1098if (is_self) {1099if (!ldso.prev) {1100tail->next = &ldso;1101ldso.prev = tail;1102tail = &ldso;1103}1104return &ldso;1105}1106if (strchr(name, '/')) {1107pathname = name;1108fd = open(name, O_RDONLY|O_CLOEXEC);1109} else {1110/* Search for the name to see if it's already loaded */1111for (p=head->next; p; p=p->next) {1112if (p->shortname && !strcmp(p->shortname, name)) {1113return p;1114}1115}1116if (strlen(name) > NAME_MAX) return 0;1117fd = -1;1118if (env_path) fd = path_open(name, env_path, buf, sizeof buf);1119for (p=needed_by; fd == -1 && p; p=p->needed_by) {1120if (fixup_rpath(p, buf, sizeof buf) < 0)1121fd = -2; /* Inhibit further search. */1122if (p->rpath)1123fd = path_open(name, p->rpath, buf, sizeof buf);1124}1125if (fd == -1) {1126if (!sys_path) {1127char *prefix = 0;1128size_t prefix_len;1129if (ldso.name[0]=='/') {1130char *s, *t, *z;1131for (s=t=z=ldso.name; *s; s++)1132if (*s=='/') z=t, t=s;1133prefix_len = z-ldso.name;1134if (prefix_len < PATH_MAX)1135prefix = ldso.name;1136}1137if (!prefix) {1138prefix = "";1139prefix_len = 0;1140}1141char etc_ldso_path[prefix_len + 11142+ sizeof "/etc/ld-musl-" LDSO_ARCH ".path"];1143snprintf(etc_ldso_path, sizeof etc_ldso_path,1144"%.*s/etc/ld-musl-" LDSO_ARCH ".path",1145(int)prefix_len, prefix);1146fd = open(etc_ldso_path, O_RDONLY|O_CLOEXEC);1147if (fd>=0) {1148size_t n = 0;1149if (!fstat(fd, &st)) n = st.st_size;1150if ((sys_path = malloc(n+1)))1151sys_path[n] = 0;1152if (!sys_path || read_loop(fd, sys_path, n)<0) {1153free(sys_path);1154sys_path = "";1155}1156close(fd);1157} else if (errno != ENOENT) {1158sys_path = "";1159}1160}1161if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";1162fd = path_open(name, sys_path, buf, sizeof buf);1163}1164pathname = buf;1165}1166if (fd < 0) return 0;1167if (fstat(fd, &st) < 0) {1168close(fd);1169return 0;1170}1171for (p=head->next; p; p=p->next) {1172if (p->dev == st.st_dev && p->ino == st.st_ino) {1173/* If this library was previously loaded with a1174* pathname but a search found the same inode,1175* setup its shortname so it can be found by name. */1176if (!p->shortname && pathname != name)1177p->shortname = strrchr(p->name, '/')+1;1178close(fd);1179return p;1180}1181}1182map = noload ? 0 : map_library(fd, &temp_dso);1183close(fd);1184if (!map) return 0;11851186/* Avoid the danger of getting two versions of libc mapped into the1187* same process when an absolute pathname was used. The symbols1188* checked are chosen to catch both musl and glibc, and to avoid1189* false positives from interposition-hack libraries. */1190decode_dyn(&temp_dso);1191if (find_sym(&temp_dso, "__libc_start_main", 1).sym &&1192find_sym(&temp_dso, "stdin", 1).sym) {1193unmap_library(&temp_dso);1194return load_library("libc.so", needed_by);1195}1196/* Past this point, if we haven't reached runtime yet, ldso has1197* committed either to use the mapped library or to abort execution.1198* Unmapping is not possible, so we can safely reclaim gaps. */1199if (!runtime) reclaim_gaps(&temp_dso);12001201/* Allocate storage for the new DSO. When there is TLS, this1202* storage must include a reservation for all pre-existing1203* threads to obtain copies of both the new TLS, and an1204* extended DTV capable of storing an additional slot for1205* the newly-loaded DSO. */1206alloc_size = sizeof *p + strlen(pathname) + 1;1207if (runtime && temp_dso.tls.image) {1208size_t per_th = temp_dso.tls.size + temp_dso.tls.align1209+ sizeof(void *) * (tls_cnt+3);1210n_th = libc.threads_minus_1 + 1;1211if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;1212else alloc_size += n_th * per_th;1213}1214p = calloc(1, alloc_size);1215if (!p) {1216unmap_library(&temp_dso);1217return 0;1218}1219memcpy(p, &temp_dso, sizeof temp_dso);1220p->dev = st.st_dev;1221p->ino = st.st_ino;1222p->needed_by = needed_by;1223p->name = p->buf;1224p->runtime_loaded = runtime;1225strcpy(p->name, pathname);1226/* Add a shortname only if name arg was not an explicit pathname. */1227if (pathname != name) p->shortname = strrchr(p->name, '/')+1;1228if (p->tls.image) {1229p->tls_id = ++tls_cnt;1230tls_align = MAXP2(tls_align, p->tls.align);1231#ifdef TLS_ABOVE_TP1232p->tls.offset = tls_offset + ( (p->tls.align-1) &1233(-tls_offset + (uintptr_t)p->tls.image) );1234tls_offset = p->tls.offset + p->tls.size;1235#else1236tls_offset += p->tls.size + p->tls.align - 1;1237tls_offset -= (tls_offset + (uintptr_t)p->tls.image)1238& (p->tls.align-1);1239p->tls.offset = tls_offset;1240#endif1241p->new_dtv = (void *)(-sizeof(size_t) &1242(uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));1243p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));1244if (tls_tail) tls_tail->next = &p->tls;1245else libc.tls_head = &p->tls;1246tls_tail = &p->tls;1247}12481249tail->next = p;1250p->prev = tail;1251tail = p;12521253if (DL_FDPIC) makefuncdescs(p);12541255if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);12561257return p;1258}12591260static void load_direct_deps(struct dso *p)1261{1262size_t i, cnt=0;12631264if (p->deps) return;1265/* For head, all preloads are direct pseudo-dependencies.1266* Count and include them now to avoid realloc later. */1267if (p==head) for (struct dso *q=p->next; q; q=q->next)1268cnt++;1269for (i=0; p->dynv[i]; i+=2)1270if (p->dynv[i] == DT_NEEDED) cnt++;1271/* Use builtin buffer for apps with no external deps, to1272* preserve property of no runtime failure paths. */1273p->deps = (p==head && cnt<2) ? builtin_deps :1274calloc(cnt+1, sizeof *p->deps);1275if (!p->deps) {1276error("Error loading dependencies for %s", p->name);1277if (runtime) longjmp(*rtld_fail, 1);1278}1279cnt=0;1280if (p==head) for (struct dso *q=p->next; q; q=q->next)1281p->deps[cnt++] = q;1282for (i=0; p->dynv[i]; i+=2) {1283if (p->dynv[i] != DT_NEEDED) continue;1284struct dso *dep = load_library(p->strings + p->dynv[i+1], p);1285if (!dep) {1286error("Error loading shared library %s: %m (needed by %s)",1287p->strings + p->dynv[i+1], p->name);1288if (runtime) longjmp(*rtld_fail, 1);1289continue;1290}1291p->deps[cnt++] = dep;1292}1293p->deps[cnt] = 0;1294p->ndeps_direct = cnt;1295}12961297static void load_deps(struct dso *p)1298{1299if (p->deps) return;1300for (; p; p=p->next)1301load_direct_deps(p);1302}13031304static void extend_bfs_deps(struct dso *p)1305{1306size_t i, j, cnt, ndeps_all;1307struct dso **tmp;13081309/* Can't use realloc if the original p->deps was allocated at1310* program entry and malloc has been replaced, or if it's1311* the builtin non-allocated trivial main program deps array. */1312int no_realloc = (__malloc_replaced && !p->runtime_loaded)1313|| p->deps == builtin_deps;13141315if (p->bfs_built) return;1316ndeps_all = p->ndeps_direct;13171318/* Mark existing (direct) deps so they won't be duplicated. */1319for (i=0; p->deps[i]; i++)1320p->deps[i]->mark = 1;13211322/* For each dependency already in the list, copy its list of direct1323* dependencies to the list, excluding any items already in the1324* list. Note that the list this loop iterates over will grow during1325* the loop, but since duplicates are excluded, growth is bounded. */1326for (i=0; p->deps[i]; i++) {1327struct dso *dep = p->deps[i];1328for (j=cnt=0; j<dep->ndeps_direct; j++)1329if (!dep->deps[j]->mark) cnt++;1330tmp = no_realloc ?1331malloc(sizeof(*tmp) * (ndeps_all+cnt+1)) :1332realloc(p->deps, sizeof(*tmp) * (ndeps_all+cnt+1));1333if (!tmp) {1334error("Error recording dependencies for %s", p->name);1335if (runtime) longjmp(*rtld_fail, 1);1336continue;1337}1338if (no_realloc) {1339memcpy(tmp, p->deps, sizeof(*tmp) * (ndeps_all+1));1340no_realloc = 0;1341}1342p->deps = tmp;1343for (j=0; j<dep->ndeps_direct; j++) {1344if (dep->deps[j]->mark) continue;1345dep->deps[j]->mark = 1;1346p->deps[ndeps_all++] = dep->deps[j];1347}1348p->deps[ndeps_all] = 0;1349}1350p->bfs_built = 1;1351for (p=head; p; p=p->next)1352p->mark = 0;1353}13541355static void load_preload(char *s)1356{1357int tmp;1358char *z;1359for (z=s; *z; s=z) {1360for ( ; *s && (isspace(*s) || *s==':'); s++);1361for (z=s; *z && !isspace(*z) && *z!=':'; z++);1362tmp = *z;1363*z = 0;1364load_library(s, 0);1365*z = tmp;1366}1367}13681369static void add_syms(struct dso *p)1370{1371if (!p->syms_next && syms_tail != p) {1372syms_tail->syms_next = p;1373syms_tail = p;1374}1375}13761377static void revert_syms(struct dso *old_tail)1378{1379struct dso *p, *next;1380/* Chop off the tail of the list of dsos that participate in1381* the global symbol table, reverting them to RTLD_LOCAL. */1382for (p=old_tail; p; p=next) {1383next = p->syms_next;1384p->syms_next = 0;1385}1386syms_tail = old_tail;1387}13881389static void do_mips_relocs(struct dso *p, size_t *got)1390{1391size_t i, j, rel[2];1392unsigned char *base = p->base;1393i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);1394if (p==&ldso) {1395got += i;1396} else {1397while (i--) *got++ += (size_t)base;1398}1399j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);1400i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);1401Sym *sym = p->syms + j;1402rel[0] = (unsigned char *)got - base;1403for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {1404rel[1] = R_INFO(sym-p->syms, R_MIPS_JUMP_SLOT);1405do_relocs(p, rel, sizeof rel, 2);1406}1407}14081409static void reloc_all(struct dso *p)1410{1411size_t dyn[DYN_CNT];1412for (; p; p=p->next) {1413if (p->relocated) continue;1414decode_vec(p->dynv, dyn, DYN_CNT);1415if (NEED_MIPS_GOT_RELOCS)1416do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));1417do_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],14182+(dyn[DT_PLTREL]==DT_RELA));1419do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);1420do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);1421if (!DL_FDPIC)1422do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]);14231424if (head != &ldso && p->relro_start != p->relro_end) {1425long ret = __syscall(SYS_mprotect, laddr(p, p->relro_start),1426p->relro_end-p->relro_start, PROT_READ);1427if (ret != 0 && ret != -ENOSYS) {1428error("Error relocating %s: RELRO protection failed: %m",1429p->name);1430if (runtime) longjmp(*rtld_fail, 1);1431}1432}14331434p->relocated = 1;1435}1436}14371438static void kernel_mapped_dso(struct dso *p)1439{1440size_t min_addr = -1, max_addr = 0, cnt;1441Phdr *ph = p->phdr;1442for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {1443if (ph->p_type == PT_DYNAMIC) {1444p->dynv = laddr(p, ph->p_vaddr);1445} else if (ph->p_type == PT_GNU_RELRO) {1446p->relro_start = ph->p_vaddr & -PAGE_SIZE;1447p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;1448} else if (ph->p_type == PT_GNU_STACK) {1449if (!runtime && ph->p_memsz > __default_stacksize) {1450__default_stacksize =1451ph->p_memsz < DEFAULT_STACK_MAX ?1452ph->p_memsz : DEFAULT_STACK_MAX;1453}1454}1455if (ph->p_type != PT_LOAD) continue;1456if (ph->p_vaddr < min_addr)1457min_addr = ph->p_vaddr;1458if (ph->p_vaddr+ph->p_memsz > max_addr)1459max_addr = ph->p_vaddr+ph->p_memsz;1460}1461min_addr &= -PAGE_SIZE;1462max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;1463p->map = p->base + min_addr;1464p->map_len = max_addr - min_addr;1465p->kernel_mapped = 1;1466}14671468void __libc_exit_fini()1469{1470struct dso *p;1471size_t dyn[DYN_CNT];1472pthread_t self = __pthread_self();14731474/* Take both locks before setting shutting_down, so that1475* either lock is sufficient to read its value. The lock1476* order matches that in dlopen to avoid deadlock. */1477pthread_rwlock_wrlock(&lock);1478pthread_mutex_lock(&init_fini_lock);1479shutting_down = 1;1480pthread_rwlock_unlock(&lock);1481for (p=fini_head; p; p=p->fini_next) {1482while (p->ctor_visitor && p->ctor_visitor!=self)1483pthread_cond_wait(&ctor_cond, &init_fini_lock);1484if (!p->constructed) continue;1485decode_vec(p->dynv, dyn, DYN_CNT);1486if (dyn[0] & (1<<DT_FINI_ARRAY)) {1487size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);1488size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n;1489while (n--) ((void (*)(void))*--fn)();1490}1491#ifndef NO_LEGACY_INITFINI1492if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])1493fpaddr(p, dyn[DT_FINI])();1494#endif1495}1496}14971498void __ldso_atfork(int who)1499{1500if (who<0) {1501pthread_rwlock_wrlock(&lock);1502pthread_mutex_lock(&init_fini_lock);1503} else {1504pthread_mutex_unlock(&init_fini_lock);1505pthread_rwlock_unlock(&lock);1506}1507}15081509static struct dso **queue_ctors(struct dso *dso)1510{1511size_t cnt, qpos, spos, i;1512struct dso *p, **queue, **stack;15131514if (ldd_mode) return 0;15151516/* Bound on queue size is the total number of indirect deps.1517* If a bfs deps list was built, we can use it. Otherwise,1518* bound by the total number of DSOs, which is always safe and1519* is reasonable we use it (for main app at startup). */1520if (dso->bfs_built) {1521for (cnt=0; dso->deps[cnt]; cnt++)1522dso->deps[cnt]->mark = 0;1523cnt++; /* self, not included in deps */1524} else {1525for (cnt=0, p=head; p; cnt++, p=p->next)1526p->mark = 0;1527}1528cnt++; /* termination slot */1529if (dso==head && cnt <= countof(builtin_ctor_queue))1530queue = builtin_ctor_queue;1531else1532queue = calloc(cnt, sizeof *queue);15331534if (!queue) {1535error("Error allocating constructor queue: %m\n");1536if (runtime) longjmp(*rtld_fail, 1);1537return 0;1538}15391540/* Opposite ends of the allocated buffer serve as an output queue1541* and a working stack. Setup initial stack with just the argument1542* dso and initial queue empty... */1543stack = queue;1544qpos = 0;1545spos = cnt;1546stack[--spos] = dso;1547dso->next_dep = 0;1548dso->mark = 1;15491550/* Then perform pseudo-DFS sort, but ignoring circular deps. */1551while (spos<cnt) {1552p = stack[spos++];1553while (p->next_dep < p->ndeps_direct) {1554if (p->deps[p->next_dep]->mark) {1555p->next_dep++;1556} else {1557stack[--spos] = p;1558p = p->deps[p->next_dep];1559p->next_dep = 0;1560p->mark = 1;1561}1562}1563queue[qpos++] = p;1564}1565queue[qpos] = 0;1566for (i=0; i<qpos; i++) queue[i]->mark = 0;1567for (i=0; i<qpos; i++)1568if (queue[i]->ctor_visitor && queue[i]->ctor_visitor->tid < 0) {1569error("State of %s is inconsistent due to multithreaded fork\n",1570queue[i]->name);1571free(queue);1572if (runtime) longjmp(*rtld_fail, 1);1573}15741575return queue;1576}15771578static void do_init_fini(struct dso **queue)1579{1580struct dso *p;1581size_t dyn[DYN_CNT], i;1582pthread_t self = __pthread_self();15831584pthread_mutex_lock(&init_fini_lock);1585for (i=0; (p=queue[i]); i++) {1586while ((p->ctor_visitor && p->ctor_visitor!=self) || shutting_down)1587pthread_cond_wait(&ctor_cond, &init_fini_lock);1588if (p->ctor_visitor || p->constructed)1589continue;1590p->ctor_visitor = self;15911592decode_vec(p->dynv, dyn, DYN_CNT);1593if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {1594p->fini_next = fini_head;1595fini_head = p;1596}15971598pthread_mutex_unlock(&init_fini_lock);15991600#ifndef NO_LEGACY_INITFINI1601if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])1602fpaddr(p, dyn[DT_INIT])();1603#endif1604if (dyn[0] & (1<<DT_INIT_ARRAY)) {1605size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);1606size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]);1607while (n--) ((void (*)(void))*fn++)();1608}16091610pthread_mutex_lock(&init_fini_lock);1611p->ctor_visitor = 0;1612p->constructed = 1;1613pthread_cond_broadcast(&ctor_cond);1614}1615pthread_mutex_unlock(&init_fini_lock);1616}16171618void __libc_start_init(void)1619{1620do_init_fini(main_ctor_queue);1621if (!__malloc_replaced && main_ctor_queue != builtin_ctor_queue)1622free(main_ctor_queue);1623main_ctor_queue = 0;1624}16251626static void dl_debug_state(void)1627{1628}16291630weak_alias(dl_debug_state, _dl_debug_state);16311632void __init_tls(size_t *auxv)1633{1634}16351636static void update_tls_size()1637{1638libc.tls_cnt = tls_cnt;1639libc.tls_align = tls_align;1640libc.tls_size = ALIGN(1641(1+tls_cnt) * sizeof(void *) +1642tls_offset +1643sizeof(struct pthread) +1644tls_align * 2,1645tls_align);1646}16471648static void install_new_tls(void)1649{1650sigset_t set;1651pthread_t self = __pthread_self(), td;1652struct dso *dtv_provider = container_of(tls_tail, struct dso, tls);1653uintptr_t (*newdtv)[tls_cnt+1] = (void *)dtv_provider->new_dtv;1654struct dso *p;1655size_t i, j;1656size_t old_cnt = self->dtv[0];16571658__block_app_sigs(&set);1659__tl_lock();1660/* Copy existing dtv contents from all existing threads. */1661for (i=0, td=self; !i || td!=self; i++, td=td->next) {1662memcpy(newdtv+i, td->dtv,1663(old_cnt+1)*sizeof(uintptr_t));1664newdtv[i][0] = tls_cnt;1665}1666/* Install new dtls into the enlarged, uninstalled dtv copies. */1667for (p=head; ; p=p->next) {1668if (p->tls_id <= old_cnt) continue;1669unsigned char *mem = p->new_tls;1670for (j=0; j<i; j++) {1671unsigned char *new = mem;1672new += ((uintptr_t)p->tls.image - (uintptr_t)mem)1673& (p->tls.align-1);1674memcpy(new, p->tls.image, p->tls.len);1675newdtv[j][p->tls_id] =1676(uintptr_t)new + DTP_OFFSET;1677mem += p->tls.size + p->tls.align;1678}1679if (p->tls_id == tls_cnt) break;1680}16811682/* Broadcast barrier to ensure contents of new dtv is visible1683* if the new dtv pointer is. The __membarrier function has a1684* fallback emulation using signals for kernels that lack the1685* feature at the syscall level. */16861687__membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0);16881689/* Install new dtv for each thread. */1690for (j=0, td=self; !j || td!=self; j++, td=td->next) {1691td->dtv = newdtv[j];1692}16931694__tl_unlock();1695__restore_sigs(&set);1696}16971698/* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the1699* following stage 2 and stage 3 functions via primitive symbolic lookup1700* since it does not have access to their addresses to begin with. */17011702/* Stage 2 of the dynamic linker is called after relative relocations1703* have been processed. It can make function calls to static functions1704* and access string literals and static data, but cannot use extern1705* symbols. Its job is to perform symbolic relocations on the dynamic1706* linker itself, but some of the relocations performed may need to be1707* replaced later due to copy relocations in the main program. */17081709hidden void __dls2(unsigned char *base, size_t *sp)1710{1711size_t *auxv;1712for (auxv=sp+1+*sp+1; *auxv; auxv++);1713auxv++;1714if (DL_FDPIC) {1715void *p1 = (void *)sp[-2];1716void *p2 = (void *)sp[-1];1717if (!p1) {1718size_t aux[AUX_CNT];1719decode_vec(auxv, aux, AUX_CNT);1720if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];1721else ldso.base = (void *)(aux[AT_PHDR] & -4096);1722}1723app_loadmap = p2 ? p1 : 0;1724ldso.loadmap = p2 ? p2 : p1;1725ldso.base = laddr(&ldso, 0);1726} else {1727ldso.base = base;1728}1729Ehdr *ehdr = __ehdr_start ? (void *)__ehdr_start : (void *)ldso.base;1730ldso.name = ldso.shortname = "libc.so";1731ldso.phnum = ehdr->e_phnum;1732ldso.phdr = laddr(&ldso, ehdr->e_phoff);1733ldso.phentsize = ehdr->e_phentsize;1734search_vec(auxv, &ldso_page_size, AT_PAGESZ);1735kernel_mapped_dso(&ldso);1736decode_dyn(&ldso);17371738if (DL_FDPIC) makefuncdescs(&ldso);17391740/* Prepare storage for to save clobbered REL addends so they1741* can be reused in stage 3. There should be very few. If1742* something goes wrong and there are a huge number, abort1743* instead of risking stack overflow. */1744size_t dyn[DYN_CNT];1745decode_vec(ldso.dynv, dyn, DYN_CNT);1746size_t *rel = laddr(&ldso, dyn[DT_REL]);1747size_t rel_size = dyn[DT_RELSZ];1748size_t symbolic_rel_cnt = 0;1749apply_addends_to = rel;1750for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))1751if (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++;1752if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();1753size_t addends[symbolic_rel_cnt+1];1754saved_addends = addends;17551756head = &ldso;1757reloc_all(&ldso);17581759ldso.relocated = 0;17601761/* Call dynamic linker stage-2b, __dls2b, looking it up1762* symbolically as a barrier against moving the address1763* load across the above relocation processing. */1764struct symdef dls2b_def = find_sym(&ldso, "__dls2b", 0);1765if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls2b_def.sym-ldso.syms])(sp, auxv);1766else ((stage3_func)laddr(&ldso, dls2b_def.sym->st_value))(sp, auxv);1767}17681769/* Stage 2b sets up a valid thread pointer, which requires relocations1770* completed in stage 2, and on which stage 3 is permitted to depend.1771* This is done as a separate stage, with symbolic lookup as a barrier,1772* so that loads of the thread pointer and &errno can be pure/const and1773* thereby hoistable. */17741775void __dls2b(size_t *sp, size_t *auxv)1776{1777/* Setup early thread pointer in builtin_tls for ldso/libc itself to1778* use during dynamic linking. If possible it will also serve as the1779* thread pointer at runtime. */1780search_vec(auxv, &__hwcap, AT_HWCAP);1781libc.auxv = auxv;1782libc.tls_size = sizeof builtin_tls;1783libc.tls_align = tls_align;1784if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {1785a_crash();1786}17871788struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);1789if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp, auxv);1790else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp, auxv);1791}17921793/* Stage 3 of the dynamic linker is called with the dynamic linker/libc1794* fully functional. Its job is to load (if not already loaded) and1795* process dependencies and relocations for the main application and1796* transfer control to its entry point. */17971798void __dls3(size_t *sp, size_t *auxv)1799{1800static struct dso app, vdso;1801size_t aux[AUX_CNT];1802size_t i;1803char *env_preload=0;1804char *replace_argv0=0;1805size_t vdso_base;1806int argc = *sp;1807char **argv = (void *)(sp+1);1808char **argv_orig = argv;1809char **envp = argv+argc+1;18101811/* Find aux vector just past environ[] and use it to initialize1812* global data that may be needed before we can make syscalls. */1813__environ = envp;1814decode_vec(auxv, aux, AUX_CNT);1815search_vec(auxv, &__sysinfo, AT_SYSINFO);1816__pthread_self()->sysinfo = __sysinfo;1817libc.page_size = aux[AT_PAGESZ];1818libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]1819|| aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);18201821/* Only trust user/env if kernel says we're not suid/sgid */1822if (!libc.secure) {1823env_path = getenv("LD_LIBRARY_PATH");1824env_preload = getenv("LD_PRELOAD");1825}18261827/* Activate error handler function */1828error = error_impl;18291830/* If the main program was already loaded by the kernel,1831* AT_PHDR will point to some location other than the dynamic1832* linker's program headers. */1833if (aux[AT_PHDR] != (size_t)ldso.phdr) {1834size_t interp_off = 0;1835size_t tls_image = 0;1836/* Find load address of the main program, via AT_PHDR vs PT_PHDR. */1837Phdr *phdr = app.phdr = (void *)aux[AT_PHDR];1838app.phnum = aux[AT_PHNUM];1839app.phentsize = aux[AT_PHENT];1840for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {1841if (phdr->p_type == PT_PHDR)1842app.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);1843else if (phdr->p_type == PT_INTERP)1844interp_off = (size_t)phdr->p_vaddr;1845else if (phdr->p_type == PT_TLS) {1846tls_image = phdr->p_vaddr;1847app.tls.len = phdr->p_filesz;1848app.tls.size = phdr->p_memsz;1849app.tls.align = phdr->p_align;1850}1851}1852if (DL_FDPIC) app.loadmap = app_loadmap;1853if (app.tls.size) app.tls.image = laddr(&app, tls_image);1854if (interp_off) ldso.name = laddr(&app, interp_off);1855if ((aux[0] & (1UL<<AT_EXECFN))1856&& strncmp((char *)aux[AT_EXECFN], "/proc/", 6))1857app.name = (char *)aux[AT_EXECFN];1858else1859app.name = argv[0];1860kernel_mapped_dso(&app);1861} else {1862int fd;1863char *ldname = argv[0];1864size_t l = strlen(ldname);1865if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;1866argv++;1867while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') {1868char *opt = argv[0]+2;1869*argv++ = (void *)-1;1870if (!*opt) {1871break;1872} else if (!memcmp(opt, "list", 5)) {1873ldd_mode = 1;1874} else if (!memcmp(opt, "library-path", 12)) {1875if (opt[12]=='=') env_path = opt+13;1876else if (opt[12]) *argv = 0;1877else if (*argv) env_path = *argv++;1878} else if (!memcmp(opt, "preload", 7)) {1879if (opt[7]=='=') env_preload = opt+8;1880else if (opt[7]) *argv = 0;1881else if (*argv) env_preload = *argv++;1882} else if (!memcmp(opt, "argv0", 5)) {1883if (opt[5]=='=') replace_argv0 = opt+6;1884else if (opt[5]) *argv = 0;1885else if (*argv) replace_argv0 = *argv++;1886} else {1887argv[0] = 0;1888}1889}1890argv[-1] = (void *)(argc - (argv-argv_orig));1891if (!argv[0]) {1892dprintf(2, "musl libc (" LDSO_ARCH ")\n"1893"Version %s\n"1894"Dynamic Program Loader\n"1895"Usage: %s [options] [--] pathname%s\n",1896__libc_version, ldname,1897ldd_mode ? "" : " [args]");1898_exit(1);1899}1900fd = open(argv[0], O_RDONLY);1901if (fd < 0) {1902dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));1903_exit(1);1904}1905Ehdr *ehdr = map_library(fd, &app);1906if (!ehdr) {1907dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);1908_exit(1);1909}1910close(fd);1911ldso.name = ldname;1912app.name = argv[0];1913aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry);1914/* Find the name that would have been used for the dynamic1915* linker had ldd not taken its place. */1916if (ldd_mode) {1917for (i=0; i<app.phnum; i++) {1918if (app.phdr[i].p_type == PT_INTERP)1919ldso.name = laddr(&app, app.phdr[i].p_vaddr);1920}1921dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);1922}1923}1924if (app.tls.size) {1925libc.tls_head = tls_tail = &app.tls;1926app.tls_id = tls_cnt = 1;1927#ifdef TLS_ABOVE_TP1928app.tls.offset = GAP_ABOVE_TP;1929app.tls.offset += (-GAP_ABOVE_TP + (uintptr_t)app.tls.image)1930& (app.tls.align-1);1931tls_offset = app.tls.offset + app.tls.size;1932#else1933tls_offset = app.tls.offset = app.tls.size1934+ ( -((uintptr_t)app.tls.image + app.tls.size)1935& (app.tls.align-1) );1936#endif1937tls_align = MAXP2(tls_align, app.tls.align);1938}1939decode_dyn(&app);1940if (DL_FDPIC) {1941makefuncdescs(&app);1942if (!app.loadmap) {1943app.loadmap = (void *)&app_dummy_loadmap;1944app.loadmap->nsegs = 1;1945app.loadmap->segs[0].addr = (size_t)app.map;1946app.loadmap->segs[0].p_vaddr = (size_t)app.map1947- (size_t)app.base;1948app.loadmap->segs[0].p_memsz = app.map_len;1949}1950argv[-3] = (void *)app.loadmap;1951}19521953/* Initial dso chain consists only of the app. */1954head = tail = syms_tail = &app;19551956/* Donate unused parts of app and library mapping to malloc */1957reclaim_gaps(&app);1958reclaim_gaps(&ldso);19591960/* Load preload/needed libraries, add symbols to global namespace. */1961ldso.deps = (struct dso **)no_deps;1962if (env_preload) load_preload(env_preload);1963load_deps(&app);1964for (struct dso *p=head; p; p=p->next)1965add_syms(p);19661967/* Attach to vdso, if provided by the kernel, last so that it does1968* not become part of the global namespace. */1969if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) {1970Ehdr *ehdr = (void *)vdso_base;1971Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);1972vdso.phnum = ehdr->e_phnum;1973vdso.phentsize = ehdr->e_phentsize;1974for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {1975if (phdr->p_type == PT_DYNAMIC)1976vdso.dynv = (void *)(vdso_base + phdr->p_offset);1977if (phdr->p_type == PT_LOAD)1978vdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);1979}1980vdso.name = "";1981vdso.shortname = "linux-gate.so.1";1982vdso.relocated = 1;1983vdso.deps = (struct dso **)no_deps;1984decode_dyn(&vdso);1985vdso.prev = tail;1986tail->next = &vdso;1987tail = &vdso;1988}19891990for (i=0; app.dynv[i]; i+=2) {1991if (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG)1992app.dynv[i+1] = (size_t)&debug;1993if (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) {1994size_t *ptr = (size_t *) app.dynv[i+1];1995*ptr = (size_t)&debug;1996}1997if (app.dynv[i]==DT_DEBUG_INDIRECT_REL) {1998size_t *ptr = (size_t *)((size_t)&app.dynv[i] + app.dynv[i+1]);1999*ptr = (size_t)&debug;2000}2001}20022003/* This must be done before final relocations, since it calls2004* malloc, which may be provided by the application. Calling any2005* application code prior to the jump to its entry point is not2006* valid in our model and does not work with FDPIC, where there2007* are additional relocation-like fixups that only the entry point2008* code can see to perform. */2009main_ctor_queue = queue_ctors(&app);20102011/* Initial TLS must also be allocated before final relocations2012* might result in calloc being a call to application code. */2013update_tls_size();2014void *initial_tls = builtin_tls;2015if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) {2016initial_tls = calloc(libc.tls_size, 1);2017if (!initial_tls) {2018dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",2019argv[0], libc.tls_size);2020_exit(127);2021}2022}2023static_tls_cnt = tls_cnt;20242025/* The main program must be relocated LAST since it may contain2026* copy relocations which depend on libraries' relocations. */2027reloc_all(app.next);2028reloc_all(&app);20292030/* Actual copying to new TLS needs to happen after relocations,2031* since the TLS images might have contained relocated addresses. */2032if (initial_tls != builtin_tls) {2033if (__init_tp(__copy_tls(initial_tls)) < 0) {2034a_crash();2035}2036} else {2037size_t tmp_tls_size = libc.tls_size;2038pthread_t self = __pthread_self();2039/* Temporarily set the tls size to the full size of2040* builtin_tls so that __copy_tls will use the same layout2041* as it did for before. Then check, just to be safe. */2042libc.tls_size = sizeof builtin_tls;2043if (__copy_tls((void*)builtin_tls) != self) a_crash();2044libc.tls_size = tmp_tls_size;2045}20462047if (ldso_fail) _exit(127);2048if (ldd_mode) _exit(0);20492050/* Determine if malloc was interposed by a replacement implementation2051* so that calloc and the memalign family can harden against the2052* possibility of incomplete replacement. */2053if (find_sym(head, "malloc", 1).dso != &ldso)2054__malloc_replaced = 1;2055if (find_sym(head, "aligned_alloc", 1).dso != &ldso)2056__aligned_alloc_replaced = 1;20572058/* Switch to runtime mode: any further failures in the dynamic2059* linker are a reportable failure rather than a fatal startup2060* error. */2061runtime = 1;20622063debug.ver = 1;2064debug.bp = dl_debug_state;2065debug.head = head;2066debug.base = ldso.base;2067debug.state = RT_CONSISTENT;2068_dl_debug_state();20692070if (replace_argv0) argv[0] = replace_argv0;20712072errno = 0;20732074CRTJMP((void *)aux[AT_ENTRY], argv-1);2075for(;;);2076}20772078static void prepare_lazy(struct dso *p)2079{2080size_t dyn[DYN_CNT], n, flags1=0;2081decode_vec(p->dynv, dyn, DYN_CNT);2082search_vec(p->dynv, &flags1, DT_FLAGS_1);2083if (dyn[DT_BIND_NOW] || (dyn[DT_FLAGS] & DF_BIND_NOW) || (flags1 & DF_1_NOW))2084return;2085n = dyn[DT_RELSZ]/2 + dyn[DT_RELASZ]/3 + dyn[DT_PLTRELSZ]/2 + 1;2086if (NEED_MIPS_GOT_RELOCS) {2087size_t j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);2088size_t i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);2089n += i-j;2090}2091p->lazy = calloc(n, 3*sizeof(size_t));2092if (!p->lazy) {2093error("Error preparing lazy relocation for %s: %m", p->name);2094longjmp(*rtld_fail, 1);2095}2096p->lazy_next = lazy_head;2097lazy_head = p;2098}20992100void *dlopen(const char *file, int mode)2101{2102struct dso *volatile p, *orig_tail, *orig_syms_tail, *orig_lazy_head, *next;2103struct tls_module *orig_tls_tail;2104size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;2105size_t i;2106int cs;2107jmp_buf jb;2108struct dso **volatile ctor_queue = 0;21092110if (!file) return head;21112112pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);2113pthread_rwlock_wrlock(&lock);2114__inhibit_ptc();21152116debug.state = RT_ADD;2117_dl_debug_state();21182119p = 0;2120if (shutting_down) {2121error("Cannot dlopen while program is exiting.");2122goto end;2123}2124orig_tls_tail = tls_tail;2125orig_tls_cnt = tls_cnt;2126orig_tls_offset = tls_offset;2127orig_tls_align = tls_align;2128orig_lazy_head = lazy_head;2129orig_syms_tail = syms_tail;2130orig_tail = tail;2131noload = mode & RTLD_NOLOAD;21322133rtld_fail = &jb;2134if (setjmp(*rtld_fail)) {2135/* Clean up anything new that was (partially) loaded */2136revert_syms(orig_syms_tail);2137for (p=orig_tail->next; p; p=next) {2138next = p->next;2139while (p->td_index) {2140void *tmp = p->td_index->next;2141free(p->td_index);2142p->td_index = tmp;2143}2144free(p->funcdescs);2145if (p->rpath != p->rpath_orig)2146free(p->rpath);2147free(p->deps);2148unmap_library(p);2149free(p);2150}2151free(ctor_queue);2152ctor_queue = 0;2153if (!orig_tls_tail) libc.tls_head = 0;2154tls_tail = orig_tls_tail;2155if (tls_tail) tls_tail->next = 0;2156tls_cnt = orig_tls_cnt;2157tls_offset = orig_tls_offset;2158tls_align = orig_tls_align;2159lazy_head = orig_lazy_head;2160tail = orig_tail;2161tail->next = 0;2162p = 0;2163goto end;2164} else p = load_library(file, head);21652166if (!p) {2167error(noload ?2168"Library %s is not already loaded" :2169"Error loading shared library %s: %m",2170file);2171goto end;2172}21732174/* First load handling */2175load_deps(p);2176extend_bfs_deps(p);2177pthread_mutex_lock(&init_fini_lock);2178int constructed = p->constructed;2179pthread_mutex_unlock(&init_fini_lock);2180if (!constructed) ctor_queue = queue_ctors(p);2181if (!p->relocated && (mode & RTLD_LAZY)) {2182prepare_lazy(p);2183for (i=0; p->deps[i]; i++)2184if (!p->deps[i]->relocated)2185prepare_lazy(p->deps[i]);2186}2187if (!p->relocated || (mode & RTLD_GLOBAL)) {2188/* Make new symbols global, at least temporarily, so we can do2189* relocations. If not RTLD_GLOBAL, this is reverted below. */2190add_syms(p);2191for (i=0; p->deps[i]; i++)2192add_syms(p->deps[i]);2193}2194if (!p->relocated) {2195reloc_all(p);2196}21972198/* If RTLD_GLOBAL was not specified, undo any new additions2199* to the global symbol table. This is a nop if the library was2200* previously loaded and already global. */2201if (!(mode & RTLD_GLOBAL))2202revert_syms(orig_syms_tail);22032204/* Processing of deferred lazy relocations must not happen until2205* the new libraries are committed; otherwise we could end up with2206* relocations resolved to symbol definitions that get removed. */2207redo_lazy_relocs();22082209update_tls_size();2210if (tls_cnt != orig_tls_cnt)2211install_new_tls();2212orig_tail = tail;2213end:2214debug.state = RT_CONSISTENT;2215_dl_debug_state();2216__release_ptc();2217if (p) gencnt++;2218pthread_rwlock_unlock(&lock);2219if (ctor_queue) {2220do_init_fini(ctor_queue);2221free(ctor_queue);2222}2223pthread_setcancelstate(cs, 0);2224return p;2225}22262227hidden int __dl_invalid_handle(void *h)2228{2229struct dso *p;2230for (p=head; p; p=p->next) if (h==p) return 0;2231error("Invalid library handle %p", (void *)h);2232return 1;2233}22342235static void *addr2dso(size_t a)2236{2237struct dso *p;2238size_t i;2239if (DL_FDPIC) for (p=head; p; p=p->next) {2240i = count_syms(p);2241if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))2242return p;2243}2244for (p=head; p; p=p->next) {2245if (DL_FDPIC && p->loadmap) {2246for (i=0; i<p->loadmap->nsegs; i++) {2247if (a-p->loadmap->segs[i].p_vaddr2248< p->loadmap->segs[i].p_memsz)2249return p;2250}2251} else {2252Phdr *ph = p->phdr;2253size_t phcnt = p->phnum;2254size_t entsz = p->phentsize;2255size_t base = (size_t)p->base;2256for (; phcnt--; ph=(void *)((char *)ph+entsz)) {2257if (ph->p_type != PT_LOAD) continue;2258if (a-base-ph->p_vaddr < ph->p_memsz)2259return p;2260}2261if (a-(size_t)p->map < p->map_len)2262return 0;2263}2264}2265return 0;2266}22672268static void *do_dlsym(struct dso *p, const char *s, void *ra)2269{2270int use_deps = 0;2271if (p == head || p == RTLD_DEFAULT) {2272p = head;2273} else if (p == RTLD_NEXT) {2274p = addr2dso((size_t)ra);2275if (!p) p=head;2276p = p->next;2277} else if (__dl_invalid_handle(p)) {2278return 0;2279} else2280use_deps = 1;2281struct symdef def = find_sym2(p, s, 0, use_deps);2282if (!def.sym) {2283error("Symbol not found: %s", s);2284return 0;2285}2286if ((def.sym->st_info&0xf) == STT_TLS)2287return __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value-DTP_OFFSET});2288if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)2289return def.dso->funcdescs + (def.sym - def.dso->syms);2290return laddr(def.dso, def.sym->st_value);2291}22922293int dladdr(const void *addr_arg, Dl_info *info)2294{2295size_t addr = (size_t)addr_arg;2296struct dso *p;2297Sym *sym, *bestsym;2298uint32_t nsym;2299char *strings;2300size_t best = 0;2301size_t besterr = -1;23022303pthread_rwlock_rdlock(&lock);2304p = addr2dso(addr);2305pthread_rwlock_unlock(&lock);23062307if (!p) return 0;23082309sym = p->syms;2310strings = p->strings;2311nsym = count_syms(p);23122313if (DL_FDPIC) {2314size_t idx = (addr-(size_t)p->funcdescs)2315/ sizeof(*p->funcdescs);2316if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) {2317best = (size_t)(p->funcdescs + idx);2318bestsym = sym + idx;2319besterr = 0;2320}2321}23222323if (!best) for (; nsym; nsym--, sym++) {2324if (sym->st_value2325&& (1<<(sym->st_info&0xf) & OK_TYPES)2326&& (1<<(sym->st_info>>4) & OK_BINDS)) {2327size_t symaddr = (size_t)laddr(p, sym->st_value);2328if (symaddr > addr || symaddr <= best)2329continue;2330best = symaddr;2331bestsym = sym;2332besterr = addr - symaddr;2333if (addr == symaddr)2334break;2335}2336}23372338if (best && besterr > bestsym->st_size-1) {2339best = 0;2340bestsym = 0;2341}23422343info->dli_fname = p->name;2344info->dli_fbase = p->map;23452346if (!best) {2347info->dli_sname = 0;2348info->dli_saddr = 0;2349return 1;2350}23512352if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC)2353best = (size_t)(p->funcdescs + (bestsym - p->syms));2354info->dli_sname = strings + bestsym->st_name;2355info->dli_saddr = (void *)best;23562357return 1;2358}23592360hidden void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)2361{2362void *res;2363pthread_rwlock_rdlock(&lock);2364res = do_dlsym(p, s, ra);2365pthread_rwlock_unlock(&lock);2366return res;2367}23682369hidden void *__dlsym_redir_time64(void *restrict p, const char *restrict s, void *restrict ra)2370{2371#if _REDIR_TIME642372const char *suffix, *suffix2 = "";2373char redir[36];23742375/* Map the symbol name to a time64 version of itself according to the2376* pattern used for naming the redirected time64 symbols. */2377size_t l = strnlen(s, sizeof redir);2378if (l<4 || l==sizeof redir) goto no_redir;2379if (s[l-2]=='_' && s[l-1]=='r') {2380l -= 2;2381suffix2 = s+l;2382}2383if (l<4) goto no_redir;2384if (!strcmp(s+l-4, "time")) suffix = "64";2385else suffix = "_time64";23862387/* Use the presence of the remapped symbol name in libc to determine2388* whether it's one that requires time64 redirection; replace if so. */2389snprintf(redir, sizeof redir, "__%.*s%s%s", (int)l, s, suffix, suffix2);2390if (find_sym(&ldso, redir, 1).sym) s = redir;2391no_redir:2392#endif2393return __dlsym(p, s, ra);2394}23952396int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)2397{2398struct dso *current;2399struct dl_phdr_info info;2400int ret = 0;2401for(current = head; current;) {2402info.dlpi_addr = (uintptr_t)current->base;2403info.dlpi_name = current->name;2404info.dlpi_phdr = current->phdr;2405info.dlpi_phnum = current->phnum;2406info.dlpi_adds = gencnt;2407info.dlpi_subs = 0;2408info.dlpi_tls_modid = current->tls_id;2409info.dlpi_tls_data = !current->tls_id ? 0 :2410__tls_get_addr((tls_mod_off_t[]){current->tls_id,0});24112412ret = (callback)(&info, sizeof (info), data);24132414if (ret != 0) break;24152416pthread_rwlock_rdlock(&lock);2417current = current->next;2418pthread_rwlock_unlock(&lock);2419}2420return ret;2421}24222423static void error_impl(const char *fmt, ...)2424{2425va_list ap;2426va_start(ap, fmt);2427if (!runtime) {2428vdprintf(2, fmt, ap);2429dprintf(2, "\n");2430ldso_fail = 1;2431va_end(ap);2432return;2433}2434__dl_vseterr(fmt, ap);2435va_end(ap);2436}24372438static void error_noop(const char *fmt, ...)2439{2440}244124422443