diff options
-rw-r--r-- | lld/ELF/Config.h | 2 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 12 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 2 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 31 |
5 files changed, 20 insertions, 29 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index efeadf259af..b828cdb2504 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -72,7 +72,6 @@ struct VersionDefinition { struct Configuration { InputFile *FirstElf = nullptr; uint8_t OSABI = 0; - llvm::DenseMap<llvm::StringRef, unsigned> SymbolOrderingFile; llvm::StringMap<uint64_t> SectionStartMap; llvm::StringRef DynamicLinker; llvm::StringRef Entry; @@ -89,6 +88,7 @@ struct Configuration { std::vector<VersionDefinition> VersionDefinitions; std::vector<llvm::StringRef> AuxiliaryList; std::vector<llvm::StringRef> SearchPaths; + std::vector<llvm::StringRef> SymbolOrderingFile; std::vector<llvm::StringRef> Undefined; std::vector<SymbolVersion> VersionScriptGlobals; std::vector<SymbolVersion> VersionScriptLocals; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 285fe4a795d..548aa8a1b46 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -491,16 +491,6 @@ static std::vector<StringRef> getLines(MemoryBufferRef MB) { return Ret; } -// Parse the --symbol-ordering-file argument. File has form: -// symbolName1 -// [...] -// symbolNameN -static void parseSymbolOrderingList(MemoryBufferRef MB) { - unsigned I = 0; - for (StringRef S : getLines(MB)) - Config->SymbolOrderingFile.insert({S, I++}); -} - // Initializes Config members by the command line options. void LinkerDriver::readConfigs(opt::InputArgList &Args) { for (auto *Arg : Args.filtered(OPT_L)) @@ -645,7 +635,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file)) if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue())) - parseSymbolOrderingList(*Buffer); + Config->SymbolOrderingFile = getLines(*Buffer); // If --retain-symbol-file is used, we'll retail only the symbols listed in // the file and discard all others. diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index cfb8ac9c568..bf7f9c29a29 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -153,7 +153,7 @@ template <class ELFT> void OutputSection<ELFT>::assignOffsets() { template <class ELFT> void OutputSection<ELFT>::sort( - std::function<unsigned(InputSection<ELFT> *S)> Order) { + std::function<int(InputSection<ELFT> *S)> Order) { typedef std::pair<unsigned, InputSection<ELFT> *> Pair; auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; }; diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 93d44385867..978b1f8191e 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -111,7 +111,7 @@ public: typedef typename ELFT::uint uintX_t; OutputSection(StringRef Name, uint32_t Type, uintX_t Flags); void addSection(InputSectionData *C) override; - void sort(std::function<unsigned(InputSection<ELFT> *S)> Order); + void sort(std::function<int(InputSection<ELFT> *S)> Order); void sortInitFini(); void sortCtorsDtors(); void writeTo(uint8_t *Buf) override; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 9dfb907c3c1..c7ed590dfe7 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -765,33 +765,34 @@ template <class ELFT> static void sortCtorsDtors(OutputSectionBase *S) { // Sort input sections using the list provided by --symbol-ordering-file. template <class ELFT> -static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *> V) { +static void sortBySymbolsOrder(ArrayRef<OutputSectionBase *> OutputSections) { if (Config->SymbolOrderingFile.empty()) return; - // Build sections order map from symbols list. - DenseMap<InputSectionBase<ELFT> *, unsigned> SectionsOrder; + // Build a map from symbols to their priorities. Symbols that didn't + // appear in the symbol ordering file have the lowest priority 0. + // All explicitly mentioned symbols have negative (higher) priorities. + DenseMap<StringRef, int> SymbolOrder; + int Priority = -Config->SymbolOrderingFile.size(); + for (StringRef S : Config->SymbolOrderingFile) + SymbolOrder.insert({S, Priority++}); + + // Build a map from sections to their priorities. + DenseMap<InputSectionBase<ELFT> *, int> SectionOrder; for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) { for (SymbolBody *Body : File->getSymbols()) { auto *D = dyn_cast<DefinedRegular<ELFT>>(Body); if (!D || !D->Section) continue; - auto It = Config->SymbolOrderingFile.find(Body->getName()); - if (It == Config->SymbolOrderingFile.end()) - continue; - - auto It2 = SectionsOrder.insert({D->Section, It->second}); - if (!It2.second) - It2.first->second = std::min(It->second, It2.first->second); + int &Priority = SectionOrder[D->Section]; + Priority = std::min(Priority, SymbolOrder.lookup(D->getName())); } } - for (OutputSectionBase *Base : V) + // Sort sections by priority. + for (OutputSectionBase *Base : OutputSections) if (auto *Sec = dyn_cast<OutputSection<ELFT>>(Base)) - Sec->sort([&](InputSection<ELFT> *S) { - auto It = SectionsOrder.find(S); - return It == SectionsOrder.end() ? UINT32_MAX : It->second; - }); + Sec->sort([&](InputSection<ELFT> *S) { return SectionOrder.lookup(S); }); } template <class ELFT> |