summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Config.h2
-rw-r--r--lld/ELF/Driver.cpp12
-rw-r--r--lld/ELF/OutputSections.cpp2
-rw-r--r--lld/ELF/OutputSections.h2
-rw-r--r--lld/ELF/Writer.cpp31
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>
OpenPOWER on IntegriCloud