about summary refs log tree commit diff
path: root/arch/aarch64
diff options
context:
space:
mode:
authorSzabolcs Nagy <nsz@port70.net>2018-06-02 01:52:01 +0200
committerRich Felker <dalias@aerifal.cx>2018-06-02 19:38:44 -0400
commit610c5a8524c3d6cd3ac5a5f1231422e7648a3791 (patch)
treea0d9b1b9b4dd950a475c95151b388472374699fa /arch/aarch64
parent029c622a89bf8cc15fd9fd56e8e88465ca6130cf (diff)
downloadmusl-610c5a8524c3d6cd3ac5a5f1231422e7648a3791.tar.gz
musl-610c5a8524c3d6cd3ac5a5f1231422e7648a3791.tar.xz
musl-610c5a8524c3d6cd3ac5a5f1231422e7648a3791.zip
fix TLS layout of TLS variant I when there is a gap above TP
In TLS variant I the TLS is above TP (or above a fixed offset from TP)
but on some targets there is a reserved gap above TP before TLS starts.

This matters for the local-exec tls access model when the offsets of
TLS variables from the TP are hard coded by the linker into the
executable, so the libc must compute these offsets the same way as the
linker.  The tls offset of the main module has to be

	alignup(GAP_ABOVE_TP, main_tls_align).

If there is no TLS in the main module then the gap can be ignored
since musl does not use it and the tls access models of shared
libraries are not affected.

The previous setup only worked if (tls_align & -GAP_ABOVE_TP) == 0
(i.e. TLS did not require large alignment) because the gap was
treated as a fixed offset from TP.  Now the TP points at the end
of the pthread struct (which is aligned) and there is a gap above
it (which may also need alignment).

The fix required changing TP_ADJ and __pthread_self on affected
targets (aarch64, arm and sh) and in the tlsdesc asm the offset to
access the dtv changed too.
Diffstat (limited to 'arch/aarch64')
-rw-r--r--arch/aarch64/pthread_arch.h5
-rw-r--r--arch/aarch64/reloc.h2
2 files changed, 4 insertions, 3 deletions
diff --git a/arch/aarch64/pthread_arch.h b/arch/aarch64/pthread_arch.h
index b2e2d8f1..e8499d8e 100644
--- a/arch/aarch64/pthread_arch.h
+++ b/arch/aarch64/pthread_arch.h
@@ -2,10 +2,11 @@ static inline struct pthread *__pthread_self()
 {
 	char *self;
 	__asm__ __volatile__ ("mrs %0,tpidr_el0" : "=r"(self));
-	return (void*)(self + 16 - sizeof(struct pthread));
+	return (void*)(self - sizeof(struct pthread));
 }
 
 #define TLS_ABOVE_TP
-#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 16)
+#define GAP_ABOVE_TP 16
+#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
 
 #define MC_PC pc
diff --git a/arch/aarch64/reloc.h b/arch/aarch64/reloc.h
index 51b66e23..40cf0b28 100644
--- a/arch/aarch64/reloc.h
+++ b/arch/aarch64/reloc.h
@@ -10,7 +10,7 @@
 
 #define NO_LEGACY_INITFINI
 
-#define TPOFF_K 16
+#define TPOFF_K 0
 
 #define REL_SYMBOLIC    R_AARCH64_ABS64
 #define REL_GOT         R_AARCH64_GLOB_DAT