xref: /llvm-project/lldb/test/API/linux/aarch64/tls_registers/TestAArch64LinuxTLSRegisters.py (revision ecbe78c124a78a4ea6e06b1d52ce281dcc394332)
1"""
2Test lldb's ability to read and write the AArch64 TLS registers.
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10
11class AArch64LinuxTLSRegisters(TestBase):
12    NO_DEBUG_INFO_TESTCASE = True
13
14    def setup(self, registers):
15        self.build()
16        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
17
18        lldbutil.run_break_set_by_file_and_line(
19            self,
20            "main.c",
21            line_number("main.c", "// Set break point at this line."),
22            num_expected_locations=1,
23        )
24
25        lldbutil.run_break_set_by_file_and_line(
26            self,
27            "main.c",
28            line_number("main.c", "// Set break point 2 at this line."),
29            num_expected_locations=1,
30        )
31
32        if "tpidr2" in registers:
33            self.runCmd("settings set target.run-args 1")
34        self.runCmd("run", RUN_SUCCEEDED)
35
36        if self.process().GetState() == lldb.eStateExited:
37            self.fail("Test program failed to run.")
38
39        self.expect(
40            "thread list",
41            STOPPED_DUE_TO_BREAKPOINT,
42            substrs=["stopped", "stop reason = breakpoint"],
43        )
44
45    def check_registers(self, registers, values):
46        regs = self.thread().GetSelectedFrame().GetRegisters()
47        tls_regs = regs.GetFirstValueByName("Thread Local Storage Registers")
48        self.assertTrue(tls_regs.IsValid(), "No TLS registers found.")
49
50        for register in registers:
51            tls_reg = tls_regs.GetChildMemberWithName(register)
52            self.assertTrue(
53                tls_reg.IsValid(), "{} register not found.".format(register)
54            )
55            self.assertEqual(tls_reg.GetValueAsUnsigned(), values[register])
56
57    def check_tls_reg(self, registers):
58        self.setup(registers)
59
60        # Since we can't predict what the value will be, the program has set
61        # a target value for us to find.
62        initial_values = {
63            "tpidr": 0x1122334455667788,
64            "tpidr2": 0x8877665544332211,
65        }
66
67        self.check_registers(registers, initial_values)
68
69        # Their values should be restored if an expression modifies them.
70        self.runCmd("expression expr_func()")
71
72        self.check_registers(registers, initial_values)
73
74        set_values = {
75            "tpidr": 0x1111222233334444,
76            "tpidr2": 0x4444333322221111,
77        }
78
79        # Set our own value(s) for the program to find.
80        for register in registers:
81            self.expect(
82                "register write {} 0x{:x}".format(register, set_values[register])
83            )
84
85        self.expect("continue")
86
87        self.expect(
88            "thread list",
89            STOPPED_DUE_TO_BREAKPOINT,
90            substrs=["stopped", "stop reason = breakpoint"],
91        )
92
93        for register in registers:
94            self.expect("p {}_was_set".format(register), substrs=["true"])
95
96    @skipUnlessArch("aarch64")
97    @skipUnlessPlatform(["linux"])
98    def test_tls_no_sme(self):
99        if self.isAArch64SME():
100            self.skipTest("SME must not be present.")
101
102        self.check_tls_reg(["tpidr"])
103
104    @skipUnlessArch("aarch64")
105    @skipUnlessPlatform(["linux"])
106    def test_tls_sme(self):
107        if not self.isAArch64SME():
108            self.skipTest("SME must be present.")
109
110        self.check_tls_reg(["tpidr", "tpidr2"])
111
112    @skipUnlessArch("aarch64")
113    @skipUnlessPlatform(["linux"])
114    def test_tpidr2_no_sme(self):
115        if self.isAArch64SME():
116            self.skipTest("SME must not be present.")
117
118        self.setup("tpidr")
119
120        regs = self.thread().GetSelectedFrame().GetRegisters()
121        tls_regs = regs.GetFirstValueByName("Thread Local Storage Registers")
122        self.assertTrue(tls_regs.IsValid(), "No TLS registers found.")
123        tls_reg = tls_regs.GetChildMemberWithName("tpidr2")
124        self.assertFalse(tls_reg.IsValid(), "tpdir2 should not be present without SME")
125