Skip to content

Commit 91e5eae

Browse files
Merge pull request #5249 from adrian-prantl/92248684-attach
Fix inconsistent target arch when attaching to arm64 binaries on
2 parents 8bee4fd + 99cbe91 commit 91e5eae

File tree

5 files changed

+185
-4
lines changed

5 files changed

+185
-4
lines changed

lldb/include/lldb/Target/Target.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1073,9 +1073,14 @@ class Target : public std::enable_shared_from_this<Target>,
10731073
/// currently selected platform isn't compatible (in case it might be
10741074
/// manually set following this function call).
10751075
///
1076+
/// \param[in] merged
1077+
/// If true, arch_spec is merged with the current
1078+
/// architecture. Otherwise it's replaced.
1079+
///
10761080
/// \return
10771081
/// \b true if the architecture was successfully set, \b false otherwise.
1078-
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform = false);
1082+
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform = false,
1083+
bool merge = true);
10791084

10801085
bool MergeArchitecture(const ArchSpec &arch_spec);
10811086

lldb/packages/Python/lldbsuite/test/gdbclientutils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ def respond(self, packet):
185185
return self.qsProcessInfo()
186186
if packet.startswith("qfProcessInfo"):
187187
return self.qfProcessInfo(packet)
188+
if packet.startswith("jGetLoadedDynamicLibrariesInfos"):
189+
return self.jGetLoadedDynamicLibrariesInfos(packet)
188190
if packet.startswith("qPathComplete:"):
189191
return self.qPathComplete()
190192
if packet.startswith("vFile:"):
@@ -211,6 +213,9 @@ def qsProcessInfo(self):
211213
def qfProcessInfo(self, packet):
212214
return "E04"
213215

216+
def jGetLoadedDynamicLibrariesInfos(self, packet):
217+
return ""
218+
214219
def qGetWorkingDir(self):
215220
return "2f"
216221

lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,8 +567,27 @@ void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
567567
exe_module_sp->GetFileSpec().GetPath().c_str());
568568
target.GetImages().AppendIfNeeded(exe_module_sp);
569569
UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]);
570-
if (exe_module_sp.get() != target.GetExecutableModulePointer()) {
570+
if (exe_module_sp.get() != target.GetExecutableModulePointer())
571571
target.SetExecutableModule(exe_module_sp, eLoadDependentsNo);
572+
573+
// Update the target executable's arch if necessary.
574+
auto exe_triple = exe_module_sp->GetArchitecture().GetTriple();
575+
if (target_arch.GetTriple().isArm64e() &&
576+
exe_triple.getArch() == llvm::Triple::aarch64 &&
577+
!exe_triple.isArm64e()) {
578+
// On arm64e-capable Apple platforms, the system libraries are
579+
// always arm64e, but applications often are arm64. When a
580+
// target is created from a file, LLDB recognizes it as an
581+
// arm64 target, but debugserver will still (technically
582+
// correct) report the process as being arm64e. For
583+
// consistency, set the target to arm64 here, so attaching to
584+
// a live process behaves the same as creating a process from
585+
// file.
586+
auto triple = target_arch.GetTriple();
587+
triple.setArchName(exe_triple.getArchName());
588+
target_arch.SetTriple(triple);
589+
target.SetArchitecture(target_arch, /*set_platform=*/false,
590+
/*merge=*/false);
572591
}
573592
}
574593
}

lldb/source/Target/Target.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,8 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
14961496
}
14971497
}
14981498

1499-
bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
1499+
bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform,
1500+
bool merge) {
15001501
Log *log = GetLog(LLDBLog::Target);
15011502
bool missing_local_arch = !m_arch.GetSpec().IsValid();
15021503
bool replace_local_arch = true;
@@ -1524,7 +1525,7 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
15241525
}
15251526

15261527
if (!missing_local_arch) {
1527-
if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {
1528+
if (merge && m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {
15281529
other.MergeFrom(m_arch.GetSpec());
15291530

15301531
if (m_arch.GetSpec().IsCompatibleMatch(other)) {
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
from lldbsuite.test.gdbclientutils import *
5+
from lldbsuite.test.lldbgdbclient import *
6+
7+
images = """
8+
{"images":[
9+
{"load_address":4370792448,
10+
"mod_date":0,
11+
"pathname":"/usr/lib/dyld",
12+
"uuid":"75627683-A780-32AD-AE34-CF86DD23A26B",
13+
"min_version_os_name":"macosx",
14+
"min_version_os_sdk":"12.5",
15+
"mach_header":{
16+
"magic":4277009103,
17+
"cputype":16777228,
18+
"cpusubtype":2,
19+
"filetype":7,
20+
"flags":133},
21+
"segments":[
22+
{"name":"__TEXT",
23+
"vmaddr":0,
24+
"vmsize":393216,
25+
"fileoff":0,
26+
"filesize":393216,
27+
"maxprot":5},
28+
{"name":"__DATA_CONST",
29+
"vmaddr":393216,
30+
"vmsize":98304,
31+
"fileoff":393216,
32+
"filesize":98304,
33+
"maxprot":3},
34+
{"name":"__DATA",
35+
"vmaddr":491520,
36+
"vmsize":16384,
37+
"fileoff":491520,
38+
"filesize":16384,
39+
"maxprot":3},
40+
{"name":"__LINKEDIT",
41+
"vmaddr":507904,
42+
"vmsize":229376,
43+
"fileoff":507904,
44+
"filesize":227520,
45+
"maxprot":1}
46+
]
47+
},
48+
{"load_address":4369842176,
49+
"mod_date":0,
50+
"pathname":"/tmp/a.out",
51+
"uuid":"536A0A09-792A-377C-BEBA-FFB00A787C38",
52+
"min_version_os_name":"macosx",
53+
"min_version_os_sdk":"12.0",
54+
"mach_header":{
55+
"magic":4277009103,
56+
"cputype":16777228,
57+
"cpusubtype":%s,
58+
"filetype":2,
59+
"flags":2097285
60+
},
61+
"segments":[
62+
{"name":"__PAGEZERO",
63+
"vmaddr":0,
64+
"vmsize":4294967296,
65+
"fileoff":0,
66+
"filesize":0,
67+
"maxprot":0},
68+
{"name":"__TEXT",
69+
"vmaddr":4294967296,
70+
"vmsize":16384,
71+
"fileoff":0,
72+
"filesize":16384,
73+
"maxprot":5},
74+
{"name":"__DATA_CONST",
75+
"vmaddr":4294983680,
76+
"vmsize":16384,
77+
"fileoff":16384,
78+
"filesize":16384,
79+
"maxprot":3},
80+
{"name":"__LINKEDIT",
81+
"vmaddr":4295000064,
82+
"vmsize":32768,
83+
"fileoff":32768,
84+
"filesize":19488,
85+
"maxprot":1}]
86+
}
87+
]
88+
}
89+
"""
90+
91+
arm64_binary = "cffaedfe0c000001000000000200000010000000e8020000850020000000000019000000480000005f5f504147455a45524f00000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000019000000e80000005f5f54455854000000000000000000000000000001000000004000000000000000000000000000000040000000000000050000000500000002000000000000005f5f74657874000000000000000000005f5f5445585400000000000000000000b03f0000010000000800000000000000b03f0000020000000000000000000000000400800000000000000000000000005f5f756e77696e645f696e666f0000005f5f5445585400000000000000000000b83f0000010000004800000000000000b83f00000200000000000000000000000000000000000000000000000000000019000000480000005f5f4c494e4b45444954000000000000004000000100000000400000000000000040000000000000b8010000000000000100000001000000000000000000000034000080100000000040000038000000330000801000000038400000300000000200000018000000704000000100000080400000180000000b000000500000000000000000000000000000000100000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000200000000c0000002f7573722f6c69622f64796c64000000000000001b00000018000000a9981092eb3632f4afd9957e769160d932000000200000000100000000000c0000050c000100000003000000000633032a0000001000000000000000000000002800008018000000b03f00000000000000000000000000000c00000038000000180000000200000001781f05000001002f7573722f6c69622f6c696253797374656d2e422e64796c696200000000000026000000100000006840000008000000290000001000000070400000000000001d00000010000000a04000001801"
92+
93+
class TestDynamicLoaderDarwin(GDBRemoteTestBase):
94+
95+
NO_DEBUG_INFO_TESTCASE = True
96+
class MyResponder(MockGDBServerResponder):
97+
98+
def __init__(self, cpusubtype):
99+
self.cpusubtype = cpusubtype
100+
MockGDBServerResponder.__init__(self)
101+
102+
def respond(self, packet):
103+
if packet == "qProcessInfo":
104+
return self.qProcessInfo()
105+
return MockGDBServerResponder.respond(self, packet)
106+
107+
def qHostInfo(self):
108+
return "cputype:16777223;cpusubtype:2;ostype:macosx;vendor:apple;os_version:10.15.4;maccatalyst_version:13.4;endian:little;ptrsize:8;"
109+
110+
def qProcessInfo(self):
111+
return "pid:a860;parent-pid:d2a0;real-uid:1f5;real-gid:14;effective-uid:1f5;effective-gid:14;cputype:100000c;cpusubtype:2;ptrsize:8;ostype:macosx;vendor:apple;endian:little;"
112+
113+
def jGetLoadedDynamicLibrariesInfos(self, packet):
114+
if 'fetch_all_solibs' in packet:
115+
return escape_binary(images%self.cpusubtype)
116+
return "OK"
117+
118+
def vCont(self):
119+
return "vCont;"
120+
121+
def readMemory(self, addr, length):
122+
vm_addr = 4369842176
123+
file_offset = addr - vm_addr
124+
if file_offset < 0:
125+
return None
126+
# arm64_binary is just a hex-encoded (hence the 2*) Mach-O
127+
# header, pad out the rest with NUL characters, it doesn't
128+
# matter for this test.
129+
memory = arm64_binary + '00'*(length-len(arm64_binary)<<1)
130+
return memory[2*file_offset:]
131+
132+
def setBreakpoint(self, packet):
133+
return ""
134+
135+
@skipIfRemote
136+
def test(self):
137+
"""Test that when attaching to an arm64 binary on an arm64e
138+
host, the target's arch is set to arm64, even though
139+
debugserver reports the process as being arm64e.
140+
"""
141+
subtype_arm64e = 2
142+
self.server.responder = self.MyResponder(subtype_arm64e)
143+
if self.TraceOn():
144+
self.runCmd("log enable gdb-remote packets")
145+
self.addTearDownHook(
146+
lambda: self.runCmd("log disable gdb-remote packets"))
147+
148+
target = self.dbg.CreateTargetWithFileAndArch(None, None)
149+
process = self.connect(target)
150+
151+
self.assertEqual(target.GetTriple(), "arm64-apple-macosx-")

0 commit comments

Comments
 (0)