1 //===--------- EHFrameSupport.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // EHFrame registration support for JITLink. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H 14 #define LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H 15 16 #include "llvm/ExecutionEngine/JITLink/JITLink.h" 17 #include "llvm/ExecutionEngine/JITSymbol.h" 18 #include "llvm/Support/Compiler.h" 19 #include "llvm/Support/Error.h" 20 #include "llvm/TargetParser/Triple.h" 21 22 namespace llvm { 23 namespace jitlink { 24 25 /// Inspect an eh-frame CFI record. 26 class EHFrameCFIBlockInspector { 27 public: 28 /// Identify CFI record type and edges based on number and order of edges 29 /// in the given block only. This assumes that the block contains one CFI 30 /// record that has already been split out and fixed by the 31 /// DWARFRecordSplitter and EHFrameEdgeFixer passes. 32 /// 33 /// Zero or one outgoing edges: Record is CIE. If present, edge points to 34 /// personality. 35 /// 36 /// Two or three outgoing edges: Record is an FDE. First edge points to CIE, 37 /// second to PC-begin, third (if present) to LSDA. 38 /// 39 /// It is illegal to call this function on a block with four or more edges. 40 LLVM_ABI static EHFrameCFIBlockInspector FromEdgeScan(Block &B); 41 42 /// Returns true if this frame is an FDE, false for a CIE. isFDE()43 bool isFDE() const { return CIEEdge != nullptr; } 44 45 /// Returns true if this frame is a CIE, false for an FDE. isCIE()46 bool isCIE() const { return CIEEdge == nullptr; } 47 48 /// If this is a CIE record, returns the Edge pointing at the personality 49 /// function, if any. 50 /// It is illegal to call this method on FDE records. getPersonalityEdge()51 Edge *getPersonalityEdge() const { 52 assert(isCIE() && "CFI record is not a CIE"); 53 return PersonalityEdge; 54 } 55 56 /// If this is an FDE record, returns the Edge pointing to the CIE. 57 /// If this is a CIE record, returns null. 58 /// 59 /// The result is not valid if any modification has been made to the block 60 /// after parsing. getCIEEdge()61 Edge *getCIEEdge() const { return CIEEdge; } 62 63 /// If this is an FDE record, returns the Edge pointing at the PC-begin 64 /// symbol. 65 /// If this a CIE record, returns null. getPCBeginEdge()66 Edge *getPCBeginEdge() const { return PCBeginEdge; } 67 68 /// If this is an FDE record, returns the Edge pointing at the LSDA, if any. 69 /// It is illegal to call this method on CIE records. getLSDAEdge()70 Edge *getLSDAEdge() const { 71 assert(isFDE() && "CFI record is not an FDE"); 72 return LSDAEdge; 73 } 74 75 private: 76 EHFrameCFIBlockInspector(Edge *PersonalityEdge); 77 EHFrameCFIBlockInspector(Edge &CIEEdge, Edge &PCBeginEdge, Edge *LSDAEdge); 78 79 Edge *CIEEdge = nullptr; 80 Edge *PCBeginEdge = nullptr; 81 union { 82 Edge *PersonalityEdge; 83 Edge *LSDAEdge; 84 }; 85 }; 86 87 /// Returns a pointer to the DWARF eh-frame section if the graph contains a 88 /// non-empty one, otherwise returns null. 89 LLVM_ABI Section *getEHFrameSection(LinkGraph &G); 90 91 } // end namespace jitlink 92 } // end namespace llvm 93 94 #endif // LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H 95