[Lldb-commits] [lldb] 9ab6771 - [LLDB] Arm64/Linux test case for MTE and Pointer Authentication regset

Muhammad Omair Javaid via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 30 16:39:50 PDT 2021


Author: Muhammad Omair Javaid
Date: 2021-03-31T04:39:14+05:00
New Revision: 9ab677180091a690cd99d4ac55d5fb9e1149b1ec

URL: https://github.com/llvm/llvm-project/commit/9ab677180091a690cd99d4ac55d5fb9e1149b1ec
DIFF: https://github.com/llvm/llvm-project/commit/9ab677180091a690cd99d4ac55d5fb9e1149b1ec.diff

LOG: [LLDB] Arm64/Linux test case for MTE and Pointer Authentication regset

This patch adds a test case to test AArch64 dynamic register sets.
This tests for the availability of certain register sets and query
their registers accordingly.

Reviewed By: labath, DavidSpickett

Differential Revision: https://reviews.llvm.org/D96463

Added: 
    lldb/test/API/commands/register/register/aarch64_dynamic_regset/Makefile
    lldb/test/API/commands/register/register/aarch64_dynamic_regset/TestArm64DynamicRegsets.py
    lldb/test/API/commands/register/register/aarch64_dynamic_regset/main.c

Modified: 
    lldb/packages/Python/lldbsuite/test/lldbtest.py

Removed: 
    


################################################################################
diff  --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 958cadd3a7c81..a9928af677a6e 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1269,7 +1269,7 @@ def isPPC64le(self):
             return True
         return False
 
-    def isAArch64SVE(self):
+    def getCPUInfo(self):
         triple = self.dbg.GetSelectedPlatform().GetTriple()
 
         # TODO other platforms, please implement this function
@@ -1290,7 +1290,16 @@ def isAArch64SVE(self):
         except:
             return False
 
-        return " sve " in cpuinfo
+        return cpuinfo
+
+    def isAArch64SVE(self):
+        return "sve" in self.getCPUInfo()
+
+    def isAArch64MTE(self):
+        return "mte" in self.getCPUInfo()
+
+    def isAArch64PAuth(self):
+        return "paca" in self.getCPUInfo()
 
     def hasLinuxVmFlags(self):
         """ Check that the target machine has "VmFlags" lines in

diff  --git a/lldb/test/API/commands/register/register/aarch64_dynamic_regset/Makefile b/lldb/test/API/commands/register/register/aarch64_dynamic_regset/Makefile
new file mode 100644
index 0000000000000..5fc881c2db97c
--- /dev/null
+++ b/lldb/test/API/commands/register/register/aarch64_dynamic_regset/Makefile
@@ -0,0 +1,5 @@
+C_SOURCES := main.c
+
+CFLAGS_EXTRAS := -march=armv8-a+sve
+
+include Makefile.rules

diff  --git a/lldb/test/API/commands/register/register/aarch64_dynamic_regset/TestArm64DynamicRegsets.py b/lldb/test/API/commands/register/register/aarch64_dynamic_regset/TestArm64DynamicRegsets.py
new file mode 100644
index 0000000000000..ecaefb0e657e8
--- /dev/null
+++ b/lldb/test/API/commands/register/register/aarch64_dynamic_regset/TestArm64DynamicRegsets.py
@@ -0,0 +1,109 @@
+"""
+Test AArch64 dynamic register sets
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class RegisterCommandsTestCase(TestBase):
+
+    def check_sve_register_size(self, set, name, expected):
+        reg_value = set.GetChildMemberWithName(name)
+        self.assertTrue(reg_value.IsValid(),
+                        'Expected a register named %s' % (name))
+        self.assertEqual(reg_value.GetByteSize(), expected,
+                         'Expected a register %s size == %i bytes' % (name, expected))
+
+    def sve_regs_read_dynamic(self, sve_registers):
+        vg_reg = sve_registers.GetChildMemberWithName("vg")
+        vg_reg_value = sve_registers.GetChildMemberWithName(
+            "vg").GetValueAsUnsigned()
+
+        z_reg_size = vg_reg_value * 8
+        p_reg_size = int(z_reg_size / 8)
+
+        for i in range(32):
+            z_regs_value = '{' + \
+                ' '.join('0x{:02x}'.format(i + 1)
+                         for _ in range(z_reg_size)) + '}'
+            self.expect('register read z%i' %
+                        (i), substrs=[z_regs_value])
+
+        # Set P registers with random test values. The P registers are predicate
+        # registers, which hold one bit for each byte available in a Z register.
+        # For below mentioned values of P registers, P(0,5,10,15) will have all
+        # Z register lanes set while P(4,9,14) will have no lanes set.
+        p_value_bytes = ['0xff', '0x55', '0x11', '0x01', '0x00']
+        for i in range(16):
+            p_regs_value = '{' + \
+                ' '.join(p_value_bytes[i % 5] for _ in range(p_reg_size)) + '}'
+            self.expect('register read p%i' % (i), substrs=[p_regs_value])
+
+        self.expect("register read ffr", substrs=[p_regs_value])
+
+        for i in range(32):
+            z_regs_value = '{' + \
+                ' '.join('0x{:02x}'.format(32 - i)
+                         for _ in range(z_reg_size)) + '}'
+            self.runCmd("register write z%i '%s'" % (i, z_regs_value))
+            self.expect('register read z%i' % (i), substrs=[z_regs_value])
+
+        for i in range(16):
+            p_regs_value = '{' + \
+                ' '.join('0x{:02x}'.format(16 - i)
+                         for _ in range(p_reg_size)) + '}'
+            self.runCmd("register write p%i '%s'" % (i, p_regs_value))
+            self.expect('register read p%i' % (i), substrs=[p_regs_value])
+
+        p_regs_value = '{' + \
+            ' '.join('0x{:02x}'.format(8)
+                     for _ in range(p_reg_size)) + '}'
+        self.runCmd('register write ffr ' + "'" + p_regs_value + "'")
+        self.expect('register read ffr', substrs=[p_regs_value])
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @no_debug_info_test
+    @skipIf(archs=no_match(["aarch64"]))
+    @skipIf(oslist=no_match(['linux']))
+    def test_aarch64_dynamic_regset_config(self):
+        """Test AArch64 Dynamic Register sets configuration."""
+        self.build()
+        self.line = line_number('main.c', '// Set a break point here.')
+
+        exe = self.getBuildArtifact("a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line(
+            self, "main.c", self.line, num_expected_locations=1)
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=["stop reason = breakpoint 1."])
+
+        target = self.dbg.GetSelectedTarget()
+        process = target.GetProcess()
+        thread = process.GetThreadAtIndex(0)
+        currentFrame = thread.GetFrameAtIndex(0)
+
+        for registerSet in currentFrame.GetRegisters():
+            if 'Scalable Vector Extension Registers' in registerSet.GetName():
+                self.assertTrue(self.isAArch64SVE(),
+                    'LLDB enabled AArch64 SVE register set when it was disabled by target.')
+                self.sve_regs_read_dynamic(registerSet)
+            if 'MTE Control Register' in registerSet.GetName():
+                self.assertTrue(self.isAArch64MTE(),
+                    'LLDB enabled AArch64 MTE register set when it was disabled by target.')
+                self.runCmd("register write mte_ctrl 0x7fff9")
+                self.expect("register read mte_ctrl",
+                            substrs=['mte_ctrl = 0x000000000007fff9'])
+            if 'Pointer Authentication Registers' in registerSet.GetName():
+                self.assertTrue(self.isAArch64PAuth(),
+                    'LLDB enabled AArch64 Pointer Authentication register set when it was disabled by target.')
+                self.expect("register read data_mask",
+                            substrs=['data_mask = 0x'])
+                self.expect("register read code_mask",
+                            substrs=['code_mask = 0x'])

diff  --git a/lldb/test/API/commands/register/register/aarch64_dynamic_regset/main.c b/lldb/test/API/commands/register/register/aarch64_dynamic_regset/main.c
new file mode 100644
index 0000000000000..6ed25c4eb6a09
--- /dev/null
+++ b/lldb/test/API/commands/register/register/aarch64_dynamic_regset/main.c
@@ -0,0 +1,72 @@
+#include <sys/auxv.h>
+
+void set_sve_registers() {
+  // AArch64 SVE extension ISA adds a new set of vector and predicate registers:
+  // 32 Z registers, 16 P registers, and 1 FFR register.
+  // Code below populates SVE registers to be read back by the debugger via
+  // ptrace interface at runtime.
+  // The P registers are predicate registers and hold one bit for each byte
+  // available in a Z vector register. For example, an SVE implementation with
+  // 1024-bit Z registers has 128-bit predicate registers.
+  // ptrue/pfalse instruction is used to set a predicate lane with a pattern.
+  // pattern is decided based on size specifier, b, h, s and d. if size
+  // specified is b all lanes will be set to 1. which is needed to set all bytes
+  // in a Z registers to the specified value.
+  asm volatile("setffr\n\t");
+  asm volatile("ptrue p0.b\n\t");
+  asm volatile("ptrue p1.h\n\t");
+  asm volatile("ptrue p2.s\n\t");
+  asm volatile("ptrue p3.d\n\t");
+  asm volatile("pfalse p4.b\n\t");
+  asm volatile("ptrue p5.b\n\t");
+  asm volatile("ptrue p6.h\n\t");
+  asm volatile("ptrue p7.s\n\t");
+  asm volatile("ptrue p8.d\n\t");
+  asm volatile("pfalse p9.b\n\t");
+  asm volatile("ptrue p10.b\n\t");
+  asm volatile("ptrue p11.h\n\t");
+  asm volatile("ptrue p12.s\n\t");
+  asm volatile("ptrue p13.d\n\t");
+  asm volatile("pfalse p14.b\n\t");
+  asm volatile("ptrue p15.b\n\t");
+
+  asm volatile("cpy  z0.b, p0/z, #1\n\t");
+  asm volatile("cpy  z1.b, p5/z, #2\n\t");
+  asm volatile("cpy  z2.b, p10/z, #3\n\t");
+  asm volatile("cpy  z3.b, p15/z, #4\n\t");
+  asm volatile("cpy  z4.b, p0/z, #5\n\t");
+  asm volatile("cpy  z5.b, p5/z, #6\n\t");
+  asm volatile("cpy  z6.b, p10/z, #7\n\t");
+  asm volatile("cpy  z7.b, p15/z, #8\n\t");
+  asm volatile("cpy  z8.b, p0/z, #9\n\t");
+  asm volatile("cpy  z9.b, p5/z, #10\n\t");
+  asm volatile("cpy  z10.b, p10/z, #11\n\t");
+  asm volatile("cpy  z11.b, p15/z, #12\n\t");
+  asm volatile("cpy  z12.b, p0/z, #13\n\t");
+  asm volatile("cpy  z13.b, p5/z, #14\n\t");
+  asm volatile("cpy  z14.b, p10/z, #15\n\t");
+  asm volatile("cpy  z15.b, p15/z, #16\n\t");
+  asm volatile("cpy  z16.b, p0/z, #17\n\t");
+  asm volatile("cpy  z17.b, p5/z, #18\n\t");
+  asm volatile("cpy  z18.b, p10/z, #19\n\t");
+  asm volatile("cpy  z19.b, p15/z, #20\n\t");
+  asm volatile("cpy  z20.b, p0/z, #21\n\t");
+  asm volatile("cpy  z21.b, p5/z, #22\n\t");
+  asm volatile("cpy  z22.b, p10/z, #23\n\t");
+  asm volatile("cpy  z23.b, p15/z, #24\n\t");
+  asm volatile("cpy  z24.b, p0/z, #25\n\t");
+  asm volatile("cpy  z25.b, p5/z, #26\n\t");
+  asm volatile("cpy  z26.b, p10/z, #27\n\t");
+  asm volatile("cpy  z27.b, p15/z, #28\n\t");
+  asm volatile("cpy  z28.b, p0/z, #29\n\t");
+  asm volatile("cpy  z29.b, p5/z, #30\n\t");
+  asm volatile("cpy  z30.b, p10/z, #31\n\t");
+  asm volatile("cpy  z31.b, p15/z, #32\n\t");
+}
+
+int main() {
+  if (getauxval(AT_HWCAP) & HWCAP_SVE) // check if SVE is present
+    set_sve_registers();
+
+  return 0; // Set a break point here.
+}


        


More information about the lldb-commits mailing list