[lld] r250100 - [ELF2] Sort PPC64 special sections

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 12 13:51:49 PDT 2015


Author: hfinkel
Date: Mon Oct 12 15:51:48 2015
New Revision: 250100

URL: http://llvm.org/viewvc/llvm-project?rev=250100&view=rev
Log:
[ELF2] Sort PPC64 special sections

PPC64 has several special sections that are intended to be accessed from the
TOC base pointer. When a .got is present, the TOC base pointer is .got + 0x8000
(as specified by the ABI). Furthermore, the glibc startup code contains an
assumption that a 16-bit relocation can hold the offset from the TOC base value
to the beginning of the .toc section. Thus, we need to make sure that .toc
appears after .got. This much, at least, is required in practice. The other
PPC64 special sections (.toc, .toc1, .opd, etc.) should also be close by to
optimize access by smaller TOC-base-pointer offsets.

Modified:
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/basic64be.s

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=250100&r1=250099&r2=250100&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Oct 12 15:51:48 2015
@@ -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>:
   }
 }
 
+// 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(Output
   // 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.

Modified: lld/trunk/test/elf2/basic64be.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic64be.s?rev=250100&r1=250099&r2=250100&view=diff
==============================================================================
--- lld/trunk/test/elf2/basic64be.s (original)
+++ lld/trunk/test/elf2/basic64be.s Mon Oct 12 15:51:48 2015
@@ -9,6 +9,14 @@
 _start:
 .quad   .Lfoo,.TOC. at 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)




More information about the llvm-commits mailing list