================
@@ -0,0 +1,129 @@
+"""
+Test lldb's support for the AArch64 Permission Overlay extension (POE), which
+is used to implement Linux's memory protection keys feature.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class AArch64LinuxPOE(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    EXPECTED_POR = "por = 0x0000000001234567"
+    EXPECTED_POR_FIELDS = (
+        "         = {\n"
+        "             Perm15 = No Access\n"
+        "             Perm14 = No Access\n"
+        "             Perm13 = No Access\n"
+        "             Perm12 = No Access\n"
+        "             Perm11 = No Access\n"
+        "             Perm10 = No Access\n"
+        "             Perm9 = No Access\n"
+        "             Perm8 = No Access\n"
+        "             Perm7 = No Access\n"
+        "             Perm6 = Read\n"
+        "             Perm5 = Execute\n"
+        "             Perm4 = Read, Execute\n"
+        "             Perm3 = Write\n"
+        "             Perm2 = Write, Read\n"
+        "             Perm1 = Write, Execute\n"
+        "             Perm0 = Read, Write, Execute\n"
+        "           }"
+    )
+
+    @skipUnlessArch("aarch64")
+    @skipUnlessPlatform(["linux"])
+    def test_poe_live(self):
+        if not self.isAArch64POE():
+            self.skipTest("POE must be present.")
+
+        self.build()
+        self.runCmd("file " + self.getBuildArtifact("a.out"), 
CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line(
+            self,
+            "main.c",
+            line_number("main.c", "// Set break point at this line."),
+            num_expected_locations=1,
+        )
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        if self.process().GetState() == lldb.eStateExited:
+            self.fail("Test program failed to run.")
+
+        self.expect(
+            "thread list",
+            STOPPED_DUE_TO_BREAKPOINT,
+            substrs=["stopped", "stop reason = breakpoint"],
+        )
+
+        self.expect(
+            "register read --all",
+            substrs=[
+                "Permission Overlay Registers",
+                f"{self.EXPECTED_POR}",
+            ],
+        )
+
+        if self.hasXMLSupport():
+            self.expect(
+                "register read por",
+                substrs=[f"     {self.EXPECTED_POR}\n" + 
self.EXPECTED_POR_FIELDS],
+            )
+
+        # POR should be restored after expression evaluation.
+        self.expect("expression expr_function()", substrs=["$0 = 1"])
+        self.expect("register read por", substrs=[self.EXPECTED_POR])
+
+        # Not passing this to the application allows us to fix the permissions
+        # using lldb, then continue to a normal exit.
+        self.runCmd("process handle SIGSEGV --pass false")
+
+        self.expect(
+            "continue",
+            substrs=[
+                "stop reason = signal SIGSEGV: failed protection key checks 
(fault address="
+            ],
+        )
+
+        # This fault should have happened due to the write, not the read.
+        self.assertEqual(
+            self.dbg.GetSelectedTarget()
+            .GetProcess()
+            .GetSelectedThread()
+            .GetSelectedFrame()
+            .GetFunctionName(),
+            "cause_write_fault",
+        )
+
+        # Allow writes so we can continue. This value has permission 6 changed
+        # from read only (1) to read+write (4).
----------------
DavidSpickett wrote:

This should say:
from read only (1) to write (4)

Will fix this.

https://github.com/llvm/llvm-project/pull/177145
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to