summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Writer.cpp22
-rw-r--r--lld/test/elf2/basic64be.s104
2 files changed, 97 insertions, 29 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 97c8bca0c0e..452fb30aed5 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -14,6 +14,7 @@
#include "Target.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/FileOutputBuffer.h"
using namespace llvm;
@@ -261,6 +262,22 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
}
}
+// PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections that
+// we would like to make sure appear is a specific order to maximize their
+// coverage by a single signed 16-bit offset from the TOC base pointer.
+// Conversely, the special .tocbss section should be first among all SHT_NOBITS
+// sections. This will put it next to the loaded special PPC64 sections (and,
+// thus, within reach of the TOC base pointer).
+static int getPPC64SectionRank(StringRef SectionName) {
+ return StringSwitch<int>(SectionName)
+ .Case(".tocbss", 0)
+ .Case(".branch_lt", 2)
+ .Case(".toc", 3)
+ .Case(".toc1", 4)
+ .Case(".opd", 5)
+ .Default(1);
+}
+
// Output section ordering is determined by this function.
template <class ELFT>
static bool compareOutputSections(OutputSectionBase<ELFT::Is64Bits> *A,
@@ -302,7 +319,10 @@ static bool compareOutputSections(OutputSectionBase<ELFT::Is64Bits> *A,
// them is a p_memsz that is larger than p_filesz. Seeing that it
// zeros the end of the PT_LOAD, so that has to correspond to the
// nobits sections.
- return A->getType() != SHT_NOBITS && B->getType() == SHT_NOBITS;
+ if (A->getType() != SHT_NOBITS && B->getType() == SHT_NOBITS)
+ return true;
+
+ return getPPC64SectionRank(A->getName()) < getPPC64SectionRank(B->getName());
}
// Until this function is called, common symbols do not belong to any section.
diff --git a/lld/test/elf2/basic64be.s b/lld/test/elf2/basic64be.s
index 392ed5dd1aa..4f1b451f764 100644
--- a/lld/test/elf2/basic64be.s
+++ b/lld/test/elf2/basic64be.s
@@ -9,6 +9,14 @@
_start:
.quad .Lfoo,.TOC.@tocbase,0
+# generate .toc and .toc1 sections to make sure that the ordering is as
+# intended (.toc before .toc1, and both before .opd).
+.section ".toc1","aw"
+.quad 22, 37, 89, 47
+
+.section ".toc","aw"
+.quad 45, 86, 72, 24
+
.text
.Lfoo:
li 0,1
@@ -28,17 +36,17 @@ _start:
# CHECK-NEXT: Type: Executable (0x2)
# CHECK-NEXT: Machine: EM_PPC64 (0x15)
# CHECK-NEXT: Version: 1
-# CHECK-NEXT: Entry: 0x10020000
+# CHECK-NEXT: Entry: 0x10020040
# CHECK-NEXT: ProgramHeaderOffset: 0x40
-# CHECK-NEXT: SectionHeaderOffset: 0x20078
+# CHECK-NEXT: SectionHeaderOffset: 0x200C8
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: HeaderSize: 64
# CHECK-NEXT: ProgramHeaderEntrySize: 56
# CHECK-NEXT: ProgramHeaderCount: 4
# CHECK-NEXT: SectionHeaderEntrySize: 64
-# CHECK-NEXT: SectionHeaderCount: 7
-# CHECK-NEXT: StringTableSectionIndex: 6
+# CHECK-NEXT: SectionHeaderCount: 9
+# CHECK-NEXT: StringTableSectionIndex: 8
# CHECK-NEXT: }
# CHECK-NEXT: Sections [
# CHECK-NEXT: Section {
@@ -55,18 +63,18 @@ _start:
# CHECK-NEXT: AddressAlignment: 0
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
-# CHECK: )
+# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 1
-# CHECK-NEXT: Name: .text
+# CHECK-NEXT: Name: .text (1)
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x6)
# CHECK-NEXT: SHF_ALLOC (0x2)
# CHECK-NEXT: SHF_EXECINSTR (0x4)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x10010000
-# CHECK-NEXT: Offset: 0x1000
+# CHECK-NEXT: Offset: 0x10000
# CHECK-NEXT: Size: 12
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
@@ -77,7 +85,7 @@ _start:
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 2
-# CHECK-NEXT: Name: .data
+# CHECK-NEXT: Name: .data (45)
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x3)
# CHECK-NEXT: SHF_ALLOC (0x2)
@@ -95,34 +103,74 @@ _start:
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 3
-# CHECK-NEXT: Name: .opd
+# CHECK-NEXT: Name: .toc (24)
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x3)
# CHECK-NEXT: SHF_ALLOC (0x2)
# CHECK-NEXT: SHF_WRITE (0x1)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x10020000
-# CHECK-NEXT: Offset: 0x2000
-# CHECK-NEXT: Size: 24
+# CHECK-NEXT: Offset: 0x20000
+# CHECK-NEXT: Size: 32
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
-# CHECK-NEXT: 0000: 00000000 10010000 00000000 00000000 |................|
-# CHECK-NEXT: 0010: 00000000 00000000 |........|
+# CHECK-NEXT: 0000: 00000000 0000002D 00000000 00000056 |.......-.......V|
+# CHECK-NEXT: 0010: 00000000 00000048 00000000 00000018 |.......H........|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 4
-# CHECK-NEXT: Name: .bss
+# CHECK-NEXT: Name: .toc1 (51)
+# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
+# CHECK-NEXT: Flags [ (0x3)
+# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: SHF_WRITE (0x1)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x10020020
+# CHECK-NEXT: Offset: 0x20020
+# CHECK-NEXT: Size: 32
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 1
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: SectionData (
+# CHECK-NEXT: 0000: 00000000 00000016 00000000 00000025 |...............%|
+# CHECK-NEXT: 0010: 00000000 00000059 00000000 0000002F |.......Y......./|
+# CHECK-NEXT: )
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 5
+# CHECK-NEXT: Name: .opd (19)
+# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
+# CHECK-NEXT: Flags [ (0x3)
+# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: SHF_WRITE (0x1)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x10020040
+# CHECK-NEXT: Offset: 0x20040
+# CHECK-NEXT: Size: 24
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 1
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: SectionData (
+# CHECK-NEXT: 0000: 00000000 10010000 00000000 00000000 |................|
+# CHECK-NEXT: 0010: 00000000 00000000 |........|
+# CHECK-NEXT: )
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 6
+# CHECK-NEXT: Name: .bss (14)
# CHECK-NEXT: Type: SHT_NOBITS (0x8)
# CHECK-NEXT: Flags [ (0x3)
# CHECK-NEXT: SHF_ALLOC (0x2)
# CHECK-NEXT: SHF_WRITE (0x1)
# CHECK-NEXT: ]
-# CHECK-NEXT: Address: 0x10020018
-# CHECK-NEXT: Offset: 0x20018
+# CHECK-NEXT: Address: 0x10020058
+# CHECK-NEXT: Offset: 0x20058
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
@@ -130,15 +178,15 @@ _start:
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 5
-# CHECK-NEXT: Name: .symtab
-# CHECK-NEXT: Type: SHT_SYMTAB
-# CHECK-NEXT: Flags [
+# CHECK-NEXT: Index: 7
+# CHECK-NEXT: Name: .symtab (37)
+# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
+# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
-# CHECK-NEXT: Offset: 0x20018
+# CHECK-NEXT: Offset: 0x20058
# CHECK-NEXT: Size: 48
-# CHECK-NEXT: Link: 6
+# CHECK-NEXT: Link: 8
# CHECK-NEXT: Info: 1
# CHECK-NEXT: AddressAlignment: 8
# CHECK-NEXT: EntrySize: 24
@@ -146,14 +194,14 @@ _start:
# CHECK: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
-# CHECK-NEXT: Index: 6
-# CHECK-NEXT: Name: .strtab
+# CHECK-NEXT: Index: 8
+# CHECK-NEXT: Name: .strtab (29)
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
-# CHECK-NEXT: Offset: 0x20048
-# CHECK-NEXT: Size: 46
+# CHECK-NEXT: Offset: 0x20088
+# CHECK-NEXT: Size: 57
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
@@ -205,8 +253,8 @@ _start:
# CHECK-NEXT: Offset: 0x2000
# CHECK-NEXT: VirtualAddress: 0x10020000
# CHECK-NEXT: PhysicalAddress: 0x10020000
-# CHECK-NEXT: FileSize: 24
-# CHECK-NEXT: MemSize: 24
+# CHECK-NEXT: FileSize: 88
+# CHECK-NEXT: MemSize: 88
# CHECK-NEXT: Flags [ (0x6)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: PF_W (0x2)
OpenPOWER on IntegriCloud