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