mirror of
git://git.musl-libc.org/musl
synced 2024-12-15 11:15:07 +00:00
fix __aeabi_read_tp oversight in arm atomics/tls overhaul
calls to __aeabi_read_tp may be generated by the compiler to access TLS on pre-v6 targets. previously, this function was hard-coded to call the kuser helper, which would crash on kernels with kuser helper removed. to fix the problem most efficiently, the definition of __aeabi_read_tp is moved so that it's an alias for the new __a_gettp. however, on v7+ targets, code to initialize the runtime choice of thread-pointer loading code is not even compiled, meaning that defining __aeabi_read_tp would have caused an immediate crash due to using the default implementation of __a_gettp with a HCF instruction. fortunately there is an elegant solution which reduces overall code size: putting the native thread-pointer loading instruction in the default code path for __a_gettp, so that separate default/native code paths are not needed. this function should never be called before __set_thread_area anyway, and if it is called early on pre-v6 hardware, the old behavior (crashing) is maintained. ideally __aeabi_read_tp would not be called at all on v7+ targets anyway -- in fact, prior to the overhaul, the same problem existed, but it was never caught by users building for v7+ with kuser disabled. however, it's possible for calls to __aeabi_read_tp to end up in a v7+ binary if some of the object files were built for pre-v7 targets, e.g. in the case of static libraries that were built separately, so this case needs to be handled.
This commit is contained in:
parent
4a241f14a6
commit
8cd0b11eaf
@ -9,7 +9,7 @@ extern const unsigned char __attribute__((__visibility__("hidden")))
|
|||||||
__a_barrier_dummy[], __a_barrier_oldkuser[],
|
__a_barrier_dummy[], __a_barrier_oldkuser[],
|
||||||
__a_barrier_v6[], __a_barrier_v7[],
|
__a_barrier_v6[], __a_barrier_v7[],
|
||||||
__a_cas_dummy[], __a_cas_v6[], __a_cas_v7[],
|
__a_cas_dummy[], __a_cas_v6[], __a_cas_v7[],
|
||||||
__a_gettp_dummy[], __a_gettp_native[];
|
__a_gettp_dummy[];
|
||||||
|
|
||||||
#define __a_barrier_kuser 0xffff0fa0
|
#define __a_barrier_kuser 0xffff0fa0
|
||||||
#define __a_cas_kuser 0xffff0fc0
|
#define __a_cas_kuser 0xffff0fc0
|
||||||
@ -26,7 +26,6 @@ int __set_thread_area(void *p)
|
|||||||
#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
|
#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
|
||||||
if (__hwcap & HWCAP_TLS) {
|
if (__hwcap & HWCAP_TLS) {
|
||||||
size_t *aux;
|
size_t *aux;
|
||||||
SET(gettp, native);
|
|
||||||
SET(cas, v7);
|
SET(cas, v7);
|
||||||
SET(barrier, v7);
|
SET(barrier, v7);
|
||||||
for (aux=libc.auxv; *aux; aux+=2) {
|
for (aux=libc.auxv; *aux; aux+=2) {
|
||||||
|
@ -81,6 +81,10 @@ __a_cas_v7:
|
|||||||
.word 0xf57ff05b /* dmb ish */
|
.word 0xf57ff05b /* dmb ish */
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
.global __aeabi_read_tp
|
||||||
|
.type __aeabi_read_tp,%function
|
||||||
|
__aeabi_read_tp:
|
||||||
|
|
||||||
.global __a_gettp
|
.global __a_gettp
|
||||||
.hidden __a_gettp
|
.hidden __a_gettp
|
||||||
.type __a_gettp,%function
|
.type __a_gettp,%function
|
||||||
@ -92,10 +96,6 @@ __a_gettp:
|
|||||||
.global __a_gettp_dummy
|
.global __a_gettp_dummy
|
||||||
.hidden __a_gettp_dummy
|
.hidden __a_gettp_dummy
|
||||||
__a_gettp_dummy:
|
__a_gettp_dummy:
|
||||||
.word 0xe7fddef1
|
|
||||||
.global __a_gettp_native
|
|
||||||
.hidden __a_gettp_native
|
|
||||||
__a_gettp_native:
|
|
||||||
mrc p15,0,r0,c13,c0,3
|
mrc p15,0,r0,c13,c0,3
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
.global __aeabi_read_tp
|
|
||||||
.type __aeabi_read_tp,%function
|
|
||||||
__aeabi_read_tp:
|
|
||||||
ldr pc,=0xffff0fe0
|
|
Loading…
Reference in New Issue
Block a user