[lld] r249496 - Create simpler dynamic relocations for local symbols in got.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 6 17:58:20 PDT 2015
Author: rafael
Date: Tue Oct 6 19:58:20 2015
New Revision: 249496
URL: http://llvm.org/viewvc/llvm-project?rev=249496&view=rev
Log:
Create simpler dynamic relocations for local symbols in got.
If the symbol is not preemptable, we can use a R_X86_64_RELATIVE.
Added:
lld/trunk/test/elf2/local-got-shared.s
Modified:
lld/trunk/ELF/OutputSections.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249496&r1=249495&r2=249496&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Oct 6 19:58:20 2015
@@ -104,12 +104,6 @@ RelocationSection<ELFT>::RelocationSecti
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 RelocationSec
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 Sym
return true;
if (!Config->Shared)
return false;
- return true;
+ return Body->getMostConstrainingVisibility() == STV_DEFAULT;
}
template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
Added: lld/trunk/test/elf2/local-got-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/local-got-shared.s?rev=249496&view=auto
==============================================================================
--- lld/trunk/test/elf2/local-got-shared.s (added)
+++ lld/trunk/test/elf2/local-got-shared.s Tue Oct 6 19:58:20 2015
@@ -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 at 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: ]
More information about the llvm-commits
mailing list