[Lldb-commits] [lldb] 75aa5a3 - [lldb][AArch64] Add Guarded Control Stack support for Linux core files (#124293)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Jan 28 03:32:27 PST 2025
Author: David Spickett
Date: 2025-01-28T11:32:24Z
New Revision: 75aa5a35568b9e0b3eabd1e7f991a6a0f5525e0c
URL: https://github.com/llvm/llvm-project/commit/75aa5a35568b9e0b3eabd1e7f991a6a0f5525e0c
DIFF: https://github.com/llvm/llvm-project/commit/75aa5a35568b9e0b3eabd1e7f991a6a0f5525e0c.diff
LOG: [lldb][AArch64] Add Guarded Control Stack support for Linux core files (#124293)
This allows you to read the same registers as you would for a live
process.
As the content of proc/pid/smaps is not included in the core file, we
don't get the "ss" marker that tell us that it is shadow stack. The GCS
region is still in the list though.
Added:
lldb/test/API/linux/aarch64/gcs/corefile
Modified:
lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
lldb/test/API/linux/aarch64/gcs/TestAArch64LinuxGCS.py
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 2ddf8440aeb035..bd02bb0e69a4d3 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -69,6 +69,15 @@ RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
if (fpmr_data.GetByteSize() >= sizeof(uint64_t))
opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskFPMR);
+ DataExtractor gcs_data = getRegset(notes, arch.GetTriple(), AARCH64_GCS_Desc);
+ struct __attribute__((packed)) gcs_regs {
+ uint64_t features_enabled;
+ uint64_t features_locked;
+ uint64_t gcspr_e0;
+ };
+ if (gcs_data.GetByteSize() >= sizeof(gcs_regs))
+ opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskGCS);
+
auto register_info_up =
std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
@@ -136,6 +145,9 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
if (m_register_info_up->IsFPMRPresent())
m_fpmr_data = getRegset(notes, target_triple, AARCH64_FPMR_Desc);
+ if (m_register_info_up->IsGCSPresent())
+ m_gcs_data = getRegset(notes, target_triple, AARCH64_GCS_Desc);
+
ConfigureRegisterContext();
}
@@ -330,6 +342,11 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
assert(offset < m_mte_data.GetByteSize());
value.SetFromMemoryData(*reg_info, m_mte_data.GetDataStart() + offset,
reg_info->byte_size, lldb::eByteOrderLittle, error);
+ } else if (IsGCS(reg)) {
+ offset = reg_info->byte_offset - m_register_info_up->GetGCSOffset();
+ assert(offset < m_gcs_data.GetByteSize());
+ value.SetFromMemoryData(*reg_info, m_gcs_data.GetDataStart() + offset,
+ reg_info->byte_size, lldb::eByteOrderLittle, error);
} else if (IsSME(reg)) {
// If you had SME in the process, active or otherwise, there will at least
// be a ZA header. No header, no SME at all.
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index 35588c40c2eb1a..6140f805ffc78a 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -63,6 +63,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
lldb_private::DataExtractor m_mte_data;
lldb_private::DataExtractor m_zt_data;
lldb_private::DataExtractor m_fpmr_data;
+ lldb_private::DataExtractor m_gcs_data;
SVEState m_sve_state = SVEState::Unknown;
uint16_t m_sve_vector_length = 0;
diff --git a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
index b97279b0d735b8..59382a12cde0a2 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -148,6 +148,10 @@ constexpr RegsetDesc AARCH64_FPMR_Desc[] = {
{llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_FPMR},
};
+constexpr RegsetDesc AARCH64_GCS_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_GCS},
+};
+
constexpr RegsetDesc PPC_VMX_Desc[] = {
{llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
{llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
diff --git a/lldb/test/API/linux/aarch64/gcs/TestAArch64LinuxGCS.py b/lldb/test/API/linux/aarch64/gcs/TestAArch64LinuxGCS.py
index 797551b061a237..adbef69c5c38b0 100644
--- a/lldb/test/API/linux/aarch64/gcs/TestAArch64LinuxGCS.py
+++ b/lldb/test/API/linux/aarch64/gcs/TestAArch64LinuxGCS.py
@@ -374,3 +374,35 @@ def test_gcs_expression_enable_gcs(self):
# consistent with the disabled -> enabled behaviour.
enabled |= 1
self.check_gcs_registers(enabled, locked, spr_el0)
+
+ @skipIfLLVMTargetMissing("AArch64")
+ def test_gcs_core_file(self):
+ # To re-generate the core file, build the test file and run it on a
+ # machine with GCS enabled. Note that because the kernel decides where
+ # the GCS is stored, the value of gcspr_el0 and which memory region it
+ # points to may change between runs.
+
+ self.runCmd("target create --core corefile")
+
+ self.expect(
+ "bt",
+ substrs=["stop reason = SIGSEGV: control protection fault"],
+ )
+
+ self.expect(
+ "register read --all",
+ substrs=[
+ "Guarded Control Stack Registers:",
+ "gcs_features_enabled = 0x0000000000000001",
+ "gcs_features_locked = 0x0000000000000000",
+ "gcspr_el0 = 0x0000ffffa83ffff0",
+ ],
+ )
+
+ # Core files do not include /proc/pid/smaps, so we cannot see the
+ # shadow stack "ss" flag. gcspr_el0 should at least point to some mapped
+ # region.
+ self.expect(
+ "memory region $gcspr_el0",
+ substrs=["[0x0000ffffa8000000-0x0000ffffa8400000) rw-"],
+ )
diff --git a/lldb/test/API/linux/aarch64/gcs/corefile b/lldb/test/API/linux/aarch64/gcs/corefile
new file mode 100644
index 00000000000000..34faa98c4d783d
Binary files /dev/null and b/lldb/test/API/linux/aarch64/gcs/corefile
diff er
More information about the lldb-commits
mailing list