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