[ELF] Implement GOTPCREL for defined atoms.

llvm-svn: 174426
This commit is contained in:
Michael J. Spencer 2013-02-05 19:14:28 +00:00
parent e6ab9f80a7
commit 359b6ff6bb
5 changed files with 32 additions and 8 deletions

View File

@ -152,11 +152,8 @@ class GOTPLTPass LLVM_FINAL : public Pass {
if (da)
handleGOTTPOFF(ref, *da);
break;
case R_X86_64_GOTPCREL: // GOTPCREL to an undefined weak symbol.
// Always convert it to a non-got reference.
const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
if (isa<const UndefinedAtom>(ref.target()))
handleUndefGOTPCREL(ref);
case R_X86_64_GOTPCREL:
handleGOTPCREL(ref);
break;
}
}
@ -225,10 +222,29 @@ class GOTPLTPass LLVM_FINAL : public Pass {
return _null;
}
const GOTAtom *getGOT(const DefinedAtom &da) {
auto got = _gotMap.find(&da);
if (got == _gotMap.end()) {
auto g = new (_file._alloc) GOTAtom(_file, ".got");
g->addReference(R_X86_64_64, 0, &da, 0);
#ifndef NDEBUG
g->_name = "__got_";
g->_name += da.name();
#endif
_gotMap[&da] = g;
return g;
}
return got->second;
}
/// \brief Handle a GOTPCREL relocation to an undefined weak atom by using a
/// null GOT entry.
void handleUndefGOTPCREL(const Reference &ref) {
const_cast<Reference &>(ref).setTarget(getNullGOT());
void handleGOTPCREL(const Reference &ref) {
const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
if (isa<UndefinedAtom>(ref.target()))
const_cast<Reference &>(ref).setTarget(getNullGOT());
else if (const DefinedAtom *da = dyn_cast<const DefinedAtom>(ref.target()))
const_cast<Reference &>(ref).setTarget(getGOT(*da));
}
public:

View File

@ -4,6 +4,7 @@
.type main,@function
main: # @main
movq blah@GOTPCREL(%rip), %rax
movq main@GOTPCREL(%rip), %rax
ret
.weak blah

Binary file not shown.

View File

@ -1,10 +1,17 @@
RUN: lld -core -target x86_64-linux -output=- -entry=main \
RUN: %p/Inputs/undef-gotpcrel.x86-64 -emit-yaml -noinhibit-exec \
RUN: %p/Inputs/gotpcrel.x86-64 -emit-yaml -noinhibit-exec \
RUN: | FileCheck %s -check-prefix=YAML
YAML: name: main
YAML: kind: R_X86_64_PC32
YAML: target: [[NULLGOT:[a-zA-Z0-9_]+]]
YAML: kind: R_X86_64_PC32
YAML: target: [[MAINGOT:[a-zA-Z0-9_]+]]
YAML: name: [[NULLGOT]]
YAML: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
YAML-NOT: references:
YAML: name: [[MAINGOT]]
YAML: kind: R_X86_64_64
YAML: target: main