aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Do Nascimento <Victor.DoNascimento@arm.com>2022-06-22 15:07:31 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2022-06-22 15:07:31 +0100
commit8bf2238fc0571d673b593c1ec2f72f4179a8ec79 (patch)
treebb897fe21fae87963b6ca45e1c8f0365439cd0ce
parentf931b0e187330bdd38dd0149cc16d9a103502936 (diff)
downloadarm-optimized-routines-8bf2238fc0571d673b593c1ec2f72f4179a8ec79.tar.gz
string: Add M-profile PACBTI implementation of memchr
Ensure BTI indirect branch landing pads (BTI) and pointer authentication code genetaion (PAC) and verification instructions (BXAUT) are conditionally added to assembly when branch protection is requested
-rw-r--r--string/arm/memchr.S40
1 files changed, 37 insertions, 3 deletions
diff --git a/string/arm/memchr.S b/string/arm/memchr.S
index 1271ca1..4f7d8f4 100644
--- a/string/arm/memchr.S
+++ b/string/arm/memchr.S
@@ -23,7 +23,11 @@
@ Removed unneeded cbz from align loop
.syntax unified
+#if __ARM_ARCH_8M_MAIN__
+ /* keep config inherited from -march= */
+#else
.arch armv7-a
+#endif
@ this lets us check a flag in a 00/ff byte easily in either endianness
#ifdef __ARMEB__
@@ -33,17 +37,22 @@
#endif
.thumb
+#include "../pacbti.h"
+
@ ---------------------------------------------------------------------------
.thumb_func
.align 2
.p2align 4,,15
.global __memchr_arm
.type __memchr_arm,%function
+ .fnstart
+ .cfi_startproc
__memchr_arm:
@ r0 = start of memory to scan
@ r1 = character to look for
@ r2 = length
@ returns r0 = pointer to character or NULL if not found
+ pacbti_prologue
and r1,r1,#0xff @ Don't think we can trust the caller to actually pass a char
cmp r2,#16 @ If it's short don't bother with anything clever
@@ -64,6 +73,19 @@ __memchr_arm:
10:
@ At this point, we are aligned, we know we have at least 8 bytes to work with
push {r4,r5,r6,r7}
+ .save {r4-r7}
+ .cfi_adjust_cfa_offset 16
+#ifdef __ARM_FEATURE_PAC_DEFAULT
+ .cfi_offset 4, -8
+ .cfi_offset 5, -12
+ .cfi_offset 6, -16
+ .cfi_offset 7, -20
+#else
+ .cfi_offset 4, -4
+ .cfi_offset 5, -8
+ .cfi_offset 6, -12
+ .cfi_offset 7, -16
+#endif /* __ARM_FEATURE_PAC_DEFAULT */
orr r1, r1, r1, lsl #8 @ expand the match word across to all bytes
orr r1, r1, r1, lsl #16
bic r4, r2, #7 @ Number of double words to work with
@@ -83,6 +105,11 @@ __memchr_arm:
bne 15b @ (Flags from the subs above) If not run out of bytes then go around again
pop {r4,r5,r6,r7}
+ .cfi_restore 7
+ .cfi_restore 6
+ .cfi_restore 5
+ .cfi_restore 4
+ .cfi_adjust_cfa_offset -16
and r1,r1,#0xff @ Get r1 back to a single character from the expansion above
and r2,r2,#7 @ Leave the count remaining as the number after the double words have been done
@@ -98,11 +125,11 @@ __memchr_arm:
40:
movs r0,#0 @ not found
- bx lr
+ pacbti_epilogue
50:
subs r0,r0,#1 @ found
- bx lr
+ pacbti_epilogue
60: @ We're here because the fast path found a hit - now we have to track down exactly which word it was
@ r0 points to the start of the double word after the one that was tested
@@ -126,7 +153,14 @@ __memchr_arm:
61:
pop {r4,r5,r6,r7}
+ .cfi_restore 7
+ .cfi_restore 6
+ .cfi_restore 5
+ .cfi_restore 4
+ .cfi_adjust_cfa_offset -16
subs r0,r0,#1
- bx lr
+ pacbti_epilogue
+ .cfi_endproc
+ .fnend
.size __memchr_arm, . - __memchr_arm