1""" 2Test the 'register' command. 3""" 4 5import os, sys, time 6import re 7import unittest2 8import lldb 9from lldbtest import * 10import lldbutil 11 12class RegisterCommandsTestCase(TestBase): 13 14 mydir = os.path.join("functionalities", "register") 15 16 def setUp(self): 17 TestBase.setUp(self) 18 self.has_teardown = False 19 20 def test_register_commands(self): 21 """Test commands related to registers, in particular vector registers.""" 22 if not self.getArchitecture() in ['i386', 'x86_64']: 23 self.skipTest("This test requires i386 or x86_64 as the architecture for the inferior") 24 self.buildDefault() 25 self.register_commands() 26 27 def test_fp_register_write(self): 28 """Test commands that write to registers, in particular floating-point registers.""" 29 if not self.getArchitecture() in ['i386', 'x86_64']: 30 self.skipTest("This test requires i386 or x86_64 as the architecture for the inferior") 31 self.buildDefault() 32 self.fp_register_write() 33 34 def test_register_expressions(self): 35 """Test expression evaluation with commands related to registers.""" 36 if not self.getArchitecture() in ['i386', 'x86_64']: 37 self.skipTest("This test requires i386 or x86_64 as the architecture for the inferior") 38 self.buildDefault() 39 self.register_expressions() 40 41 def test_convenience_registers(self): 42 """Test convenience registers.""" 43 if not self.getArchitecture() in ['x86_64']: 44 self.skipTest("This test requires x86_64 as the architecture for the inferior") 45 self.buildDefault() 46 self.convenience_registers() 47 48 def test_convenience_registers_with_process_attach(self): 49 """Test convenience registers after a 'process attach'.""" 50 if not self.getArchitecture() in ['x86_64']: 51 self.skipTest("This test requires x86_64 as the architecture for the inferior") 52 self.buildDefault() 53 self.convenience_registers_with_process_attach(test_16bit_regs=False) 54 55 @expectedFailureLinux("llvm.org/pr14600") # Linux doesn't support 16-bit convenience registers 56 @skipIfLinux # llvm.org/pr16301 LLDB occasionally exits with SIGABRT 57 def test_convenience_registers_16bit_with_process_attach(self): 58 """Test convenience registers after a 'process attach'.""" 59 if not self.getArchitecture() in ['x86_64']: 60 self.skipTest("This test requires x86_64 as the architecture for the inferior") 61 self.buildDefault() 62 self.convenience_registers_with_process_attach(test_16bit_regs=True) 63 64 def common_setup(self): 65 exe = os.path.join(os.getcwd(), "a.out") 66 67 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 68 69 # Break in main(). 70 lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=-1) 71 72 self.runCmd("run", RUN_SUCCEEDED) 73 74 # The stop reason of the thread should be breakpoint. 75 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 76 substrs = ['stopped', 'stop reason = breakpoint']) 77 78 def remove_log(self): 79 """ Remove the temporary log file generated by some tests.""" 80 if os.path.exists(self.log_file): 81 os.remove(self.log_file) 82 83 # platform specific logging of the specified category 84 def log_enable(self, category): 85 self.platform = "" 86 if sys.platform.startswith("darwin"): 87 self.platform = "" # TODO: add support for "log enable darwin registers" 88 if sys.platform.startswith("linux"): 89 self.platform = "linux" 90 91 if self.platform != "": 92 self.log_file = os.path.join(os.getcwd(), 'TestRegisters.log') 93 self.runCmd("log enable " + self.platform + " " + str(category) + " registers -v -f " + self.log_file, RUN_SUCCEEDED) 94 if not self.has_teardown: 95 self.has_teardown = True 96 self.addTearDownHook(self.remove_log) 97 98 def register_commands(self): 99 """Test commands related to registers, in particular vector registers.""" 100 self.common_setup() 101 102 # verify that logging does not assert 103 self.log_enable("registers") 104 105 self.expect("register read -a", MISSING_EXPECTED_REGISTERS, 106 substrs = ['registers were unavailable'], matching = False) 107 self.runCmd("register read xmm0") 108 self.runCmd("register read ymm15") # may be available 109 110 self.expect("register read -s 3", 111 substrs = ['invalid register set index: 3'], error = True) 112 113 def write_and_restore(self, frame, register, must_exist = True): 114 value = frame.FindValue(register, lldb.eValueTypeRegister) 115 if must_exist: 116 self.assertTrue(value.IsValid(), "finding a value for register " + register) 117 elif not value.IsValid(): 118 return # If register doesn't exist, skip this test 119 120 error = lldb.SBError() 121 register_value = value.GetValueAsUnsigned(error, 0) 122 self.assertTrue(error.Success(), "reading a value for " + register) 123 124 self.runCmd("register write " + register + " 0xff0e") 125 self.expect("register read " + register, 126 substrs = [register + ' = 0x', 'ff0e']) 127 128 self.runCmd("register write " + register + " " + str(register_value)) 129 self.expect("register read " + register, 130 substrs = [register + ' = 0x']) 131 132 def vector_write_and_read(self, frame, register, new_value, must_exist = True): 133 value = frame.FindValue(register, lldb.eValueTypeRegister) 134 if must_exist: 135 self.assertTrue(value.IsValid(), "finding a value for register " + register) 136 elif not value.IsValid(): 137 return # If register doesn't exist, skip this test 138 139 self.runCmd("register write " + register + " \'" + new_value + "\'") 140 self.expect("register read " + register, 141 substrs = [register + ' = ', new_value]) 142 143 def fp_register_write(self): 144 exe = os.path.join(os.getcwd(), "a.out") 145 146 # Create a target by the debugger. 147 target = self.dbg.CreateTarget(exe) 148 self.assertTrue(target, VALID_TARGET) 149 150 lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=-1) 151 152 # Launch the process, and do not stop at the entry point. 153 process = target.LaunchSimple(None, None, os.getcwd()) 154 155 process = target.GetProcess() 156 self.assertTrue(process.GetState() == lldb.eStateStopped, 157 PROCESS_STOPPED) 158 159 thread = process.GetThreadAtIndex(0) 160 self.assertTrue(thread.IsValid(), "current thread is valid") 161 162 currentFrame = thread.GetFrameAtIndex(0) 163 self.assertTrue(currentFrame.IsValid(), "current frame is valid") 164 165 self.write_and_restore(currentFrame, "fcw", False) 166 self.write_and_restore(currentFrame, "fsw", False) 167 self.write_and_restore(currentFrame, "ftw", False) 168 self.write_and_restore(currentFrame, "ip", False) 169 self.write_and_restore(currentFrame, "dp", False) 170 self.write_and_restore(currentFrame, "mxcsr", False) 171 self.write_and_restore(currentFrame, "mxcsrmask", False) 172 173 new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" 174 self.vector_write_and_read(currentFrame, "stmm0", new_value) 175 new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a}" 176 self.vector_write_and_read(currentFrame, "stmm7", new_value) 177 178 new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x2f 0x2f}" 179 self.vector_write_and_read(currentFrame, "xmm0", new_value) 180 new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f}" 181 self.vector_write_and_read(currentFrame, "xmm15", new_value, False) 182 183 has_avx = False 184 registerSets = currentFrame.GetRegisters() # Returns an SBValueList. 185 for registerSet in registerSets: 186 if 'advanced vector extensions' in registerSet.GetName().lower(): 187 has_avx = True 188 break 189 190 if has_avx: 191 new_value = "{0x01 0x02 0x03 0x00 0x00 0x00 0x00 0x00 0x09 0x0a 0x2f 0x2f 0x2f 0x2f 0x0e 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0c 0x0d 0x0e 0x0f}" 192 self.vector_write_and_read(currentFrame, "ymm0", new_value) 193 self.vector_write_and_read(currentFrame, "ymm15", new_value) 194 self.expect("expr $ymm0", substrs = ['vector_type']) 195 else: 196 self.runCmd("register read ymm0") 197 198 def register_expressions(self): 199 """Test expression evaluation with commands related to registers.""" 200 self.common_setup() 201 202 self.expect("expr/x $eax", 203 substrs = ['unsigned int', ' = 0x']) 204 205 if self.getArchitecture() in ['x86_64']: 206 self.expect("expr -- ($rax & 0xffffffff) == $eax", 207 substrs = ['true']) 208 209 self.expect("expr $xmm0", 210 substrs = ['vector_type']) 211 212 self.expect("expr (unsigned int)$xmm0[0]", 213 substrs = ['unsigned int']) 214 215 def convenience_registers(self): 216 """Test convenience registers.""" 217 self.common_setup() 218 219 # The command "register read -a" does output a derived register like eax... 220 self.expect("register read -a", matching=True, 221 substrs = ['eax']) 222 223 # ...however, the vanilla "register read" command should not output derived registers like eax. 224 self.expect("register read", matching=False, 225 substrs = ['eax']) 226 227 # Test reading of rax and eax. 228 self.expect("register read rax eax", 229 substrs = ['rax = 0x', 'eax = 0x']) 230 231 # Now write rax with a unique bit pattern and test that eax indeed represents the lower half of rax. 232 self.runCmd("register write rax 0x1234567887654321") 233 self.expect("register read rax 0x1234567887654321", 234 substrs = ['0x1234567887654321']) 235 236 def convenience_registers_with_process_attach(self, test_16bit_regs): 237 """Test convenience registers after a 'process attach'.""" 238 exe = os.path.join(os.getcwd(), "a.out") 239 240 # Spawn a new process 241 pid = 0 242 if sys.platform.startswith('linux'): 243 pid = self.forkSubprocess(exe, ['wait_for_attach']) 244 else: 245 proc = self.spawnSubprocess(exe, ['wait_for_attach']) 246 pid = proc.pid 247 self.addTearDownHook(self.cleanupSubprocesses) 248 249 if self.TraceOn(): 250 print "pid of spawned process: %d" % pid 251 252 self.runCmd("process attach -p %d" % pid) 253 254 # Check that "register read eax" works. 255 self.runCmd("register read eax") 256 257 if self.getArchitecture() in ['x86_64']: 258 self.expect("expr -- ($rax & 0xffffffff) == $eax", 259 substrs = ['true']) 260 261 if test_16bit_regs: 262 self.expect("expr -- $ax == (($ah << 8) | $al)", 263 substrs = ['true']) 264 265if __name__ == '__main__': 266 import atexit 267 lldb.SBDebugger.Initialize() 268 atexit.register(lambda: lldb.SBDebugger.Terminate()) 269 unittest2.main() 270