summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF/Hexagon/HexagonRelocationHandler.cpp
diff options
context:
space:
mode:
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