DavidSpickett updated this revision to Diff 471481.
DavidSpickett added a comment.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Add a release note.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D136938/new/
https://reviews.llvm.org/D136938
Files:
lldb/source/Target/Target.cpp
lldb/test/API/linux/aarch64/tagged_code_break/Makefile
lldb/test/API/linux/aarch64/tagged_code_break/TestAArch64LinuxTaggedCodeBreak.py
lldb/test/API/linux/aarch64/tagged_code_break/main.c
llvm/docs/ReleaseNotes.rst
Index: llvm/docs/ReleaseNotes.rst
===================================================================
--- llvm/docs/ReleaseNotes.rst
+++ llvm/docs/ReleaseNotes.rst
@@ -193,6 +193,10 @@
Changes to LLDB
---------------------------------
+* LLDB is now able to breakpoint tagged addresses. This will most commonly be
+ function pointers that use AArch64's Top Byte Ignore, Memory Tagging, or
+ Pointer Authentication.
+
Changes to Sanitizers
---------------------
Index: lldb/test/API/linux/aarch64/tagged_code_break/main.c
===================================================================
--- /dev/null
+++ lldb/test/API/linux/aarch64/tagged_code_break/main.c
@@ -0,0 +1,18 @@
+#include <stdint.h>
+
+void foo(void) {}
+typedef void (*FooPtr)(void);
+
+int main() {
+ FooPtr fnptr = foo;
+ // Set top byte.
+ fnptr = (FooPtr)((uintptr_t)fnptr | (uintptr_t)0xff << 56);
+ // Then apply a PAuth signature to it.
+ __asm__ __volatile__("pacdza %0" : "=r"(fnptr) : "r"(fnptr));
+ // fnptr is now:
+ // <8 bit top byte tag><pointer signature><virtual address>
+
+ foo(); // Set break point at this line.
+
+ return 0;
+}
Index: lldb/test/API/linux/aarch64/tagged_code_break/TestAArch64LinuxTaggedCodeBreak.py
===================================================================
--- /dev/null
+++ lldb/test/API/linux/aarch64/tagged_code_break/TestAArch64LinuxTaggedCodeBreak.py
@@ -0,0 +1,57 @@
+"""
+Test that "breakpoint set -a" uses the ABI plugin to remove non-address bits
+before attempting to set a breakpoint.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class AArch64LinuxTaggedCodeBreak(TestBase):
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def do_tagged_break(self, hardware):
+ if not self.isAArch64PAuth():
+ self.skipTest('Target must support pointer authentication.')
+
+ 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'])
+
+ cmd = "breakpoint set -a fnptr"
+ # LLDB only has the option to force hardware break, not software.
+ # It prefers sofware break when it can and this will be one of those cases.
+ if hardware:
+ cmd += " --hardware"
+ self.expect(cmd)
+
+ self.runCmd("continue")
+ self.assertEqual(self.process().GetState(), lldb.eStateStopped)
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs=['stopped', '`foo at main.c', 'stop reason = breakpoint'])
+
+ # AArch64 Linux always enables the top byte ignore feature
+ @skipUnlessArch("aarch64")
+ @skipUnlessPlatform(["linux"])
+ def test_software_break(self):
+ self.do_tagged_break(False)
+
+ @skipUnlessArch("aarch64")
+ @skipUnlessPlatform(["linux"])
+ def test_hardware_break(self):
+ self.do_tagged_break(True)
\ No newline at end of file
Index: lldb/test/API/linux/aarch64/tagged_code_break/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/linux/aarch64/tagged_code_break/Makefile
@@ -0,0 +1,5 @@
+C_SOURCES := main.c
+
+CFLAGS_EXTRAS := -march=armv8.3-a
+
+include Makefile.rules
Index: lldb/source/Target/Target.cpp
===================================================================
--- lldb/source/Target/Target.cpp
+++ lldb/source/Target/Target.cpp
@@ -2626,8 +2626,14 @@
}
lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
- auto arch_plugin = GetArchitecturePlugin();
- return arch_plugin ? arch_plugin->GetBreakableLoadAddress(addr, *this) : addr;
+ lldb::ABISP abi_plugin = m_process_sp ? m_process_sp->GetABI() : nullptr;
+ if (abi_plugin)
+ addr = abi_plugin->FixCodeAddress(addr);
+
+ if (auto arch_plugin = GetArchitecturePlugin())
+ addr = arch_plugin->GetBreakableLoadAddress(addr, *this);
+
+ return addr;
}
SourceManager &Target::GetSourceManager() {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits