From: German Gomez <german.gomez@arm.com>
To: elfutils-devel@sourceware.org
Subject: [PATCH 4/4] libdwfl, eu-stack, aarch64: Add API for setting AARCH64 PAC mask.
Date: Mon, 25 Apr 2022 14:03:11 +0000 [thread overview]
Message-ID: <20220425140311.95231-5-german.gomez@arm.com> (raw)
In-Reply-To: <20220425140311.95231-1-german.gomez@arm.com>
Add user API for setting the PAC mask.
The function is intended to be called in Dwfl_Thread_Callbacks.set_initial_registers.
Testing notes:
... consider the following program.c
| int a = 0;
| void leaf(void) {
| for (;;)
| a += a;
| }
| void parent(void) {
| leaf();
| }
| int main(void) {
| parent();
| return 0;
| }
... compiled with "gcc-10 -O0 -g -mbranch-protection=pac-ret+leaf program.c"
... should yield the correct call stack, without mangled addresses:
| $ eu-stack -p <PID>
|
| PID 760267 - process
| TID 760267:
| #0 0x0000aaaaaebd0804 leaf
| #1 0x0000aaaaaebd0818 parent
| #2 0x0000aaaaaebd0838 main
| #3 0x0000ffffbd52ad50 __libc_start_main
| #4 0x0000aaaaaebd0694 $x
Signed-off-by: German Gomez <german.gomez@arm.com>
---
libdw/libdw.map | 5 +++++
libdwfl/dwfl_frame_regs.c | 10 ++++++++++
libdwfl/libdwfl.h | 6 ++++++
libdwfl/linux-pid-attach.c | 34 ++++++++++++++++++++++++++++++++--
4 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 4f530378..469c72ab 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -366,3 +366,8 @@ ELFUTILS_0.186 {
dwarf_linecontext;
dwarf_linefunctionname;
} ELFUTILS_0.177;
+
+ELFUTILS_0.188 {
+ global:
+ dwfl_thread_state_aarch64_pauth;
+} ELFUTILS_0.186;
diff --git a/libdwfl/dwfl_frame_regs.c b/libdwfl/dwfl_frame_regs.c
index 83b1abef..f8baf6d3 100644
--- a/libdwfl/dwfl_frame_regs.c
+++ b/libdwfl/dwfl_frame_regs.c
@@ -59,3 +59,13 @@ dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc)
state->pc_state = DWFL_FRAME_STATE_PC_SET;
}
INTDEF(dwfl_thread_state_register_pc)
+
+void
+dwfl_thread_state_aarch64_pauth(Dwfl_Thread *thread, Dwarf_Word insn_mask)
+{
+ Dwfl_Frame *state = thread->unwound;
+ assert (state && state->unwound == NULL);
+ assert (state->initial_frame);
+ thread->aarch64.pauth_insn_mask = insn_mask;
+}
+INTDEF(dwfl_thread_state_aarch64_pauth)
diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
index f98f1d52..9eef703c 100644
--- a/libdwfl/libdwfl.h
+++ b/libdwfl/libdwfl.h
@@ -753,6 +753,12 @@ bool dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg,
void dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc)
__nonnull_attribute__ (1);
+/* Called by Dwfl_Thread_Callbacks.set_initial_registers implementation.
+ On AARCH64 platforms with Pointer Authentication, the bits from this mask
+ indicate the position of the PAC bits in return addresses. */
+void dwfl_thread_state_aarch64_pauth (Dwfl_Thread *thread, Dwarf_Word insn_mask)
+ __nonnull_attribute__ (1);
+
/* Iterate through the threads for a process. Returns zero if all threads have
been processed by the callback, returns -1 on error, or the value of the
callback when not DWARF_CB_OK. -1 returned on error will set dwfl_errno ().
diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
index 09cba07b..bf50a5bc 100644
--- a/libdwfl/linux-pid-attach.c
+++ b/libdwfl/linux-pid-attach.c
@@ -321,6 +321,28 @@ pid_thread_state_registers_cb (int firstreg, unsigned nregs,
return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
}
+#if defined(__aarch64__)
+
+#include <linux/ptrace.h> /* struct user_pac_mask */
+
+static void
+pid_set_aarch64_pauth(Dwfl_Thread *thread, pid_t tid)
+{
+ struct user_pac_mask pac_mask;
+ struct iovec iovec;
+
+ iovec.iov_base = &pac_mask;
+ iovec.iov_len = sizeof (pac_mask);
+
+ /* If the ptrace returns an error, the system may not support pointer
+ authentication. In that case, set the masks to 0 (no PAC bits). */
+ if (ptrace(PTRACE_GETREGSET, tid, NT_ARM_PAC_MASK, &iovec))
+ pac_mask.insn_mask = 0;
+
+ INTUSE(dwfl_thread_state_aarch64_pauth) (thread, pac_mask.insn_mask);
+}
+#endif /* __aarch64__ */
+
static bool
pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
{
@@ -333,8 +355,16 @@ pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
pid_arg->tid_attached = tid;
Dwfl_Process *process = thread->process;
Ebl *ebl = process->ebl;
- return ebl_set_initial_registers_tid (ebl, tid,
- pid_thread_state_registers_cb, thread);
+ if (!ebl_set_initial_registers_tid (ebl, tid,
+ pid_thread_state_registers_cb, thread))
+ return false;
+
+#if defined(__aarch64__)
+ /* Set aarch64 pointer authentication data. */
+ pid_set_aarch64_pauth(thread, tid);
+#endif
+
+ return true;
}
static void
--
2.25.1
next prev parent reply other threads:[~2022-04-25 14:03 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-25 14:03 [PATCH 0/4] Add AARCH64 pointer authentication support German Gomez
2022-04-25 14:03 ` [PATCH 1/4] aarch64: Create definitions for AARCH64_RA_SIGN_STATE register German Gomez
2023-02-23 16:22 ` Mark Wielaard
2022-04-25 14:03 ` [PATCH 2/4] libdw, aarch64: Implement DW_CFA_AARCH64_negate_ra_state CFI instruction German Gomez
2023-02-23 16:27 ` Mark Wielaard
2022-04-25 14:03 ` [PATCH 3/4] libdwfl, aarch64: Demangle return addresses using a PAC mask German Gomez
2022-04-25 14:03 ` German Gomez [this message]
2022-04-28 19:56 ` [PATCH 0/4] Add AARCH64 pointer authentication support Mark Wielaard
2022-05-19 13:30 ` German Gomez
2022-05-19 14:20 ` German Gomez
2023-02-24 0:17 ` Mark Wielaard
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=20220425140311.95231-5-german.gomez@arm.com \
--to=german.gomez@arm.com \
--cc=elfutils-devel@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).