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.cap...@arm.com> --- backends/aarch64_corenote.c | 17 +++++++++++++++-- libdwfl/linux-core-attach.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) 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, + ®s_offset, &nregloc, ®locs, + &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; } -- 2.43.0