xref: /freebsd-src/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/SEHFrameSupport.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1972a253aSDimitry Andric //===------- SEHFrameSupport.h - JITLink seh-frame utils --------*- C++ -*-===//
2972a253aSDimitry Andric //
3972a253aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4972a253aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5972a253aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6972a253aSDimitry Andric //
7972a253aSDimitry Andric //===----------------------------------------------------------------------===//
8972a253aSDimitry Andric //
9972a253aSDimitry Andric // SEHFrame utils for JITLink.
10972a253aSDimitry Andric //
11972a253aSDimitry Andric //===----------------------------------------------------------------------===//
12972a253aSDimitry Andric 
13972a253aSDimitry Andric #ifndef LLVM_EXECUTIONENGINE_JITLINK_SEHFRAMESUPPORT_H
14972a253aSDimitry Andric #define LLVM_EXECUTIONENGINE_JITLINK_SEHFRAMESUPPORT_H
15972a253aSDimitry Andric 
16*0fca6ea1SDimitry Andric #include "llvm/ADT/SetVector.h"
17972a253aSDimitry Andric #include "llvm/ExecutionEngine/JITLink/JITLink.h"
18972a253aSDimitry Andric #include "llvm/ExecutionEngine/JITSymbol.h"
19972a253aSDimitry Andric #include "llvm/Support/Error.h"
2006c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
21972a253aSDimitry Andric 
22972a253aSDimitry Andric namespace llvm {
23972a253aSDimitry Andric namespace jitlink {
24972a253aSDimitry Andric /// This pass adds keep-alive edge from SEH frame sections
25972a253aSDimitry Andric /// to the parent function content block.
26972a253aSDimitry Andric class SEHFrameKeepAlivePass {
27972a253aSDimitry Andric public:
28972a253aSDimitry Andric   SEHFrameKeepAlivePass(StringRef SEHFrameSectionName)
29972a253aSDimitry Andric       : SEHFrameSectionName(SEHFrameSectionName) {}
30972a253aSDimitry Andric 
31972a253aSDimitry Andric   Error operator()(LinkGraph &G) {
32972a253aSDimitry Andric     auto *S = G.findSectionByName(SEHFrameSectionName);
33972a253aSDimitry Andric     if (!S)
34972a253aSDimitry Andric       return Error::success();
35972a253aSDimitry Andric 
36972a253aSDimitry Andric     // Simply consider every block pointed by seh frame block as parants.
37972a253aSDimitry Andric     // This adds some unnecessary keep-alive edges to unwind info blocks,
38972a253aSDimitry Andric     // (xdata) but these blocks are usually dead by default, so they wouldn't
39972a253aSDimitry Andric     // count for the fate of seh frame block.
40972a253aSDimitry Andric     for (auto *B : S->blocks()) {
41972a253aSDimitry Andric       auto &DummySymbol = G.addAnonymousSymbol(*B, 0, 0, false, false);
42*0fca6ea1SDimitry Andric       SetVector<Block *> Children;
43972a253aSDimitry Andric       for (auto &E : B->edges()) {
44972a253aSDimitry Andric         auto &Sym = E.getTarget();
45972a253aSDimitry Andric         if (!Sym.isDefined())
46972a253aSDimitry Andric           continue;
47972a253aSDimitry Andric         Children.insert(&Sym.getBlock());
48972a253aSDimitry Andric       }
49972a253aSDimitry Andric       for (auto *Child : Children)
50972a253aSDimitry Andric         Child->addEdge(Edge(Edge::KeepAlive, 0, DummySymbol, 0));
51972a253aSDimitry Andric     }
52972a253aSDimitry Andric     return Error::success();
53972a253aSDimitry Andric   }
54972a253aSDimitry Andric 
55972a253aSDimitry Andric private:
56972a253aSDimitry Andric   StringRef SEHFrameSectionName;
57972a253aSDimitry Andric };
58972a253aSDimitry Andric 
59972a253aSDimitry Andric } // end namespace jitlink
60972a253aSDimitry Andric } // end namespace llvm
61972a253aSDimitry Andric 
62972a253aSDimitry Andric #endif // LLVM_EXECUTIONENGINE_JITLINK_SEHFRAMESUPPORT_H
63