[ELF] - R_X86_64_SIZE64/R_X86_64_SIZE32 relocations implemented.

R_X86_64_SIZE64/R_X86_64_SIZE32 relocations were introduced in 0.98v of "System V Application Binary Interface x86-64" (http://www.x86-64.org/documentation/abi.pdf).

Calculation for them is Z + A, where:
Z - Represents the size of the symbol whose index resides in the relocation entry.
A - Represents the addend used to compute the value of the relocatable field.

Differential revision: http://reviews.llvm.org/D15335

llvm-svn: 255332
This commit is contained in:
George Rimar 2015-12-11 08:59:37 +00:00
parent 1dbfca60f8
commit 48651489b3
6 changed files with 257 additions and 15 deletions

View File

@ -122,6 +122,14 @@ InputSectionBase<ELFT>::findMipsPairedReloc(uint8_t *Buf, uint32_t Type,
return nullptr;
}
template <class ELFT>
static typename llvm::object::ELFFile<ELFT>::uintX_t
getSymSize(SymbolBody &Body) {
if (auto *SS = dyn_cast<Defined<ELFT>>(&Body))
return SS->Sym.st_size;
return 0;
}
template <class ELFT>
template <bool isRela>
void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
@ -153,7 +161,7 @@ void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
const Elf_Shdr *SymTab = File->getSymbolTable();
if (SymIndex < SymTab->sh_info) {
uintX_t SymVA = getLocalRelTarget(*File, RI);
Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA,
Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, 0,
findMipsPairedReloc(Buf, Type, NextRelocs));
continue;
}
@ -191,11 +199,13 @@ void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
} else if (!Target->relocNeedsCopy(Type, Body) &&
isa<SharedSymbol<ELFT>>(Body)) {
continue;
} else if (Target->isTlsDynReloc(Type)) {
} else if (Target->isTlsDynReloc(Type) ||
Target->isSizeDynReloc(Type, Body)) {
continue;
}
Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
SymVA + getAddend<ELFT>(RI),
uintX_t A = getAddend<ELFT>(RI);
uintX_t Size = getSymSize<ELFT>(Body);
Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA + A, Size + A,
findMipsPairedReloc(Buf, Type, NextRelocs));
}
}

View File

@ -87,7 +87,8 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
uint64_t SA, uint64_t ZA = 0,
uint8_t *PairedLoc = nullptr) const override;
bool isTlsOptimized(unsigned Type, const SymbolBody *S) const override;
unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA,
@ -120,9 +121,11 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
uint64_t SA, uint64_t ZA = 0,
uint8_t *PairedLoc = nullptr) const override;
bool isRelRelative(uint32_t Type) const override;
bool isTlsOptimized(unsigned Type, const SymbolBody *S) const override;
bool isSizeDynReloc(uint32_t Type, const SymbolBody &S) const override;
unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA,
const SymbolBody &S) const override;
@ -150,7 +153,8 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
uint64_t SA, uint64_t ZA = 0,
uint8_t *PairedLoc = nullptr) const override;
bool isRelRelative(uint32_t Type) const override;
};
@ -169,7 +173,8 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
uint64_t SA, uint64_t ZA = 0,
uint8_t *PairedLoc = nullptr) const override;
};
template <class ELFT> class MipsTargetInfo final : public TargetInfo {
@ -185,7 +190,8 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
uint64_t SA, uint64_t ZA = 0,
uint8_t *PairedLoc = nullptr) const override;
};
} // anonymous namespace
@ -228,6 +234,10 @@ unsigned TargetInfo::getPltRefReloc(unsigned Type) const { return PCRelReloc; }
bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
bool TargetInfo::isSizeDynReloc(uint32_t Type, const SymbolBody &S) const {
return false;
}
unsigned TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P, uint64_t SA,
const SymbolBody &S) const {
@ -338,7 +348,7 @@ bool X86TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
}
void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA,
uint64_t P, uint64_t SA, uint64_t ZA,
uint8_t *PairedLoc) const {
switch (Type) {
case R_386_32:
@ -623,10 +633,18 @@ bool X86_64TargetInfo::isRelRelative(uint32_t Type) const {
case R_X86_64_PC32:
case R_X86_64_PC64:
case R_X86_64_PLT32:
case R_X86_64_SIZE32:
case R_X86_64_SIZE64:
return true;
}
}
bool X86_64TargetInfo::isSizeDynReloc(uint32_t Type,
const SymbolBody &S) const {
return (Type == R_X86_64_SIZE32 || Type == R_X86_64_SIZE64) &&
canBePreempted(&S, false);
}
bool X86_64TargetInfo::isTlsOptimized(unsigned Type,
const SymbolBody *S) const {
if (Config->Shared || (S && !S->isTLS()))
@ -767,7 +785,7 @@ unsigned X86_64TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
}
void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA,
uint64_t P, uint64_t SA, uint64_t ZA,
uint8_t *PairedLoc) const {
switch (Type) {
case R_X86_64_32:
@ -794,6 +812,12 @@ void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
case R_X86_64_TLSLD:
write32le(Loc, SA - P);
break;
case R_X86_64_SIZE32:
write32le(Loc, ZA);
break;
case R_X86_64_SIZE64:
write64le(Loc, ZA);
break;
case R_X86_64_TPOFF32: {
uint64_t Val = SA - Out<ELF64LE>::TlsPhdr->p_memsz;
checkInt<32>(Val, Type);
@ -915,7 +939,7 @@ bool PPC64TargetInfo::isRelRelative(uint32_t Type) const {
}
void PPC64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA,
uint64_t P, uint64_t SA, uint64_t ZA,
uint8_t *PairedLoc) const {
uint64_t TB = getPPC64TocBase();
@ -1153,7 +1177,7 @@ static uint64_t getAArch64Page(uint64_t Expr) {
void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P, uint64_t SA,
uint8_t *PairedLoc) const {
uint64_t ZA, uint8_t *PairedLoc) const {
switch (Type) {
case R_AARCH64_ABS16:
checkIntUInt<16>(SA, Type);
@ -1266,7 +1290,7 @@ bool MipsTargetInfo<ELFT>::relocNeedsPlt(uint32_t Type,
template <class ELFT>
void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P, uint64_t SA,
uint8_t *PairedLoc) const {
uint64_t ZA, uint8_t *PairedLoc) const {
const endianness E = ELFT::TargetEndianness;
switch (Type) {
case R_MIPS_32:

View File

@ -53,11 +53,12 @@ public:
uint64_t GotEntryAddr, uint64_t PltEntryAddr,
int32_t Index, unsigned RelOff) const = 0;
virtual bool isRelRelative(uint32_t Type) const;
virtual bool isSizeDynReloc(uint32_t Type, const SymbolBody &S) const;
virtual bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const;
virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0;
virtual bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const = 0;
virtual void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA,
uint64_t P, uint64_t SA, uint64_t ZA = 0,
uint8_t *PairedLoc = nullptr) const = 0;
virtual bool isTlsOptimized(unsigned Type, const SymbolBody *S) const;
virtual unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,

View File

@ -0,0 +1,6 @@
.data
.global fooshared
.type fooshared,%object
.size fooshared,26
fooshared:
.zero 26

View File

@ -0,0 +1,78 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocation-size-shared.s -o %tso.o
// RUN: ld.lld -shared %tso.o -o %tso
// RUN: ld.lld %t.o %tso -o %t1
// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOCSHARED %s
// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
// RELOCSHARED: Relocations [
// RELOCSHARED-NEXT: Section ({{.*}}) .rela.dyn {
// RELOCSHARED-NEXT: 0x11018 R_X86_64_SIZE64 fooshared 0xFFFFFFFFFFFFFFFF
// RELOCSHARED-NEXT: 0x11020 R_X86_64_SIZE64 fooshared 0x0
// RELOCSHARED-NEXT: 0x11028 R_X86_64_SIZE64 fooshared 0x1
// RELOCSHARED-NEXT: 0x11048 R_X86_64_SIZE32 fooshared 0xFFFFFFFFFFFFFFFF
// RELOCSHARED-NEXT: 0x1104F R_X86_64_SIZE32 fooshared 0x0
// RELOCSHARED-NEXT: 0x11056 R_X86_64_SIZE32 fooshared 0x1
// RELOCSHARED-NEXT: }
// RELOCSHARED-NEXT:]
// DISASM: Disassembly of section .text:
// DISASM: _data:
// DISASM-NEXT: 11000: 19 00
// DISASM-NEXT: 11002: 00 00
// DISASM-NEXT: 11004: 00 00
// DISASM-NEXT: 11006: 00 00
// DISASM-NEXT: 11008: 1a 00
// DISASM-NEXT: 1100a: 00 00
// DISASM-NEXT: 1100c: 00 00
// DISASM-NEXT: 1100e: 00 00
// DISASM-NEXT: 11010: 1b 00
// DISASM-NEXT: 11012: 00 00
// DISASM-NEXT: 11014: 00 00
// DISASM-NEXT: 11016: 00 00
// DISASM-NEXT: 11018: 00 00
// DISASM-NEXT: 1101a: 00 00
// DISASM-NEXT: 1101c: 00 00
// DISASM-NEXT: 1101e: 00 00
// DISASM-NEXT: 11020: 00 00
// DISASM-NEXT: 11022: 00 00
// DISASM-NEXT: 11024: 00 00
// DISASM-NEXT: 11026: 00 00
// DISASM-NEXT: 11028: 00 00
// DISASM-NEXT: 1102a: 00 00
// DISASM-NEXT: 1102c: 00 00
// DISASM-NEXT: 1102e: 00 00
// DISASM: _start:
// DISASM-NEXT: 11030: 8b 04 25 19 00 00 00 movl 25, %eax
// DISASM-NEXT: 11037: 8b 04 25 1a 00 00 00 movl 26, %eax
// DISASM-NEXT: 1103e: 8b 04 25 1b 00 00 00 movl 27, %eax
// DISASM-NEXT: 11045: 8b 04 25 00 00 00 00 movl 0, %eax
// DISASM-NEXT: 1104c: 8b 04 25 00 00 00 00 movl 0, %eax
// DISASM-NEXT: 11053: 8b 04 25 00 00 00 00 movl 0, %eax
.data
.global foo
.type foo,%object
.size foo,26
foo:
.zero 26
.text
_data:
// R_X86_64_SIZE64:
.quad foo@SIZE-1
.quad foo@SIZE
.quad foo@SIZE+1
.quad fooshared@SIZE-1
.quad fooshared@SIZE
.quad fooshared@SIZE+1
.globl _start
_start:
// R_X86_64_SIZE32:
movl foo@SIZE-1,%eax
movl foo@SIZE,%eax
movl foo@SIZE+1,%eax
movl fooshared@SIZE-1,%eax
movl fooshared@SIZE,%eax
movl fooshared@SIZE+1,%eax

View File

@ -0,0 +1,123 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
// RUN: ld.lld %t.o -o %t1
// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s
// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
// RUN: ld.lld -shared %t.o -o %t1
// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOCSHARED %s
// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s
// NORELOC: Relocations [
// NORELOC-NEXT: ]
// DISASM: Disassembly of section .text:
// DISASM-NEXT: _data:
// DISASM-NEXT: 11000: 19 00
// DISASM-NEXT: 11002: 00 00
// DISASM-NEXT: 11004: 00 00
// DISASM-NEXT: 11006: 00 00
// DISASM-NEXT: 11008: 1a 00
// DISASM-NEXT: 1100a: 00 00
// DISASM-NEXT: 1100c: 00 00
// DISASM-NEXT: 1100e: 00 00
// DISASM-NEXT: 11010: 1b 00
// DISASM-NEXT: 11012: 00 00
// DISASM-NEXT: 11014: 00 00
// DISASM-NEXT: 11016: 00 00
// DISASM-NEXT: 11018: 19 00
// DISASM-NEXT: 1101a: 00 00
// DISASM-NEXT: 1101c: 00 00
// DISASM-NEXT: 1101e: 00 00
// DISASM-NEXT: 11020: 1a 00
// DISASM-NEXT: 11022: 00 00
// DISASM-NEXT: 11024: 00 00
// DISASM-NEXT: 11026: 00 00
// DISASM-NEXT: 11028: 1b 00
// DISASM-NEXT: 1102a: 00 00
// DISASM-NEXT: 1102c: 00 00
// DISASM-NEXT: 1102e: 00 00
// DISASM: _start:
// DISASM-NEXT: 11030: 8b 04 25 19 00 00 00 movl 25, %eax
// DISASM-NEXT: 11037: 8b 04 25 1a 00 00 00 movl 26, %eax
// DISASM-NEXT: 1103e: 8b 04 25 1b 00 00 00 movl 27, %eax
// DISASM-NEXT: 11045: 8b 04 25 19 00 00 00 movl 25, %eax
// DISASM-NEXT: 1104c: 8b 04 25 1a 00 00 00 movl 26, %eax
// DISASM-NEXT: 11053: 8b 04 25 1b 00 00 00 movl 27, %eax
// RELOCSHARED: Relocations [
// RELOCSHARED-NEXT: Section ({{.*}}) .rela.dyn {
// RELOCSHARED-NEXT: 0x1000 R_X86_64_SIZE64 foo 0xFFFFFFFFFFFFFFFF
// RELOCSHARED-NEXT: 0x1008 R_X86_64_SIZE64 foo 0x0
// RELOCSHARED-NEXT: 0x1010 R_X86_64_SIZE64 foo 0x1
// RELOCSHARED-NEXT: 0x1033 R_X86_64_SIZE32 foo 0xFFFFFFFFFFFFFFFF
// RELOCSHARED-NEXT: 0x103A R_X86_64_SIZE32 foo 0x0
// RELOCSHARED-NEXT: 0x1041 R_X86_64_SIZE32 foo 0x1
// RELOCSHARED-NEXT: }
// RELOCSHARED-NEXT: ]
// DISASMSHARED: Disassembly of section .text:
// DISASMSHARED-NEXT: _data:
// DISASMSHARED-NEXT: 1000: 00 00
// DISASMSHARED-NEXT: 1002: 00 00
// DISASMSHARED-NEXT: 1004: 00 00
// DISASMSHARED-NEXT: 1006: 00 00
// DISASMSHARED-NEXT: 1008: 00 00
// DISASMSHARED-NEXT: 100a: 00 00
// DISASMSHARED-NEXT: 100c: 00 00
// DISASMSHARED-NEXT: 100e: 00 00
// DISASMSHARED-NEXT: 1010: 00 00
// DISASMSHARED-NEXT: 1012: 00 00
// DISASMSHARED-NEXT: 1014: 00 00
// DISASMSHARED-NEXT: 1016: 00 00
// DISASMSHARED-NEXT: 1018: 19 00
// DISASMSHARED-NEXT: 101a: 00 00
// DISASMSHARED-NEXT: 101c: 00 00
// DISASMSHARED-NEXT: 101e: 00 00
// DISASMSHARED-NEXT: 1020: 1a 00
// DISASMSHARED-NEXT: 1022: 00 00
// DISASMSHARED-NEXT: 1024: 00 00
// DISASMSHARED-NEXT: 1026: 00 00
// DISASMSHARED-NEXT: 1028: 1b 00
// DISASMSHARED-NEXT: 102a: 00 00
// DISASMSHARED-NEXT: 102c: 00 00
// DISASMSHARED-NEXT: 102e: 00 00
// DISASMSHARED: _start:
// DISASMSHARED-NEXT: 1030: 8b 04 25 00 00 00 00 movl 0, %eax
// DISASMSHARED-NEXT: 1037: 8b 04 25 00 00 00 00 movl 0, %eax
// DISASMSHARED-NEXT: 103e: 8b 04 25 00 00 00 00 movl 0, %eax
// DISASMSHARED-NEXT: 1045: 8b 04 25 19 00 00 00 movl 25, %eax
// DISASMSHARED-NEXT: 104c: 8b 04 25 1a 00 00 00 movl 26, %eax
// DISASMSHARED-NEXT: 1053: 8b 04 25 1b 00 00 00 movl 27, %eax
.data
.global foo
.type foo,%object
.size foo,26
foo:
.zero 26
.data
.global foohidden
.hidden foohidden
.type foohidden,%object
.size foohidden,26
foohidden:
.zero 26
.text
_data:
// R_X86_64_SIZE64:
.quad foo@SIZE-1
.quad foo@SIZE
.quad foo@SIZE+1
.quad foohidden@SIZE-1
.quad foohidden@SIZE
.quad foohidden@SIZE+1
.globl _start
_start:
// R_X86_64_SIZE32:
movl foo@SIZE-1,%eax
movl foo@SIZE,%eax
movl foo@SIZE+1,%eax
movl foohidden@SIZE-1,%eax
movl foohidden@SIZE,%eax
movl foohidden@SIZE+1,%eax