Index: ELF/Arch/PPC64.cpp =================================================================== --- ELF/Arch/PPC64.cpp +++ ELF/Arch/PPC64.cpp @@ -98,13 +98,9 @@ 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 { Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ ELF/InputFiles.h @@ -114,14 +114,15 @@ 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 Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -1000,8 +1000,16 @@ if (isRelExprOneOf(Expr)) return; - if (Config->EMachine == EM_PPC64 && isPPC64SmallCodeModelReloc(Type)) - Sec.File->PPC64SmallCodeModelRelocs = true; + // In regards to the .toc section sorting (to avoid small code model + // relocation overflows) we need only to identify those small code model + // relocations that will access the .toc section. The got based small code + // model relocations inform the linker to create a got entry (or entries) and + // fill in the instructions with the offset from the toc pointer to said got + // entry. Since they access the .got instead of the .toc, and we don't try to + // sort .got entries based on code model, we can ignore the got based + // relocations. + if (Config->EMachine == EM_PPC64 && isPPC64SmallCodeModelTocReloc(Type)) + Sec.File->PPC64SmallCodeModelTocRelocs = true; // Strenghten or relax relocations. // Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -176,7 +176,9 @@ // 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); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1262,8 +1262,8 @@ auto *ISD = cast(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; }