Add support for relocating R_X86_64_GOTPCREL.

llvm-svn: 248425
This commit is contained in:
Rafael Espindola 2015-09-23 20:08:25 +00:00
parent 5c3f9d516d
commit cdfecffd80
4 changed files with 42 additions and 14 deletions

View File

@ -50,6 +50,7 @@ void InputSection<ELFT>::relocate(
const SymbolBody *Body = File.getSymbolBody(SymIndex);
if (!Body)
continue;
uint32_t OrigType = Type;
switch (Body->kind()) {
case SymbolBody::DefinedRegularKind:
SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));
@ -63,15 +64,12 @@ void InputSection<ELFT>::relocate(
break;
}
case SymbolBody::SharedKind:
if (Target->relocNeedsPlt(Type)) {
SymVA = PltSec.getEntryAddr(*Body);
if (Target->relocNeedsPlt(Type))
Type = Target->getPCRelReloc();
} else if (Target->relocNeedsGot(Type)) {
SymVA = GotSec.getEntryAddr(*Body);
else if (Target->relocNeedsGot(Type))
Type = Target->getPCRelReloc();
} else {
else
continue;
}
break;
case SymbolBody::UndefinedKind:
assert(Body->isWeak() && "Undefined symbol reached writer");
@ -80,6 +78,11 @@ void InputSection<ELFT>::relocate(
case SymbolBody::LazyKind:
llvm_unreachable("Lazy symbol reached writer");
}
if (Target->relocNeedsPlt(OrigType))
SymVA = PltSec.getEntryAddr(*Body);
else if (Target->relocNeedsGot(OrigType))
SymVA = GotSec.getEntryAddr(*Body);
}
Target->relocateOne(Buf, reinterpret_cast<const void *>(&RI), Type,

View File

@ -137,6 +137,7 @@ void X86_64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
uint8_t *Location = Buf + Offset;
switch (Type) {
case R_X86_64_PC32:
case R_X86_64_GOTPCREL:
support::endian::write32le(Location,
SymVA + Rel.r_addend - (BaseAddr + Offset));
break;

View File

@ -255,9 +255,6 @@ void Writer<ELFT>::scanRelocs(
SymbolBody *Body = File.getSymbolBody(SymIndex);
if (!Body)
continue;
auto *S = dyn_cast<SharedSymbol<ELFT>>(Body);
if (!S)
continue;
uint32_t Type = RI.getType(IsMips64EL);
if (Target->relocNeedsPlt(Type)) {
if (Body->isInPlt())
@ -269,7 +266,9 @@ void Writer<ELFT>::scanRelocs(
continue;
GotSec.addEntry(Body);
}
S->setUsedInDynamicReloc();
if (!isa<SharedSymbol<ELFT>>(Body))
continue;
Body->setUsedInDynamicReloc();
RelaDynSec.addReloc({C, RI});
}
}
@ -395,11 +394,11 @@ template <class ELFT> void Writer<ELFT>::createSections() {
OutputSections.push_back(&DynStrSec);
if (RelaDynSec.hasRelocs())
OutputSections.push_back(&RelaDynSec);
if (!GotSec.empty())
OutputSections.push_back(&GotSec);
if (!PltSec.empty())
OutputSections.push_back(&PltSec);
}
if (!GotSec.empty())
OutputSections.push_back(&GotSec);
if (!PltSec.empty())
OutputSections.push_back(&PltSec);
std::stable_sort(OutputSections.begin(), OutputSections.end(),
compSec<ELFT::Is64Bits>);

View File

@ -1,8 +1,23 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
// RUN: lld -flavor gnu2 %t -o %t2
// RUN: llvm-readobj -s %t2 | FileCheck --check-prefix=SEC %s
// RUN: llvm-objdump -s -d %t2 | FileCheck %s
// REQUIRES: x86
// SEC: Name: .got
// SEC-NEXT: Type: SHT_PROGBITS
// SEC-NEXT: Flags [
// SEC-NEXT: SHF_ALLOC
// SEC-NEXT: SHF_WRITE
// SEC-NEXT: ]
// SEC-NEXT: Address: 0x13000
// SEC-NEXT: Offset:
// SEC-NEXT: Size: 8
// SEC-NEXT: Link: 0
// SEC-NEXT: Info: 0
// SEC-NEXT: AddressAlignment: 8
// SEC-NEXT: EntrySize: 0
// SEC-NEXT: }
.section .text,"ax",@progbits,unique,1
.global _start
@ -51,3 +66,13 @@ R_X86_64_64:
// CHECK: Contents of section .R_X86_64_64:
// CHECK-NEXT: 12000 00200100 00000000
.section .R_X86_64_GOTPCREL,"a",@progbits
.global R_X86_64_GOTPCREL
R_X86_64_GOTPCREL:
.long R_X86_64_GOTPCREL@gotpcrel
// 0x13000 - 0x12008 = 4088
// 4088 = 0xf80f0000 in little endian
// CHECK: Contents of section .R_X86_64_GOTPCREL
// CHECK-NEXT: 12008 f80f0000