rtld: use _get_tp() in __tls_get_addr()

This eliminates some non-trivial amount of code duplication, where done.
Only x86 and mips are handled right now.

Tested by:      bdragon (powerpc), mhorne (riscv)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29623
This commit is contained in:
Konstantin Belousov 2021-04-07 06:49:28 +03:00
parent 7cb32a0d03
commit e8b9c508b7
4 changed files with 13 additions and 72 deletions

View File

@ -541,11 +541,10 @@ allocate_initial_tls(Obj_Entry *objs)
void *
__tls_get_addr(tls_index *ti)
{
Elf_Addr** segbase;
Elf_Addr **dtvp;
__asm __volatile("movq %%fs:0, %0" : "=r" (segbase));
return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset);
dtvp = _get_tp();
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset));
}
size_t

View File

@ -522,22 +522,20 @@ __attribute__((__regparm__(1)))
void *
___tls_get_addr(tls_index *ti)
{
Elf_Addr** segbase;
Elf_Addr **dtvp;
__asm __volatile("movl %%gs:0, %0" : "=r" (segbase));
return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset);
dtvp = _get_tp();
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset));
}
/* Sun ABI */
void *
__tls_get_addr(tls_index *ti)
{
Elf_Addr** segbase;
Elf_Addr **dtvp;
__asm __volatile("movl %%gs:0, %0" : "=r" (segbase));
return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset);
dtvp = _get_tp();
return (tls_get_addr_common(dtvp, ti->ti_module, ti->ti_offset));
}
size_t

View File

@ -776,69 +776,15 @@ allocate_initial_tls(Obj_Entry *objs)
sysarch(MIPS_SET_TLS, tls);
}
#ifdef __mips_n64
void *
_mips_get_tls(void)
{
uint64_t _rv;
__asm__ __volatile__ (
".set\tpush\n\t"
".set\tmips64r2\n\t"
"rdhwr\t%0, $29\n\t"
".set\tpop"
: "=r" (_rv));
/*
* XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317'
*
* Remove the offset since this really a request to get the TLS
* pointer via sysarch() (in theory). Of course, this may go away
* once the TLS code is rewritten.
*/
_rv = _rv - TLS_TP_OFFSET - TLS_TCB_SIZE;
return (void *)_rv;
}
#else /* mips 32 */
void *
_mips_get_tls(void)
{
uint32_t _rv;
__asm__ __volatile__ (
".set\tpush\n\t"
".set\tmips32r2\n\t"
"rdhwr\t%0, $29\n\t"
".set\tpop"
: "=r" (_rv));
/*
* XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317'
*
* Remove the offset since this really a request to get the TLS
* pointer via sysarch() (in theory). Of course, this may go away
* once the TLS code is rewritten.
*/
_rv = _rv - TLS_TP_OFFSET - TLS_TCB_SIZE;
return (void *)_rv;
}
#endif /* ! __mips_n64 */
void *
__tls_get_addr(tls_index* ti)
{
Elf_Addr** tls;
Elf_Addr **tls;
char *p;
#ifdef TLS_USE_SYSARCH
sysarch(MIPS_GET_TLS, &tls);
#else
tls = _mips_get_tls();
#endif
p = tls_get_addr_common(tls, ti->ti_module, ti->ti_offset + TLS_DTP_OFFSET);
tls = _get_tp();
p = tls_get_addr_common(tls, ti->ti_module, ti->ti_offset +
TLS_DTP_OFFSET);
return (p);
}

View File

@ -44,8 +44,6 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
const Elf_Rel *rel);
Elf_Addr _mips_rtld_bind(struct Struct_Obj_Entry *obj, Elf_Size reloff);
void *_mips_get_tls(void);
#define make_function_pointer(def, defobj) \
((defobj)->relocbase + (def)->st_value)