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