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 splits blocks in an eh-frame section into sub-blocks
25 /// representing individual eh-frames.
26 /// EHFrameSplitter should not be run without EHFrameEdgeFixer, which is
27 /// responsible for adding FDE-to-CIE edges.
28 class EHFrameSplitter
{
30 EHFrameSplitter(StringRef EHFrameSectionName
);
31 Error
operator()(LinkGraph
&G
);
34 Error
processBlock(LinkGraph
&G
, Block
&B
, LinkGraph::SplitBlockCache
&Cache
);
36 StringRef EHFrameSectionName
;
39 /// A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA
41 class EHFrameEdgeFixer
{
43 EHFrameEdgeFixer(StringRef EHFrameSectionName
, unsigned PointerSize
,
44 Edge::Kind Delta64
, Edge::Kind Delta32
,
45 Edge::Kind NegDelta32
);
46 Error
operator()(LinkGraph
&G
);
50 struct AugmentationInfo
{
51 bool AugmentationDataPresent
= false;
52 bool EHDataFieldPresent
= false;
53 uint8_t Fields
[4] = {0x0, 0x0, 0x0, 0x0};
56 struct CIEInformation
{
57 CIEInformation() = default;
58 CIEInformation(Symbol
&CIESymbol
) : CIESymbol(&CIESymbol
) {}
59 Symbol
*CIESymbol
= nullptr;
60 bool FDEsHaveLSDAField
= false;
61 uint8_t FDEPointerEncoding
= 0;
62 uint8_t LSDAPointerEncoding
= 0;
66 EdgeTarget() = default;
67 EdgeTarget(const Edge
&E
) : Target(&E
.getTarget()), Addend(E
.getAddend()) {}
69 Symbol
*Target
= nullptr;
70 Edge::AddendT Addend
= 0;
73 using BlockEdgeMap
= DenseMap
<Edge::OffsetT
, EdgeTarget
>;
74 using CIEInfosMap
= DenseMap
<JITTargetAddress
, CIEInformation
>;
77 ParseContext(LinkGraph
&G
) : G(G
) {}
79 Expected
<CIEInformation
*> findCIEInfo(JITTargetAddress Address
) {
80 auto I
= CIEInfos
.find(Address
);
81 if (I
== CIEInfos
.end())
82 return make_error
<JITLinkError
>("No CIE found at address " +
83 formatv("{0:x16}", Address
));
89 BlockAddressMap AddrToBlock
;
90 SymbolAddressMap AddrToSyms
;
93 Error
processBlock(ParseContext
&PC
, Block
&B
);
94 Error
processCIE(ParseContext
&PC
, Block
&B
, size_t RecordOffset
,
95 size_t RecordLength
, size_t CIEDeltaFieldOffset
);
96 Error
processFDE(ParseContext
&PC
, Block
&B
, size_t RecordOffset
,
97 size_t RecordLength
, size_t CIEDeltaFieldOffset
,
98 uint32_t CIEDelta
, BlockEdgeMap
&BlockEdges
);
100 Expected
<AugmentationInfo
>
101 parseAugmentationString(BinaryStreamReader
&RecordReader
);
103 static bool isSupportedPointerEncoding(uint8_t PointerEncoding
);
104 unsigned getPointerEncodingDataSize(uint8_t PointerEncoding
);
105 Expected
<std::pair
<JITTargetAddress
, Edge::Kind
>>
106 readEncodedPointer(uint8_t PointerEncoding
,
107 JITTargetAddress PointerFieldAddress
,
108 BinaryStreamReader
&RecordReader
);
110 Expected
<Symbol
&> getOrCreateSymbol(ParseContext
&PC
, JITTargetAddress Addr
);
112 StringRef EHFrameSectionName
;
113 unsigned PointerSize
;
116 Edge::Kind NegDelta32
;
119 /// Add a 32-bit null-terminator to the end of the eh-frame section.
120 class EHFrameNullTerminator
{
122 EHFrameNullTerminator(StringRef EHFrameSectionName
);
123 Error
operator()(LinkGraph
&G
);
126 static char NullTerminatorBlockContent
[];
127 StringRef EHFrameSectionName
;
130 } // end namespace jitlink
131 } // end namespace llvm
133 #endif // LLVM_LIB_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORTIMPL_H