Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:49

0001 //===--------- EHFrameSupport.h - JITLink eh-frame utils --------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // EHFrame registration support for JITLink.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H
0014 #define LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H
0015 
0016 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
0017 #include "llvm/ExecutionEngine/JITSymbol.h"
0018 #include "llvm/Support/Error.h"
0019 #include "llvm/TargetParser/Triple.h"
0020 
0021 namespace llvm {
0022 namespace jitlink {
0023 
0024 /// Inspect an eh-frame CFI record.
0025 class EHFrameCFIBlockInspector {
0026 public:
0027   /// Identify CFI record type and edges based on number and order of edges
0028   /// in the given block only. This assumes that the block contains one CFI
0029   /// record that has already been split out and fixed by the
0030   /// DWARFRecordSplitter and EHFrameEdgeFixer passes.
0031   ///
0032   /// Zero or one outgoing edges: Record is CIE. If present, edge points to
0033   /// personality.
0034   ///
0035   /// Two or three outgoing edges: Record is an FDE. First edge points to CIE,
0036   /// second to PC-begin, third (if present) to LSDA.
0037   ///
0038   /// It is illegal to call this function on a block with four or more edges.
0039   static EHFrameCFIBlockInspector FromEdgeScan(Block &B);
0040 
0041   /// Returns true if this frame is an FDE, false for a CIE.
0042   bool isFDE() const { return CIEEdge != nullptr; }
0043 
0044   /// Returns true if this frame is a CIE, false for an FDE.
0045   bool isCIE() const { return CIEEdge == nullptr; }
0046 
0047   /// If this is a CIE record, returns the Edge pointing at the personality
0048   /// function, if any.
0049   /// It is illegal to call this method on FDE records.
0050   Edge *getPersonalityEdge() const {
0051     assert(isCIE() && "CFI record is not a CIE");
0052     return PersonalityEdge;
0053   }
0054 
0055   /// If this is an FDE record, returns the Edge pointing to the CIE.
0056   /// If this is a CIE record, returns null.
0057   ///
0058   /// The result is not valid if any modification has been made to the block
0059   /// after parsing.
0060   Edge *getCIEEdge() const { return CIEEdge; }
0061 
0062   /// If this is an FDE record, returns the Edge pointing at the PC-begin
0063   /// symbol.
0064   /// If this a CIE record, returns null.
0065   Edge *getPCBeginEdge() const { return PCBeginEdge; }
0066 
0067   /// If this is an FDE record, returns the Edge pointing at the LSDA, if any.
0068   /// It is illegal to call this method on CIE records.
0069   Edge *getLSDAEdge() const {
0070     assert(isFDE() && "CFI record is not an FDE");
0071     return LSDAEdge;
0072   }
0073 
0074 private:
0075   EHFrameCFIBlockInspector(Edge *PersonalityEdge);
0076   EHFrameCFIBlockInspector(Edge &CIEEdge, Edge &PCBeginEdge, Edge *LSDAEdge);
0077 
0078   Edge *CIEEdge = nullptr;
0079   Edge *PCBeginEdge = nullptr;
0080   union {
0081     Edge *PersonalityEdge;
0082     Edge *LSDAEdge;
0083   };
0084 };
0085 
0086 /// Supports registration/deregistration of EH-frames in a target process.
0087 class EHFrameRegistrar {
0088 public:
0089   virtual ~EHFrameRegistrar();
0090   virtual Error registerEHFrames(orc::ExecutorAddrRange EHFrameSection) = 0;
0091   virtual Error deregisterEHFrames(orc::ExecutorAddrRange EHFrameSection) = 0;
0092 };
0093 
0094 /// Registers / Deregisters EH-frames in the current process.
0095 class InProcessEHFrameRegistrar final : public EHFrameRegistrar {
0096 public:
0097   Error registerEHFrames(orc::ExecutorAddrRange EHFrameSection) override;
0098 
0099   Error deregisterEHFrames(orc::ExecutorAddrRange EHFrameSection) override;
0100 };
0101 
0102 using StoreFrameRangeFunction = std::function<void(
0103     orc::ExecutorAddr EHFrameSectionAddr, size_t EHFrameSectionSize)>;
0104 
0105 /// Creates a pass that records the address and size of the EH frame section.
0106 /// If no eh-frame section is found then the address and size will both be given
0107 /// as zero.
0108 ///
0109 /// Authors of JITLinkContexts can use this function to register a post-fixup
0110 /// pass that records the range of the eh-frame section. This range can
0111 /// be used after finalization to register and deregister the frame.
0112 LinkGraphPassFunction
0113 createEHFrameRecorderPass(const Triple &TT,
0114                           StoreFrameRangeFunction StoreFrameRange);
0115 
0116 } // end namespace jitlink
0117 } // end namespace llvm
0118 
0119 #endif // LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H