1 //===------- EHFrameSupportImpl.h - JITLink eh-frame utils ------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // EHFrame registration support for JITLink.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H
14 #define LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H
16 #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
18 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
19 #include "llvm/Support/BinaryStreamReader.h"
24 /// A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA
26 class EHFrameEdgeFixer
{
28 /// Create an eh-frame edge fixer.
29 /// If a given edge-kind is not supported on the target architecture then
30 /// Edge::Invalid should be used.
31 EHFrameEdgeFixer(StringRef EHFrameSectionName
, unsigned PointerSize
,
32 Edge::Kind Pointer32
, Edge::Kind Pointer64
,
33 Edge::Kind Delta32
, Edge::Kind Delta64
,
34 Edge::Kind NegDelta32
);
35 Error
operator()(LinkGraph
&G
);
39 struct AugmentationInfo
{
40 bool AugmentationDataPresent
= false;
41 bool EHDataFieldPresent
= false;
42 uint8_t Fields
[4] = {0x0, 0x0, 0x0, 0x0};
45 struct CIEInformation
{
46 CIEInformation() = default;
47 CIEInformation(Symbol
&CIESymbol
) : CIESymbol(&CIESymbol
) {}
48 Symbol
*CIESymbol
= nullptr;
49 bool AugmentationDataPresent
= false;
50 bool LSDAPresent
= false;
51 uint8_t LSDAEncoding
= 0;
52 uint8_t AddressEncoding
= 0;
56 EdgeTarget() = default;
57 EdgeTarget(const Edge
&E
) : Target(&E
.getTarget()), Addend(E
.getAddend()) {}
59 Symbol
*Target
= nullptr;
60 Edge::AddendT Addend
= 0;
63 struct BlockEdgesInfo
{
64 DenseMap
<Edge::OffsetT
, EdgeTarget
> TargetMap
;
65 DenseSet
<Edge::OffsetT
> Multiple
;
68 using CIEInfosMap
= DenseMap
<orc::ExecutorAddr
, CIEInformation
>;
71 ParseContext(LinkGraph
&G
) : G(G
) {}
73 Expected
<CIEInformation
*> findCIEInfo(orc::ExecutorAddr Address
) {
74 auto I
= CIEInfos
.find(Address
);
75 if (I
== CIEInfos
.end())
76 return make_error
<JITLinkError
>("No CIE found at address " +
77 formatv("{0:x16}", Address
));
83 BlockAddressMap AddrToBlock
;
84 DenseMap
<orc::ExecutorAddr
, Symbol
*> AddrToSym
;
87 Error
processBlock(ParseContext
&PC
, Block
&B
);
88 Error
processCIE(ParseContext
&PC
, Block
&B
, size_t CIEDeltaFieldOffset
,
89 const BlockEdgesInfo
&BlockEdges
);
90 Error
processFDE(ParseContext
&PC
, Block
&B
, size_t CIEDeltaFieldOffset
,
91 uint32_t CIEDelta
, const BlockEdgesInfo
&BlockEdges
);
93 Expected
<AugmentationInfo
>
94 parseAugmentationString(BinaryStreamReader
&RecordReader
);
96 Expected
<uint8_t> readPointerEncoding(BinaryStreamReader
&RecordReader
,
97 Block
&InBlock
, const char *FieldName
);
98 Error
skipEncodedPointer(uint8_t PointerEncoding
,
99 BinaryStreamReader
&RecordReader
);
100 Expected
<Symbol
*> getOrCreateEncodedPointerEdge(
101 ParseContext
&PC
, const BlockEdgesInfo
&BlockEdges
,
102 uint8_t PointerEncoding
, BinaryStreamReader
&RecordReader
,
103 Block
&BlockToFix
, size_t PointerFieldOffset
, const char *FieldName
);
105 Expected
<Symbol
&> getOrCreateSymbol(ParseContext
&PC
,
106 orc::ExecutorAddr Addr
);
108 StringRef EHFrameSectionName
;
109 unsigned PointerSize
;
110 Edge::Kind Pointer32
;
111 Edge::Kind Pointer64
;
114 Edge::Kind NegDelta32
;
117 /// Add a 32-bit null-terminator to the end of the eh-frame section.
118 class EHFrameNullTerminator
{
120 EHFrameNullTerminator(StringRef EHFrameSectionName
);
121 Error
operator()(LinkGraph
&G
);
124 static char NullTerminatorBlockContent
[];
125 StringRef EHFrameSectionName
;
128 } // end namespace jitlink
129 } // end namespace llvm
131 #endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H