From: "Victor L. Do Nascimento" <victor.donascimento@arm.com>
To: <newlib@sourceware.org>
Cc: <Richard.Earnshaw@arm.com>
Subject: [PATCH v3 1/8] newlib: libc: define M-profile PACBTI-enablement macros
Date: Wed, 24 Aug 2022 11:27:11 +0100 [thread overview]
Message-ID: <yw8j8rne2ayo.fsf@arm.com> (raw)
In-Reply-To: <yw8jedx62bdi.fsf@arm.com> (Victor L. Do Nascimento's message of "Wed, 24 Aug 2022 11:18:17 +0100")
Hi all,
This patch augments the arm_asm.h header file to provide support for
PACBTI enablement via macros for hand-written assembly functions,
updating both prologues/epilogues as well as cfi-related directives
depending on the compile-time mbranch-protection argument values.
It defines the following preprocessor macros:
* HAVE_PAC_LEAF: Indicates whether pac-signing has been requested for
leaf functions.
* PAC_LEAF_PUSH_IP: Whether leaf functions should push the pac code
to the stack irrespective of whether the ip register is clobbered in
the function or not.
* PAC_CFI_ADJUST: Given values for the above two parameters, this
holds the calculated offset applied to default CFI address/offset
values as a consequence of potentially pushing the pac-code to the
stack.
It also defines the following assembler macros:
* prologue: In addition to pushing any callee-saved registers onto
the stack, it generates any requested pacbti instructions.
Pushed registers are specified via the optional `first', `last' and
`savepac' macro argument parameters.
when a single register number is provided, it pushes that
register. When two register numbers are provided, they specify a
range to save. If savepac is non-zero, the ip register is also
saved.
For example:
prologue savepac=1 -> push {ip}
prologue 1 -> push {r1}
prologue 1 savepac=1 -> push {r1, ip}
prologue 1 4 -> push {r1-r4}
prologue 1 4 savepac=1 -> push {r1-r4, ip}
* epilogue: pops registers off the stack and emits pac key signing
instruction if requested. The optional `first', `last' and
`savepac' function as per the prologue macro, generating a pop
instead of push instruction.
* cfisavelist - prologue macro helper function, generating
necessary .cfi_offset directives associated with push instruction.
Therefore, the net effect of calling `prologue 1 2 savepac=1' is
to generate the following:
push {r1-r2, ip}
.cfi_adjust_cfa_offset 12
.cfi_offset 143, -12
.cfi_offset 2, -8
.cfi_offset 1, -4
* cfirestorelist - epilogue macro helper function, emitting
.cfi_restore instructions prior to resetting the cfa offset. As
such, calling `epilogue 1 2 savepac=1' will produce:
pop {r1-r2, ip}
.cfi_restore 143
.cfi_restore 2
.cfi_restore 1
.cfi_def_cfa_offset 0
Regards,
Victor
---
newlib/libc/machine/arm/arm_asm.h | 130 ++++++++++++++++++++++++++++++
1 file changed, 130 insertions(+)
diff --git a/newlib/libc/machine/arm/arm_asm.h b/newlib/libc/machine/arm/arm_asm.h
index 2708057de..d314094c9 100644
--- a/newlib/libc/machine/arm/arm_asm.h
+++ b/newlib/libc/machine/arm/arm_asm.h
@@ -60,4 +60,134 @@
# define _ISA_THUMB_1
#endif
+/* Check whether leaf function PAC signing has been requested in the
+ -mbranch-protect compile-time option. */
+#define LEAF_PROTECT_BIT 2
+
+#ifdef __ARM_FEATURE_PAC_DEFAULT
+# define HAVE_PAC_LEAF \
+ __ARM_FEATURE_PAC_DEFAULT & (1 << LEAF_PROTECT_BIT)
+#else
+# define HAVE_PAC_LEAF 0
+#endif
+
+/* Provide default parameters for PAC-code handling in leaf-functions. */
+#ifndef PAC_LEAF_PUSH_IP
+# define PAC_LEAF_PUSH_IP 0
+#endif
+
+#if HAVE_PAC_LEAF
+# if PAC_LEAF_PUSH_IP
+# define PAC_CFI_ADJ 4
+# else
+# define PAC_CFI_ADJ 0
+# endif /* PAC_LEAF_PUSH_IP*/
+#else
+# undef PAC_LEAF_PUSH_IP
+# define PAC_LEAF_PUSH_IP 0
+# define PAC_CFI_ADJ 0
+#endif /* HAVE_PAC_LEAF */
+
+#ifdef __ASSEMBLER__
+/* Emit .cfi_restore directives for a consecutive sequence of registers. */
+ .macro cfirestorelist first, last
+ .cfi_restore \last
+ .if \last-\first
+ cfirestorelist \first, \last-1
+ .endif
+ .endm
+
+/* Emit .cfi_offset directives for a consecutive sequence of registers. */
+ .macro cfisavelist first, last, index=1
+ .cfi_offset \last, -4*(\index) - PAC_CFI_ADJ
+ .if \last-\first
+ cfisavelist \first, \last-1, \index+1
+ .endif
+ .endm
+
+/* Create a prologue entry sequence handling PAC/BTI, if required and emitting
+ CFI directives for generated PAC code and any pushed registers. */
+ .macro prologue first=-1, last=-1, savepac=PAC_LEAF_PUSH_IP
+#if HAVE_PAC_LEAF
+#if __ARM_FEATURE_BTI_DEFAULT
+ pacbti ip, lr, sp
+#else
+ pac ip, lr, sp
+#endif /* __ARM_FEATURE_BTI_DEFAULT */
+ .cfi_register 143, 12
+#else
+#if __ARM_FEATURE_BTI_DEFAULT
+ bti
+#endif /* __ARM_FEATURE_BTI_DEFAULT */
+#endif /* HAVE_PAC_LEAF */
+ .if \first != -1
+ .if \last != -1
+ .if \savepac
+ push {r\first-r\last, ip}
+ .cfi_adjust_cfa_offset ((\last-\first)+1)*4 + PAC_CFI_ADJ
+ .cfi_offset 143, -PAC_CFI_ADJ
+ cfisavelist \first, \last
+ .else
+ push {r\first-r\last}
+ .cfi_adjust_cfa_offset ((\last-\first)+1)*4
+ cfisavelist \first, \last
+ .endif
+ .else
+ .if \savepac
+ push {r\first, ip}
+ .cfi_adjust_cfa_offset 4 + PAC_CFI_ADJ
+ .cfi_offset 143, -PAC_CFI_ADJ
+ cfisavelist \first, \first
+ .else // !\savepac
+ push {r\first}
+ .cfi_adjust_cfa_offset PAC_CFI_ADJ
+ cfisavelist \first, \first
+ .endif
+ .endif
+ .else // \first == -1
+ .if \savepac
+ push {ip}
+ .cfi_adjust_cfa_offset PAC_CFI_ADJ
+ .cfi_offset 143, -PAC_CFI_ADJ
+ .endif
+ .endif
+ .endm
+
+/* Create an epilogue exit sequence handling PAC/BTI, if required and emitting
+ CFI directives for all restored registers. */
+ .macro epilogue first=-1, last=-1, savepac=PAC_LEAF_PUSH_IP
+ .if \first != -1
+ .if \last != -1
+ .if \savepac
+ pop {r\first-r\last, ip}
+ .cfi_restore 143
+ cfirestorelist \first, \last
+ .else
+ pop {r\first-r\last}
+ cfirestorelist \first, \last
+ .endif
+ .else
+ .if \savepac
+ pop {r\first, ip}
+ .cfi_restore 143
+ cfirestorelist \first, \first
+ .else
+ pop {r\first}
+ cfirestorelist \first, \first
+ .endif
+ .endif
+ .else
+ .if \savepac
+ pop {ip}
+ .cfi_restore 143
+ .endif
+ .endif
+ .cfi_def_cfa_offset 0
+#if HAVE_PAC_LEAF
+ aut ip, lr, sp
+#endif /* HAVE_PAC_LEAF */
+ bx lr
+ .endm
+#endif /* __ASSEMBLER__ */
+
#endif /* ARM_ASM__H */
--
2.36.1
next prev parent reply other threads:[~2022-08-24 10:27 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-24 10:18 [PATCH v3 0/8] Implement assembly cortex-M PACBTI functionality Victor L. Do Nascimento
2022-08-24 10:27 ` Victor L. Do Nascimento [this message]
2022-08-24 10:30 ` [PATCH v3 2/8] newlib: libc: strcmp M-profile PACBTI-enablement Victor L. Do Nascimento
2022-08-24 10:33 ` [PATCH v3 3/8] newlib: libc: strlen " Victor L. Do Nascimento
2022-08-24 10:34 ` [PATCH v3 4/8] newlib: libc: memchr " Victor L. Do Nascimento
2022-08-24 10:36 ` [PATCH v3 5/8] newlib: libc: memcpy " Victor L. Do Nascimento
2022-08-24 10:38 ` [PATCH v3 6/8] newlib: libc: setjmp/longjmp " Victor L. Do Nascimento
2022-08-24 10:40 ` [PATCH v3 7/8] newlib: libc: aeabi_memmove " Victor L. Do Nascimento
2022-08-24 10:41 ` [PATCH v3 8/8] newlib: libc: aeabi_memset " Victor L. Do Nascimento
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=yw8j8rne2ayo.fsf@arm.com \
--to=victor.donascimento@arm.com \
--cc=Richard.Earnshaw@arm.com \
--cc=newlib@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).