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
|
""" Check that registers written to memory for expression evaluation are
written using the target's endian not the host's.
"""
from enum import Enum
from textwrap import dedent
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
from lldbsuite.test.gdbclientutils import *
from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
class Endian(Enum):
BIG = 0
LITTLE = 1
class Responder(MockGDBServerResponder):
def __init__(self, doc, endian):
super().__init__()
self.target_xml = doc
self.endian = endian
def qXferRead(self, obj, annex, offset, length):
if annex == "target.xml":
return self.target_xml, False
return (None,)
def readRegister(self, regnum):
return "E01"
def readRegisters(self):
# 64 bit pc value.
data = ["00", "00", "00", "00", "00", "00", "12", "34"]
if self.endian == Endian.LITTLE:
data.reverse()
return "".join(data)
class TestXMLRegisterFlags(GDBRemoteTestBase):
def do_endian_test(self, endian):
architecture, pc_reg_name, yaml_file, data, machine = {
Endian.BIG: ("s390x", "pswa", "s390x.yaml", "ELFDATA2MSB", "EM_S390"),
Endian.LITTLE: (
"aarch64",
"pc",
"aarch64.yaml",
"ELFDATA2LSB",
"EM_AARCH64",
),
}[endian]
self.server.responder = Responder(
dedent(
f"""\
<?xml version="1.0"?>
<target version="1.0">
<architecture>{architecture}</architecture>
<feature>
<reg name="{pc_reg_name}" bitsize="64"/>
</feature>
</target>"""
),
endian,
)
# We need to have a program file, so that we have a full type system,
# so that we can do the casts later.
obj_path = self.getBuildArtifact("main.o")
yaml_path = self.getBuildArtifact(yaml_file)
with open(yaml_path, "w") as f:
f.write(
dedent(
f"""\
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: {data}
Type: ET_REL
Machine: {machine}
...
"""
)
)
self.yaml2obj(yaml_path, obj_path)
target = self.dbg.CreateTarget(obj_path)
process = self.connect(target)
lldbutil.expect_state_changes(
self, self.dbg.GetListener(), process, [lldb.eStateStopped]
)
# If expressions convert register values into target endian, the
# result of register read, expr and casts should be the same.
pc_value = "0x0000000000001234"
self.expect(
"register read pc",
substrs=[pc_value],
)
self.expect("expr --format hex -- $pc", substrs=[pc_value])
pc = (
process.thread[0]
.frame[0]
.GetRegisters()
.GetValueAtIndex(0)
.GetChildMemberWithName("pc")
)
ull = target.FindTypes("unsigned long long").GetTypeAtIndex(0)
pc_ull = pc.Cast(ull)
self.assertEqual(pc.GetValue(), pc_ull.GetValue())
self.assertEqual(pc.GetValueAsAddress(), pc_ull.GetValueAsAddress())
self.assertEqual(pc.GetValueAsSigned(), pc_ull.GetValueAsSigned())
self.assertEqual(pc.GetValueAsUnsigned(), pc_ull.GetValueAsUnsigned())
@skipIfXmlSupportMissing
@skipIfRemote
@skipIfLLVMTargetMissing("AArch64")
def test_little_endian_target(self):
self.do_endian_test(Endian.LITTLE)
@skipIfXmlSupportMissing
@skipIfRemote
@skipIfLLVMTargetMissing("SystemZ")
def test_big_endian_target(self):
self.do_endian_test(Endian.BIG)
|