Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -848,16 +848,8 @@ Type = Target->RelativeRel; else Type = Target->GotRel; - InX::RelaDyn->addReloc({Type, InX::Got, Off, !Preemptible, &Sym, 0}); - - // REL type relocations don't have addend fields unlike RELAs, and - // their addends are stored to the section to which they are applied. - // So, store addends if we need to. - // - // This is ugly -- the difference between REL and RELA should be - // handled in a better way. It's a TODO. - if (!Config->IsRela && !Preemptible) - InX::Got->Relocations.push_back({R_ABS, Target->GotRel, Off, 0, &Sym}); + InX::RelaDyn->addReloc({Type, InX::Got, Off, !Preemptible, &Sym, 0}, R_ABS, + Target->GotRel); } // The reason we have to do this early scan is as follows @@ -1035,15 +1027,8 @@ // dynamic linker. We can however do better than just copying the incoming // relocation. We can process some of it and and just ask the dynamic // linker to add the load address. - if (Config->IsRela) { - InX::RelaDyn->addReloc( - {Target->RelativeRel, &Sec, Offset, true, &Sym, Addend}); - } else { - // In REL, addends are stored to the target section. - InX::RelaDyn->addReloc( - {Target->RelativeRel, &Sec, Offset, true, &Sym, 0}); - Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym}); - } + InX::RelaDyn->addReloc( + {Target->RelativeRel, &Sec, Offset, true, &Sym, Addend}, Expr, Type); } } Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -310,21 +310,19 @@ class DynamicReloc { public: - DynamicReloc(uint32_t Type, const InputSectionBase *InputSec, - uint64_t OffsetInSec, bool UseSymVA, Symbol *Sym, int64_t Addend) + DynamicReloc(uint32_t Type, InputSectionBase *InputSec, uint64_t OffsetInSec, + bool UseSymVA, Symbol *Sym, int64_t Addend) : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {} uint64_t getOffset() const; int64_t getAddend() const; uint32_t getSymIndex() const; - const InputSectionBase *getInputSec() const { return InputSec; } + InputSectionBase *getInputSec() const { return InputSec; } uint32_t Type; - -private: Symbol *Sym; - const InputSectionBase *InputSec = nullptr; + InputSectionBase *InputSec = nullptr; uint64_t OffsetInSec; bool UseSymVA; int64_t Addend; @@ -361,6 +359,7 @@ public: RelocationBaseSection(StringRef Name, uint32_t Type, int32_t DynamicTag, int32_t SizeDynamicTag); + void addReloc(const DynamicReloc &Reloc, RelExpr Expr, RelType Type); void addReloc(const DynamicReloc &Reloc); bool empty() const override { return Relocs.empty(); } size_t getSize() const override { return Relocs.size() * this->Entsize; } Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1202,6 +1202,17 @@ : SyntheticSection(SHF_ALLOC, Type, Config->Wordsize, Name), DynamicTag(DynamicTag), SizeDynamicTag(SizeDynamicTag) {} +void RelocationBaseSection::addReloc(const DynamicReloc &Reloc, RelExpr Expr, + RelType Type) { + // REL type relocations don't have addend fields unlike RELAs, and + // their addends are stored to the section to which they are applied. + // So, store addends if we need to. + if (!Config->IsRela && Reloc.UseSymVA) + Reloc.getInputSec()->Relocations.push_back( + {Expr, Type, Reloc.OffsetInSec, Reloc.Addend, Reloc.Sym}); + addReloc(Reloc); +} + void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) { if (Reloc.Type == Target->RelativeRel) ++NumRelativeRelocs;