aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ExecutionEngine/JITLink/SEHFrameSupport.h
blob: 21bfd36d44a21dbee2622de3e30ffd348c03ba8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//===------- SEHFrameSupport.h - JITLink seh-frame utils --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// SEHFrame utils for JITLink.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_JITLINK_SEHFRAMESUPPORT_H
#define LLVM_EXECUTIONENGINE_JITLINK_SEHFRAMESUPPORT_H

#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Support/Error.h"
#include "llvm/TargetParser/Triple.h"

namespace llvm {
namespace jitlink {
/// This pass adds keep-alive edge from SEH frame sections
/// to the parent function content block.
class SEHFrameKeepAlivePass {
public:
  SEHFrameKeepAlivePass(StringRef SEHFrameSectionName)
      : SEHFrameSectionName(SEHFrameSectionName) {}

  Error operator()(LinkGraph &G) {
    auto *S = G.findSectionByName(SEHFrameSectionName);
    if (!S)
      return Error::success();

    // Simply consider every block pointed by seh frame block as parants.
    // This adds some unnecessary keep-alive edges to unwind info blocks,
    // (xdata) but these blocks are usually dead by default, so they wouldn't
    // count for the fate of seh frame block.
    for (auto *B : S->blocks()) {
      auto &DummySymbol = G.addAnonymousSymbol(*B, 0, 0, false, false);
      DenseSet<Block *> Children;
      for (auto &E : B->edges()) {
        auto &Sym = E.getTarget();
        if (!Sym.isDefined())
          continue;
        Children.insert(&Sym.getBlock());
      }
      for (auto *Child : Children)
        Child->addEdge(Edge(Edge::KeepAlive, 0, DummySymbol, 0));
    }
    return Error::success();
  }

private:
  StringRef SEHFrameSectionName;
};

} // end namespace jitlink
} // end namespace llvm

#endif // LLVM_EXECUTIONENGINE_JITLINK_SEHFRAMESUPPORT_H