xref: /llvm-project/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py (revision b88d94caba518bc63c25fe476c4de3d9b0bbd2c0)
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