forked from OSchip/llvm-project
[lld][ELF][All Archs] Addend is used by dynamic relocations
only if they are relative. This removes the FIXME when the relocations are being emitted and checks if the relocation is relative and only then populates the addend information. I couldnt add a testcase for this as llvm-readobj lacks functionality of printing dynamic relocations. When the functionality is added, remove the commented lines from elf/ifunc.test to test functionality. llvm-svn: 182077
This commit is contained in:
parent
f9a7933d90
commit
9af77a2cab
|
@ -86,7 +86,10 @@ public:
|
|||
}
|
||||
|
||||
/// \brief Does the output have dynamic sections.
|
||||
bool isDynamic() const;
|
||||
virtual bool isDynamic() const;
|
||||
|
||||
/// \brief Is the relocation a relative relocation
|
||||
virtual bool isRelativeReloc(const Reference &r) const;
|
||||
|
||||
template <typename ELFT>
|
||||
lld::elf::TargetHandler<ELFT> &getTargetHandler() const {
|
||||
|
|
|
@ -91,8 +91,11 @@ bool ELFTargetInfo::isDynamic() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
error_code ELFTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
|
||||
std::vector<std::unique_ptr<File>> &result) const {
|
||||
bool ELFTargetInfo::isRelativeReloc(const Reference &) const { return false; }
|
||||
|
||||
error_code
|
||||
ELFTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
|
||||
std::vector<std::unique_ptr<File> > &result) const {
|
||||
error_code ec = _elfReader->parseFile(mb, result);
|
||||
if (ec) {
|
||||
// Not an ELF file, check file extension to see if it might be yaml
|
||||
|
|
|
@ -22,8 +22,9 @@ namespace elf {
|
|||
|
||||
class HexagonTargetInfo LLVM_FINAL : public ELFTargetInfo {
|
||||
public:
|
||||
HexagonTargetInfo(llvm::Triple triple)
|
||||
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(new HexagonTargetHandler(*this))) {}
|
||||
HexagonTargetInfo(llvm::Triple triple)
|
||||
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(
|
||||
new HexagonTargetHandler(*this))) {}
|
||||
|
||||
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
|
||||
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
|
||||
|
@ -50,6 +51,17 @@ public:
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Hexagon has only one relative relocation
|
||||
/// a) for supporting relative relocs - R_HEX_RELATIVE
|
||||
virtual bool isRelativeReloc(const Reference &r) const {
|
||||
switch (r.kind()) {
|
||||
case llvm::ELF::R_HEX_RELATIVE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // elf
|
||||
|
|
|
@ -25,6 +25,10 @@ public:
|
|||
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(new PPCTargetHandler(*this))) {}
|
||||
|
||||
virtual bool isLittleEndian() const { return false; }
|
||||
|
||||
/// \brief PPC has no relative relocations defined
|
||||
virtual bool isRelativeReloc(const Reference &) const { return false; }
|
||||
|
||||
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
|
||||
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
|
||||
};
|
||||
|
|
|
@ -933,10 +933,9 @@ public:
|
|||
r->setSymbolAndType(index, rel.second->kind());
|
||||
r->r_offset =
|
||||
writer->addressOfAtom(rel.first) + rel.second->offsetInAtom();
|
||||
// FIXME: The addend is used only by IRELATIVE relocations while static
|
||||
// linking executable statically, check to see how does dynamic linking
|
||||
// work with IFUNC and change accordingly
|
||||
if (!this->_targetInfo.isDynamic())
|
||||
r->r_addend = 0;
|
||||
// The addend is used only by relative relocations
|
||||
if (this->_targetInfo.isRelativeReloc(*rel.second))
|
||||
r->r_addend =
|
||||
writer->addressOfAtom(rel.second->target()) + rel.second->addend();
|
||||
dest += sizeof(Elf_Rela);
|
||||
|
|
|
@ -21,9 +21,22 @@ namespace lld {
|
|||
namespace elf {
|
||||
class X86TargetInfo LLVM_FINAL : public ELFTargetInfo {
|
||||
public:
|
||||
X86TargetInfo(llvm::Triple triple)
|
||||
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(new X86TargetHandler(*this))) {}
|
||||
X86TargetInfo(llvm::Triple triple)
|
||||
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(
|
||||
new X86TargetHandler(*this))) {}
|
||||
|
||||
/// \brief X86 has only two relative relocation
|
||||
/// a) for supporting IFUNC relocs - R_386_IRELATIVE
|
||||
/// b) for supporting relative relocs - R_386_RELATIVE
|
||||
virtual bool isRelativeReloc(const Reference &r) const {
|
||||
switch (r.kind()) {
|
||||
case llvm::ELF::R_386_IRELATIVE:
|
||||
case llvm::ELF::R_386_RELATIVE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
|
||||
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
|
||||
};
|
||||
|
|
|
@ -28,8 +28,9 @@ enum {
|
|||
|
||||
class X86_64TargetInfo LLVM_FINAL : public ELFTargetInfo {
|
||||
public:
|
||||
X86_64TargetInfo(llvm::Triple triple)
|
||||
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(new X86_64TargetHandler(*this))) {}
|
||||
X86_64TargetInfo(llvm::Triple triple)
|
||||
: ELFTargetInfo(triple, std::unique_ptr<TargetHandlerBase>(
|
||||
new X86_64TargetHandler(*this))) {}
|
||||
|
||||
virtual void addPasses(PassManager &) const;
|
||||
|
||||
|
@ -61,6 +62,19 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/// \brief X86_64 has two relative relocations
|
||||
/// a) for supporting IFUNC - R_X86_64_IRELATIVE
|
||||
/// b) for supporting relative relocs - R_X86_64_RELATIVE
|
||||
virtual bool isRelativeReloc(const Reference &r) const {
|
||||
switch (r.kind()) {
|
||||
case llvm::ELF::R_X86_64_IRELATIVE:
|
||||
case llvm::ELF::R_X86_64_RELATIVE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
|
||||
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@ RUN: | FileCheck %s --check-prefix=PLT
|
|||
RUN: lld -flavor gnu -target x86_64-linux -o %t %p/Inputs/ifunc.x86-64 \
|
||||
RUN: -e main -static %p/Inputs/ifunc.cpp.x86-64 \
|
||||
RUN: && llvm-objdump -d -s %t| FileCheck %s --check-prefix=BIN
|
||||
|
||||
#REMOVE THE BELOW LINE WHEN llvm-readobj adds functionality to print
|
||||
#Dynamic relocations
|
||||
#llvm-readobj -r %t | FileCheck %s --check-prefix=RELATIVEADDEND
|
||||
|
||||
PLT: defined-atoms:
|
||||
|
||||
|
|
Loading…
Reference in New Issue