diff options
Diffstat (limited to 'lld/ELF')
| -rw-r--r-- | lld/ELF/Config.h | 1 | ||||
| -rw-r--r-- | lld/ELF/Driver.cpp | 1 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 21 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.h | 3 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 5 |
5 files changed, 26 insertions, 5 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index fd7dbc2239b..ade684c1c17 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -88,6 +88,7 @@ struct Configuration { bool Verbose; bool VersionScript = false; bool WarnCommon; + bool ZCombreloc; bool ZExecStack; bool ZNodelete; bool ZNow; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 9a6be7dc988..f23db3d5fcc 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -352,6 +352,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { if (Config->LtoJobs == 0) error("number of threads must be > 0"); + Config->ZCombreloc = !hasZOption(Args, "nocombreloc"); Config->ZExecStack = hasZOption(Args, "execstack"); Config->ZNodelete = hasZOption(Args, "nodelete"); Config->ZNow = hasZOption(Args, "now"); diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 9a44339a5c1..676eb8029ef 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -301,9 +301,10 @@ template <class ELFT> void PltSection<ELFT>::finalize() { } template <class ELFT> -RelocationSection<ELFT>::RelocationSection(StringRef Name) +RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort) : OutputSectionBase<ELFT>(Name, Config->Rela ? SHT_RELA : SHT_REL, - SHF_ALLOC) { + SHF_ALLOC), + Sort(Sort) { this->Header.sh_entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); this->Header.sh_addralign = sizeof(uintX_t); } @@ -313,7 +314,13 @@ void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) { Relocs.push_back(Reloc); } +template <class ELFT, class RelTy> +static bool compRelocations(const RelTy &A, const RelTy &B) { + return A.getSymbol(Config->Mips64EL) < B.getSymbol(Config->Mips64EL); +} + template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { + uint8_t *BufBegin = Buf; for (const DynamicReloc<ELFT> &Rel : Relocs) { auto *P = reinterpret_cast<Elf_Rela *>(Buf); Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); @@ -325,6 +332,16 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { uint32_t SymIdx = (!Rel.UseSymVA && Sym) ? Sym->DynsymIndex : 0; P->setSymbolAndType(SymIdx, Rel.Type, Config->Mips64EL); } + + if (Sort) { + if (Config->Rela) + std::stable_sort((Elf_Rela *)BufBegin, + (Elf_Rela *)BufBegin + Relocs.size(), + compRelocations<ELFT, Elf_Rela>); + else + std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(), + compRelocations<ELFT, Elf_Rel>); + } } template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() { diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index d8c0e5b7484..b94f76588e6 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -274,7 +274,7 @@ class RelocationSection final : public OutputSectionBase<ELFT> { typedef typename ELFT::uint uintX_t; public: - RelocationSection(StringRef Name); + RelocationSection(StringRef Name, bool Sort); void addReloc(const DynamicReloc<ELFT> &Reloc); unsigned getRelocOffset(); void finalize() override; @@ -284,6 +284,7 @@ public: bool Static = false; private: + bool Sort; std::vector<DynamicReloc<ELFT>> Relocs; }; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index c568d7144e7..4c9be04e42a 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -129,7 +129,8 @@ template <class ELFT> void elf::writeResult(SymbolTable<ELFT> *Symtab) { GotSection<ELFT> Got; InterpSection<ELFT> Interp; PltSection<ELFT> Plt; - RelocationSection<ELFT> RelaDyn(Config->Rela ? ".rela.dyn" : ".rel.dyn"); + RelocationSection<ELFT> RelaDyn(Config->Rela ? ".rela.dyn" : ".rel.dyn", + Config->ZCombreloc); StringTableSection<ELFT> DynStrTab(".dynstr", true); StringTableSection<ELFT> ShStrTab(".shstrtab", false); SymbolTableSection<ELFT> DynSymTab(*Symtab, DynStrTab); @@ -165,7 +166,7 @@ template <class ELFT> void elf::writeResult(SymbolTable<ELFT> *Symtab) { if (Target->UseLazyBinding) { StringRef S = Config->Rela ? ".rela.plt" : ".rel.plt"; GotPlt.reset(new GotPltSection<ELFT>); - RelaPlt.reset(new RelocationSection<ELFT>(S)); + RelaPlt.reset(new RelocationSection<ELFT>(S, false /*Sort*/)); } if (!Config->StripAll) { StrTab.reset(new StringTableSection<ELFT>(".strtab", false)); |

