if (IsRela) {
uintX_t VA = 0;
- if (Rel.UseSymVA) {
+ if (Rel.UseSymVA)
VA = Sym->getVA<ELFT>();
- } else if (Rel.TargetSec) {
+ else if (Rel.TargetSec)
VA = Rel.TargetSec->getOffset(Rel.OffsetInTargetSec) +
Rel.TargetSec->OutSec->getVA();
- } else if (!Sym && Rel.OffsetSec) {
- // Sym equal to nullptr means the dynamic relocation is against a
- // local symbol represented by Rel.SymIndex.
- ObjectFile<ELFT> *File = Rel.OffsetSec->getFile();
- const Elf_Sym *LocalSym = File->getLocalSymbol(Rel.SymIndex);
- VA = getLocalTarget(*File, *LocalSym, 0);
- }
reinterpret_cast<Elf_Rela *>(P)->r_addend = Rel.Addend + VA;
}
const Elf_Rel_Impl<ELFT, IsRela> &RI,
typename ELFFile<ELFT>::uintX_t Addend) {
typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
+ typedef typename ELFFile<ELFT>::uintX_t uintX_t;
// PPC64 has a special relocation representing the TOC base pointer
// that does not have a corresponding symbol.
if (!Sym)
fatal("Unsupported relocation without symbol");
- return getLocalTarget(File, *Sym, Addend);
-}
-
-template <class ELFT>
-typename ELFFile<ELFT>::uintX_t
-elf2::getLocalTarget(const ObjectFile<ELFT> &File,
- const typename ELFFile<ELFT>::Elf_Sym &Sym,
- typename ELFFile<ELFT>::uintX_t Addend) {
- typedef typename ELFFile<ELFT>::uintX_t uintX_t;
-
- InputSectionBase<ELFT> *Section = File.getSection(Sym);
- if (!Section)
- return Addend;
+ InputSectionBase<ELFT> *Section = File.getSection(*Sym);
- if (Sym.getType() == STT_TLS)
- return (Section->OutSec->getVA() + Section->getOffset(Sym) + Addend) -
+ if (Sym->getType() == STT_TLS)
+ return (Section->OutSec->getVA() + Section->getOffset(*Sym) + Addend) -
Out<ELFT>::TlsPhdr->p_vaddr;
// According to the ELF spec reference to a local symbol from outside
if (Section == &InputSection<ELFT>::Discarded || !Section->isLive())
return Addend;
- uintX_t Offset = Sym.st_value;
- if (Sym.getType() == STT_SECTION) {
+ uintX_t Offset = Sym->st_value;
+ if (Sym->getType() == STT_SECTION) {
Offset += Addend;
Addend = 0;
}
template uint64_t getLocalRelTarget(const ObjectFile<ELF64BE> &,
const ELFFile<ELF64BE>::Elf_Rela &,
uint64_t);
-
-template uint32_t getLocalTarget(const ObjectFile<ELF32LE> &,
- const ELFFile<ELF32LE>::Elf_Sym &Sym,
- uint32_t);
-template uint32_t getLocalTarget(const ObjectFile<ELF32BE> &,
- const ELFFile<ELF32BE>::Elf_Sym &Sym,
- uint32_t);
-template uint64_t getLocalTarget(const ObjectFile<ELF64LE> &,
- const ELFFile<ELF64LE>::Elf_Sym &Sym,
- uint64_t);
-template uint64_t getLocalTarget(const ObjectFile<ELF64BE> &,
- const ELFFile<ELF64BE>::Elf_Sym &Sym,
- uint64_t);
}
}
const llvm::object::Elf_Rel_Impl<ELFT, IsRela> &Rel,
typename llvm::object::ELFFile<ELFT>::uintX_t Addend);
-template <class ELFT>
-typename llvm::object::ELFFile<ELFT>::uintX_t
-getLocalTarget(const ObjectFile<ELFT> &File,
- const typename llvm::object::ELFFile<ELFT>::Elf_Sym &Sym,
- typename llvm::object::ELFFile<ELFT>::uintX_t Addend);
-
bool canBePreempted(const SymbolBody *Body, bool NeedsGot);
// This represents a section in an output file.
} OKind;
SymbolBody *Sym = nullptr;
- uint32_t SymIndex = 0;
InputSectionBase<ELFT> *OffsetSec = nullptr;
uintX_t OffsetInSec = 0;
bool UseSymVA = false;
OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {}
DynamicReloc(uint32_t Type, InputSectionBase<ELFT> *OffsetSec,
- uintX_t OffsetInSec, bool UseSymVA, uint32_t SymIndex,
- uintX_t Addend)
- : Type(Type), OKind(Off_Sec), SymIndex(SymIndex), OffsetSec(OffsetSec),
- OffsetInSec(OffsetInSec), UseSymVA(UseSymVA), Addend(Addend) {}
-
- DynamicReloc(uint32_t Type, InputSectionBase<ELFT> *OffsetSec,
uintX_t OffsetInSec, InputSectionBase<ELFT> *TargetSec,
uintX_t OffsetInTargetSec, uintX_t Addend)
: Type(Type), OKind(Off_Sec), OffsetSec(OffsetSec),
template <class ELFT>
class RelocationSection final : public OutputSectionBase<ELFT> {
- typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
int32_t Index, unsigned RelOff) const override;
unsigned getTlsGotRel(unsigned Type) const override;
bool isTlsDynRel(unsigned Type, const SymbolBody &S) const override;
+ bool isRelRelative(uint32_t Type) const override;
bool needsCopyRelImpl(uint32_t Type) const override;
- bool needsDynRelative(unsigned Type) const override;
bool needsGot(uint32_t Type, SymbolBody &S) const override;
PltNeed needsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
PltZeroSize = 32;
}
+bool AArch64TargetInfo::isRelRelative(uint32_t Type) const { return false; }
+
bool AArch64TargetInfo::isTlsGlobalDynamicRel(unsigned Type) const {
return Type == R_AARCH64_TLSDESC_ADR_PAGE21 ||
Type == R_AARCH64_TLSDESC_LD64_LO12_NC ||
}
}
-bool AArch64TargetInfo::needsDynRelative(unsigned Type) const {
- return Config->Shared && Type == R_AARCH64_ABS64;
-}
-
bool AArch64TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const {
switch (Type) {
case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
if (handleTlsRelocation<ELFT>(Type, Body, C, RI))
continue;
- if (Target->needsDynRelative(Type)) {
- // If Body is null it means the relocation is against a local symbol
- // and thus we need to pass the local symbol index instead.
- if (Body)
- Out<ELFT>::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, true,
- Body, getAddend<ELFT>(RI)});
- else
- Out<ELFT>::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, false,
- SymIndex, getAddend<ELFT>(RI)});
- }
+ if (Target->needsDynRelative(Type))
+ Out<ELFT>::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, true,
+ Body, getAddend<ELFT>(RI)});
// MIPS has a special rule to create GOTs for local symbols.
if (Config->EMachine == EM_MIPS && !canBePreempted(Body, true) &&
// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
-// Creates a R_AARCH64_ABS64 relocation against _foo. It will be used on a
-// shared object to check for a dynamic relocation creation.
-.globl _foo
-_foo:
- ret
-_foo_init_array:
- .xword _foo
+// Creates a R_AARCH64_ABS64 relocation against foo and bar
+ .globl foo
+foo:
+
+ .global bar
+ .hidden bar
+bar:
+
+ .data
+ .xword foo
+ .xword bar
// RUN: ld.lld -shared -o %t.so %t.o
// RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s
-// CHECK: Dynamic Relocations {
-// CHECK-NEXT: {{.*}} R_AARCH64_RELATIVE - [[FOO_ADDR:[0-9xa-f]+]]
+// CHECK: Dynamic Relocations {
+// CHECK-NEXT: {{.*}} R_AARCH64_ABS64 foo 0x0
+// CHECK-NEXT: {{.*}} R_AARCH64_RELATIVE - [[BAR_ADDR:.*]]
+// CHECK-NEXT: }
-// CHECK: Symbols [
-// CHECK: Symbol {
-// CHECK: Name: _foo
-// CHECK: Value: [[FOO_ADDR]]
+// CHECK: Symbols [
+// CHECK: Symbol {
+// CHECK: Name: bar
+// CHECK-NEXT: Value: [[BAR_ADDR]]