summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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