forked from OSchip/llvm-project
Create simpler dynamic relocations for local symbols in got.
If the symbol is not preemptable, we can use a R_X86_64_RELATIVE. llvm-svn: 249496
This commit is contained in:
parent
187276fa94
commit
52dca345db
|
@ -104,12 +104,6 @@ RelocationSection<ELFT>::RelocationSection(SymbolTableSection<ELFT> &DynSymSec,
|
|||
this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
|
||||
}
|
||||
|
||||
static bool isLocalDefinition(const SymbolBody *Body) {
|
||||
if (!Body)
|
||||
return true;
|
||||
return !Body->isShared() && !Body->isUndefined();
|
||||
}
|
||||
|
||||
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
|
||||
bool IsMips64EL = Relocs[0].C.getFile()->getObj().isMips64EL();
|
||||
|
@ -126,32 +120,36 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
const ELFFile<ELFT> &Obj = File.getObj();
|
||||
|
||||
uint32_t Type = RI.getType(IsMips64EL);
|
||||
|
||||
bool CanBePreempted = canBePreempted(Body);
|
||||
uintX_t Addend = 0;
|
||||
if (!CanBePreempted) {
|
||||
if (IsRela) {
|
||||
if (Body)
|
||||
Addend += getSymVA(cast<ELFSymbolBody<ELFT>>(*Body), BssSec);
|
||||
else
|
||||
Addend += getLocalSymVA(
|
||||
Obj.getRelocationSymbol(&RI, File.getSymbolTable()), File);
|
||||
}
|
||||
P->setSymbolAndType(0, Target->getRelativeReloc(), IsMips64EL);
|
||||
}
|
||||
|
||||
if (Body && Target->relocNeedsGot(Type, *Body)) {
|
||||
P->r_offset = GotSec.getEntryAddr(*Body);
|
||||
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
|
||||
Target->getGotReloc(), IsMips64EL);
|
||||
if (CanBePreempted)
|
||||
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
|
||||
Target->getGotReloc(), IsMips64EL);
|
||||
} else {
|
||||
P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA();
|
||||
uintX_t Addend = 0;
|
||||
if (IsRela)
|
||||
Addend = static_cast<const Elf_Rela &>(RI).r_addend;
|
||||
|
||||
if (!isLocalDefinition(Body)) {
|
||||
Addend += static_cast<const Elf_Rela &>(RI).r_addend;
|
||||
P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA();
|
||||
if (CanBePreempted)
|
||||
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type,
|
||||
IsMips64EL);
|
||||
} else {
|
||||
P->setSymbolAndType(0, Target->getRelativeReloc(), IsMips64EL);
|
||||
if (IsRela) {
|
||||
if (Body)
|
||||
Addend += getSymVA(cast<ELFSymbolBody<ELFT>>(*Body), BssSec);
|
||||
else
|
||||
Addend += getLocalSymVA(
|
||||
Obj.getRelocationSymbol(&RI, File.getSymbolTable()), File);
|
||||
}
|
||||
}
|
||||
if (IsRela)
|
||||
static_cast<Elf_Rela *>(P)->r_addend = Addend;
|
||||
}
|
||||
|
||||
if (IsRela)
|
||||
static_cast<Elf_Rela *>(P)->r_addend = Addend;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,7 +416,7 @@ bool lld::elf2::canBePreempted(const SymbolBody *Body) {
|
|||
return true;
|
||||
if (!Config->Shared)
|
||||
return false;
|
||||
return true;
|
||||
return Body->getMostConstrainingVisibility() == STV_DEFAULT;
|
||||
}
|
||||
|
||||
template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
|
||||
// RUN: ld.lld2 %t.o -o %t -shared
|
||||
// RUN: llvm-readobj -s -r %t | FileCheck %s
|
||||
// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
|
||||
|
||||
bar:
|
||||
call foo@gotpcrel
|
||||
|
||||
.hidden foo
|
||||
.global foo
|
||||
foo:
|
||||
nop
|
||||
|
||||
// 0x3090 - 0x2000 - 5 = 4235
|
||||
// DISASM: bar:
|
||||
// DISASM-NEXT: 2000: {{.*}} callq 4235
|
||||
|
||||
// DISASM: foo:
|
||||
// DISASM-NEXT: 2005: {{.*}} nop
|
||||
|
||||
// CHECK: Name: .got
|
||||
// CHECK-NEXT: Type: SHT_PROGBITS
|
||||
// CHECK-NEXT: Flags [
|
||||
// CHECK-NEXT: SHF_ALLOC
|
||||
// CHECK-NEXT: SHF_WRITE
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x3090
|
||||
// CHECK-NEXT: Offset:
|
||||
// CHECK-NEXT: Size: 8
|
||||
|
||||
// CHECK: Relocations [
|
||||
// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
|
||||
// CHECK-NEXT: 0x3090 R_X86_64_RELATIVE - 0x2005
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
Loading…
Reference in New Issue