aboutsummaryrefslogtreecommitdiff
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
commit00d845f77b82ed67ee23e0e265066fd1480527fd (patch)
treed9ef824bb8c8e18c4d3355e99d30354323a0f2f1
parent2cfa2ff84ac8faa091d3ca042f2beea2f53b58ff (diff)
downloadlld-00d845f77b82ed67ee23e0e265066fd1480527fd.tar.gz
[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 git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@353849 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--ELF/Arch/PPC64.cpp10
-rw-r--r--ELF/InputFiles.h17
-rw-r--r--ELF/Relocations.cpp12
-rw-r--r--ELF/Target.h4
-rw-r--r--ELF/Writer.cpp4
5 files changed, 27 insertions, 20 deletions
diff --git a/ELF/Arch/PPC64.cpp b/ELF/Arch/PPC64.cpp
index c40c97878..4f5aa45aa 100644
--- a/ELF/Arch/PPC64.cpp
+++ b/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/ELF/InputFiles.h b/ELF/InputFiles.h
index 07f85e89b..105e5ecbd 100644
--- a/ELF/InputFiles.h
+++ b/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/ELF/Relocations.cpp b/ELF/Relocations.cpp
index 70aa7ba55..7de2c05ff 100644
--- a/ELF/Relocations.cpp
+++ b/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/ELF/Target.h b/ELF/Target.h
index 9f26f132e..c7d29b63b 100644
--- a/ELF/Target.h
+++ b/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/ELF/Writer.cpp b/ELF/Writer.cpp
index 6465a619d..bdc7235b6 100644
--- a/ELF/Writer.cpp
+++ b/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;
}