aboutsummaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorBrooks Davis <brooks@FreeBSD.org>2018-08-21 18:22:12 +0000
committerBrooks Davis <brooks@FreeBSD.org>2018-08-21 18:22:12 +0000
commita5207d3ef62c069aa8edf3c2b28ed8a21001dfed (patch)
tree7e174c28d3e8a3ddfbf92e248050af78f899e77f /libexec
parent62a08214bca8e288712bfb99aa8ed42c8daeae08 (diff)
downloadsrc-a5207d3ef62c069aa8edf3c2b28ed8a21001dfed.tar.gz
src-a5207d3ef62c069aa8edf3c2b28ed8a21001dfed.zip
Revert r337978: Rework rtld's TLS Variant I implementation to match r326794
Michal Meloun reports that it breaks ctype (isspace()..) related functions on armv7 so back out while we diagnose the issue. Reported by: Michal Meloun <melounmichal@gmail.com>
Notes
Notes: svn path=/head/; revision=338149
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/aarch64/rtld_machdep.h2
-rw-r--r--libexec/rtld-elf/arm/rtld_machdep.h2
-rw-r--r--libexec/rtld-elf/mips/rtld_machdep.h3
-rw-r--r--libexec/rtld-elf/powerpc/rtld_machdep.h3
-rw-r--r--libexec/rtld-elf/powerpc64/rtld_machdep.h3
-rw-r--r--libexec/rtld-elf/riscv/rtld_machdep.h3
-rw-r--r--libexec/rtld-elf/rtld.c77
7 files changed, 20 insertions, 73 deletions
diff --git a/libexec/rtld-elf/aarch64/rtld_machdep.h b/libexec/rtld-elf/aarch64/rtld_machdep.h
index 9ff53d900aaa..eb72a61b6fe8 100644
--- a/libexec/rtld-elf/aarch64/rtld_machdep.h
+++ b/libexec/rtld-elf/aarch64/rtld_machdep.h
@@ -69,8 +69,6 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
round(prev_offset + prev_size, align)
#define calculate_tls_end(off, size) ((off) + (size))
-#define calculate_tls_post_size(align) \
- round(TLS_TCB_SIZE, align) - TLS_TCB_SIZE
#define TLS_TCB_SIZE 16
typedef struct {
diff --git a/libexec/rtld-elf/arm/rtld_machdep.h b/libexec/rtld-elf/arm/rtld_machdep.h
index 030c83cdc7f4..926971c41524 100644
--- a/libexec/rtld-elf/arm/rtld_machdep.h
+++ b/libexec/rtld-elf/arm/rtld_machdep.h
@@ -69,8 +69,6 @@ typedef struct {
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
round(prev_offset + prev_size, align)
#define calculate_tls_end(off, size) ((off) + (size))
-#define calculate_tls_post_size(align) \
- round(TLS_TCB_SIZE, align) - TLS_TCB_SIZE
extern void *__tls_get_addr(tls_index *ti);
diff --git a/libexec/rtld-elf/mips/rtld_machdep.h b/libexec/rtld-elf/mips/rtld_machdep.h
index e20c32794530..0cfb665e7898 100644
--- a/libexec/rtld-elf/mips/rtld_machdep.h
+++ b/libexec/rtld-elf/mips/rtld_machdep.h
@@ -64,11 +64,10 @@ typedef struct {
#define round(size, align) \
(((size) + (align) - 1) & ~((align) - 1))
#define calculate_first_tls_offset(size, align) \
- TLS_TCB_SIZE
+ round(TLS_TCB_SIZE, align)
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
round(prev_offset + prev_size, align)
#define calculate_tls_end(off, size) ((off) + (size))
-#define calculate_tls_post_size(align) 0
extern void *__tls_get_addr(tls_index *ti);
diff --git a/libexec/rtld-elf/powerpc/rtld_machdep.h b/libexec/rtld-elf/powerpc/rtld_machdep.h
index c89ec4817401..584ccd977ec0 100644
--- a/libexec/rtld-elf/powerpc/rtld_machdep.h
+++ b/libexec/rtld-elf/powerpc/rtld_machdep.h
@@ -74,11 +74,10 @@ void _rtld_powerpc_pltcall(void);
#define round(size, align) \
(((size) + (align) - 1) & ~((align) - 1))
#define calculate_first_tls_offset(size, align) \
- TLS_TCB_SIZE
+ round(8, align)
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
round(prev_offset + prev_size, align)
#define calculate_tls_end(off, size) ((off) + (size))
-#define calculate_tls_post_size(align) 0
typedef struct {
unsigned long ti_module;
diff --git a/libexec/rtld-elf/powerpc64/rtld_machdep.h b/libexec/rtld-elf/powerpc64/rtld_machdep.h
index b0f71d312db0..cf42db426f4f 100644
--- a/libexec/rtld-elf/powerpc64/rtld_machdep.h
+++ b/libexec/rtld-elf/powerpc64/rtld_machdep.h
@@ -66,11 +66,10 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
#define round(size, align) \
(((size) + (align) - 1) & ~((align) - 1))
#define calculate_first_tls_offset(size, align) \
- TLS_TCB_SIZE
+ round(16, align)
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
round(prev_offset + prev_size, align)
#define calculate_tls_end(off, size) ((off) + (size))
-#define calculate_tls_post_size(align) 0
typedef struct {
unsigned long ti_module;
diff --git a/libexec/rtld-elf/riscv/rtld_machdep.h b/libexec/rtld-elf/riscv/rtld_machdep.h
index 1737fa73ff8b..bb1f6868f1ac 100644
--- a/libexec/rtld-elf/riscv/rtld_machdep.h
+++ b/libexec/rtld-elf/riscv/rtld_machdep.h
@@ -89,11 +89,10 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
#define round(size, align) \
(((size) + (align) - 1) & ~((align) - 1))
#define calculate_first_tls_offset(size, align) \
- TLS_TCB_SIZE
+ round(16, align)
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
round(prev_offset + prev_size, align)
#define calculate_tls_end(off, size) ((off) + (size))
-#define calculate_tls_post_size(align) 0
typedef struct {
unsigned long ti_module;
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index dfd0388478f9..43240568b3e8 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -4693,87 +4693,47 @@ tls_get_addr_common(Elf_Addr **dtvp, int index, size_t offset)
defined(__powerpc__) || defined(__riscv)
/*
- * Return pointer to allocated TLS block
- */
-static void *
-get_tls_block_ptr(void *tcb, size_t tcbsize)
-{
- size_t extra_size, post_size, pre_size, tls_block_size;
- size_t tls_init_align;
-
- tls_init_align = MAX(obj_main->tlsalign, 1);
-
- /* Compute fragments sizes. */
- extra_size = tcbsize - TLS_TCB_SIZE;
- post_size = calculate_tls_post_size(tls_init_align);
- tls_block_size = tcbsize + post_size;
- pre_size = roundup2(tls_block_size, tls_init_align) - tls_block_size;
-
- return ((char *)tcb - pre_size - extra_size);
-}
-
-/*
* Allocate Static TLS using the Variant I method.
- *
- * For details on the layout, see lib/libc/gen/tls.c.
- *
- * NB: rtld's tls_static_space variable includes TLS_TCB_SIZE and post_size as
- * it is based on tls_last_offset, and TLS offsets here are really TCB
- * offsets, whereas libc's tls_static_space is just the executable's static
- * TLS segment.
*/
void *
allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign)
{
Obj_Entry *obj;
- char *tls_block;
- Elf_Addr *dtv, **tcb;
+ char *tcb;
+ Elf_Addr **tls;
+ Elf_Addr *dtv;
Elf_Addr addr;
int i;
- size_t extra_size, maxalign, post_size, pre_size, tls_block_size;
- size_t tls_init_align;
if (oldtcb != NULL && tcbsize == TLS_TCB_SIZE)
return (oldtcb);
assert(tcbsize >= TLS_TCB_SIZE);
- maxalign = MAX(tcbalign, tls_static_max_align);
- tls_init_align = MAX(obj_main->tlsalign, 1);
-
- /* Compute fragmets sizes. */
- extra_size = tcbsize - TLS_TCB_SIZE;
- post_size = calculate_tls_post_size(tls_init_align);
- tls_block_size = tcbsize + post_size;
- pre_size = roundup2(tls_block_size, tls_init_align) - tls_block_size;
- tls_block_size += pre_size + tls_static_space - TLS_TCB_SIZE - post_size;
-
- /* Allocate whole TLS block */
- tls_block = malloc_aligned(tls_block_size, maxalign);
- tcb = (Elf_Addr **)(tls_block + pre_size + extra_size);
+ tcb = xcalloc(1, tls_static_space - TLS_TCB_SIZE + tcbsize);
+ tls = (Elf_Addr **)(tcb + tcbsize - TLS_TCB_SIZE);
if (oldtcb != NULL) {
- memcpy(tls_block, get_tls_block_ptr(oldtcb, tcbsize),
- tls_static_space);
- free_aligned(get_tls_block_ptr(oldtcb, tcbsize));
+ memcpy(tls, oldtcb, tls_static_space);
+ free(oldtcb);
/* Adjust the DTV. */
- dtv = tcb[0];
+ dtv = tls[0];
for (i = 0; i < dtv[1]; i++) {
if (dtv[i+2] >= (Elf_Addr)oldtcb &&
dtv[i+2] < (Elf_Addr)oldtcb + tls_static_space) {
- dtv[i+2] = dtv[i+2] - (Elf_Addr)oldtcb + (Elf_Addr)tcb;
+ dtv[i+2] = dtv[i+2] - (Elf_Addr)oldtcb + (Elf_Addr)tls;
}
}
} else {
dtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr));
- tcb[0] = dtv;
+ tls[0] = dtv;
dtv[0] = tls_dtv_generation;
dtv[1] = tls_max_index;
for (obj = globallist_curr(objs); obj != NULL;
obj = globallist_next(obj)) {
if (obj->tlsoffset > 0) {
- addr = (Elf_Addr)tcb + obj->tlsoffset;
+ addr = (Elf_Addr)tls + obj->tlsoffset;
if (obj->tlsinitsize > 0)
memcpy((void*) addr, obj->tlsinit, obj->tlsinitsize);
if (obj->tlssize > obj->tlsinitsize)
@@ -4792,19 +4752,14 @@ free_tls(void *tcb, size_t tcbsize, size_t tcbalign)
{
Elf_Addr *dtv;
Elf_Addr tlsstart, tlsend;
- size_t post_size;
- size_t dtvsize, i, tls_init_align;
+ int dtvsize, i;
assert(tcbsize >= TLS_TCB_SIZE);
- tls_init_align = MAX(obj_main->tlsalign, 1);
-
- /* Compute fragments sizes. */
- post_size = calculate_tls_post_size(tls_init_align);
- tlsstart = (Elf_Addr)tcb + TLS_TCB_SIZE + post_size;
- tlsend = (Elf_Addr)tcb + tls_static_space;
+ tlsstart = (Elf_Addr)tcb + tcbsize - TLS_TCB_SIZE;
+ tlsend = tlsstart + tls_static_space;
- dtv = *(Elf_Addr **)tcb;
+ dtv = *(Elf_Addr **)tlsstart;
dtvsize = dtv[1];
for (i = 0; i < dtvsize; i++) {
if (dtv[i+2] && (dtv[i+2] < tlsstart || dtv[i+2] >= tlsend)) {
@@ -4812,7 +4767,7 @@ free_tls(void *tcb, size_t tcbsize, size_t tcbalign)
}
}
free(dtv);
- free_aligned(get_tls_block_ptr(tcb, tcbsize));
+ free(tcb);
}
#endif