[lld] r249340 - Create R_X86_64_RELATIVE when needed.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 5 12:30:12 PDT 2015
Author: rafael
Date: Mon Oct 5 14:30:12 2015
New Revision: 249340
URL: http://llvm.org/viewvc/llvm-project?rev=249340&view=rev
Log:
Create R_X86_64_RELATIVE when needed.
The dynamic relocation code needs refactoring, but it is probably better
to do it with this test passing.
Added:
lld/trunk/test/elf2/relative-dynamic-reloc.s
Modified:
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Target.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249340&r1=249339&r2=249340&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Oct 5 14:30:12 2015
@@ -104,16 +104,23 @@ template <class ELFT> void RelocationSec
uint32_t SymIndex = RI.getSymbol(IsMips64EL);
const SymbolBody *Body = C.getFile()->getSymbolBody(SymIndex);
uint32_t Type = RI.getType(IsMips64EL);
- if (Target->relocNeedsGot(Type, *Body)) {
+ if (Body && Target->relocNeedsGot(Type, *Body)) {
P->r_offset = GotSec.getEntryAddr(*Body);
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
Target->getGotReloc(), IsMips64EL);
} else {
P->r_offset = RI.r_offset + C.getOutputSectionOff() + Out->getVA();
- P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type, IsMips64EL);
- if (IsRela)
- static_cast<Elf_Rela *>(P)->r_addend =
- static_cast<const Elf_Rela &>(RI).r_addend;
+ if (Body && Body->isShared()) {
+ P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type,
+ IsMips64EL);
+ if (IsRela)
+ static_cast<Elf_Rela *>(P)->r_addend =
+ static_cast<const Elf_Rela &>(RI).r_addend;
+ } else {
+ P->setSymbolAndType(0, Target->getRelativeReloc(), IsMips64EL);
+ if (IsRela)
+ static_cast<Elf_Rela *>(P)->r_addend = P->r_offset;
+ }
}
}
}
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=249340&r1=249339&r2=249340&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Mon Oct 5 14:30:12 2015
@@ -30,6 +30,8 @@ TargetInfo::~TargetInfo() {}
bool TargetInfo::relocPointsToGot(uint32_t Type) const { return false; }
+bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
+
X86TargetInfo::X86TargetInfo() {
PCRelReloc = R_386_PC32;
GotReloc = R_386_GLOB_DAT;
@@ -87,6 +89,7 @@ X86_64TargetInfo::X86_64TargetInfo() {
PCRelReloc = R_X86_64_PC32;
GotReloc = R_X86_64_GLOB_DAT;
GotRefReloc = R_X86_64_PC32;
+ RelativeReloc = R_X86_64_RELATIVE;
}
void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -139,6 +142,18 @@ bool X86_64TargetInfo::relocNeedsPlt(uin
return true;
}
}
+
+bool X86_64TargetInfo::isRelRelative(uint32_t Type) const {
+ switch (Type) {
+ default:
+ return false;
+ case R_X86_64_PC64:
+ case R_X86_64_PC32:
+ case R_X86_64_PC16:
+ case R_X86_64_PC8:
+ return true;
+ }
+}
void X86_64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
uint32_t Type, uint64_t BaseAddr,
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=249340&r1=249339&r2=249340&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Mon Oct 5 14:30:12 2015
@@ -23,9 +23,11 @@ public:
llvm::StringRef getDefaultEntry() const { return DefaultEntry; }
unsigned getPCRelReloc() const { return PCRelReloc; }
unsigned getGotReloc() const { return GotReloc; }
- unsigned getGotRefReloc() const { return GotRefReloc; };
+ unsigned getGotRefReloc() const { return GotRefReloc; }
+ unsigned getRelativeReloc() const { return RelativeReloc; }
virtual void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
uint64_t PltEntryAddr) const = 0;
+ virtual bool isRelRelative(uint32_t Type) const;
virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0;
virtual bool relocPointsToGot(uint32_t Type) const;
virtual bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const = 0;
@@ -39,6 +41,7 @@ protected:
unsigned PCRelReloc;
unsigned GotRefReloc;
unsigned GotReloc;
+ unsigned RelativeReloc;
llvm::StringRef DefaultEntry = "_start";
};
@@ -65,6 +68,7 @@ public:
void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
uint64_t BaseAddr, uint64_t SymVA,
uint64_t GotVA) const override;
+ bool isRelRelative(uint32_t Type) const override;
};
class PPC64TargetInfo final : public TargetInfo {
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249340&r1=249339&r2=249340&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Oct 5 14:30:12 2015
@@ -217,22 +217,29 @@ void Writer<ELFT>::scanRelocs(
for (const RelType &RI : Rels) {
uint32_t SymIndex = RI.getSymbol(IsMips64EL);
SymbolBody *Body = File.getSymbolBody(SymIndex);
- if (!Body)
- continue;
uint32_t Type = RI.getType(IsMips64EL);
- if (Target->relocNeedsPlt(Type, *Body)) {
- if (Body->isInPlt())
+ if (Body) {
+ if (Target->relocNeedsPlt(Type, *Body)) {
+ if (Body->isInPlt())
+ continue;
+ PltSec.addEntry(Body);
+ }
+ if (Target->relocNeedsGot(Type, *Body)) {
+ if (Body->isInGot())
+ continue;
+ GotSec.addEntry(Body);
+ Body->setUsedInDynamicReloc();
+ RelaDynSec.addReloc({C, RI});
continue;
- PltSec.addEntry(Body);
- }
- if (Target->relocNeedsGot(Type, *Body)) {
- if (Body->isInGot())
+ }
+ if (Body->isShared()) {
+ Body->setUsedInDynamicReloc();
+ RelaDynSec.addReloc({C, RI});
continue;
- GotSec.addEntry(Body);
- } else if (!isa<SharedSymbol<ELFT>>(Body))
- continue;
- Body->setUsedInDynamicReloc();
- RelaDynSec.addReloc({C, RI});
+ }
+ }
+ if (Config->Shared && !Target->isRelRelative(Type))
+ RelaDynSec.addReloc({C, RI});
}
}
Added: lld/trunk/test/elf2/relative-dynamic-reloc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/relative-dynamic-reloc.s?rev=249340&view=auto
==============================================================================
--- lld/trunk/test/elf2/relative-dynamic-reloc.s (added)
+++ lld/trunk/test/elf2/relative-dynamic-reloc.s Mon Oct 5 14:30:12 2015
@@ -0,0 +1,40 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld2 -shared %t.o -o %t.so
+// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
+
+// Test that we create R_X86_64_RELATIVE relocations but don't put any
+// symbols in the dynamic symbol table.
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: [[FOO_ADDR:.*]] R_X86_64_RELATIVE - [[FOO_ADDR]]
+// CHECK-NEXT: [[BAR_ADDR:.*]] R_X86_64_RELATIVE - [[BAR_ADDR]]
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+// CHECK: Symbols [
+// CHECK: Name: foo
+// CHECK-NEXT: Value: [[FOO_ADDR]]
+// CHECK: Name: bar
+// CHECK-NEXT: Value: [[BAR_ADDR]]
+// CHECK: ]
+
+// CHECK: DynamicSymbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: @ (0)
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+foo:
+ .quad foo
+
+ .hidden bar
+ .global bar
+bar:
+ .quad bar
More information about the llvm-commits
mailing list