[lld] r310045 - [ELF] - Fix "--symbol-ordering-file doesn't work with linker scripts"
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 4 03:25:29 PDT 2017
Author: grimar
Date: Fri Aug 4 03:25:29 2017
New Revision: 310045
URL: http://llvm.org/viewvc/llvm-project?rev=310045&view=rev
Log:
[ELF] - Fix "--symbol-ordering-file doesn't work with linker scripts"
This is PR33889,
Patch adds support of combination of linkerscript and
-symbol-ordering-file option.
If no sorting commands are present in script inside section declaration
and no --sort-section option specified, code uses sorting from ordering
file if any exist.
Differential revision: https://reviews.llvm.org/D35843
Added:
lld/trunk/test/ELF/linkerscript/symbol-ordering-file.s
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=310045&r1=310044&r2=310045&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Aug 4 03:25:29 2017
@@ -44,6 +44,29 @@ std::string lld::toString(const InputSec
return (toString(Sec->File) + ":(" + Sec->Name + ")").str();
}
+template <class ELFT> DenseMap<SectionBase *, int> elf::buildSectionOrder() {
+ // 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<SectionBase *, int> SectionOrder;
+ for (ObjFile<ELFT> *File : ObjFile<ELFT>::Instances) {
+ for (SymbolBody *Body : File->getSymbols()) {
+ auto *D = dyn_cast<DefinedRegular>(Body);
+ if (!D || !D->Section)
+ continue;
+ int &Priority = SectionOrder[D->Section];
+ Priority = std::min(Priority, SymbolOrder.lookup(D->getName()));
+ }
+ }
+ return SectionOrder;
+}
+
template <class ELFT>
static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> *File,
const typename ELFT::Shdr *Hdr) {
@@ -982,6 +1005,11 @@ uint64_t MergeInputSection::getOffset(ui
return Piece.OutputOff + Addend;
}
+template DenseMap<SectionBase *, int> elf::buildSectionOrder<ELF32LE>();
+template DenseMap<SectionBase *, int> elf::buildSectionOrder<ELF32BE>();
+template DenseMap<SectionBase *, int> elf::buildSectionOrder<ELF64LE>();
+template DenseMap<SectionBase *, int> elf::buildSectionOrder<ELF64BE>();
+
template InputSection::InputSection(ObjFile<ELF32LE> *, const ELF32LE::Shdr *,
StringRef);
template InputSection::InputSection(ObjFile<ELF32BE> *, const ELF32BE::Shdr *,
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=310045&r1=310044&r2=310045&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Fri Aug 4 03:25:29 2017
@@ -331,6 +331,9 @@ private:
// The list of all input sections.
extern std::vector<InputSectionBase *> InputSections;
+// Builds section order for handling --symbol-ordering-file.
+template <class ELFT> llvm::DenseMap<SectionBase *, int> buildSectionOrder();
+
} // namespace elf
std::string toString(const elf::InputSectionBase *);
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=310045&r1=310044&r2=310045&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Aug 4 03:25:29 2017
@@ -228,6 +228,29 @@ static void sortSections(InputSection **
std::stable_sort(Begin, End, getComparator(K));
}
+static llvm::DenseMap<SectionBase *, int> getSectionOrder() {
+ switch (Config->EKind) {
+ case ELF32LEKind:
+ return buildSectionOrder<ELF32LE>();
+ case ELF32BEKind:
+ return buildSectionOrder<ELF32BE>();
+ case ELF64LEKind:
+ return buildSectionOrder<ELF64LE>();
+ case ELF64BEKind:
+ return buildSectionOrder<ELF64BE>();
+ default:
+ llvm_unreachable("unknown ELF type");
+ }
+}
+
+static void sortBySymbolOrder(InputSection **Begin, InputSection **End) {
+ if (Config->SymbolOrderingFile.empty())
+ return;
+ static llvm::DenseMap<SectionBase *, int> Order = getSectionOrder();
+ MutableArrayRef<InputSection *> In(Begin, End - Begin);
+ sortByOrder(In, [&](InputSectionBase *S) { return Order.lookup(S); });
+}
+
// Compute and remember which sections the InputSectionDescription matches.
std::vector<InputSection *>
LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
@@ -273,8 +296,15 @@ LinkerScript::computeInputSections(const
// --sort-section is handled as an inner SORT command.
// 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
// 4. If no SORT command is given, sort according to --sort-section.
+ // 5. If no SORT commands are given and --sort-section is not specified,
+ // apply sorting provided by --symbol-ordering-file if any exist.
InputSection **Begin = Ret.data() + SizeBefore;
InputSection **End = Ret.data() + Ret.size();
+ if (Pat.SortOuter == SortSectionPolicy::Default &&
+ Config->SortSection == SortSectionPolicy::Default) {
+ sortBySymbolOrder(Begin, End);
+ continue;
+ }
if (Pat.SortOuter != SortSectionPolicy::None) {
if (Pat.SortInner == SortSectionPolicy::Default)
sortSections(Begin, End, Config->SortSection);
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=310045&r1=310044&r2=310045&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Aug 4 03:25:29 2017
@@ -184,6 +184,20 @@ static bool canMergeToProgbits(unsigned
Type == SHT_NOTE;
}
+void elf::sortByOrder(MutableArrayRef<InputSection *> In,
+ std::function<int(InputSectionBase *S)> Order) {
+ typedef std::pair<int, InputSection *> Pair;
+ auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; };
+
+ std::vector<Pair> V;
+ for (InputSection *S : In)
+ V.push_back({Order(S), S});
+ std::stable_sort(V.begin(), V.end(), Comp);
+
+ for (size_t I = 0; I < V.size(); ++I)
+ In[I] = V[I].second;
+}
+
void elf::reportDiscarded(InputSectionBase *IS) {
if (!Config->PrintGcSections)
return;
@@ -291,18 +305,8 @@ bool OutputSection::classof(const BaseCo
}
void OutputSection::sort(std::function<int(InputSectionBase *S)> Order) {
- typedef std::pair<int, InputSection *> Pair;
- auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; };
-
- std::vector<Pair> V;
assert(Commands.size() == 1);
- auto *ISD = cast<InputSectionDescription>(Commands[0]);
- for (InputSection *S : ISD->Sections)
- V.push_back({Order(S), S});
- std::stable_sort(V.begin(), V.end(), Comp);
- ISD->Sections.clear();
- for (Pair &P : V)
- ISD->Sections.push_back(P.second);
+ sortByOrder(cast<InputSectionDescription>(Commands[0])->Sections, Order);
}
// Fill [Buf, Buf + Size) with Filler.
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=310045&r1=310044&r2=310045&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Aug 4 03:25:29 2017
@@ -170,6 +170,8 @@ private:
uint64_t getHeaderSize();
void reportDiscarded(InputSectionBase *IS);
+void sortByOrder(llvm::MutableArrayRef<InputSection *> In,
+ std::function<int(InputSectionBase *S)> Order);
extern std::vector<OutputSection *> OutputSections;
} // namespace elf
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=310045&r1=310044&r2=310045&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Aug 4 03:25:29 2017
@@ -872,27 +872,8 @@ template <class ELFT> static void sortBy
if (Config->SymbolOrderingFile.empty())
return;
- // 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<SectionBase *, int> SectionOrder;
- for (ObjFile<ELFT> *File : ObjFile<ELFT>::Instances) {
- for (SymbolBody *Body : File->getSymbols()) {
- auto *D = dyn_cast<DefinedRegular>(Body);
- if (!D || !D->Section)
- continue;
- int &Priority = SectionOrder[D->Section];
- Priority = std::min(Priority, SymbolOrder.lookup(D->getName()));
- }
- }
-
// Sort sections by priority.
+ DenseMap<SectionBase *, int> SectionOrder = buildSectionOrder<ELFT>();
for (BaseCommand *Base : Script->Opt.Commands)
if (auto *Sec = dyn_cast<OutputSection>(Base))
Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); });
Added: lld/trunk/test/ELF/linkerscript/symbol-ordering-file.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/symbol-ordering-file.s?rev=310045&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/symbol-ordering-file.s (added)
+++ lld/trunk/test/ELF/linkerscript/symbol-ordering-file.s Fri Aug 4 03:25:29 2017
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "SECTIONS { .foo : { *(.foo) } }" > %t.script
+
+# RUN: ld.lld %t.o --script %t.script -o %t.out
+# RUN: llvm-objdump -s %t.out| FileCheck %s --check-prefix=BEFORE
+# BEFORE: Contents of section .foo:
+# BEFORE-NEXT: 1122
+
+# RUN: echo "_foo2" > %t.ord
+# RUN: echo "_foo1" >> %t.ord
+# RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t.script -o %t2.out
+# RUN: llvm-objdump -s %t2.out| FileCheck %s --check-prefix=AFTER
+# AFTER: Contents of section .foo:
+# AFTER-NEXT: 2211
+
+.section .foo,"ax", at progbits,unique,1
+_foo1:
+ .byte 0x11
+
+.section .foo,"ax", at progbits,unique,2
+_foo2:
+ .byte 0x22
More information about the llvm-commits
mailing list