summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Fertile <sfertile@ca.ibm.com>2019-02-12 15:35:49 +0000
committerSean Fertile <sfertile@ca.ibm.com>2019-02-12 15:35:49 +0000
commitd694160e665eb3cefc93a07af8232aec0b7d2410 (patch)
tree67f22df3db4d2681b33dc6163f484f9097c8023b
parenta1805540205b9852117fa54716a54940c2af465d (diff)
downloadbcm5719-llvm-d694160e665eb3cefc93a07af8232aec0b7d2410.tar.gz
bcm5719-llvm-d694160e665eb3cefc93a07af8232aec0b7d2410.zip
[PPC64] Sort .toc sections accessed with small code model relocs.
A follow up to the intial patch that unblocked linking against libgcc. For lld we don't need to bother tracking which objects have got based small code model relocations. This is due to the fact that the compilers on powerpc64 use the .toc section to generate indirections to symbols (rather then using got relocations) which keeps the got small. This makes overflowing a small code model got relocation very unlikely. Differential Revision: https://reviews.llvm.org/D57245 llvm-svn: 353849
-rw-r--r--lld/ELF/Arch/PPC64.cpp10
-rw-r--r--lld/ELF/InputFiles.h17
-rw-r--r--lld/ELF/Relocations.cpp12
-rw-r--r--lld/ELF/Target.h4
-rw-r--r--lld/ELF/Writer.cpp4
5 files changed, 27 insertions, 20 deletions
diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index c40c9787896..4f5aa45aac6 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -98,13 +98,9 @@ unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther) {
return 0;
}
-bool elf::isPPC64SmallCodeModelReloc(RelType Type) {
- // List is not yet complete, at the very least the got based tls related
- // relocations need to be added, and we need to determine how the section
- // sorting interacts with the thread pointer and dynamic thread pointer
- // relative tls relocations.
- return Type == R_PPC64_GOT16 || Type == R_PPC64_TOC16 ||
- Type == R_PPC64_TOC16_DS;
+bool elf::isPPC64SmallCodeModelTocReloc(RelType Type) {
+ // The only small code model relocations that access the .toc section.
+ return Type == R_PPC64_TOC16 || Type == R_PPC64_TOC16_DS;
}
namespace {
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 07f85e89b7b..105e5ecbdd3 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -114,14 +114,15 @@ public:
bool JustSymbols = false;
// On PPC64 we need to keep track of which files contain small code model
- // relocations. To minimize the chance of a relocation overflow files that do
- // contain small code model relocations should have their .toc sections sorted
- // closer to the .got section than files that do not contain any small code
- // model relocations. Thats because the toc-pointer is defined to point at
- // .got + 0x8000 and the instructions used with small code model relocations
- // support immediates in the range [-0x8000, 0x7FFC], making the addressable
- // range relative to the toc pointer [.got, .got + 0xFFFC].
- bool PPC64SmallCodeModelRelocs = false;
+ // relocations that access the .toc section. To minimize the chance of a
+ // relocation overflow, files that do contain said relocations should have
+ // their .toc sections sorted closer to the .got section than files that do
+ // not contain any small code model relocations. Thats because the toc-pointer
+ // is defined to point at .got + 0x8000 and the instructions used with small
+ // code model relocations support immediates in the range [-0x8000, 0x7FFC],
+ // making the addressable range relative to the toc pointer
+ // [.got, .got + 0xFFFC].
+ bool PPC64SmallCodeModelTocRelocs = false;
// GroupId is used for --warn-backrefs which is an optional error
// checking feature. All files within the same --{start,end}-group or
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 70aa7ba5594..7de2c05ffc6 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1000,8 +1000,16 @@ static void scanReloc(InputSectionBase &Sec, OffsetGetter &GetOffset, RelTy *&I,
if (isRelExprOneOf<R_HINT, R_NONE>(Expr))
return;
- if (Config->EMachine == EM_PPC64 && isPPC64SmallCodeModelReloc(Type))
- Sec.File->PPC64SmallCodeModelRelocs = true;
+ // We can separate the small code model relocations into 2 categories:
+ // 1) Those that access the compiler generated .toc sections.
+ // 2) Those that access the linker allocated got entries.
+ // lld allocates got entries to symbols on demand. Since we don't try to sort
+ // the got entries in any way, we don't have to track which objects have
+ // got-based small code model relocs. The .toc sections get placed after the
+ // end of the linker allocated .got section and we do sort those so sections
+ // addressed with small code model relocations come first.
+ if (Config->EMachine == EM_PPC64 && isPPC64SmallCodeModelTocReloc(Type))
+ Sec.File->PPC64SmallCodeModelTocRelocs = true;
// Strengthen or relax relocations.
//
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 9f26f132e89..c7d29b63b47 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -176,7 +176,9 @@ static inline std::string getErrorLocation(const uint8_t *Loc) {
// to the local entry-point.
unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t StOther);
-bool isPPC64SmallCodeModelReloc(RelType Type);
+// Returns true if a relocation is a small code model relocation that accesses
+// the .toc section.
+bool isPPC64SmallCodeModelTocReloc(RelType Type);
uint64_t getPPC64TocBase();
uint64_t getAArch64Page(uint64_t Expr);
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 6465a619d06..bdc7235b6df 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1262,8 +1262,8 @@ static void sortSection(OutputSection *Sec,
auto *ISD = cast<InputSectionDescription>(Sec->SectionCommands[0]);
std::stable_sort(ISD->Sections.begin(), ISD->Sections.end(),
[](const InputSection *A, const InputSection *B) -> bool {
- return A->File->PPC64SmallCodeModelRelocs &&
- !B->File->PPC64SmallCodeModelRelocs;
+ return A->File->PPC64SmallCodeModelTocRelocs &&
+ !B->File->PPC64SmallCodeModelTocRelocs;
});
return;
}
OpenPOWER on IntegriCloud