diff options
Diffstat (limited to 'ports/sysdeps/arm')
-rw-r--r-- | ports/sysdeps/arm/dl-tlsdesc.S | 13 | ||||
-rw-r--r-- | ports/sysdeps/arm/sysdep.h | 19 |
2 files changed, 21 insertions, 11 deletions
diff --git a/ports/sysdeps/arm/dl-tlsdesc.S b/ports/sysdeps/arm/dl-tlsdesc.S index 7b4c8dfcb5..1a15272821 100644 --- a/ports/sysdeps/arm/dl-tlsdesc.S +++ b/ports/sysdeps/arm/dl-tlsdesc.S @@ -50,18 +50,9 @@ _dl_tlsdesc_return: .fnstart .align 2 _dl_tlsdesc_undefweak: - @ Are we allowed a misaligned stack pointer calling read_tp? - .save {lr} - stmdb sp!, {lr} - cfi_adjust_cfa_offset (4) - cfi_rel_offset (lr,0) - bl __aeabi_read_tp + GET_TLS (r1) rsb r0, r0, #0 - ldmia sp!, {lr} - cfi_adjust_cfa_offset (-4) - cfi_restore (lr) BX (lr) - cfi_endproc .fnend .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak @@ -106,7 +97,7 @@ _dl_tlsdesc_dynamic: cfi_rel_offset (r4,8) cfi_rel_offset (lr,12) ldr r1, [r0] /* td */ - bl __aeabi_read_tp + GET_TLS (lr) mov r4, r0 /* r4 = tp */ ldr r0, [r0] ldr r2, [r1, #8] /* gen_count */ diff --git a/ports/sysdeps/arm/sysdep.h b/ports/sysdeps/arm/sysdep.h index 9230131c78..c525d5b977 100644 --- a/ports/sysdeps/arm/sysdep.h +++ b/ports/sysdeps/arm/sysdep.h @@ -150,6 +150,25 @@ # define NEGOFF_OFF1(R, OFF) [R, $OFF] # define NEGOFF_OFF2(R, OFFA, OFFB) [R, $OFFA] # endif + +/* Helper to get the TLS base pointer. The interface is that TMP is a + register that may be used to hold the LR, if necessary. TMP may be + LR itself to indicate that LR need not be saved. The base pointer + is returned in R0. Only R0 and TMP are modified. + + At this generic level we have no tricks to pull. Call the ABI routine. */ +# define GET_TLS(TMP) \ + push { r1, r2, r3, lr }; \ + cfi_remember_state; \ + cfi_adjust_cfa_offset (16); \ + cfi_rel_offset (r1, 0); \ + cfi_rel_offset (r2, 4); \ + cfi_rel_offset (r3, 8); \ + cfi_rel_offset (lr, 12); \ + bl __aeabi_read_tp; \ + pop { r1, r2, r3, lr }; \ + cfi_restore_state + #endif /* __ASSEMBLER__ */ /* This number is the offset from the pc at the current location. */ |