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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
import gdbremote_testcase
import lldbgdbserverutils
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test.lldbdwarf import *
class TestGdbRemote_qMemoryRegion(gdbremote_testcase.GdbRemoteTestCaseBase):
def test_qRegisterInfo_returns_one_valid_result(self):
self.build()
self.prep_debug_monitor_and_inferior()
self.test_sequence.add_log_lines(
[
"read packet: $qRegisterInfo0#00",
{
"direction": "send",
"regex": r"^\$(.+);#[0-9A-Fa-f]{2}",
"capture": {1: "reginfo_0"},
},
],
True,
)
# Run the stream
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
reg_info_packet = context.get("reginfo_0")
self.assertIsNotNone(reg_info_packet)
self.assert_valid_reg_info(
lldbgdbserverutils.parse_reg_info_response(reg_info_packet)
)
def test_qRegisterInfo_returns_all_valid_results(self):
self.build()
self.prep_debug_monitor_and_inferior()
self.add_register_info_collection_packets()
# Run the stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Validate that each register info returned validates.
for reg_info in self.parse_register_info_packets(context):
self.assert_valid_reg_info(reg_info)
def test_qRegisterInfo_contains_required_generics_debugserver(self):
self.build()
self.prep_debug_monitor_and_inferior()
self.add_register_info_collection_packets()
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather register info entries.
reg_infos = self.parse_register_info_packets(context)
# Collect all generic registers found.
generic_regs = {
reg_info["generic"]: 1 for reg_info in reg_infos if "generic" in reg_info
}
# Ensure we have a program counter register.
self.assertIn("pc", generic_regs)
# Ensure we have a frame pointer register. PPC64le's FP is the same as SP
if self.getArchitecture() != "powerpc64le":
self.assertIn("fp", generic_regs)
# Ensure we have a stack pointer register.
self.assertIn("sp", generic_regs)
# Ensure we have a flags register. RISC-V doesn't have a flags register
if not self.isRISCV():
self.assertIn("flags", generic_regs)
if self.isRISCV() or self.isAArch64() or self.isARM():
# Specific register for a return address
self.assertIn("ra", generic_regs)
# Function arguments registers
for i in range(1, 5 if self.isARM() else 9):
self.assertIn(f"arg{i}", generic_regs)
def test_qRegisterInfo_contains_at_least_one_register_set(self):
self.build()
self.prep_debug_monitor_and_inferior()
self.add_register_info_collection_packets()
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather register info entries.
reg_infos = self.parse_register_info_packets(context)
# Collect all register sets found.
register_sets = {
reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info
}
self.assertGreaterEqual(len(register_sets), 1)
def targetHasAVX(self):
triple = self.dbg.GetSelectedPlatform().GetTriple()
# TODO other platforms, please implement this function
if not re.match(".*-.*-linux", triple):
return True
# Need to do something different for non-Linux/Android targets
if lldb.remote_platform:
self.runCmd('platform get-file "/proc/cpuinfo" "cpuinfo"')
cpuinfo_path = "cpuinfo"
self.addTearDownHook(lambda: os.unlink("cpuinfo"))
else:
cpuinfo_path = "/proc/cpuinfo"
f = open(cpuinfo_path, "r")
cpuinfo = f.read()
f.close()
return " avx " in cpuinfo
@expectedFailureAll(oslist=["windows"]) # no avx for now.
@skipIf(archs=no_match(["amd64", "i386", "x86_64"]))
@add_test_categories(["llgs"])
def test_qRegisterInfo_contains_avx_registers(self):
self.build()
self.prep_debug_monitor_and_inferior()
self.add_register_info_collection_packets()
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Gather register info entries.
reg_infos = self.parse_register_info_packets(context)
# Collect all generics found.
register_sets = {
reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info
}
self.assertEqual(
self.targetHasAVX(), "Advanced Vector Extensions" in register_sets
)
|