xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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