diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 927dc272b5326..4c796a7178b7a 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -258,6 +258,65 @@ StringRef InputFile::getNameForScript() const { return nameForScriptCache; } +// An ELF object file may contain a `.deplibs` section. If it exists, the +// section contains a list of library specifiers such as `m` for libm. This +// function resolves a given name by finding the first matching library checking +// the various ways that a library can be specified to LLD. This ELF extension +// is a form of autolinking and is called `dependent libraries`. It is currently +// unique to LLVM and lld. +static void addDependentLibrary(StringRef specifier, const InputFile *f) { + if (!config->dependentLibraries) + return; + if (Optional s = searchLibraryBaseName(specifier)) + driver->addFile(saver().save(*s), /*withLOption=*/true); + else if (Optional s = findFromSearchPaths(specifier)) + driver->addFile(saver().save(*s), /*withLOption=*/true); + else if (fs::exists(specifier)) + driver->addFile(specifier, /*withLOption=*/false); + else + error(toString(f) + + ": unable to find library from dependent library specifier: " + + specifier); +} + +// Record the membership of a section group so that in the garbage collection +// pass, section group members are kept or discarded as a unit. +template +static void handleSectionGroup(ArrayRef sections, + ArrayRef entries) { + bool hasAlloc = false; + for (uint32_t index : entries.slice(1)) { + if (index >= sections.size()) + return; + if (InputSectionBase *s = sections[index]) + if (s != &InputSection::discarded && s->flags & SHF_ALLOC) + hasAlloc = true; + } + + // If any member has the SHF_ALLOC flag, the whole group is subject to garbage + // collection. See the comment in markLive(). This rule retains .debug_types + // and .rela.debug_types. + if (!hasAlloc) + return; + + // Connect the members in a circular doubly-linked list via + // nextInSectionGroup. + InputSectionBase *head; + InputSectionBase *prev = nullptr; + for (uint32_t index : entries.slice(1)) { + InputSectionBase *s = sections[index]; + if (!s || s == &InputSection::discarded) + continue; + if (prev) + prev->nextInSectionGroup = s; + else + head = s; + prev = s; + } + if (prev) + prev->nextInSectionGroup = head; +} + template DWARFCache *ObjFile::getDwarf() { llvm::call_once(initDwarf, [this]() { dwarf = std::make_unique(std::make_unique( @@ -450,65 +509,6 @@ template void ObjFile::initializeJustSymbols() { sections.resize(numELFShdrs); } -// An ELF object file may contain a `.deplibs` section. If it exists, the -// section contains a list of library specifiers such as `m` for libm. This -// function resolves a given name by finding the first matching library checking -// the various ways that a library can be specified to LLD. This ELF extension -// is a form of autolinking and is called `dependent libraries`. It is currently -// unique to LLVM and lld. -static void addDependentLibrary(StringRef specifier, const InputFile *f) { - if (!config->dependentLibraries) - return; - if (Optional s = searchLibraryBaseName(specifier)) - driver->addFile(saver().save(*s), /*withLOption=*/true); - else if (Optional s = findFromSearchPaths(specifier)) - driver->addFile(saver().save(*s), /*withLOption=*/true); - else if (fs::exists(specifier)) - driver->addFile(specifier, /*withLOption=*/false); - else - error(toString(f) + - ": unable to find library from dependent library specifier: " + - specifier); -} - -// Record the membership of a section group so that in the garbage collection -// pass, section group members are kept or discarded as a unit. -template -static void handleSectionGroup(ArrayRef sections, - ArrayRef entries) { - bool hasAlloc = false; - for (uint32_t index : entries.slice(1)) { - if (index >= sections.size()) - return; - if (InputSectionBase *s = sections[index]) - if (s != &InputSection::discarded && s->flags & SHF_ALLOC) - hasAlloc = true; - } - - // If any member has the SHF_ALLOC flag, the whole group is subject to garbage - // collection. See the comment in markLive(). This rule retains .debug_types - // and .rela.debug_types. - if (!hasAlloc) - return; - - // Connect the members in a circular doubly-linked list via - // nextInSectionGroup. - InputSectionBase *head; - InputSectionBase *prev = nullptr; - for (uint32_t index : entries.slice(1)) { - InputSectionBase *s = sections[index]; - if (!s || s == &InputSection::discarded) - continue; - if (prev) - prev->nextInSectionGroup = s; - else - head = s; - prev = s; - } - if (prev) - prev->nextInSectionGroup = head; -} - template void ObjFile::initializeSections(bool ignoreComdats, const llvm::object::ELFFile &obj) {