diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -89,6 +89,7 @@ bool hasReexports = false; bool allLoad = false; bool forceLoadObjC = false; + bool forceLoadSwift = false; bool staticLink = false; bool implicitDylibs = false; bool isPic = false; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -327,10 +327,10 @@ } static void addLibrary(StringRef name, bool isNeeded, bool isWeak, - bool isReexport, bool isExplicit) { + bool isReexport, bool isExplicit, bool forceLoad) { if (Optional path = findLibrary(name)) { if (auto *dylibFile = dyn_cast_or_null( - addFile(*path, /*forceLoadArchive=*/false, isExplicit))) { + addFile(*path, forceLoad, isExplicit))) { if (isNeeded) dylibFile->forceNeeded = true; if (isWeak) @@ -386,10 +386,14 @@ 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 @@ 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 @@ 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); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -193,6 +193,9 @@ MetaVarName<"">, HelpText<"Load all members static archive library at ">, Group; +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; def grp_content : OptionGroup<"content">, HelpText<"ADDITIONAL CONTENT">; @@ -1193,10 +1196,6 @@ HelpText<"This option is undocumented in ld64">, Flags<[HelpHidden]>, Group; -def force_load_swift_libs : Flag<["-"], "force_load_swift_libs">, - HelpText<"This option is undocumented in ld64">, - Flags<[HelpHidden]>, - Group; def force_symbol_not_weak : Flag<["-"], "force_symbol_not_weak">, HelpText<"This option is undocumented in ld64">, Flags<[HelpHidden]>, diff --git a/lld/test/MachO/force-load-swift-libs.ll b/lld/test/MachO/force-load-swift-libs.ll new file mode 100644 --- /dev/null +++ b/lld/test/MachO/force-load-swift-libs.ll @@ -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: