xref: /freebsd-src/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/SEHFrameSupport.h (revision 972a253a57b6f144b0e4a3e2080a2a0076ec55a0)
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