diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h')
-rw-r--r-- | llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h | 96 |
1 files changed, 65 insertions, 31 deletions
diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h index 6f9f68ad8382..a8cd32c664dc 100644 --- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h +++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h @@ -21,30 +21,30 @@ namespace llvm { namespace jitlink { -/// A generic binary parser for eh-frame sections. -/// -/// Adds blocks and symbols representing CIE and FDE entries to a JITLink graph. -/// -/// This parser assumes that the user has already verified that the EH-frame's -/// address range does not overlap any other section/symbol, so that generated -/// CIE/FDE records do not overlap other sections/symbols. -class EHFrameBinaryParser { +/// A LinkGraph pass that splits blocks in an eh-frame section into sub-blocks +/// representing individual eh-frames. +/// EHFrameSplitter should not be run without EHFrameEdgeFixer, which is +/// responsible for adding FDE-to-CIE edges. +class EHFrameSplitter { public: - EHFrameBinaryParser(JITTargetAddress EHFrameAddress, StringRef EHFrameContent, - unsigned PointerSize, support::endianness Endianness); - virtual ~EHFrameBinaryParser() {} + EHFrameSplitter(StringRef EHFrameSectionName); + Error operator()(LinkGraph &G); - Error addToGraph(); +private: + Error processBlock(LinkGraph &G, Block &B, LinkGraph::SplitBlockCache &Cache); + + StringRef EHFrameSectionName; +}; + +/// A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA +/// edges. +class EHFrameEdgeFixer { +public: + EHFrameEdgeFixer(StringRef EHFrameSectionName, Edge::Kind FDEToCIE, + Edge::Kind FDEToPCBegin, Edge::Kind FDEToLSDA); + Error operator()(LinkGraph &G); private: - virtual void anchor(); - virtual Symbol *getSymbolAtAddress(JITTargetAddress Addr) = 0; - virtual Symbol &createCIERecord(JITTargetAddress RecordAddr, - StringRef RecordContent) = 0; - virtual Expected<Symbol &> - createFDERecord(JITTargetAddress RecordAddr, StringRef RecordContent, - Symbol &CIE, size_t CIEOffset, Symbol &Func, - size_t FuncOffset, Symbol *LSDA, size_t LSDAOffset) = 0; struct AugmentationInfo { bool AugmentationDataPresent = false; @@ -52,12 +52,6 @@ private: uint8_t Fields[4] = {0x0, 0x0, 0x0, 0x0}; }; - Expected<AugmentationInfo> parseAugmentationString(); - Expected<JITTargetAddress> readAbsolutePointer(); - Error processCIE(size_t RecordOffset, size_t RecordLength); - Error processFDE(size_t RecordOffset, size_t RecordLength, - JITTargetAddress CIEPointerOffset, uint32_t CIEPointer); - struct CIEInformation { CIEInformation() = default; CIEInformation(Symbol &CIESymbol) : CIESymbol(&CIESymbol) {} @@ -65,11 +59,51 @@ private: bool FDEsHaveLSDAField = false; }; - JITTargetAddress EHFrameAddress; - StringRef EHFrameContent; - unsigned PointerSize; - BinaryStreamReader EHFrameReader; - DenseMap<JITTargetAddress, CIEInformation> CIEInfos; + struct EdgeTarget { + EdgeTarget() = default; + EdgeTarget(const Edge &E) : Target(&E.getTarget()), Addend(E.getAddend()) {} + + Symbol *Target = nullptr; + Edge::AddendT Addend = 0; + }; + + using BlockEdgeMap = DenseMap<Edge::OffsetT, EdgeTarget>; + using CIEInfosMap = DenseMap<JITTargetAddress, CIEInformation>; + + struct ParseContext { + ParseContext(LinkGraph &G) : G(G) {} + + Expected<CIEInformation *> findCIEInfo(JITTargetAddress Address) { + auto I = CIEInfos.find(Address); + if (I == CIEInfos.end()) + return make_error<JITLinkError>("No CIE found at address " + + formatv("{0:x16}", Address)); + return &I->second; + } + + LinkGraph &G; + CIEInfosMap CIEInfos; + BlockAddressMap AddrToBlock; + SymbolAddressMap AddrToSyms; + }; + + Error processBlock(ParseContext &PC, Block &B); + Error processCIE(ParseContext &PC, Block &B, size_t RecordOffset, + size_t RecordLength, size_t CIEDeltaFieldOffset); + Error processFDE(ParseContext &PC, Block &B, size_t RecordOffset, + size_t RecordLength, size_t CIEDeltaFieldOffset, + uint32_t CIEDelta, BlockEdgeMap &BlockEdges); + + Expected<AugmentationInfo> + parseAugmentationString(BinaryStreamReader &RecordReader); + Expected<JITTargetAddress> + readAbsolutePointer(LinkGraph &G, BinaryStreamReader &RecordReader); + Expected<Symbol &> getOrCreateSymbol(ParseContext &PC, JITTargetAddress Addr); + + StringRef EHFrameSectionName; + Edge::Kind FDEToCIE; + Edge::Kind FDEToPCBegin; + Edge::Kind FDEToLSDA; }; } // end namespace jitlink |