Index: lld/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -104,8 +104,12 @@ typename ELFT::uint InputSectionBase::getOffset(uintX_t Offset) const { switch (kind()) { case Regular: - case Synthetic: return cast>(this)->OutSecOff + Offset; + case Synthetic: + // For synthetic sections we treat offset -1 as the end of the section. + // The same approach is used for synthetic symbols (DefinedSynthetic). + return cast>(this)->OutSecOff + + (Offset == uintX_t(-1) ? getSize() : Offset); case EHFrame: // The file crtbeginT.o has relocations pointing to the start of an empty // .eh_frame that is known to be the first in the link. It does that to @@ -525,6 +529,11 @@ if (this->Type == SHT_NOBITS) return; + if (auto *S = dyn_cast>(this)) { + S->writeTo(Buf); + return; + } + // If -r is given, then an InputSection may be a relocation section. if (this->Type == SHT_RELA) { copyRelocations(Buf + OutSecOff, this->template getDataAs()); @@ -535,11 +544,6 @@ return; } - if (auto *S = dyn_cast>(this)) { - S->writeTo(Buf); - return; - } - // Copy section contents from source object file to output file. ArrayRef Data = this->Data; memcpy(Buf + OutSecOff, Data.data(), Data.size()); Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -52,7 +52,6 @@ Merge, Plt, Regular, - Reloc, SymTable, VersDef, VersNeed, @@ -156,39 +155,6 @@ std::vector> Entries; }; -template class DynamicReloc { - typedef typename ELFT::uint uintX_t; - -public: - DynamicReloc(uint32_t Type, const InputSectionBase *InputSec, - uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, - uintX_t Addend) - : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), - UseSymVA(UseSymVA), Addend(Addend) {} - - DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec, - uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, - uintX_t Addend) - : Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec), - UseSymVA(UseSymVA), Addend(Addend) {} - - uintX_t getOffset() const; - uintX_t getAddend() const; - uint32_t getSymIndex() const; - const OutputSectionBase *getOutputSec() const { return OutputSec; } - const InputSectionBase *getInputSec() const { return InputSec; } - - uint32_t Type; - -private: - SymbolBody *Sym; - const InputSectionBase *InputSec = nullptr; - const OutputSectionBase *OutputSec = nullptr; - uintX_t OffsetInSec; - bool UseSymVA; - uintX_t Addend; -}; - struct SymbolTableEntry { SymbolBody *Symbol; size_t StrTabOffset; @@ -305,30 +271,6 @@ } }; -template class RelocationSection final : public OutputSectionBase { - typedef typename ELFT::Rel Elf_Rel; - typedef typename ELFT::Rela Elf_Rela; - typedef typename ELFT::uint uintX_t; - -public: - RelocationSection(StringRef Name, bool Sort); - void addReloc(const DynamicReloc &Reloc); - unsigned getRelocOffset(); - void finalize() override; - void writeTo(uint8_t *Buf) override; - bool hasRelocs() const { return !Relocs.empty(); } - Kind getKind() const override { return Reloc; } - size_t getRelativeRelocCount() const { return NumRelativeRelocs; } - static bool classof(const OutputSectionBase *B) { - return B->getKind() == Reloc; - } - -private: - bool Sort; - size_t NumRelativeRelocs = 0; - std::vector> Relocs; -}; - template class OutputSection final : public OutputSectionBase { public: @@ -526,8 +468,6 @@ static OutputSectionBase *Opd; static uint8_t *OpdBuf; static PltSection *Plt; - static RelocationSection *RelaDyn; - static RelocationSection *RelaPlt; static SymbolTableSection *DynSymTab; static SymbolTableSection *SymTab; static VersionDefinitionSection *VerDef; @@ -586,8 +526,6 @@ template OutputSectionBase *Out::Opd; template uint8_t *Out::OpdBuf; template PltSection *Out::Plt; -template RelocationSection *Out::RelaDyn; -template RelocationSection *Out::RelaPlt; template SymbolTableSection *Out::DynSymTab; template SymbolTableSection *Out::SymTab; template VersionDefinitionSection *Out::VerDef; Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -132,7 +132,7 @@ template void PltSection::addEntry(SymbolBody &Sym) { Sym.PltIndex = Entries.size(); - unsigned RelOff = Out::RelaPlt->getRelocOffset(); + unsigned RelOff = In::RelaPlt->getRelocOffset(); Entries.push_back(std::make_pair(&Sym, RelOff)); } @@ -141,69 +141,6 @@ } template -RelocationSection::RelocationSection(StringRef Name, bool Sort) - : OutputSectionBase(Name, Config->Rela ? SHT_RELA : SHT_REL, SHF_ALLOC), - Sort(Sort) { - this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); - this->Addralign = sizeof(uintX_t); -} - -template -void RelocationSection::addReloc(const DynamicReloc &Reloc) { - if (Reloc.Type == Target->RelativeRel) - ++NumRelativeRelocs; - Relocs.push_back(Reloc); -} - -template -static bool compRelocations(const RelTy &A, const RelTy &B) { - bool AIsRel = A.getType(Config->Mips64EL) == Target->RelativeRel; - bool BIsRel = B.getType(Config->Mips64EL) == Target->RelativeRel; - if (AIsRel != BIsRel) - return AIsRel; - - return A.getSymbol(Config->Mips64EL) < B.getSymbol(Config->Mips64EL); -} - -template void RelocationSection::writeTo(uint8_t *Buf) { - uint8_t *BufBegin = Buf; - for (const DynamicReloc &Rel : Relocs) { - auto *P = reinterpret_cast(Buf); - Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); - - if (Config->Rela) - P->r_addend = Rel.getAddend(); - P->r_offset = Rel.getOffset(); - if (Config->EMachine == EM_MIPS && Rel.getInputSec() == In::Got) - // Dynamic relocation against MIPS GOT section make deal TLS entries - // allocated in the end of the GOT. We need to adjust the offset to take - // in account 'local' and 'global' GOT entries. - P->r_offset += In::Got->getMipsTlsOffset(); - P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->Mips64EL); - } - - if (Sort) { - if (Config->Rela) - std::stable_sort((Elf_Rela *)BufBegin, - (Elf_Rela *)BufBegin + Relocs.size(), - compRelocations); - else - std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(), - compRelocations); - } -} - -template unsigned RelocationSection::getRelocOffset() { - return this->Entsize * Relocs.size(); -} - -template void RelocationSection::finalize() { - this->Link = Out::DynSymTab ? Out::DynSymTab->SectionIndex - : Out::SymTab->SectionIndex; - this->Size = Relocs.size() * this->Entsize; -} - -template HashTableSection::HashTableSection() : OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) { this->Entsize = sizeof(Elf_Word); @@ -463,20 +400,21 @@ } template void OutputSection::finalize() { + if (!Config->Relocatable) { + // SHF_LINK_ORDER only has meaning in relocatable objects + this->Flags &= ~SHF_LINK_ORDER; + return; + } + uint32_t Type = this->Type; - if (this->Flags & SHF_LINK_ORDER) { - if (!Config->Relocatable) { - // SHF_LINK_ORDER only has meaning in relocatable objects - this->Flags &= ~SHF_LINK_ORDER; - } else if (!this->Sections.empty()) { - // When doing a relocatable link we must preserve the link order - // dependency of sections with the SHF_LINK_ORDER flag. The dependency - // is indicated by the sh_link field. We need to translate the - // InputSection sh_link to the OutputSection sh_link, all InputSections - // in the OutputSection have the same dependency. - if (auto *D = this->Sections.front()->getLinkOrderDep()) - this->Link = D->OutSec->SectionIndex; - } + if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) { + // When doing a relocatable link we must preserve the link order + // dependency of sections with the SHF_LINK_ORDER flag. The dependency + // is indicated by the sh_link field. We need to translate the + // InputSection sh_link to the OutputSection sh_link, all InputSections + // in the OutputSection have the same dependency. + if (auto *D = this->Sections.front()->getLinkOrderDep()) + this->Link = D->OutSec->SectionIndex; } if (Type != SHT_RELA && Type != SHT_REL) @@ -881,26 +819,6 @@ } template -typename ELFT::uint DynamicReloc::getOffset() const { - if (OutputSec) - return OutputSec->Addr + OffsetInSec; - return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec); -} - -template -typename ELFT::uint DynamicReloc::getAddend() const { - if (UseSymVA) - return Sym->getVA(Addend); - return Addend; -} - -template uint32_t DynamicReloc::getSymIndex() const { - if (Sym && !UseSymVA) - return Sym->DynsymIndex; - return 0; -} - -template SymbolTableSection::SymbolTableSection( StringTableSection &StrTabSec) : OutputSectionBase(StrTabSec.isDynamic() ? ".dynsym" : ".symtab", @@ -1350,11 +1268,6 @@ template class PltSection; template class PltSection; -template class RelocationSection; -template class RelocationSection; -template class RelocationSection; -template class RelocationSection; - template class GnuHashTableSection; template class GnuHashTableSection; template class GnuHashTableSection; Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -103,9 +103,9 @@ if (Expr == R_MIPS_TLSLD || Expr == R_TLSLD_PC) { if (In::Got->addTlsIndex() && (Config->Pic || Config->EMachine == EM_ARM)) - Out::RelaDyn->addReloc({Target->TlsModuleIndexRel, In::Got, - In::Got->getTlsIndexOff(), false, - nullptr, 0}); + In::RelaDyn->addReloc({Target->TlsModuleIndexRel, In::Got, + In::Got->getTlsIndexOff(), false, + nullptr, 0}); C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; } @@ -114,12 +114,12 @@ if (In::Got->addDynTlsEntry(Body) && (Body.isPreemptible() || Config->EMachine == EM_ARM)) { uintX_t Off = In::Got->getGlobalDynOffset(Body); - Out::RelaDyn->addReloc( + In::RelaDyn->addReloc( {Target->TlsModuleIndexRel, In::Got, Off, false, &Body, 0}); if (Body.isPreemptible()) - Out::RelaDyn->addReloc({Target->TlsOffsetRel, In::Got, - Off + (uintX_t)sizeof(uintX_t), false, - &Body, 0}); + In::RelaDyn->addReloc({Target->TlsOffsetRel, In::Got, + Off + (uintX_t)sizeof(uintX_t), false, + &Body, 0}); } C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; @@ -149,7 +149,7 @@ Config->Shared) { if (In::Got->addDynTlsEntry(Body)) { uintX_t Off = In::Got->getGlobalDynOffset(Body); - Out::RelaDyn->addReloc( + In::RelaDyn->addReloc( {Target->TlsDescRel, In::Got, Off, false, &Body, 0}); } if (Expr != R_TLSDESC_CALL) @@ -165,9 +165,9 @@ return 2; } if (In::Got->addTlsIndex()) - Out::RelaDyn->addReloc({Target->TlsModuleIndexRel, In::Got, - In::Got->getTlsIndexOff(), false, - nullptr, 0}); + In::RelaDyn->addReloc({Target->TlsModuleIndexRel, In::Got, + In::Got->getTlsIndexOff(), false, + nullptr, 0}); C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; } @@ -184,15 +184,15 @@ if (Config->Shared) { if (In::Got->addDynTlsEntry(Body)) { uintX_t Off = In::Got->getGlobalDynOffset(Body); - Out::RelaDyn->addReloc( + In::RelaDyn->addReloc( {Target->TlsModuleIndexRel, In::Got, Off, false, &Body, 0}); // If the symbol is preemptible we need the dynamic linker to write // the offset too. if (isPreemptible(Body, Type)) - Out::RelaDyn->addReloc({Target->TlsOffsetRel, In::Got, - Off + (uintX_t)sizeof(uintX_t), false, - &Body, 0}); + In::RelaDyn->addReloc({Target->TlsOffsetRel, In::Got, + Off + (uintX_t)sizeof(uintX_t), false, + &Body, 0}); } C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; @@ -206,9 +206,9 @@ Offset, Addend, &Body}); if (!Body.isInGot()) { In::Got->addEntry(Body); - Out::RelaDyn->addReloc({Target->TlsGotRel, In::Got, - Body.getGotOffset(), false, &Body, - 0}); + In::RelaDyn->addReloc({Target->TlsGotRel, In::Got, + Body.getGotOffset(), false, &Body, + 0}); } return Target->TlsGdRelaxSkip; } @@ -417,7 +417,7 @@ Alias->NeedsCopyOrPltAddr = true; Alias->symbol()->IsUsedInRegularObj = true; } - Out::RelaDyn->addReloc( + In::RelaDyn->addReloc( {Target->CopyRel, Out::Bss, SS->OffsetInBss, false, SS, 0}); } @@ -619,7 +619,7 @@ bool IsWrite = C.Flags & SHF_WRITE; auto AddDyn = [=](const DynamicReloc &Reloc) { - Out::RelaDyn->addReloc(Reloc); + In::RelaDyn->addReloc(Reloc); }; const elf::ObjectFile *File = C.getFile(); @@ -754,9 +754,9 @@ Rel = Target->PltRel; In::GotPlt->addEntry(Body); - Out::RelaPlt->addReloc({Rel, In::GotPlt, - Body.getGotPltOffset(), !Preemptible, - &Body, 0}); + In::RelaPlt->addReloc({Rel, In::GotPlt, + Body.getGotPltOffset(), !Preemptible, + &Body, 0}); continue; } Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -239,6 +239,39 @@ std::vector Strings; }; +template class DynamicReloc { + typedef typename ELFT::uint uintX_t; + +public: + DynamicReloc(uint32_t Type, const InputSectionBase *InputSec, + uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, + uintX_t Addend) + : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), + UseSymVA(UseSymVA), Addend(Addend) {} + + DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec, + uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, + uintX_t Addend) + : Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec), + UseSymVA(UseSymVA), Addend(Addend) {} + + uintX_t getOffset() const; + uintX_t getAddend() const; + uint32_t getSymIndex() const; + const OutputSectionBase *getOutputSec() const { return OutputSec; } + const InputSectionBase *getInputSec() const { return InputSec; } + + uint32_t Type; + +private: + SymbolBody *Sym; + const InputSectionBase *InputSec = nullptr; + const OutputSectionBase *OutputSec = nullptr; + uintX_t OffsetInSec; + bool UseSymVA; + uintX_t Addend; +}; + template class DynamicSection final : public SyntheticSection { typedef typename ELFT::Dyn Elf_Dyn; @@ -287,6 +320,28 @@ uintX_t Size = 0; }; +template +class RelocationSection final : public SyntheticSection { + typedef typename ELFT::Rel Elf_Rel; + typedef typename ELFT::Rela Elf_Rela; + typedef typename ELFT::uint uintX_t; + +public: + RelocationSection(StringRef Name, bool Sort); + void addReloc(const DynamicReloc &Reloc); + unsigned getRelocOffset(); + void finalize() override; + void writeTo(uint8_t *Buf) override; + size_t getSize() const override { return Relocs.size() * this->Entsize; } + bool hasRelocs() const { return !Relocs.empty(); } + size_t getRelativeRelocCount() const { return NumRelativeRelocs; } + +private: + bool Sort; + size_t NumRelativeRelocs = 0; + std::vector> Relocs; +}; + template InputSection *createCommonSection(); template InputSection *createInterpSection(); template MergeInputSection *createCommentSection(); @@ -303,6 +358,8 @@ static MipsAbiFlagsSection *MipsAbiFlags; static MipsOptionsSection *MipsOptions; static MipsReginfoSection *MipsReginfo; + static RelocationSection *RelaDyn; + static RelocationSection *RelaPlt; static StringTableSection *ShStrTab; static StringTableSection *StrTab; }; @@ -317,6 +374,8 @@ template MipsAbiFlagsSection *In::MipsAbiFlags; template MipsOptionsSection *In::MipsOptions; template MipsReginfoSection *In::MipsReginfo; +template RelocationSection *In::RelaDyn; +template RelocationSection *In::RelaPlt; template StringTableSection *In::ShStrTab; template StringTableSection *In::StrTab; } // namespace elf Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -737,10 +737,10 @@ this->Link = In::DynStrTab->OutSec->SectionIndex; - if (Out::RelaDyn->hasRelocs()) { + if (In::RelaDyn->hasRelocs()) { bool IsRela = Config->Rela; - Add({IsRela ? DT_RELA : DT_REL, Out::RelaDyn}); - Add({IsRela ? DT_RELASZ : DT_RELSZ, Out::RelaDyn->Size}); + Add({IsRela ? DT_RELA : DT_REL, In::RelaDyn}); + Add({IsRela ? DT_RELASZ : DT_RELSZ, In::RelaDyn->getSize()}); Add({IsRela ? DT_RELAENT : DT_RELENT, uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))}); @@ -748,14 +748,14 @@ // The problem is in the tight relation between dynamic // relocations and GOT. So do not emit this tag on MIPS. if (Config->EMachine != EM_MIPS) { - size_t NumRelativeRels = Out::RelaDyn->getRelativeRelocCount(); + size_t NumRelativeRels = In::RelaDyn->getRelativeRelocCount(); if (Config->ZCombreloc && NumRelativeRels) Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels}); } } - if (Out::RelaPlt && Out::RelaPlt->hasRelocs()) { - Add({DT_JMPREL, Out::RelaPlt}); - Add({DT_PLTRELSZ, Out::RelaPlt->Size}); + if (In::RelaPlt->hasRelocs()) { + Add({DT_JMPREL, In::RelaPlt}); + Add({DT_PLTRELSZ, In::RelaPlt->getSize()}); Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT, In::GotPlt}); Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)}); @@ -848,6 +848,92 @@ } } +template +typename ELFT::uint DynamicReloc::getOffset() const { + if (OutputSec) + return OutputSec->Addr + OffsetInSec; + return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec); +} + +template +typename ELFT::uint DynamicReloc::getAddend() const { + if (UseSymVA) + return Sym->getVA(Addend); + return Addend; +} + +template uint32_t DynamicReloc::getSymIndex() const { + if (Sym && !UseSymVA) + return Sym->DynsymIndex; + return 0; +} + +template +RelocationSection::RelocationSection(StringRef Name, bool Sort) + : SyntheticSection(SHF_ALLOC, Config->Rela ? SHT_RELA : SHT_REL, + sizeof(uintX_t), Name), + Sort(Sort) { + this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); +} + +template +void RelocationSection::addReloc(const DynamicReloc &Reloc) { + if (Reloc.Type == Target->RelativeRel) + ++NumRelativeRelocs; + Relocs.push_back(Reloc); +} + +template +static bool compRelocations(const RelTy &A, const RelTy &B) { + bool AIsRel = A.getType(Config->Mips64EL) == Target->RelativeRel; + bool BIsRel = B.getType(Config->Mips64EL) == Target->RelativeRel; + if (AIsRel != BIsRel) + return AIsRel; + + return A.getSymbol(Config->Mips64EL) < B.getSymbol(Config->Mips64EL); +} + +template void RelocationSection::writeTo(uint8_t *Buf) { + uint8_t *BufBegin = Buf; + for (const DynamicReloc &Rel : Relocs) { + auto *P = reinterpret_cast(Buf); + Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); + + if (Config->Rela) + P->r_addend = Rel.getAddend(); + P->r_offset = Rel.getOffset(); + if (Config->EMachine == EM_MIPS && Rel.getInputSec() == In::Got) + // Dynamic relocation against MIPS GOT section make deal TLS entries + // allocated in the end of the GOT. We need to adjust the offset to take + // in account 'local' and 'global' GOT entries. + P->r_offset += In::Got->getMipsTlsOffset(); + P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->Mips64EL); + } + + if (Sort) { + if (Config->Rela) + std::stable_sort((Elf_Rela *)BufBegin, + (Elf_Rela *)BufBegin + Relocs.size(), + compRelocations); + else + std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(), + compRelocations); + } +} + +template unsigned RelocationSection::getRelocOffset() { + return this->Entsize * Relocs.size(); +} + +template void RelocationSection::finalize() { + this->Link = Out::DynSymTab ? Out::DynSymTab->SectionIndex + : Out::SymTab->SectionIndex; + + // Set required output section properties. + this->OutSec->Link = this->Link; + this->OutSec->Entsize = this->Entsize; +} + template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); template InputSection *elf::createCommonSection(); @@ -927,3 +1013,8 @@ template class elf::DynamicSection; template class elf::DynamicSection; template class elf::DynamicSection; + +template class elf::RelocationSection; +template class elf::RelocationSection; +template class elf::RelocationSection; +template class elf::RelocationSection; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -213,7 +213,7 @@ In::Dynamic = make>(); Out::EhFrame = make>(); Out::Plt = make>(); - Out::RelaDyn = make>( + In::RelaDyn = make>( Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc); In::ShStrTab = make>(".shstrtab", false); Out::VerSym = make>(); @@ -245,7 +245,7 @@ if (Config->GdbIndex) Out::GdbIndex = make>(); - Out::RelaPlt = make>( + In::RelaPlt = make>( Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/); if (Config->Strip != StripPolicy::All) { In::StrTab = make>(".strtab", false); @@ -589,11 +589,10 @@ if (Out::DynSymTab) return; StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start"; - addOptionalSynthetic(S, Out::RelaPlt, 0); + addOptionalRegular(S, In::RelaPlt, 0); S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end"; - addOptionalSynthetic(S, Out::RelaPlt, - DefinedSynthetic::SectionEnd); + addOptionalRegular(S, In::RelaPlt, -1); } // The linker is expected to define some symbols depending on @@ -945,8 +944,10 @@ for (OutputSectionBase *Sec : OutputSections) Sec->finalize(); + // Dynamic section must be the last one in this list. finalizeSynthetic({In::ShStrTab, In::StrTab, In::DynStrTab, In::Got, In::GotPlt, + In::RelaDyn, In::RelaPlt, In::Dynamic}); // Now that all output offsets are fixed. Finalize mergeable sections @@ -997,15 +998,15 @@ Add(Out::HashTab); addInputSec(In::Dynamic); addInputSec(In::DynStrTab); - if (Out::RelaDyn->hasRelocs()) - Add(Out::RelaDyn); + if (In::RelaDyn->hasRelocs()) + addInputSec(In::RelaDyn); Add(Out::MipsRldMap); } // We always need to add rel[a].plt to output if it has entries. // Even during static linking it can contain R_[*]_IRELATIVE relocations. - if (Out::RelaPlt->hasRelocs()) - Add(Out::RelaPlt); + if (In::RelaPlt->hasRelocs()) + addInputSec(In::RelaPlt); // We fill .got and .got.plt sections in scanRelocs(). This is the // reason we don't add it earlier in createSections().