Index: lldb/test/API/functionalities/unwind/aarch64_unwind_pac/Makefile =================================================================== --- /dev/null +++ lldb/test/API/functionalities/unwind/aarch64_unwind_pac/Makefile @@ -0,0 +1,5 @@ +C_SOURCES := main.c + +CFLAGS := -g -Os -march=armv8.5-a -mbranch-protection=pac-ret+leaf + +include Makefile.rules Index: lldb/test/API/functionalities/unwind/aarch64_unwind_pac/TestAArch64UnwindPAC.py =================================================================== --- /dev/null +++ lldb/test/API/functionalities/unwind/aarch64_unwind_pac/TestAArch64UnwindPAC.py @@ -0,0 +1,43 @@ +""" +Test that we can backtrace correctly when AArch64 PAC is enabled +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class AArch64UnwindPAC(TestBase): + mydir = TestBase.compute_mydir(__file__) + + @skipIf(archs=no_match(["aarch64"])) + @skipIf(oslist=no_match(['linux'])) + def test(self): + """Test that we can backtrace correctly when AArch64 PAC is enabled""" + self.build() + + self.line = line_number('main.c', '// Frame func_c') + + 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) + + backtrace = ["func_c", "func_b", "func_a", "main", "__libc_start_main", "_start"] + self.assertEqual(thread.GetNumFrames(), len(backtrace)) + for frame_idx, frame in enumerate(thread.frames): + frame = thread.GetFrameAtIndex(frame_idx) + self.assertTrue(frame) + self.assertEqual(frame.GetFunctionName(), backtrace[frame_idx]) + if (frame_idx < 4): + self.assertEqual(frame.GetLineEntry().GetLine(), + line_number("main.c", "Frame " + backtrace[frame_idx])) Index: lldb/test/API/functionalities/unwind/aarch64_unwind_pac/main.c =================================================================== --- /dev/null +++ lldb/test/API/functionalities/unwind/aarch64_unwind_pac/main.c @@ -0,0 +1,24 @@ +// This program makes a multi tier nested function call to test AArch64 +// Pointer Authentication feature. + +// To enable PAC return address signing compile with following clang arguments: +// -march=armv8.5-a -mbranch-protection=pac-ret+leaf + +#include + +static void __attribute__((noinline)) func_c(void) { + exit(0); // Frame func_c +} + +static void __attribute__((noinline)) func_b(void) { + func_c(); // Frame func_b +} + +static void __attribute__((noinline)) func_a(void) { + func_b(); // Frame func_a +} + +int main(int argc, char *argv[]) { + func_a(); // Frame main + return 0; +}