diff --git a/system/lib/libc/musl/src/aio/aio_cancel.c b/system/lib/libc/musl/src/aio/aio_cancel.c deleted file mode 100644 index 5a753b1f42f6b..0000000000000 --- a/system/lib/libc/musl/src/aio/aio_cancel.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include - -int aio_cancel(int fd, struct aiocb *cb) -{ - if (!cb) { - /* FIXME: for correctness, we should return AIO_ALLDONE - * if there are no outstanding aio operations on this - * file descriptor, but that would require making aio - * much slower, and seems to have little advantage since - * we don't support cancellation anyway. */ - return AIO_NOTCANCELED; - } - return cb->__err==EINPROGRESS ? AIO_NOTCANCELED : AIO_ALLDONE; -} diff --git a/system/lib/libc/musl/src/aio/aio_error.c b/system/lib/libc/musl/src/aio/aio_error.c deleted file mode 100644 index a780fd33d3c9e..0000000000000 --- a/system/lib/libc/musl/src/aio/aio_error.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int aio_error(const struct aiocb *cb) -{ - return cb->__err; -} diff --git a/system/lib/libc/musl/src/aio/aio_fsync.c b/system/lib/libc/musl/src/aio/aio_fsync.c deleted file mode 100644 index 0ac6ea873020e..0000000000000 --- a/system/lib/libc/musl/src/aio/aio_fsync.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int aio_fsync(int op, struct aiocb *cb) -{ - /* FIXME: unsupported */ - errno = EINVAL; - return -1; -} diff --git a/system/lib/libc/musl/src/aio/aio_readwrite.c b/system/lib/libc/musl/src/aio/aio_readwrite.c deleted file mode 100644 index 0de3d4fb7ec76..0000000000000 --- a/system/lib/libc/musl/src/aio/aio_readwrite.c +++ /dev/null @@ -1,107 +0,0 @@ -#include -#include -#include -#include -#include "pthread_impl.h" -#include "libc.h" - -static void dummy(void) -{ -} - -weak_alias(dummy, __aio_wake); - -static void notify_signal(struct sigevent *sev) -{ - siginfo_t si = { - .si_signo = sev->sigev_signo, - .si_value = sev->sigev_value, - .si_code = SI_ASYNCIO, - .si_pid = __pthread_self()->pid, - .si_uid = getuid() - }; - __syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si); -} - -static void *io_thread(void *p) -{ - struct aiocb *cb = p; - int fd = cb->aio_fildes; - void *buf = (void *)cb->aio_buf; - size_t len = cb->aio_nbytes; - off_t off = cb->aio_offset; - int op = cb->aio_lio_opcode; - struct sigevent sev = cb->aio_sigevent; - ssize_t ret; - - if (op == LIO_WRITE) { - if ( (fcntl(fd, F_GETFL) & O_APPEND) - ||((ret = pwrite(fd, buf, len, off))<0 && errno==ESPIPE) ) - ret = write(fd, buf, len); - } else if (op == LIO_READ) { - if ( (ret = pread(fd, buf, len, off))<0 && errno==ESPIPE ) - ret = read(fd, buf, len); - } else { - ret = 0; - } - cb->__ret = ret; - - if (ret < 0) a_store(&cb->__err, errno); - else a_store(&cb->__err, 0); - - __aio_wake(); - - switch (sev.sigev_notify) { - case SIGEV_SIGNAL: - notify_signal(&sev); - break; - case SIGEV_THREAD: - sev.sigev_notify_function(sev.sigev_value); - break; - } - - return 0; -} - -static int new_req(struct aiocb *cb) -{ - int ret = 0; - pthread_attr_t a; - sigset_t set; - pthread_t td; - - if (cb->aio_sigevent.sigev_notify == SIGEV_THREAD) { - if (cb->aio_sigevent.sigev_notify_attributes) - a = *cb->aio_sigevent.sigev_notify_attributes; - else - pthread_attr_init(&a); - } else { - pthread_attr_init(&a); - pthread_attr_setstacksize(&a, PAGE_SIZE); - pthread_attr_setguardsize(&a, 0); - } - pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED); - sigfillset(&set); - pthread_sigmask(SIG_BLOCK, &set, &set); - cb->__err = EINPROGRESS; - if (pthread_create(&td, &a, io_thread, cb)) { - errno = EAGAIN; - ret = -1; - } - pthread_sigmask(SIG_SETMASK, &set, 0); - cb->__td = td; - - return ret; -} - -int aio_read(struct aiocb *cb) -{ - cb->aio_lio_opcode = LIO_READ; - return new_req(cb); -} - -int aio_write(struct aiocb *cb) -{ - cb->aio_lio_opcode = LIO_WRITE; - return new_req(cb); -} diff --git a/system/lib/libc/musl/src/aio/aio_return.c b/system/lib/libc/musl/src/aio/aio_return.c deleted file mode 100644 index df10bdbe2272f..0000000000000 --- a/system/lib/libc/musl/src/aio/aio_return.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -ssize_t aio_return(struct aiocb *cb) -{ - return cb->__ret; -} diff --git a/system/lib/libc/musl/src/env/__init_security.c b/system/lib/libc/musl/src/env/__init_security.c deleted file mode 100644 index 6204c5e1e34f4..0000000000000 --- a/system/lib/libc/musl/src/env/__init_security.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include "syscall.h" -#include "libc.h" -#include "atomic.h" - -static void dummy(void *ent) -{ -} -weak_alias(dummy, __init_ssp); - -void __init_security(size_t *aux) -{ - struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; - int i; - -#ifndef SHARED - __init_ssp((void *)aux[AT_RANDOM]); -#endif - - if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID] - && !aux[AT_SECURE]) return; - - __syscall(SYS_poll, pfd, 3, 0); - for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL) - if (__syscall(SYS_open, "/dev/null", O_RDWR|O_LARGEFILE)<0) - a_crash(); - libc.secure = 1; -} diff --git a/system/lib/libc/musl/src/fenv/armebhf/fenv.sub b/system/lib/libc/musl/src/fenv/armebhf/fenv.sub deleted file mode 100644 index 5281e40b92fcd..0000000000000 --- a/system/lib/libc/musl/src/fenv/armebhf/fenv.sub +++ /dev/null @@ -1 +0,0 @@ -../armhf/fenv.s diff --git a/system/lib/libc/musl/src/fenv/armhf/fenv.s b/system/lib/libc/musl/src/fenv/armhf/fenv.s deleted file mode 100644 index 26ac87e10042c..0000000000000 --- a/system/lib/libc/musl/src/fenv/armhf/fenv.s +++ /dev/null @@ -1,63 +0,0 @@ -.global fegetround -.type fegetround,%function -fegetround: - mrc p10, 7, r0, cr1, cr0, 0 - and r0, r0, #0xc00000 - bx lr - -.global __fesetround -.type __fesetround,%function -__fesetround: - mrc p10, 7, r3, cr1, cr0, 0 - bic r3, r3, #0xc00000 - orr r3, r3, r0 - mcr p10, 7, r3, cr1, cr0, 0 - mov r0, #0 - bx lr - -.global fetestexcept -.type fetestexcept,%function -fetestexcept: - and r0, r0, #0x1f - mrc p10, 7, r3, cr1, cr0, 0 - and r0, r0, r3 - bx lr - -.global feclearexcept -.type feclearexcept,%function -feclearexcept: - and r0, r0, #0x1f - mrc p10, 7, r3, cr1, cr0, 0 - bic r3, r3, r0 - mcr p10, 7, r3, cr1, cr0, 0 - mov r0, #0 - bx lr - -.global feraiseexcept -.type feraiseexcept,%function -feraiseexcept: - and r0, r0, #0x1f - mrc p10, 7, r3, cr1, cr0, 0 - orr r3, r3, r0 - mcr p10, 7, r3, cr1, cr0, 0 - mov r0, #0 - bx lr - -.global fegetenv -.type fegetenv,%function -fegetenv: - mrc p10, 7, r3, cr1, cr0, 0 - str r3, [r0] - mov r0, #0 - bx lr - -.global fesetenv -.type fesetenv,%function -fesetenv: - mrc p10, 7, r3, cr1, cr0, 0 - cmn r0, #1 - moveq r3, #0 - ldrne r3, [r0] - mcr p10, 7, r3, cr1, cr0, 0 - mov r0, #0 - bx lr diff --git a/system/lib/libc/musl/src/fenv/armhf/fenv.sub b/system/lib/libc/musl/src/fenv/armhf/fenv.sub deleted file mode 100644 index ec559cd47ab0c..0000000000000 --- a/system/lib/libc/musl/src/fenv/armhf/fenv.sub +++ /dev/null @@ -1 +0,0 @@ -fenv.s diff --git a/system/lib/libc/musl/src/fenv/mips-sf/fenv.sub b/system/lib/libc/musl/src/fenv/mips-sf/fenv.sub deleted file mode 100644 index 9cafca5e98889..0000000000000 --- a/system/lib/libc/musl/src/fenv/mips-sf/fenv.sub +++ /dev/null @@ -1 +0,0 @@ -../fenv.c diff --git a/system/lib/libc/musl/src/fenv/mipsel-sf/fenv.sub b/system/lib/libc/musl/src/fenv/mipsel-sf/fenv.sub deleted file mode 100644 index 9cafca5e98889..0000000000000 --- a/system/lib/libc/musl/src/fenv/mipsel-sf/fenv.sub +++ /dev/null @@ -1 +0,0 @@ -../fenv.c diff --git a/system/lib/libc/musl/src/fenv/sh-nofpu/fenv.sub b/system/lib/libc/musl/src/fenv/sh-nofpu/fenv.sub deleted file mode 100644 index 9cafca5e98889..0000000000000 --- a/system/lib/libc/musl/src/fenv/sh-nofpu/fenv.sub +++ /dev/null @@ -1 +0,0 @@ -../fenv.c diff --git a/system/lib/libc/musl/src/fenv/sheb-nofpu/fenv.sub b/system/lib/libc/musl/src/fenv/sheb-nofpu/fenv.sub deleted file mode 100644 index 9cafca5e98889..0000000000000 --- a/system/lib/libc/musl/src/fenv/sheb-nofpu/fenv.sub +++ /dev/null @@ -1 +0,0 @@ -../fenv.c diff --git a/system/lib/libc/musl/src/ldso/dynlink.c b/system/lib/libc/musl/src/ldso/dynlink.c deleted file mode 100644 index cc84c8ab44949..0000000000000 --- a/system/lib/libc/musl/src/ldso/dynlink.c +++ /dev/null @@ -1,1475 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pthread_impl.h" -#include "libc.h" - -static int errflag; -static char errbuf[128]; - -#ifdef SHARED - -#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 - -#define MAXP2(a,b) (-(-(a)&-(b))) -#define ALIGN(x,y) ((x)+(y)-1 & -(y)) - -struct debug { - int ver; - void *head; - void (*bp)(void); - int state; - void *base; -}; - -struct dso { - unsigned char *base; - char *name; - size_t *dynv; - struct dso *next, *prev; - - Phdr *phdr; - int phnum; - int refcnt; - Sym *syms; - uint32_t *hashtab; - uint32_t *ghashtab; - int16_t *versym; - char *strings; - unsigned char *map; - size_t map_len; - dev_t dev; - ino_t ino; - signed char global; - char relocated; - char constructed; - char kernel_mapped; - struct dso **deps, *needed_by; - char *rpath_orig, *rpath; - void *tls_image; - size_t tls_len, tls_size, tls_align, tls_id, tls_offset; - void **new_dtv; - unsigned char *new_tls; - int new_dtv_idx, new_tls_idx; - struct dso *fini_next; - char *shortname; - char buf[]; -}; - -struct symdef { - Sym *sym; - struct dso *dso; -}; - -#include "reloc.h" - -void __init_ssp(size_t *); -void *__install_initial_tls(void *); -void __init_libc(char **, char *); - -const char *__libc_get_version(void); - -static struct dso *head, *tail, *ldso, *fini_head; -static char *env_path, *sys_path; -static unsigned long long gencnt; -static int ssp_used; -static int runtime; -static int ldd_mode; -static int ldso_fail; -static int noload; -static jmp_buf *rtld_fail; -static pthread_rwlock_t lock; -static struct debug debug; -static size_t tls_cnt, tls_offset, tls_align = 4*sizeof(size_t); -static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE }; - -struct debug *_dl_debug_addr = &debug; - -#define AUX_CNT 38 -#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]>24 & 0xf0; - } - return h & 0xfffffff; -} - -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) -{ - size_t i; - Sym *syms = dso->syms; - uint32_t *hashtab = dso->hashtab; - char *strings = dso->strings; - for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) { - if ((!dso->versym || dso->versym[i] >= 0) - && (!strcmp(s, strings+syms[i].st_name))) - return syms+i; - } - return 0; -} - -static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso) -{ - Sym *syms = dso->syms; - char *strings = dso->strings; - 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; - uint32_t i = buckets[h1 % nbuckets]; - - if (!i) return 0; - - hashval = buckets + nbuckets + (i - hashtab[1]); - - for (h1 |= 1; ; i++) { - h2 = *hashval++; - if ((!dso->versym || dso->versym[i] >= 0) - && (h1 == (h2|1)) && !strcmp(s, strings + syms[i].st_name)) - return syms+i; - if (h2 & 1) break; - } - - return 0; -} - -#define OK_TYPES (1<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; - } - for (; dso; dso=dso->next) { - Sym *sym; - if (!dso->global) continue; - 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); - } - 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; - } - return def; -} - -static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride) -{ - unsigned char *base = dso->base; - Sym *syms = dso->syms; - char *strings = dso->strings; - Sym *sym; - const char *name; - void *ctx; - int type; - int sym_index; - struct symdef def; - - 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; - ctx = IS_COPY(type) ? head->next : head; - def = find_sym(ctx, name, IS_PLT(type)); - if (!def.sym && (sym->st_shndx != SHN_UNDEF - || sym->st_info>>4 != STB_WEAK)) { - snprintf(errbuf, sizeof errbuf, - "Error relocating %s: %s: symbol not found", - dso->name, name); - if (runtime) longjmp(*rtld_fail, 1); - dprintf(2, "%s\n", errbuf); - ldso_fail = 1; - continue; - } - } else { - sym = 0; - def.sym = 0; - def.dso = 0; - } - 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); - } -} - -/* 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); - } -} - -static void *map_library(int fd, struct dso *dso) -{ - Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)]; - void *allocated_buf=0; - 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; - Phdr *ph, *ph0; - unsigned prot; - unsigned char *map=MAP_FAILED, *base; - size_t dyn=0; - size_t tls_image=0; - size_t i; - - ssize_t l = read(fd, buf, sizeof buf); - eh = buf; - if (l<0) return 0; - if (le_type != ET_DYN && eh->e_type != ET_EXEC)) - goto noexec; - phsize = eh->e_phentsize * eh->e_phnum; - 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) { - l = pread(fd, buf+1, phsize, eh->e_phoff); - if (l < 0) goto error; - if (l != phsize) goto noexec; - ph = ph0 = (void *)(buf + 1); - } else { - ph = ph0 = (void *)((char *)buf + eh->e_phoff); - } - for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) { - if (ph->p_type == PT_DYNAMIC) - dyn = ph->p_vaddr; - 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; - } - 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; - } - } - if (!dyn) goto noexec; - 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. */ - map = mmap((void *)addr_min, map_len, prot, MAP_PRIVATE, fd, off_start); - if (map==MAP_FAILED) goto error; - /* 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; - } - base = map - addr_min; - dso->phdr = 0; - dso->phnum = 0; - for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) { - if (ph->p_type != PT_LOAD) continue; - /* 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; - } - /* 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)); - if (mmap(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED) - goto error; - 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); - 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; - } - } - for (i=0; ((size_t *)(base+dyn))[i]; i+=2) - if (((size_t *)(base+dyn))[i]==DT_TEXTREL) { - if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC) < 0) - goto error; - break; - } - if (!runtime) reclaim_gaps(base, ph0, eh->e_phentsize, eh->e_phnum); - 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); - free(allocated_buf); - return map; -noexec: - errno = ENOEXEC; -error: - if (map!=MAP_FAILED) munmap(map, map_len); - free(allocated_buf); - return 0; -} - -static int path_open(const char *name, const char *s, char *buf, size_t buf_size) -{ - size_t l; - int fd; - for (;;) { - 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; - if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd; - s += l; - } -} - -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; - while ((t=strchr(s, '$'))) { - if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9)) - return -1; - 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; - l = readlink("/proc/self/exe", buf, buf_size); - if (l >= buf_size) - return -1; - buf[l] = 0; - 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; - while ((t=strchr(s, '$'))) { - memcpy(d, s, t-s); - d += t-s; - memcpy(d, origin, l); - d += l; - /* It was determined previously that the '$' is followed - * either by "ORIGIN" or "{ORIGIN}". */ - s = t + 7 + 2*(t[1]=='{'); - } - strcpy(d, s); - return 0; -} - -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]); - if (dyn[0]&(1<hashtab = (void *)(p->base + dyn[DT_HASH]); - if (dyn[0]&(1<rpath_orig = (void *)(p->strings + dyn[DT_RPATH]); - if (dyn[0]&(1<rpath_orig = (void *)(p->strings + dyn[DT_RUNPATH]); - if (search_vec(p->dynv, dyn, DT_GNU_HASH)) - p->ghashtab = (void *)(p->base + *dyn); - if (search_vec(p->dynv, dyn, DT_VERSYM)) - p->versym = (void *)(p->base + *dyn); -} - -static struct dso *load_library(const char *name, struct dso *needed_by) -{ - char buf[2*NAME_MAX+2]; - const char *pathname; - unsigned char *map; - struct dso *p, temp_dso = {0}; - int fd; - struct stat st; - size_t alloc_size; - int n_th = 0; - int is_self = 0; - - /* 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; - for (rp=reserved; *rp && strncmp(name+3, rp, l-3); rp+=strlen(rp)+1); - if (*rp) { - 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); - } - } - is_self = 1; - } - } - } - 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; - } - if (strchr(name, '/')) { - pathname = name; - fd = open(name, O_RDONLY|O_CLOEXEC); - } else { - /* 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; - } - } - if (strlen(name) > NAME_MAX) return 0; - fd = -1; - if (env_path) fd = path_open(name, env_path, buf, sizeof buf); - for (p=needed_by; fd < 0 && p; p=p->needed_by) - if (!fixup_rpath(p, buf, sizeof buf)) - fd = path_open(name, p->rpath, buf, sizeof buf); - if (fd < 0) { - if (!sys_path) { - 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"); - if (f) { - if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) { - free(sys_path); - sys_path = ""; - } - fclose(f); - } else if (errno != ENOENT) { - sys_path = ""; - } - } - if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib"; - fd = path_open(name, sys_path, buf, sizeof buf); - } - pathname = buf; - } - 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) { - /* 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. */ - if (!p->shortname && pathname != name) - p->shortname = strrchr(p->name, '/')+1; - close(fd); - p->refcnt++; - return p; - } - } - map = noload ? 0 : map_library(fd, &temp_dso); - close(fd); - if (!map) return 0; - - /* 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); - n_th = libc.threads_minus_1 + 1; - if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX; - else alloc_size += n_th * per_th; - } - p = calloc(1, alloc_size); - if (!p) { - munmap(map, temp_dso.map_len); - return 0; - } - memcpy(p, &temp_dso, sizeof temp_dso); - decode_dyn(p); - p->dev = st.st_dev; - p->ino = st.st_ino; - p->refcnt = 1; - p->needed_by = needed_by; - p->name = p->buf; - 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; - if (p->tls_image) { - if (runtime && !__pthread_self_init()) { - munmap(map, p->map_len); - free(p); - return 0; - } - p->tls_id = ++tls_cnt; - tls_align = MAXP2(tls_align, p->tls_align); -#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 - 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; -#endif - 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)); - } - - tail->next = p; - p->prev = tail; - tail = p; - - if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base); - - return p; -} - -static void load_deps(struct dso *p) -{ - size_t i, ndeps=0; - struct dso ***deps = &p->deps, **tmp, *dep; - for (; p; p=p->next) { - for (i=0; p->dynv[i]; i+=2) { - if (p->dynv[i] != DT_NEEDED) continue; - dep = load_library(p->strings + p->dynv[i+1], p); - if (!dep) { - snprintf(errbuf, sizeof errbuf, - "Error loading shared library %s: %m (needed by %s)", - p->strings + p->dynv[i+1], p->name); - if (runtime) longjmp(*rtld_fail, 1); - dprintf(2, "%s\n", errbuf); - ldso_fail = 1; - continue; - } - if (runtime) { - tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2)); - if (!tmp) longjmp(*rtld_fail, 1); - tmp[ndeps++] = dep; - tmp[ndeps] = 0; - *deps = tmp; - } - } - } -} - -static void load_preload(char *s) -{ - int tmp; - char *z; - for (z=s; *z; s=z) { - for ( ; *s && (isspace(*s) || *s==':'); s++); - for (z=s; *z && !isspace(*z) && *z!=':'; z++); - tmp = *z; - *z = 0; - load_library(s, 0); - *z = tmp; - } -} - -static void make_global(struct dso *p) -{ - for (; p; p=p->next) p->global = 1; -} - -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); -#ifdef NEED_ARCH_RELOCS - do_arch_relocs(p, head); -#endif - 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); - p->relocated = 1; - } -} - -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; -} - -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; -} - -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); - if (dyn[0] & (1<base + dyn[DT_FINI_ARRAY])+n; - while (n--) ((void (*)(void))*--fn)(); - } -#ifndef NO_LEGACY_INITFINI - if ((dyn[0] & (1<base + dyn[DT_FINI]))(); -#endif - } -} - -static void do_init_fini(struct dso *p) -{ - size_t dyn[DYN_CNT] = {0}; - int need_locking = libc.threads_minus_1; - /* 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); - for (; p; p=p->prev) { - if (p->constructed) continue; - p->constructed = 1; - decode_vec(p->dynv, dyn, DYN_CNT); - if (dyn[0] & ((1<fini_next = fini_head; - fini_head = p; - } -#ifndef NO_LEGACY_INITFINI - if ((dyn[0] & (1<base + dyn[DT_INIT]))(); -#endif - if (dyn[0] & (1<base + dyn[DT_INIT_ARRAY]); - while (n--) ((void (*)(void))*fn++)(); - } - if (!need_locking && libc.threads_minus_1) { - need_locking = 1; - pthread_mutex_lock(&init_fini_lock); - } - } - if (need_locking) pthread_mutex_unlock(&init_fini_lock); -} - -void _dl_debug_state(void) -{ -} - -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; - } -} - -void *__copy_tls(unsigned char *mem) -{ - pthread_t td; - struct dso *p; - - if (!tls_cnt) return mem; - - void **dtv = (void *)mem; - dtv[0] = (void *)tls_cnt; - -#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 - mem += libc.tls_size - sizeof(struct pthread); - mem -= (uintptr_t)mem & (tls_align-1); - td = (pthread_t)mem; - - 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); - } -#endif - td->dtv = dtv; - return td; -} - -void *__tls_get_addr(size_t *v) -{ - pthread_t self = __pthread_self(); - if (v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) - return (char *)self->dtv[v[0]]+v[1]; - - /* Block signals to make accessing new TLS async-signal-safe */ - sigset_t set; - pthread_sigmask(SIG_BLOCK, SIGALL_SET, &set); - if (v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) { - 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 */ - if (v[0] > (size_t)self->dtv[0]) { - void **newdtv = p->new_dtv + - (v[0]+1)*sizeof(void *)*a_fetch_add(&p->new_dtv_idx,1); - memcpy(newdtv, self->dtv, - ((size_t)self->dtv[0]+1) * sizeof(void *)); - newdtv[0] = (void *)v[0]; - self->dtv = newdtv; - } - - /* 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; - memcpy(mem, p->tls_image, p->tls_len); - pthread_sigmask(SIG_SETMASK, &set, 0); - return mem + v[1]; -} - -static void update_tls_size() -{ - libc.tls_size = ALIGN( - (1+tls_cnt) * sizeof(void *) + - tls_offset + - sizeof(struct pthread) + - tls_align * 2, - tls_align); -} - -void *__dynlink(int argc, char **argv) -{ - size_t aux[AUX_CNT] = {0}; - size_t i; - Phdr *phdr; - Ehdr *ehdr; - static struct dso builtin_dsos[3]; - struct dso *const app = builtin_dsos+0; - struct dso *const lib = builtin_dsos+1; - struct dso *const vdso = builtin_dsos+2; - char *env_preload=0; - size_t vdso_base; - size_t *auxv; - char **envp = argv+argc+1; - - /* Find aux vector just past environ[] */ - for (i=argc+1; argv[i]; i++) - if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16)) - env_path = argv[i]+16; - else if (!memcmp(argv[i], "LD_PRELOAD=", 11)) - env_preload = argv[i]+11; - auxv = (void *)(argv+i+1); - - decode_vec(auxv, aux, AUX_CNT); - - /* Only trust user/env if kernel says we're not suid/sgid */ - if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID] - || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]) { - env_path = 0; - env_preload = 0; - libc.secure = 1; - } - libc.page_size = aux[AT_PAGESZ]; - - /* 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; - } - - /* The dynamic linker load address is passed by the kernel - * in the AUX vector, so this is easy. */ - lib->base = (void *)aux[AT_BASE]; - lib->name = lib->shortname = "libc.so"; - lib->global = 1; - lib->kernel_mapped = 1; - ehdr = (void *)lib->base; - 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, - ehdr->e_phnum, ehdr->e_phentsize)); - decode_dyn(lib); - - if (aux[AT_PHDR]) { - size_t interp_off = 0; - size_t tls_image = 0; - /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */ - app->phdr = phdr = (void *)aux[AT_PHDR]; - app->phnum = aux[AT_PHNUM]; - 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); - else if (phdr->p_type == PT_INTERP) - interp_off = (size_t)phdr->p_vaddr; - 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; - } - } - if (app->tls_size) app->tls_image = (char *)app->base + tls_image; - if (interp_off) lib->name = (char *)app->base + interp_off; - if ((aux[0] & (1UL<name = (char *)aux[AT_EXECFN]; - else - app->name = argv[0]; - app->kernel_mapped = 1; - app->dynv = (void *)(app->base + find_dyn( - (void *)aux[AT_PHDR], aux[AT_PHNUM], aux[AT_PHENT])); - find_map_range((void *)aux[AT_PHDR], - aux[AT_PHNUM], aux[AT_PHENT], app); - } else { - int fd; - char *ldname = argv[0]; - size_t l = strlen(ldname); - 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]) { - dprintf(2, "musl libc\n" - "Version %s\n" - "Dynamic Program Loader\n" - "Usage: %s [--] pathname%s\n", - __libc_get_version(), ldname, - 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; - ehdr = (void *)map_library(fd, app); - if (!ehdr) { - dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]); - _exit(1); - } - runtime = 0; - close(fd); - lib->name = ldname; - app->name = argv[0]; - aux[AT_ENTRY] = (size_t)app->base + ehdr->e_entry; - /* Find the name that would have been used for the dynamic - * linker had ldd not taken its place. */ - if (ldd_mode) { - for (i=0; iphnum; 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); - } - } - if (app->tls_size) { - app->tls_id = tls_cnt = 1; -#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 - tls_offset = app->tls_offset = app->tls_size - + ( -((uintptr_t)app->tls_image + app->tls_size) - & (app->tls_align-1) ); -#endif - tls_align = MAXP2(tls_align, app->tls_align); - } - app->global = 1; - decode_dyn(app); - - /* Attach to vdso, if provided by the kernel */ - if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR)) { - ehdr = (void *)vdso_base; - vdso->phdr = phdr = (void *)(vdso_base + ehdr->e_phoff); - vdso->phnum = ehdr->e_phnum; - 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); - } - vdso->name = ""; - vdso->shortname = "linux-gate.so.1"; - vdso->global = 1; - decode_dyn(vdso); - vdso->prev = lib; - lib->next = vdso; - } - - /* 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; - ldso = lib; - app->next = lib; - reloc_all(lib); - app->next = 0; - - /* PAST THIS POINT, ALL LIBC INTERFACES ARE FULLY USABLE. */ - - /* Donate unused parts of app and library mapping to malloc */ - 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), - ehdr->e_phentsize, ehdr->e_phnum); - - /* Load preload/needed libraries, add their symbols to the global - * namespace, and perform all remaining relocations. The main - * program must be relocated LAST since it may contain copy - * relocations which depend on libraries' relocations. */ - if (env_preload) load_preload(env_preload); - load_deps(app); - make_global(app); - - reloc_all(app->next); - reloc_all(app); - - update_tls_size(); - if (tls_cnt) { - void *mem = mmap(0, libc.tls_size, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - if (mem==MAP_FAILED || - !__install_initial_tls(__copy_tls(mem))) { - dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n", - argv[0], libc.tls_size); - _exit(127); - } - } - - if (ldso_fail) _exit(127); - if (ldd_mode) _exit(0); - - /* 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. */ - runtime = 1; - -#ifndef DYNAMIC_IS_RO - for (i=0; app->dynv[i]; i+=2) - if (app->dynv[i]==DT_DEBUG) - app->dynv[i+1] = (size_t)&debug; -#endif - debug.ver = 1; - debug.bp = _dl_debug_state; - debug.head = head; - debug.base = lib->base; - debug.state = 0; - _dl_debug_state(); - - if (ssp_used) __init_ssp((void *)aux[AT_RANDOM]); - __init_libc(envp, argv[0]); - atexit(do_fini); - errno = 0; - do_init_fini(tail); - - return (void *)aux[AT_ENTRY]; -} - -void *dlopen(const char *file, int mode) -{ - struct dso *volatile p, *orig_tail, *next; - size_t orig_tls_cnt, orig_tls_offset, orig_tls_align; - size_t i; - int cs; - jmp_buf jb; - - if (!file) return head; - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); - pthread_rwlock_wrlock(&lock); - __inhibit_ptc(); - - p = 0; - orig_tls_cnt = tls_cnt; - orig_tls_offset = tls_offset; - orig_tls_align = tls_align; - orig_tail = tail; - noload = mode & RTLD_NOLOAD; - - rtld_fail = &jb; - if (setjmp(*rtld_fail)) { - /* Clean up anything new that was (partially) loaded */ - if (p && p->deps) for (i=0; p->deps[i]; i++) - if (p->deps[i]->global < 0) - p->deps[i]->global = 0; - for (p=orig_tail->next; p; p=next) { - next = p->next; - munmap(p->map, p->map_len); - free(p->deps); - free(p); - } - tls_cnt = orig_tls_cnt; - tls_offset = orig_tls_offset; - tls_align = orig_tls_align; - tail = orig_tail; - tail->next = 0; - p = 0; - errflag = 1; - goto end; - } else p = load_library(file, head); - - if (!p) { - snprintf(errbuf, sizeof errbuf, noload ? - "Library %s is not already loaded" : - "Error loading shared library %s: %m", - file); - errflag = 1; - goto end; - } - - /* First load handling */ - if (!p->deps) { - load_deps(p); - if (p->deps) for (i=0; p->deps[i]; i++) - if (!p->deps[i]->global) - p->deps[i]->global = -1; - if (!p->global) p->global = -1; - reloc_all(p); - if (p->deps) for (i=0; p->deps[i]; i++) - if (p->deps[i]->global < 0) - p->deps[i]->global = 0; - if (p->global < 0) p->global = 0; - } - - if (mode & RTLD_GLOBAL) { - if (p->deps) for (i=0; p->deps[i]; i++) - p->deps[i]->global = 1; - p->global = 1; - } - - update_tls_size(); - - if (ssp_used) __init_ssp(libc.auxv); - - _dl_debug_state(); - orig_tail = tail; -end: - __release_ptc(); - if (p) gencnt++; - pthread_rwlock_unlock(&lock); - if (p) do_init_fini(orig_tail); - pthread_setcancelstate(cs, 0); - return p; -} - -static int invalid_dso_handle(void *h) -{ - 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; -} - -static void *do_dlsym(struct dso *p, const char *s, void *ra) -{ - size_t i; - uint32_t h = 0, gh = 0; - Sym *sym; - if (p == head || p == RTLD_DEFAULT || p == RTLD_NEXT) { - if (p == RTLD_DEFAULT) { - p = head; - } else if (p == RTLD_NEXT) { - for (p=head; p && (unsigned char *)ra-p->map>p->map_len; p=p->next); - if (!p) p=head; - p = p->next; - } - struct symdef def = find_sym(p, s, 0); - if (!def.sym) goto failed; - if ((def.sym->st_info&0xf) == STT_TLS) - return __tls_get_addr((size_t []){def.dso->tls_id, def.sym->st_value}); - return def.dso->base + def.sym->st_value; - } - if (p != RTLD_DEFAULT && p != RTLD_NEXT && invalid_dso_handle(p)) - return 0; - if (p->ghashtab) { - gh = gnu_hash(s); - sym = gnu_lookup(s, gh, p); - } else { - h = sysv_hash(s); - sym = sysv_lookup(s, h, p); - } - if (sym && (sym->st_info&0xf) == STT_TLS) - return __tls_get_addr((size_t []){p->tls_id, sym->st_value}); - 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++) { - if (p->deps[i]->ghashtab) { - if (!gh) gh = gnu_hash(s); - sym = gnu_lookup(s, gh, p->deps[i]); - } else { - if (!h) h = sysv_hash(s); - sym = sysv_lookup(s, h, p->deps[i]); - } - if (sym && (sym->st_info&0xf) == STT_TLS) - return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value}); - if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES)) - return p->deps[i]->base + sym->st_value; - } -failed: - errflag = 1; - snprintf(errbuf, sizeof errbuf, "Symbol not found: %s", s); - return 0; -} - -int __dladdr(const void *addr, Dl_info *info) -{ - 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]; - for (i = nsym = 0; i < p->ghashtab[0]; i++) { - 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++) { - if (sym->st_value - && (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; -} - -void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra) -{ - void *res; - pthread_rwlock_rdlock(&lock); - res = do_dlsym(p, s, ra); - pthread_rwlock_unlock(&lock); - return res; -} - -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; -} -#else -static int invalid_dso_handle(void *h) -{ - snprintf(errbuf, sizeof errbuf, "Invalid library handle %p", (void *)h); - errflag = 1; - return 1; -} -void *dlopen(const char *file, int mode) -{ - return 0; -} -void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra) -{ - return 0; -} -int __dladdr (const void *addr, Dl_info *info) -{ - return 0; -} -#endif - -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; -} - -char *dlerror() -{ - if (!errflag) return 0; - errflag = 0; - return errbuf; -} - -int dlclose(void *p) -{ - return invalid_dso_handle(p); -} diff --git a/system/lib/libc/musl/src/ldso/start.c b/system/lib/libc/musl/src/ldso/start.c deleted file mode 100644 index f6ae7cd2f88eb..0000000000000 --- a/system/lib/libc/musl/src/ldso/start.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -/* stub for archs that lack dynamic linker support */ - -void _start() -{ - _Exit(1); -} diff --git a/system/lib/libc/musl/src/locale/isalnum_l.c b/system/lib/libc/musl/src/locale/isalnum_l.c deleted file mode 100644 index b8a6eef373f0b..0000000000000 --- a/system/lib/libc/musl/src/locale/isalnum_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isalnum_l(int c, locale_t l) -{ - return isalnum(c); -} diff --git a/system/lib/libc/musl/src/locale/isalpha_l.c b/system/lib/libc/musl/src/locale/isalpha_l.c deleted file mode 100644 index 2e1205c617e70..0000000000000 --- a/system/lib/libc/musl/src/locale/isalpha_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isalpha_l(int c, locale_t l) -{ - return isalpha(c); -} diff --git a/system/lib/libc/musl/src/locale/isblank_l.c b/system/lib/libc/musl/src/locale/isblank_l.c deleted file mode 100644 index 27479aa151fba..0000000000000 --- a/system/lib/libc/musl/src/locale/isblank_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isblank_l(int c, locale_t l) -{ - return isblank(c); -} diff --git a/system/lib/libc/musl/src/locale/iscntrl_l.c b/system/lib/libc/musl/src/locale/iscntrl_l.c deleted file mode 100644 index ca596fa9d7c76..0000000000000 --- a/system/lib/libc/musl/src/locale/iscntrl_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iscntrl_l(int c, locale_t l) -{ - return iscntrl(c); -} diff --git a/system/lib/libc/musl/src/locale/isdigit_l.c b/system/lib/libc/musl/src/locale/isdigit_l.c deleted file mode 100644 index c8ae7bd319037..0000000000000 --- a/system/lib/libc/musl/src/locale/isdigit_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isdigit_l(int c, locale_t l) -{ - return isdigit(c); -} diff --git a/system/lib/libc/musl/src/locale/isgraph_l.c b/system/lib/libc/musl/src/locale/isgraph_l.c deleted file mode 100644 index 713a86e6956ac..0000000000000 --- a/system/lib/libc/musl/src/locale/isgraph_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isgraph_l(int c, locale_t l) -{ - return isgraph(c); -} diff --git a/system/lib/libc/musl/src/locale/islower_l.c b/system/lib/libc/musl/src/locale/islower_l.c deleted file mode 100644 index 25ec97a12a415..0000000000000 --- a/system/lib/libc/musl/src/locale/islower_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int islower_l(int c, locale_t l) -{ - return islower(c); -} diff --git a/system/lib/libc/musl/src/locale/isprint_l.c b/system/lib/libc/musl/src/locale/isprint_l.c deleted file mode 100644 index 79ef351426975..0000000000000 --- a/system/lib/libc/musl/src/locale/isprint_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isprint_l(int c, locale_t l) -{ - return isprint(c); -} diff --git a/system/lib/libc/musl/src/locale/ispunct_l.c b/system/lib/libc/musl/src/locale/ispunct_l.c deleted file mode 100644 index 1c0bd046ab61b..0000000000000 --- a/system/lib/libc/musl/src/locale/ispunct_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int ispunct_l(int c, locale_t l) -{ - return ispunct(c); -} diff --git a/system/lib/libc/musl/src/locale/isspace_l.c b/system/lib/libc/musl/src/locale/isspace_l.c deleted file mode 100644 index e1a0efed92059..0000000000000 --- a/system/lib/libc/musl/src/locale/isspace_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isspace_l(int c, locale_t l) -{ - return isspace(c); -} diff --git a/system/lib/libc/musl/src/locale/isupper_l.c b/system/lib/libc/musl/src/locale/isupper_l.c deleted file mode 100644 index 11ba703638b53..0000000000000 --- a/system/lib/libc/musl/src/locale/isupper_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isupper_l(int c, locale_t l) -{ - return isupper(c); -} diff --git a/system/lib/libc/musl/src/locale/iswalnum_l.c b/system/lib/libc/musl/src/locale/iswalnum_l.c deleted file mode 100644 index c888060c4ce55..0000000000000 --- a/system/lib/libc/musl/src/locale/iswalnum_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswalnum_l(wint_t c, locale_t l) -{ - return iswalnum(c); -} diff --git a/system/lib/libc/musl/src/locale/iswalpha_l.c b/system/lib/libc/musl/src/locale/iswalpha_l.c deleted file mode 100644 index cd2be91e58281..0000000000000 --- a/system/lib/libc/musl/src/locale/iswalpha_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswalpha_l(wint_t c, locale_t l) -{ - return iswalpha(c); -} diff --git a/system/lib/libc/musl/src/locale/iswblank_l.c b/system/lib/libc/musl/src/locale/iswblank_l.c deleted file mode 100644 index f3a2691f581ff..0000000000000 --- a/system/lib/libc/musl/src/locale/iswblank_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswblank_l(wint_t c, locale_t l) -{ - return iswblank(c); -} diff --git a/system/lib/libc/musl/src/locale/iswcntrl_l.c b/system/lib/libc/musl/src/locale/iswcntrl_l.c deleted file mode 100644 index 7681fe092b6f8..0000000000000 --- a/system/lib/libc/musl/src/locale/iswcntrl_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswcntrl_l(wint_t c, locale_t l) -{ - return iswcntrl(c); -} diff --git a/system/lib/libc/musl/src/locale/iswctype_l.c b/system/lib/libc/musl/src/locale/iswctype_l.c deleted file mode 100644 index 13dfb1ed359f4..0000000000000 --- a/system/lib/libc/musl/src/locale/iswctype_l.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include "libc.h" - -int iswctype_l(wint_t c, wctype_t t, locale_t l) -{ - return iswctype(c, t); -} - -weak_alias(iswctype_l, __iswctype_l); diff --git a/system/lib/libc/musl/src/locale/iswdigit_l.c b/system/lib/libc/musl/src/locale/iswdigit_l.c deleted file mode 100644 index 3de678c24f132..0000000000000 --- a/system/lib/libc/musl/src/locale/iswdigit_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswdigit_l(wint_t c, locale_t l) -{ - return iswdigit(c); -} diff --git a/system/lib/libc/musl/src/locale/iswgraph_l.c b/system/lib/libc/musl/src/locale/iswgraph_l.c deleted file mode 100644 index 34df64fc3ba33..0000000000000 --- a/system/lib/libc/musl/src/locale/iswgraph_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswgraph_l(wint_t c, locale_t l) -{ - return iswgraph(c); -} diff --git a/system/lib/libc/musl/src/locale/iswlower_l.c b/system/lib/libc/musl/src/locale/iswlower_l.c deleted file mode 100644 index c52421a043c86..0000000000000 --- a/system/lib/libc/musl/src/locale/iswlower_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswlower_l(wint_t c, locale_t l) -{ - return iswlower(c); -} diff --git a/system/lib/libc/musl/src/locale/iswprint_l.c b/system/lib/libc/musl/src/locale/iswprint_l.c deleted file mode 100644 index 73d83ab356333..0000000000000 --- a/system/lib/libc/musl/src/locale/iswprint_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswprint_l(wint_t c, locale_t l) -{ - return iswprint(c); -} diff --git a/system/lib/libc/musl/src/locale/iswpunct_l.c b/system/lib/libc/musl/src/locale/iswpunct_l.c deleted file mode 100644 index 831e0e5441963..0000000000000 --- a/system/lib/libc/musl/src/locale/iswpunct_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswpunct_l(wint_t c, locale_t l) -{ - return iswpunct(c); -} diff --git a/system/lib/libc/musl/src/locale/iswspace_l.c b/system/lib/libc/musl/src/locale/iswspace_l.c deleted file mode 100644 index b507e9e3a613c..0000000000000 --- a/system/lib/libc/musl/src/locale/iswspace_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswspace_l(wint_t c, locale_t l) -{ - return iswspace(c); -} diff --git a/system/lib/libc/musl/src/locale/iswupper_l.c b/system/lib/libc/musl/src/locale/iswupper_l.c deleted file mode 100644 index fc988ef119b49..0000000000000 --- a/system/lib/libc/musl/src/locale/iswupper_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswupper_l(wint_t c, locale_t l) -{ - return iswupper(c); -} diff --git a/system/lib/libc/musl/src/locale/iswxdigit_l.c b/system/lib/libc/musl/src/locale/iswxdigit_l.c deleted file mode 100644 index 9527cf3e1d8c6..0000000000000 --- a/system/lib/libc/musl/src/locale/iswxdigit_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int iswxdigit_l(wint_t c, locale_t l) -{ - return iswxdigit(c); -} diff --git a/system/lib/libc/musl/src/locale/isxdigit_l.c b/system/lib/libc/musl/src/locale/isxdigit_l.c deleted file mode 100644 index 68649d093ad9b..0000000000000 --- a/system/lib/libc/musl/src/locale/isxdigit_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int isxdigit_l(int c, locale_t l) -{ - return isxdigit(c); -} diff --git a/system/lib/libc/musl/src/locale/strcasecmp_l.c b/system/lib/libc/musl/src/locale/strcasecmp_l.c deleted file mode 100644 index ca8054308bf1c..0000000000000 --- a/system/lib/libc/musl/src/locale/strcasecmp_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int strcasecmp_l(const char *l, const char *r, locale_t loc) -{ - return strcasecmp(l, r); -} diff --git a/system/lib/libc/musl/src/locale/strerror_l.c b/system/lib/libc/musl/src/locale/strerror_l.c deleted file mode 100644 index 765f5c69feaed..0000000000000 --- a/system/lib/libc/musl/src/locale/strerror_l.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -char *strerror_l(int err, locale_t l) -{ - return strerror(err); -} diff --git a/system/lib/libc/musl/src/locale/strncasecmp_l.c b/system/lib/libc/musl/src/locale/strncasecmp_l.c deleted file mode 100644 index af33ada63b77a..0000000000000 --- a/system/lib/libc/musl/src/locale/strncasecmp_l.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -int strncasecmp_l(const char *l, const char *r, size_t n, locale_t loc) -{ - return strncasecmp(l, r, n); -} diff --git a/system/lib/libc/musl/src/locale/tolower_l.c b/system/lib/libc/musl/src/locale/tolower_l.c deleted file mode 100644 index ba277919e2193..0000000000000 --- a/system/lib/libc/musl/src/locale/tolower_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int tolower_l(int c, locale_t l) -{ - return tolower(c); -} diff --git a/system/lib/libc/musl/src/locale/toupper_l.c b/system/lib/libc/musl/src/locale/toupper_l.c deleted file mode 100644 index 73f2f39be13a1..0000000000000 --- a/system/lib/libc/musl/src/locale/toupper_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int toupper_l(int c, locale_t l) -{ - return toupper(c); -} diff --git a/system/lib/libc/musl/src/locale/towctrans_l.c b/system/lib/libc/musl/src/locale/towctrans_l.c deleted file mode 100644 index 6222058c750cf..0000000000000 --- a/system/lib/libc/musl/src/locale/towctrans_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -wint_t towctrans_l(wint_t c, wctrans_t t, locale_t l) -{ - return towctrans(c, t); -} diff --git a/system/lib/libc/musl/src/locale/towlower_l.c b/system/lib/libc/musl/src/locale/towlower_l.c deleted file mode 100644 index aaaea370f81fa..0000000000000 --- a/system/lib/libc/musl/src/locale/towlower_l.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include "libc.h" - -wint_t towlower_l(wint_t c, locale_t l) -{ - return towlower(c); -} - -weak_alias(towlower_l, __towlower_l); diff --git a/system/lib/libc/musl/src/locale/towupper_l.c b/system/lib/libc/musl/src/locale/towupper_l.c deleted file mode 100644 index ad02a4beab3ec..0000000000000 --- a/system/lib/libc/musl/src/locale/towupper_l.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include "libc.h" - -wint_t towupper_l(wint_t c, locale_t l) -{ - return towupper(c); -} - -weak_alias(towupper_l, __towupper_l); diff --git a/system/lib/libc/musl/src/locale/wctrans_l.c b/system/lib/libc/musl/src/locale/wctrans_l.c deleted file mode 100644 index dae3381e11cf8..0000000000000 --- a/system/lib/libc/musl/src/locale/wctrans_l.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -wctrans_t wctrans_l(const char *s, locale_t l) -{ - return wctrans(s); -} diff --git a/system/lib/libc/musl/src/locale/wctype_l.c b/system/lib/libc/musl/src/locale/wctype_l.c deleted file mode 100644 index 601bab37d163f..0000000000000 --- a/system/lib/libc/musl/src/locale/wctype_l.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include "libc.h" - -wctype_t wctype_l(const char *s, locale_t l) -{ - return wctype(s); -} - -weak_alias(wctype_l, __wctype_l); diff --git a/system/lib/libc/musl/src/math/armebhf/fabs.sub b/system/lib/libc/musl/src/math/armebhf/fabs.sub deleted file mode 100644 index 10d9fb7e40e32..0000000000000 --- a/system/lib/libc/musl/src/math/armebhf/fabs.sub +++ /dev/null @@ -1 +0,0 @@ -../armhf/fabs.s diff --git a/system/lib/libc/musl/src/math/armebhf/fabsf.sub b/system/lib/libc/musl/src/math/armebhf/fabsf.sub deleted file mode 100644 index 940b20bd33dc2..0000000000000 --- a/system/lib/libc/musl/src/math/armebhf/fabsf.sub +++ /dev/null @@ -1 +0,0 @@ -../armhf/fabsf.s diff --git a/system/lib/libc/musl/src/math/armebhf/sqrt.sub b/system/lib/libc/musl/src/math/armebhf/sqrt.sub deleted file mode 100644 index de2be116a1c20..0000000000000 --- a/system/lib/libc/musl/src/math/armebhf/sqrt.sub +++ /dev/null @@ -1 +0,0 @@ -../armhf/sqrt.s diff --git a/system/lib/libc/musl/src/math/armebhf/sqrtf.sub b/system/lib/libc/musl/src/math/armebhf/sqrtf.sub deleted file mode 100644 index 150ab9ccdc207..0000000000000 --- a/system/lib/libc/musl/src/math/armebhf/sqrtf.sub +++ /dev/null @@ -1 +0,0 @@ -../armhf/sqrtf.s diff --git a/system/lib/libc/musl/src/math/armhf/fabs.s b/system/lib/libc/musl/src/math/armhf/fabs.s deleted file mode 100644 index 2bdebff5aeff1..0000000000000 --- a/system/lib/libc/musl/src/math/armhf/fabs.s +++ /dev/null @@ -1,6 +0,0 @@ -.text -.global fabs -.type fabs,%function -fabs: - vabs.f64 d0, d0 - bx lr diff --git a/system/lib/libc/musl/src/math/armhf/fabs.sub b/system/lib/libc/musl/src/math/armhf/fabs.sub deleted file mode 100644 index 99e87406662bb..0000000000000 --- a/system/lib/libc/musl/src/math/armhf/fabs.sub +++ /dev/null @@ -1 +0,0 @@ -fabs.s diff --git a/system/lib/libc/musl/src/math/armhf/fabsf.s b/system/lib/libc/musl/src/math/armhf/fabsf.s deleted file mode 100644 index 35c720fab81db..0000000000000 --- a/system/lib/libc/musl/src/math/armhf/fabsf.s +++ /dev/null @@ -1,6 +0,0 @@ -.text -.global fabsf -.type fabsf,%function -fabsf: - vabs.f32 s0, s0 - bx lr diff --git a/system/lib/libc/musl/src/math/armhf/fabsf.sub b/system/lib/libc/musl/src/math/armhf/fabsf.sub deleted file mode 100644 index c04638aeb7250..0000000000000 --- a/system/lib/libc/musl/src/math/armhf/fabsf.sub +++ /dev/null @@ -1 +0,0 @@ -fabsf.s diff --git a/system/lib/libc/musl/src/math/armhf/sqrt.s b/system/lib/libc/musl/src/math/armhf/sqrt.s deleted file mode 100644 index 99fe64b90b843..0000000000000 --- a/system/lib/libc/musl/src/math/armhf/sqrt.s +++ /dev/null @@ -1,6 +0,0 @@ -.text -.global sqrt -.type sqrt,%function -sqrt: - vsqrt.f64 d0, d0 - bx lr diff --git a/system/lib/libc/musl/src/math/armhf/sqrt.sub b/system/lib/libc/musl/src/math/armhf/sqrt.sub deleted file mode 100644 index 25de7cfa1273c..0000000000000 --- a/system/lib/libc/musl/src/math/armhf/sqrt.sub +++ /dev/null @@ -1 +0,0 @@ -sqrt.s diff --git a/system/lib/libc/musl/src/math/armhf/sqrtf.s b/system/lib/libc/musl/src/math/armhf/sqrtf.s deleted file mode 100644 index 9ea519f600a1c..0000000000000 --- a/system/lib/libc/musl/src/math/armhf/sqrtf.s +++ /dev/null @@ -1,6 +0,0 @@ -.text -.global sqrtf -.type sqrtf,%function -sqrtf: - vsqrt.f32 s0, s0 - bx lr diff --git a/system/lib/libc/musl/src/math/armhf/sqrtf.sub b/system/lib/libc/musl/src/math/armhf/sqrtf.sub deleted file mode 100644 index 3bcbac87a0bb0..0000000000000 --- a/system/lib/libc/musl/src/math/armhf/sqrtf.sub +++ /dev/null @@ -1 +0,0 @@ -sqrtf.s diff --git a/system/lib/libc/musl/src/misc/getgrouplist.c b/system/lib/libc/musl/src/misc/getgrouplist.c deleted file mode 100644 index c9a8f090da19f..0000000000000 --- a/system/lib/libc/musl/src/misc/getgrouplist.c +++ /dev/null @@ -1,24 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include - -int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups) -{ - size_t n, i; - struct group *gr; - if (*ngroups<1) return -1; - n = *ngroups; - *groups++ = gid; - *ngroups = 1; - - setgrent(); - while ((gr = getgrent()) && *ngroups < INT_MAX) { - for (i=0; gr->gr_mem[i] && strcmp(user, gr->gr_mem[i]); i++); - if (!gr->gr_mem[i]) continue; - if (++*ngroups <= n) *groups++ = gr->gr_gid; - } - endgrent(); - - return *ngroups > n ? -1 : *ngroups; -} diff --git a/system/lib/libc/musl/src/network/__dns.c b/system/lib/libc/musl/src/network/__dns.c deleted file mode 100644 index 97d8031ca1d50..0000000000000 --- a/system/lib/libc/musl/src/network/__dns.c +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "__dns.h" -#include "stdio_impl.h" - -#define TIMEOUT 5 -#define RETRY 1000 -#define PACKET_MAX 512 -#define PTR_MAX (64 + sizeof ".in-addr.arpa") - -static void cleanup(void *p) -{ - close((intptr_t)p); -} - -int __dns_doqueries(unsigned char *dest, const char *name, int *rr, int rrcnt) -{ - time_t t0 = time(0); - int fd; - FILE *f, _f; - unsigned char _buf[256]; - char line[64], *s, *z; - union { - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - } sa = {0}, ns[3] = {{0}}; - socklen_t sl = sizeof sa.sin; - int nns = 0; - int family = AF_INET; - unsigned char q[280] = "", *r = dest; - int ql; - int rlen; - int got = 0, failed = 0; - int errcode = EAI_AGAIN; - int i, j; - struct timespec ts; - struct pollfd pfd; - int id; - int cs; - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); - - /* Construct query template - RR and ID will be filled later */ - if (strlen(name)-1 >= 254U) return EAI_NONAME; - q[2] = q[5] = 1; - strcpy((char *)q+13, name); - for (i=13; q[i]; i=j+1) { - for (j=i; q[j] && q[j] != '.'; j++); - if (j-i-1u > 62u) return EAI_NONAME; - q[i-1] = j-i; - } - q[i+3] = 1; - ql = i+4; - - /* Make a reasonably unpredictable id */ - clock_gettime(CLOCK_REALTIME, &ts); - id = ts.tv_nsec + ts.tv_nsec/65536UL & 0xffff; - - /* Get nameservers from resolv.conf, fallback to localhost */ - f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf); - if (f) for (nns=0; nns<3 && fgets(line, sizeof line, f); ) { - if (strncmp(line, "nameserver", 10) || !isspace(line[10])) - continue; - for (s=line+11; isspace(*s); s++); - for (z=s; *z && !isspace(*z); z++); - *z=0; - if (__ipparse(ns+nns, AF_UNSPEC, s) < 0) continue; - ns[nns].sin.sin_port = htons(53); - if (ns[nns++].sin.sin_family == AF_INET6) { - family = AF_INET6; - sl = sizeof sa.sin6; - } - } - if (f) __fclose_ca(f); - if (!nns) { - ns[0].sin.sin_family = family = AF_INET; - ns[0].sin.sin_port = htons(53); - ns[0].sin.sin_addr.s_addr = htonl(0x7f000001); - nns=1; - sl = sizeof sa.sin; - } - - /* Get local address and open/bind a socket */ - sa.sin.sin_family = family; - fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); - - /* Handle case where system lacks IPv6 support */ - if (fd < 0 && errno == EAFNOSUPPORT) { - if (family != AF_INET6) return EAI_SYSTEM; - fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); - family = AF_INET; - } - if (fd < 0) return EAI_SYSTEM; - - /* Convert any IPv4 addresses in a mixed environment to v4-mapped */ - if (family == AF_INET6) { - setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0); - for (i=0; i> 8; - q[1] = id+i; - q[ql-3] = rr[i]; - sendto(fd, q, ql, MSG_NOSIGNAL, (void *)&ns[j], sl); - } - - /* Wait for a response, or until time to retry */ - if (poll(&pfd, 1, RETRY) <= 0) continue; - - /* Process any and all replies */ - while (got+failed < rrcnt && (rlen = recvfrom(fd, r, 512, 0, - (void *)&sa, (socklen_t[1]){sl})) >= 2) - { - /* Ignore replies from addresses we didn't send to */ - for (i=0; i= rrcnt || !rr[i]) continue; - - /* Interpret the result code */ - switch (r[3] & 15) { - case 0: - got++; - break; - case 3: - if (1) errcode = EAI_NONAME; else - default: - errcode = EAI_FAIL; - failed++; - } - - /* Mark this record as answered */ - rr[i] = 0; - r += 512; - } - - /* Check to see if we have answers to all queries */ - if (got+failed == rrcnt) break; - } -out: - pthread_cleanup_pop(1); - - /* Return the number of results, or an error code if none */ - if (got) return got; - return errcode; -} - -static void mkptr4(char *s, const unsigned char *ip) -{ - sprintf(s, "%d.%d.%d.%d.in-addr.arpa", - ip[3], ip[2], ip[1], ip[0]); -} - -static void mkptr6(char *s, const unsigned char *ip) -{ - static const char xdigits[] = "0123456789abcdef"; - int i; - for (i=15; i>=0; i--) { - *s++ = xdigits[ip[i]&15]; *s++ = '.'; - *s++ = xdigits[ip[i]>>4]; *s++ = '.'; - } - strcpy(s, "ip6.arpa"); -} - -int __dns_query(unsigned char *r, const void *a, int family, int ptr) -{ - char buf[PTR_MAX]; - int rr[2], rrcnt = 1; - - if (ptr) { - if (family == AF_INET6) mkptr6(buf, a); - else mkptr4(buf, a); - rr[0] = RR_PTR; - a = buf; - } else if (family == AF_INET6) { - rr[0] = RR_AAAA; - } else { - rr[0] = RR_A; - if (family != AF_INET) rr[rrcnt++] = RR_AAAA; - } - - return __dns_doqueries(r, a, rr, rrcnt); -} - -int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int); - -int __dns_get_rr(void *dest, size_t stride, size_t maxlen, size_t limit, const unsigned char *r, int rr, int dec) -{ - int qdcount, ancount; - const unsigned char *p; - char tmp[256]; - int found = 0; - int len; - - if ((r[3]&15)) return 0; - p = r+12; - qdcount = r[4]*256 + r[5]; - ancount = r[6]*256 + r[7]; - if (qdcount+ancount > 64) return -1; - while (qdcount--) { - while (p-r < 512 && *p-1U < 127) p++; - if (*p>193 || (*p==193 && p[1]>254) || p>r+506) - return -1; - p += 5 + !!*p; - } - while (ancount--) { - while (p-r < 512 && *p-1U < 127) p++; - if (*p>193 || (*p==193 && p[1]>254) || p>r+506) - return -1; - p += 1 + !!*p; - len = p[8]*256 + p[9]; - if (p+len > r+512) return -1; - if (p[1]==rr && len <= maxlen) { - if (dec && __dn_expand(r, r+512, p+10, tmp, sizeof tmp)<0) - return -1; - if (dest && limit) { - if (dec) strcpy(dest, tmp); - else memcpy(dest, p+10, len); - dest = (char *)dest + stride; - limit--; - } - found++; - } - p += 10 + len; - } - return found; -} - -int __dns_count_addrs(const unsigned char *r, int cnt) -{ - int found=0, res, i; - static const int p[2][2] = { { 4, RR_A }, { 16, RR_AAAA } }; - - while (cnt--) { - for (i=0; i<2; i++) { - res = __dns_get_rr(0, 0, p[i][0], -1, r, p[i][1], 0); - if (res < 0) return res; - found += res; - } - r += 512; - } - return found; -} diff --git a/system/lib/libc/musl/src/network/__dns.h b/system/lib/libc/musl/src/network/__dns.h deleted file mode 100644 index 9a3f7402a13f4..0000000000000 --- a/system/lib/libc/musl/src/network/__dns.h +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#define RR_A 1 -#define RR_CNAME 5 -#define RR_PTR 12 -#define RR_AAAA 28 - -int __dns_count_addrs(const unsigned char *, int); -int __dns_get_rr(void *, size_t, size_t, size_t, const unsigned char *, int, int); - -int __dns_query(unsigned char *, const void *, int, int); -int __ipparse(void *, int, const char *); - -int __dns_doqueries(unsigned char *, const char *, int *, int); diff --git a/system/lib/libc/musl/src/network/__ipparse.c b/system/lib/libc/musl/src/network/__ipparse.c deleted file mode 100644 index 79f3b8cfeedfd..0000000000000 --- a/system/lib/libc/musl/src/network/__ipparse.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include "__dns.h" - -int __ipparse(void *dest, int family, const char *s0) -{ - const char *s = s0; - unsigned char *d = dest; - unsigned long a[16] = { 0 }; - char *z; - int i; - - if (family == AF_INET6) goto not_v4; - - for (i=0; i<4; i++) { - a[i] = strtoul(s, &z, 0); - if (z==s || (*z && *z != '.') || !isdigit(*s)) { - if (family == AF_INET) return -1; - goto not_v4; - } - if (!*z) break; - s=z+1; - } - if (i==4) return -1; - switch (i) { - case 0: - a[1] = a[0] & 0xffffff; - a[0] >>= 24; - case 1: - a[2] = a[1] & 0xffff; - a[1] >>= 16; - case 2: - a[3] = a[2] & 0xff; - a[2] >>= 8; - } - ((struct sockaddr_in *)d)->sin_family = AF_INET; - d = (void *)&((struct sockaddr_in *)d)->sin_addr; - for (i=0; i<4; i++) { - if (a[i] > 255) return -1; - d[i] = a[i]; - } - return 0; - -not_v4: - s = s0; - ((struct sockaddr_in6 *)d)->sin6_family = AF_INET6; - return inet_pton(AF_INET6, s, (void *)&((struct sockaddr_in6 *)d)->sin6_addr) <= 0 ? -1 : 0; -} diff --git a/system/lib/libc/musl/src/setjmp/mips-sf/longjmp.s b/system/lib/libc/musl/src/setjmp/mips-sf/longjmp.s deleted file mode 100644 index 8e7696759c5de..0000000000000 --- a/system/lib/libc/musl/src/setjmp/mips-sf/longjmp.s +++ /dev/null @@ -1,25 +0,0 @@ -.set noreorder - -.global _longjmp -.global longjmp -.type _longjmp,@function -.type longjmp,@function -_longjmp: -longjmp: - move $2, $5 - bne $2, $0, 1f - nop - addu $2, $2, 1 -1: lw $ra, 0($4) - lw $sp, 4($4) - lw $16, 8($4) - lw $17, 12($4) - lw $18, 16($4) - lw $19, 20($4) - lw $20, 24($4) - lw $21, 28($4) - lw $22, 32($4) - lw $23, 36($4) - lw $30, 40($4) - jr $ra - lw $28, 44($4) diff --git a/system/lib/libc/musl/src/setjmp/mips-sf/longjmp.sub b/system/lib/libc/musl/src/setjmp/mips-sf/longjmp.sub deleted file mode 100644 index e80331b6541f9..0000000000000 --- a/system/lib/libc/musl/src/setjmp/mips-sf/longjmp.sub +++ /dev/null @@ -1 +0,0 @@ -longjmp.s diff --git a/system/lib/libc/musl/src/setjmp/mips-sf/setjmp.s b/system/lib/libc/musl/src/setjmp/mips-sf/setjmp.s deleted file mode 100644 index 38ed5e00d6056..0000000000000 --- a/system/lib/libc/musl/src/setjmp/mips-sf/setjmp.s +++ /dev/null @@ -1,25 +0,0 @@ -.set noreorder - -.global __setjmp -.global _setjmp -.global setjmp -.type __setjmp,@function -.type _setjmp,@function -.type setjmp,@function -__setjmp: -_setjmp: -setjmp: - sw $ra, 0($4) - sw $sp, 4($4) - sw $16, 8($4) - sw $17, 12($4) - sw $18, 16($4) - sw $19, 20($4) - sw $20, 24($4) - sw $21, 28($4) - sw $22, 32($4) - sw $23, 36($4) - sw $30, 40($4) - sw $28, 44($4) - jr $ra - li $2, 0 diff --git a/system/lib/libc/musl/src/setjmp/mips-sf/setjmp.sub b/system/lib/libc/musl/src/setjmp/mips-sf/setjmp.sub deleted file mode 100644 index b7ad221051dd4..0000000000000 --- a/system/lib/libc/musl/src/setjmp/mips-sf/setjmp.sub +++ /dev/null @@ -1 +0,0 @@ -setjmp.s diff --git a/system/lib/libc/musl/src/setjmp/mipsel-sf/longjmp.sub b/system/lib/libc/musl/src/setjmp/mipsel-sf/longjmp.sub deleted file mode 100644 index 6907202918ce4..0000000000000 --- a/system/lib/libc/musl/src/setjmp/mipsel-sf/longjmp.sub +++ /dev/null @@ -1 +0,0 @@ -../mips-sf/longjmp.s diff --git a/system/lib/libc/musl/src/setjmp/mipsel-sf/setjmp.sub b/system/lib/libc/musl/src/setjmp/mipsel-sf/setjmp.sub deleted file mode 100644 index 991747580bcb3..0000000000000 --- a/system/lib/libc/musl/src/setjmp/mipsel-sf/setjmp.sub +++ /dev/null @@ -1 +0,0 @@ -../mips-sf/setjmp.s diff --git a/system/lib/libc/musl/src/setjmp/sh-nofpu/longjmp.s b/system/lib/libc/musl/src/setjmp/sh-nofpu/longjmp.s deleted file mode 100644 index cda482c547876..0000000000000 --- a/system/lib/libc/musl/src/setjmp/sh-nofpu/longjmp.s +++ /dev/null @@ -1,22 +0,0 @@ -.global _longjmp -.global longjmp -.type _longjmp, @function -.type longjmp, @function -_longjmp: -longjmp: - mov.l @r4+, r8 - mov.l @r4+, r9 - mov.l @r4+, r10 - mov.l @r4+, r11 - mov.l @r4+, r12 - mov.l @r4+, r13 - mov.l @r4+, r14 - mov.l @r4+, r15 - lds.l @r4+, pr - - tst r5, r5 - movt r0 - add r5, r0 - - rts - nop diff --git a/system/lib/libc/musl/src/setjmp/sh-nofpu/longjmp.sub b/system/lib/libc/musl/src/setjmp/sh-nofpu/longjmp.sub deleted file mode 100644 index e80331b6541f9..0000000000000 --- a/system/lib/libc/musl/src/setjmp/sh-nofpu/longjmp.sub +++ /dev/null @@ -1 +0,0 @@ -longjmp.s diff --git a/system/lib/libc/musl/src/setjmp/sh-nofpu/setjmp.s b/system/lib/libc/musl/src/setjmp/sh-nofpu/setjmp.s deleted file mode 100644 index c6c7359a0cfa8..0000000000000 --- a/system/lib/libc/musl/src/setjmp/sh-nofpu/setjmp.s +++ /dev/null @@ -1,21 +0,0 @@ -.global __setjmp -.global _setjmp -.global setjmp -.type __setjmp, @function -.type _setjmp, @function -.type setjmp, @function -__setjmp: -_setjmp: -setjmp: - add #36, r4 - sts.l pr, @-r4 - mov.l r15 @-r4 - mov.l r14, @-r4 - mov.l r13, @-r4 - mov.l r12, @-r4 - mov.l r11, @-r4 - mov.l r10, @-r4 - mov.l r9, @-r4 - mov.l r8, @-r4 - rts - mov #0, r0 diff --git a/system/lib/libc/musl/src/setjmp/sh-nofpu/setjmp.sub b/system/lib/libc/musl/src/setjmp/sh-nofpu/setjmp.sub deleted file mode 100644 index b7ad221051dd4..0000000000000 --- a/system/lib/libc/musl/src/setjmp/sh-nofpu/setjmp.sub +++ /dev/null @@ -1 +0,0 @@ -setjmp.s diff --git a/system/lib/libc/musl/src/setjmp/sheb-nofpu/longjmp.sub b/system/lib/libc/musl/src/setjmp/sheb-nofpu/longjmp.sub deleted file mode 100644 index 62fcd2b16c0da..0000000000000 --- a/system/lib/libc/musl/src/setjmp/sheb-nofpu/longjmp.sub +++ /dev/null @@ -1 +0,0 @@ -../sh-nofpu/longjmp.s diff --git a/system/lib/libc/musl/src/setjmp/sheb-nofpu/setjmp.sub b/system/lib/libc/musl/src/setjmp/sheb-nofpu/setjmp.sub deleted file mode 100644 index a5bb294cd9d06..0000000000000 --- a/system/lib/libc/musl/src/setjmp/sheb-nofpu/setjmp.sub +++ /dev/null @@ -1 +0,0 @@ -../sh-nofpu/setjmp.s diff --git a/system/lib/libc/musl/src/string/armel/memcpy.s b/system/lib/libc/musl/src/string/armel/memcpy.s deleted file mode 100644 index 9f24a4f332a34..0000000000000 --- a/system/lib/libc/musl/src/string/armel/memcpy.s +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -/* - * Optimized memcpy() for ARM. - * - * note that memcpy() always returns the destination pointer, - * so we have to preserve R0. - */ - -/* - * This file has been modified from the original for use in musl libc. - * The main changes are: addition of .type memcpy,%function to make the - * code safely callable from thumb mode, adjusting the return - * instructions to be compatible with pre-thumb ARM cpus, and removal - * of prefetch code that is not compatible with older cpus. - */ - -.global memcpy -.type memcpy,%function -memcpy: - /* The stack must always be 64-bits aligned to be compliant with the - * ARM ABI. Since we have to save R0, we might as well save R4 - * which we can use for better pipelining of the reads below - */ - .fnstart - .save {r0, r4, lr} - stmfd sp!, {r0, r4, lr} - /* Making room for r5-r11 which will be spilled later */ - .pad #28 - sub sp, sp, #28 - - /* it simplifies things to take care of len<4 early */ - cmp r2, #4 - blo copy_last_3_and_return - - /* compute the offset to align the source - * offset = (4-(src&3))&3 = -src & 3 - */ - rsb r3, r1, #0 - ands r3, r3, #3 - beq src_aligned - - /* align source to 32 bits. We need to insert 2 instructions between - * a ldr[b|h] and str[b|h] because byte and half-word instructions - * stall 2 cycles. - */ - movs r12, r3, lsl #31 - sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */ - ldrmib r3, [r1], #1 - ldrcsb r4, [r1], #1 - ldrcsb r12,[r1], #1 - strmib r3, [r0], #1 - strcsb r4, [r0], #1 - strcsb r12,[r0], #1 - -src_aligned: - - /* see if src and dst are aligned together (congruent) */ - eor r12, r0, r1 - tst r12, #3 - bne non_congruent - - /* Use post-incriment mode for stm to spill r5-r11 to reserved stack - * frame. Don't update sp. - */ - stmea sp, {r5-r11} - - /* align the destination to a cache-line */ - rsb r3, r0, #0 - ands r3, r3, #0x1C - beq congruent_aligned32 - cmp r3, r2 - andhi r3, r2, #0x1C - - /* conditionnaly copies 0 to 7 words (length in r3) */ - movs r12, r3, lsl #28 - ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */ - ldmmiia r1!, {r8, r9} /* 8 bytes */ - stmcsia r0!, {r4, r5, r6, r7} - stmmiia r0!, {r8, r9} - tst r3, #0x4 - ldrne r10,[r1], #4 /* 4 bytes */ - strne r10,[r0], #4 - sub r2, r2, r3 - -congruent_aligned32: - /* - * here source is aligned to 32 bytes. - */ - -cached_aligned32: - subs r2, r2, #32 - blo less_than_32_left - - /* - * We preload a cache-line up to 64 bytes ahead. On the 926, this will - * stall only until the requested world is fetched, but the linefill - * continues in the the background. - * While the linefill is going, we write our previous cache-line - * into the write-buffer (which should have some free space). - * When the linefill is done, the writebuffer will - * start dumping its content into memory - * - * While all this is going, we then load a full cache line into - * 8 registers, this cache line should be in the cache by now - * (or partly in the cache). - * - * This code should work well regardless of the source/dest alignment. - * - */ - - /* Align the preload register to a cache-line because the cpu does - * "critical word first" (the first word requested is loaded first). - */ - @ bic r12, r1, #0x1F - @ add r12, r12, #64 - -1: ldmia r1!, { r4-r11 } - subs r2, r2, #32 - - /* - * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi - * for ARM9 preload will not be safely guarded by the preceding subs. - * When it is safely guarded the only possibility to have SIGSEGV here - * is because the caller overstates the length. - */ - @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */ - stmia r0!, { r4-r11 } - bhs 1b - - add r2, r2, #32 - -less_than_32_left: - /* - * less than 32 bytes left at this point (length in r2) - */ - - /* skip all this if there is nothing to do, which should - * be a common case (if not executed the code below takes - * about 16 cycles) - */ - tst r2, #0x1F - beq 1f - - /* conditionnaly copies 0 to 31 bytes */ - movs r12, r2, lsl #28 - ldmcsia r1!, {r4, r5, r6, r7} /* 16 bytes */ - ldmmiia r1!, {r8, r9} /* 8 bytes */ - stmcsia r0!, {r4, r5, r6, r7} - stmmiia r0!, {r8, r9} - movs r12, r2, lsl #30 - ldrcs r3, [r1], #4 /* 4 bytes */ - ldrmih r4, [r1], #2 /* 2 bytes */ - strcs r3, [r0], #4 - strmih r4, [r0], #2 - tst r2, #0x1 - ldrneb r3, [r1] /* last byte */ - strneb r3, [r0] - - /* we're done! restore everything and return */ -1: ldmfd sp!, {r5-r11} - ldmfd sp!, {r0, r4, lr} - tst lr, #1 - moveq pc, lr - bx lr - - /********************************************************************/ - -non_congruent: - /* - * here source is aligned to 4 bytes - * but destination is not. - * - * in the code below r2 is the number of bytes read - * (the number of bytes written is always smaller, because we have - * partial words in the shift queue) - */ - cmp r2, #4 - blo copy_last_3_and_return - - /* Use post-incriment mode for stm to spill r5-r11 to reserved stack - * frame. Don't update sp. - */ - stmea sp, {r5-r11} - - /* compute shifts needed to align src to dest */ - rsb r5, r0, #0 - and r5, r5, #3 /* r5 = # bytes in partial words */ - mov r12, r5, lsl #3 /* r12 = right */ - rsb lr, r12, #32 /* lr = left */ - - /* read the first word */ - ldr r3, [r1], #4 - sub r2, r2, #4 - - /* write a partial word (0 to 3 bytes), such that destination - * becomes aligned to 32 bits (r5 = nb of words to copy for alignment) - */ - movs r5, r5, lsl #31 - strmib r3, [r0], #1 - movmi r3, r3, lsr #8 - strcsb r3, [r0], #1 - movcs r3, r3, lsr #8 - strcsb r3, [r0], #1 - movcs r3, r3, lsr #8 - - cmp r2, #4 - blo partial_word_tail - - /* Align destination to 32 bytes (cache line boundary) */ -1: tst r0, #0x1c - beq 2f - ldr r5, [r1], #4 - sub r2, r2, #4 - orr r4, r3, r5, lsl lr - mov r3, r5, lsr r12 - str r4, [r0], #4 - cmp r2, #4 - bhs 1b - blo partial_word_tail - - /* copy 32 bytes at a time */ -2: subs r2, r2, #32 - blo less_than_thirtytwo - - /* Use immediate mode for the shifts, because there is an extra cycle - * for register shifts, which could account for up to 50% of - * performance hit. - */ - - cmp r12, #24 - beq loop24 - cmp r12, #8 - beq loop8 - -loop16: - ldr r12, [r1], #4 -1: mov r4, r12 - ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} - subs r2, r2, #32 - ldrhs r12, [r1], #4 - orr r3, r3, r4, lsl #16 - mov r4, r4, lsr #16 - orr r4, r4, r5, lsl #16 - mov r5, r5, lsr #16 - orr r5, r5, r6, lsl #16 - mov r6, r6, lsr #16 - orr r6, r6, r7, lsl #16 - mov r7, r7, lsr #16 - orr r7, r7, r8, lsl #16 - mov r8, r8, lsr #16 - orr r8, r8, r9, lsl #16 - mov r9, r9, lsr #16 - orr r9, r9, r10, lsl #16 - mov r10, r10, lsr #16 - orr r10, r10, r11, lsl #16 - stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} - mov r3, r11, lsr #16 - bhs 1b - b less_than_thirtytwo - -loop8: - ldr r12, [r1], #4 -1: mov r4, r12 - ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} - subs r2, r2, #32 - ldrhs r12, [r1], #4 - orr r3, r3, r4, lsl #24 - mov r4, r4, lsr #8 - orr r4, r4, r5, lsl #24 - mov r5, r5, lsr #8 - orr r5, r5, r6, lsl #24 - mov r6, r6, lsr #8 - orr r6, r6, r7, lsl #24 - mov r7, r7, lsr #8 - orr r7, r7, r8, lsl #24 - mov r8, r8, lsr #8 - orr r8, r8, r9, lsl #24 - mov r9, r9, lsr #8 - orr r9, r9, r10, lsl #24 - mov r10, r10, lsr #8 - orr r10, r10, r11, lsl #24 - stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} - mov r3, r11, lsr #8 - bhs 1b - b less_than_thirtytwo - -loop24: - ldr r12, [r1], #4 -1: mov r4, r12 - ldmia r1!, { r5,r6,r7, r8,r9,r10,r11} - subs r2, r2, #32 - ldrhs r12, [r1], #4 - orr r3, r3, r4, lsl #8 - mov r4, r4, lsr #24 - orr r4, r4, r5, lsl #8 - mov r5, r5, lsr #24 - orr r5, r5, r6, lsl #8 - mov r6, r6, lsr #24 - orr r6, r6, r7, lsl #8 - mov r7, r7, lsr #24 - orr r7, r7, r8, lsl #8 - mov r8, r8, lsr #24 - orr r8, r8, r9, lsl #8 - mov r9, r9, lsr #24 - orr r9, r9, r10, lsl #8 - mov r10, r10, lsr #24 - orr r10, r10, r11, lsl #8 - stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10} - mov r3, r11, lsr #24 - bhs 1b - -less_than_thirtytwo: - /* copy the last 0 to 31 bytes of the source */ - rsb r12, lr, #32 /* we corrupted r12, recompute it */ - add r2, r2, #32 - cmp r2, #4 - blo partial_word_tail - -1: ldr r5, [r1], #4 - sub r2, r2, #4 - orr r4, r3, r5, lsl lr - mov r3, r5, lsr r12 - str r4, [r0], #4 - cmp r2, #4 - bhs 1b - -partial_word_tail: - /* we have a partial word in the input buffer */ - movs r5, lr, lsl #(31-3) - strmib r3, [r0], #1 - movmi r3, r3, lsr #8 - strcsb r3, [r0], #1 - movcs r3, r3, lsr #8 - strcsb r3, [r0], #1 - - /* Refill spilled registers from the stack. Don't update sp. */ - ldmfd sp, {r5-r11} - -copy_last_3_and_return: - movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */ - ldrmib r2, [r1], #1 - ldrcsb r3, [r1], #1 - ldrcsb r12,[r1] - strmib r2, [r0], #1 - strcsb r3, [r0], #1 - strcsb r12,[r0] - - /* we're done! restore sp and spilled registers and return */ - add sp, sp, #28 - ldmfd sp!, {r0, r4, lr} - tst lr, #1 - moveq pc, lr - bx lr diff --git a/system/lib/libc/musl/src/string/armel/memcpy.sub b/system/lib/libc/musl/src/string/armel/memcpy.sub deleted file mode 100644 index 543f583fdf9e2..0000000000000 --- a/system/lib/libc/musl/src/string/armel/memcpy.sub +++ /dev/null @@ -1 +0,0 @@ -memcpy.s diff --git a/system/lib/libc/musl/src/string/armhf/memcpy.sub b/system/lib/libc/musl/src/string/armhf/memcpy.sub deleted file mode 100644 index add0590cf0e7e..0000000000000 --- a/system/lib/libc/musl/src/string/armhf/memcpy.sub +++ /dev/null @@ -1 +0,0 @@ -../armel/memcpy.s diff --git a/system/lib/libc/musl/src/thread/cancel_dummy.c b/system/lib/libc/musl/src/thread/cancel_dummy.c deleted file mode 100644 index b630b02c79153..0000000000000 --- a/system/lib/libc/musl/src/thread/cancel_dummy.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "pthread_impl.h" -#include "syscall.h" - -static long sccp(syscall_arg_t nr, - syscall_arg_t u, syscall_arg_t v, syscall_arg_t w, - syscall_arg_t x, syscall_arg_t y, syscall_arg_t z) -{ - return (__syscall)(nr, u, v, w, x, y, z); -} - -weak_alias(sccp, __syscall_cp); - -static void dummy() -{ -} - -weak_alias(dummy, __testcancel); diff --git a/system/lib/libc/musl/src/thread/cancel_impl.c b/system/lib/libc/musl/src/thread/cancel_impl.c deleted file mode 100644 index c835813a30f02..0000000000000 --- a/system/lib/libc/musl/src/thread/cancel_impl.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "pthread_impl.h" -#include "syscall.h" - -void __cancel() -{ - pthread_t self = __pthread_self(); - self->canceldisable = 1; - self->cancelasync = 0; - pthread_exit(PTHREAD_CANCELED); -} - -long __syscall_cp_asm(volatile void *, syscall_arg_t, - syscall_arg_t, syscall_arg_t, syscall_arg_t, - syscall_arg_t, syscall_arg_t, syscall_arg_t); - -long (__syscall_cp)(syscall_arg_t nr, - syscall_arg_t u, syscall_arg_t v, syscall_arg_t w, - syscall_arg_t x, syscall_arg_t y, syscall_arg_t z) -{ - pthread_t self; - long r; - - if (!libc.main_thread || (self = __pthread_self())->canceldisable) - return __syscall(nr, u, v, w, x, y, z); - - r = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z); - if (r==-EINTR && nr!=SYS_close && self->cancel && !self->canceldisable) - __cancel(); - return r; -} - -static void _sigaddset(sigset_t *set, int sig) -{ - unsigned s = sig-1; - set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1); -} - -static void cancel_handler(int sig, siginfo_t *si, void *ctx) -{ - pthread_t self = __pthread_self(); - ucontext_t *uc = ctx; - const char *ip = ((char **)&uc->uc_mcontext)[CANCEL_REG_IP]; - extern const char __cp_begin[1], __cp_end[1]; - - if (!self->cancel || self->canceldisable) return; - - _sigaddset(&uc->uc_sigmask, SIGCANCEL); - - if (self->cancelasync || ip >= __cp_begin && ip < __cp_end) { - self->canceldisable = 1; - pthread_sigmask(SIG_SETMASK, &uc->uc_sigmask, 0); - __cancel(); - } - - __syscall(SYS_tgkill, self->pid, self->tid, SIGCANCEL); -} - -void __testcancel() -{ - pthread_t self = pthread_self(); - if (self->cancel && !self->canceldisable) - __cancel(); -} - -static void init_cancellation() -{ - struct sigaction sa = { - .sa_flags = SA_SIGINFO | SA_RESTART, - .sa_sigaction = cancel_handler - }; - sigfillset(&sa.sa_mask); - __libc_sigaction(SIGCANCEL, &sa, 0); -} - -int pthread_cancel(pthread_t t) -{ - static int init; - if (!init) { - init_cancellation(); - init = 1; - } - a_store(&t->cancel, 1); - return pthread_kill(t, SIGCANCEL); -} diff --git a/system/lib/libc/musl/src/thread/cancellation.c b/system/lib/libc/musl/src/thread/cancellation.c deleted file mode 100644 index 9b21764b56b0b..0000000000000 --- a/system/lib/libc/musl/src/thread/cancellation.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "pthread_impl.h" - -static void dummy(struct __ptcb *cb) -{ -} -weak_alias(dummy, __do_cleanup_push); -weak_alias(dummy, __do_cleanup_pop); - -void _pthread_cleanup_push(struct __ptcb *cb, void (*f)(void *), void *x) -{ - cb->__f = f; - cb->__x = x; - __do_cleanup_push(cb); -} - -void _pthread_cleanup_pop(struct __ptcb *cb, int run) -{ - __do_cleanup_pop(cb); - if (run) cb->__f(cb->__x); -} diff --git a/tests/other/metadce/hello_libcxx_fastcomp_O2.funcs b/tests/other/metadce/hello_libcxx_fastcomp_O2.funcs index a6061b36c8376..1d7294c2b7a31 100644 --- a/tests/other/metadce/hello_libcxx_fastcomp_O2.funcs +++ b/tests/other/metadce/hello_libcxx_fastcomp_O2.funcs @@ -409,6 +409,7 @@ $___floatscan $___fwritex $___get_locale $___intscan +$___isxdigit_l $___loc_is_allocated $___munmap $___newlocale @@ -448,7 +449,6 @@ $_getint $_hexfloat $_isdigit $_isspace -$_isxdigit_l $_main $_malloc $_mbrtowc diff --git a/tests/other/metadce/hello_libcxx_fastcomp_O2_EMULATED_FUNCTION_POINTERS.funcs b/tests/other/metadce/hello_libcxx_fastcomp_O2_EMULATED_FUNCTION_POINTERS.funcs index f64a50b9a4bd2..75bb19cb1c43c 100644 --- a/tests/other/metadce/hello_libcxx_fastcomp_O2_EMULATED_FUNCTION_POINTERS.funcs +++ b/tests/other/metadce/hello_libcxx_fastcomp_O2_EMULATED_FUNCTION_POINTERS.funcs @@ -409,6 +409,7 @@ $___floatscan $___fwritex $___get_locale $___intscan +$___isxdigit_l $___loc_is_allocated $___munmap $___newlocale @@ -448,7 +449,6 @@ $_getint $_hexfloat $_isdigit $_isspace -$_isxdigit_l $_main $_malloc $_mbrtowc