diff options
-rw-r--r-- | lld/ELF/Arch/PPC64.cpp | 10 | ||||
-rw-r--r-- | lld/ELF/InputFiles.h | 17 | ||||
-rw-r--r-- | lld/ELF/Relocations.cpp | 12 | ||||
-rw-r--r-- | lld/ELF/Target.h | 4 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 4 |
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; } |