diff options
-rw-r--r-- | lld/ELF/Writer.cpp | 22 | ||||
-rw-r--r-- | lld/test/elf2/basic64be.s | 104 |
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) |