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