brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 841ec9c Raw
135 lines · c
1//===------- EHFrameSupportImpl.h - JITLink eh-frame utils ------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// EHFrame registration support for JITLink.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H14#define LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H15 16#include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"17 18#include "llvm/ExecutionEngine/JITLink/JITLink.h"19#include "llvm/Support/BinaryStreamReader.h"20 21namespace llvm {22namespace jitlink {23 24/// A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA25/// edges.26class EHFrameEdgeFixer {27public:28  /// Create an eh-frame edge fixer.29  /// Adds edges for implicit relocations on platforms where these are used30  /// (e.g. MachO/x86-64).31  ///32  /// If a given edge-kind is not supported on the target architecture then33  /// Edge::Invalid should be used.34  EHFrameEdgeFixer(StringRef EHFrameSectionName, unsigned PointerSize,35                   Edge::Kind Pointer32, Edge::Kind Pointer64,36                   Edge::Kind Delta32, Edge::Kind Delta64,37                   Edge::Kind NegDelta32);38  Error operator()(LinkGraph &G);39 40private:41 42  struct AugmentationInfo {43    bool AugmentationDataPresent = false;44    bool EHDataFieldPresent = false;45    uint8_t Fields[4] = {0x0, 0x0, 0x0, 0x0};46  };47 48  struct CIEInformation {49    CIEInformation() = default;50    CIEInformation(Symbol &CIESymbol) : CIESymbol(&CIESymbol) {}51    Symbol *CIESymbol = nullptr;52    bool AugmentationDataPresent = false;53    bool LSDAPresent = false;54    uint8_t LSDAEncoding = 0;55    uint8_t AddressEncoding = 0;56  };57 58  struct EdgeTarget {59    EdgeTarget() = default;60    EdgeTarget(const Edge &E) : Target(&E.getTarget()), Addend(E.getAddend()) {}61 62    Symbol *Target = nullptr;63    Edge::AddendT Addend = 0;64  };65 66  struct BlockEdgesInfo {67    DenseMap<Edge::OffsetT, EdgeTarget> TargetMap;68    DenseSet<Edge::OffsetT> Multiple;69  };70 71  using CIEInfosMap = DenseMap<orc::ExecutorAddr, CIEInformation>;72 73  struct ParseContext {74    ParseContext(LinkGraph &G) : G(G) {}75 76    Expected<CIEInformation *> findCIEInfo(orc::ExecutorAddr Address) {77      auto I = CIEInfos.find(Address);78      if (I == CIEInfos.end())79        return make_error<JITLinkError>("No CIE found at address " +80                                        formatv("{0:x16}", Address));81      return &I->second;82    }83 84    LinkGraph &G;85    CIEInfosMap CIEInfos;86    BlockAddressMap AddrToBlock;87    DenseMap<orc::ExecutorAddr, Symbol *> AddrToSym;88  };89 90  Error processBlock(ParseContext &PC, Block &B);91  Error processCIE(ParseContext &PC, Block &B, size_t CIEDeltaFieldOffset,92                   const BlockEdgesInfo &BlockEdges);93  Error processFDE(ParseContext &PC, Block &B, size_t CIEDeltaFieldOffset,94                   uint32_t CIEDelta, const BlockEdgesInfo &BlockEdges);95 96  Expected<AugmentationInfo>97  parseAugmentationString(BinaryStreamReader &RecordReader);98 99  Expected<uint8_t> readPointerEncoding(BinaryStreamReader &RecordReader,100                                        Block &InBlock, const char *FieldName);101  Error skipEncodedPointer(uint8_t PointerEncoding,102                           BinaryStreamReader &RecordReader);103  Expected<Symbol *> getOrCreateEncodedPointerEdge(104      ParseContext &PC, const BlockEdgesInfo &BlockEdges,105      uint8_t PointerEncoding, BinaryStreamReader &RecordReader,106      Block &BlockToFix, size_t PointerFieldOffset, const char *FieldName);107 108  Expected<Symbol &> getOrCreateSymbol(ParseContext &PC,109                                       orc::ExecutorAddr Addr);110 111  StringRef EHFrameSectionName;112  unsigned PointerSize;113  Edge::Kind Pointer32;114  Edge::Kind Pointer64;115  Edge::Kind Delta32;116  Edge::Kind Delta64;117  Edge::Kind NegDelta32;118};119 120/// Add a 32-bit null-terminator to the end of the eh-frame section.121class EHFrameNullTerminator {122public:123  EHFrameNullTerminator(StringRef EHFrameSectionName);124  Error operator()(LinkGraph &G);125 126private:127  static char NullTerminatorBlockContent[];128  StringRef EHFrameSectionName;129};130 131} // end namespace jitlink132} // end namespace llvm133 134#endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H135