[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