//===-------- JITLink_EHFrameSupport.cpp - JITLink eh-frame utils ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "EHFrameSupportImpl.h"

#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/DynamicLibrary.h"

#define DEBUG_TYPE "jitlink"

namespace llvm {
namespace jitlink {

EHFrameParser::EHFrameParser(AtomGraph &G, Section &EHFrameSection,
                             StringRef EHFrameContent,
                             JITTargetAddress EHFrameAddress,
                             Edge::Kind FDEToCIERelocKind,
                             Edge::Kind FDEToTargetRelocKind)
    : G(G), EHFrameSection(EHFrameSection), EHFrameContent(EHFrameContent),
      EHFrameAddress(EHFrameAddress),
      EHFrameReader(EHFrameContent, G.getEndianness()),
      FDEToCIERelocKind(FDEToCIERelocKind),
      FDEToTargetRelocKind(FDEToTargetRelocKind) {}

Error EHFrameParser::atomize() {
  while (!EHFrameReader.empty()) {
    size_t RecordOffset = EHFrameReader.getOffset();

    LLVM_DEBUG({
      dbgs() << "Processing eh-frame record at "
             << format("0x%016" PRIx64, EHFrameAddress + RecordOffset)
             << " (offset " << RecordOffset << ")\n";
    });

    size_t CIELength = 0;
    uint32_t CIELengthField;
    if (auto Err = EHFrameReader.readInteger(CIELengthField))
      return Err;

    // Process CIE length/extended-length fields to build the atom.
    //
    // The value of these fields describe the length of the *rest* of the CIE
    // (not including data up to the end of the field itself) so we have to
    // bump CIELength to include the data up to the end of the field: 4 bytes
    // for Length, or 12 bytes (4 bytes + 8 bytes) for ExtendedLength.
    if (CIELengthField == 0) // Length 0 means end of __eh_frame section.
      break;

    // If the regular length field's value is 0xffffffff, use extended length.
    if (CIELengthField == 0xffffffff) {
      uint64_t CIEExtendedLengthField;
      if (auto Err = EHFrameReader.readInteger(CIEExtendedLengthField))
        return Err;
      if (CIEExtendedLengthField > EHFrameReader.bytesRemaining())
        return make_error<JITLinkError>("CIE record extends past the end of "
                                        "the __eh_frame section");
      if (CIEExtendedLengthField + 12 > std::numeric_limits<size_t>::max())
        return make_error<JITLinkError>("CIE record too large to process");
      CIELength = CIEExtendedLengthField + 12;
    } else {
      if (CIELengthField > EHFrameReader.bytesRemaining())
        return make_error<JITLinkError>("CIE record extends past the end of "
                                        "the __eh_frame section");
      CIELength = CIELengthField + 4;
    }

    LLVM_DEBUG(dbgs() << "  length: " << CIELength << "\n");

    // Add an atom for this record.
    CurRecordAtom = &G.addAnonymousAtom(
        EHFrameSection, EHFrameAddress + RecordOffset, G.getPointerSize());
    CurRecordAtom->setContent(EHFrameContent.substr(RecordOffset, CIELength));

    // Read the CIE Pointer.
    size_t CIEPointerAddress = EHFrameAddress + EHFrameReader.getOffset();
    uint32_t CIEPointer;
    if (auto Err = EHFrameReader.readInteger(CIEPointer))
      return Err;

    // Based on the CIE pointer value, parse this as a CIE or FDE record.
    if (CIEPointer == 0) {
      if (auto Err = processCIE())
        return Err;
    } else {
      if (auto Err = processFDE(CIEPointerAddress, CIEPointer))
        return Err;
    }

    EHFrameReader.setOffset(RecordOffset + CIELength);
  }

  return Error::success();
}

Expected<EHFrameParser::AugmentationInfo>
EHFrameParser::parseAugmentationString() {
  AugmentationInfo AugInfo;
  uint8_t NextChar;
  uint8_t *NextField = &AugInfo.Fields[0];

  if (auto Err = EHFrameReader.readInteger(NextChar))
    return std::move(Err);

  while (NextChar != 0) {
    switch (NextChar) {
    case 'z':
      AugInfo.AugmentationDataPresent = true;
      break;
    case 'e':
      if (auto Err = EHFrameReader.readInteger(NextChar))
        return std::move(Err);
      if (NextChar != 'h')
        return make_error<JITLinkError>("Unrecognized substring e" +
                                        Twine(NextChar) +
                                        " in augmentation string");
      AugInfo.EHDataFieldPresent = true;
      break;
    case 'L':
    case 'P':
    case 'R':
      *NextField++ = NextChar;
      break;
    default:
      return make_error<JITLinkError>("Unrecognized character " +
                                      Twine(NextChar) +
                                      " in augmentation string");
    }

    if (auto Err = EHFrameReader.readInteger(NextChar))
      return std::move(Err);
  }

  return std::move(AugInfo);
}

Expected<JITTargetAddress> EHFrameParser::readAbsolutePointer() {
  static_assert(sizeof(JITTargetAddress) == sizeof(uint64_t),
                "Result must be able to hold a uint64_t");
  JITTargetAddress Addr;
  if (G.getPointerSize() == 8) {
    if (auto Err = EHFrameReader.readInteger(Addr))
      return std::move(Err);
  } else if (G.getPointerSize() == 4) {
    uint32_t Addr32;
    if (auto Err = EHFrameReader.readInteger(Addr32))
      return std::move(Err);
    Addr = Addr32;
  } else
    llvm_unreachable("Pointer size is not 32-bit or 64-bit");
  return Addr;
}

Error EHFrameParser::processCIE() {
  // Use the dwarf namespace for convenient access to pointer encoding
  // constants.
  using namespace dwarf;

  LLVM_DEBUG(dbgs() << "  Record is CIE\n");

  CIEInformation CIEInfo(*CurRecordAtom);

  uint8_t Version = 0;
  if (auto Err = EHFrameReader.readInteger(Version))
    return Err;

  if (Version != 0x01)
    return make_error<JITLinkError>("Bad CIE version " + Twine(Version) +
                                    " (should be 0x01) in eh-frame");

  auto AugInfo = parseAugmentationString();
  if (!AugInfo)
    return AugInfo.takeError();

  // Skip the EH Data field if present.
  if (AugInfo->EHDataFieldPresent)
    if (auto Err = EHFrameReader.skip(G.getPointerSize()))
      return Err;

  // Read and sanity check the code alignment factor.
  {
    uint64_t CodeAlignmentFactor = 0;
    if (auto Err = EHFrameReader.readULEB128(CodeAlignmentFactor))
      return Err;
    if (CodeAlignmentFactor != 1)
      return make_error<JITLinkError>("Unsupported CIE code alignment factor " +
                                      Twine(CodeAlignmentFactor) +
                                      " (expected 1)");
  }

  // Read and sanity check the data alignment factor.
  {
    int64_t DataAlignmentFactor = 0;
    if (auto Err = EHFrameReader.readSLEB128(DataAlignmentFactor))
      return Err;
    if (DataAlignmentFactor != -8)
      return make_error<JITLinkError>("Unsupported CIE data alignment factor " +
                                      Twine(DataAlignmentFactor) +
                                      " (expected -8)");
  }

  // Skip the return address register field.
  if (auto Err = EHFrameReader.skip(1))
    return Err;

  uint64_t AugmentationDataLength = 0;
  if (auto Err = EHFrameReader.readULEB128(AugmentationDataLength))
    return Err;

  uint32_t AugmentationDataStartOffset = EHFrameReader.getOffset();

  uint8_t *NextField = &AugInfo->Fields[0];
  while (uint8_t Field = *NextField++) {
    switch (Field) {
    case 'L': {
      CIEInfo.FDEsHaveLSDAField = true;
      uint8_t LSDAPointerEncoding;
      if (auto Err = EHFrameReader.readInteger(LSDAPointerEncoding))
        return Err;
      if (LSDAPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr))
        return make_error<JITLinkError>(
            "Unsupported LSDA pointer encoding " +
            formatv("{0:x2}", LSDAPointerEncoding) + " in CIE at " +
            formatv("{0:x16}", CurRecordAtom->getAddress()));
      break;
    }
    case 'P': {
      uint8_t PersonalityPointerEncoding = 0;
      if (auto Err = EHFrameReader.readInteger(PersonalityPointerEncoding))
        return Err;
      if (PersonalityPointerEncoding !=
          (DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4))
        return make_error<JITLinkError>(
            "Unspported personality pointer "
            "encoding " +
            formatv("{0:x2}", PersonalityPointerEncoding) + " in CIE at " +
            formatv("{0:x16}", CurRecordAtom->getAddress()));
      uint32_t PersonalityPointerAddress;
      if (auto Err = EHFrameReader.readInteger(PersonalityPointerAddress))
        return Err;
      break;
    }
    case 'R': {
      uint8_t FDEPointerEncoding;
      if (auto Err = EHFrameReader.readInteger(FDEPointerEncoding))
        return Err;
      if (FDEPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr))
        return make_error<JITLinkError>(
            "Unsupported FDE address pointer "
            "encoding " +
            formatv("{0:x2}", FDEPointerEncoding) + " in CIE at " +
            formatv("{0:x16}", CurRecordAtom->getAddress()));
      break;
    }
    default:
      llvm_unreachable("Invalid augmentation string field");
    }
  }

  if (EHFrameReader.getOffset() - AugmentationDataStartOffset >
      AugmentationDataLength)
    return make_error<JITLinkError>("Read past the end of the augmentation "
                                    "data while parsing fields");

  assert(!CIEInfos.count(CurRecordAtom->getAddress()) &&
         "Multiple CIEs recorded at the same address?");
  CIEInfos[CurRecordAtom->getAddress()] = std::move(CIEInfo);

  return Error::success();
}

Error EHFrameParser::processFDE(JITTargetAddress CIEPointerAddress,
                                uint32_t CIEPointer) {
  LLVM_DEBUG(dbgs() << "  Record is FDE\n");

  LLVM_DEBUG({
    dbgs() << "  CIE pointer: "
           << format("0x%016" PRIx64, CIEPointerAddress - CIEPointer) << "\n";
  });

  auto CIEInfoItr = CIEInfos.find(CIEPointerAddress - CIEPointer);
  if (CIEInfoItr == CIEInfos.end())
    return make_error<JITLinkError>(
        "FDE at " + formatv("{0:x16}", CurRecordAtom->getAddress()) +
        " points to non-existant CIE at " +
        formatv("{0:x16}", CIEPointerAddress - CIEPointer));
  auto &CIEInfo = CIEInfoItr->second;

  // The CIEPointer looks good. Add a relocation.
  CurRecordAtom->addEdge(FDEToCIERelocKind,
                         CIEPointerAddress - CurRecordAtom->getAddress(),
                         *CIEInfo.CIEAtom, 0);

  // Read and sanity check the PC-start pointer and size.
  JITTargetAddress PCBeginAddress = EHFrameAddress + EHFrameReader.getOffset();

  auto PCBeginDelta = readAbsolutePointer();
  if (!PCBeginDelta)
    return PCBeginDelta.takeError();

  JITTargetAddress PCBegin = PCBeginAddress + *PCBeginDelta;
  LLVM_DEBUG({
    dbgs() << "  PC begin: " << format("0x%016" PRIx64, PCBegin) << "\n";
  });

  auto *TargetAtom = G.getAtomByAddress(PCBegin);

  if (!TargetAtom)
    return make_error<JITLinkError>("FDE PC-begin " +
                                    formatv("{0:x16}", PCBegin) +
                                    " does not point at atom");

  if (TargetAtom->getAddress() != PCBegin)
    return make_error<JITLinkError>(
        "FDE PC-begin " + formatv("{0:x16}", PCBegin) +
        " does not point to start of atom at " +
        formatv("{0:x16}", TargetAtom->getAddress()));

  LLVM_DEBUG(dbgs() << "  FDE target: " << *TargetAtom << "\n");

  // The PC-start pointer and size look good. Add relocations.
  CurRecordAtom->addEdge(FDEToTargetRelocKind,
                         PCBeginAddress - CurRecordAtom->getAddress(),
                         *TargetAtom, 0);

  // Add a keep-alive relocation from the function to the FDE to ensure it is
  // not dead stripped.
  TargetAtom->addEdge(Edge::KeepAlive, 0, *CurRecordAtom, 0);

  // Skip over the PC range size field.
  if (auto Err = EHFrameReader.skip(G.getPointerSize()))
    return Err;

  if (CIEInfo.FDEsHaveLSDAField) {
    uint64_t AugmentationDataSize;
    if (auto Err = EHFrameReader.readULEB128(AugmentationDataSize))
      return Err;
    if (AugmentationDataSize != G.getPointerSize())
      return make_error<JITLinkError>(
          "Unexpected FDE augmentation data size (expected " +
          Twine(G.getPointerSize()) + ", got " + Twine(AugmentationDataSize) +
          ") for FDE at " + formatv("{0:x16}", CurRecordAtom->getAddress()));
    JITTargetAddress LSDAAddress = EHFrameAddress + EHFrameReader.getOffset();
    auto LSDADelta = readAbsolutePointer();
    if (!LSDADelta)
      return LSDADelta.takeError();

    JITTargetAddress LSDA = LSDAAddress + *LSDADelta;

    auto *LSDAAtom = G.getAtomByAddress(LSDA);

    if (!LSDAAtom)
      return make_error<JITLinkError>("FDE LSDA " + formatv("{0:x16}", LSDA) +
                                      " does not point at atom");

    if (LSDAAtom->getAddress() != LSDA)
      return make_error<JITLinkError>(
          "FDE LSDA " + formatv("{0:x16}", LSDA) +
          " does not point to start of atom at " +
          formatv("{0:x16}", LSDAAtom->getAddress()));

    LLVM_DEBUG(dbgs() << "  FDE LSDA: " << *LSDAAtom << "\n");

    // LSDA looks good. Add relocations.
    CurRecordAtom->addEdge(FDEToTargetRelocKind,
                           LSDAAddress - CurRecordAtom->getAddress(), *LSDAAtom,
                           0);
  }

  return Error::success();
}

Error addEHFrame(AtomGraph &G, Section &EHFrameSection,
                 StringRef EHFrameContent, JITTargetAddress EHFrameAddress,
                 Edge::Kind FDEToCIERelocKind,
                 Edge::Kind FDEToTargetRelocKind) {
  return EHFrameParser(G, EHFrameSection, EHFrameContent, EHFrameAddress,
                       FDEToCIERelocKind, FDEToTargetRelocKind)
      .atomize();
}

// Determine whether we can register EH tables.
#if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) &&      \
     !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__))
#define HAVE_EHTABLE_SUPPORT 1
#else
#define HAVE_EHTABLE_SUPPORT 0
#endif

#if HAVE_EHTABLE_SUPPORT
extern "C" void __register_frame(const void *);
extern "C" void __deregister_frame(const void *);

Error registerFrameWrapper(const void *P) {
  __register_frame(P);
  return Error::success();
}

Error deregisterFrameWrapper(const void *P) {
  __deregister_frame(P);
  return Error::success();
}

#else

// The building compiler does not have __(de)register_frame but
// it may be found at runtime in a dynamically-loaded library.
// For example, this happens when building LLVM with Visual C++
// but using the MingW runtime.
static Error registerFrameWrapper(const void *P) {
  static void((*RegisterFrame)(const void *)) = 0;

  if (!RegisterFrame)
    *(void **)&RegisterFrame =
        llvm::sys::DynamicLibrary::SearchForAddressOfSymbol("__register_frame");

  if (RegisterFrame) {
    RegisterFrame(P);
    return Error::success();
  }

  return make_error<JITLinkError>("could not register eh-frame: "
                                  "__register_frame function not found");
}

static Error deregisterFrameWrapper(const void *P) {
  static void((*DeregisterFrame)(const void *)) = 0;

  if (!DeregisterFrame)
    *(void **)&DeregisterFrame =
        llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(
            "__deregister_frame");

  if (DeregisterFrame) {
    DeregisterFrame(P);
    return Error::success();
  }

  return make_error<JITLinkError>("could not deregister eh-frame: "
                                  "__deregister_frame function not found");
}
#endif

#ifdef __APPLE__

template <typename HandleFDEFn>
Error walkAppleEHFrameSection(const char *const SectionStart,
                              HandleFDEFn HandleFDE) {
  const char *CurCFIRecord = SectionStart;
  uint64_t Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord);

  while (Size != 0) {
    const char *OffsetField = CurCFIRecord + (Size == 0xffffffff ? 12 : 4);
    if (Size == 0xffffffff)
      Size = *reinterpret_cast<const uint64_t *>(CurCFIRecord + 4) + 12;
    else
      Size += 4;
    uint32_t Offset = *reinterpret_cast<const uint32_t *>(OffsetField);
    if (Offset != 0)
      if (auto Err = HandleFDE(CurCFIRecord))
        return Err;

    LLVM_DEBUG({
      dbgs() << "Registering eh-frame section:\n";
      dbgs() << "Processing " << (Offset ? "FDE" : "CIE") << " @"
             << (void *)CurCFIRecord << ": [";
      for (unsigned I = 0; I < Size; ++I)
        dbgs() << format(" 0x%02" PRIx8, *(CurCFIRecord + I));
      dbgs() << " ]\n";
    });
    CurCFIRecord += Size;

    Size = *reinterpret_cast<const uint32_t *>(CurCFIRecord);
  }

  return Error::success();
}

#endif // __APPLE__

Error registerEHFrameSection(const void *EHFrameSectionAddr) {
#ifdef __APPLE__
  // On Darwin __register_frame has to be called for each FDE entry.
  return walkAppleEHFrameSection(static_cast<const char *>(EHFrameSectionAddr),
                                 registerFrameWrapper);
#else
  // On Linux __register_frame takes a single argument:
  // a pointer to the start of the .eh_frame section.

  // How can it find the end? Because crtendS.o is linked
  // in and it has an .eh_frame section with four zero chars.
  return registerFrameWrapper(EHFrameSectionAddr);
#endif
}

Error deregisterEHFrameSection(const void *EHFrameSectionAddr) {
#ifdef __APPLE__
  return walkAppleEHFrameSection(static_cast<const char *>(EHFrameSectionAddr),
                                 deregisterFrameWrapper);
#else
  return deregisterFrameWrapper(EHFrameSectionAddr);
#endif
}

AtomGraphPassFunction
createEHFrameRecorderPass(const Triple &TT,
                          StoreFrameAddressFunction StoreFrameAddress) {
  const char *EHFrameSectionName = nullptr;
  if (TT.getObjectFormat() == Triple::MachO)
    EHFrameSectionName = "__eh_frame";
  else
    EHFrameSectionName = ".eh_frame";

  auto RecordEHFrame = [EHFrameSectionName,
                        StoreFrameAddress](AtomGraph &G) -> Error {
    // Search for a non-empty eh-frame and record the address of the first atom
    // in it.
    JITTargetAddress Addr = 0;
    if (auto *S = G.findSectionByName(EHFrameSectionName))
      Addr = S->getRange().getStart();
    StoreFrameAddress(Addr);
    return Error::success();
  };

  return RecordEHFrame;
}

} // end namespace jitlink
} // end namespace llvm
