[lld] r173897 - [ELF][x86-64] Add X86_64TargetRelocationHandler and friends.

Michael J. Spencer bigcheesegs at gmail.com
Tue Jan 29 21:26:04 PST 2013


Author: mspencer
Date: Tue Jan 29 23:26:03 2013
New Revision: 173897

URL: http://llvm.org/viewvc/llvm-project?rev=173897&view=rev
Log:
[ELF][x86-64] Add X86_64TargetRelocationHandler and friends.

Added:
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
Modified:
    lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt?rev=173897&r1=173896&r2=173897&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt Tue Jan 29 23:26:03 2013
@@ -1,5 +1,6 @@
 add_lld_library(lldX86_64ELFTarget
   X86_64TargetInfo.cpp
+  X86_64TargetHandler.cpp
   )
 
 target_link_libraries(lldX86_64ELFTarget

Added: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp?rev=173897&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp Tue Jan 29 23:26:03 2013
@@ -0,0 +1,90 @@
+//===- lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp ----------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86_64TargetHandler.h"
+#include "X86_64TargetInfo.h"
+
+using namespace lld;
+using namespace elf;
+
+using namespace llvm::ELF;
+
+namespace {
+/// \brief R_X86_64_64 - word64: S + A
+void reloc64(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
+  uint64_t result = S + A;
+  *reinterpret_cast<llvm::support::ulittle64_t *>(location) = result |
+            (uint64_t)*reinterpret_cast<llvm::support::ulittle64_t *>(location);
+}
+
+/// \brief R_X86_64_PC32 - word32: S + A - P
+void relocPC32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
+  uint32_t result = (uint32_t)((S + A) - P);
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) = result +
+            (uint32_t)*reinterpret_cast<llvm::support::ulittle32_t *>(location);
+}
+
+/// \brief R_X86_64_32 - word32:  S + A
+void reloc32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
+  int32_t result = (uint32_t)(S + A);
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) = result |
+            (uint32_t)*reinterpret_cast<llvm::support::ulittle32_t *>(location);
+  // TODO: Make sure that the result zero extends to the 64bit value.
+}
+
+/// \brief R_X86_64_32S - word32:  S + A
+void reloc32S(uint8_t *location, uint64_t P, uint64_t S, int64_t A) {
+  int32_t result = (int32_t)(S + A);
+  *reinterpret_cast<llvm::support::little32_t *>(location) = result |
+            (int32_t)*reinterpret_cast<llvm::support::little32_t *>(location);
+  // TODO: Make sure that the result sign extends to the 64bit value.
+}
+} // end anon namespace
+
+ErrorOr<void> X86_64TargetRelocationHandler::applyRelocation(
+    ELFWriter &writer, llvm::FileOutputBuffer &buf, const AtomLayout &atom,
+    const Reference &ref) const {
+  uint8_t *atomContent = buf.getBufferStart() + atom._fileOffset;
+  uint8_t *location = atomContent + ref.offsetInAtom();
+  uint64_t targetVAddress = writer.addressOfAtom(ref.target());
+  uint64_t relocVAddress = atom._virtualAddr + ref.offsetInAtom();
+
+  switch (ref.kind()) {
+  case R_X86_64_64:
+    reloc64(location, relocVAddress, targetVAddress, ref.addend());
+    break;
+  case R_X86_64_PC32:
+    relocPC32(location, relocVAddress, targetVAddress, ref.addend());
+    break;
+  case R_X86_64_32:
+    reloc32(location, relocVAddress, targetVAddress, ref.addend());
+    break;
+  case R_X86_64_32S:
+    reloc32S(location, relocVAddress, targetVAddress, ref.addend());
+    break;
+  // Runtime only relocations. Ignore here.
+  case R_X86_64_IRELATIVE:
+    break;
+  default: {
+    std::string str;
+    llvm::raw_string_ostream s(str);
+    auto name = _targetInfo.stringFromRelocKind(ref.kind());
+    s << "Unhandled relocation: "
+      << (name ? *name : "<unknown>" ) << " (" << ref.kind() << ")";
+    s.flush();
+    llvm_unreachable(str.c_str());
+  }
+  }
+
+  return error_code::success();
+}
+
+X86_64TargetHandler::X86_64TargetHandler(X86_64TargetInfo &targetInfo)
+    : DefaultTargetHandler(targetInfo), _relocationHandler(targetInfo) {
+}

Added: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h?rev=173897&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h Tue Jan 29 23:26:03 2013
@@ -0,0 +1,48 @@
+//===- lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h ------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_ELF_X86_64_TARGET_HANDLER_H
+#define LLD_READER_WRITER_ELF_X86_64_TARGET_HANDLER_H
+
+#include "DefaultTargetHandler.h"
+
+namespace lld {
+namespace elf {
+typedef llvm::object::ELFType<llvm::support::little, 8, false> X86_64ELFType;
+class X86_64TargetInfo;
+
+class X86_64TargetRelocationHandler LLVM_FINAL
+    : public TargetRelocationHandler<X86_64ELFType> {
+public:
+  X86_64TargetRelocationHandler(const X86_64TargetInfo &ti) : _targetInfo(ti) {}
+
+  virtual ErrorOr<void> applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
+                                        const AtomLayout &,
+                                        const Reference &)const;
+
+private:
+  const X86_64TargetInfo &_targetInfo;
+};
+
+class X86_64TargetHandler LLVM_FINAL
+    : public DefaultTargetHandler<X86_64ELFType> {
+public:
+  X86_64TargetHandler(X86_64TargetInfo &targetInfo);
+
+  virtual const X86_64TargetRelocationHandler &getRelocationHandler() const {
+    return _relocationHandler;
+  }
+
+private:
+  X86_64TargetRelocationHandler _relocationHandler;
+};
+} // end namespace elf
+} // end namespace lld
+
+#endif

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h?rev=173897&r1=173896&r2=173897&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetInfo.h Tue Jan 29 23:26:03 2013
@@ -10,7 +10,7 @@
 #ifndef LLD_READER_WRITER_ELF_X86_64_TARGETINFO_H
 #define LLD_READER_WRITER_ELF_X86_64_TARGETINFO_H
 
-#include "DefaultTargetHandler.h"
+#include "X86_64TargetHandler.h"
 
 #include "lld/Core/LinkerOptions.h"
 #include "lld/ReaderWriter/ELFTargetInfo.h"
@@ -20,12 +20,13 @@
 
 namespace lld {
 namespace elf {
+typedef llvm::object::ELFType<llvm::support::little, 8, false> X86_64ELFType;
+
 class X86_64TargetInfo LLVM_FINAL : public ELFTargetInfo {
 public:
   X86_64TargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {
-    _targetHandler = std::unique_ptr<TargetHandlerBase>(
-        new DefaultTargetHandler<llvm::object::ELFType<llvm::support::little,
-                                                          8, false> >(*this));
+    _targetHandler =
+        std::unique_ptr<TargetHandlerBase>(new X86_64TargetHandler(*this));
   }
 
   virtual uint64_t getPageSize() const { return 0x1000; }
@@ -47,7 +48,7 @@ public:
   virtual ErrorOr<std::string> stringFromRelocKind(int32_t kind) const;
 
 };
-} // elf
-} // lld
+} // end namespace elf
+} // end namespace lld
 
-#endif // LLD_READER_WRITER_ELF_X86_64_TARGETINFO_H
+#endif





More information about the llvm-commits mailing list