rtld-elf: Pass struct tcb * around rather than struct dtv **
When this code was first written we didn't have even a struct tcb, so to make it MI a pointer to the DTV pointer in the TCB was passed around. Now that we have a struct tcb we can simplify the code by instead passing around a pointer to that, and the MI code can access the tcb_dtv member wherever it happens to be in the layout. This reduces boilerplate in all the various callers of tls_get_addr_common/slow and makes it clearer that tls_get_addr_common/slow are operating on the TCB, rather than obfuscating it slightly through the double pointer. Whilst here, clarify the comments in aarch64's TLSDESC dynamic resolver, which were using tp without clarifying what this was for (previously a pointer to the DTV pointer, now a pointer to the TCB, which happen to be the same thing for Variant I TLS, and in the case of AArch64 are what TPIDR_EL0 point to directly, with no offset/bias). Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D50591
This commit is contained in:
@@ -629,8 +629,5 @@ allocate_initial_tls(Obj_Entry *objs)
|
||||
void *
|
||||
__tls_get_addr(tls_index* ti)
|
||||
{
|
||||
struct dtv **dtvp;
|
||||
|
||||
dtvp = &_tcb_get()->tcb_dtv;
|
||||
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset));
|
||||
return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset));
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ ENTRY(_rtld_tlsdesc_dynamic)
|
||||
/*
|
||||
* Slow path
|
||||
* return(
|
||||
* tls_get_addr_common(tp, tlsdesc->tls_index, tlsdesc->tls_offs));
|
||||
* tls_get_addr_common(tcb, tlsdesc->tls_index, tlsdesc->tls_offs));
|
||||
*
|
||||
*/
|
||||
1:
|
||||
@@ -223,7 +223,7 @@ ENTRY(_rtld_tlsdesc_dynamic)
|
||||
.cfi_rel_offset x18, 120
|
||||
|
||||
/* Find the tls offset */
|
||||
mov x0, x4 /* tp */
|
||||
mov x0, x4 /* tcb */
|
||||
mov x3, x1 /* tlsdesc ptr */
|
||||
ldr w1, [x3, #8] /* tlsdec->tls_index */
|
||||
ldr x2, [x3, #16] /* tlsdec->tls_offs */
|
||||
|
||||
@@ -558,10 +558,7 @@ allocate_initial_tls(Obj_Entry *objs)
|
||||
void *
|
||||
__tls_get_addr(tls_index *ti)
|
||||
{
|
||||
struct dtv **dtvp;
|
||||
|
||||
dtvp = &_tcb_get()->tcb_dtv;
|
||||
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset));
|
||||
return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset));
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -465,8 +465,5 @@ allocate_initial_tls(Obj_Entry *objs)
|
||||
void *
|
||||
__tls_get_addr(tls_index* ti)
|
||||
{
|
||||
struct dtv **dtvp;
|
||||
|
||||
dtvp = &_tcb_get()->tcb_dtv;
|
||||
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset));
|
||||
return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset));
|
||||
}
|
||||
|
||||
@@ -523,20 +523,14 @@ allocate_initial_tls(Obj_Entry *objs)
|
||||
__attribute__((__regparm__(1))) void *
|
||||
___tls_get_addr(tls_index *ti)
|
||||
{
|
||||
struct dtv **dtvp;
|
||||
|
||||
dtvp = &_tcb_get()->tcb_dtv;
|
||||
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset));
|
||||
return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset));
|
||||
}
|
||||
|
||||
/* Sun ABI */
|
||||
void *
|
||||
__tls_get_addr(tls_index *ti)
|
||||
{
|
||||
struct dtv **dtvp;
|
||||
|
||||
dtvp = &_tcb_get()->tcb_dtv;
|
||||
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset));
|
||||
return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset));
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -837,9 +837,6 @@ allocate_initial_tls(Obj_Entry *list)
|
||||
void*
|
||||
__tls_get_addr(tls_index* ti)
|
||||
{
|
||||
struct dtv **dtvp;
|
||||
|
||||
dtvp = &_tcb_get()->tcb_dtv;
|
||||
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset +
|
||||
return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset +
|
||||
TLS_DTV_OFFSET));
|
||||
}
|
||||
|
||||
@@ -734,9 +734,6 @@ allocate_initial_tls(Obj_Entry *list)
|
||||
void*
|
||||
__tls_get_addr(tls_index* ti)
|
||||
{
|
||||
struct dtv **dtvp;
|
||||
|
||||
dtvp = &_tcb_get()->tcb_dtv;
|
||||
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset +
|
||||
return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset +
|
||||
TLS_DTV_OFFSET));
|
||||
}
|
||||
|
||||
@@ -478,9 +478,6 @@ allocate_initial_tls(Obj_Entry *objs)
|
||||
void *
|
||||
__tls_get_addr(tls_index* ti)
|
||||
{
|
||||
struct dtv **dtvp;
|
||||
|
||||
dtvp = &_tcb_get()->tcb_dtv;
|
||||
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset +
|
||||
return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset +
|
||||
TLS_DTV_OFFSET));
|
||||
}
|
||||
|
||||
+8
-11
@@ -170,7 +170,7 @@ static int symlook_list(SymLook *, const Objlist *, DoneList *);
|
||||
static int symlook_needed(SymLook *, const Needed_Entry *, DoneList *);
|
||||
static int symlook_obj1_sysv(SymLook *, const Obj_Entry *);
|
||||
static int symlook_obj1_gnu(SymLook *, const Obj_Entry *);
|
||||
static void *tls_get_addr_slow(struct dtv **, int, size_t, bool) __noinline;
|
||||
static void *tls_get_addr_slow(struct tcb *, int, size_t, bool) __noinline;
|
||||
static void trace_loaded_objects(Obj_Entry *, bool);
|
||||
static void unlink_object(Obj_Entry *);
|
||||
static void unload_object(Obj_Entry *, RtldLockState *lockstate);
|
||||
@@ -4312,15 +4312,12 @@ dlinfo(void *handle, int request, void *p)
|
||||
static void
|
||||
rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info)
|
||||
{
|
||||
struct dtv **dtvp;
|
||||
|
||||
phdr_info->dlpi_addr = (Elf_Addr)obj->relocbase;
|
||||
phdr_info->dlpi_name = obj->path;
|
||||
phdr_info->dlpi_phdr = obj->phdr;
|
||||
phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]);
|
||||
phdr_info->dlpi_tls_modid = obj->tlsindex;
|
||||
dtvp = &_tcb_get()->tcb_dtv;
|
||||
phdr_info->dlpi_tls_data = (char *)tls_get_addr_slow(dtvp,
|
||||
phdr_info->dlpi_tls_data = (char *)tls_get_addr_slow(_tcb_get(),
|
||||
obj->tlsindex, 0, true);
|
||||
phdr_info->dlpi_adds = obj_loads;
|
||||
phdr_info->dlpi_subs = obj_loads - obj_count;
|
||||
@@ -5350,13 +5347,13 @@ unref_dag(Obj_Entry *root)
|
||||
* Common code for MD __tls_get_addr().
|
||||
*/
|
||||
static void *
|
||||
tls_get_addr_slow(struct dtv **dtvp, int index, size_t offset, bool locked)
|
||||
tls_get_addr_slow(struct tcb *tcb, int index, size_t offset, bool locked)
|
||||
{
|
||||
struct dtv *newdtv, *dtv;
|
||||
RtldLockState lockstate;
|
||||
int to_copy;
|
||||
|
||||
dtv = *dtvp;
|
||||
dtv = tcb->tcb_dtv;
|
||||
/* Check dtv generation in case new modules have arrived */
|
||||
if (dtv->dtv_gen != tls_dtv_generation) {
|
||||
if (!locked)
|
||||
@@ -5373,7 +5370,7 @@ tls_get_addr_slow(struct dtv **dtvp, int index, size_t offset, bool locked)
|
||||
free(dtv);
|
||||
if (!locked)
|
||||
lock_release(rtld_bind_lock, &lockstate);
|
||||
dtv = *dtvp = newdtv;
|
||||
dtv = tcb->tcb_dtv = newdtv;
|
||||
}
|
||||
|
||||
/* Dynamically allocate module TLS if necessary */
|
||||
@@ -5391,16 +5388,16 @@ tls_get_addr_slow(struct dtv **dtvp, int index, size_t offset, bool locked)
|
||||
}
|
||||
|
||||
void *
|
||||
tls_get_addr_common(struct dtv **dtvp, int index, size_t offset)
|
||||
tls_get_addr_common(struct tcb *tcb, int index, size_t offset)
|
||||
{
|
||||
struct dtv *dtv;
|
||||
|
||||
dtv = *dtvp;
|
||||
dtv = tcb->tcb_dtv;
|
||||
/* Check dtv generation in case new modules have arrived */
|
||||
if (__predict_true(dtv->dtv_gen == tls_dtv_generation &&
|
||||
dtv->dtv_slots[index - 1].dtvs_tls != 0))
|
||||
return (dtv->dtv_slots[index - 1].dtvs_tls + offset);
|
||||
return (tls_get_addr_slow(dtvp, index, offset, false));
|
||||
return (tls_get_addr_slow(tcb, index, offset, false));
|
||||
}
|
||||
|
||||
#ifdef TLS_VARIANT_I
|
||||
|
||||
@@ -415,7 +415,7 @@ void _rtld_bind_start(void);
|
||||
void *rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def);
|
||||
void symlook_init(SymLook *, const char *);
|
||||
int symlook_obj(SymLook *, const Obj_Entry *);
|
||||
void *tls_get_addr_common(struct dtv **dtvp, int index, size_t offset);
|
||||
void *tls_get_addr_common(struct tcb *tcb, int index, size_t offset);
|
||||
void *allocate_tls(Obj_Entry *, void *, size_t, size_t);
|
||||
void free_tls(void *, size_t, size_t);
|
||||
void *allocate_module_tls(int index);
|
||||
|
||||
Reference in New Issue
Block a user