Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -246,9 +246,9 @@ cast>(Body).Section->OutSec->Addr; } else if (Config->Relocatable) { const uint8_t *BufLoc = RelocatedSection->Data.begin() + Rel.r_offset; - uint64_t Implicit = Target->getImplicitAddend(BufLoc, Type); RelocatedSection->Relocations.push_back( - {R_ABS, Type, Rel.r_offset, Implicit, &Body}); + {R_ABS, Type, Rel.r_offset, Target->getImplicitAddend(BufLoc, Type), + &Body}); } } @@ -297,7 +297,7 @@ template static typename ELFT::uint -getRelocTargetVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P, +getRelocTargetVA(uint32_t Type, int64_t A, typename ELFT::uint P, const SymbolBody &Body, RelExpr Expr) { switch (Expr) { case R_HINT: @@ -447,7 +447,7 @@ uint32_t Type = Rel.getType(Config->Mips64EL); uintX_t Offset = this->getOffset(Rel.r_offset); uint8_t *BufLoc = Buf + Offset; - uintX_t Addend = getAddend(Rel); + int64_t Addend = getAddend(Rel); if (!RelTy::IsRela) Addend += Target->getImplicitAddend(BufLoc, Type); @@ -485,12 +485,11 @@ uintX_t Offset = getOffset(Rel.Offset); uint8_t *BufLoc = Buf + Offset; uint32_t Type = Rel.Type; - uintX_t A = Rel.Addend; uintX_t AddrLoc = OutSec->Addr + Offset; RelExpr Expr = Rel.Expr; uint64_t TargetVA = SignExtend64( - getRelocTargetVA(Type, A, AddrLoc, *Rel.Sym, Expr)); + getRelocTargetVA(Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr)); switch (Expr) { case R_RELAX_GOT_PC: Index: ELF/Relocations.h =================================================================== --- ELF/Relocations.h +++ ELF/Relocations.h @@ -105,7 +105,7 @@ RelExpr Expr; uint32_t Type; uint64_t Offset; - uint64_t Addend; + int64_t Addend; SymbolBody *Sym; }; @@ -114,14 +114,15 @@ template void createThunks(ArrayRef OutputSections); +// Return a int64_t to make sure we get the sign extension out of the way as +// early as possible. template -static inline typename ELFT::uint getAddend(const typename ELFT::Rel &Rel) { +static inline int64_t getAddend(const typename ELFT::Rel &Rel) { return 0; } - template -static inline typename ELFT::uint getAddend(const typename ELFT::Rela &Rel) { - return Rel.r_addend; +static inline int64_t getAddend(const typename ELFT::Rela &Rel) { + return llvm::SignExtend64 < ELFT::Is64Bits ? 64 : 32 > (Rel.r_addend); } } } Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -91,9 +91,11 @@ // handling in to the separate function we can simplify the code and do not // pollute `handleTlsRelocation` by ARM and MIPS `ifs` statements. template -static unsigned handleNoRelaxTlsRelocation( - GOT *Got, uint32_t Type, SymbolBody &Body, InputSectionBase &C, - typename ELFT::uint Offset, typename ELFT::uint Addend, RelExpr Expr) { +static unsigned handleNoRelaxTlsRelocation(GOT *Got, uint32_t Type, + SymbolBody &Body, + InputSectionBase &C, + typename ELFT::uint Offset, + int64_t Addend, RelExpr Expr) { typedef typename ELFT::uint uintX_t; auto addModuleReloc = [](SymbolBody &Body, GOT *Got, uintX_t Off, bool LD) { // The Dynamic TLS Module Index Relocation can be statically resolved to 1 @@ -133,10 +135,9 @@ // Returns the number of relocations processed. template -static unsigned handleTlsRelocation(uint32_t Type, SymbolBody &Body, - InputSectionBase &C, - typename ELFT::uint Offset, - typename ELFT::uint Addend, RelExpr Expr) { +static unsigned +handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, + typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) { if (!(C.Flags & SHF_ALLOC)) return 0; @@ -530,14 +531,11 @@ } template -static typename ELFT::uint computeAddend(const elf::ObjectFile &File, - const uint8_t *SectionData, - const RelTy *End, const RelTy &RI, - RelExpr Expr, SymbolBody &Body) { - typedef typename ELFT::uint uintX_t; - +static int64_t computeAddend(const elf::ObjectFile &File, + const uint8_t *SectionData, const RelTy *End, + const RelTy &RI, RelExpr Expr, SymbolBody &Body) { uint32_t Type = RI.getType(Config->Mips64EL); - uintX_t Addend = getAddend(RI); + int64_t Addend = getAddend(RI); const uint8_t *BufLoc = SectionData + RI.r_offset; if (!RelTy::IsRela) Addend += Target->getImplicitAddend(BufLoc, Type); @@ -675,7 +673,7 @@ Expr == R_GOTREL || Expr == R_GOTREL_FROM_END || Expr == R_PPC_TOC) In::Got->HasGotOffRel = true; - uintX_t Addend = computeAddend(*File, Buf, E, RI, Expr, Body); + int64_t Addend = computeAddend(*File, Buf, E, RI, Expr, Body); if (unsigned Processed = handleTlsRelocation(Type, Body, C, Offset, Addend, Expr)) { Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -77,8 +77,7 @@ bool isInGot() const { return GotIndex != -1U; } bool isInPlt() const { return PltIndex != -1U; } - template - typename ELFT::uint getVA(typename ELFT::uint Addend = 0) const; + template typename ELFT::uint getVA(int64_t Addend = 0) const; template typename ELFT::uint getGotOffset() const; template typename ELFT::uint getGotVA() const; Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -29,8 +29,7 @@ using namespace lld::elf; template -static typename ELFT::uint getSymVA(const SymbolBody &Body, - typename ELFT::uint &Addend) { +static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) { typedef typename ELFT::uint uintX_t; switch (Body.kind()) { @@ -135,7 +134,7 @@ } template -typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const { +typename ELFT::uint SymbolBody::getVA(int64_t Addend) const { typename ELFT::uint OutVA = getSymVA(*this, Addend); return OutVA + Addend; } @@ -322,10 +321,10 @@ return B.getName(); } -template uint32_t SymbolBody::template getVA(uint32_t) const; -template uint32_t SymbolBody::template getVA(uint32_t) const; -template uint64_t SymbolBody::template getVA(uint64_t) const; -template uint64_t SymbolBody::template getVA(uint64_t) const; +template uint32_t SymbolBody::template getVA(int64_t) const; +template uint32_t SymbolBody::template getVA(int64_t) const; +template uint64_t SymbolBody::template getVA(int64_t) const; +template uint64_t SymbolBody::template getVA(int64_t) const; template uint32_t SymbolBody::template getGotVA() const; template uint32_t SymbolBody::template getGotVA() const; Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -129,11 +129,11 @@ size_t getSize() const override { return Size; } void finalize() override; bool empty() const override; - void addEntry(SymbolBody &Sym, uintX_t Addend, RelExpr Expr); + void addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr); bool addDynTlsEntry(SymbolBody &Sym); bool addTlsIndex(); - uintX_t getPageEntryOffset(const SymbolBody &B, uintX_t Addend) const; - uintX_t getBodyEntryOffset(const SymbolBody &B, uintX_t Addend) const; + uintX_t getPageEntryOffset(const SymbolBody &B, int64_t Addend) const; + uintX_t getBodyEntryOffset(const SymbolBody &B, int64_t Addend) const; uintX_t getGlobalDynOffset(const SymbolBody &B) const; // Returns the symbol which corresponds to the first entry of the global part @@ -279,12 +279,12 @@ public: DynamicReloc(uint32_t Type, const InputSectionBase *InputSec, uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym, - uintX_t Addend) + int64_t Addend) : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {} uintX_t getOffset() const; - uintX_t getAddend() const; + int64_t getAddend() const; uint32_t getSymIndex() const; const InputSectionBase *getInputSec() const { return InputSec; } @@ -295,7 +295,7 @@ const InputSectionBase *InputSec = nullptr; uintX_t OffsetInSec; bool UseSymVA; - uintX_t Addend; + int64_t Addend; }; template Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -461,7 +461,7 @@ SHT_PROGBITS, 16, ".got") {} template -void MipsGotSection::addEntry(SymbolBody &Sym, uintX_t Addend, +void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr) { // For "true" local symbols which can be referenced from the same module // only compiler creates two instructions for address loading: @@ -563,7 +563,7 @@ template typename MipsGotSection::uintX_t MipsGotSection::getPageEntryOffset(const SymbolBody &B, - uintX_t Addend) const { + int64_t Addend) const { const OutputSectionBase *OutSec = cast>(&B)->Section->getOutputSection(); uintX_t SecAddr = getMipsPageAddr(OutSec->Addr); @@ -576,7 +576,7 @@ template typename MipsGotSection::uintX_t MipsGotSection::getBodyEntryOffset(const SymbolBody &B, - uintX_t Addend) const { + int64_t Addend) const { // Calculate offset of the GOT entries block: TLS, global, local. uintX_t Index = HeaderEntriesNum + PageEntriesNum; if (B.isTls()) @@ -978,8 +978,7 @@ return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec); } -template -typename ELFT::uint DynamicReloc::getAddend() const { +template int64_t DynamicReloc::getAddend() const { if (UseSymVA) return Sym->getVA(Addend); return Addend;