summaryrefslogtreecommitdiff
path: root/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
blob: 102f2b0edd4c674acadf6fe417c9141af143179d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import lldb

SINGLE_INSTANCE_PATTERN_STACK = "stack_there_is_only_one_of_me"
DOUBLE_INSTANCE_PATTERN_HEAP = "heap_there_is_exactly_two_of_me"
ALIGNED_INSTANCE_PATTERN_HEAP = "i_am_unaligned_string_on_the_heap"
UNALIGNED_INSTANCE_PATTERN_HEAP = ALIGNED_INSTANCE_PATTERN_HEAP[1:]


def GetAlignedRange(test_base, shrink=False):
    frame = test_base.thread.GetSelectedFrame()
    ex = frame.EvaluateExpression("aligned_string_ptr")
    test_base.assertTrue(ex.IsValid())
    return GetRangeFromAddrValue(test_base, ex, shrink)


def GetStackRange(test_base, shrink=False):
    frame = test_base.thread.GetSelectedFrame()
    ex = frame.EvaluateExpression("&stack_pointer")
    test_base.assertTrue(ex.IsValid())
    return GetRangeFromAddrValue(test_base, ex, shrink)


def GetStackRanges(test_base, shrink=False):
    addr_ranges = lldb.SBAddressRangeList()
    addr_ranges.Append(GetStackRange(test_base))
    return addr_ranges


def GetRangeFromAddrValue(test_base, addr, shrink=False):
    """Returns a memory region containing 'addr'.
    If 'shrink' is True, the address range will be reduced to not exceed 2K.
    """
    region = lldb.SBMemoryRegionInfo()
    test_base.assertTrue(
        test_base.process.GetMemoryRegionInfo(
            addr.GetValueAsUnsigned(), region
        ).Success(),
    )

    test_base.assertTrue(region.IsReadable())
    test_base.assertFalse(region.IsExecutable())

    base = region.GetRegionBase()
    end = region.GetRegionEnd()

    if shrink:
        addr2 = addr.GetValueAsUnsigned()
        addr2 -= addr2 % 512
        base = max(base, addr2 - 1024)
        end = min(end, addr2 + 1024)

    start = lldb.SBAddress(base, test_base.target)
    size = end - base

    return lldb.SBAddressRange(start, size)


def GetHeapRanges(test_base, shrink=False):
    frame = test_base.thread.GetSelectedFrame()

    ex = frame.EvaluateExpression("heap_pointer1")
    test_base.assertTrue(ex.IsValid())
    range1 = GetRangeFromAddrValue(test_base, ex, shrink)
    range1_start = range1.GetBaseAddress().GetLoadAddress(test_base.target)
    range1_end = range1_start + range1.GetByteSize()

    ex = frame.EvaluateExpression("heap_pointer2")
    test_base.assertTrue(ex.IsValid())
    range2 = GetRangeFromAddrValue(test_base, ex, shrink)
    range2_start = range2.GetBaseAddress().GetLoadAddress(test_base.target)
    range2_end = range2_start + range2.GetByteSize()

    addr_ranges = lldb.SBAddressRangeList()

    if range1_end < range2_start or range2_end < range1_start:
        # The ranges do not overlap; add them both.
        addr_ranges.Append(range1)
        addr_ranges.Append(range2)
    else:
        # Merge overlapping ranges.
        base = min(range1_start, range2_start)
        end = max(range1_end, range2_end)
        start = lldb.SBAddress(base, test_base.target)
        size = end - base
        addr_ranges.Append(lldb.SBAddressRange(start, size))

    return addr_ranges


def GetRanges(test_base, shrink=False):
    ranges = GetHeapRanges(test_base, shrink)
    ranges.Append(GetStackRanges(test_base, shrink))

    return ranges