1"""
2Test that we can backtrace correctly when AArch64 PAC is enabled
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10
11class AArch64UnwindPAC(TestBase):
12    mydir = TestBase.compute_mydir(__file__)
13
14    @skipIf(archs=no_match(["aarch64"]))
15    @skipIf(oslist=no_match(['linux']))
16    def test(self):
17        """Test that we can backtrace correctly when AArch64 PAC is enabled"""
18        if not self.isAArch64PAuth():
19            self.skipTest('Target must support Pointer Authentication.')
20
21        self.build()
22
23        self.line = line_number('main.c', '// Frame func_c')
24
25        exe = self.getBuildArtifact("a.out")
26        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
27
28        lldbutil.run_break_set_by_file_and_line(
29            self, "main.c", self.line, num_expected_locations=1)
30        self.runCmd("run", RUN_SUCCEEDED)
31        self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
32                    substrs=["stop reason = breakpoint 1."])
33
34        target = self.dbg.GetSelectedTarget()
35        process = target.GetProcess()
36        thread = process.GetThreadAtIndex(0)
37
38        backtrace = ["func_c", "func_b", "func_a", "main", "__libc_start_main", "_start"]
39        self.assertEqual(thread.GetNumFrames(), len(backtrace))
40        for frame_idx, frame in enumerate(thread.frames):
41            frame = thread.GetFrameAtIndex(frame_idx)
42            self.assertTrue(frame)
43            self.assertEqual(frame.GetFunctionName(), backtrace[frame_idx])
44			# Check line number for functions in main.c
45            if (frame_idx < 4):
46                self.assertEqual(frame.GetLineEntry().GetLine(),
47                                 line_number("main.c", "Frame " + backtrace[frame_idx]))
48