1*972a253aSDimitry Andric //===------- SEHFrameSupport.h - JITLink seh-frame utils --------*- C++ -*-===// 2*972a253aSDimitry Andric // 3*972a253aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*972a253aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*972a253aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*972a253aSDimitry Andric // 7*972a253aSDimitry Andric //===----------------------------------------------------------------------===// 8*972a253aSDimitry Andric // 9*972a253aSDimitry Andric // SEHFrame utils for JITLink. 10*972a253aSDimitry Andric // 11*972a253aSDimitry Andric //===----------------------------------------------------------------------===// 12*972a253aSDimitry Andric 13*972a253aSDimitry Andric #ifndef LLVM_EXECUTIONENGINE_JITLINK_SEHFRAMESUPPORT_H 14*972a253aSDimitry Andric #define LLVM_EXECUTIONENGINE_JITLINK_SEHFRAMESUPPORT_H 15*972a253aSDimitry Andric 16*972a253aSDimitry Andric #include "llvm/ADT/Triple.h" 17*972a253aSDimitry Andric #include "llvm/ExecutionEngine/JITLink/JITLink.h" 18*972a253aSDimitry Andric #include "llvm/ExecutionEngine/JITSymbol.h" 19*972a253aSDimitry Andric #include "llvm/Support/Error.h" 20*972a253aSDimitry Andric 21*972a253aSDimitry Andric namespace llvm { 22*972a253aSDimitry Andric namespace jitlink { 23*972a253aSDimitry Andric /// This pass adds keep-alive edge from SEH frame sections 24*972a253aSDimitry Andric /// to the parent function content block. 25*972a253aSDimitry Andric class SEHFrameKeepAlivePass { 26*972a253aSDimitry Andric public: 27*972a253aSDimitry Andric SEHFrameKeepAlivePass(StringRef SEHFrameSectionName) 28*972a253aSDimitry Andric : SEHFrameSectionName(SEHFrameSectionName) {} 29*972a253aSDimitry Andric 30*972a253aSDimitry Andric Error operator()(LinkGraph &G) { 31*972a253aSDimitry Andric auto *S = G.findSectionByName(SEHFrameSectionName); 32*972a253aSDimitry Andric if (!S) 33*972a253aSDimitry Andric return Error::success(); 34*972a253aSDimitry Andric 35*972a253aSDimitry Andric // Simply consider every block pointed by seh frame block as parants. 36*972a253aSDimitry Andric // This adds some unnecessary keep-alive edges to unwind info blocks, 37*972a253aSDimitry Andric // (xdata) but these blocks are usually dead by default, so they wouldn't 38*972a253aSDimitry Andric // count for the fate of seh frame block. 39*972a253aSDimitry Andric for (auto *B : S->blocks()) { 40*972a253aSDimitry Andric auto &DummySymbol = G.addAnonymousSymbol(*B, 0, 0, false, false); 41*972a253aSDimitry Andric DenseSet<Block *> Children; 42*972a253aSDimitry Andric for (auto &E : B->edges()) { 43*972a253aSDimitry Andric auto &Sym = E.getTarget(); 44*972a253aSDimitry Andric if (!Sym.isDefined()) 45*972a253aSDimitry Andric continue; 46*972a253aSDimitry Andric Children.insert(&Sym.getBlock()); 47*972a253aSDimitry Andric } 48*972a253aSDimitry Andric for (auto *Child : Children) 49*972a253aSDimitry Andric Child->addEdge(Edge(Edge::KeepAlive, 0, DummySymbol, 0)); 50*972a253aSDimitry Andric } 51*972a253aSDimitry Andric return Error::success(); 52*972a253aSDimitry Andric } 53*972a253aSDimitry Andric 54*972a253aSDimitry Andric private: 55*972a253aSDimitry Andric StringRef SEHFrameSectionName; 56*972a253aSDimitry Andric }; 57*972a253aSDimitry Andric 58*972a253aSDimitry Andric } // end namespace jitlink 59*972a253aSDimitry Andric } // end namespace llvm 60*972a253aSDimitry Andric 61*972a253aSDimitry Andric #endif // LLVM_EXECUTIONENGINE_JITLINK_SEHFRAMESUPPORT_H