Skip to content

Commit 1a3436f

Browse files
Merge pull request #8280 from adrian-prantl/123338218-725
Replace ArchSpec::PiecewiseCompare() with Triple::operator==()
2 parents 8aff003 + e491dde commit 1a3436f

File tree

12 files changed

+146
-78
lines changed

12 files changed

+146
-78
lines changed

lldb/include/lldb/Utility/ArchSpec.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -505,11 +505,6 @@ class ArchSpec {
505505

506506
bool IsFullySpecifiedTriple() const;
507507

508-
void PiecewiseTripleCompare(const ArchSpec &other, bool &arch_different,
509-
bool &vendor_different, bool &os_different,
510-
bool &os_version_different,
511-
bool &env_different) const;
512-
513508
/// Detect whether this architecture uses thumb code exclusively
514509
///
515510
/// Some embedded ARM chips (e.g. the ARM Cortex M0-7 line) can only execute

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "lldb/Core/ModuleSpec.h"
1919
#include "lldb/Host/HostInfo.h"
20+
#include "lldb/Host/SafeMachO.h"
2021
#include "lldb/Host/XML.h"
2122
#include "lldb/Symbol/Symbol.h"
2223
#include "lldb/Target/MemoryRegionInfo.h"
@@ -2147,8 +2148,20 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
21472148
if (!value.getAsInteger(16, cpu))
21482149
++num_keys_decoded;
21492150
} else if (name.equals("cpusubtype")) {
2150-
if (!value.getAsInteger(16, sub))
2151+
if (!value.getAsInteger(16, sub)) {
21512152
++num_keys_decoded;
2153+
// Workaround for for pre-2024 Apple debugserver, which always
2154+
// returns arm64e on arm64e-capable hardware regardless of
2155+
// what the process is. This can be deleted at some point in
2156+
// the future.
2157+
if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&
2158+
sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {
2159+
if (GetGDBServerVersion())
2160+
if (m_gdb_server_version >= 1000 &&
2161+
m_gdb_server_version <= 1504)
2162+
sub = 0;
2163+
}
2164+
}
21522165
} else if (name.equals("triple")) {
21532166
StringExtractor extractor(value);
21542167
extractor.GetHexByteString(triple);

lldb/source/Target/Target.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,14 +1641,8 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform,
16411641

16421642
if (m_arch.GetSpec().IsCompatibleMatch(other)) {
16431643
compatible_local_arch = true;
1644-
bool arch_changed, vendor_changed, os_changed, os_ver_changed,
1645-
env_changed;
16461644

1647-
m_arch.GetSpec().PiecewiseTripleCompare(other, arch_changed,
1648-
vendor_changed, os_changed,
1649-
os_ver_changed, env_changed);
1650-
1651-
if (!arch_changed && !vendor_changed && !os_changed && !env_changed)
1645+
if (m_arch.GetSpec().GetTriple() == other.GetTriple())
16521646
replace_local_arch = false;
16531647
}
16541648
}

lldb/source/Utility/ArchSpec.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,23 +1421,6 @@ bool ArchSpec::IsFullySpecifiedTriple() const {
14211421
return true;
14221422
}
14231423

1424-
void ArchSpec::PiecewiseTripleCompare(
1425-
const ArchSpec &other, bool &arch_different, bool &vendor_different,
1426-
bool &os_different, bool &os_version_different, bool &env_different) const {
1427-
const llvm::Triple &me(GetTriple());
1428-
const llvm::Triple &them(other.GetTriple());
1429-
1430-
arch_different = (me.getArch() != them.getArch());
1431-
1432-
vendor_different = (me.getVendor() != them.getVendor());
1433-
1434-
os_different = (me.getOS() != them.getOS());
1435-
1436-
os_version_different = (me.getOSMajorVersion() != them.getOSMajorVersion());
1437-
1438-
env_different = (me.getEnvironment() != them.getEnvironment());
1439-
}
1440-
14411424
bool ArchSpec::IsAlwaysThumbInstructions() const {
14421425
std::string Status;
14431426
if (GetTriple().getArch() == llvm::Triple::arm ||
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
C_SOURCES := main.c
2+
3+
# Uncomment this for local debugging.
4+
#all:
5+
# xcrun clang -g $(SRCDIR)/main.c -o a.out -target arm64e-apple-macosx
6+
7+
include Makefile.rules
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
7+
class TestArm64eAttach(TestBase):
8+
NO_DEBUG_INFO_TESTCASE = True
9+
10+
# On Darwin systems, arch arm64e means ARMv8.3 with ptrauth ABI used.
11+
@skipIf(archs=no_match(["arm64e"]))
12+
def test(self):
13+
# Skip this test if not running on AArch64 target that supports PAC
14+
if not self.isAArch64PAuth():
15+
self.skipTest("Target must support pointer authentication.")
16+
17+
self.build()
18+
popen = self.spawnSubprocess(self.getBuildArtifact(), [])
19+
20+
# This simulates how Xcode attaches to a process by pid/name.
21+
error = lldb.SBError()
22+
target = self.dbg.CreateTarget("", "arm64", "", True, error)
23+
listener = lldb.SBListener("my.attach.listener")
24+
process = target.AttachToProcessWithID(listener, popen.pid, error)
25+
self.assertSuccess(error)
26+
self.assertTrue(process, PROCESS_IS_VALID)
27+
self.assertEqual(target.GetTriple().split('-')[0], "arm64e",
28+
"target triple is updated correctly")
29+
30+
self.expect('process plugin packet send qProcessInfo',
31+
"debugserver returns correct triple",
32+
substrs=['cputype:100000c', 'cpusubtype:2', 'ptrsize:8'])
33+
34+
error = process.Kill()
35+
self.assertSuccess(error)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
int getchar();
2+
int main() { return getchar(); }

lldb/tools/debugserver/source/DNB.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,14 @@ DNBGetTSDAddressForThread(nub_process_t pid, nub_thread_t tid,
10251025
return INVALID_NUB_ADDRESS;
10261026
}
10271027

1028+
std::optional<std::pair<cpu_type_t, cpu_subtype_t>>
1029+
DNBGetMainBinaryCPUTypes(nub_process_t pid) {
1030+
MachProcessSP procSP;
1031+
if (GetProcessSP(pid, procSP))
1032+
return procSP->GetMainBinaryCPUTypes(pid);
1033+
return {};
1034+
}
1035+
10281036
JSONGenerator::ObjectSP
10291037
DNBGetAllLoadedLibrariesInfos(nub_process_t pid, bool report_load_commands) {
10301038
MachProcessSP procSP;

lldb/tools/debugserver/source/DNB.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ DNBGetTSDAddressForThread(nub_process_t pid, nub_thread_t tid,
210210
uint64_t plo_pthread_tsd_base_address_offset,
211211
uint64_t plo_pthread_tsd_base_offset,
212212
uint64_t plo_pthread_tsd_entry_size);
213+
std::optional<std::pair<cpu_type_t, cpu_subtype_t>>
214+
DNBGetMainBinaryCPUTypes(nub_process_t pid);
213215
JSONGenerator::ObjectSP
214216
DNBGetAllLoadedLibrariesInfos(nub_process_t pid, bool report_load_commands);
215217
JSONGenerator::ObjectSP

lldb/tools/debugserver/source/MacOSX/MachProcess.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ class MachProcess {
103103
const char *stdin_path, const char *stdout_path, const char *stderr_path,
104104
bool no_stdio, MachProcess *process, int disable_aslr, DNBError &err);
105105
nub_addr_t GetDYLDAllImageInfosAddress();
106+
std::optional<std::pair<cpu_type_t, cpu_subtype_t>>
107+
GetMainBinaryCPUTypes(nub_process_t pid);
106108
static const void *PrepareForAttach(const char *path,
107109
nub_launch_flavor_t launch_flavor,
108110
bool waitfor, DNBError &err_str);

lldb/tools/debugserver/source/MacOSX/MachProcess.mm

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,23 @@ static bool mach_header_validity_test(uint32_t magic, uint32_t cputype) {
11111111
return FormatDynamicLibrariesIntoJSON(image_infos, report_load_commands);
11121112
}
11131113

1114+
std::optional<std::pair<cpu_type_t, cpu_subtype_t>>
1115+
MachProcess::GetMainBinaryCPUTypes(nub_process_t pid) {
1116+
int pointer_size = GetInferiorAddrSize(pid);
1117+
std::vector<struct binary_image_information> image_infos;
1118+
GetAllLoadedBinariesViaDYLDSPI(image_infos);
1119+
uint32_t platform = GetPlatform();
1120+
for (auto &image_info : image_infos)
1121+
if (GetMachOInformationFromMemory(platform, image_info.load_address,
1122+
pointer_size, image_info.macho_info))
1123+
if (image_info.macho_info.mach_header.filetype == MH_EXECUTE)
1124+
return {
1125+
{static_cast<cpu_type_t>(image_info.macho_info.mach_header.cputype),
1126+
static_cast<cpu_subtype_t>(
1127+
image_info.macho_info.mach_header.cpusubtype)}};
1128+
return {};
1129+
}
1130+
11141131
// Fetch information about the shared libraries at the given load addresses
11151132
// using the
11161133
// dyld SPIs that exist in macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer.

lldb/tools/debugserver/source/RNBRemote.cpp

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6216,59 +6216,14 @@ rnb_err_t RNBRemote::HandlePacket_qSymbol(const char *command) {
62166216
}
62176217
}
62186218

6219-
// Note that all numeric values returned by qProcessInfo are hex encoded,
6220-
// including the pid and the cpu type.
6221-
6222-
rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) {
6223-
nub_process_t pid;
6224-
std::ostringstream rep;
6225-
6226-
// If we haven't run the process yet, return an error.
6227-
if (!m_ctx.HasValidProcessID())
6228-
return SendPacket("E68");
6229-
6230-
pid = m_ctx.ProcessID();
6231-
6232-
rep << "pid:" << std::hex << pid << ';';
6233-
6234-
int procpid_mib[4];
6235-
procpid_mib[0] = CTL_KERN;
6236-
procpid_mib[1] = KERN_PROC;
6237-
procpid_mib[2] = KERN_PROC_PID;
6238-
procpid_mib[3] = pid;
6239-
struct kinfo_proc proc_kinfo;
6240-
size_t proc_kinfo_size = sizeof(struct kinfo_proc);
6241-
6242-
if (::sysctl(procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) {
6243-
if (proc_kinfo_size > 0) {
6244-
rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';';
6245-
rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid
6246-
<< ';';
6247-
rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid
6248-
<< ';';
6249-
rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid
6250-
<< ';';
6251-
if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
6252-
rep << "effective-gid:" << std::hex
6253-
<< proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';';
6254-
}
6255-
}
6256-
6219+
static std::pair<cpu_type_t, cpu_subtype_t>
6220+
GetCPUTypesFromHost(nub_process_t pid) {
62576221
cpu_type_t cputype = DNBProcessGetCPUType(pid);
62586222
if (cputype == 0) {
62596223
DNBLog("Unable to get the process cpu_type, making a best guess.");
62606224
cputype = best_guess_cpu_type();
62616225
}
62626226

6263-
uint32_t addr_size = 0;
6264-
if (cputype != 0) {
6265-
rep << "cputype:" << std::hex << cputype << ";";
6266-
if (cputype & CPU_ARCH_ABI64)
6267-
addr_size = 8;
6268-
else
6269-
addr_size = 4;
6270-
}
6271-
62726227
bool host_cpu_is_64bit = false;
62736228
uint32_t is64bit_capable;
62746229
size_t is64bit_capable_len = sizeof(is64bit_capable);
@@ -6309,14 +6264,69 @@ rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) {
63096264
if (cputype == CPU_TYPE_ARM64_32 && cpusubtype == 2)
63106265
cpusubtype = CPU_SUBTYPE_ARM64_32_V8;
63116266
#endif
6267+
}
6268+
6269+
return {cputype, cpusubtype};
6270+
}
6271+
6272+
// Note that all numeric values returned by qProcessInfo are hex encoded,
6273+
// including the pid and the cpu type.
63126274

6275+
rnb_err_t RNBRemote::HandlePacket_qProcessInfo(const char *p) {
6276+
nub_process_t pid;
6277+
std::ostringstream rep;
6278+
6279+
// If we haven't run the process yet, return an error.
6280+
if (!m_ctx.HasValidProcessID())
6281+
return SendPacket("E68");
6282+
6283+
pid = m_ctx.ProcessID();
6284+
6285+
rep << "pid:" << std::hex << pid << ';';
6286+
6287+
int procpid_mib[4];
6288+
procpid_mib[0] = CTL_KERN;
6289+
procpid_mib[1] = KERN_PROC;
6290+
procpid_mib[2] = KERN_PROC_PID;
6291+
procpid_mib[3] = pid;
6292+
struct kinfo_proc proc_kinfo;
6293+
size_t proc_kinfo_size = sizeof(struct kinfo_proc);
6294+
6295+
if (::sysctl(procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) {
6296+
if (proc_kinfo_size > 0) {
6297+
rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ';';
6298+
rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid
6299+
<< ';';
6300+
rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid
6301+
<< ';';
6302+
rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid
6303+
<< ';';
6304+
if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
6305+
rep << "effective-gid:" << std::hex
6306+
<< proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ';';
6307+
}
6308+
}
6309+
6310+
cpu_type_t cputype;
6311+
cpu_subtype_t cpusubtype;
6312+
if (auto cputypes = DNBGetMainBinaryCPUTypes(pid))
6313+
std::tie(cputype, cpusubtype) = *cputypes;
6314+
else
6315+
std::tie(cputype, cpusubtype) = GetCPUTypesFromHost(pid);
6316+
6317+
uint32_t addr_size = 0;
6318+
if (cputype != 0) {
6319+
rep << "cputype:" << std::hex << cputype << ";";
63136320
rep << "cpusubtype:" << std::hex << cpusubtype << ';';
6321+
if (cputype & CPU_ARCH_ABI64)
6322+
addr_size = 8;
6323+
else
6324+
addr_size = 4;
63146325
}
63156326

63166327
bool os_handled = false;
63176328
if (addr_size > 0) {
63186329
rep << "ptrsize:" << std::dec << addr_size << ';';
6319-
63206330
#if defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1
63216331
// Try and get the OS type by looking at the load commands in the main
63226332
// executable and looking for a LC_VERSION_MIN load command. This is the

0 commit comments

Comments
 (0)