HexagonRelocator.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
16f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===- HexagonRelocator.cpp -----------------------------------------------===// 26f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// 36f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// The MCLinker Project 46f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// 56f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// This file is distributed under the University of Illinois Open Source 66f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// License. See LICENSE.TXT for details. 76f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// 86f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 96f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/ADT/Twine.h> 116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/DataTypes.h> 126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ELF.h> 136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Support/MsgHandling.h> 146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include "HexagonRelocator.h" 166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include "HexagonRelocationFunctions.h" 176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesusing namespace mcld; 196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===--------------------------------------------------------------------===// 216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// Relocation Functions and Tables 226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===--------------------------------------------------------------------===// 236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesDECL_HEXAGON_APPLY_RELOC_FUNCS 246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// the prototype of applying function 266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestypedef Relocator::Result (*ApplyFunctionType)(Relocation& pReloc, 276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator& pParent); 286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// the table entry of applying functions 306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesstruct ApplyFunctionTriple 316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ApplyFunctionType func; 336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int type; 346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* name; 356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}; 366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// declare the table of applying functions 386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesstatic const ApplyFunctionTriple ApplyFunctions[] = { 396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines DECL_HEXAGON_APPLY_RELOC_FUNC_PTRS 406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}; 416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===--------------------------------------------------------------------===// 436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// HexagonRelocator 446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===--------------------------------------------------------------------===// 456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::HexagonRelocator(HexagonLDBackend& pParent) 466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : Relocator(), 476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_Target(pParent) { 486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::~HexagonRelocator() 516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesRelocator::Result 556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::applyRelocation(Relocation& pRelocation) 566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Relocation::Type type = pRelocation.type(); 586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (type > 85) { // 86-255 relocs do not exists for Hexagon 606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Relocator::Unknown; 616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // apply the relocation 646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ApplyFunctions[type].func(pRelocation, *this); 656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesconst char* HexagonRelocator::getName(Relocation::Type pType) const 686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ApplyFunctions[pType].name; 706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesRelocator::Size HexagonRelocator::getSize(Relocation::Type pType) const 736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return 32; 756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===--------------------------------------------------------------------===// 776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// Relocation helper function 786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===--------------------------------------------------------------------===// 796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<typename T1, typename T2> 806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesT1 ApplyMask(T2 pMask, T1 pData) { 816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines T1 result = 0; 826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t off = 0; 836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t bit = 0; bit != sizeof (T1) * 8; ++bit) { 856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const bool valBit = (pData >> off) & 1; 866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const bool maskBit = (pMask >> bit) & 1; 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (maskBit) { 886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result |= static_cast<T1>(valBit) << bit; 896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ++off; 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//=========================================// 966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// Each relocation function implementation // 976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//=========================================// 986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_NONE 1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result none(Relocation& pReloc, HexagonRelocator& pParent) 1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_B22_PCREL: Word32_B22 : 0x01ff3ffe (S + A - P) >> 2 : Signed Verify 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result relocB22PCREL(Relocation& pReloc, 1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator& pParent) 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::Address S = pReloc.symValue(); 1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord P = pReloc.place(); 1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int32_t result = (int32_t) ((S + A - P) >> 2); 1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int32_t range = 1 << 21; 1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ( (result < range) && (result > -range)) { 1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = pReloc.target() | ApplyMask(0x01ff3ffe, result); 1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::Overflow; 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_B15_PCREL: Word32_B15 : 0x00df20fe (S + A - P) >> 2 : Signed Verify 1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result relocB15PCREL(Relocation& pReloc, 1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator& pParent) 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::Address S = pReloc.symValue(); 1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord P = pReloc.place(); 1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int32_t result = (int32_t) ((S + A - P) >> 2); 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int32_t range = 1 << 14; 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ( (result < range) && (result > -range)) { 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = pReloc.target() | ApplyMask(0x00df20fe,result); 1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::Overflow; 1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_B7_PCREL: Word32_B7 : 0x0001f18 (S + A - P) >> 2 : Signed Verify 1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result relocB7PCREL(Relocation& pReloc, 1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator& pParent) 1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::Address S = pReloc.symValue(); 1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord P = pReloc.place(); 1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int32_t result = (int32_t) ((S + A - P) >> 2); 1496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int32_t range = 1 << 6; 1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ( (result < range) && (result > -range)) { 1516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = pReloc.target() | ApplyMask(0x00001f18, result); 1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::Overflow; 1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_LO16: Word32_LO : 0x00c03fff (S + A) : Unsigned Truncate 1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result relocLO16(Relocation& pReloc, 1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator& pParent) 1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::Address S = pReloc.symValue(); 1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t result = (uint32_t) (S + A); 1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = pReloc.target() | ApplyMask(0x00c03fff, result); 1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_HI16: Word32_LO : 0x00c03fff (S + A) >> 16 : Unsigned Truncate 1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result relocHI16(Relocation& pReloc, 1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator& pParent) 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::Address S = pReloc.symValue(); 1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t result = (uint32_t) ((S + A) >> 16); 1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = pReloc.target() | ApplyMask(0x00c03fff, result); 1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_32: Word32 : 0xffffffff : (S + A) : Unsigned Truncate 1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result reloc32(Relocation& pReloc, HexagonRelocator& pParent) 1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord S = pReloc.symValue(); 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t result = (uint32_t) (S + A); 1886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = result | pReloc.target(); 1906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 1916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_16: Word32 : 0xffff : (S + A) : Unsigned Truncate 1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result reloc16(Relocation& pReloc, HexagonRelocator& pParent) 1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord S = pReloc.symValue(); 1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t result = (uint32_t) (S + A); 2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = pReloc.target() | ApplyMask(0x0000ffff, result); 2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_8: Word32 : 0xff : (S + A) : Unsigned Truncate 2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result reloc8(Relocation& pReloc, HexagonRelocator& pParent) 2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord S = pReloc.symValue(); 2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t result = (uint32_t) (S + A); 2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = pReloc.target() | ApplyMask(0x000000ff, result); 2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_B13_PCREL : Word32_B13 : 0x00202ffe (S + A - P)>>2 : Signed Verify 2186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result relocB13PCREL(Relocation& pReloc, 2196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator& pParent) 2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::Address S = pReloc.symValue(); 2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord P = pReloc.place(); 2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int32_t result = ((S + A - P) >> 2); 2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int32_t range = 1L << 12; 2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (result < range && result > -range) { 2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = pReloc.target() | ApplyMask(0x00202ffe, result); 2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::Overflow; 2326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result unsupport(Relocation& pReloc, 2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator& pParent) 2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::Unsupport; 2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// R_HEX_32_PCREL : Word32 : 0xffffffff (S + A - P) : Signed Verify 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesHexagonRelocator::Result reloc32PCREL(Relocation& pReloc, 2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator& pParent) 2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::Address S = pReloc.symValue(); 2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord A = pReloc.addend(); 2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines HexagonRelocator::DWord P = pReloc.place(); 2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int64_t result = S + A - P; 2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int32_t range = 1 << 31; 2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (result < range && result > -range) { 2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.target() = pReloc.target() | ApplyMask(0xffffffff, result); 2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::OK; 2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return HexagonRelocator::Overflow; 2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 260