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/Error.h"
19#include "llvm/TargetParser/Triple.h"
20
21namespace llvm {
22namespace jitlink {
23
24/// Inspect an eh-frame CFI record.
25class EHFrameCFIBlockInspector {
26public:
27 /// Identify CFI record type and edges based on number and order of edges
28 /// in the given block only. This assumes that the block contains one CFI
29 /// record that has already been split out and fixed by the
30 /// DWARFRecordSplitter and EHFrameEdgeFixer passes.
31 ///
32 /// Zero or one outgoing edges: Record is CIE. If present, edge points to
33 /// personality.
34 ///
35 /// Two or three outgoing edges: Record is an FDE. First edge points to CIE,
36 /// second to PC-begin, third (if present) to LSDA.
37 ///
38 /// It is illegal to call this function on a block with four or more edges.
39 static EHFrameCFIBlockInspector FromEdgeScan(Block &B);
40
41 /// Returns true if this frame is an FDE, false for a CIE.
42 bool isFDE() const { return CIEEdge != nullptr; }
43
44 /// Returns true if this frame is a CIE, false for an FDE.
45 bool isCIE() const { return CIEEdge == nullptr; }
46
47 /// If this is a CIE record, returns the Edge pointing at the personality
48 /// function, if any.
49 /// It is illegal to call this method on FDE records.
50 Edge *getPersonalityEdge() const {
51 assert(isCIE() && "CFI record is not a CIE");
52 return PersonalityEdge;
53 }
54
55 /// If this is an FDE record, returns the Edge pointing to the CIE.
56 /// If this is a CIE record, returns null.
57 ///
58 /// The result is not valid if any modification has been made to the block
59 /// after parsing.
60 Edge *getCIEEdge() const { return CIEEdge; }
61
62 /// If this is an FDE record, returns the Edge pointing at the PC-begin
63 /// symbol.
64 /// If this a CIE record, returns null.
65 Edge *getPCBeginEdge() const { return PCBeginEdge; }
66
67 /// If this is an FDE record, returns the Edge pointing at the LSDA, if any.
68 /// It is illegal to call this method on CIE records.
69 Edge *getLSDAEdge() const {
70 assert(isFDE() && "CFI record is not an FDE");
71 return LSDAEdge;
72 }
73
74private:
75 EHFrameCFIBlockInspector(Edge *PersonalityEdge);
76 EHFrameCFIBlockInspector(Edge &CIEEdge, Edge &PCBeginEdge, Edge *LSDAEdge);
77
78 Edge *CIEEdge = nullptr;
79 Edge *PCBeginEdge = nullptr;
80 union {
81 Edge *PersonalityEdge;
82 Edge *LSDAEdge;
83 };
84};
85
86/// Supports registration/deregistration of EH-frames in a target process.
87class EHFrameRegistrar {
88public:
89 virtual ~EHFrameRegistrar();
90 virtual Error registerEHFrames(orc::ExecutorAddrRange EHFrameSection) = 0;
91 virtual Error deregisterEHFrames(orc::ExecutorAddrRange EHFrameSection) = 0;
92};
93
94/// Registers / Deregisters EH-frames in the current process.
95class InProcessEHFrameRegistrar final : public EHFrameRegistrar {
96public:
97 Error registerEHFrames(orc::ExecutorAddrRange EHFrameSection) override;
98
99 Error deregisterEHFrames(orc::ExecutorAddrRange EHFrameSection) override;
100};
101
102using StoreFrameRangeFunction = std::function<void(
103 orc::ExecutorAddr EHFrameSectionAddr, size_t EHFrameSectionSize)>;
104
105/// Creates a pass that records the address and size of the EH frame section.
106/// If no eh-frame section is found then the address and size will both be given
107/// as zero.
108///
109/// Authors of JITLinkContexts can use this function to register a post-fixup
110/// pass that records the range of the eh-frame section. This range can
111/// be used after finalization to register and deregister the frame.
112LinkGraphPassFunction
113createEHFrameRecorderPass(const Triple &TT,
114 StoreFrameRangeFunction StoreFrameRange);
115
116} // end namespace jitlink
117} // end namespace llvm
118
119#endif // LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H
120

source code of llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h