Index: lld/ELF/Config.h =================================================================== --- lld/ELF/Config.h +++ lld/ELF/Config.h @@ -111,6 +111,7 @@ bool AsNeeded = false; bool Bsymbolic; bool BsymbolicFunctions; + bool CheckLibraryDependency; bool CheckSections; bool CompressDebugSections; bool Cref; Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -625,6 +625,8 @@ Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary); Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic); Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions); + Config->CheckLibraryDependency = Args.hasFlag( + OPT_check_library_dependency, OPT_no_check_library_dependency, false); Config->CheckSections = Args.hasFlag(OPT_check_sections, OPT_no_check_sections, true); Config->Chroot = Args.getLastArgValue(OPT_chroot); @@ -923,6 +925,15 @@ Files.back()->JustSymbols = true; } break; + case OPT_start_group: + ++InputFile::GroupDepth; + break; + case OPT_end_group: + if (InputFile::GroupDepth > 0) + --InputFile::GroupDepth; + else + error("stray --end-group"); + break; case OPT_start_lib: case OPT_end_lib: InLib = (ID == OPT_start_lib); Index: lld/ELF/InputFiles.h =================================================================== --- lld/ELF/InputFiles.h +++ lld/ELF/InputFiles.h @@ -112,6 +112,14 @@ // True if this is an argument for --just-symbols. Usually false. bool JustSymbols = false; + // GroupId is used for --check-library-dependency which is an + // optional error checking feature. All files within the same + // --{start,end}-group get the same group ID. Otherwise, each file + // gets a new group ID. For more info, see checkDependency() in + // SymbolTable.cpp. + uint32_t GroupId; + static uint32_t GroupDepth; + protected: InputFile(Kind K, MemoryBufferRef M); std::vector Sections; @@ -119,6 +127,8 @@ private: const Kind FileKind; + + static uint32_t NextGroupId; }; template class ELFFileBase : public InputFile { Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -38,6 +38,8 @@ using namespace lld; using namespace lld::elf; +uint32_t InputFile::GroupDepth; +uint32_t InputFile::NextGroupId; std::vector elf::BinaryFiles; std::vector elf::BitcodeFiles; std::vector elf::ObjectFiles; @@ -45,7 +47,13 @@ TarWriter *elf::Tar; -InputFile::InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {} +InputFile::InputFile(Kind K, MemoryBufferRef M) + : MB(M), GroupId(NextGroupId), FileKind(K) { + // All files within the same --{start,end}-group get the same group ID. + // Otherwise, a new file will get a new group ID. + if (GroupDepth == 0) + ++NextGroupId; +} Optional elf::readFile(StringRef Path) { // The --chroot option changes our virtual root directory. @@ -760,8 +768,10 @@ if (Tar && C.getParent()->isThin()) Tar->append(relativeToRoot(CHECK(C.getFullName(), this)), MB.getBuffer()); - return createObjectFile(MB, getName(), - C.getParent()->isThin() ? 0 : C.getChildOffset()); + InputFile *File = createObjectFile( + MB, getName(), C.getParent()->isThin() ? 0 : C.getChildOffset()); + File->GroupId = GroupId; + return File; } template @@ -1162,7 +1172,10 @@ MemoryBufferRef MBRef = getBuffer(); if (MBRef.getBuffer().empty()) return nullptr; - return createObjectFile(MBRef, ArchiveName, OffsetInArchive); + + InputFile *File = createObjectFile(MBRef, ArchiveName, OffsetInArchive); + File->GroupId = GroupId; + return File; } template void LazyObjFile::parse() { Index: lld/ELF/Options.td =================================================================== --- lld/ELF/Options.td +++ lld/ELF/Options.td @@ -113,6 +113,9 @@ def enable_new_dtags: F<"enable-new-dtags">, HelpText<"Enable new dynamic tags">; +def end_group: F<"end-group">, + HelpText<"Ignored for compatibility with GNU unless you pass --check-library-dependency">; + def end_lib: F<"end-lib">, HelpText<"End a grouping of objects that should be treated as if they were together in an archive">; @@ -274,6 +277,9 @@ defm sort_section: Eq<"sort-section">, HelpText<"Specifies sections sorting rule when linkerscript is used">; +def start_group: F<"start-group">, + HelpText<"Ignored for compatibility with GNU unless you pass --check-library-dependency">; + def start_lib: F<"start-lib">, HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">; @@ -344,6 +350,10 @@ def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"