Skip to content

Commit 2461061

Browse files
committed
Upstream macCatalyst support in debugserver and the macOS dynamic loader
plugin. Unfortunately the test is currently XFAILed because of missing changes to the clang driver. Differential Revision: https://reviews.llvm.org/D67124 llvm-svn: 370931
1 parent 40fe351 commit 2461061

File tree

21 files changed

+259
-48
lines changed

21 files changed

+259
-48
lines changed

lldb/include/lldb/Core/Module.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,9 @@ class Module : public std::enable_shared_from_this<Module>,
895895
bool RemapSourceFile(llvm::StringRef path, std::string &new_path) const;
896896
bool RemapSourceFile(const char *, std::string &) const = delete;
897897

898+
/// Update the ArchSpec to a more specific variant.
899+
bool MergeArchitecture(const ArchSpec &arch_spec);
900+
898901
/// \class LookupInfo Module.h "lldb/Core/Module.h"
899902
/// A class that encapsulates name lookup information.
900903
///

lldb/include/lldb/Host/macosx/HostInfoMacOSX.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class HostInfoMacOSX : public HostInfoPosix {
2727

2828
public:
2929
static llvm::VersionTuple GetOSVersion();
30+
static llvm::VersionTuple GetMacCatalystVersion();
3031
static bool GetOSBuildString(std::string &s);
3132
static bool GetOSKernelDescription(std::string &s);
3233
static FileSpec GetProgramFileSpec();

lldb/include/lldb/Target/Process.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,9 @@ class Process : public std::enable_shared_from_this<Process>,
11961196
/// VersionTuple is returner.
11971197
virtual llvm::VersionTuple GetHostOSVersion() { return llvm::VersionTuple(); }
11981198

1199+
/// \return the macCatalyst version of the host OS.
1200+
virtual llvm::VersionTuple GetHostMacCatalystVersion() { return {}; }
1201+
11991202
/// Get the target object pointer for this module.
12001203
///
12011204
/// \return
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
LEVEL = ../../make
2+
3+
C_SOURCES := main.c
4+
LD_EXTRAS := -L. -lfoo
5+
6+
TRIPLE := x86_64-apple-ios13.0-macabi
7+
CFLAGS_EXTRAS := -target $(TRIPLE)
8+
9+
all: libfoo.dylib a.out
10+
11+
lib%.dylib: %.c
12+
$(MAKE) MAKE_DSYM=YES CC=$(CC) \
13+
ARCH=$(ARCH) DSYMUTIL=$(DSYMUTIL) \
14+
BASENAME=$(shell basename $< .c) \
15+
TRIPLE=x86_64-apple-macosx10.15 SDKROOT=$(SDKROOT) \
16+
VPATH=$(SRCDIR) -I $(SRCDIR) -f $(SRCDIR)/dylib.mk all
17+
18+
include $(LEVEL)/Makefile.rules
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# TestMacABImacOSFramework.py
2+
import lldb
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test.decorators import *
5+
import lldbsuite.test.lldbutil as lldbutil
6+
import os
7+
import unittest2
8+
9+
10+
class TestMacABImacOSFramework(TestBase):
11+
12+
mydir = TestBase.compute_mydir(__file__)
13+
14+
@skipIf(macos_version=["<", "10.15"])
15+
@skipUnlessDarwin
16+
@skipIfDarwinEmbedded
17+
# There is a Clang driver change missing on llvm.org.
18+
@expectedFailureAll(bugnumber="rdar://problem/54986190>")
19+
def test_macabi(self):
20+
"""Test the x86_64-apple-ios-macabi target linked against a macos dylib"""
21+
self.build()
22+
lldbutil.run_to_source_breakpoint(self, "break here",
23+
lldb.SBFileSpec('main.c'))
24+
self.expect("image list -t -b",
25+
patterns=["x86_64.*-apple-ios.*-macabi a\.out",
26+
"x86_64.*-apple-macosx.* libfoo.dylib[^(]"])
27+
self.expect("fr v s", "Hello MacABI")
28+
self.expect("p s", "Hello MacABI")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
LEVEL = ../../make
2+
DYLIB_ONLY := YES
3+
DYLIB_NAME := $(BASENAME)
4+
DYLIB_C_SOURCES := $(DYLIB_NAME).c
5+
6+
include $(LEVEL)/Makefile.rules
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "foo.h"
2+
3+
void stop() {}
4+
5+
int foo() {
6+
stop();
7+
return 0;
8+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int foo();
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include "foo.h"
2+
int main() {
3+
const char *s = "Hello MacABI!";
4+
return foo(); // break here
5+
}

lldb/packages/Python/lldbsuite/test/make/Makefile.rules

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ ifneq "$(TRIPLE)" ""
8888
triple_os_and_version =$(shell echo $(word 3, $(triple_space)) | sed 's/\([a-z]*\)\(.*\)/\1 \2/')
8989
TRIPLE_OS =$(word 1, $(triple_os_and_version))
9090
TRIPLE_VERSION =$(word 2, $(triple_os_and_version))
91+
TRIPLE_ENV =$(word 4, $(triple_space))
9192
ifeq "$(TRIPLE_VENDOR)" "apple"
9293
ifeq "$(TRIPLE_OS)" "ios"
9394
CODESIGN := codesign
@@ -100,11 +101,19 @@ ifneq "$(TRIPLE)" ""
100101
endif
101102
ARCH_CFLAGS :=-mios-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)"
102103
else
103-
SDKROOT = $(shell xcrun --sdk iphonesimulator --show-sdk-path)
104+
ifeq "$(TRIPLE_ENV)" "macabi"
105+
SDKROOT = $(shell xcrun --sdk macosx --show-sdk-path)
106+
else
107+
SDKROOT = $(shell xcrun --sdk iphonesimulator --show-sdk-path)
108+
endif
104109
ifeq "$(TRIPLE_VERSION)" ""
105110
TRIPLE_VERSION =$(shell echo $(notdir $(SDKROOT)) | sed -e 's/.*\([0-9]\.[0-9]\).*/\1/')
106111
endif
107-
ARCH_CFLAGS :=-mios-simulator-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)"
112+
ifeq "$(TRIPLE_ENV)" "macabi"
113+
ARCH_CFLAGS :=-mios-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)"
114+
else
115+
ARCH_CFLAGS :=-mios-simulator-version-min=$(TRIPLE_VERSION) -isysroot "$(SDKROOT)"
116+
endif
108117
endif
109118
endif
110119
endif

lldb/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class TestGdbRemoteHostInfo(GdbRemoteTestCaseBase):
2424
"os_build",
2525
"os_kernel",
2626
"os_version",
27+
"maccatalyst_version",
2728
"ptrsize",
2829
"triple",
2930
"vendor",

lldb/source/Core/Module.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,26 @@ bool Module::RemapSourceFile(llvm::StringRef path,
16341634
return m_source_mappings.RemapPath(path, new_path);
16351635
}
16361636

1637+
bool Module::MergeArchitecture(const ArchSpec &arch_spec) {
1638+
if (!arch_spec.IsValid())
1639+
return false;
1640+
LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES),
1641+
"module has arch %s, merging/replacing with arch %s",
1642+
m_arch.GetTriple().getTriple().c_str(),
1643+
arch_spec.GetTriple().getTriple().c_str());
1644+
if (!m_arch.IsCompatibleMatch(arch_spec)) {
1645+
// The new architecture is different, we just need to replace it.
1646+
return SetArchitecture(arch_spec);
1647+
}
1648+
1649+
// Merge bits from arch_spec into "merged_arch" and set our architecture.
1650+
ArchSpec merged_arch(m_arch);
1651+
merged_arch.MergeFrom(arch_spec);
1652+
// SetArchitecture() is a no-op if m_arch is already valid.
1653+
m_arch = ArchSpec();
1654+
return SetArchitecture(merged_arch);
1655+
}
1656+
16371657
llvm::VersionTuple Module::GetVersion() {
16381658
if (ObjectFile *obj_file = GetObjectFile())
16391659
return obj_file->GetVersion();

lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,23 +71,32 @@
7171
return false;
7272
}
7373

74+
static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
75+
@autoreleasepool {
76+
NSDictionary *version_info =
77+
[NSDictionary dictionaryWithContentsOfFile:
78+
@"/System/Library/CoreServices/SystemVersion.plist"];
79+
NSString *version_value = [version_info objectForKey: Key];
80+
const char *version_str = [version_value UTF8String];
81+
version.tryParse(version_str);
82+
}
83+
}
84+
7485
llvm::VersionTuple HostInfoMacOSX::GetOSVersion() {
7586
static llvm::VersionTuple g_version;
87+
if (g_version.empty())
88+
ParseOSVersion(g_version, @"ProductVersion");
89+
return g_version;
90+
}
7691

77-
if (g_version.empty()) {
78-
@autoreleasepool {
79-
NSDictionary *version_info = [NSDictionary
80-
dictionaryWithContentsOfFile:
81-
@"/System/Library/CoreServices/SystemVersion.plist"];
82-
NSString *version_value = [version_info objectForKey:@"ProductVersion"];
83-
const char *version_str = [version_value UTF8String];
84-
g_version.tryParse(version_str);
85-
}
86-
}
87-
92+
llvm::VersionTuple HostInfoMacOSX::GetMacCatalystVersion() {
93+
static llvm::VersionTuple g_version;
94+
if (g_version.empty())
95+
ParseOSVersion(g_version, @"iOSSupportVersion");
8896
return g_version;
8997
}
9098

99+
91100
FileSpec HostInfoMacOSX::GetProgramFileSpec() {
92101
static FileSpec g_program_filespec;
93102
if (!g_program_filespec) {

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
100100
const ModuleList &target_images = target.GetImages();
101101
ModuleSpec module_spec(image_info.file_spec);
102102
module_spec.GetUUID() = image_info.uuid;
103+
104+
// macCatalyst support: Request matching os/environment.
105+
{
106+
auto &target_triple = target.GetArchitecture().GetTriple();
107+
if (target_triple.getOS() == llvm::Triple::IOS &&
108+
target_triple.getEnvironment() == llvm::Triple::MacABI) {
109+
// Request the macCatalyst variant of frameworks that have both
110+
// a PLATFORM_MACOS and a PLATFORM_MACCATALYST load command.
111+
module_spec.GetArchitecture() = ArchSpec(target_triple);
112+
}
113+
}
114+
103115
ModuleSP module_sp(target_images.FindFirstModule(module_spec));
104116

105117
if (module_sp && !module_spec.GetUUID().IsValid() &&
@@ -384,6 +396,10 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
384396
image_infos[i].os_type = llvm::Triple::WatchOS;
385397
// NEED_BRIDGEOS_TRIPLE else if (os_name == "bridgeos")
386398
// NEED_BRIDGEOS_TRIPLE image_infos[i].os_type = llvm::Triple::BridgeOS;
399+
else if (os_name == "maccatalyst") {
400+
image_infos[i].os_type = llvm::Triple::IOS;
401+
image_infos[i].os_env = llvm::Triple::MacABI;
402+
}
387403
}
388404
if (image->HasKey("min_version_os_sdk")) {
389405
image_infos[i].min_version_os_sdk =
@@ -654,6 +670,20 @@ bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
654670
target_images.AppendIfNeeded(image_module_sp);
655671
loaded_module_list.AppendIfNeeded(image_module_sp);
656672
}
673+
674+
// macCataylst support:
675+
// Update the module's platform with the DYLD info.
676+
ArchSpec dyld_spec = image_infos[idx].GetArchitecture();
677+
if (dyld_spec.GetTriple().getOS() == llvm::Triple::IOS &&
678+
dyld_spec.GetTriple().getEnvironment() == llvm::Triple::MacABI) {
679+
image_module_sp->MergeArchitecture(dyld_spec);
680+
const auto &target_triple = target.GetArchitecture().GetTriple();
681+
// If dyld reports the process as being loaded as MACCATALYST,
682+
// force-update the target's architecture to MACCATALYST.
683+
if (!(target_triple.getOS() == llvm::Triple::IOS &&
684+
target_triple.getEnvironment() == llvm::Triple::MacABI))
685+
target.SetArchitecture(dyld_spec);
686+
}
657687
}
658688
}
659689

@@ -711,6 +741,20 @@ void DynamicLoaderDarwin::Segment::PutToLog(Log *log,
711741
}
712742
}
713743

744+
lldb_private::ArchSpec DynamicLoaderDarwin::ImageInfo::GetArchitecture() const {
745+
// Update the module's platform with the DYLD info.
746+
lldb_private::ArchSpec arch_spec(lldb_private::eArchTypeMachO, header.cputype,
747+
header.cpusubtype);
748+
if (os_type == llvm::Triple::IOS && os_env == llvm::Triple::MacABI) {
749+
llvm::Triple triple(llvm::Twine("x86_64-apple-ios") + min_version_os_sdk +
750+
"-macabi");
751+
ArchSpec maccatalyst_spec(triple);
752+
if (arch_spec.IsCompatibleMatch(maccatalyst_spec))
753+
arch_spec.MergeFrom(maccatalyst_spec);
754+
}
755+
return arch_spec;
756+
}
757+
714758
const DynamicLoaderDarwin::Segment *
715759
DynamicLoaderDarwin::ImageInfo::FindSegment(ConstString name) const {
716760
const size_t num_segments = segments.size();

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

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -95,25 +95,34 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
9595
};
9696

9797
struct ImageInfo {
98-
lldb::addr_t address; // Address of mach header for this dylib
99-
lldb::addr_t slide; // The amount to slide all segments by if there is a
100-
// global slide.
101-
lldb::addr_t mod_date; // Modification date for this dylib
102-
lldb_private::FileSpec file_spec; // Resolved path for this dylib
103-
lldb_private::UUID
104-
uuid; // UUID for this dylib if it has one, else all zeros
105-
llvm::MachO::mach_header header; // The mach header for this image
106-
std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for
107-
// this executable (from memory of inferior)
108-
uint32_t load_stop_id; // The process stop ID that the sections for this
109-
// image were loaded
110-
llvm::Triple::OSType os_type; // LC_VERSION_MIN_... load command os type
111-
std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
112-
113-
ImageInfo()
114-
: address(LLDB_INVALID_ADDRESS), slide(0), mod_date(0), file_spec(),
115-
uuid(), header(), segments(), load_stop_id(0),
116-
os_type(llvm::Triple::OSType::UnknownOS), min_version_os_sdk() {}
98+
/// Address of mach header for this dylib.
99+
lldb::addr_t address = LLDB_INVALID_ADDRESS;
100+
/// The amount to slide all segments by if there is a global
101+
/// slide.
102+
lldb::addr_t slide = 0;
103+
/// Modification date for this dylib.
104+
lldb::addr_t mod_date = 0;
105+
/// Resolved path for this dylib.
106+
lldb_private::FileSpec file_spec;
107+
/// UUID for this dylib if it has one, else all zeros.
108+
lldb_private::UUID uuid;
109+
/// The mach header for this image.
110+
llvm::MachO::mach_header header;
111+
/// All segment vmaddr and vmsize pairs for this executable (from
112+
/// memory of inferior).
113+
std::vector<Segment> segments;
114+
/// The process stop ID that the sections for this image were
115+
/// loaded.
116+
uint32_t load_stop_id = 0;
117+
/// LC_VERSION_MIN_... load command os type.
118+
llvm::Triple::OSType os_type = llvm::Triple::OSType::UnknownOS;
119+
/// LC_VERSION_MIN_... load command os environment.
120+
llvm::Triple::EnvironmentType os_env =
121+
llvm::Triple::EnvironmentType::UnknownEnvironment;
122+
/// LC_VERSION_MIN_... SDK.
123+
std::string min_version_os_sdk;
124+
125+
ImageInfo() = default;
117126

118127
void Clear(bool load_cmd_data_only) {
119128
if (!load_cmd_data_only) {
@@ -127,6 +136,7 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
127136
segments.clear();
128137
load_stop_id = 0;
129138
os_type = llvm::Triple::OSType::UnknownOS;
139+
os_env = llvm::Triple::EnvironmentType::UnknownEnvironment;
130140
min_version_os_sdk.clear();
131141
}
132142

@@ -135,7 +145,8 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
135145
mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
136146
uuid == rhs.uuid &&
137147
memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
138-
segments == rhs.segments && os_type == rhs.os_type;
148+
segments == rhs.segments && os_type == rhs.os_type &&
149+
os_env == rhs.os_env;
139150
}
140151

141152
bool UUIDValid() const { return uuid.IsValid(); }
@@ -150,10 +161,7 @@ class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
150161
return 0;
151162
}
152163

153-
lldb_private::ArchSpec GetArchitecture() const {
154-
return lldb_private::ArchSpec(lldb_private::eArchTypeMachO,
155-
header.cputype, header.cpusubtype);
156-
}
164+
lldb_private::ArchSpec GetArchitecture() const;
157165

158166
const Segment *FindSegment(lldb_private::ConstString name) const;
159167

0 commit comments

Comments
 (0)