Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define HWCAP_ASIMDHP (1ULL << 10)
#define HWCAP_DIT (1ULL << 24)
#define HWCAP_SSBS (1ULL << 28)
#define HWCAP_GCS (1UL << 32)

#define HWCAP2_BTI (1ULL << 17)
#define HWCAP2_MTE (1ULL << 18)
Expand Down Expand Up @@ -50,6 +51,21 @@ Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2) {
};
}

Arm64RegisterFlagsDetector::Fields
Arm64RegisterFlagsDetector::DetectGCSFeatureFields(uint64_t hwcap,
uint64_t hwcap2) {
(void)hwcap2;

if (!(hwcap & HWCAP_GCS))
return {};

return {
{"PUSH", 2},
{"WRITE", 1},
{"ENABLE", 0},
};
}

Arm64RegisterFlagsDetector::Fields
Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
(void)hwcap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Arm64RegisterFlagsDetector {
static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2);
static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2);
static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2);
static Fields DetectGCSFeatureFields(uint64_t hwcap, uint64_t hwcap2);

struct RegisterEntry {
RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
Expand All @@ -70,13 +71,15 @@ class Arm64RegisterFlagsDetector {
llvm::StringRef m_name;
RegisterFlags m_flags;
DetectorFn m_detector;
} m_registers[6] = {
} m_registers[8] = {
RegisterEntry("cpsr", 4, DetectCPSRFields),
RegisterEntry("fpsr", 4, DetectFPSRFields),
RegisterEntry("fpcr", 4, DetectFPCRFields),
RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields),
RegisterEntry("svcr", 8, DetectSVCRFields),
RegisterEntry("fpmr", 8, DetectFPMRFields),
RegisterEntry("gcs_features_enabled", 8, DetectGCSFeatureFields),
RegisterEntry("gcs_features_locked", 8, DetectGCSFeatureFields),
};

// Becomes true once field detection has been run for all registers.
Expand Down
15 changes: 14 additions & 1 deletion lldb/test/API/linux/aarch64/gcs/TestAArch64LinuxGCS.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,10 @@ def test_gcs_registers(self):
self.runCmd(f"register write gcs_features_enabled {enabled}")
self.expect(
"register read gcs_features_enabled",
substrs=[f"gcs_features_enabled = 0x{enabled:016x}"],
substrs=[
f"gcs_features_enabled = 0x{enabled:016x}",
f"= (PUSH = {(enabled >> 2) & 1}, WRITE = {(enabled >> 1) & 1}, ENABLE = {enabled & 1})",
],
)

# With GCS disabled, the invalid guarded control stack pointer is not
Expand Down Expand Up @@ -399,6 +402,16 @@ def test_gcs_core_file(self):
],
)

# Should get register fields for both. They have the same fields.
self.expect(
"register read gcs_features_enabled",
substrs=["= (PUSH = 0, WRITE = 0, ENABLE = 1)"],
)
self.expect(
"register read gcs_features_locked",
substrs=["= (PUSH = 0, WRITE = 0, ENABLE = 0)"],
)

# 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.
Expand Down
Loading