[v2,5/5] libdwfl, aarch64: Read PAC mask from core

Message ID 20240826105257.2669-6-steve.capper@arm.com
State Committed
Headers
Series Enable PAC support in elfutils |

Commit Message

Steve Capper Aug. 26, 2024, 10:52 a.m. UTC
  We need to read the PAC mask from a core file when debugging offline
as the information is still needed to demangle return addresses.

This commit pulls out the NT_ARM_PAC_MASK info from the core and feeds
it through to dwfl_thread_state_registers for each thread.

Signed-off-by: Steve Capper <steve.capper@arm.com>
---
 backends/aarch64_corenote.c | 17 +++++++++++++++--
 libdwfl/linux-core-attach.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 2 deletions(-)
  

Patch

diff --git a/backends/aarch64_corenote.c b/backends/aarch64_corenote.c
index bd0a4a72..38b21de7 100644
--- a/backends/aarch64_corenote.c
+++ b/backends/aarch64_corenote.c
@@ -115,6 +115,18 @@  static const Ebl_Core_Item aarch64_mte_items [] =
     }
   };
 
+static const Ebl_Core_Item aarch64_pac_items [] =
+  {
+    {
+      .name = "data_mask", .type = ELF_T_XWORD, .format = 'x',
+      .offset = 0, .group = "register"
+    },
+    {
+      .name = "insn_mask", .type = ELF_T_XWORD, .format = 'x',
+      .offset = 8, .group = "register"
+    }
+  };
+
 #define AARCH64_HWBP_REG(KIND, N)					\
     {									\
       .name = "DBG" KIND "VR" #N "_EL1", .type = ELF_T_XWORD, .format = 'x', \
@@ -175,7 +187,8 @@  AARCH64_BP_WP_GROUP ("W", aarch64_hw_wp_items);
   EXTRA_ITEMS (NT_ARM_TLS, 8, aarch64_tls_items)			\
   EXTRA_ITEMS (NT_ARM_HW_BREAK, 264, aarch64_hw_bp_items)		\
   EXTRA_ITEMS (NT_ARM_HW_WATCH, 264, aarch64_hw_wp_items)		\
-  EXTRA_ITEMS (NT_ARM_SYSTEM_CALL, 4, aarch64_syscall_items) \
-  EXTRA_ITEMS (NT_ARM_TAGGED_ADDR_CTRL, 8, aarch64_mte_items)
+  EXTRA_ITEMS (NT_ARM_SYSTEM_CALL, 4, aarch64_syscall_items)		\
+  EXTRA_ITEMS (NT_ARM_TAGGED_ADDR_CTRL, 8, aarch64_mte_items)		\
+  EXTRA_ITEMS (NT_ARM_PAC_MASK, 16, aarch64_pac_items)
 
 #include "linux-core-note.c"
diff --git a/libdwfl/linux-core-attach.c b/libdwfl/linux-core-attach.c
index d6f9e971..75e3c219 100644
--- a/libdwfl/linux-core-attach.c
+++ b/libdwfl/linux-core-attach.c
@@ -289,6 +289,40 @@  core_set_initial_registers (Dwfl_Thread *thread, void *thread_arg_voidp)
 	  reg_desc += regloc->pad;
 	}
     }
+
+  /* look for any Pointer Authentication code masks on AArch64 machines */
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr(core, &ehdr_mem);
+  if (ehdr && ehdr->e_machine == EM_AARCH64)
+  {
+    while (offset < note_data->d_size
+           && (offset = gelf_getnote (note_data, offset,
+			            &nhdr, &name_offset, &desc_offset)) > 0)
+    {
+      if (nhdr.n_type != NT_ARM_PAC_MASK)
+        continue;
+
+      name = (nhdr.n_namesz == 0 ? "" : note_data->d_buf + name_offset);
+      desc = note_data->d_buf + desc_offset;
+      core_note_err = ebl_core_note (core_arg->ebl, &nhdr, name, desc,
+		                   &regs_offset, &nregloc, &reglocs,
+				   &nitems, &items);
+      if (!core_note_err)
+        break;
+
+      for (item = items; item < items + nitems; item++)
+        if (strcmp(item->name, "insn_mask") == 0)
+          break;
+
+      if (item == items + nitems)
+        continue;
+
+      uint64_t insn_mask = read_8ubyte_unaligned_noncvt(desc + item->offset);
+      INTUSE(dwfl_thread_state_registers)(thread, -2, 1, &insn_mask);
+      break;
+    }
+  }
+
   return true;
 }