Index: lld/MachO/Driver.h =================================================================== --- lld/MachO/Driver.h +++ lld/MachO/Driver.h @@ -70,7 +70,8 @@ llvm::Optional loadArchiveMember(MemoryBufferRef, uint32_t modTime, StringRef archiveName, - bool objCOnly); + bool objCOnly, + uint64_t offsetInArchive); uint32_t getModTime(llvm::StringRef path); Index: lld/MachO/Driver.cpp =================================================================== --- lld/MachO/Driver.cpp +++ lld/MachO/Driver.cpp @@ -228,6 +228,7 @@ struct ArchiveMember { MemoryBufferRef mbref; uint32_t modTime; + uint64_t offsetInArchive; }; } // namespace @@ -257,7 +258,7 @@ CHECK(c.getLastModified(), mb.getBufferIdentifier() + ": could not get the modification " "time for a child of the archive")); - v.push_back({mbref, modTime}); + v.push_back({mbref, modTime, c.getChildOffset()}); } if (err) fatal(mb.getBufferIdentifier() + @@ -298,7 +299,8 @@ if (Optional buffer = readFile(path)) { for (const ArchiveMember &member : getArchiveMembers(*buffer)) { if (Optional file = loadArchiveMember( - member.mbref, member.modTime, path, /*objCOnly=*/false)) { + member.mbref, member.modTime, path, /*objCOnly=*/false, + member.offsetInArchive)) { inputFiles.insert(*file); printArchiveMemberLoad( (forceLoadArchive ? "-force_load" : "-all_load"), @@ -319,7 +321,8 @@ if (Optional buffer = readFile(path)) { for (const ArchiveMember &member : getArchiveMembers(*buffer)) { if (Optional file = loadArchiveMember( - member.mbref, member.modTime, path, /*objCOnly=*/true)) { + member.mbref, member.modTime, path, /*objCOnly=*/true, + member.offsetInArchive)) { inputFiles.insert(*file); printArchiveMemberLoad("-ObjC", inputFiles.back()); } @@ -343,7 +346,7 @@ } break; case file_magic::bitcode: - newFile = make(mbref); + newFile = make(mbref, "", 0); break; case file_magic::macho_executable: case file_magic::macho_bundle: Index: lld/MachO/DriverUtils.cpp =================================================================== --- lld/MachO/DriverUtils.cpp +++ lld/MachO/DriverUtils.cpp @@ -280,7 +280,8 @@ Optional macho::loadArchiveMember(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName, - bool objCOnly) { + bool objCOnly, + uint64_t offsetInArchive) { if (config->zeroModTime) modTime = 0; @@ -291,7 +292,7 @@ return None; case file_magic::bitcode: if (!objCOnly || check(isBitcodeContainingObjCCategory(mb))) - return make(mb); + return make(mb, archiveName, offsetInArchive); return None; default: error(archiveName + ": archive member " + mb.getBufferIdentifier() + Index: lld/MachO/InputFiles.h =================================================================== --- lld/MachO/InputFiles.h +++ lld/MachO/InputFiles.h @@ -196,7 +196,8 @@ class BitcodeFile final : public InputFile { public: - explicit BitcodeFile(MemoryBufferRef mb); + explicit BitcodeFile(MemoryBufferRef mb, StringRef archiveName, + uint64_t offsetInArchive); static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; } std::unique_ptr obj; Index: lld/MachO/InputFiles.cpp =================================================================== --- lld/MachO/InputFiles.cpp +++ lld/MachO/InputFiles.cpp @@ -1215,8 +1215,8 @@ // to it later. const object::Archive::Symbol symCopy = sym; - if (Optional file = - loadArchiveMember(mb, modTime, getName(), /*objCOnly=*/false)) { + if (Optional file = loadArchiveMember( + mb, modTime, getName(), /*objCOnly=*/false, c.getChildOffset())) { inputFiles.insert(*file); // ld64 doesn't demangle sym here even with -demangle. // Match that: intentionally don't call toMachOString(). @@ -1255,8 +1255,22 @@ /*noDeadStrip=*/false); } -BitcodeFile::BitcodeFile(MemoryBufferRef mbref) - : InputFile(BitcodeKind, mbref) { +BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName, + uint64_t offsetInArchive) + : InputFile(BitcodeKind, mb) { + std::string path = mb.getBufferIdentifier().str(); + // ThinLTO assumes that all MemoryBufferRefs given to it have a unique + // name. If two archives define two members with the same name, this + // causes a collision which result in only one of the objects being taken + // into consideration at LTO time (which very likely causes undefined + // symbols later in the link stage). So we append file offset to make + // filename unique. + MemoryBufferRef mbref( + mb.getBuffer(), + saver.save(archiveName.empty() ? path + : archiveName + sys::path::filename(path) + + utostr(offsetInArchive))); + obj = check(lto::InputFile::create(mbref)); // Convert LTO Symbols to LLD Symbols in order to perform resolution. The