[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:
Shankar Easwaran 2013-05-17 05:10:30 +00:00
parent f9a7933d90
commit 9af77a2cab
8 changed files with 64 additions and 14 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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;
};

View File

@ -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);

View File

@ -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;
};

View File

@ -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;

View File

@ -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: