Index: lld/MachO/Driver.cpp =================================================================== --- lld/MachO/Driver.cpp +++ lld/MachO/Driver.cpp @@ -218,10 +218,12 @@ std::unique_ptr file = CHECK(Archive::create(mb), mb.getBufferIdentifier() + ": failed to parse archive"); + Archive *archive = file.get(); + make>(std::move(file)); // take ownership std::vector v; Error err = Error::success(); - for (const Archive::Child &c : file->children(err)) { + for (const Archive::Child &c : archive->children(err)) { MemoryBufferRef mbref = CHECK(c.getMemoryBufferRef(), mb.getBufferIdentifier() + @@ -235,7 +237,7 @@ return v; } -static InputFile *addFile(StringRef path) { +static InputFile *addFile(StringRef path, bool forceLoadArchive) { Optional buffer = readFile(path); if (!buffer) return nullptr; @@ -250,7 +252,7 @@ if (!file->isEmpty() && !file->hasSymbolTable()) error(path + ": archive has no index; run ranlib to add one"); - if (config->allLoad) { + if (config->allLoad || forceLoadArchive) { if (Optional buffer = readFile(path)) for (MemoryBufferRef member : getArchiveMembers(*buffer)) inputFiles.push_back(make(member)); @@ -301,13 +303,7 @@ return; MemoryBufferRef mbref = *buffer; for (StringRef path : args::getLines(mbref)) - addFile(path); -} - -static void forceLoadArchive(StringRef path) { - if (Optional buffer = readFile(path)) - for (MemoryBufferRef member : getArchiveMembers(*buffer)) - inputFiles.push_back(make(member)); + addFile(path, false); } static std::array archNames{"arm", "arm64", "i386", @@ -643,10 +639,11 @@ // TODO: are any of these better handled via filtered() or getLastArg()? switch (opt.getID()) { case OPT_INPUT: - addFile(arg->getValue()); + addFile(arg->getValue(), false); break; case OPT_weak_library: { - auto *dylibFile = dyn_cast_or_null(addFile(arg->getValue())); + auto *dylibFile = + dyn_cast_or_null(addFile(arg->getValue(), false)); if (dylibFile) dylibFile->forceWeakImport = true; break; @@ -655,13 +652,13 @@ addFileList(arg->getValue()); break; case OPT_force_load: - forceLoadArchive(arg->getValue()); + addFile(arg->getValue(), true); break; case OPT_l: case OPT_weak_l: { StringRef name = arg->getValue(); if (Optional path = findLibrary(name)) { - auto *dylibFile = dyn_cast_or_null(addFile(*path)); + auto *dylibFile = dyn_cast_or_null(addFile(*path, false)); if (opt.getID() == OPT_weak_l && dylibFile) dylibFile->forceWeakImport = true; break; @@ -673,7 +670,7 @@ case OPT_weak_framework: { StringRef name = arg->getValue(); if (Optional path = findFramework(name)) { - auto *dylibFile = dyn_cast_or_null(addFile(*path)); + auto *dylibFile = dyn_cast_or_null(addFile(*path, false)); if (opt.getID() == OPT_weak_framework && dylibFile) dylibFile->forceWeakImport = true; break; Index: lld/MachO/InputFiles.cpp =================================================================== --- lld/MachO/InputFiles.cpp +++ lld/MachO/InputFiles.cpp @@ -558,7 +558,7 @@ object::Archive::Child c = CHECK(sym.getMember(), toString(this) + ": could not get the member for symbol " + - sym.getName()); + toMachOString(sym)); if (!seen.insert(c.getChildOffset()).second) return; @@ -567,7 +567,7 @@ CHECK(c.getMemoryBufferRef(), toString(this) + ": could not get the buffer for the member defining symbol " + - sym.getName()); + toMachOString(sym)); auto file = make(mb); symbols.insert(symbols.end(), file->symbols.begin(), file->symbols.end()); subsections.insert(subsections.end(), file->subsections.begin(), Index: lld/MachO/Symbols.h =================================================================== --- lld/MachO/Symbols.h +++ lld/MachO/Symbols.h @@ -235,6 +235,8 @@ } // namespace macho std::string toString(const macho::Symbol &); +std::string toMachOString(const llvm::object::Archive::Symbol &); + } // namespace lld #endif Index: lld/MachO/Symbols.cpp =================================================================== --- lld/MachO/Symbols.cpp +++ lld/MachO/Symbols.cpp @@ -14,6 +14,21 @@ using namespace lld; using namespace lld::macho; +// Returns a symbol for an error message. +static std::string demangle(StringRef symName) { + if (config->demangle) + return demangleItanium(symName); + return std::string(symName); +} + +std::string lld::toString(const Symbol &sym) { + return demangle(sym.getName()); +} + +std::string lld::toMachOString(const object::Archive::Symbol &b) { + return demangle(b.getName()); +} + uint64_t Defined::getVA() const { if (isAbsolute()) return value; @@ -31,13 +46,6 @@ void LazySymbol::fetchArchiveMember() { file->fetch(sym); } -// Returns a symbol for an error message. -std::string lld::toString(const Symbol &sym) { - if (config->demangle) - return demangleItanium(sym.getName()); - return std::string(sym.getName()); -} - uint64_t DSOHandle::getVA() const { return header->addr; } uint64_t DSOHandle::getFileOffset() const { return header->fileOff; } Index: lld/test/MachO/thin-archive.s =================================================================== --- /dev/null +++ lld/test/MachO/thin-archive.s @@ -0,0 +1,40 @@ +# REQUIRES: x86 + +# RUN: split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t/main.o %t/main.s + +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t/lib.o \ +# RUN: %t/mangled-symbol.s +# RUN: llvm-ar csr %t/lib.a %t/lib.o +# RUN: llvm-ar csrT %t/lib_thin.a %t/lib.o + +# RUN: %lld %t/main.o %t/lib.a -o %t/out 2>&1 | \ +# RUN: FileCheck --allow-empty %s +# RUN: %lld %t/main.o %t/lib_thin.a -o %t/out 2>&1 | \ +# RUN: FileCheck --allow-empty %s +# RUN: %lld /%t/main.o -force_load %t/lib_thin.a -o %t/out 2>&1 | \ +# RUN: FileCheck --allow-empty %s + +# RUN: rm %t/lib.o +# RUN: %lld %t/main.o %t/lib.a -o %t/out 2>&1 | \ +# RUN: FileCheck --allow-empty %s +# RUN: not %lld %t/main.o %t/lib_thin.a -demangle -o %t/out 2>&1 | \ +# RUN: FileCheck --check-prefix=NOOBJ %s +# RUN: not %lld %t/main.o %t/lib_thin.a -o %t/out 2>&1 | \ +# RUN: FileCheck --check-prefix=NOOBJNODEMANGLE %s + +# CHECK-NOT: error: {{.*}}could not get the buffer for the member defining +# NOOBJ: error: {{.*}}lib_thin.a: could not get the buffer for the member defining symbol f(): '{{.*}}lib.o': +# NOOBJNODEMANGLE: error: {{.*}}lib_thin.a: could not get the buffer for the member defining symbol __Z1fv: '{{.*}}lib.o': + +#--- mangled-symbol.s +.globl __Z1fv +__Z1fv: + retq + +#--- main.s +.global _main +_main: + callq __Z1fv + mov $0, %rax + retq