-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb][AArch64][Linux] Add register field information for SME's SVCR register #71809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
First commit is #71808, review the second. |
@llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) ChangesThis register is a pseudo register but mirrors the architectural For the full details. Example output:
Full diff: https://github.com/llvm/llvm-project/pull/71809.diff 7 Files Affected:
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 15e8ba21266c896..19ba0e8c133edcf 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1224,6 +1224,17 @@ def dumpSessionInfo(self):
# (enables reading of the current test configuration)
# ====================================================
+ def hasXMLSupport(self):
+ """Returns True if lldb was built with XML support. Use this check to
+ enable parts of tests, if you want to skip a whole test use skipIfXmlSupportMissing
+ instead."""
+ return (
+ lldb.SBDebugger.GetBuildConfiguration()
+ .GetValueForKey("xml")
+ .GetValueForKey("value")
+ .GetBooleanValue(False)
+ )
+
def isMIPS(self):
"""Returns true if the architecture is MIPS."""
arch = self.getArchitecture()
diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp
index 87f2464a9eb4868..77c7116d3c624ae 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.cpp
@@ -24,6 +24,32 @@
using namespace lldb_private;
+LinuxArm64RegisterFlags::Fields
+LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
+ (void)hwcap;
+ (void)hwcap2;
+ // Represents the pseudo register that lldb-server builds, which itself
+ // matches the architectural register SCVR. The fields match SVCR in the Arm
+ // manual.
+ return {
+ {"ZA", 1},
+ {"SM", 0},
+ };
+}
+
+LinuxArm64RegisterFlags::Fields
+LinuxArm64RegisterFlags::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2) {
+ (void)hwcap;
+ (void)hwcap2;
+ // Represents the contents of NT_ARM_TAGGED_ADDR_CTRL and the value passed
+ // to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the defines
+ // used to build the value.
+ return {{"TAGS", 3, 18}, // 16 bit bitfield shifted up by PR_MTE_TAG_SHIFT.
+ {"TCF_ASYNC", 2},
+ {"TCF_SYNC", 1},
+ {"TAGGED_ADDR_ENABLE", 0}};
+}
+
LinuxArm64RegisterFlags::Fields
LinuxArm64RegisterFlags::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) {
std::vector<RegisterFlags::Field> fpcr_fields{
diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h
index 651a8c86f7c86a9..660bef08700f4c8 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsLinux_arm64.h
@@ -58,6 +58,8 @@ class LinuxArm64RegisterFlags {
static Fields DetectCPSRFields(uint64_t hwcap, uint64_t hwcap2);
static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2);
static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2);
+ static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2);
+ static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2);
struct RegisterEntry {
RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
@@ -67,10 +69,12 @@ class LinuxArm64RegisterFlags {
llvm::StringRef m_name;
RegisterFlags m_flags;
DetectorFn m_detector;
- } m_registers[3] = {
+ } m_registers[5] = {
RegisterEntry("cpsr", 4, DetectCPSRFields),
RegisterEntry("fpsr", 4, DetectFPSRFields),
RegisterEntry("fpcr", 4, DetectFPCRFields),
+ RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields),
+ RegisterEntry("svcr", 8, DetectSVCRFields),
};
// Becomes true once field detection has been run for all registers.
diff --git a/lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py b/lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py
index 7fd6b2dada640e6..3eaca00b0dccca9 100644
--- a/lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py
+++ b/lldb/test/API/commands/register/register/aarch64_mte_ctrl_register/TestMTECtrlRegister.py
@@ -34,17 +34,28 @@ def test_mte_ctrl_register(self):
substrs=["stop reason = breakpoint 1."],
)
- # Bit 0 = tagged addressing enabled
- # Bit 1 = synchronous faults
- # Bit 2 = asynchronous faults
- # We start enabled with synchronous faults.
- self.expect("register read mte_ctrl", substrs=["0x0000000000000003"])
+ def check_mte_ctrl(async_err, sync_err):
+ # Bit 0 = tagged addressing enabled
+ # Bit 1 = synchronous faults
+ # Bit 2 = asynchronous faults
+ value = "0x{:016x}".format((async_err << 2) | (sync_err << 1) | 1)
+ expected = [value]
+
+ if self.hasXMLSupport():
+ expected.append(
+ "(TAGS = 0, TCF_ASYNC = {}, TCF_SYNC = {}, TAGGED_ADDR_ENABLE = 1)".format(
+ async_err, sync_err
+ )
+ )
+
+ self.expect("register read mte_ctrl", substrs=expected)
+ # We start enabled with synchronous faults.
+ check_mte_ctrl(0, 1)
# Change to asynchronous faults.
self.runCmd("register write mte_ctrl 5")
- self.expect("register read mte_ctrl", substrs=["0x0000000000000005"])
-
+ check_mte_ctrl(1, 0)
# This would return to synchronous faults if we did not restore the
# previous value.
self.expect("expression setup_mte()", substrs=["= 0"])
- self.expect("register read mte_ctrl", substrs=["0x0000000000000005"])
+ check_mte_ctrl(1, 0)
diff --git a/lldb/test/API/commands/register/register/aarch64_sme_z_registers/save_restore/TestSMEZRegistersSaveRestore.py b/lldb/test/API/commands/register/register/aarch64_sme_z_registers/save_restore/TestSMEZRegistersSaveRestore.py
index a0949d80c56640a..9433aae0c53c45e 100644
--- a/lldb/test/API/commands/register/register/aarch64_sme_z_registers/save_restore/TestSMEZRegistersSaveRestore.py
+++ b/lldb/test/API/commands/register/register/aarch64_sme_z_registers/save_restore/TestSMEZRegistersSaveRestore.py
@@ -180,9 +180,12 @@ def za_expr_test_impl(self, sve_mode, za_state, swap_start_vl):
self.runCmd("register read " + sve_reg_names)
sve_values = self.res.GetOutput()
- svcr_value = 1 if sve_mode == Mode.SSVE else 0
- if za_state == ZA.Enabled:
- svcr_value += 2
+ za = 1 if za_state == ZA.Enabled else 0
+ sm = 1 if sve_mode == Mode.SSVE else 0
+ svcr_value = "0x{:016x}".format((za << 1) | sm)
+ expected_svcr = [svcr_value]
+ if self.hasXMLSupport():
+ expected_svcr.append("(ZA = {}, SM = {})".format(za, sm))
has_zt0 = self.isAArch64SME2()
@@ -201,7 +204,8 @@ def check_regs():
self.assertEqual(start_vg, self.read_vg())
self.expect("register read " + sve_reg_names, substrs=[sve_values])
- self.expect("register read svcr", substrs=["0x{:016x}".format(svcr_value)])
+
+ self.expect("register read svcr", substrs=expected_svcr)
for expr in exprs:
expr_cmd = "expression {}()".format(expr)
diff --git a/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py b/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
index 4389d3d761d79c2..045f8c0a7010839 100644
--- a/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
+++ b/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
@@ -235,4 +235,11 @@ def test_mte_ctrl_register(self):
# * Allowed tags value of 0xFFFF, shifted up by 3 resulting in 0x7fff8.
# * Bit 1 set to enable synchronous tag faults.
# * Bit 0 set to enable the tagged address ABI.
- self.expect("register read mte_ctrl", substrs=["mte_ctrl = 0x000000000007fffb"])
+ expected = ["mte_ctrl = 0x000000000007fffb"]
+
+ if self.hasXMLSupport():
+ expected.append(
+ "(TAGS = 65535, TCF_ASYNC = 0, TCF_SYNC = 1, TAGGED_ADDR_ENABLE = 1)"
+ )
+
+ self.expect("register read mte_ctrl", substrs=expected)
diff --git a/lldb/test/API/linux/aarch64/sme_core_file/TestAArch64LinuxSMECoreFile.py b/lldb/test/API/linux/aarch64/sme_core_file/TestAArch64LinuxSMECoreFile.py
index a5fdd0ab2068cbb..ee699aad2982607 100644
--- a/lldb/test/API/linux/aarch64/sme_core_file/TestAArch64LinuxSMECoreFile.py
+++ b/lldb/test/API/linux/aarch64/sme_core_file/TestAArch64LinuxSMECoreFile.py
@@ -5,17 +5,17 @@
import lldb
import itertools
-from enum import Enum
+from enum import IntEnum
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
-class Mode(Enum):
+class Mode(IntEnum):
SVE = 0
SSVE = 1
-class ZA(Enum):
+class ZA(IntEnum):
Disabled = 0
Enabled = 1
@@ -56,7 +56,12 @@ def check_corefile(self, corefile):
svcr = 1 if sve_mode == Mode.SSVE else 0
if za == ZA.Enabled:
svcr |= 2
- self.expect("register read svcr", substrs=["0x{:016x}".format(svcr)])
+
+ expected_svcr = ["0x{:016x}".format(svcr)]
+ if self.hasXMLSupport():
+ expected_svcr.append("(ZA = {:d}, SM = {})".format(za, sve_mode))
+
+ self.expect("register read svcr", substrs=expected_svcr)
repeat_bytes = lambda v, n: " ".join(["0x{:02x}".format(v)] * n)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
…register This register is a pseudo register but mirrors the architectural register's contents. See: https://developer.arm.com/documentation/ddi0616/latest/ For the full details. Example output: ``` (lldb) register read svcr svcr = 0x0000000000000002 = (ZA = 1, SM = 0) ```
c0aef38
to
67fb6c0
Compare
…register (llvm#71809) This register is a pseudo register but mirrors the architectural register's contents. See: https://developer.arm.com/documentation/ddi0616/latest/ For the full details. Example output: ``` (lldb) register read svcr svcr = 0x0000000000000002 = (ZA = 1, SM = 0) ```
This register is a pseudo register but mirrors the architectural
register's contents. See:
https://developer.arm.com/documentation/ddi0616/latest/
For the full details. Example output: