forked from OSchip/llvm-project
Add support for relocating R_X86_64_GOTPCREL.
llvm-svn: 248425
This commit is contained in:
parent
5c3f9d516d
commit
cdfecffd80
|
|
@ -50,6 +50,7 @@ void InputSection<ELFT>::relocate(
|
||||||
const SymbolBody *Body = File.getSymbolBody(SymIndex);
|
const SymbolBody *Body = File.getSymbolBody(SymIndex);
|
||||||
if (!Body)
|
if (!Body)
|
||||||
continue;
|
continue;
|
||||||
|
uint32_t OrigType = Type;
|
||||||
switch (Body->kind()) {
|
switch (Body->kind()) {
|
||||||
case SymbolBody::DefinedRegularKind:
|
case SymbolBody::DefinedRegularKind:
|
||||||
SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));
|
SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));
|
||||||
|
|
@ -63,15 +64,12 @@ void InputSection<ELFT>::relocate(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolBody::SharedKind:
|
case SymbolBody::SharedKind:
|
||||||
if (Target->relocNeedsPlt(Type)) {
|
if (Target->relocNeedsPlt(Type))
|
||||||
SymVA = PltSec.getEntryAddr(*Body);
|
|
||||||
Type = Target->getPCRelReloc();
|
Type = Target->getPCRelReloc();
|
||||||
} else if (Target->relocNeedsGot(Type)) {
|
else if (Target->relocNeedsGot(Type))
|
||||||
SymVA = GotSec.getEntryAddr(*Body);
|
|
||||||
Type = Target->getPCRelReloc();
|
Type = Target->getPCRelReloc();
|
||||||
} else {
|
else
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case SymbolBody::UndefinedKind:
|
case SymbolBody::UndefinedKind:
|
||||||
assert(Body->isWeak() && "Undefined symbol reached writer");
|
assert(Body->isWeak() && "Undefined symbol reached writer");
|
||||||
|
|
@ -80,6 +78,11 @@ void InputSection<ELFT>::relocate(
|
||||||
case SymbolBody::LazyKind:
|
case SymbolBody::LazyKind:
|
||||||
llvm_unreachable("Lazy symbol reached writer");
|
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,
|
Target->relocateOne(Buf, reinterpret_cast<const void *>(&RI), Type,
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ void X86_64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
|
||||||
uint8_t *Location = Buf + Offset;
|
uint8_t *Location = Buf + Offset;
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case R_X86_64_PC32:
|
case R_X86_64_PC32:
|
||||||
|
case R_X86_64_GOTPCREL:
|
||||||
support::endian::write32le(Location,
|
support::endian::write32le(Location,
|
||||||
SymVA + Rel.r_addend - (BaseAddr + Offset));
|
SymVA + Rel.r_addend - (BaseAddr + Offset));
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -255,9 +255,6 @@ void Writer<ELFT>::scanRelocs(
|
||||||
SymbolBody *Body = File.getSymbolBody(SymIndex);
|
SymbolBody *Body = File.getSymbolBody(SymIndex);
|
||||||
if (!Body)
|
if (!Body)
|
||||||
continue;
|
continue;
|
||||||
auto *S = dyn_cast<SharedSymbol<ELFT>>(Body);
|
|
||||||
if (!S)
|
|
||||||
continue;
|
|
||||||
uint32_t Type = RI.getType(IsMips64EL);
|
uint32_t Type = RI.getType(IsMips64EL);
|
||||||
if (Target->relocNeedsPlt(Type)) {
|
if (Target->relocNeedsPlt(Type)) {
|
||||||
if (Body->isInPlt())
|
if (Body->isInPlt())
|
||||||
|
|
@ -269,7 +266,9 @@ void Writer<ELFT>::scanRelocs(
|
||||||
continue;
|
continue;
|
||||||
GotSec.addEntry(Body);
|
GotSec.addEntry(Body);
|
||||||
}
|
}
|
||||||
S->setUsedInDynamicReloc();
|
if (!isa<SharedSymbol<ELFT>>(Body))
|
||||||
|
continue;
|
||||||
|
Body->setUsedInDynamicReloc();
|
||||||
RelaDynSec.addReloc({C, RI});
|
RelaDynSec.addReloc({C, RI});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -395,11 +394,11 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
||||||
OutputSections.push_back(&DynStrSec);
|
OutputSections.push_back(&DynStrSec);
|
||||||
if (RelaDynSec.hasRelocs())
|
if (RelaDynSec.hasRelocs())
|
||||||
OutputSections.push_back(&RelaDynSec);
|
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(),
|
std::stable_sort(OutputSections.begin(), OutputSections.end(),
|
||||||
compSec<ELFT::Is64Bits>);
|
compSec<ELFT::Is64Bits>);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,23 @@
|
||||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
|
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
|
||||||
// RUN: lld -flavor gnu2 %t -o %t2
|
// 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
|
// RUN: llvm-objdump -s -d %t2 | FileCheck %s
|
||||||
// REQUIRES: x86
|
// 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
|
.section .text,"ax",@progbits,unique,1
|
||||||
.global _start
|
.global _start
|
||||||
|
|
@ -51,3 +66,13 @@ R_X86_64_64:
|
||||||
|
|
||||||
// CHECK: Contents of section .R_X86_64_64:
|
// CHECK: Contents of section .R_X86_64_64:
|
||||||
// CHECK-NEXT: 12000 00200100 00000000
|
// 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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue