summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
diff options
context:
space:
mode:
authorShankar Easwaran <shankare@codeaurora.org>2013-03-20 05:10:02 +0000
committerShankar Easwaran <shankare@codeaurora.org>2013-03-20 05:10:02 +0000
commit452ba132712d284186ef79142f4906390f2bf0ad (patch)
tree898e99c739c605f07679717b786768535183032a /lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
parent06a4039572b6c0e2d1dec87a50fb2b8a42432967 (diff)
downloadbcm5719-llvm-452ba132712d284186ef79142f4906390f2bf0ad.tar.gz
bcm5719-llvm-452ba132712d284186ef79142f4906390f2bf0ad.zip
[ELF][Hexagon] Add Hexagon dynamic relocations
llvm-svn: 177484
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp')
-rw-r--r--lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp97
1 files changed, 97 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
index d0cd2400f45..d63eb918493 100644
--- a/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
@@ -131,6 +131,81 @@ int relocHexGPRELN(uint8_t *location, uint64_t P, uint64_t S, uint64_t A,
}
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> HexagonTargetRelocationHandler::applyRelocation(
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:
OpenPOWER on IntegriCloud