[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
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 2c58be3..4d24dd9 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -123,6 +123,14 @@
}
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,
RelIteratorRange<isRela> Rels) {
@@ -153,7 +161,7 @@
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 @@
} 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));
}
}