diff options
Diffstat (limited to 'main/musl/0002-66fcde4a-to-3fa2eb2a.patch')
-rw-r--r-- | main/musl/0002-66fcde4a-to-3fa2eb2a.patch | 1194 |
1 files changed, 0 insertions, 1194 deletions
diff --git a/main/musl/0002-66fcde4a-to-3fa2eb2a.patch b/main/musl/0002-66fcde4a-to-3fa2eb2a.patch deleted file mode 100644 index 5b30442f06..0000000000 --- a/main/musl/0002-66fcde4a-to-3fa2eb2a.patch +++ /dev/null @@ -1,1194 +0,0 @@ -diff --git a/Makefile b/Makefile -index 0ab0bfd..d5a64fc 100644 ---- a/Makefile -+++ b/Makefile -@@ -125,7 +125,7 @@ $(foreach s,$(wildcard src/*/$(ARCH)*/*.s),$(eval $(call mkasmdep,$(s)))) - - lib/libc.so: $(LOBJS) - $(CC) $(CFLAGS_ALL_SHARED) $(LDFLAGS) -nostdlib -shared \ -- -Wl,-e,_start -Wl,-Bsymbolic-functions \ -+ -Wl,-e,_dlstart -Wl,-Bsymbolic-functions \ - -o $@ $(LOBJS) $(LIBCC) - - lib/libc.a: $(OBJS) -diff --git a/arch/arm/reloc.h b/arch/arm/reloc.h -index 264b7ab..ee39b7f 100644 ---- a/arch/arm/reloc.h -+++ b/arch/arm/reloc.h -@@ -16,41 +16,29 @@ - - #define LDSO_ARCH "arm" ENDIAN_SUFFIX FP_SUFFIX - --#define IS_COPY(x) ((x)==R_ARM_COPY) --#define IS_PLT(x) ((x)==R_ARM_JUMP_SLOT) -+#define NO_LEGACY_INITFINI -+ -+#define TPOFF_K 8 - --static inline void do_single_reloc( -- struct dso *self, unsigned char *base_addr, -- size_t *reloc_addr, int type, size_t addend, -- Sym *sym, size_t sym_size, -- struct symdef def, size_t sym_val) -+static int remap_rel(int type) - { - switch(type) { - case R_ARM_ABS32: -- *reloc_addr += sym_val; -- break; -+ return REL_SYMBOLIC; - case R_ARM_GLOB_DAT: -+ return REL_GOT; - case R_ARM_JUMP_SLOT: -- *reloc_addr = sym_val; -- break; -+ return REL_PLT; - case R_ARM_RELATIVE: -- *reloc_addr += (size_t)base_addr; -- break; -+ return REL_RELATIVE; - case R_ARM_COPY: -- memcpy(reloc_addr, (void *)sym_val, sym_size); -- break; -+ return REL_COPY; - case R_ARM_TLS_DTPMOD32: -- *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; -- break; -+ return REL_DTPMOD; - case R_ARM_TLS_DTPOFF32: -- *reloc_addr += def.sym->st_value; -- break; -+ return REL_DTPOFF; - case R_ARM_TLS_TPOFF32: -- *reloc_addr += def.sym -- ? def.sym->st_value + def.dso->tls_offset + 8 -- : self->tls_offset + 8; -- break; -+ return REL_TPOFF; - } -+ return 0; - } -- --#define NO_LEGACY_INITFINI -diff --git a/arch/i386/reloc.h b/arch/i386/reloc.h -index 3923b54..eaf5aae 100644 ---- a/arch/i386/reloc.h -+++ b/arch/i386/reloc.h -@@ -3,47 +3,31 @@ - - #define LDSO_ARCH "i386" - --#define IS_COPY(x) ((x)==R_386_COPY) --#define IS_PLT(x) ((x)==R_386_JMP_SLOT) -- --static inline void do_single_reloc( -- struct dso *self, unsigned char *base_addr, -- size_t *reloc_addr, int type, size_t addend, -- Sym *sym, size_t sym_size, -- struct symdef def, size_t sym_val) -+static int remap_rel(int type) - { - switch(type) { - case R_386_32: -- *reloc_addr += sym_val; -- break; -+ return REL_SYMBOLIC; - case R_386_PC32: -- *reloc_addr += sym_val - (size_t)reloc_addr; -- break; -+ return REL_OFFSET; - case R_386_GLOB_DAT: -+ return REL_GOT; - case R_386_JMP_SLOT: -- *reloc_addr = sym_val; -- break; -+ return REL_PLT; - case R_386_RELATIVE: -- *reloc_addr += (size_t)base_addr; -- break; -+ return REL_RELATIVE; - case R_386_COPY: -- memcpy(reloc_addr, (void *)sym_val, sym_size); -- break; -+ return REL_COPY; - case R_386_TLS_DTPMOD32: -- *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; -- break; -+ return REL_DTPMOD; - case R_386_TLS_DTPOFF32: -- *reloc_addr = def.sym->st_value; -- break; -+ return REL_DTPOFF; - case R_386_TLS_TPOFF: -- *reloc_addr += def.sym -- ? def.sym->st_value - def.dso->tls_offset -- : 0 - self->tls_offset; -- break; -+ return REL_TPOFF; - case R_386_TLS_TPOFF32: -- *reloc_addr += def.sym -- ? def.dso->tls_offset - def.sym->st_value -- : self->tls_offset; -- break; -+ return REL_TPOFF_NEG; -+ case R_386_TLS_DESC: -+ return REL_TLSDESC; - } -+ return 0; - } -diff --git a/arch/microblaze/reloc.h b/arch/microblaze/reloc.h -index 7bf3a5b..71a6219 100644 ---- a/arch/microblaze/reloc.h -+++ b/arch/microblaze/reloc.h -@@ -10,34 +10,27 @@ - - #define LDSO_ARCH "microblaze" ENDIAN_SUFFIX - --#define IS_COPY(x) ((x)==R_MICROBLAZE_COPY) --#define IS_PLT(x) ((x)==R_MICROBLAZE_JUMP_SLOT) -+#define TPOFF_K 0 - --static inline void do_single_reloc( -- struct dso *self, unsigned char *base_addr, -- size_t *reloc_addr, int type, size_t addend, -- Sym *sym, size_t sym_size, -- struct symdef def, size_t sym_val) -+static int remap_rel(int type) - { - switch(type) { - case R_MICROBLAZE_32: -+ return REL_SYMBOLIC; - case R_MICROBLAZE_GLOB_DAT: -+ return REL_GOT; - case R_MICROBLAZE_JUMP_SLOT: -- *reloc_addr = sym_val + addend; -- break; -+ return REL_PLT; - case R_MICROBLAZE_REL: -- *reloc_addr = (size_t)base_addr + addend; -- break; -+ return REL_RELATIVE; - case R_MICROBLAZE_COPY: -- memcpy(reloc_addr, (void *)sym_val, sym_size); -- break; -+ return REL_COPY; - case R_MICROBLAZE_TLSDTPMOD32: -- *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; -- break; -+ return REL_DTPMOD; - case R_MICROBLAZE_TLSDTPREL32: -- *reloc_addr = def.sym->st_value + addend; -- break; -+ return REL_DTPOFF; - } -+ return 0; - } - - #include "syscall.h" -diff --git a/arch/mips/reloc.h b/arch/mips/reloc.h -index 4ca8125..91fa097 100644 ---- a/arch/mips/reloc.h -+++ b/arch/mips/reloc.h -@@ -16,38 +16,25 @@ - - #define LDSO_ARCH "mips" ENDIAN_SUFFIX FP_SUFFIX - --#define IS_COPY(x) ((x)==R_MIPS_COPY) --#define IS_PLT(x) 1 -+#define TPOFF_K (-0x7000) - --static inline void do_single_reloc( -- struct dso *self, unsigned char *base_addr, -- size_t *reloc_addr, int type, size_t addend, -- Sym *sym, size_t sym_size, -- struct symdef def, size_t sym_val) -+static int remap_rel(int type) - { - switch(type) { -- case R_MIPS_JUMP_SLOT: -- *reloc_addr = sym_val; -- break; - case R_MIPS_REL32: -- if (sym_val) *reloc_addr += sym_val; -- else *reloc_addr += (size_t)base_addr; -- break; -+ return REL_SYM_OR_REL; -+ case R_MIPS_JUMP_SLOT: -+ return REL_PLT; - case R_MIPS_COPY: -- memcpy(reloc_addr, (void *)sym_val, sym_size); -- break; -+ return REL_COPY; - case R_MIPS_TLS_DTPMOD32: -- *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; -- break; -+ return REL_DTPMOD; - case R_MIPS_TLS_DTPREL32: -- *reloc_addr += def.sym->st_value; -- break; -+ return REL_DTPOFF; - case R_MIPS_TLS_TPREL32: -- *reloc_addr += def.sym -- ? def.sym->st_value + def.dso->tls_offset - 0x7000 -- : self->tls_offset - 0x7000; -- break; -+ return REL_TPOFF; - } -+ return 0; - } - - void __reloc_self(int c, size_t *a, size_t *dynv, size_t *got) -diff --git a/arch/powerpc/reloc.h b/arch/powerpc/reloc.h -index 38034c5..73c583b 100644 ---- a/arch/powerpc/reloc.h -+++ b/arch/powerpc/reloc.h -@@ -3,40 +3,29 @@ - - #define LDSO_ARCH "powerpc" - --#define IS_COPY(x) ((x)==R_PPC_COPY) --#define IS_PLT(x) ((x)==R_PPC_JMP_SLOT) -+#define TPOFF_K (-0x7000) - --// see linux' arch/powerpc/include/asm/elf.h --static inline void do_single_reloc( -- struct dso *self, unsigned char *base_addr, -- size_t *reloc_addr, int type, size_t addend, -- Sym *sym, size_t sym_size, -- struct symdef def, size_t sym_val) -+static int remap_rel(int type) - { - switch(type) { -+ case R_PPC_ADDR32: -+ return REL_SYMBOLIC; - case R_PPC_GLOB_DAT: -+ return REL_GOT; - case R_PPC_JMP_SLOT: -- case R_PPC_ADDR32: -- *reloc_addr = sym_val + addend; -- break; -- case R_PPC_COPY: -- memcpy(reloc_addr, (void *)sym_val, sym_size); -- break; -+ return REL_PLT; - case R_PPC_RELATIVE: -- *reloc_addr = (size_t)base_addr + addend; -- break; -+ return REL_RELATIVE; -+ case R_PPC_COPY: -+ return REL_COPY; - case R_PPC_DTPMOD32: -- *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; -- break; -+ return REL_DTPMOD; - case R_PPC_DTPREL32: -- *reloc_addr = def.sym->st_value + addend; -- break; -+ return REL_DTPOFF; - case R_PPC_TPREL32: -- *reloc_addr += def.sym -- ? def.sym->st_value + def.dso->tls_offset - 0x7000 -- : self->tls_offset - 0x7000; -- break; -+ return REL_TPOFF; - } -+ return 0; - } - - void __reloc_self(int c, size_t *a, size_t *dynv) -diff --git a/arch/sh/reloc.h b/arch/sh/reloc.h -index db3de08..aeb02d0 100644 ---- a/arch/sh/reloc.h -+++ b/arch/sh/reloc.h -@@ -6,42 +6,29 @@ - - #define LDSO_ARCH "sh" ENDIAN_SUFFIX - --#define IS_COPY(x) ((x) == R_SH_COPY) --#define IS_PLT(x) ((x) == R_SH_JMP_SLOT) -+#define TPOFF_K 8 - --static inline void do_single_reloc( -- struct dso *self, unsigned char *base_addr, -- size_t *reloc_addr, int type, size_t addend, -- Sym *sym, size_t sym_size, -- struct symdef def, size_t sym_val) -+static int remap_rel(int type) - { - switch(type) { -+ case R_SH_DIR32: -+ return REL_SYMBOLIC; -+ case R_SH_REL32: -+ return REL_OFFSET; - case R_SH_GLOB_DAT: -+ return REL_GOT; - case R_SH_JMP_SLOT: -- *reloc_addr = sym_val; -- break; -+ return REL_PLT; - case R_SH_RELATIVE: -- *reloc_addr = (size_t)base_addr + addend; -- break; -- case R_SH_DIR32: -- *reloc_addr = sym_val + addend; -- break; -- case R_SH_REL32: -- *reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr; -- break; -+ return REL_RELATIVE; - case R_SH_COPY: -- memcpy(reloc_addr, (void *)sym_val, sym_size); -- break; -+ return REL_COPY; - case R_SH_TLS_DTPMOD32: -- *reloc_addr += def.dso ? def.dso->tls_id : self->tls_id; -- break; -+ return REL_DTPMOD; - case R_SH_TLS_DTPOFF32: -- *reloc_addr += def.sym->st_value; -- break; -+ return REL_DTPOFF; - case R_SH_TLS_TPOFF32: -- *reloc_addr += def.sym -- ? def.sym->st_value + def.dso->tls_offset + 8 -- : self->tls_offset + 8; -- break; -+ return REL_TPOFF; - } -+ return 0; - } -diff --git a/arch/x32/reloc.h b/arch/x32/reloc.h -index f294eec..fcfbf99 100644 ---- a/arch/x32/reloc.h -+++ b/arch/x32/reloc.h -@@ -4,43 +4,37 @@ - - #define LDSO_ARCH "x32" - --#define IS_COPY(x) ((x)==R_X86_64_COPY) --#define IS_PLT(x) ((x)==R_X86_64_JUMP_SLOT) -+/* FIXME: x32 is very strange in its use of 64-bit relocation types in -+ * a 32-bit environment. As long as the memory at reloc_addr is -+ * zero-filled prior to relocations, just treating 64-bit relocations -+ * as operating on 32-bit slots should be fine, but this should be -+ * checked. In particular, R_X86_64_64, R_X86_64_DTPOFF64, and -+ * R_X86_64_TPOFF64 may need checking. */ - --static inline void do_single_reloc( -- struct dso *self, unsigned char *base_addr, -- size_t *reloc_addr, int type, size_t addend, -- Sym *sym, size_t sym_size, -- struct symdef def, size_t sym_val) -+static int remap_rel(int type) - { - switch(type) { -- case R_X86_64_GLOB_DAT: -- case R_X86_64_JUMP_SLOT: - case R_X86_64_64: -- *reloc_addr = sym_val + addend; -- break; - case R_X86_64_32: -- *(uint32_t *)reloc_addr = sym_val + addend; -- break; -+ return REL_SYMBOLIC; - case R_X86_64_PC32: -- *reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr; -- break; -+ return REL_OFFSET; -+ case R_X86_64_GLOB_DAT: -+ return REL_GOT; -+ case R_X86_64_JUMP_SLOT: -+ return REL_PLT; - case R_X86_64_RELATIVE: -- *reloc_addr = (size_t)base_addr + addend; -- break; -+ return REL_RELATIVE; - case R_X86_64_COPY: -- memcpy(reloc_addr, (void *)sym_val, sym_size); -- break; -+ return REL_COPY; - case R_X86_64_DTPMOD64: -- *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; -- break; -+ return REL_DTPMOD; - case R_X86_64_DTPOFF64: -- *reloc_addr = def.sym->st_value + addend; -- break; -+ case R_X86_64_DTPOFF32: -+ return REL_DTPOFF; - case R_X86_64_TPOFF64: -- *reloc_addr = (def.sym -- ? def.sym->st_value - def.dso->tls_offset -- : 0 - self->tls_offset) + addend; -- break; -+ case R_X86_64_TPOFF32: -+ return REL_TPOFF; - } -+ return 0; - } -diff --git a/arch/x86_64/reloc.h b/arch/x86_64/reloc.h -index 28cf7cc..9bc5849 100644 ---- a/arch/x86_64/reloc.h -+++ b/arch/x86_64/reloc.h -@@ -4,43 +4,29 @@ - - #define LDSO_ARCH "x86_64" - --#define IS_COPY(x) ((x)==R_X86_64_COPY) --#define IS_PLT(x) ((x)==R_X86_64_JUMP_SLOT) -- --static inline void do_single_reloc( -- struct dso *self, unsigned char *base_addr, -- size_t *reloc_addr, int type, size_t addend, -- Sym *sym, size_t sym_size, -- struct symdef def, size_t sym_val) -+static int remap_rel(int type) - { - switch(type) { -- case R_X86_64_GLOB_DAT: -- case R_X86_64_JUMP_SLOT: - case R_X86_64_64: -- *reloc_addr = sym_val + addend; -- break; -- case R_X86_64_32: -- *(uint32_t *)reloc_addr = sym_val + addend; -- break; -+ return REL_SYMBOLIC; - case R_X86_64_PC32: -- *reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr; -- break; -+ return REL_OFFSET32; -+ case R_X86_64_GLOB_DAT: -+ return REL_GOT; -+ case R_X86_64_JUMP_SLOT: -+ return REL_PLT; - case R_X86_64_RELATIVE: -- *reloc_addr = (size_t)base_addr + addend; -- break; -+ return REL_RELATIVE; - case R_X86_64_COPY: -- memcpy(reloc_addr, (void *)sym_val, sym_size); -- break; -+ return REL_COPY; - case R_X86_64_DTPMOD64: -- *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; -- break; -+ return REL_DTPMOD; - case R_X86_64_DTPOFF64: -- *reloc_addr = def.sym->st_value + addend; -- break; -+ return REL_DTPOFF; - case R_X86_64_TPOFF64: -- *reloc_addr = (def.sym -- ? def.sym->st_value - def.dso->tls_offset -- : 0 - self->tls_offset) + addend; -- break; -+ return REL_TPOFF; -+ case R_X86_64_TLSDESC: -+ return REL_TLSDESC; - } -+ return 0; - } -diff --git a/include/sys/socket.h b/include/sys/socket.h -index d752791..b911d6e 100644 ---- a/include/sys/socket.h -+++ b/include/sys/socket.h -@@ -26,6 +26,17 @@ struct ucred - uid_t uid; - gid_t gid; - }; -+ -+struct mmsghdr -+{ -+ struct msghdr msg_hdr; -+ unsigned int msg_len; -+}; -+ -+struct timespec; -+ -+int sendmmsg (int, struct mmsghdr *, unsigned int, unsigned int); -+int recvmmsg (int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *); - #endif - - struct linger -diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c -index f7eab8d..13cf2ee 100644 ---- a/src/env/__init_tls.c -+++ b/src/env/__init_tls.c -@@ -53,11 +53,6 @@ void *__copy_tls(unsigned char *mem) - return td; - } - --void *__tls_get_addr(size_t *v) --{ -- return (char *)__pthread_self()->dtv[1]+v[1]; --} -- - #if ULONG_MAX == 0xffffffff - typedef Elf32_Phdr Phdr; - #else -diff --git a/src/ldso/arm/start.s b/src/ldso/arm/start.s -index dfa3657..5dd93b5 100644 ---- a/src/ldso/arm/start.s -+++ b/src/ldso/arm/start.s -@@ -1,6 +1,6 @@ - .text --.global _start --_start: -+.global _dlstart -+_dlstart: - ldr r0,[sp] - add r1,sp,#4 - bl __dynlink -diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c -index 1cb3fb4..bc4f2f6 100644 ---- a/src/ldso/dynlink.c -+++ b/src/ldso/dynlink.c -@@ -1,6 +1,8 @@ - #define _GNU_SOURCE - #include <stdio.h> - #include <stdlib.h> -+#include <stdarg.h> -+#include <stddef.h> - #include <string.h> - #include <unistd.h> - #include <stdint.h> -@@ -48,6 +50,11 @@ struct debug { - void *base; - }; - -+struct td_index { -+ size_t args[2]; -+ struct td_index *next; -+}; -+ - struct dso { - unsigned char *base; - char *name; -@@ -79,6 +86,7 @@ struct dso { - void **new_dtv; - unsigned char *new_tls; - int new_dtv_idx, new_tls_idx; -+ struct td_index *td_index; - struct dso *fini_next; - char *shortname; - char buf[]; -@@ -89,6 +97,24 @@ struct symdef { - struct dso *dso; - }; - -+enum { -+ REL_ERR, -+ REL_SYMBOLIC, -+ REL_GOT, -+ REL_PLT, -+ REL_RELATIVE, -+ REL_OFFSET, -+ REL_OFFSET32, -+ REL_COPY, -+ REL_SYM_OR_REL, -+ REL_TLS, /* everything past here is TLS */ -+ REL_DTPMOD, -+ REL_DTPOFF, -+ REL_TPOFF, -+ REL_TPOFF_NEG, -+ REL_TLSDESC, -+}; -+ - #include "reloc.h" - - int __init_tp(void *); -@@ -107,6 +133,7 @@ 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 size_t static_tls_cnt; - static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE }; - static long long builtin_tls[(sizeof(struct pthread) + 64)/sizeof(long long)]; - -@@ -132,6 +159,17 @@ static int search_vec(size_t *v, size_t *r, size_t key) - return 1; - } - -+static void error(const char *fmt, ...) -+{ -+ va_list ap; -+ va_start(ap, fmt); -+ vsnprintf(errbuf, sizeof errbuf, fmt, ap); -+ va_end(ap); -+ if (runtime) longjmp(*rtld_fail, 1); -+ dprintf(2, "%s\n", errbuf); -+ ldso_fail = 1; -+} -+ - static uint32_t sysv_hash(const char *s0) - { - const unsigned char *s = (void *)s0; -@@ -227,6 +265,10 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def) - return def; - } - -+#define NO_INLINE_ADDEND (1<<REL_COPY | 1<<REL_GOT | 1<<REL_PLT) -+ -+ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic(); -+ - static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride) - { - unsigned char *base = dso->base; -@@ -235,36 +277,116 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri - Sym *sym; - const char *name; - void *ctx; -- int type; -+ int astype, type; - int sym_index; - struct symdef def; -+ size_t *reloc_addr; -+ size_t sym_val; -+ size_t tls_val; -+ size_t addend; - - for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) { -- type = R_TYPE(rel[1]); -+ astype = R_TYPE(rel[1]); -+ if (!astype) continue; -+ type = remap_rel(astype); -+ if (!type) { -+ error(errbuf, sizeof errbuf, -+ "Error relocating %s: unsupported relocation type %d", -+ dso->name, astype); -+ continue; -+ } - sym_index = R_SYM(rel[1]); -+ reloc_addr = (void *)(base + rel[0]); - 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)); -+ ctx = type==REL_COPY ? head->next : head; -+ def = find_sym(ctx, name, type==REL_PLT); - if (!def.sym && (sym->st_shndx != SHN_UNDEF - || sym->st_info>>4 != STB_WEAK)) { -- snprintf(errbuf, sizeof errbuf, -+ error(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; -+ def.dso = dso; -+ } -+ -+ addend = stride>2 ? rel[2] -+ : (1<<type & NO_INLINE_ADDEND) ? 0 -+ : *reloc_addr; -+ -+ sym_val = def.sym ? (size_t)def.dso->base+def.sym->st_value : 0; -+ tls_val = def.sym ? def.sym->st_value : 0; -+ -+ switch(type) { -+ case REL_OFFSET: -+ addend -= (size_t)reloc_addr; -+ case REL_SYMBOLIC: -+ case REL_GOT: -+ case REL_PLT: -+ *reloc_addr = sym_val + addend; -+ break; -+ case REL_RELATIVE: -+ *reloc_addr = (size_t)base + addend; -+ break; -+ case REL_SYM_OR_REL: -+ if (sym) *reloc_addr = sym_val + addend; -+ else *reloc_addr = (size_t)base + addend; -+ break; -+ case REL_COPY: -+ memcpy(reloc_addr, (void *)sym_val, sym->st_size); -+ break; -+ case REL_OFFSET32: -+ *(uint32_t *)reloc_addr = sym_val + addend -+ - (size_t)reloc_addr; -+ break; -+ case REL_DTPMOD: -+ *reloc_addr = def.dso->tls_id; -+ break; -+ case REL_DTPOFF: -+ *reloc_addr = tls_val + addend; -+ break; -+#ifdef TLS_ABOVE_TP -+ case REL_TPOFF: -+ *reloc_addr = tls_val + def.dso->tls_offset + TPOFF_K + addend; -+ break; -+#else -+ case REL_TPOFF: -+ *reloc_addr = tls_val - def.dso->tls_offset + addend; -+ break; -+ case REL_TPOFF_NEG: -+ *reloc_addr = def.dso->tls_offset - tls_val + addend; -+ break; -+#endif -+ case REL_TLSDESC: -+ if (stride<3) addend = reloc_addr[1]; -+ if (runtime && def.dso->tls_id >= static_tls_cnt) { -+ struct td_index *new = malloc(sizeof *new); -+ if (!new) error(errbuf, sizeof errbuf, -+ "Error relocating %s: cannot allocate TLSDESC for %s", -+ dso->name, sym ? name : "(local)" ); -+ new->next = dso->td_index; -+ dso->td_index = new; -+ new->args[0] = def.dso->tls_id; -+ new->args[1] = tls_val + addend; -+ reloc_addr[0] = (size_t)__tlsdesc_dynamic; -+ reloc_addr[1] = (size_t)new; -+ } else { -+ reloc_addr[0] = (size_t)__tlsdesc_static; -+#ifdef TLS_ABOVE_TP -+ reloc_addr[1] = tls_val + def.dso->tls_offset -+ + TPOFF_K + addend; -+#else -+ reloc_addr[1] = tls_val - def.dso->tls_offset -+ + addend; -+#endif -+ } -+ break; - } -- 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); - } - } - -@@ -717,12 +839,9 @@ static void load_deps(struct dso *p) - if (p->dynv[i] != DT_NEEDED) continue; - dep = load_library(p->strings + p->dynv[i+1], p); - if (!dep) { -- snprintf(errbuf, sizeof errbuf, -+ error(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) { -@@ -771,12 +890,9 @@ static void reloc_all(struct dso *p) - - if (p->relro_start != p->relro_end && - mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ) < 0) { -- snprintf(errbuf, sizeof errbuf, -+ error(errbuf, sizeof errbuf, - "Error relocating %s: RELRO protection failed: %m", - p->name); -- if (runtime) longjmp(*rtld_fail, 1); -- dprintf(2, "%s\n", errbuf); -- ldso_fail = 1; - } - - p->relocated = 1; -@@ -915,17 +1031,15 @@ void *__copy_tls(unsigned char *mem) - return td; - } - --void *__tls_get_addr(size_t *v) -+void *__tls_get_new(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); -+ __block_all_sigs(&set); -+ if (v[0]<=(size_t)self->dtv[0]) { -+ __restore_sigs(&set); - return (char *)self->dtv[v[0]]+v[1]; - } - -@@ -946,13 +1060,19 @@ void *__tls_get_addr(size_t *v) - 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); -+ /* Get new TLS memory from all new DSOs up to the requested one */ -+ unsigned char *mem; -+ for (p=head; ; p=p->next) { -+ if (!p->tls_id || self->dtv[p->tls_id]) continue; -+ 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[p->tls_id] = mem; -+ memcpy(mem, p->tls_image, p->tls_len); -+ if (p->tls_id == v[0]) break; -+ } -+ __restore_sigs(&set); - return mem + v[1]; - } - -@@ -1196,6 +1316,7 @@ void *__dynlink(int argc, char **argv) - dprintf(2, "%s: Thread-local storage not supported by kernel.\n", argv[0]); - _exit(127); - } -+ static_tls_cnt = tls_cnt; - - if (ldso_fail) _exit(127); - if (ldd_mode) _exit(0); -@@ -1251,6 +1372,11 @@ void *dlopen(const char *file, int mode) - for (p=orig_tail->next; p; p=next) { - next = p->next; - munmap(p->map, p->map_len); -+ while (p->td_index) { -+ void *tmp = p->td_index->next; -+ free(p->td_index); -+ p->td_index = tmp; -+ } - free(p->deps); - free(p); - } -@@ -1314,6 +1440,8 @@ static int invalid_dso_handle(void *h) - return 1; - } - -+void *__tls_get_addr(size_t *); -+ - static void *do_dlsym(struct dso *p, const char *s, void *ra) - { - size_t i; -diff --git a/src/ldso/i386/start.s b/src/ldso/i386/start.s -index b16f8af..c37a1fa 100644 ---- a/src/ldso/i386/start.s -+++ b/src/ldso/i386/start.s -@@ -1,6 +1,6 @@ - .text --.global _start --_start: -+.global _dlstart -+_dlstart: - xor %ebp,%ebp - pop %edi - mov %esp,%esi -diff --git a/src/ldso/i386/tlsdesc.s b/src/ldso/i386/tlsdesc.s -new file mode 100644 -index 0000000..3ac6129 ---- /dev/null -+++ b/src/ldso/i386/tlsdesc.s -@@ -0,0 +1,27 @@ -+.text -+.global __tlsdesc_static -+.type __tlsdesc_static,@function -+__tlsdesc_static: -+ mov 4(%eax),%eax -+ ret -+ -+.global __tlsdesc_dynamic -+.type __tlsdesc_dynamic,@function -+__tlsdesc_dynamic: -+ mov 4(%eax),%eax -+ push %edx -+ mov %gs:4,%edx -+ push %ecx -+ mov (%eax),%ecx -+ cmp %ecx,(%edx) -+ jc 1f -+ mov 4(%eax),%eax -+ add (%edx,%ecx,4),%eax -+2: pop %ecx -+ sub %gs:0,%eax -+ pop %edx -+ ret -+1: push %eax -+ call __tls_get_addr -+ pop %ecx -+ jmp 2b -diff --git a/src/ldso/microblaze/start.s b/src/ldso/microblaze/start.s -index 4e0a0e5..067e861 100644 ---- a/src/ldso/microblaze/start.s -+++ b/src/ldso/microblaze/start.s -@@ -1,6 +1,6 @@ - # FIXME: clearing argv entries --.global _start --_start: -+.global _dlstart -+_dlstart: - add r19, r0, r0 - - lw r5, r0, r1 -diff --git a/src/ldso/mips/start.s b/src/ldso/mips/start.s -index 2e98529..0cadbf8 100644 ---- a/src/ldso/mips/start.s -+++ b/src/ldso/mips/start.s -@@ -2,9 +2,9 @@ - .hidden __reloc_self - .set noreorder - .set nomacro --.global _start --.type _start,@function --_start: -+.global _dlstart -+.type _dlstart,@function -+_dlstart: - move $fp, $0 - - bgezal $0, 1f -diff --git a/src/ldso/powerpc/start.s b/src/ldso/powerpc/start.s -index 6c499e8..6548d58 100644 ---- a/src/ldso/powerpc/start.s -+++ b/src/ldso/powerpc/start.s -@@ -1,6 +1,6 @@ -- .global _start -- .type _start,@function --_start: -+ .global _dlstart -+ .type _dlstart,@function -+_dlstart: - bl 1f - 2: .long _DYNAMIC-2b - 1: mflr 5 -diff --git a/src/ldso/sh/start.s b/src/ldso/sh/start.s -index ca6b7fc..0d2d913 100644 ---- a/src/ldso/sh/start.s -+++ b/src/ldso/sh/start.s -@@ -1,7 +1,7 @@ - .text --.global _start --.type _start, @function --_start: -+.global _dlstart -+.type _dlstart, @function -+_dlstart: - mov.l @r15, r4 - mov r15, r5 - mov.l L1, r0 -diff --git a/src/ldso/tlsdesc.c b/src/ldso/tlsdesc.c -new file mode 100644 -index 0000000..031b5b8 ---- /dev/null -+++ b/src/ldso/tlsdesc.c -@@ -0,0 +1,13 @@ -+#ifdef SHARED -+ -+#include <stddef.h> -+#include "libc.h" -+ -+ptrdiff_t __tlsdesc_static() -+{ -+ return 0; -+} -+ -+weak_alias(__tlsdesc_static, __tlsdesc_dynamic); -+ -+#endif -diff --git a/src/ldso/x32/start.s b/src/ldso/x32/start.s -index 0fcf46d..3c3800a 100644 ---- a/src/ldso/x32/start.s -+++ b/src/ldso/x32/start.s -@@ -1,6 +1,6 @@ - .text --.global _start --_start: -+.global _dlstart -+_dlstart: - mov (%rsp),%rdi /* move argc into 1st argument slot */ - lea 4(%rsp),%rsi /* move argv into 2nd argument slot */ - call __dynlink -diff --git a/src/ldso/x86_64/start.s b/src/ldso/x86_64/start.s -index 80c1d08..1c5598a 100644 ---- a/src/ldso/x86_64/start.s -+++ b/src/ldso/x86_64/start.s -@@ -1,6 +1,6 @@ - .text --.global _start --_start: -+.global _dlstart -+_dlstart: - mov (%rsp),%rdi - lea 8(%rsp),%rsi - call __dynlink -diff --git a/src/ldso/x86_64/tlsdesc.s b/src/ldso/x86_64/tlsdesc.s -new file mode 100644 -index 0000000..57b78e0 ---- /dev/null -+++ b/src/ldso/x86_64/tlsdesc.s -@@ -0,0 +1,40 @@ -+.text -+.global __tlsdesc_static -+.type __tlsdesc_static,@function -+__tlsdesc_static: -+ mov 8(%rax),%rax -+ ret -+ -+.global __tlsdesc_dynamic -+.type __tlsdesc_dynamic,@function -+__tlsdesc_dynamic: -+ mov 8(%rax),%rax -+ push %rdx -+ mov %fs:8,%rdx -+ push %rcx -+ mov (%rax),%rcx -+ cmp %rcx,(%rdx) -+ jc 1f -+ mov 8(%rax),%rax -+ add (%rdx,%rcx,8),%rax -+2: pop %rcx -+ sub %fs:0,%rax -+ pop %rdx -+ ret -+1: push %rdi -+ push %rdi -+ push %rsi -+ push %r8 -+ push %r9 -+ push %r10 -+ push %r11 -+ mov %rax,%rdi -+ call __tls_get_addr -+ pop %r11 -+ pop %r10 -+ pop %r9 -+ pop %r8 -+ pop %rsi -+ pop %rdi -+ pop %rdi -+ jmp 2b -diff --git a/src/linux/fanotify.c b/src/linux/fanotify.c -index 1f4ef93..c6211af 100644 ---- a/src/linux/fanotify.c -+++ b/src/linux/fanotify.c -@@ -9,6 +9,6 @@ int fanotify_init(unsigned flags, unsigned event_f_flags) - int fanotify_mark(int fanotify_fd, unsigned flags, unsigned long long mask, - int dfd, const char *pathname) - { -- return syscall(SYS_fanotify_mark, flags, __SYSCALL_LL_O(mask), dfd, pathname); -+ return syscall(SYS_fanotify_mark, fanotify_fd, flags, __SYSCALL_LL_E(mask), dfd, pathname); - } - -diff --git a/src/network/recvmmsg.c b/src/network/recvmmsg.c -new file mode 100644 -index 0000000..58b1b2f ---- /dev/null -+++ b/src/network/recvmmsg.c -@@ -0,0 +1,15 @@ -+#define _GNU_SOURCE -+#include <sys/socket.h> -+#include <limits.h> -+#include "syscall.h" -+ -+int recvmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags, struct timespec *timeout) -+{ -+#if LONG_MAX > INT_MAX -+ struct mmsghdr *mh = msgvec; -+ unsigned int i; -+ for (i = vlen; i; i--, mh++) -+ mh->msg_hdr.__pad1 = mh->msg_hdr.__pad2 = 0; -+#endif -+ return syscall_cp(SYS_recvmmsg, fd, msgvec, vlen, flags, timeout); -+} -diff --git a/src/network/sendmmsg.c b/src/network/sendmmsg.c -new file mode 100644 -index 0000000..ff9f861 ---- /dev/null -+++ b/src/network/sendmmsg.c -@@ -0,0 +1,29 @@ -+#define _GNU_SOURCE -+#include <sys/socket.h> -+#include <limits.h> -+#include <errno.h> -+#include "syscall.h" -+ -+int sendmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags) -+{ -+#if LONG_MAX > INT_MAX -+ /* Can't use the syscall directly because the kernel has the wrong -+ * idea for the types of msg_iovlen, msg_controllen, and cmsg_len, -+ * and the cmsg blocks cannot be modified in-place. */ -+ int i; -+ if (vlen > IOV_MAX) vlen = IOV_MAX; /* This matches the kernel. */ -+ for (i=0; i<vlen; i++) { -+ /* As an unfortunate inconsistency, the sendmmsg API uses -+ * unsigned int for the resulting msg_len, despite sendmsg -+ * returning ssize_t. However Linux limits the total bytes -+ * sent by sendmsg to INT_MAX, so the assignment is safe. */ -+ ssize_t r = sendmsg(fd, &msgvec[i].msg_hdr, flags); -+ if (r < 0) goto error; -+ msgvec[i].msg_len = r; -+ } -+error: -+ return i ? i : -1; -+#else -+ return syscall_cp(SYS_sendmmsg, fd, msgvec, vlen, flags); -+#endif -+} -diff --git a/src/string/memmem.c b/src/string/memmem.c -index 3b1ae18..d7e1221 100644 ---- a/src/string/memmem.c -+++ b/src/string/memmem.c -@@ -112,8 +112,8 @@ static char *twoway_memmem(const unsigned char *h, const unsigned char *z, const - } - - /* Compare right half */ -- for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++); -- if (n[k]) { -+ for (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++); -+ if (k < l) { - h += k-ms; - mem = 0; - continue; -diff --git a/src/thread/__tls_get_addr.c b/src/thread/__tls_get_addr.c -new file mode 100644 -index 0000000..28ec7f0 ---- /dev/null -+++ b/src/thread/__tls_get_addr.c -@@ -0,0 +1,17 @@ -+#include <stddef.h> -+#include "pthread_impl.h" -+#include "libc.h" -+ -+void *__tls_get_new(size_t *) ATTR_LIBC_VISIBILITY; -+ -+void *__tls_get_addr(size_t *v) -+{ -+ pthread_t self = __pthread_self(); -+#ifdef SHARED -+ if (v[0]<=(size_t)self->dtv[0]) -+ return (char *)self->dtv[v[0]]+v[1]; -+ return __tls_get_new(v); -+#else -+ return (char *)self->dtv[1]+v[1]; -+#endif -+} -diff --git a/src/thread/i386/tls.s b/src/thread/i386/tls.s -index e1f2262..6e01adf 100644 ---- a/src/thread/i386/tls.s -+++ b/src/thread/i386/tls.s -@@ -2,7 +2,14 @@ - .global ___tls_get_addr - .type ___tls_get_addr,@function - ___tls_get_addr: -- push %eax -+ mov %gs:4,%edx -+ mov (%eax),%ecx -+ cmp %ecx,(%edx) -+ jc 1f -+ mov 4(%eax),%eax -+ add (%edx,%ecx,4),%eax -+ ret -+1: push %eax - call __tls_get_addr - pop %edx - ret |