[compiler-rt][ARM] Add missing PACBTI support to assembly aeabi functions (#142400)

Some of the aeabi functions were missing PACBTI support. The lack of it
resulted in exceptions at runtime if the running environment had PAC
and/or BTI enabled.

This patch adds this support. This involves the addition of PACBTI
instructions, depending on whether each of these features is enabled,
plus the saving and restoring of the PAC code that resides in r12. Some
of the common code has been put in preprocessor macros to reduce
duplication, but not all, especially since some register saving and
restoring is very specific to each context.
This commit is contained in:
Victor Campos
2025-06-10 10:20:42 +01:00
committed by GitHub
parent 902d6894f5
commit a59a8ae1a9
12 changed files with 149 additions and 12 deletions

View File

@@ -22,7 +22,12 @@
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
PACBTI_LANDING
#if defined(__ARM_FEATURE_PAC_DEFAULT)
push {r0-r3, r12, lr}
#else
push {r0-r3, lr}
#endif
bl __aeabi_cdcmpeq_check_nan
cmp r0, #1
#if defined(USE_THUMB_1)
@@ -37,8 +42,13 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
movs r0, #0xF
lsls r0, r0, #31
pop {r0-r3, pc}
#else
#if defined(__ARM_FEATURE_PAC_DEFAULT)
pop {r0-r3, r12, lr}
aut r12, lr, sp
#else
pop {r0-r3, lr}
#endif
// NaN has been ruled out, so __aeabi_cdcmple can't trap
// Use "it ne" + unconditional branch to guarantee a supported relocation if
@@ -47,8 +57,8 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
bne __aeabi_cdcmple
#if defined(USE_THUMB_2)
mov ip, #APSR_C
msr APSR_nzcvq, ip
mov r12, #APSR_C
msr APSR_nzcvq, r12
#else
msr APSR_nzcvq, #APSR_C
#endif
@@ -70,9 +80,14 @@ END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
PACBTI_LANDING
// Per the RTABI, this function must preserve r0-r11.
// Save lr in the same instruction for compactness
#if defined(__ARM_FEATURE_PAC_DEFAULT)
push {r0-r3, r12, lr}
#else
push {r0-r3, lr}
#endif
bl __aeabi_dcmplt
cmp r0, #1
@@ -111,9 +126,14 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
1:
msr APSR_nzcvq, ip
#if defined(__ARM_FEATURE_PAC_DEFAULT)
pop {r0-r3, r12, lr}
bxaut r12, lr, sp
#else
pop {r0-r3}
POP_PC()
#endif
#endif
END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
// int __aeabi_cdrcmple(double a, double b) {
@@ -123,6 +143,9 @@ END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
#if defined(__ARM_FEATURE_BTI_DEFAULT)
bti
#endif
// Swap r0 and r2
mov ip, r0
mov r0, r2

View File

@@ -22,7 +22,12 @@
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
PACBTI_LANDING
#if defined(__ARM_FEATURE_PAC_DEFAULT)
push {r0-r3, r12, lr}
#else
push {r0-r3, lr}
#endif
bl __aeabi_cfcmpeq_check_nan
cmp r0, #1
#if defined(USE_THUMB_1)
@@ -37,8 +42,13 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
movs r0, #0xF
lsls r0, r0, #31
pop {r0-r3, pc}
#else
#if defined(__ARM_FEATURE_PAC_DEFAULT)
pop {r0-r3, r12, lr}
aut r12, lr, sp
#else
pop {r0-r3, lr}
#endif
// NaN has been ruled out, so __aeabi_cfcmple can't trap
// Use "it ne" + unconditional branch to guarantee a supported relocation if
@@ -47,8 +57,8 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
bne __aeabi_cfcmple
#if defined(USE_THUMB_2)
mov ip, #APSR_C
msr APSR_nzcvq, ip
mov r12, #APSR_C
msr APSR_nzcvq, r12
#else
msr APSR_nzcvq, #APSR_C
#endif
@@ -70,9 +80,14 @@ END_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple)
PACBTI_LANDING
// Per the RTABI, this function must preserve r0-r11.
// Save lr in the same instruction for compactness
#if defined(__ARM_FEATURE_PAC_DEFAULT)
push {r0-r3, r12, lr}
#else
push {r0-r3, lr}
#endif
bl __aeabi_fcmplt
cmp r0, #1
@@ -111,9 +126,14 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple)
1:
msr APSR_nzcvq, ip
#if defined(__ARM_FEATURE_PAC_DEFAULT)
pop {r0-r3, r12, lr}
bxaut r12, lr, sp
#else
pop {r0-r3}
POP_PC()
#endif
#endif
END_COMPILERRT_FUNCTION(__aeabi_cfcmple)
// int __aeabi_cfrcmple(float a, float b) {
@@ -123,6 +143,9 @@ END_COMPILERRT_FUNCTION(__aeabi_cfcmple)
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
#if defined(__ARM_FEATURE_BTI_DEFAULT)
bti
#endif
// Swap r0 and r1
mov ip, r0
mov r0, r1

View File

@@ -25,20 +25,34 @@
# define CONVERT_DCMP_ARGS_TO_DF2_ARGS
#endif
#if defined(__ARM_FEATURE_PAC_DEFAULT)
# define PROLOGUE PACBTI_LANDING SEPARATOR \
push { r12, lr }
# define EPILOGUE pop { r12, lr } SEPARATOR \
bxaut r12, lr, sp
#elif defined(__ARM_FEATURE_BTI_DEFAULT)
# define PROLOGUE PACBTI_LANDING SEPARATOR \
push { r4, lr }
# define EPILOGUE pop { r4, pc }
#else
# define PROLOGUE push { r4, lr }
# define EPILOGUE pop { r4, pc }
#endif
#define DEFINE_AEABI_DCMP(cond) \
.syntax unified SEPARATOR \
.p2align 2 SEPARATOR \
DEFINE_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond) \
push { r4, lr } SEPARATOR \
PROLOGUE SEPARATOR \
CONVERT_DCMP_ARGS_TO_DF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \
cmp r0, #0 SEPARATOR \
b ## cond 1f SEPARATOR \
movs r0, #0 SEPARATOR \
pop { r4, pc } SEPARATOR \
EPILOGUE SEPARATOR \
1: SEPARATOR \
movs r0, #1 SEPARATOR \
pop { r4, pc } SEPARATOR \
EPILOGUE SEPARATOR \
END_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond)
DEFINE_AEABI_DCMP(eq)

View File

@@ -25,20 +25,34 @@
# define CONVERT_FCMP_ARGS_TO_SF2_ARGS
#endif
#if defined(__ARM_FEATURE_PAC_DEFAULT)
# define PROLOGUE PACBTI_LANDING SEPARATOR \
push { r12, lr }
# define EPILOGUE pop { r12, lr } SEPARATOR \
bxaut r12, lr, sp
#elif defined(__ARM_FEATURE_BTI_DEFAULT)
# define PROLOGUE PACBTI_LANDING SEPARATOR \
push { r4, lr }
# define EPILOGUE pop { r4, pc }
#else
# define PROLOGUE push { r4, lr }
# define EPILOGUE pop { r4, pc }
#endif
#define DEFINE_AEABI_FCMP(cond) \
.syntax unified SEPARATOR \
.p2align 2 SEPARATOR \
DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond) \
push { r4, lr } SEPARATOR \
PROLOGUE SEPARATOR \
CONVERT_FCMP_ARGS_TO_SF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \
cmp r0, #0 SEPARATOR \
b ## cond 1f SEPARATOR \
movs r0, #0 SEPARATOR \
pop { r4, pc } SEPARATOR \
EPILOGUE SEPARATOR \
1: SEPARATOR \
movs r0, #1 SEPARATOR \
pop { r4, pc } SEPARATOR \
EPILOGUE SEPARATOR \
END_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond)
DEFINE_AEABI_FCMP(eq)

View File

@@ -31,7 +31,12 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod)
subs r1, r1, r2
JMP (r3)
#else // defined(USE_THUMB_1)
PACBTI_LANDING
#if defined(__ARM_FEATURE_PAC_DEFAULT)
push { r12, lr }
#else
push { lr }
#endif
sub sp, sp, #4
mov r2, sp
#if defined(__MINGW32__)
@@ -42,7 +47,12 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod)
bl SYMBOL_NAME(__divmodsi4)
ldr r1, [sp]
add sp, sp, #4
#if defined(__ARM_FEATURE_PAC_DEFAULT)
pop { r12, lr }
bxaut r12, lr, sp
#else
pop { pc }
#endif
#endif // defined(USE_THUMB_1)
END_COMPILERRT_FUNCTION(__aeabi_idivmod)

View File

@@ -22,7 +22,12 @@
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
PACBTI_LANDING
#if defined(__ARM_FEATURE_PAC_DEFAULT)
push {r6, r12, lr}
#else
push {r6, lr}
#endif
sub sp, sp, #16
add r6, sp, #8
str r6, [sp]
@@ -38,7 +43,12 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
ldr r2, [sp, #8]
ldr r3, [sp, #12]
add sp, sp, #16
#if defined(__ARM_FEATURE_PAC_DEFAULT)
pop {r6, r12, lr}
bxaut r12, lr, sp
#else
pop {r6, pc}
#endif
END_COMPILERRT_FUNCTION(__aeabi_ldivmod)
NO_EXEC_STACK_DIRECTIVE

View File

@@ -18,6 +18,9 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_memcpy)
bl memcpy
pop {r7, pc}
#else
#if defined(__ARM_FEATURE_BTI_DEFAULT)
bti
#endif
b memcpy
#endif
END_COMPILERRT_FUNCTION(__aeabi_memcpy)

View File

@@ -17,6 +17,9 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_memmove)
bl memmove
pop {r7, pc}
#else
#if defined(__ARM_FEATURE_BTI_DEFAULT)
bti
#endif
b memmove
#endif
END_COMPILERRT_FUNCTION(__aeabi_memmove)

View File

@@ -14,6 +14,9 @@
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_memset)
#if defined(__ARM_FEATURE_BTI_DEFAULT)
bti
#endif
mov r3, r1
mov r1, r2
mov r2, r3
@@ -31,6 +34,9 @@ DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset8, __aeabi_memset)
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_memclr)
#if defined(__ARM_FEATURE_BTI_DEFAULT)
bti
#endif
mov r2, r1
movs r1, #0
#ifdef USE_THUMB_1

View File

@@ -38,7 +38,12 @@ LOCAL_LABEL(case_denom_larger):
movs r0, #0
JMP (lr)
#else // defined(USE_THUMB_1)
PACBTI_LANDING
#if defined(__ARM_FEATURE_PAC_DEFAULT)
push { r12, lr }
#else
push { lr }
#endif
sub sp, sp, #4
mov r2, sp
#if defined(__MINGW32__)
@@ -49,8 +54,13 @@ LOCAL_LABEL(case_denom_larger):
bl SYMBOL_NAME(__udivmodsi4)
ldr r1, [sp]
add sp, sp, #4
#if defined(__ARM_FEATURE_PAC_DEFAULT)
pop { r12, lr }
bxaut r12, lr, sp
#else
pop { pc }
#endif
#endif
END_COMPILERRT_FUNCTION(__aeabi_uidivmod)
NO_EXEC_STACK_DIRECTIVE

View File

@@ -22,7 +22,12 @@
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
push {r6, lr}
PACBTI_LANDING
#if defined(__ARM_FEATURE_PAC_DEFAULT)
push {r6, r12, lr}
#else
push {r6, lr}
#endif
sub sp, sp, #16
add r6, sp, #8
str r6, [sp]
@@ -38,7 +43,12 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
ldr r2, [sp, #8]
ldr r3, [sp, #12]
add sp, sp, #16
pop {r6, pc}
#if defined(__ARM_FEATURE_PAC_DEFAULT)
pop {r6, r12, lr}
bxaut r12, lr, sp
#else
pop {r6, pc}
#endif
END_COMPILERRT_FUNCTION(__aeabi_uldivmod)
NO_EXEC_STACK_DIRECTIVE

View File

@@ -194,6 +194,17 @@
#else
#define WIDE(op) op
#endif
#if defined(__ARM_FEATURE_PAC_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT)
#define PACBTI_LANDING pacbti r12, lr, sp
#elif defined(__ARM_FEATURE_PAC_DEFAULT)
#define PACBTI_LANDING pac r12, lr, sp
#elif defined(__ARM_FEATURE_BTI_DEFAULT)
#define PACBTI_LANDING bti
#else
#define PACBTI_LANDING
#endif
#else // !defined(__arm)
#define DECLARE_FUNC_ENCODING
#define DEFINE_CODE_STATE