Index: ELF/Writer.cpp
===================================================================
--- ELF/Writer.cpp
+++ ELF/Writer.cpp
@@ -13,6 +13,7 @@
 #include "SymbolTable.h"
 #include "Target.h"
 
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/FileOutputBuffer.h"
 
 using namespace llvm;
@@ -300,6 +301,22 @@
   }
 }
 
+// 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,
@@ -341,7 +358,10 @@
   // 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.
Index: test/elf2/basic64be.s
===================================================================
--- test/elf2/basic64be.s
+++ 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 @@
 # 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: 3
 # 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 @@
 # 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 @@
 # 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 @@
 # 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 @@
 # 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 @@
 # 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
@@ -163,42 +211,43 @@
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 # CHECK-NEXT: ProgramHeaders [
-# CHECK-NEXT:  ProgramHeader {
-# CHECK-NEXT:    Type: PT_LOAD (0x1)
-# CHECK-NEXT:    Offset: 0x0
-# CHECK-NEXT:    VirtualAddress: 0x10000000
-# CHECK-NEXT:    PhysicalAddress: 0x10000000
-# CHECK-NEXT:    FileSize: 232
-# CHECK-NEXT:    MemSize: 232
-# CHECK-NEXT:    Flags [
-# CHECK-NEXT:      PF_R
-# CHECK-NEXT:    ]
-# CHECK-NEXT:    Alignment: 65536
-# CHECK-NEXT:  }
-# CHECK-NEXT:  ProgramHeader {
-# CHECK-NEXT:    Type: PT_LOAD (0x1)
-# CHECK-NEXT:    Offset: 0x1000
-# CHECK-NEXT:    VirtualAddress: 0x10010000
-# CHECK-NEXT:    PhysicalAddress: 0x10010000
-# CHECK-NEXT:    FileSize: 12
-# CHECK-NEXT:    MemSize: 12
-# CHECK-NEXT:    Flags [ (0x5)
-# CHECK-NEXT:      PF_R (0x4)
-# CHECK-NEXT:      PF_X (0x1)
-# CHECK-NEXT:    ]
-# CHECK-NEXT:    Alignment: 65536
-# CHECK-NEXT:  }
-# CHECK-NEXT:  ProgramHeader {
-# CHECK-NEXT:    Type: PT_LOAD (0x1)
-# CHECK-NEXT:    Offset: 0x2000
-# CHECK-NEXT:    VirtualAddress: 0x10020000
-# CHECK-NEXT:    PhysicalAddress: 0x10020000
-# CHECK-NEXT:    FileSize: 24
-# CHECK-NEXT:    MemSize: 24
-# CHECK-NEXT:    Flags [ (0x6)
-# CHECK-NEXT:      PF_R (0x4)
-# CHECK-NEXT:      PF_W (0x2)
-# CHECK-NEXT:    ]
-# CHECK-NEXT:    Alignment: 65536
-# CHECK-NEXT:  }
-# CHECK-NEXT:]
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD (0x1)
+# CHECK-NEXT:     Offset: 0x0
+# CHECK-NEXT:     VirtualAddress: 0x10000000
+# CHECK-NEXT:     PhysicalAddress: 0x10000000
+# CHECK-NEXT:     FileSize: 232
+# CHECK-NEXT:     MemSize: 232
+# CHECK-NEXT:     Flags [ (0x4)
+# CHECK-NEXT:       PF_R (0x4)
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 65536
+# CHECK-NEXT:   }
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD (0x1)
+# CHECK-NEXT:     Offset: 0x10000
+# CHECK-NEXT:     VirtualAddress: 0x10010000
+# CHECK-NEXT:     PhysicalAddress: 0x10010000
+# CHECK-NEXT:     FileSize: 12
+# CHECK-NEXT:     MemSize: 12
+# CHECK-NEXT:     Flags [ (0x5)
+# CHECK-NEXT:       PF_R (0x4)
+# CHECK-NEXT:       PF_X (0x1)
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 65536
+# CHECK-NEXT:   }
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD (0x1)
+# CHECK-NEXT:     Offset: 0x20000
+# CHECK-NEXT:     VirtualAddress: 0x10020000
+# CHECK-NEXT:     PhysicalAddress: 0x10020000
+# CHECK-NEXT:     FileSize: 88
+# CHECK-NEXT:     MemSize: 88
+# CHECK-NEXT:     Flags [ (0x6)
+# CHECK-NEXT:       PF_R (0x4)
+# CHECK-NEXT:       PF_W (0x2)
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 65536
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+