@@ -47,6 +47,7 @@
#include "gdbsupport/unordered_map.h"
#include <ctype.h>
+#include <algorithm>
/* This enum represents the values that the user can choose when
informing the Linux kernel about which memory mappings will be
@@ -96,6 +97,10 @@ struct smaps_vmflags
/* Memory map has memory tagging enabled. */
unsigned int memory_tagging : 1;
+
+ /* Memory map used for shadow stack. */
+
+ unsigned int shadow_stack_memory : 1;
};
/* Data structure that holds the information contained in the
@@ -537,6 +542,8 @@ decode_vmflags (char *p, struct smaps_vmflags *v)
v->shared_mapping = 1;
else if (strcmp (s, "mt") == 0)
v->memory_tagging = 1;
+ else if (strcmp (s, "ss") == 0)
+ v->shadow_stack_memory = 1;
}
}
@@ -3036,6 +3043,46 @@ show_dump_excluded_mappings (struct ui_file *file, int from_tty,
" flag is %s.\n"), value);
}
+/* See linux-tdep.h. */
+
+bool
+linux_address_in_shadow_stack_mem_range
+ (CORE_ADDR addr, std::pair<CORE_ADDR, CORE_ADDR> *range)
+{
+ if (!target_has_execution () || current_inferior ()->fake_pid_p)
+ return false;
+
+ const int pid = current_inferior ()->pid;
+
+ std::string smaps_file = string_printf ("/proc/%d/smaps", pid);
+
+ gdb::unique_xmalloc_ptr<char> data
+ = target_fileio_read_stralloc (nullptr, smaps_file.c_str ());
+
+ if (data == nullptr)
+ return false;
+
+ const std::vector<smaps_data> smaps
+ = parse_smaps_data (data.get (), std::move (smaps_file));
+
+ auto find_addr_mem_range = [&addr] (const smaps_data &map)
+ {
+ bool addr_in_mem_range
+ = (addr >= map.start_address && addr < map.end_address);
+ return (addr_in_mem_range && map.vmflags.shadow_stack_memory);
+ };
+ auto it = std::find_if (smaps.begin (), smaps.end (), find_addr_mem_range);
+
+ if (it != smaps.end ())
+ {
+ range->first = it->start_address;
+ range->second = it->end_address;
+ return true;
+ }
+
+ return false;
+}
+
/* To be called from the various GDB_OSABI_LINUX handlers for the
various GNU/Linux architectures and machine types.
@@ -117,4 +117,11 @@ extern CORE_ADDR linux_get_hwcap2 ();
extern struct link_map_offsets *linux_ilp32_fetch_link_map_offsets ();
extern struct link_map_offsets *linux_lp64_fetch_link_map_offsets ();
+/* Returns true if ADDR belongs to a shadow stack memory range. If this
+ is the case, assign the shadow stack memory range to RANGE
+ [start_address, end_address). */
+
+extern bool linux_address_in_shadow_stack_mem_range
+ (CORE_ADDR addr, std::pair<CORE_ADDR, CORE_ADDR> *range);
+
#endif /* GDB_LINUX_TDEP_H */
From: Christina Schimpe <christina.schimpe@intel.com> The function comes from the following patch from the Intel CET shadow stack support series: [PATCH v4 07/11] gdb: Handle shadow stack pointer register unwinding for amd64 linux. AArch64 also needs the function for unwinding the GCSPR, so include it in this patch series. Abridged-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org> --- gdb/linux-tdep.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ gdb/linux-tdep.h | 7 +++++++ 2 files changed, 54 insertions(+) This is the patch mentioned above: https://inbox.sourceware.org/gdb-patches/20250617121147.1956686-8-christina.schimpe@intel.com/ Minus the change in amd64-linux-tdep.c and the testcase. Patch 8 in this series adds the corresponding AArch64 change and testcase.