Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -105,14 +105,18 @@ if (Offset == (uintX_t)-1) continue; + uintX_t Addend = getAddend(RI); + if (Addend != 0 && !Target->isNonzeroAddendSupported(Type)) + error("Nonzero addend is not supported for relocation " + + getELFRelocationTypeName(Config->EMachine, Type)); + uint8_t *BufLoc = Buf + Offset; uintX_t AddrLoc = OutSec->getVA() + Offset; if (Target->isTlsLocalDynamicReloc(Type)) { Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, Out::Got->getVA() + - Out::LocalModuleTlsIndexOffset + - getAddend(RI)); + Out::LocalModuleTlsIndexOffset + Addend); continue; } @@ -129,8 +133,7 @@ if (Target->isTlsGlobalDynamicReloc(Type)) { Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, - Out::Got->getEntryAddr(Body) + - getAddend(RI)); + Out::Got->getEntryAddr(Body) + Addend); continue; } @@ -155,8 +158,7 @@ isa>(Body)) { continue; } - Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, - SymVA + getAddend(RI)); + Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA + Addend); } } Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -52,6 +52,7 @@ uint64_t PltEntryAddr) const = 0; virtual void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr, int32_t Index) const = 0; + virtual bool isNonzeroAddendSupported(uint32_t Type) const; virtual bool isRelRelative(uint32_t Type) const; virtual bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const; virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0; Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -105,6 +105,7 @@ uint64_t PltEntryAddr) const override; void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr, int32_t Index) const override; + bool isNonzeroAddendSupported(uint32_t Type) const override; bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override; bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, @@ -170,6 +171,8 @@ bool TargetInfo::isRelRelative(uint32_t Type) const { return true; } +bool TargetInfo::isNonzeroAddendSupported(uint32_t Type) const { return true; } + void TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint64_t P, uint64_t SA) const {} @@ -730,6 +733,10 @@ GotEntryAddr); } +bool AArch64TargetInfo::isNonzeroAddendSupported(uint32_t Type) const { + return Type != R_AARCH64_ADR_GOT_PAGE && Type != R_AARCH64_LD64_GOT_LO12_NC; +} + bool AArch64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const { return Type == R_AARCH64_ADR_GOT_PAGE || Type == R_AARCH64_LD64_GOT_LO12_NC || Index: test/ELF/aarch64-got-nonzero-addend-error.s =================================================================== --- /dev/null +++ test/ELF/aarch64-got-nonzero-addend-error.s @@ -0,0 +1,13 @@ +// REQUIRES: aarch64 +// Until we support a nonzero addend for GOT relocations, +// we have to print the corresponding error message. + +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o +// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s + +.global dat + adrp x0, :got:dat+1 +dat: + .word 42 + +// CHECK: Nonzero addend is not supported for relocation R_AARCH64_ADR_GOT_PAGE