//===--- RuntimeDyldCOFFThumb.h --- COFF/Thumb specific code ---*- C++ --*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// COFF thumb support for MC-JIT runtime dynamic linker.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFTHUMB_H
#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFTHUMB_H

#include "../RuntimeDyldCOFF.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/COFF.h"

#define DEBUG_TYPE "dyld"

namespace llvm {

static bool isThumbFunc(symbol_iterator Symbol, const ObjectFile &Obj,
                        section_iterator Section) {
  Expected<SymbolRef::Type> SymTypeOrErr = Symbol->getType();
  if (!SymTypeOrErr) {
    std::string Buf;
    raw_string_ostream OS(Buf);
    logAllUnhandledErrors(SymTypeOrErr.takeError(), OS, "");
    OS.flush();
    report_fatal_error(Buf);
  }

  if (*SymTypeOrErr != SymbolRef::ST_Function)
    return false;

  // We check the IMAGE_SCN_MEM_16BIT flag in the section of the symbol to tell
  // if it's thumb or not
  return cast<COFFObjectFile>(Obj).getCOFFSection(*Section)->Characteristics &
         COFF::IMAGE_SCN_MEM_16BIT;
}

class RuntimeDyldCOFFThumb : public RuntimeDyldCOFF {
public:
  RuntimeDyldCOFFThumb(RuntimeDyld::MemoryManager &MM,
                       JITSymbolResolver &Resolver)
      : RuntimeDyldCOFF(MM, Resolver) {}

  unsigned getMaxStubSize() override {
    return 16; // 8-byte load instructions, 4-byte jump, 4-byte padding
  }

  unsigned getStubAlignment() override { return 1; }

  Expected<relocation_iterator>
  processRelocationRef(unsigned SectionID,
                       relocation_iterator RelI,
                       const ObjectFile &Obj,
                       ObjSectionToIDMap &ObjSectionToID,
                       StubMap &Stubs) override {
    auto Symbol = RelI->getSymbol();
    if (Symbol == Obj.symbol_end())
      report_fatal_error("Unknown symbol in relocation");

    Expected<StringRef> TargetNameOrErr = Symbol->getName();
    if (!TargetNameOrErr)
      return TargetNameOrErr.takeError();
    StringRef TargetName = *TargetNameOrErr;

    auto SectionOrErr = Symbol->getSection();
    if (!SectionOrErr)
      return SectionOrErr.takeError();
    auto Section = *SectionOrErr;

    uint64_t RelType = RelI->getType();
    uint64_t Offset = RelI->getOffset();

    // Determine the Addend used to adjust the relocation value.
    uint64_t Addend = 0;
    SectionEntry &AddendSection = Sections[SectionID];
    uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset;
    uint8_t *Displacement = (uint8_t *)ObjTarget;

    switch (RelType) {
    case COFF::IMAGE_REL_ARM_ADDR32:
    case COFF::IMAGE_REL_ARM_ADDR32NB:
    case COFF::IMAGE_REL_ARM_SECREL:
      Addend = readBytesUnaligned(Displacement, 4);
      break;
    default:
      break;
    }

#if !defined(NDEBUG)
    SmallString<32> RelTypeName;
    RelI->getTypeName(RelTypeName);
#endif
    LLVM_DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
                      << " RelType: " << RelTypeName << " TargetName: "
                      << TargetName << " Addend " << Addend << "\n");

    unsigned TargetSectionID = -1;
    if (Section == Obj.section_end()) {
      RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0);
      addRelocationForSymbol(RE, TargetName);
    } else {
      if (auto TargetSectionIDOrErr =
          findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID))
        TargetSectionID = *TargetSectionIDOrErr;
      else
        return TargetSectionIDOrErr.takeError();

      // We need to find out if the relocation is relative to a thumb function
      // so that we include the ISA selection bit when resolve the relocation
      bool IsTargetThumbFunc = isThumbFunc(Symbol, Obj, Section);

      switch (RelType) {
      default: llvm_unreachable("unsupported relocation type");
      case COFF::IMAGE_REL_ARM_ABSOLUTE:
        // This relocation is ignored.
        break;
      case COFF::IMAGE_REL_ARM_ADDR32: {
        RelocationEntry RE = RelocationEntry(
            SectionID, Offset, RelType, Addend, TargetSectionID,
            getSymbolOffset(*Symbol), 0, 0, false, 0, IsTargetThumbFunc);
        addRelocationForSection(RE, TargetSectionID);
        break;
      }
      case COFF::IMAGE_REL_ARM_ADDR32NB: {
        RelocationEntry RE =
            RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID,
                            getSymbolOffset(*Symbol), 0, 0, false, 0);
        addRelocationForSection(RE, TargetSectionID);
        break;
      }
      case COFF::IMAGE_REL_ARM_SECTION: {
        RelocationEntry RE =
            RelocationEntry(TargetSectionID, Offset, RelType, 0);
        addRelocationForSection(RE, TargetSectionID);
        break;
      }
      case COFF::IMAGE_REL_ARM_SECREL: {
        RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType,
                                             getSymbolOffset(*Symbol) + Addend);
        addRelocationForSection(RE, TargetSectionID);
        break;
      }
      case COFF::IMAGE_REL_ARM_MOV32T: {
        RelocationEntry RE = RelocationEntry(
            SectionID, Offset, RelType, Addend, TargetSectionID,
            getSymbolOffset(*Symbol), 0, 0, false, 0, IsTargetThumbFunc);
        addRelocationForSection(RE, TargetSectionID);
        break;
      }
      case COFF::IMAGE_REL_ARM_BRANCH20T:
      case COFF::IMAGE_REL_ARM_BRANCH24T:
      case COFF::IMAGE_REL_ARM_BLX23T: {
        RelocationEntry RE =
            RelocationEntry(SectionID, Offset, RelType,
                            getSymbolOffset(*Symbol) + Addend, true, 0);
        addRelocationForSection(RE, TargetSectionID);
        break;
      }
      }
    }

    return ++RelI;
  }

  void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
    const auto Section = Sections[RE.SectionID];
    uint8_t *Target = Section.getAddressWithOffset(RE.Offset);
    int ISASelectionBit = RE.IsTargetThumbFunc ? 1 : 0;

    switch (RE.RelType) {
    default: llvm_unreachable("unsupported relocation type");
    case COFF::IMAGE_REL_ARM_ABSOLUTE:
      // This relocation is ignored.
      break;
    case COFF::IMAGE_REL_ARM_ADDR32: {
      // The target's 32-bit VA.
      uint64_t Result =
          RE.Sections.SectionA == static_cast<uint32_t>(-1)
              ? Value
              : Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend);
      Result |= ISASelectionBit;
      assert(Result <= UINT32_MAX && "relocation overflow");
      LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
                        << " RelType: IMAGE_REL_ARM_ADDR32"
                        << " TargetSection: " << RE.Sections.SectionA
                        << " Value: " << format("0x%08" PRIx32, Result)
                        << '\n');
      writeBytesUnaligned(Result, Target, 4);
      break;
    }
    case COFF::IMAGE_REL_ARM_ADDR32NB: {
      // The target's 32-bit RVA.
      // NOTE: use Section[0].getLoadAddress() as an approximation of ImageBase
      uint64_t Result = Sections[RE.Sections.SectionA].getLoadAddress() -
                        Sections[0].getLoadAddress() + RE.Addend;
      assert(Result <= UINT32_MAX && "relocation overflow");
      LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
                        << " RelType: IMAGE_REL_ARM_ADDR32NB"
                        << " TargetSection: " << RE.Sections.SectionA
                        << " Value: " << format("0x%08" PRIx32, Result)
                        << '\n');
      Result |= ISASelectionBit;
      writeBytesUnaligned(Result, Target, 4);
      break;
    }
    case COFF::IMAGE_REL_ARM_SECTION:
      // 16-bit section index of the section that contains the target.
      assert(static_cast<uint32_t>(RE.SectionID) <= UINT16_MAX &&
             "relocation overflow");
      LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
                        << " RelType: IMAGE_REL_ARM_SECTION Value: "
                        << RE.SectionID << '\n');
      writeBytesUnaligned(RE.SectionID, Target, 2);
      break;
    case COFF::IMAGE_REL_ARM_SECREL:
      // 32-bit offset of the target from the beginning of its section.
      assert(static_cast<uint64_t>(RE.Addend) <= UINT32_MAX &&
             "relocation overflow");
      LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
                        << " RelType: IMAGE_REL_ARM_SECREL Value: " << RE.Addend
                        << '\n');
      writeBytesUnaligned(RE.Addend, Target, 2);
      break;
    case COFF::IMAGE_REL_ARM_MOV32T: {
      // 32-bit VA of the target applied to a contiguous MOVW+MOVT pair.
      uint64_t Result =
          Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend);
      assert(Result <= UINT32_MAX && "relocation overflow");
      LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
                        << " RelType: IMAGE_REL_ARM_MOV32T"
                        << " TargetSection: " << RE.Sections.SectionA
                        << " Value: " << format("0x%08" PRIx32, Result)
                        << '\n');

      // MOVW(T3): |11110|i|10|0|1|0|0|imm4|0|imm3|Rd|imm8|
      //            imm32 = zext imm4:i:imm3:imm8
      // MOVT(T1): |11110|i|10|1|1|0|0|imm4|0|imm3|Rd|imm8|
      //            imm16 =      imm4:i:imm3:imm8

      auto EncodeImmediate = [](uint8_t *Bytes, uint16_t Immediate)  {
        Bytes[0] |= ((Immediate & 0xf000) >> 12);
        Bytes[1] |= ((Immediate & 0x0800) >> 11);
        Bytes[2] |= ((Immediate & 0x00ff) >>  0);
        Bytes[3] |= (((Immediate & 0x0700) >>  8) << 4);
      };

      EncodeImmediate(&Target[0],
                      (static_cast<uint32_t>(Result) >> 00) | ISASelectionBit);
      EncodeImmediate(&Target[4], static_cast<uint32_t>(Result) >> 16);

      break;
    }
    case COFF::IMAGE_REL_ARM_BRANCH20T: {
      // The most significant 20-bits of the signed 21-bit relative displacement
      uint64_t Value =
          RE.Addend - (Sections[RE.SectionID].getLoadAddress() + RE.Offset) - 4;
      assert(static_cast<int64_t>(RE.Addend) <= INT32_MAX &&
             "relocation overflow");
      assert(static_cast<int64_t>(RE.Addend) >= INT32_MIN &&
             "relocation underflow");
      LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
                        << " RelType: IMAGE_REL_ARM_BRANCH20T"
                        << " Value: " << static_cast<int32_t>(Value) << '\n');
      static_cast<void>(Value);
      llvm_unreachable("unimplemented relocation");
      break;
    }
    case COFF::IMAGE_REL_ARM_BRANCH24T: {
      // The most significant 24-bits of the signed 25-bit relative displacement
      uint64_t Value =
          RE.Addend - (Sections[RE.SectionID].getLoadAddress() + RE.Offset) - 4;
      assert(static_cast<int64_t>(RE.Addend) <= INT32_MAX &&
             "relocation overflow");
      assert(static_cast<int64_t>(RE.Addend) >= INT32_MIN &&
             "relocation underflow");
      LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
                        << " RelType: IMAGE_REL_ARM_BRANCH24T"
                        << " Value: " << static_cast<int32_t>(Value) << '\n');
      static_cast<void>(Value);
      llvm_unreachable("unimplemented relocation");
      break;
    }
    case COFF::IMAGE_REL_ARM_BLX23T: {
      // The most significant 24-bits of the signed 25-bit relative displacement
      uint64_t Value =
          RE.Addend - (Sections[RE.SectionID].getLoadAddress() + RE.Offset) - 4;
      assert(static_cast<int64_t>(RE.Addend) <= INT32_MAX &&
             "relocation overflow");
      assert(static_cast<int64_t>(RE.Addend) >= INT32_MIN &&
             "relocation underflow");
      LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
                        << " RelType: IMAGE_REL_ARM_BLX23T"
                        << " Value: " << static_cast<int32_t>(Value) << '\n');
      static_cast<void>(Value);
      llvm_unreachable("unimplemented relocation");
      break;
    }
    }
  }

  void registerEHFrames() override {}
};

}

#endif
