1""" 2Test SBAddressRange APIs. 3""" 4 5import lldb 6from lldbsuite.test.lldbtest import * 7 8 9class AddressRangeTestCase(TestBase): 10 NO_DEBUG_INFO_TESTCASE = True 11 12 def setUp(self): 13 TestBase.setUp(self) 14 15 self.build() 16 exe = self.getBuildArtifact("a.out") 17 18 self.target = self.dbg.CreateTarget(exe) 19 self.assertTrue(self.target, VALID_TARGET) 20 self.launch_info = self.target.GetLaunchInfo() 21 self.launch_info.SetWorkingDirectory(self.get_process_working_directory()) 22 23 self.bp1 = self.target.BreakpointCreateByName("main", "a.out") 24 self.bp2 = self.target.BreakpointCreateByName("foo", "a.out") 25 self.bp3 = self.target.BreakpointCreateByName("bar", "a.out") 26 27 self.assertTrue(self.bp1.IsValid()) 28 self.assertTrue(self.bp2.IsValid()) 29 self.assertTrue(self.bp3.IsValid()) 30 31 self.addr1 = self.bp1.GetLocationAtIndex(0).GetAddress() 32 self.addr2 = self.bp2.GetLocationAtIndex(0).GetAddress() 33 self.addr3 = self.bp3.GetLocationAtIndex(0).GetAddress() 34 35 self.assertTrue(self.addr1.IsValid()) 36 self.assertTrue(self.addr2.IsValid()) 37 self.assertTrue(self.addr3.IsValid()) 38 39 def test_address_range_default(self): 40 """Testing default constructor.""" 41 empty_range = lldb.SBAddressRange() 42 self.assertEqual(empty_range.IsValid(), False) 43 44 def test_address_range_construction(self): 45 """Make sure the construction and getters work.""" 46 range = lldb.SBAddressRange(self.addr1, 8) 47 self.assertEqual(range.IsValid(), True) 48 self.assertEqual(range.GetBaseAddress(), self.addr1) 49 self.assertEqual(range.GetByteSize(), 8) 50 51 def test_address_range_clear(self): 52 """Make sure the clear method works.""" 53 range = lldb.SBAddressRange(self.addr1, 8) 54 self.assertEqual(range.IsValid(), True) 55 self.assertEqual(range.GetBaseAddress(), self.addr1) 56 self.assertEqual(range.GetByteSize(), 8) 57 58 range.Clear() 59 self.assertEqual(range.IsValid(), False) 60 61 def test_function(self): 62 """Make sure the range works in SBFunction APIs.""" 63 64 # Setup breakpoints in main 65 loc = self.bp1.GetLocationAtIndex(0) 66 loc_addr = loc.GetAddress() 67 func = loc_addr.GetFunction() 68 ranges = func.GetRanges() 69 self.assertEqual(ranges.GetSize(), 1) 70 71 range = ranges.GetAddressRangeAtIndex(0) 72 self.assertEqual( 73 range.GetByteSize(), 74 func.GetEndAddress().GetOffset() - func.GetStartAddress().GetOffset(), 75 ) 76 self.assertEqual( 77 range.GetBaseAddress().GetOffset(), 78 func.GetStartAddress().GetOffset(), 79 ) 80 81 def test_block(self): 82 """Make sure the range works in SBBlock APIs.""" 83 loc = self.bp1.GetLocationAtIndex(0) 84 loc_addr = loc.GetAddress() 85 block = loc_addr.GetBlock() 86 87 ranges = block.GetRanges() 88 self.assertEqual(ranges.GetSize(), 1) 89 90 range = ranges.GetAddressRangeAtIndex(0) 91 self.assertEqual( 92 range.GetByteSize(), 93 block.GetRangeEndAddress(0).GetOffset() 94 - block.GetRangeStartAddress(0).GetOffset(), 95 ) 96 self.assertEqual( 97 range.GetBaseAddress().GetOffset(), 98 block.GetRangeStartAddress(0).GetOffset(), 99 ) 100 101 def test_address_range_list(self): 102 """Make sure the SBAddressRangeList works by adding and getting ranges.""" 103 range1 = lldb.SBAddressRange(self.addr1, 8) 104 range2 = lldb.SBAddressRange(self.addr2, 16) 105 range3 = lldb.SBAddressRange(self.addr3, 32) 106 107 range_list = lldb.SBAddressRangeList() 108 self.assertEqual(range_list.GetSize(), 0) 109 110 range_list.Append(range1) 111 range_list.Append(range2) 112 range_list.Append(range3) 113 self.assertEqual(range_list.GetSize(), 3) 114 self.assertRaises(IndexError, lambda: range_list[3]) 115 116 range1_copy = range_list.GetAddressRangeAtIndex(0) 117 self.assertEqual(range1.GetByteSize(), range1_copy.GetByteSize()) 118 self.assertEqual( 119 range1.GetBaseAddress().GetOffset(), 120 range1_copy.GetBaseAddress().GetOffset(), 121 ) 122 123 range2_copy = range_list.GetAddressRangeAtIndex(1) 124 self.assertEqual(range2.GetByteSize(), range2_copy.GetByteSize()) 125 self.assertEqual( 126 range2.GetBaseAddress().GetOffset(), 127 range2_copy.GetBaseAddress().GetOffset(), 128 ) 129 130 range3_copy = range_list.GetAddressRangeAtIndex(2) 131 self.assertEqual(range3.GetByteSize(), range3_copy.GetByteSize()) 132 self.assertEqual( 133 range3.GetBaseAddress().GetOffset(), 134 range3_copy.GetBaseAddress().GetOffset(), 135 ) 136 137 range_list.Clear() 138 self.assertEqual(range_list.GetSize(), 0) 139 140 def test_address_range_list_len(self): 141 """Make sure the len() operator works.""" 142 range = lldb.SBAddressRange(self.addr1, 8) 143 144 range_list = lldb.SBAddressRangeList() 145 self.assertEqual(len(range_list), 0) 146 147 range_list.Append(range) 148 self.assertEqual(len(range_list), 1) 149 150 def test_address_range_list_iterator(self): 151 """Make sure the SBAddressRangeList iterator works.""" 152 range1 = lldb.SBAddressRange(self.addr1, 8) 153 range2 = lldb.SBAddressRange(self.addr2, 16) 154 range3 = lldb.SBAddressRange(self.addr3, 32) 155 156 range_list = lldb.SBAddressRangeList() 157 range_list.Append(range1) 158 range_list.Append(range2) 159 range_list.Append(range3) 160 self.assertEqual(range_list.GetSize(), 3) 161 162 # Test the iterator 163 for range in range_list: 164 self.assertTrue(range.IsValid()) 165 166 def test_address_range_print_invalid(self): 167 """Make sure the SBAddressRange can be printed when invalid.""" 168 range = lldb.SBAddressRange() 169 self.assertEqual(str(range), "[0xffffffffffffffff-0xffffffffffffffff)") 170 171 def test_address_range_print_resolved(self): 172 """Make sure the SBAddressRange can be printed when resolved.""" 173 lldb.target = self.target 174 error = lldb.SBError() 175 process = self.target.Launch(self.launch_info, error) 176 self.assertTrue(error.Success(), "Make sure process launched successfully") 177 self.assertTrue(process, PROCESS_IS_VALID) 178 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 179 script = ( 180 "script " 181 + "bp = lldb.target.GetBreakpointAtIndex(0);" 182 + "loc = bp.GetLocationAtIndex(0);" 183 + "loc_addr = loc.GetAddress();" 184 + "func = loc_addr.GetFunction();" 185 + "range = func.GetRanges().GetAddressRangeAtIndex(0);" 186 + "print(range)" 187 ) 188 189 interp = self.dbg.GetCommandInterpreter() 190 result = lldb.SBCommandReturnObject() 191 interp.HandleCommand(script, result, False) 192 self.assertTrue(result.Succeeded(), "script command succeeded") 193 # [0x1000-0x2000] // Resolved with target or addresses without sections 194 self.assertRegex(result.GetOutput(), "^\[0x[0-9a-f]+\-0x[0-9a-f]+\)") 195 process.Kill() 196 197 def test_address_range_print_no_section_resolved(self): 198 """Make sure the SBAddressRange can be printed with no secion.""" 199 lldb.target = self.target 200 error = lldb.SBError() 201 process = self.target.Launch(self.launch_info, error) 202 self.assertTrue(error.Success(), "Make sure process launched successfully") 203 self.assertTrue(process, PROCESS_IS_VALID) 204 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 205 206 loc = self.bp1.GetLocationAtIndex(0) 207 loc_addr = loc.GetAddress() 208 func = loc_addr.GetFunction() 209 range = func.GetRanges().GetAddressRangeAtIndex(0) 210 211 addr = lldb.SBAddress() 212 addr.SetAddress(lldb.SBSection(), range.GetBaseAddress().GetOffset()) 213 self.assertFalse(addr.GetSection().IsValid()) 214 range = lldb.SBAddressRange(addr, range.GetByteSize()) 215 216 range_str = str(range) 217 # [0x1000-0x2000] // Resolved with target or addresses without sections 218 self.assertRegex(range_str, "^\[0x[0-9a-f]+\-0x[0-9a-f]+\)$") 219 process.Kill() 220 221 def test_address_range_print_not_resolved(self): 222 """Make sure the SBAddressRange can be printed when not resolved.""" 223 range = lldb.SBAddressRange(self.addr1, 8) 224 range_str = str(range) 225 # a.out[0x1000-0x2000] // Without target 226 self.assertRegex(range_str, "^a.out\[0x[0-9a-f]+\-0x[0-9a-f]+\)$") 227 228 def test_address_range_list_print(self): 229 """Make sure the SBAddressRangeList can be printed.""" 230 range1 = lldb.SBAddressRange(self.addr1, 8) 231 range2 = lldb.SBAddressRange(self.addr2, 16) 232 range3 = lldb.SBAddressRange(self.addr3, 32) 233 self.dbg.SetAsync(True) 234 235 range_list = lldb.SBAddressRangeList() 236 self.assertEqual(range_list.GetSize(), 0) 237 238 range_list.Append(range1) 239 range_list.Append(range2) 240 range_list.Append(range3) 241 self.assertEqual(range_list.GetSize(), 3) 242 243 range_list_str = str(range_list) 244 self.assertTrue(range_list_str.startswith("[")) 245 self.assertGreater(range_list_str.count(","), 1) 246 self.assertTrue(range_list_str.endswith("]")) 247 248 def test_address_range_list_indexing(self): 249 """Make sure the SBAddressRangeList can be printed.""" 250 range1 = lldb.SBAddressRange(self.addr1, 8) 251 range2 = lldb.SBAddressRange(self.addr2, 16) 252 range_list = lldb.SBAddressRangeList() 253 range_list.Append(range1) 254 range_list.Append(range2) 255 256 self.assertEqual(range_list.GetSize(), 2) 257 self.assertRaises(IndexError, lambda: range_list[2]) 258 self.assertRaises(TypeError, lambda: range_list["0"]) 259 self.assertEqual(range_list[0], range1) 260 self.assertEqual(range_list[1], range2) 261 self.assertEqual(range_list[-1], range2) 262 self.assertEqual(range_list[-2], range1) 263