[lld-macho] Implement -force_load_swift_libs

It causes libraries whose names start with "swift" to be force-loaded.
Note that unlike the more general `-force_load`, this flag only applies
to libraries specified via LC_LINKER_OPTIONS, and not those passed on
the command-line. This is what ld64 does.

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D103709
This commit is contained in:
Jez Ng 2021-06-07 23:48:16 -04:00
parent 04259cde15
commit 447dfbe005
4 changed files with 58 additions and 10 deletions

View File

@ -89,6 +89,7 @@ struct Configuration {
bool hasReexports = false;
bool allLoad = false;
bool forceLoadObjC = false;
bool forceLoadSwift = false;
bool staticLink = false;
bool implicitDylibs = false;
bool isPic = false;

View File

@ -327,10 +327,10 @@ static InputFile *addFile(StringRef path, bool forceLoadArchive,
}
static void addLibrary(StringRef name, bool isNeeded, bool isWeak,
bool isReexport, bool isExplicit) {
bool isReexport, bool isExplicit, bool forceLoad) {
if (Optional<StringRef> path = findLibrary(name)) {
if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
addFile(*path, /*forceLoadArchive=*/false, isExplicit))) {
addFile(*path, forceLoad, isExplicit))) {
if (isNeeded)
dylibFile->forceNeeded = true;
if (isWeak)
@ -386,10 +386,14 @@ void macho::parseLCLinkerOption(InputFile *f, unsigned argc, StringRef data) {
for (const Arg *arg : args) {
switch (arg->getOption().getID()) {
case OPT_l:
addLibrary(arg->getValue(), /*isNeeded=*/false, /*isWeak=*/false,
/*isReexport=*/false, /*isExplicit=*/false);
case OPT_l: {
StringRef name = arg->getValue();
bool forceLoad =
config->forceLoadSwift ? name.startswith("swift") : false;
addLibrary(name, /*isNeeded=*/false, /*isWeak=*/false,
/*isReexport=*/false, /*isExplicit=*/false, forceLoad);
break;
}
case OPT_framework:
addFramework(arg->getValue(), /*isNeeded=*/false, /*isWeak=*/false,
/*isReexport=*/false, /*isExplicit=*/false);
@ -916,7 +920,7 @@ void createFiles(const InputArgList &args) {
case OPT_weak_l:
addLibrary(arg->getValue(), opt.getID() == OPT_needed_l,
opt.getID() == OPT_weak_l, opt.getID() == OPT_reexport_l,
/*isExplicit=*/true);
/*isExplicit=*/true, /*forceLoad=*/false);
break;
case OPT_framework:
case OPT_needed_framework:
@ -1032,6 +1036,7 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
config->runtimePaths = args::getStrings(args, OPT_rpath);
config->allLoad = args.hasArg(OPT_all_load);
config->forceLoadObjC = args.hasArg(OPT_ObjC);
config->forceLoadSwift = args.hasArg(OPT_force_load_swift_libs);
config->deadStripDylibs = args.hasArg(OPT_dead_strip_dylibs);
config->demangle = args.hasArg(OPT_demangle);
config->implicitDylibs = !args.hasArg(OPT_no_implicit_dylibs);

View File

@ -193,6 +193,9 @@ def force_load : Separate<["-"], "force_load">,
MetaVarName<"<path>">,
HelpText<"Load all members static archive library at <path>">,
Group<grp_libs>;
def force_load_swift_libs : Flag<["-"], "force_load_swift_libs">,
HelpText<"Apply -force_load to libraries listed in LC_LINKER_OPTIONS whose names start with 'swift'">,
Group<grp_libs>;
def grp_content : OptionGroup<"content">, HelpText<"ADDITIONAL CONTENT">;
@ -1193,10 +1196,6 @@ def flto_codegen_only : Flag<["-"], "flto-codegen-only">,
HelpText<"This option is undocumented in ld64">,
Flags<[HelpHidden]>,
Group<grp_undocumented>;
def force_load_swift_libs : Flag<["-"], "force_load_swift_libs">,
HelpText<"This option is undocumented in ld64">,
Flags<[HelpHidden]>,
Group<grp_undocumented>;
def force_symbol_not_weak : Flag<["-"], "force_symbol_not_weak">,
HelpText<"This option is undocumented in ld64">,
Flags<[HelpHidden]>,

View File

@ -0,0 +1,43 @@
; REQUIRES: x86
; RUN: rm -rf %t; split-file %s %t
; RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/swift-foo.s -o %t/swift-foo.o
; RUN: llvm-ar rcs %t/libswiftFoo.a %t/swift-foo.o
; RUN: llvm-as %t/lc-linker-opt.ll -o %t/lc-linker-opt.o
; RUN: llvm-as %t/no-lc-linker-opt.ll -o %t/no-lc-linker-opt.o
; RUN: %lld -lSystem -force_load_swift_libs -L%t %t/lc-linker-opt.o -o %t/lc-linker-opt
; RUN: llvm-objdump --macho --syms %t/lc-linker-opt | FileCheck %s --check-prefix=HAS-SWIFT
; RUN: %lld -lSystem -L%t %t/lc-linker-opt.o -o %t/lc-linker-opt-no-force
; RUN: llvm-objdump --macho --syms %t/lc-linker-opt-no-force | FileCheck %s --check-prefix=NO-SWIFT
;; Swift libraries passed on the CLI don't get force-loaded!
; RUN: %lld -lSystem -force_load_swift_libs -lswiftFoo -L%t %t/no-lc-linker-opt.o -o %t/no-lc-linker-opt
; RUN: llvm-objdump --macho --syms %t/no-lc-linker-opt | FileCheck %s --check-prefix=NO-SWIFT
; HAS-SWIFT: _swift_foo
; NO-SWIFT-NOT: _swift_foo
;--- lc-linker-opt.ll
target triple = "x86_64-apple-macosx10.15.0"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
!0 = !{!"-lswiftFoo"}
!llvm.linker.options = !{!0}
define void @main() {
ret void
}
;--- no-lc-linker-opt.ll
target triple = "x86_64-apple-macosx10.15.0"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
define void @main() {
ret void
}
;--- swift-foo.s
.globl _swift_foo
_swift_foo: