1import lldb 2 3SINGLE_INSTANCE_PATTERN_STACK = "stack_there_is_only_one_of_me" 4DOUBLE_INSTANCE_PATTERN_HEAP = "heap_there_is_exactly_two_of_me" 5ALIGNED_INSTANCE_PATTERN_HEAP = "i_am_unaligned_string_on_the_heap" 6UNALIGNED_INSTANCE_PATTERN_HEAP = ALIGNED_INSTANCE_PATTERN_HEAP[1:] 7 8 9def GetAlignedRange(test_base, shrink=False): 10 frame = test_base.thread.GetSelectedFrame() 11 ex = frame.EvaluateExpression("aligned_string_ptr") 12 test_base.assertTrue(ex.IsValid()) 13 return GetRangeFromAddrValue(test_base, ex, shrink) 14 15 16def GetStackRange(test_base, shrink=False): 17 frame = test_base.thread.GetSelectedFrame() 18 ex = frame.EvaluateExpression("&stack_pointer") 19 test_base.assertTrue(ex.IsValid()) 20 return GetRangeFromAddrValue(test_base, ex, shrink) 21 22 23def GetStackRanges(test_base, shrink=False): 24 addr_ranges = lldb.SBAddressRangeList() 25 addr_ranges.Append(GetStackRange(test_base)) 26 return addr_ranges 27 28 29def GetRangeFromAddrValue(test_base, addr, shrink=False): 30 """Returns a memory region containing 'addr'. 31 If 'shrink' is True, the address range will be reduced to not exceed 2K. 32 """ 33 region = lldb.SBMemoryRegionInfo() 34 test_base.assertTrue( 35 test_base.process.GetMemoryRegionInfo( 36 addr.GetValueAsUnsigned(), region 37 ).Success(), 38 ) 39 40 test_base.assertTrue(region.IsReadable()) 41 test_base.assertFalse(region.IsExecutable()) 42 43 base = region.GetRegionBase() 44 end = region.GetRegionEnd() 45 46 if shrink: 47 addr2 = addr.GetValueAsUnsigned() 48 addr2 -= addr2 % 512 49 base = max(base, addr2 - 1024) 50 end = min(end, addr2 + 1024) 51 52 start = lldb.SBAddress(base, test_base.target) 53 size = end - base 54 55 return lldb.SBAddressRange(start, size) 56 57 58def IsWithinRange(addr, size, range, target): 59 start_addr = range.GetBaseAddress().GetLoadAddress(target) 60 end_addr = start_addr + range.GetByteSize() 61 addr = addr.GetValueAsUnsigned() 62 return addr >= start_addr and addr + size <= end_addr 63 64 65def GetHeapRanges(test_base, shrink=False): 66 frame = test_base.thread.GetSelectedFrame() 67 68 ex = frame.EvaluateExpression("heap_pointer1") 69 test_base.assertTrue(ex.IsValid()) 70 range = GetRangeFromAddrValue(test_base, ex, shrink) 71 addr_ranges = lldb.SBAddressRangeList() 72 addr_ranges.Append(range) 73 74 ex = frame.EvaluateExpression("heap_pointer2") 75 test_base.assertTrue(ex.IsValid()) 76 size = len(DOUBLE_INSTANCE_PATTERN_HEAP) 77 if not IsWithinRange(ex, size, addr_ranges[0], test_base.target): 78 addr_ranges.Append(GetRangeFromAddrValue(test_base, ex, shrink)) 79 80 return addr_ranges 81 82 83def GetRanges(test_base, shrink=False): 84 ranges = GetHeapRanges(test_base, shrink) 85 ranges.Append(GetStackRanges(test_base, shrink)) 86 87 return ranges 88