[lld] r248319 - Move relocation processing to Target.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 13:54:08 PDT 2015
Author: rafael
Date: Tue Sep 22 15:54:08 2015
New Revision: 248319
URL: http://llvm.org/viewvc/llvm-project?rev=248319&view=rev
Log:
Move relocation processing to Target.
I will add a couple of ppc64 relocs in the next patches.
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Target.h
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Sep 22 15:54:08 2015
@@ -13,8 +13,6 @@
#include "OutputSections.h"
#include "Target.h"
-#include "llvm/Support/raw_ostream.h"
-
using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
@@ -27,57 +25,6 @@ InputSection<ELFT>::InputSection(ObjectF
: File(F), Header(Header) {}
template <class ELFT>
-void InputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rel &Rel,
- uint32_t Type, uintX_t BaseAddr,
- uintX_t SymVA) {
- uintX_t Offset = Rel.r_offset;
- uint8_t *Location = Buf + Offset;
- uint32_t Addend = *(support::ulittle32_t *)Location;
- switch (Type) {
- case R_386_PC32:
- support::endian::write32le(Location, SymVA + Addend - (BaseAddr + Offset));
- break;
- case R_386_32:
- support::endian::write32le(Location, SymVA + Addend);
- break;
- default:
- llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';
- break;
- }
-}
-
-template <class ELFT>
-void InputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rela &Rel,
- uint32_t Type, uintX_t BaseAddr,
- uintX_t SymVA) {
- uintX_t Offset = Rel.r_offset;
- uint8_t *Location = Buf + Offset;
- switch (Type) {
- case R_X86_64_PC32:
- support::endian::write32le(Location,
- SymVA + Rel.r_addend - (BaseAddr + Offset));
- break;
- case R_X86_64_64:
- support::endian::write64le(Location, SymVA + Rel.r_addend);
- break;
- case R_X86_64_32: {
- case R_X86_64_32S:
- uint64_t VA = SymVA + Rel.r_addend;
- if (Type == R_X86_64_32 && !isUInt<32>(VA))
- error("R_X86_64_32 out of range");
- else if (!isInt<32>(VA))
- error("R_X86_64_32S out of range");
-
- support::endian::write32le(Location, VA);
- break;
- }
- default:
- llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';
- break;
- }
-}
-
-template <class ELFT>
template <bool isRela>
void InputSection<ELFT>::relocate(
uint8_t *Buf, iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,
@@ -134,7 +81,8 @@ void InputSection<ELFT>::relocate(
}
}
- relocateOne(Buf, RI, Type, BaseAddr, SymVA);
+ Target->relocateOne(Buf, reinterpret_cast<const void *>(&RI), Type,
+ BaseAddr, SymVA);
}
}
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Tue Sep 22 15:54:08 2015
@@ -60,11 +60,6 @@ public:
SmallVector<const Elf_Shdr *, 1> RelocSections;
private:
- void relocateOne(uint8_t *Buf, const Elf_Rela &Rel, uint32_t Type,
- uintX_t BaseAddr, uintX_t SymVA);
- void relocateOne(uint8_t *Buf, const Elf_Rel &Rel, uint32_t Type,
- uintX_t BaseAddr, uintX_t SymVA);
-
template <bool isRela>
void relocate(uint8_t *Buf,
llvm::iterator_range<
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Sep 22 15:54:08 2015
@@ -40,7 +40,9 @@ void SymbolTable::addFile(std::unique_pt
}
template <class ELFT> void SymbolTable::init(uint16_t EMachine) {
- if (EMachine == EM_X86_64)
+ if (EMachine == EM_PPC64)
+ Target.reset(new PPC64TargetInfo());
+ else if (EMachine == EM_X86_64)
Target.reset(new X86_64TargetInfo());
else
Target.reset(new X86TargetInfo());
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Tue Sep 22 15:54:08 2015
@@ -8,12 +8,15 @@
//===----------------------------------------------------------------------===//
#include "Target.h"
+#include "Error.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ELF.h"
using namespace llvm;
+using namespace llvm::object;
using namespace llvm::ELF;
namespace lld {
@@ -59,6 +62,27 @@ bool X86TargetInfo::relocNeedsPlt(uint32
}
}
+void X86TargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+ uint64_t BaseAddr, uint64_t SymVA) const {
+ typedef ELFFile<ELF32LE>::Elf_Rel Elf_Rel;
+ auto &Rel = *reinterpret_cast<const Elf_Rel *>(RelP);
+
+ uint32_t Offset = Rel.r_offset;
+ uint8_t *Location = Buf + Offset;
+ uint32_t Addend = *(support::ulittle32_t *)Location;
+ switch (Type) {
+ case R_386_PC32:
+ support::endian::write32le(Location, SymVA + Addend - (BaseAddr + Offset));
+ break;
+ case R_386_32:
+ support::endian::write32le(Location, SymVA + Addend);
+ break;
+ default:
+ error(Twine("unrecognized reloc ") + Twine(Type));
+ break;
+ }
+}
+
X86_64TargetInfo::X86_64TargetInfo() { PCRelReloc = R_X86_64_PC32; }
void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -96,5 +120,48 @@ bool X86_64TargetInfo::relocNeedsPlt(uin
return true;
}
}
+
+void X86_64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
+ uint32_t Type, uint64_t BaseAddr,
+ uint64_t SymVA) const {
+ typedef ELFFile<ELF64LE>::Elf_Rela Elf_Rela;
+ auto &Rel = *reinterpret_cast<const Elf_Rela *>(RelP);
+
+ uint64_t Offset = Rel.r_offset;
+ uint8_t *Location = Buf + Offset;
+ switch (Type) {
+ case R_X86_64_PC32:
+ support::endian::write32le(Location,
+ SymVA + Rel.r_addend - (BaseAddr + Offset));
+ break;
+ case R_X86_64_64:
+ support::endian::write64le(Location, SymVA + Rel.r_addend);
+ break;
+ case R_X86_64_32: {
+ case R_X86_64_32S:
+ uint64_t VA = SymVA + Rel.r_addend;
+ if (Type == R_X86_64_32 && !isUInt<32>(VA))
+ error("R_X86_64_32 out of range");
+ else if (!isInt<32>(VA))
+ error("R_X86_64_32S out of range");
+
+ support::endian::write32le(Location, VA);
+ break;
+ }
+ default:
+ error(Twine("unrecognized reloc ") + Twine(Type));
+ break;
+ }
+}
+
+PPC64TargetInfo::PPC64TargetInfo() {
+ // PCRelReloc = FIXME
+}
+void PPC64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
+ uint64_t PltEntryAddr) const {}
+bool PPC64TargetInfo::relocNeedsGot(uint32_t Type) const { return false; }
+bool PPC64TargetInfo::relocNeedsPlt(uint32_t Type) const { return false; }
+void PPC64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+ uint64_t BaseAddr, uint64_t SymVA) const {}
}
}
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Tue Sep 22 15:54:08 2015
@@ -23,6 +23,9 @@ public:
uint64_t PltEntryAddr) const = 0;
virtual bool relocNeedsGot(uint32_t Type) const = 0;
virtual bool relocNeedsPlt(uint32_t Type) const = 0;
+ virtual void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+ uint64_t BaseAddr, uint64_t SymVA) const = 0;
+
virtual ~TargetInfo();
protected:
@@ -36,6 +39,8 @@ public:
uint64_t PltEntryAddr) const override;
bool relocNeedsGot(uint32_t Type) const override;
bool relocNeedsPlt(uint32_t Type) const override;
+ void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+ uint64_t BaseAddr, uint64_t SymVA) const override;
};
class X86_64TargetInfo final : public TargetInfo {
@@ -45,6 +50,19 @@ public:
uint64_t PltEntryAddr) const override;
bool relocNeedsGot(uint32_t Type) const override;
bool relocNeedsPlt(uint32_t Type) const override;
+ void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+ uint64_t BaseAddr, uint64_t SymVA) const override;
+};
+
+class PPC64TargetInfo final : public TargetInfo {
+public:
+ PPC64TargetInfo();
+ void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
+ uint64_t PltEntryAddr) const override;
+ bool relocNeedsGot(uint32_t Type) const override;
+ bool relocNeedsPlt(uint32_t Type) const override;
+ void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+ uint64_t BaseAddr, uint64_t SymVA) const override;
};
extern std::unique_ptr<TargetInfo> Target;
More information about the llvm-commits
mailing list