diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -247,7 +247,8 @@ return CHECK(parseCachePruningPolicy(ltoPolicy), "invalid LTO cache policy"); } -static DenseMap loadedArchives; +static DenseMap lazyLoadedArchives; +static DenseMap forceLoadedArchives; static InputFile *addFile(StringRef path, ForceLoad forceLoadArchive, bool isLazy = false, bool isExplicit = true, @@ -267,9 +268,18 @@ // We don't take a reference to cachedFile here because the // loadArchiveMember() call below may recursively call addFile() and // invalidate this reference. - auto entry = loadedArchives.find(path); - if (entry != loadedArchives.end()) - return entry->second; + + if (forceLoadArchive == ForceLoad::No) { + auto entry = lazyLoadedArchives.find(path); + if (entry != lazyLoadedArchives.end()) { + return entry->second; + } + } else { + auto forceLoadedEntry = forceLoadedArchives.find(path); + if (forceLoadedEntry != forceLoadedArchives.end()) { + return forceLoadedEntry->second; + } + } std::unique_ptr archive = CHECK( object::Archive::create(mbref), path + ": failed to parse archive"); @@ -293,6 +303,9 @@ error(toString(file) + ": Archive::children failed: " + toString(std::move(e))); } + + forceLoadedArchives[path] = file; + } else if (forceLoadArchive == ForceLoad::Default && config->forceLoadObjC) { for (const object::Archive::Symbol &sym : file->getArchive().symbols()) @@ -315,10 +328,12 @@ error(toString(file) + ": Archive::children failed: " + toString(std::move(e))); } + + forceLoadedArchives[path] = file; } file->addLazySymbols(); - newFile = loadedArchives[path] = file; + newFile = lazyLoadedArchives[path] = file; break; } case file_magic::macho_object: @@ -1112,7 +1127,8 @@ concatOutputSections.clear(); inputFiles.clear(); inputSections.clear(); - loadedArchives.clear(); + forceLoadedArchives.clear(); + lazyLoadedArchives.clear(); loadedObjectFrameworks.clear(); syntheticSections.clear(); thunkMap.clear(); diff --git a/lld/test/MachO/lc-linker-option.ll b/lld/test/MachO/lc-linker-option.ll --- a/lld/test/MachO/lc-linker-option.ll +++ b/lld/test/MachO/lc-linker-option.ll @@ -77,6 +77,33 @@ ; SYMS-NEXT: g F __TEXT,__text __mh_execute_header ; SYMS-EMPTY: +;; Make sure -all_load has effect when libraries are loaded via LC_LINKER_OPTION flags +;; and explicily passed as well +; RUN: %lld -all_load %t/load-framework-foo.o %t/load-library-foo.o \ +; RUN: %t/main.o -o %t/main -F%t -L%t -lfoo +; RUN: llvm-objdump --macho --syms %t/main | FileCheck %s --check-prefix=SYMS_ALL_LOAD + +;; Note that _OBJC_CLASS_$_TestClass is *included* here. +; SYMS_ALL_LOAD: SYMBOL TABLE: +; SYMS_ALL_LOAD-NEXT: g F __TEXT,__text _main +; SYMS_ALL_LOAD-NEXT: g O __DATA,__objc_data _OBJC_CLASS_$_TestClass +; SYMS_ALL_LOAD-NEXT: g F __TEXT,__text __mh_execute_header +; SYMS_ALL_LOAD-EMPTY: + + +;; Make sure -ObjC has effect when frameworks are loaded via LC_LINKER_OPTION flags +;; and explicily passed as well +; RUN: %lld -ObjC %t/load-framework-foo.o %t/load-library-foo.o \ +; RUN: %t/main.o -o %t/main -F%t -L%t -framework Foo +; RUN: llvm-objdump --macho --syms %t/main | FileCheck %s --check-prefix=SYMS_OBJC_LOAD + +;; Note that _OBJC_CLASS_$_TestClass is *included* here. +; SYMS_OBJC_LOAD: SYMBOL TABLE: +; SYMS_OBJC_LOAD-NEXT: g F __TEXT,__text _main +; SYMS_OBJC_LOAD-NEXT: g O __DATA,__objc_data _OBJC_CLASS_$_TestClass +; SYMS_OBJC_LOAD-NEXT: g F __TEXT,__text __mh_execute_header +; SYMS_OBJC_LOAD-EMPTY: + ;; Make sure that frameworks containing object files or bitcode instead of ;; dylibs or archives do not cause duplicate symbol errors ; RUN: mkdir -p %t/Foo.framework