Page MenuHomeFreeBSD

D59269.id185425.diff
No OneTemporary

D59269.id185425.diff

diff --git a/libexec/rtld-elf/aarch64/rtld_machdep.h b/libexec/rtld-elf/aarch64/rtld_machdep.h
--- a/libexec/rtld-elf/aarch64/rtld_machdep.h
+++ b/libexec/rtld-elf/aarch64/rtld_machdep.h
@@ -41,6 +41,9 @@
#define MD_OBJ_ENTRY \
bool variant_pcs : 1; /* Object has a variant pcs function */
+#define MD_OBJ_ENTRY_INIT(obj)
+#define MD_OBJ_ENTRY_FINI(obj)
+
/* Return the address of the .dynamic section in the dynamic linker. */
#define rtld_dynamic(obj) \
({ \
diff --git a/libexec/rtld-elf/amd64/reloc.c b/libexec/rtld-elf/amd64/reloc.c
--- a/libexec/rtld-elf/amd64/reloc.c
+++ b/libexec/rtld-elf/amd64/reloc.c
@@ -53,6 +53,22 @@
#include "rtld.h"
#include "rtld_tls.h"
+void
+md_obj_entry_init(Obj_Entry *obj)
+{
+ STAILQ_INIT(&obj->tlsdesc_dynargs);
+}
+
+void
+md_obj_entry_fini(Obj_Entry *obj)
+{
+ struct tlsdesc_dynarg *tda, *t;
+
+ STAILQ_FOREACH_SAFE(tda, &obj->tlsdesc_dynargs, link, t) {
+ free(tda);
+ }
+}
+
/*
* Process the special R_X86_64_COPY relocations in the main program. These
* copy data from a shared object into a region in the main program's BSS
@@ -127,6 +143,62 @@
}
}
+static struct tlsdesc_dynarg *
+reloc_tlsdesc_alloc(Obj_Entry *obj, Elf_Addr tlsoffs)
+{
+ struct tlsdesc_dynarg *tda;
+
+ tda = xmalloc(sizeof(struct tlsdesc_dynarg));
+ tda->tlsinfo.ti_module = obj->tlsindex;
+ tda->tlsinfo.ti_offset = tlsoffs;
+ tda->dtv_gen = 0;
+ STAILQ_INSERT_TAIL(&obj->tlsdesc_dynargs, tda, link);
+ return (tda);
+}
+
+static void
+reloc_tlsdesc(const Obj_Entry *obj, const Elf_Rela *rela,
+ struct tlsdesc *where, int flags, RtldLockState *lockstate)
+{
+ const Elf_Sym *def;
+ const Obj_Entry *defobj;
+ Elf_Addr offs;
+
+ dbg("reloc_tlsdesc obj %s rela %p where %p", obj->path, rela, where);
+ offs = 0;
+ if (ELF_R_SYM(rela->r_info) != 0) {
+ def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, flags,
+ NULL, lockstate);
+ if (def == NULL)
+ rtld_die();
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ _rtld_error("%s: IFUNC for TLSDESC reloc",
+ obj->path);
+ rtld_die();
+ }
+ offs = def->st_value;
+ obj = defobj;
+ if (def->st_shndx == SHN_UNDEF) {
+ /* Weak undefined thread variable */
+ where->entry = rtld_tlsdesc_undef;
+ where->addend = rela->r_addend;
+ return;
+ }
+ }
+ offs += rela->r_addend;
+
+ if (obj->tlsoffset != 0) {
+ /* Variable is in initialy allocated TLS segment */
+ where->entry = rtld_tlsdesc_static;
+ where->offset = offs - obj->tlsoffset;
+ } else {
+ /* TLS offest is unknown at load time, use dynamic resolving */
+ where->entry = rtld_tlsdesc_dynamic;
+ where->arg = reloc_tlsdesc_alloc(__DECONST(Obj_Entry *, obj),
+ offs);
+ }
+}
+
/* Process the non-PLT relocations. */
int
reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
@@ -313,6 +385,10 @@
case R_X86_64_IRELATIVE:
obj->irelative_nonplt = true;
break;
+ case R_X86_64_TLSDESC:
+ reloc_tlsdesc(obj, rela, (struct tlsdesc *)where,
+ flags, lockstate);
+ break;
/*
* missing:
@@ -334,7 +410,7 @@
/* Process the PLT relocations. */
int
-reloc_plt(Obj_Entry *obj, int flags __unused, RtldLockState *lockstate __unused)
+reloc_plt(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
@@ -344,10 +420,10 @@
for (rela = obj->pltrela; rela < relalim; rela++) {
Elf_Addr *where;
+ where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
switch (ELF_R_TYPE(rela->r_info)) {
case R_X86_64_JMP_SLOT:
/* Relocate the GOT slot pointing into the PLT. */
- where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
*where += (Elf_Addr)obj->relocbase;
break;
@@ -355,6 +431,11 @@
obj->irelative = true;
break;
+ case R_X86_64_TLSDESC:
+ reloc_tlsdesc(obj, rela, (struct tlsdesc *)where,
+ SYMLOOK_IN_PLT | flags, lockstate);
+ break;
+
default:
_rtld_error("Unknown relocation type %x in PLT",
(unsigned int)ELF_R_TYPE(rela->r_info));
@@ -580,3 +661,27 @@
{
return (calculate_tls_offset(0, 0, size, align, offset));
}
+
+ptrdiff_t
+rtld_tlsdesc_dynamic_impl(struct tlsdesc *tdp)
+{
+ struct tlsdesc_dynarg *tda;
+ struct tcb *tcb;
+ struct dtv *dtv;
+ tls_index *ti;
+ uintptr_t gen;
+
+ tda = tdp->arg;
+ ti = &tda->tlsinfo;
+ tcb = _tcb_get();
+ dtv = tcb->tcb_dtv;
+
+ gen = atomic_load_ptr(&tls_dtv_generation);
+ if (__predict_true(tda->dtv_gen == gen && dtv->dtv_gen == gen &&
+ dtv->dtv_slots[ti->ti_module - 1].dtvs_tls != 0)) {
+ return ((ptrdiff_t)dtv->dtv_slots[ti->ti_module - 1].dtvs_tls +
+ ti->ti_offset - (ptrdiff_t)tcb);
+ }
+ return ((ptrdiff_t)tls_get_addr_slow_dtv(tcb, ti->ti_module,
+ ti->ti_offset, &tda->dtv_gen) - (ptrdiff_t)tcb);
+}
diff --git a/libexec/rtld-elf/amd64/rtld_machdep.h b/libexec/rtld-elf/amd64/rtld_machdep.h
--- a/libexec/rtld-elf/amd64/rtld_machdep.h
+++ b/libexec/rtld-elf/amd64/rtld_machdep.h
@@ -35,7 +35,14 @@
struct Struct_Obj_Entry;
-#define MD_OBJ_ENTRY
+#define MD_OBJ_ENTRY \
+ STAILQ_HEAD(, tlsdesc_dynarg) tlsdesc_dynargs;
+
+#define MD_OBJ_ENTRY_INIT(obj) md_obj_entry_init(obj)
+#define MD_OBJ_ENTRY_FINI(obj) md_obj_entry_fini(obj)
+
+void md_obj_entry_init(struct Struct_Obj_Entry *obj);
+void md_obj_entry_fini(struct Struct_Obj_Entry *obj);
/* Return the address of the .dynamic section in the dynamic linker. */
Elf_Dyn *rtld_dynamic_addr(void);
@@ -77,9 +84,35 @@
void *__tls_get_addr(tls_index *ti) __exported;
+#define __NONE_ABI /* Cannot be expressed in C */
+
+struct tlsdesc_dynarg
+{
+ tls_index tlsinfo;
+ size_t dtv_gen;
+ STAILQ_ENTRY(tlsdesc_dynarg) link;
+};
+
+struct tlsdesc
+{
+ ptrdiff_t (*entry)(struct tlsdesc *) __NONE_ABI;
+ union {
+ Elf_Ssize addend;
+ Elf_Size offset;
+ struct tlsdesc_dynarg *arg;
+ };
+};
+
#define md_abi_variant_hook(x)
size_t calculate_first_tls_offset(size_t size, size_t align, size_t offset);
size_t calculate_tls_offset(size_t prev_offset, size_t prev_size, size_t size,
size_t align, size_t offset);
+
+ptrdiff_t rtld_tlsdesc_dynamic_impl(struct tlsdesc *tdp);
+
+ptrdiff_t rtld_tlsdesc_static(struct tlsdesc *) __NONE_ABI;
+ptrdiff_t rtld_tlsdesc_undef(struct tlsdesc *) __NONE_ABI;
+ptrdiff_t rtld_tlsdesc_dynamic(struct tlsdesc *) __NONE_ABI;
+
#endif
diff --git a/libexec/rtld-elf/amd64/rtld_start.S b/libexec/rtld-elf/amd64/rtld_start.S
--- a/libexec/rtld-elf/amd64/rtld_start.S
+++ b/libexec/rtld-elf/amd64/rtld_start.S
@@ -171,4 +171,57 @@
.cfi_endproc
.size rtld_dynamic_addr, . - rtld_dynamic_addr
+rtld_tlsdesc_static:
+ .globl rtld_tlsdesc_static
+ .type rtld_tlsdesc_static,@function
+ .cfi_startproc
+ movq 8(%rax), %rax
+ ret
+ .cfi_endproc
+ .size rtld_tlsdesc_static, . - rtld_tlsdesc_static
+
+rtld_tlsdesc_undef:
+ .globl rtld_tlsdesc_undef
+ .type rtld_tlsdesc_undef,@function
+ .cfi_startproc
+ movq 8(%rax), %rax
+ subq %fs:0, %rax
+ ret
+ .cfi_endproc
+ .size rtld_tlsdesc_undef, . - rtld_tlsdesc_undef
+
+rtld_tlsdesc_dynamic:
+ .globl rtld_tlsdesc_dynamic
+ .type rtld_tlsdesc_dynamic,@function
+ .cfi_startproc
+ pushq %rbp
+ /*
+ * XXXKIB cfi.
+ * XXXKIB Inlining the fast path would allow to avoid saving
+ * unneeded registers.
+ */
+ movq %rsp,%rbp
+ pushq %rdx
+ pushq %rcx
+ pushq %rsi
+ pushq %rdi
+ pushq %r8
+ pushq %r9
+ pushq %r10
+ pushq %r11
+ movq %rax,%rdi
+ call rtld_tlsdesc_dynamic_impl
+ popq %r11
+ popq %r10
+ popq %r9
+ popq %r8
+ popq %rdi
+ popq %rsi
+ popq %rcx
+ popq %rdx
+ popq %rbp
+ ret
+ .cfi_endproc
+ .size rtld_tlsdesc_dynamic, . - rtld_tlsdesc_dynamic
+
.section .note.GNU-stack,"",%progbits
diff --git a/libexec/rtld-elf/arm/rtld_machdep.h b/libexec/rtld-elf/arm/rtld_machdep.h
--- a/libexec/rtld-elf/arm/rtld_machdep.h
+++ b/libexec/rtld-elf/arm/rtld_machdep.h
@@ -38,6 +38,9 @@
#define MD_OBJ_ENTRY
+#define MD_OBJ_ENTRY_INIT(obj)
+#define MD_OBJ_ENTRY_FINI(obj)
+
/* Return the address of the .dynamic section in the dynamic linker. */
#define rtld_dynamic(obj) (&_DYNAMIC)
diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c
--- a/libexec/rtld-elf/i386/reloc.c
+++ b/libexec/rtld-elf/i386/reloc.c
@@ -51,6 +51,22 @@
#include "rtld.h"
#include "rtld_tls.h"
+void
+md_obj_entry_init(Obj_Entry *obj)
+{
+ STAILQ_INIT(&obj->tlsdesc_dynargs);
+}
+
+void
+md_obj_entry_fini(Obj_Entry *obj)
+{
+ struct tlsdesc_dynarg *tda, *t;
+
+ STAILQ_FOREACH_SAFE(tda, &obj->tlsdesc_dynargs, link, t) {
+ free(tda);
+ }
+}
+
/*
* Process the special R_386_COPY relocations in the main program. These
* copy data from a shared object into a region in the main program's BSS
@@ -125,6 +141,61 @@
}
}
+static struct tlsdesc_dynarg *
+reloc_tlsdesc_alloc(Obj_Entry *obj, Elf_Addr tlsoffs)
+{
+ struct tlsdesc_dynarg *tda;
+
+ tda = xmalloc(sizeof(struct tlsdesc_dynarg));
+ tda->tlsinfo.ti_module = obj->tlsindex;
+ tda->tlsinfo.ti_offset = tlsoffs;
+ tda->dtv_gen = 0;
+ STAILQ_INSERT_TAIL(&obj->tlsdesc_dynargs, tda, link);
+ return (tda);
+}
+
+static void
+reloc_tlsdesc(const Obj_Entry *obj, const Elf_Rel *rel,
+ struct tlsdesc *where, int flags, RtldLockState *lockstate)
+{
+ const Elf_Sym *def;
+ const Obj_Entry *defobj;
+ Elf_Addr offs;
+
+ dbg("reloc_tlsdesc obj %s rel %p where %p", obj->path, rel, where);
+ offs = 0;
+ if (ELF_R_SYM(rel->r_info) != 0) {
+ def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, flags,
+ NULL, lockstate);
+ if (def == NULL)
+ rtld_die();
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ _rtld_error("%s: IFUNC for TLSDESC reloc",
+ obj->path);
+ rtld_die();
+ }
+ offs = def->st_value;
+ obj = defobj;
+ if (def->st_shndx == SHN_UNDEF) {
+ /* Weak undefined thread variable */
+ where->entry = rtld_tlsdesc_undef;
+ return;
+ }
+ }
+ offs += where->offset;
+
+ if (obj->tlsoffset != 0) {
+ /* Variable is in initialy allocated TLS segment */
+ where->entry = rtld_tlsdesc_static;
+ where->offset = offs - obj->tlsoffset;
+ } else {
+ /* TLS offest is unknown at load time, use dynamic resolving */
+ where->entry = rtld_tlsdesc_dynamic;
+ where->arg = reloc_tlsdesc_alloc(__DECONST(Obj_Entry *, obj),
+ offs);
+ }
+}
+
/* Process the non-PLT relocations. */
int
reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
@@ -271,6 +342,10 @@
case R_386_IRELATIVE:
obj->irelative_nonplt = true;
break;
+ case R_386_TLS_DESC:
+ reloc_tlsdesc(obj, rel, (struct tlsdesc *)where,
+ flags, lockstate);
+ break;
default:
_rtld_error(
"%s: Unsupported relocation type %d in non-PLT relocations",
@@ -295,10 +370,10 @@
for (rel = obj->pltrel; rel < rellim; rel++) {
Elf_Addr *where;
+ where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
switch (ELF_R_TYPE(rel->r_info)) {
case R_386_JMP_SLOT:
/* Relocate the GOT slot pointing into the PLT. */
- where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
*where += (Elf_Addr)obj->relocbase;
break;
@@ -306,6 +381,11 @@
obj->irelative = true;
break;
+ case R_386_TLS_DESC:
+ reloc_tlsdesc(obj, rel, (struct tlsdesc *)where,
+ SYMLOOK_IN_PLT | flags, lockstate);
+ break;
+
default:
_rtld_error("Unknown relocation type %x in PLT",
ELF_R_TYPE(rel->r_info));
@@ -519,8 +599,7 @@
_tcb_set(tls);
}
-/* GNU ABI */
-__attribute__((__regparm__(1))) void *
+__GNU_ABI void *
___tls_get_addr(tls_index *ti)
{
return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset));
@@ -553,3 +632,27 @@
{
return (calculate_tls_offset(0, 0, size, align, offset));
}
+
+__GNU_ABI ptrdiff_t
+rtld_tlsdesc_dynamic_impl(struct tlsdesc *tdp)
+{
+ struct tlsdesc_dynarg *tda;
+ struct tcb *tcb;
+ struct dtv *dtv;
+ tls_index *ti;
+ uintptr_t gen;
+
+ tda = tdp->arg;
+ ti = &tda->tlsinfo;
+ tcb = _tcb_get();
+ dtv = tcb->tcb_dtv;
+
+ gen = atomic_load_ptr(&tls_dtv_generation);
+ if (__predict_true(tda->dtv_gen == gen && dtv->dtv_gen == gen &&
+ dtv->dtv_slots[ti->ti_module - 1].dtvs_tls != 0)) {
+ return ((ptrdiff_t)dtv->dtv_slots[ti->ti_module - 1].dtvs_tls +
+ ti->ti_offset - (ptrdiff_t)tcb);
+ }
+ return ((ptrdiff_t)tls_get_addr_slow_dtv(tcb, ti->ti_module,
+ ti->ti_offset, &tda->dtv_gen) - (ptrdiff_t)tcb);
+}
diff --git a/libexec/rtld-elf/i386/rtld_machdep.h b/libexec/rtld-elf/i386/rtld_machdep.h
--- a/libexec/rtld-elf/i386/rtld_machdep.h
+++ b/libexec/rtld-elf/i386/rtld_machdep.h
@@ -35,7 +35,14 @@
struct Struct_Obj_Entry;
-#define MD_OBJ_ENTRY
+#define MD_OBJ_ENTRY \
+ STAILQ_HEAD(, tlsdesc_dynarg) tlsdesc_dynargs;
+
+#define MD_OBJ_ENTRY_INIT(obj) md_obj_entry_init(obj)
+#define MD_OBJ_ENTRY_FINI(obj) md_obj_entry_fini(obj)
+
+void md_obj_entry_init(struct Struct_Obj_Entry *obj);
+void md_obj_entry_fini(struct Struct_Obj_Entry *obj);
/* Return the address of the .dynamic section in the dynamic linker. */
#define rtld_dynamic(obj) \
@@ -75,12 +82,37 @@
unsigned long ti_offset;
} tls_index;
-void *___tls_get_addr(tls_index *ti) __attribute__((__regparm__(1))) __exported;
+#define __GNU_ABI __attribute__((__regparm__(1)))
+
+void *___tls_get_addr(tls_index *ti) __GNU_ABI __exported;
void *__tls_get_addr(tls_index *ti) __exported;
+struct tlsdesc_dynarg
+{
+ tls_index tlsinfo;
+ size_t dtv_gen;
+ STAILQ_ENTRY(tlsdesc_dynarg) link;
+};
+
+struct tlsdesc
+{
+ ptrdiff_t (*entry)(struct tlsdesc *) __GNU_ABI;
+ union {
+ Elf_Size offset;
+ struct tlsdesc_dynarg *arg;
+ };
+};
+
#define md_abi_variant_hook(x)
size_t calculate_first_tls_offset(size_t size, size_t align, size_t offset);
size_t calculate_tls_offset(size_t prev_offset, size_t prev_size, size_t size,
size_t align, size_t offset);
+
+ptrdiff_t rtld_tlsdesc_dynamic_impl(struct tlsdesc *tdp) __GNU_ABI;
+
+ptrdiff_t rtld_tlsdesc_static(struct tlsdesc *) __GNU_ABI;
+ptrdiff_t rtld_tlsdesc_undef(struct tlsdesc *) __GNU_ABI;
+ptrdiff_t rtld_tlsdesc_dynamic(struct tlsdesc *) __GNU_ABI;
+
#endif
diff --git a/libexec/rtld-elf/i386/rtld_start.S b/libexec/rtld-elf/i386/rtld_start.S
--- a/libexec/rtld-elf/i386/rtld_start.S
+++ b/libexec/rtld-elf/i386/rtld_start.S
@@ -95,4 +95,40 @@
leal 4(%esp),%esp # Discard reloff, do not change eflags
ret # "Return" to target address
+rtld_tlsdesc_static:
+ .globl rtld_tlsdesc_static
+ .type rtld_tlsdesc_static,@function
+ .cfi_startproc
+ movl 4(%eax), %eax
+ ret
+ .cfi_endproc
+ .size rtld_tlsdesc_static, . - rtld_tlsdesc_static
+
+rtld_tlsdesc_undef:
+ .globl rtld_tlsdesc_undef
+ .type rtld_tlsdesc_undef,@function
+ .cfi_startproc
+ movl 4(%eax), %eax
+ subl %gs:0, %eax
+ ret
+ .cfi_endproc
+ .size rtld_tlsdesc_undef, . - rtld_tlsdesc_undef
+
+rtld_tlsdesc_dynamic:
+ .globl rtld_tlsdesc_dynamic
+ .type rtld_tlsdesc_dynamic,@function
+ .cfi_startproc
+ pushl %ebp
+ /* XXXKIB cfi */
+ movl %esp, %ebp
+ pushl %edx
+ pushl %ecx
+ call rtld_tlsdesc_dynamic_impl
+ popl %ecx
+ popl %edx
+ popl %ebp
+ ret
+ .cfi_endproc
+ .size rtld_tlsdesc_dynamic, . - rtld_tlsdesc_dynamic
+
.section .note.GNU-stack,"",%progbits
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c
--- a/libexec/rtld-elf/map_object.c
+++ b/libexec/rtld-elf/map_object.c
@@ -482,6 +482,7 @@
free(obj->path);
if (obj->phdr_alloc)
free(__DECONST(void *, obj->phdr));
+ MD_OBJ_ENTRY_FINI(obj);
free(obj);
}
@@ -494,6 +495,7 @@
STAILQ_INIT(&obj->dldags);
STAILQ_INIT(&obj->dagmembers);
STAILQ_INIT(&obj->names);
+ MD_OBJ_ENTRY_INIT(obj);
return (obj);
}
diff --git a/libexec/rtld-elf/powerpc/rtld_machdep.h b/libexec/rtld-elf/powerpc/rtld_machdep.h
--- a/libexec/rtld-elf/powerpc/rtld_machdep.h
+++ b/libexec/rtld-elf/powerpc/rtld_machdep.h
@@ -38,6 +38,9 @@
#define MD_OBJ_ENTRY \
Elf_Addr *gotptr; /* GOT pointer (secure-plt only) */
+#define MD_OBJ_ENTRY_INIT(obj)
+#define MD_OBJ_ENTRY_FINI(obj)
+
/* Return the address of the .dynamic section in the dynamic linker. */
#define rtld_dynamic(obj) (&_DYNAMIC)
diff --git a/libexec/rtld-elf/powerpc64/rtld_machdep.h b/libexec/rtld-elf/powerpc64/rtld_machdep.h
--- a/libexec/rtld-elf/powerpc64/rtld_machdep.h
+++ b/libexec/rtld-elf/powerpc64/rtld_machdep.h
@@ -38,6 +38,9 @@
#define MD_OBJ_ENTRY \
Elf_Addr glink; /* GLINK PLT call stub section */
+#define MD_OBJ_ENTRY_INIT(obj)
+#define MD_OBJ_ENTRY_FINI(obj)
+
/* Return the address of the .dynamic section in the dynamic linker. */
#define rtld_dynamic(obj) (&_DYNAMIC)
diff --git a/libexec/rtld-elf/riscv/rtld_machdep.h b/libexec/rtld-elf/riscv/rtld_machdep.h
--- a/libexec/rtld-elf/riscv/rtld_machdep.h
+++ b/libexec/rtld-elf/riscv/rtld_machdep.h
@@ -44,6 +44,9 @@
#define MD_OBJ_ENTRY
+#define MD_OBJ_ENTRY_INIT(obj)
+#define MD_OBJ_ENTRY_FINI(obj)
+
uint64_t set_gp(struct Struct_Obj_Entry *obj);
/* Return the address of the .dynamic section in the dynamic linker. */
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -418,6 +418,8 @@
void symlook_init(SymLook *, const char *);
int symlook_obj(SymLook *, const Obj_Entry *);
void *tls_get_addr_common(struct tcb *tcb, int index, size_t offset);
+ptrdiff_t tls_get_addr_slow_dtv(struct tcb *tcb, int index, size_t offset,
+ Elf_Addr *dtv_genp);
void *allocate_tls(Obj_Entry *, void *, size_t, size_t);
void free_tls(void *, size_t, size_t);
void *allocate_module_tls(struct tcb *tcb, int index);
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -5517,6 +5517,20 @@
return (tls_get_addr_slow(tcb, index, offset, false));
}
+ptrdiff_t
+tls_get_addr_slow_dtv(struct tcb *tcb, int index, size_t offset,
+ Elf_Addr *dtv_genp)
+{
+ RtldLockState lockstate;
+ ptrdiff_t res;
+
+ wlock_acquire(rtld_bind_lock, &lockstate);
+ res = (ptrdiff_t)tls_get_addr_slow(tcb, index, offset, true);
+ *dtv_genp = tls_dtv_generation;
+ lock_release(rtld_bind_lock, &lockstate);
+ return (res);
+}
+
static struct tcb *
tcb_from_tcb_list_entry(struct tcb_list_entry *tcbelm)
{

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 8, 8:05 AM (20 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38507366
Default Alt Text
D59269.id185425.diff (17 KB)

Event Timeline