//===-------- JITLink_EHFrameSupport.cpp - JITLink eh-frame utils ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "EHFrameSupportImpl.h"

#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
#include "llvm/Support/DynamicLibrary.h"

#define DEBUG_TYPE "jitlink"

namespace llvm {
namespace jitlink {

EHFrameEdgeFixer::EHFrameEdgeFixer(StringRef EHFrameSectionName,
                                   unsigned PointerSize, Edge::Kind Pointer32,
                                   Edge::Kind Pointer64, Edge::Kind Delta32,
                                   Edge::Kind Delta64, Edge::Kind NegDelta32)
    : EHFrameSectionName(EHFrameSectionName), PointerSize(PointerSize),
      Pointer32(Pointer32), Pointer64(Pointer64), Delta32(Delta32),
      Delta64(Delta64), NegDelta32(NegDelta32) {}

Error EHFrameEdgeFixer::operator()(LinkGraph &G) {
  auto *EHFrame = G.findSectionByName(EHFrameSectionName);

  if (!EHFrame) {
    LLVM_DEBUG({
      dbgs() << "EHFrameEdgeFixer: No " << EHFrameSectionName
             << " section in \"" << G.getName() << "\". Nothing to do.\n";
    });
    return Error::success();
  }

  // Check that we support the graph's pointer size.
  if (G.getPointerSize() != 4 && G.getPointerSize() != 8)
    return make_error<JITLinkError>(
        "EHFrameEdgeFixer only supports 32 and 64 bit targets");

  LLVM_DEBUG({
    dbgs() << "EHFrameEdgeFixer: Processing " << EHFrameSectionName << " in \""
           << G.getName() << "\"...\n";
  });

  ParseContext PC(G);

  // Build a map of all blocks and symbols in the text sections. We will use
  // these for finding / building edge targets when processing FDEs.
  for (auto &Sec : G.sections()) {
    // Just record the most-canonical symbol (for eh-frame purposes) at each
    // address.
    for (auto *Sym : Sec.symbols()) {
      auto &CurSym = PC.AddrToSym[Sym->getAddress()];
      if (!CurSym || (std::make_tuple(Sym->getLinkage(), Sym->getScope(),
                                      !Sym->hasName(), Sym->getName()) <
                      std::make_tuple(CurSym->getLinkage(), CurSym->getScope(),
                                      !CurSym->hasName(), CurSym->getName())))
        CurSym = Sym;
    }
    if (auto Err = PC.AddrToBlock.addBlocks(Sec.blocks(),
                                            BlockAddressMap::includeNonNull))
      return Err;
  }

  // Sort eh-frame blocks into address order to ensure we visit CIEs before
  // their child FDEs.
  std::vector<Block *> EHFrameBlocks;
  for (auto *B : EHFrame->blocks())
    EHFrameBlocks.push_back(B);
  llvm::sort(EHFrameBlocks, [](const Block *LHS, const Block *RHS) {
    return LHS->getAddress() < RHS->getAddress();
  });

  // Loop over the blocks in address order.
  for (auto *B : EHFrameBlocks)
    if (auto Err = processBlock(PC, *B))
      return Err;

  return Error::success();
}

static Expected<size_t> readCFIRecordLength(const Block &B,
                                            BinaryStreamReader &R) {
  uint32_t Length;
  if (auto Err = R.readInteger(Length))
    return std::move(Err);

  // If Length < 0xffffffff then use the regular length field, otherwise
  // read the extended length field.
  if (Length != 0xffffffff)
    return Length;

  uint64_t ExtendedLength;
  if (auto Err = R.readInteger(ExtendedLength))
    return std::move(Err);

  if (ExtendedLength > std::numeric_limits<size_t>::max())
    return make_error<JITLinkError>(
        "In CFI record at " +
        formatv("{0:x}", B.getAddress() + R.getOffset() - 12) +
        ", extended length of " + formatv("{0:x}", ExtendedLength) +
        " exceeds address-range max (" +
        formatv("{0:x}", std::numeric_limits<size_t>::max()));

  return ExtendedLength;
}

Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {

  LLVM_DEBUG(dbgs() << "  Processing block at " << B.getAddress() << "\n");

  // eh-frame should not contain zero-fill blocks.
  if (B.isZeroFill())
    return make_error<JITLinkError>("Unexpected zero-fill block in " +
                                    EHFrameSectionName + " section");

  if (B.getSize() == 0) {
    LLVM_DEBUG(dbgs() << "    Block is empty. Skipping.\n");
    return Error::success();
  }

  // Find the offsets of any existing edges from this block.
  BlockEdgeMap BlockEdges;
  for (auto &E : B.edges())
    if (E.isRelocation()) {
      if (BlockEdges.count(E.getOffset()))
        return make_error<JITLinkError>(
            "Multiple relocations at offset " +
            formatv("{0:x16}", E.getOffset()) + " in " + EHFrameSectionName +
            " block at address " + formatv("{0:x16}", B.getAddress()));

      BlockEdges[E.getOffset()] = EdgeTarget(E);
    }

  CIEInfosMap CIEInfos;
  BinaryStreamReader BlockReader(
      StringRef(B.getContent().data(), B.getContent().size()),
      PC.G.getEndianness());
  while (!BlockReader.empty()) {
    size_t RecordStartOffset = BlockReader.getOffset();

    LLVM_DEBUG({
      dbgs() << "    Processing CFI record at "
             << (B.getAddress() + RecordStartOffset) << "\n";
    });

    // Get the record length.
    Expected<size_t> RecordRemaining = readCFIRecordLength(B, BlockReader);
    if (!RecordRemaining)
      return RecordRemaining.takeError();

    if (BlockReader.bytesRemaining() < *RecordRemaining)
      return make_error<JITLinkError>(
          "Incomplete CFI record at " +
          formatv("{0:x16}", B.getAddress() + RecordStartOffset));

    // Read the CIE delta for this record.
    uint64_t CIEDeltaFieldOffset = BlockReader.getOffset() - RecordStartOffset;
    uint32_t CIEDelta;
    if (auto Err = BlockReader.readInteger(CIEDelta))
      return Err;

    if (CIEDelta == 0) {
      if (auto Err = processCIE(PC, B, RecordStartOffset,
                                CIEDeltaFieldOffset + *RecordRemaining,
                                CIEDeltaFieldOffset, BlockEdges))
        return Err;
    } else {
      if (auto Err = processFDE(PC, B, RecordStartOffset,
                                CIEDeltaFieldOffset + *RecordRemaining,
                                CIEDeltaFieldOffset, CIEDelta, BlockEdges))
        return Err;
    }

    // Move to the next record.
    BlockReader.setOffset(RecordStartOffset + CIEDeltaFieldOffset +
                          *RecordRemaining);
  }

  return Error::success();
}

Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
                                   size_t RecordOffset, size_t RecordLength,
                                   size_t CIEDeltaFieldOffset,
                                   const BlockEdgeMap &BlockEdges) {

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

  auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
  BinaryStreamReader RecordReader(
      StringRef(RecordContent.data(), RecordContent.size()),
      PC.G.getEndianness());

  // Skip past the CIE delta field: we've already processed this far.
  RecordReader.setOffset(CIEDeltaFieldOffset + 4);

  auto &CIESymbol =
      PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);
  CIEInformation CIEInfo(CIESymbol);

  uint8_t Version = 0;
  if (auto Err = RecordReader.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(RecordReader);
  if (!AugInfo)
    return AugInfo.takeError();

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

  // Read and validate the code alignment factor.
  {
    uint64_t CodeAlignmentFactor = 0;
    if (auto Err = RecordReader.readULEB128(CodeAlignmentFactor))
      return Err;
  }

  // Read and validate the data alignment factor.
  {
    int64_t DataAlignmentFactor = 0;
    if (auto Err = RecordReader.readSLEB128(DataAlignmentFactor))
      return Err;
  }

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

  if (AugInfo->AugmentationDataPresent) {

    CIEInfo.AugmentationDataPresent = true;

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

    uint32_t AugmentationDataStartOffset = RecordReader.getOffset();

    uint8_t *NextField = &AugInfo->Fields[0];
    while (uint8_t Field = *NextField++) {
      switch (Field) {
      case 'L':
        CIEInfo.LSDAPresent = true;
        if (auto PE = readPointerEncoding(RecordReader, B, "LSDA"))
          CIEInfo.LSDAEncoding = *PE;
        else
          return PE.takeError();
        break;
      case 'P': {
        auto PersonalityPointerEncoding =
            readPointerEncoding(RecordReader, B, "personality");
        if (!PersonalityPointerEncoding)
          return PersonalityPointerEncoding.takeError();
        if (auto Err =
                getOrCreateEncodedPointerEdge(
                    PC, BlockEdges, *PersonalityPointerEncoding, RecordReader,
                    B, RecordOffset + RecordReader.getOffset(), "personality")
                    .takeError())
          return Err;
        break;
      }
      case 'R':
        if (auto PE = readPointerEncoding(RecordReader, B, "address")) {
          CIEInfo.AddressEncoding = *PE;
          if (CIEInfo.AddressEncoding == dwarf::DW_EH_PE_omit)
            return make_error<JITLinkError>(
                "Invalid address encoding DW_EH_PE_omit in CIE at " +
                formatv("{0:x}", (B.getAddress() + RecordOffset).getValue()));
        } else
          return PE.takeError();
        break;
      default:
        llvm_unreachable("Invalid augmentation string field");
      }
    }

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

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

  return Error::success();
}

Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
                                   size_t RecordOffset, size_t RecordLength,
                                   size_t CIEDeltaFieldOffset,
                                   uint32_t CIEDelta,
                                   const BlockEdgeMap &BlockEdges) {
  LLVM_DEBUG(dbgs() << "      Record is FDE\n");

  orc::ExecutorAddr RecordAddress = B.getAddress() + RecordOffset;

  auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
  BinaryStreamReader RecordReader(
      StringRef(RecordContent.data(), RecordContent.size()),
      PC.G.getEndianness());

  // Skip past the CIE delta field: we've already read this far.
  RecordReader.setOffset(CIEDeltaFieldOffset + 4);

  auto &FDESymbol =
      PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);

  CIEInformation *CIEInfo = nullptr;

  {
    // Process the CIE pointer field.
    auto CIEEdgeItr = BlockEdges.find(RecordOffset + CIEDeltaFieldOffset);
    orc::ExecutorAddr CIEAddress =
        RecordAddress + orc::ExecutorAddrDiff(CIEDeltaFieldOffset) -
        orc::ExecutorAddrDiff(CIEDelta);
    if (CIEEdgeItr == BlockEdges.end()) {

      LLVM_DEBUG({
        dbgs() << "        Adding edge at "
               << (RecordAddress + CIEDeltaFieldOffset)
               << " to CIE at: " << CIEAddress << "\n";
      });
      if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress))
        CIEInfo = *CIEInfoOrErr;
      else
        return CIEInfoOrErr.takeError();
      assert(CIEInfo->CIESymbol && "CIEInfo has no CIE symbol set");
      B.addEdge(NegDelta32, RecordOffset + CIEDeltaFieldOffset,
                *CIEInfo->CIESymbol, 0);
    } else {
      LLVM_DEBUG({
        dbgs() << "        Already has edge at "
               << (RecordAddress + CIEDeltaFieldOffset) << " to CIE at "
               << CIEAddress << "\n";
      });
      auto &EI = CIEEdgeItr->second;
      if (EI.Addend)
        return make_error<JITLinkError>(
            "CIE edge at " +
            formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset) +
            " has non-zero addend");
      if (auto CIEInfoOrErr = PC.findCIEInfo(EI.Target->getAddress()))
        CIEInfo = *CIEInfoOrErr;
      else
        return CIEInfoOrErr.takeError();
    }
  }

  // Process the PC-Begin field.
  LLVM_DEBUG({
    dbgs() << "        Processing PC-begin at "
           << (RecordAddress + RecordReader.getOffset()) << "\n";
  });
  if (auto PCBegin = getOrCreateEncodedPointerEdge(
          PC, BlockEdges, CIEInfo->AddressEncoding, RecordReader, B,
          RecordReader.getOffset(), "PC begin")) {
    assert(*PCBegin && "PC-begin symbol not set");
    if ((*PCBegin)->isDefined()) {
      // Add a keep-alive edge from the FDE target to the FDE to ensure that the
      // FDE is kept alive if its target is.
      LLVM_DEBUG({
        dbgs() << "        Adding keep-alive edge from target at "
               << (*PCBegin)->getBlock().getAddress() << " to FDE at "
               << RecordAddress << "\n";
      });
      (*PCBegin)->getBlock().addEdge(Edge::KeepAlive, 0, FDESymbol, 0);
    } else {
      LLVM_DEBUG({
        dbgs() << "        WARNING: Not adding keep-alive edge to FDE at "
               << RecordAddress << ", which points to "
               << ((*PCBegin)->isExternal() ? "external" : "absolute")
               << " symbol \"" << (*PCBegin)->getName()
               << "\" -- FDE must be kept alive manually or it will be "
               << "dead stripped.\n";
      });
    }
  } else
    return PCBegin.takeError();

  // Skip over the PC range size field.
  if (auto Err = skipEncodedPointer(CIEInfo->AddressEncoding, RecordReader))
    return Err;

  if (CIEInfo->AugmentationDataPresent) {
    uint64_t AugmentationDataSize;
    if (auto Err = RecordReader.readULEB128(AugmentationDataSize))
      return Err;

    if (CIEInfo->LSDAPresent)
      if (auto Err = getOrCreateEncodedPointerEdge(
                         PC, BlockEdges, CIEInfo->LSDAEncoding, RecordReader, B,
                         RecordReader.getOffset(), "LSDA")
                         .takeError())
        return Err;
  } else {
    LLVM_DEBUG(dbgs() << "        Record does not have LSDA field.\n");
  }

  return Error::success();
}

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

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

  while (NextChar != 0) {
    switch (NextChar) {
    case 'z':
      AugInfo.AugmentationDataPresent = true;
      break;
    case 'e':
      if (auto Err = RecordReader.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 = RecordReader.readInteger(NextChar))
      return std::move(Err);
  }

  return std::move(AugInfo);
}

Expected<uint8_t> EHFrameEdgeFixer::readPointerEncoding(BinaryStreamReader &R,
                                                        Block &InBlock,
                                                        const char *FieldName) {
  using namespace dwarf;

  uint8_t PointerEncoding;
  if (auto Err = R.readInteger(PointerEncoding))
    return std::move(Err);

  bool Supported = true;
  switch (PointerEncoding & 0xf) {
  case DW_EH_PE_uleb128:
  case DW_EH_PE_udata2:
  case DW_EH_PE_sleb128:
  case DW_EH_PE_sdata2:
    Supported = false;
    break;
  }
  if (Supported) {
    switch (PointerEncoding & 0x70) {
    case DW_EH_PE_textrel:
    case DW_EH_PE_datarel:
    case DW_EH_PE_funcrel:
    case DW_EH_PE_aligned:
      Supported = false;
      break;
    }
  }

  if (Supported)
    return PointerEncoding;

  return make_error<JITLinkError>("Unsupported pointer encoding " +
                                  formatv("{0:x2}", PointerEncoding) + " for " +
                                  FieldName + "in CFI record at " +
                                  formatv("{0:x16}", InBlock.getAddress()));
}

Error EHFrameEdgeFixer::skipEncodedPointer(uint8_t PointerEncoding,
                                           BinaryStreamReader &RecordReader) {
  using namespace dwarf;

  // Switch absptr to corresponding udata encoding.
  if ((PointerEncoding & 0xf) == DW_EH_PE_absptr)
    PointerEncoding |= (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;

  switch (PointerEncoding & 0xf) {
  case DW_EH_PE_udata4:
  case DW_EH_PE_sdata4:
    if (auto Err = RecordReader.skip(4))
      return Err;
    break;
  case DW_EH_PE_udata8:
  case DW_EH_PE_sdata8:
    if (auto Err = RecordReader.skip(8))
      return Err;
    break;
  default:
    llvm_unreachable("Unrecognized encoding");
  }
  return Error::success();
}

Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
    ParseContext &PC, const BlockEdgeMap &BlockEdges, uint8_t PointerEncoding,
    BinaryStreamReader &RecordReader, Block &BlockToFix,
    size_t PointerFieldOffset, const char *FieldName) {
  using namespace dwarf;

  if (PointerEncoding == DW_EH_PE_omit)
    return nullptr;

  // If there's already an edge here then just skip the encoded pointer and
  // return the edge's target.
  {
    auto EdgeI = BlockEdges.find(PointerFieldOffset);
    if (EdgeI != BlockEdges.end()) {
      LLVM_DEBUG({
        dbgs() << "        Existing edge at "
               << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
               << FieldName << " at " << EdgeI->second.Target->getAddress();
        if (EdgeI->second.Target->hasName())
          dbgs() << " (" << EdgeI->second.Target->getName() << ")";
        dbgs() << "\n";
      });
      if (auto Err = skipEncodedPointer(PointerEncoding, RecordReader))
        return std::move(Err);
      return EdgeI->second.Target;
    }
  }

  // Switch absptr to corresponding udata encoding.
  if ((PointerEncoding & 0xf) == DW_EH_PE_absptr)
    PointerEncoding |= (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4;

  // We need to create an edge. Start by reading the field value.
  uint64_t FieldValue;
  bool Is64Bit = false;
  switch (PointerEncoding & 0xf) {
  case DW_EH_PE_udata4: {
    uint32_t Val;
    if (auto Err = RecordReader.readInteger(Val))
      return std::move(Err);
    FieldValue = Val;
    break;
  }
  case DW_EH_PE_sdata4: {
    uint32_t Val;
    if (auto Err = RecordReader.readInteger(Val))
      return std::move(Err);
    FieldValue = Val;
    break;
  }
  case DW_EH_PE_udata8:
  case DW_EH_PE_sdata8:
    Is64Bit = true;
    if (auto Err = RecordReader.readInteger(FieldValue))
      return std::move(Err);
    break;
  default:
    llvm_unreachable("Unsupported encoding");
  }

  // Find the edge target and edge kind to use.
  orc::ExecutorAddr Target;
  Edge::Kind PtrEdgeKind = Edge::Invalid;
  if ((PointerEncoding & 0x70) == DW_EH_PE_pcrel) {
    Target = BlockToFix.getAddress() + PointerFieldOffset;
    PtrEdgeKind = Is64Bit ? Delta64 : Delta32;
  } else
    PtrEdgeKind = Is64Bit ? Pointer64 : Pointer32;
  Target += FieldValue;

  // Find or create a symbol to point the edge at.
  auto TargetSym = getOrCreateSymbol(PC, Target);
  if (!TargetSym)
    return TargetSym.takeError();
  BlockToFix.addEdge(PtrEdgeKind, PointerFieldOffset, *TargetSym, 0);

  LLVM_DEBUG({
    dbgs() << "        Adding edge at "
           << (BlockToFix.getAddress() + PointerFieldOffset) << " to "
           << FieldName << " at " << TargetSym->getAddress();
    if (TargetSym->hasName())
      dbgs() << " (" << TargetSym->getName() << ")";
    dbgs() << "\n";
  });

  return &*TargetSym;
}

Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC,
                                                       orc::ExecutorAddr Addr) {
  // See whether we have a canonical symbol for the given address already.
  auto CanonicalSymI = PC.AddrToSym.find(Addr);
  if (CanonicalSymI != PC.AddrToSym.end())
    return *CanonicalSymI->second;

  // Otherwise search for a block covering the address and create a new symbol.
  auto *B = PC.AddrToBlock.getBlockCovering(Addr);
  if (!B)
    return make_error<JITLinkError>("No symbol or block covering address " +
                                    formatv("{0:x16}", Addr));

  auto &S =
      PC.G.addAnonymousSymbol(*B, Addr - B->getAddress(), 0, false, false);
  PC.AddrToSym[S.getAddress()] = &S;
  return S;
}

char EHFrameNullTerminator::NullTerminatorBlockContent[4] = {0, 0, 0, 0};

EHFrameNullTerminator::EHFrameNullTerminator(StringRef EHFrameSectionName)
    : EHFrameSectionName(EHFrameSectionName) {}

Error EHFrameNullTerminator::operator()(LinkGraph &G) {
  auto *EHFrame = G.findSectionByName(EHFrameSectionName);

  if (!EHFrame)
    return Error::success();

  LLVM_DEBUG({
    dbgs() << "EHFrameNullTerminator adding null terminator to "
           << EHFrameSectionName << "\n";
  });

  auto &NullTerminatorBlock =
      G.createContentBlock(*EHFrame, NullTerminatorBlockContent,
                           orc::ExecutorAddr(~uint64_t(4)), 1, 0);
  G.addAnonymousSymbol(NullTerminatorBlock, 0, 4, false, true);
  return Error::success();
}

EHFrameRegistrar::~EHFrameRegistrar() = default;

Error InProcessEHFrameRegistrar::registerEHFrames(
    orc::ExecutorAddrRange EHFrameSection) {
  return orc::registerEHFrameSection(EHFrameSection.Start.toPtr<void *>(),
                                     EHFrameSection.size());
}

Error InProcessEHFrameRegistrar::deregisterEHFrames(
    orc::ExecutorAddrRange EHFrameSection) {
  return orc::deregisterEHFrameSection(EHFrameSection.Start.toPtr<void *>(),
                                       EHFrameSection.size());
}

EHFrameCFIBlockInspector EHFrameCFIBlockInspector::FromEdgeScan(Block &B) {
  if (B.edges_empty())
    return EHFrameCFIBlockInspector(nullptr);
  if (B.edges_size() == 1)
    return EHFrameCFIBlockInspector(&*B.edges().begin());
  SmallVector<Edge *, 3> Es;
  for (auto &E : B.edges())
    Es.push_back(&E);
  assert(Es.size() >= 2 && Es.size() <= 3 && "Unexpected number of edges");
  llvm::sort(Es, [](const Edge *LHS, const Edge *RHS) {
    return LHS->getOffset() < RHS->getOffset();
  });
  return EHFrameCFIBlockInspector(*Es[0], *Es[1],
                                  Es.size() == 3 ? Es[2] : nullptr);
  return EHFrameCFIBlockInspector(nullptr);
}

EHFrameCFIBlockInspector::EHFrameCFIBlockInspector(Edge *PersonalityEdge)
    : PersonalityEdge(PersonalityEdge) {}

EHFrameCFIBlockInspector::EHFrameCFIBlockInspector(Edge &CIEEdge,
                                                   Edge &PCBeginEdge,
                                                   Edge *LSDAEdge)
    : CIEEdge(&CIEEdge), PCBeginEdge(&PCBeginEdge), LSDAEdge(LSDAEdge) {}

LinkGraphPassFunction
createEHFrameRecorderPass(const Triple &TT,
                          StoreFrameRangeFunction StoreRangeAddress) {
  const char *EHFrameSectionName = nullptr;
  if (TT.getObjectFormat() == Triple::MachO)
    EHFrameSectionName = "__TEXT,__eh_frame";
  else
    EHFrameSectionName = ".eh_frame";

  auto RecordEHFrame =
      [EHFrameSectionName,
       StoreFrameRange = std::move(StoreRangeAddress)](LinkGraph &G) -> Error {
    // Search for a non-empty eh-frame and record the address of the first
    // symbol in it.
    orc::ExecutorAddr Addr;
    size_t Size = 0;
    if (auto *S = G.findSectionByName(EHFrameSectionName)) {
      auto R = SectionRange(*S);
      Addr = R.getStart();
      Size = R.getSize();
    }
    if (!Addr && Size != 0)
      return make_error<JITLinkError>(
          StringRef(EHFrameSectionName) +
          " section can not have zero address with non-zero size");
    StoreFrameRange(Addr, Size);
    return Error::success();
  };

  return RecordEHFrame;
}

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