Skip to content

Commit

Permalink
Default relative method lest: all platforms are included
Browse files Browse the repository at this point in the history
Category merging: Change tests to reflect that both flag is needed to crash

Signed-off-by: Peter Rong <[email protected]>
  • Loading branch information
DataCorrupted committed Aug 1, 2024
1 parent dee85bc commit d82b683
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 65 deletions.
106 changes: 55 additions & 51 deletions lld/MachO/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1042,20 +1042,36 @@ static bool shouldAdhocSignByDefault(Architecture arch, PlatformType platform) {
platform == PLATFORM_XROS_SIMULATOR;
}

static bool dataConstDefault(const InputArgList &args) {
static const std::array<std::pair<PlatformType, VersionTuple>, 6> minVersion =
{{{PLATFORM_MACOS, VersionTuple(10, 15)},
{PLATFORM_IOS, VersionTuple(13, 0)},
{PLATFORM_TVOS, VersionTuple(13, 0)},
{PLATFORM_WATCHOS, VersionTuple(6, 0)},
{PLATFORM_XROS, VersionTuple(1, 0)},
{PLATFORM_BRIDGEOS, VersionTuple(4, 0)}}};
PlatformType platform = removeSimulator(config->platformInfo.target.Platform);
auto it = llvm::find_if(minVersion,
template <unsigned long N>
using MinVersions = std::array<std::pair<PlatformType, VersionTuple>, N>;

/// Returns true if the platform is greater than the min version.
/// Returns false if the platform does not exist.
template <unsigned long N>
static bool greaterEqMinVersion(const MinVersions<N> &minVersions,
bool ignoreSimulator) {
PlatformType platform = config->platformInfo.target.Platform;
if (ignoreSimulator)
platform = removeSimulator(platform);
auto it = llvm::find_if(minVersions,
[&](const auto &p) { return p.first == platform; });
if (it != minVersion.end())
if (config->platformInfo.target.MinDeployment < it->second)
return false;
if (it != minVersions.end())
if (config->platformInfo.target.MinDeployment >= it->second)
return true;
return false;
}

static bool dataConstDefault(const InputArgList &args) {
static const MinVersions<6> minVersion = {{
{PLATFORM_MACOS, VersionTuple(10, 15)},
{PLATFORM_IOS, VersionTuple(13, 0)},
{PLATFORM_TVOS, VersionTuple(13, 0)},
{PLATFORM_WATCHOS, VersionTuple(6, 0)},
{PLATFORM_XROS, VersionTuple(1, 0)},
{PLATFORM_BRIDGEOS, VersionTuple(4, 0)},
}};
if (!greaterEqMinVersion(minVersion, true))
return false;

switch (config->outputType) {
case MH_EXECUTE:
Expand Down Expand Up @@ -1106,30 +1122,18 @@ static bool shouldEmitChainedFixups(const InputArgList &args) {
if (requested)
return true;

static const std::array<std::pair<PlatformType, VersionTuple>, 9> minVersion =
{{
{PLATFORM_IOS, VersionTuple(13, 4)},
{PLATFORM_IOSSIMULATOR, VersionTuple(16, 0)},
{PLATFORM_MACOS, VersionTuple(13, 0)},
{PLATFORM_TVOS, VersionTuple(14, 0)},
{PLATFORM_TVOSSIMULATOR, VersionTuple(15, 0)},
{PLATFORM_WATCHOS, VersionTuple(7, 0)},
{PLATFORM_WATCHOSSIMULATOR, VersionTuple(8, 0)},
{PLATFORM_XROS, VersionTuple(1, 0)},
{PLATFORM_XROS_SIMULATOR, VersionTuple(1, 0)},
}};
PlatformType platform = config->platformInfo.target.Platform;
auto it = llvm::find_if(minVersion,
[&](const auto &p) { return p.first == platform; });

// We don't know the versions for other platforms, so default to disabled.
if (it == minVersion.end())
return false;

if (it->second > config->platformInfo.target.MinDeployment)
return false;

return true;
static const MinVersions<9> minVersion = {{
{PLATFORM_IOS, VersionTuple(13, 4)},
{PLATFORM_IOSSIMULATOR, VersionTuple(16, 0)},
{PLATFORM_MACOS, VersionTuple(13, 0)},
{PLATFORM_TVOS, VersionTuple(14, 0)},
{PLATFORM_TVOSSIMULATOR, VersionTuple(15, 0)},
{PLATFORM_WATCHOS, VersionTuple(7, 0)},
{PLATFORM_WATCHOSSIMULATOR, VersionTuple(8, 0)},
{PLATFORM_XROS, VersionTuple(1, 0)},
{PLATFORM_XROS_SIMULATOR, VersionTuple(1, 0)},
}};
return greaterEqMinVersion(minVersion, false);
}

static bool shouldEmitRelativeMethodLists(const InputArgList &args) {
Expand All @@ -1140,20 +1144,20 @@ static bool shouldEmitRelativeMethodLists(const InputArgList &args) {
if (arg && arg->getOption().getID() == OPT_no_objc_relative_method_lists)
return false;

// If no flag is specified:
// - default true on >= ios14/macos11
// - default false on everything else
switch (config->platformInfo.target.Platform) {
case PLATFORM_IOS:
case PLATFORM_IOSSIMULATOR:
return config->platformInfo.target.MinDeployment >= VersionTuple(14, 0);
case PLATFORM_MACOS:
return config->platformInfo.target.MinDeployment >= VersionTuple(11, 0);
default:
return false;
};
llvm_unreachable("RelativeMethodList should default to false, control flow "
"should not reach here");
// If no flag is specified, enable this on newer versions by default.
// The min versions is taken from
// ld64(https://github.com/apple-oss-distributions/ld64/blob/47f477cb721755419018f7530038b272e9d0cdea/src/ld/ld.hpp#L310)
// to mimic to operation of ld64
// [here](https://github.com/apple-oss-distributions/ld64/blob/47f477cb721755419018f7530038b272e9d0cdea/src/ld/Options.cpp#L6085-L6101)
static const MinVersions<6> minVersion = {{
{PLATFORM_MACOS, VersionTuple(10, 16)},
{PLATFORM_IOS, VersionTuple(14, 0)},
{PLATFORM_WATCHOS, VersionTuple(7, 0)},
{PLATFORM_TVOS, VersionTuple(14, 0)},
{PLATFORM_BRIDGEOS, VersionTuple(5, 0)},
{PLATFORM_XROS, VersionTuple(1, 0)},
}};
return greaterEqMinVersion(minVersion, true);
}

void SymbolPatterns::clear() {
Expand Down
2 changes: 1 addition & 1 deletion lld/test/MachO/objc-category-merging-complete-test.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
############ Test merging multiple categories into a single category ############
## Create a dylib to link against(a64_file1.dylib) and merge categories in the main binary (file2_merge_a64.exe)
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_file1.o a64_file1.s
# RUN: %lld -no_objc_relative_method_lists -arch arm64 a64_file1.o -o a64_file1.dylib -dylib
# RUN: %lld -arch arm64 a64_file1.o -o a64_file1.dylib -dylib

# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_file2.o a64_file2.s
# RUN: %lld -no_objc_relative_method_lists -arch arm64 -o a64_file2_no_merge.exe a64_file1.dylib a64_file2.o
Expand Down
6 changes: 3 additions & 3 deletions lld/test/MachO/objc-category-merging-minimal.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
############ Test merging multiple categories into a single category ############
## Create a dylib with a fake base class to link against in when merging between categories
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o a64_fakedylib.o a64_fakedylib.s
# RUN: %lld -no_objc_relative_method_lists -arch arm64 a64_fakedylib.o -o a64_fakedylib.dylib -dylib
# RUN: %lld -arch arm64 a64_fakedylib.o -o a64_fakedylib.dylib -dylib

## Create our main testing dylib - linking against the fake dylib above
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_cat_minimal.o merge_cat_minimal.s
# RUN: %lld -no_objc_relative_method_lists -arch arm64 -dylib -o merge_cat_minimal_no_merge.dylib a64_fakedylib.dylib merge_cat_minimal.o
# RUN: %lld -arch arm64 -dylib -o merge_cat_minimal_no_merge.dylib a64_fakedylib.dylib merge_cat_minimal.o
# RUN: %lld -no_objc_relative_method_lists -arch arm64 -dylib -o merge_cat_minimal_merge.dylib -objc_category_merging a64_fakedylib.dylib merge_cat_minimal.o

## Now verify that the flag caused category merging to happen appropriatelly
Expand All @@ -21,7 +21,7 @@
############ Test merging multiple categories into the base class ############
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos -o merge_base_class_minimal.o merge_base_class_minimal.s
# RUN: %lld -no_objc_relative_method_lists -arch arm64 -dylib -o merge_base_class_minimal_yes_merge.dylib -objc_category_merging merge_base_class_minimal.o merge_cat_minimal.o
# RUN: %lld -no_objc_relative_method_lists -arch arm64 -dylib -o merge_base_class_minimal_no_merge.dylib merge_base_class_minimal.o merge_cat_minimal.o
# RUN: %lld -arch arm64 -dylib -o merge_base_class_minimal_no_merge.dylib merge_base_class_minimal.o merge_cat_minimal.o

# RUN: llvm-objdump --objc-meta-data --macho merge_base_class_minimal_no_merge.dylib | FileCheck %s --check-prefixes=NO_MERGE_INTO_BASE
# RUN: llvm-objdump --objc-meta-data --macho merge_base_class_minimal_yes_merge.dylib | FileCheck %s --check-prefixes=YES_MERGE_INTO_BASE
Expand Down
17 changes: 7 additions & 10 deletions lld/test/MachO/objc-relative-method-lists-simple.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# UNSUPPORTED: target=arm{{.*}}-unknown-linux-gnueabihf
# RUN: rm -rf %t; split-file %s %t && cd %t

## Compile a64_rel_dylib.o with MacOS 11
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11 -o a64_rel_dylib.o a64_simple_class.s
## Compile a64_rel_dylib.o
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos10.15 -o a64_rel_dylib.o a64_simple_class.s

## Test arm64 + relative method lists
# RUN: %no-lsystem-lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64
Expand All @@ -17,19 +17,16 @@
# RUN: %no-lsystem-lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -no_objc_relative_method_lists
# RUN: llvm-objdump --macho --objc-meta-data a64_rel_dylib.dylib | FileCheck %s --check-prefix=CHK_NO_REL

## Compile a64_rel_dylib.o with MacOS 10
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos10 -o a64_rel_dylib.o a64_simple_class.s

## Test arm64 + relative method lists by explicitly adding `-objc_relative_method_lists`.
# RUN: %lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -platform_version macOS 10.0 10.0 -objc_relative_method_lists
# RUN: %lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -platform_version macOS 10.15 10.15 -objc_relative_method_lists
# RUN: llvm-objdump --macho --objc-meta-data a64_rel_dylib.dylib | FileCheck %s --check-prefix=CHK_REL

## Test arm64 + no relative method lists by default.
# RUN: %lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -platform_version macOS 10.0 10.0
# RUN: %lld a64_rel_dylib.o -o a64_rel_dylib.dylib -map a64_rel_dylib.map -dylib -arch arm64 -platform_version macOS 10.15 10.15
# RUN: llvm-objdump --macho --objc-meta-data a64_rel_dylib.dylib | FileCheck %s --check-prefix=CHK_NO_REL


CHK_REL: Contents of (__DATA{{(_CONST)?}},__objc_classlist) section
CHK_REL: Contents of (__DATA_CONST,__objc_classlist) section
CHK_REL-NEXT: _OBJC_CLASS_$_MyClass
CHK_REL: baseMethods
CHK_REL-NEXT: entsize 12 (relative)
Expand Down Expand Up @@ -62,7 +59,7 @@ CHK_REL-NEXT: imp 0x{{[0-9a-f]*}} (0x{{[0-9a-f]*}}) +[MyClass class_method_0

CHK_NO_REL-NOT: (relative)

CHK_NO_REL: Contents of (__DATA{{(_CONST)?}},__objc_classlist) section
CHK_NO_REL: Contents of (__DATA_CONST,__objc_classlist) section
CHK_NO_REL-NEXT: _OBJC_CLASS_$_MyClass

CHK_NO_REL: baseMethods 0x{{[0-9a-f]*}} (struct method_list_t *)
Expand Down Expand Up @@ -136,7 +133,7 @@ CHK_NO_REL-NEXT: imp +[MyClass class_method_02]
.include "objc-macros.s"

.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 0
.build_version macos, 10, 15

.objc_selector_def "-[MyClass instance_method_00]"
.objc_selector_def "-[MyClass instance_method_01]"
Expand Down

0 comments on commit d82b683

Please sign in to comment.