summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Writer.cpp32
-rw-r--r--lld/test/elf2/output-section.s34
2 files changed, 49 insertions, 17 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 553938ac386..831af1fa910 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -184,11 +184,6 @@ private:
StringTableSection<ELFT::Is64Bits> StringTable;
SymbolTableSection<ELFT> SymTable;
-
- void addOutputSection(OutputSectionBase<ELFT::Is64Bits> *Sec) {
- OutputSections.push_back(Sec);
- Sec->setSectionIndex(OutputSections.size());
- }
};
} // anonymous namespace
@@ -428,6 +423,13 @@ static bool cmpAlign(const DefinedCommon<ELFT> *A,
return A->MaxAlignment > B->MaxAlignment;
}
+template <bool Is64Bits>
+static bool compSec(OutputSectionBase<Is64Bits> *A,
+ OutputSectionBase<Is64Bits> *B) {
+ // Place SHF_ALLOC sections first.
+ return (A->getFlags() & SHF_ALLOC) && !(B->getFlags() & SHF_ALLOC);
+}
+
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::createSections() {
SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSection<ELFT> *> Map;
@@ -438,7 +440,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
if (!Sec) {
Sec = new (CAlloc.Allocate())
OutputSection<ELFT>(Key.Name, Key.sh_type, Key.sh_flags);
- addOutputSection(Sec);
+ OutputSections.push_back(Sec);
}
return Sec;
};
@@ -485,13 +487,14 @@ template <class ELFT> void Writer<ELFT>::createSections() {
}
BSSSec->setSize(Off);
-}
-template <bool Is64Bits>
-static bool compSec(OutputSectionBase<Is64Bits> *A,
- OutputSectionBase<Is64Bits> *B) {
- // Place SHF_ALLOC sections first.
- return (A->getFlags() & SHF_ALLOC) && !(B->getFlags() & SHF_ALLOC);
+ OutputSections.push_back(&SymTable);
+ OutputSections.push_back(&StringTable);
+
+ std::stable_sort(OutputSections.begin(), OutputSections.end(),
+ compSec<ELFT::Is64Bits>);
+ for (unsigned I = 0, N = OutputSections.size(); I < N; ++I)
+ OutputSections[I]->setSectionIndex(I + 1);
}
// Visits all sections to assign incremental, non-overlapping RVAs and
@@ -501,11 +504,6 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
uintX_t VA = 0x1000; // The first page is kept unmapped.
uintX_t FileOff = SizeOfHeaders;
- std::stable_sort(OutputSections.begin(), OutputSections.end(),
- compSec<ELFT::Is64Bits>);
-
- addOutputSection(&SymTable);
- addOutputSection(&StringTable);
StringTableIndex = OutputSections.size();
SymTable.setStringTableIndex(StringTableIndex);
diff --git a/lld/test/elf2/output-section.s b/lld/test/elf2/output-section.s
new file mode 100644
index 00000000000..62eb747770c
--- /dev/null
+++ b/lld/test/elf2/output-section.s
@@ -0,0 +1,34 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+// RUN: lld -flavor gnu2 %t -o %t2
+// RUN: llvm-readobj -t %t2 | FileCheck %s
+// REQUIRES: x86
+
+// CHECK: Symbol {
+// CHECK: Name: bar_sym
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding:
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section: bar
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo_sym
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding:
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section: foo
+// CHECK-NEXT: }
+
+.section foo
+.global foo_sym
+foo_sym:
+
+.section bar, "a"
+.global bar_sym
+bar_sym:
+
+.global _start
+_start:
OpenPOWER on IntegriCloud