151 lines · python
1"""Test that lldb will read additional registers from Mach-O LC_NOTE metadata."""2 3import os4import re5import subprocess6 7import lldb8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10from lldbsuite.test import lldbutil11 12 13class TestMetadataRegisters(TestBase):14 NO_DEBUG_INFO_TESTCASE = True15 16 @skipUnlessDarwin17 @skipIfRemote18 def test_add_registers_via_metadata(self):19 self.build()20 self.aout_exe = self.getBuildArtifact("a.out")21 lldb_corefile = self.getBuildArtifact("lldb.core")22 metadata_corefile = self.getBuildArtifact("metadata.core")23 bad_metadata1_corefile = self.getBuildArtifact("bad-metadata1.core")24 bad_metadata2_corefile = self.getBuildArtifact("bad-metadata2.core")25 add_lcnote = self.getBuildArtifact("add-lcnote")26 27 (target, process, t, bp) = lldbutil.run_to_source_breakpoint(28 self, "break here", lldb.SBFileSpec("main.c")29 )30 31 self.assertTrue(process.IsValid())32 33 if self.TraceOn():34 self.runCmd("bt")35 self.runCmd("reg read -a")36 37 self.runCmd("process save-core " + lldb_corefile)38 process.Kill()39 target.Clear()40 41 cmd = (42 add_lcnote43 + " -r"44 + " -i '%s'" % lldb_corefile45 + " -o '%s'" % metadata_corefile46 + " -n 'process metadata' "47 + " -s '"48 + """{"threads":[{"register_info":49 {"sets":["Special Registers", "General Purpose Registers"],50 "registers":[51 {"name":"jar", "value":10, "bitsize": 32, "set": 0},52 {"name":"bar", "value":65537, "bitsize":16, "set":0},53 {"name":"mar", "value":65537, "bitsize":32, "set":0},54 {"name":"anotherpc", "value":55, "bitsize":64, "set": 1}]}}]}"""55 + "'"56 )57 call(cmd, shell=True)58 59 cmd = (60 add_lcnote61 + " -r"62 + " -i '%s'" % lldb_corefile63 + " -o '%s'" % bad_metadata1_corefile64 + " -n 'process metadata' "65 + " -s '"66 + """{lol im bad json}"""67 + "'"68 )69 call(cmd, shell=True)70 71 cmd = (72 add_lcnote73 + " -r"74 + " -i '%s'" % lldb_corefile75 + " -o '%s'" % bad_metadata2_corefile76 + " -n 'process metadata' "77 + " -s '"78 + """{"threads":[79 {"register_info":80 {"sets":["a"],"registers":[{"name":"a", "value":1, "bitsize": 32, "set": 0}]}},81 {"register_info":82 {"sets":["a"],"registers":[{"name":"a", "value":1, "bitsize": 32, "set": 0}]}}83 ]}"""84 + "'"85 )86 call(cmd, shell=True)87 88 # Now load the corefile89 target = self.dbg.CreateTarget("")90 process = target.LoadCore(metadata_corefile)91 self.assertTrue(process.IsValid())92 if self.TraceOn():93 self.runCmd("bt")94 self.runCmd("reg read -a")95 96 thread = process.GetSelectedThread()97 frame = thread.GetFrameAtIndex(0)98 99 # Register sets will be100 # from LC_THREAD:101 # General Purpose Registers102 # Floating Point Registers103 # Exception State Registers104 # from LC_NOTE metadata:105 # Special Registers106 self.assertEqual(frame.registers[0].GetName(), "General Purpose Registers")107 self.assertEqual(frame.registers[3].GetName(), "Special Registers")108 109 anotherpc = frame.registers[0].GetChildMemberWithName("anotherpc")110 self.assertTrue(anotherpc.IsValid())111 self.assertEqual(anotherpc.GetValueAsUnsigned(), 0x37)112 113 jar = frame.registers[3].GetChildMemberWithName("jar")114 self.assertTrue(jar.IsValid())115 self.assertEqual(jar.GetValueAsUnsigned(), 10)116 self.assertEqual(jar.GetByteSize(), 4)117 118 bar = frame.registers[3].GetChildMemberWithName("bar")119 self.assertTrue(bar.IsValid())120 self.assertEqual(bar.GetByteSize(), 2)121 122 mar = frame.registers[3].GetChildMemberWithName("mar")123 self.assertTrue(mar.IsValid())124 self.assertEqual(mar.GetValueAsUnsigned(), 0x10001)125 self.assertEqual(mar.GetByteSize(), 4)126 127 # bad1 has invalid JSON, no additional registers128 target = self.dbg.CreateTarget("")129 process = target.LoadCore(bad_metadata1_corefile)130 self.assertTrue(process.IsValid())131 thread = process.GetSelectedThread()132 frame = thread.GetFrameAtIndex(0)133 gpr_found = False134 for regset in frame.registers:135 if regset.GetName() == "General Purpose Registers":136 gpr_found = True137 self.assertTrue(gpr_found)138 139 # bad2 has invalid JSON, more process metadata threads than140 # LC_THREADs, and should be rejected.141 target = self.dbg.CreateTarget("")142 process = target.LoadCore(bad_metadata2_corefile)143 self.assertTrue(process.IsValid())144 thread = process.GetSelectedThread()145 frame = thread.GetFrameAtIndex(0)146 metadata_regset_found = False147 for regset in frame.registers:148 if regset.GetName() == "a" or regset.GetName() == "b":149 metadata_regset_found = True150 self.assertFalse(metadata_regset_found)151