Index: lld/ELF/InputFiles.h =================================================================== --- lld/ELF/InputFiles.h +++ lld/ELF/InputFiles.h @@ -92,6 +92,9 @@ return symbols; } + // Get filename to use for linker script processing. + StringRef getNameForScript() const; + // Filename of .a which contained this file. If this file was // not in an archive file, it is the empty string. We use this // string for creating error messages. @@ -147,6 +150,9 @@ private: const Kind fileKind; + + // Cache for getNameForScript(). + mutable std::string nameForScriptCache; }; class ELFFileBase : public InputFile { Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -274,6 +274,16 @@ } } +StringRef InputFile::getNameForScript() const { + if (archiveName.empty()) + return getName(); + + if (nameForScriptCache.empty()) + nameForScriptCache = (archiveName + ':' + getName()).str(); + + return nameForScriptCache; +} + template DWARFCache *ObjFile::getDwarf() { llvm::call_once(initDwarf, [this]() { dwarf = std::make_unique(std::make_unique( Index: lld/ELF/LinkerScript.h =================================================================== --- lld/ELF/LinkerScript.h +++ lld/ELF/LinkerScript.h @@ -29,6 +29,7 @@ namespace elf { class Defined; +class InputFile; class InputSection; class InputSectionBase; class OutputSection; @@ -156,6 +157,9 @@ StringMatcher sectionPat; SortSectionPolicy sortOuter; SortSectionPolicy sortInner; + + mutable llvm::Optional> excludesFileCache; + bool excludesFile(const InputFile *file) const; }; struct InputSectionDescription : BaseCommand { @@ -169,6 +173,8 @@ } SingleStringMatcher filePat; + mutable llvm::Optional> matchesFileCache; + bool matchesFile(const InputFile *file) const; // Input sections that matches at least one of SectionPatterns // will be associated with this InputSectionDescription. Index: lld/ELF/LinkerScript.cpp =================================================================== --- lld/ELF/LinkerScript.cpp +++ lld/ELF/LinkerScript.cpp @@ -320,20 +320,37 @@ cmd->sym->type = v.type; } -static std::string getFilename(InputFile *file) { - if (!file) - return ""; - if (file->archiveName.empty()) - return std::string(file->getName()); - return (file->archiveName + ':' + file->getName()).str(); +static StringRef getFilename(const InputFile *file) { + return file ? file->getNameForScript() : StringRef(); +} + +bool InputSectionDescription::matchesFile(const InputFile *file) const { + if (filePat.isTrivialMatchAll()) + return true; + + if (!matchesFileCache || matchesFileCache->first != file) + matchesFileCache = std::make_pair(file, filePat.match(getFilename(file))); + + return matchesFileCache->second; +} + +bool SectionPattern::excludesFile(const InputFile *file) const { + if (excludedFilePat.empty()) + return false; + + if (!excludesFileCache || excludesFileCache->first != file) + excludesFileCache = + std::make_pair(file, excludedFilePat.match(getFilename(file))); + + return excludesFileCache->second; } bool LinkerScript::shouldKeep(InputSectionBase *s) { if (keptSections.empty()) return false; - std::string filename = getFilename(s->file); + for (InputSectionDescription *id : keptSections) - if (id->filePat.match(filename)) + if (id->matchesFile(s->file)) for (SectionPattern &p : id->sectionPatterns) if (p.sectionPat.match(s->name) && (s->flags & id->withFlags) == id->withFlags && @@ -433,9 +450,7 @@ if (!pat.sectionPat.match(sec->name)) continue; - std::string filename = getFilename(sec->file); - if (!cmd->filePat.match(filename) || - pat.excludedFilePat.match(filename) || + if (!cmd->matchesFile(sec->file) || pat.excludesFile(sec->file) || (sec->flags & cmd->withFlags) != cmd->withFlags || (sec->flags & cmd->withoutFlags) != 0) continue; Index: lld/include/lld/Common/Strings.h =================================================================== --- lld/include/lld/Common/Strings.h +++ lld/include/lld/Common/Strings.h @@ -39,6 +39,11 @@ // Match s against this pattern, exactly if ExactMatch is true. bool match(llvm::StringRef s) const; + // Returns true for pattern "*" which will match all inputs. + bool isTrivialMatchAll() const { + return !ExactMatch && GlobPatternMatcher.isTrivialMatchAll(); + } + private: // Whether to do an exact match irregardless of the presence of wildcard // character. @@ -69,7 +74,7 @@ // Add a new pattern to the existing ones to match against. void addPattern(SingleStringMatcher Matcher) { patterns.push_back(Matcher); } - bool empty() { return patterns.empty(); } + bool empty() const { return patterns.empty(); } // Match s against the patterns. bool match(llvm::StringRef s) const;