[lld] r177484 - [ELF][Hexagon] Add Hexagon dynamic relocations

Shankar Easwaran shankare at codeaurora.org
Tue Mar 19 22:10:03 PDT 2013


Author: shankare
Date: Wed Mar 20 00:10:02 2013
New Revision: 177484

URL: http://llvm.org/viewvc/llvm-project?rev=177484&view=rev
Log:
[ELF][Hexagon] Add Hexagon dynamic relocations

Modified:
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp?rev=177484&r1=177483&r2=177484&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp Wed Mar 20 00:10:02 2013
@@ -131,6 +131,81 @@ int relocHexGPRELN(uint8_t *location, ui
   }
   return 1;
 }
+
+/// \brief Word32_LO: 0x00c03fff : (G) : Truncate
+int relocHexGOTLO16(uint8_t *location, uint64_t G) {
+  uint32_t result = (uint32_t)(G);
+  result = lld::scatterBits<int32_t>(result, 0x00c03fff);
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) =
+      result |
+      (uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
+  return 0;
+}
+
+/// \brief Word32_LO: 0x00c03fff : (G) >> 16 : Truncate
+int relocHexGOTHI16(uint8_t *location, uint64_t G) {
+  uint32_t result = (uint32_t)(G >> 16);
+  result = lld::scatterBits<int32_t>(result, 0x00c03fff);
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) =
+      result |
+      (uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
+  return 0;
+}
+
+/// \brief Word32: 0xffffffff : (G) : Truncate
+int relocHexGOT32(uint8_t *location, uint64_t G) {
+  uint32_t result = (uint32_t)(G);
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) =
+      result |
+      (uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
+  return 0;
+}
+
+/// \brief Word32_U16 : (G) : Truncate
+int relocHexGOT16(uint8_t *location, uint64_t G) {
+  uint32_t result = (uint32_t)(G);
+  uint32_t range = 1L << 16;
+  if (result <= range) {
+    result = lld::scatterBits<uint32_t>(result, FINDV4BITMASK(location));
+    *reinterpret_cast<llvm::support::ulittle32_t *>(location) =
+        result |
+        (uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
+    return 0;
+  }
+  return 1;
+}
+
+int relocHexGOT32_6_X(uint8_t *location, uint64_t G) {
+  uint32_t result = (uint32_t)(G >> 6);
+  result = lld::scatterBits<uint32_t>(result, FINDV4BITMASK(location));
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) =
+      result |
+      (uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
+  return 0;
+}
+
+int relocHexGOT16_X(uint8_t *location, uint64_t G) {
+  uint32_t result = (uint32_t)(G);
+  uint32_t range = 1L << 6;
+  if (result <= range) {
+    result = lld::scatterBits<uint32_t>(result, FINDV4BITMASK(location));
+    *reinterpret_cast<llvm::support::ulittle32_t *>(location) =
+        result |
+        (uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
+    return 0;
+  }
+  return 1;
+}
+
+int relocHexGOT11_X(uint8_t *location, uint64_t G) {
+  uint32_t result = (uint32_t)(G);
+  result = lld::scatterBits<uint32_t>(result, FINDV4BITMASK(location));
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) =
+      result |
+      (uint32_t) * reinterpret_cast<llvm::support::ulittle32_t *>(location);
+  return 0;
+}
+
 } // end anon namespace
 
 ErrorOr<void> HexagonTargetRelocationHandler::applyRelocation(
@@ -211,6 +286,28 @@ ErrorOr<void> HexagonTargetRelocationHan
     relocHex6PCRELX(location, relocVAddress, targetVAddress, ref.addend());
     break;
   case R_HEX_JMP_SLOT:
+  case R_HEX_GLOB_DAT:
+    break;
+  case R_HEX_GOT_LO16:
+    relocHexGOTLO16(location, targetVAddress);
+    break;
+  case R_HEX_GOT_HI16:
+    relocHexGOTHI16(location, targetVAddress);
+    break;
+  case R_HEX_GOT_32:
+    relocHexGOT32(location, targetVAddress);
+    break;
+  case R_HEX_GOT_16:
+    relocHexGOT16(location, targetVAddress);
+    break;
+  case R_HEX_GOT_32_6_X:
+    relocHexGOT32_6_X(location, targetVAddress);
+    break;
+  case R_HEX_GOT_16_X:
+    relocHexGOT16_X(location, targetVAddress);
+    break;
+  case R_HEX_GOT_11_X:
+    relocHexGOT11_X(location, targetVAddress);
     break;
   case lld::Reference::kindLayoutAfter:
   case lld::Reference::kindLayoutBefore:

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp?rev=177484&r1=177483&r2=177484&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp Wed Mar 20 00:10:02 2013
@@ -40,6 +40,13 @@ template <class Derived> class GOTPLTPas
     case R_HEX_PLT_B22_PCREL:
       static_cast<Derived *>(this)->handlePLT32(ref);
       break;
+    case R_HEX_GOT_LO16:
+    case R_HEX_GOT_HI16:
+    case R_HEX_GOT_32_6_X:
+    case R_HEX_GOT_16_X:
+    case R_HEX_GOT_11_X:
+      static_cast<Derived *>(this)->handleGOTREL(ref);
+      break;
     }
   }
 
@@ -124,20 +131,21 @@ protected:
 
 class DynamicGOTPLTPass LLVM_FINAL : public GOTPLTPass<DynamicGOTPLTPass> {
 public:
-  DynamicGOTPLTPass(const elf::HexagonTargetInfo &ti) : GOTPLTPass(ti) {}
+  DynamicGOTPLTPass(const elf::HexagonTargetInfo &ti) : GOTPLTPass(ti) {
+    // Fill in the null entry.
+    getNullGOT();
+    _got0 = new (_file._alloc) HexagonGOTAtom(_file, ".got.plt");
+#ifndef NDEBUG
+    _got0->_name = "__got0";
+#endif
+  }
 
   const PLT0Atom *getPLT0() {
     if (_PLT0)
       return _PLT0;
-    // Fill in the null entry.
-    getNullGOT();
     _PLT0 = new (_file._alloc) HexagonPLT0Atom(_file);
-    _got0 = new (_file._alloc) HexagonGOTAtom(_file, ".got.plt");
     _PLT0->addReference(R_HEX_B32_PCREL_X, 0, _got0, 0);
     _PLT0->addReference(R_HEX_6_PCREL_X, 4, _got0, 0);
-#ifndef NDEBUG
-    _got0->_name = "__got0";
-#endif
     DEBUG_WITH_TYPE("PLT", llvm::dbgs() << "[ PLT0/GOT0 ] "
                                         << "Adding plt0/got0 \n");
     return _PLT0;
@@ -171,6 +179,30 @@ public:
     return pa;
   }
 
+  const GOTAtom *getGOTEntry(const Atom *a) {
+    auto got = _gotMap.find(a);
+    if (got != _gotMap.end())
+      return got->second;
+    auto ga = new (_file._alloc) HexagonGOTAtom(_file, ".got");
+    ga->addReference(R_HEX_GLOB_DAT, 0, a, 0);
+
+#ifndef NDEBUG
+    ga->_name = "__got_";
+    ga->_name += a->name();
+    DEBUG_WITH_TYPE("GOT", llvm::dbgs() << "[" << a->name() << "] "
+                                        << "Adding got: " << ga->_name << "\n");
+#endif
+    _gotMap[a] = ga;
+    _gotVector.push_back(ga);
+    return ga;
+  }
+
+  ErrorOr<void> handleGOTREL(const Reference &ref) {
+    // Turn this so that the target is set to the GOT entry 
+    const_cast<Reference &>(ref).setTarget(getGOTEntry(ref.target()));
+    return error_code::success();
+  }
+
   ErrorOr<void> handlePLT32(const Reference &ref) {
     // Turn this into a PC32 to the PLT entry.
     const_cast<Reference &>(ref).setKind(R_HEX_B22_PCREL);

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h?rev=177484&r1=177483&r2=177484&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h Wed Mar 20 00:10:02 2013
@@ -170,6 +170,8 @@ public:
 
   void addDefaultAtoms() {
     _hexagonRuntimeFile.addAbsoluteAtom("_SDA_BASE_");
+    if (_targetInfo.isDynamic())
+      _hexagonRuntimeFile.addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
   }
 
   virtual void addFiles(InputFiles &inputFiles) {
@@ -180,14 +182,27 @@ public:
   void finalizeSymbolValues() {
     auto sdabaseAtomIter = _targetLayout.findAbsoluteAtom("_SDA_BASE_");
     (*sdabaseAtomIter)->_virtualAddr =
-      _targetLayout.getSDataSection()->virtualAddr();
+        _targetLayout.getSDataSection()->virtualAddr();
+    if (_targetInfo.isDynamic()) {
+      auto gotAtomIter =
+          _targetLayout.findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+      _gotSymAtom = (*gotAtomIter);
+      auto gotpltSection = _targetLayout.findOutputSection(".got.plt");
+      if (gotpltSection)
+        _gotSymAtom->_virtualAddr = gotpltSection->virtualAddr();
+      else
+        _gotSymAtom->_virtualAddr = 0;
+    }
   }
 
+  uint64_t getGOTSymAddr() { return _gotSymAtom->_virtualAddr; }
+
 private:
   HexagonTargetLayout<HexagonELFType> _targetLayout;
   HexagonTargetRelocationHandler _relocationHandler;
   HexagonTargetAtomHandler<HexagonELFType> _targetAtomHandler;
   HexagonRuntimeFile<HexagonELFType> _hexagonRuntimeFile;
+  AtomLayout *_gotSymAtom;
 };
 } // end namespace elf
 } // end namespace lld





More information about the llvm-commits mailing list