File: llvm-jitlink.h

package info (click to toggle)
llvm-toolchain-20 1%3A20.1.6-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,111,304 kB
  • sloc: cpp: 7,438,677; ansic: 1,393,822; asm: 1,012,926; python: 241,650; f90: 86,635; objc: 75,479; lisp: 42,144; pascal: 17,286; sh: 10,027; ml: 5,082; perl: 4,730; awk: 3,523; makefile: 3,349; javascript: 2,251; xml: 892; fortran: 672
file content (159 lines) | stat: -rw-r--r-- 6,481 bytes parent folder | download
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//===---- llvm-jitlink.h - Session and format-specific decls ----*- 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
//
//===----------------------------------------------------------------------===//
//
// llvm-jitlink Session class and tool utilities.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H
#define LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H

#include "llvm/ADT/StringSet.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/LazyObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/RedirectionManager.h"
#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/TargetParser/Triple.h"

namespace llvm {

struct Session {

  struct LazyLinkingSupport {
    LazyLinkingSupport(
        std::unique_ptr<orc::RedirectableSymbolManager> RSMgr,
        std::shared_ptr<orc::SimpleLazyReexportsSpeculator> Speculator,
        std::unique_ptr<orc::LazyReexportsManager> LRMgr,
        orc::ObjectLinkingLayer &ObjLinkingLayer)
        : RSMgr(std::move(RSMgr)), Speculator(std::move(Speculator)),
          LRMgr(std::move(LRMgr)),
          LazyObjLinkingLayer(ObjLinkingLayer, *this->LRMgr) {}

    std::unique_ptr<orc::RedirectableSymbolManager> RSMgr;
    std::shared_ptr<orc::SimpleLazyReexportsSpeculator> Speculator;
    std::unique_ptr<orc::LazyReexportsManager> LRMgr;
    orc::LazyObjectLinkingLayer LazyObjLinkingLayer;
  };

  orc::ExecutionSession ES;
  orc::JITDylib *MainJD = nullptr;
  orc::JITDylib *ProcessSymsJD = nullptr;
  orc::JITDylib *PlatformJD = nullptr;
  orc::ObjectLinkingLayer ObjLayer;
  std::unique_ptr<LazyLinkingSupport> LazyLinking;
  orc::JITDylibSearchOrder JDSearchOrder;
  SubtargetFeatures Features;
  std::vector<std::pair<std::string, orc::SymbolStringPtr>> LazyFnExecOrder;

  ~Session();

  static Expected<std::unique_ptr<Session>> Create(Triple TT,
                                                   SubtargetFeatures Features);
  void dumpSessionInfo(raw_ostream &OS);
  void modifyPassConfig(jitlink::LinkGraph &G,
                        jitlink::PassConfiguration &PassConfig);

  /// For -check: wait for all files that are referenced (transitively) from
  /// the entry point *file* to be linked. (ORC's usual dependence tracking is
  /// to fine-grained here: a lookup of the main symbol will return as soon as
  /// all reachable symbols have been linked, but testcases may want to
  /// inspect side-effects in unreachable symbols)..
  void waitForFilesLinkedFromEntryPointFile() {
    std::unique_lock<std::mutex> Lock(M);
    return ActiveLinksCV.wait(Lock, [this]() { return ActiveLinks == 0; });
  }

  using MemoryRegionInfo = RuntimeDyldChecker::MemoryRegionInfo;

  struct FileInfo {
    StringMap<MemoryRegionInfo> SectionInfos;
    StringMap<SmallVector<MemoryRegionInfo, 1>> StubInfos;
    StringMap<MemoryRegionInfo> GOTEntryInfos;

    using Symbol = jitlink::Symbol;
    using LinkGraph = jitlink::LinkGraph;
    using GetSymbolTargetFunction =
        unique_function<Expected<Symbol &>(LinkGraph &G, jitlink::Block &)>;
    Error registerGOTEntry(LinkGraph &G, Symbol &Sym,
                           GetSymbolTargetFunction GetSymbolTarget);
    Error registerStubEntry(LinkGraph &G, Symbol &Sym,
                            GetSymbolTargetFunction GetSymbolTarget);
    Error registerMultiStubEntry(LinkGraph &G, Symbol &Sym,
                                 GetSymbolTargetFunction GetSymbolTarget);
  };

  using DynLibJDMap = std::map<std::string, orc::JITDylib *, std::less<>>;
  using SymbolInfoMap = DenseMap<orc::SymbolStringPtr, MemoryRegionInfo>;
  using FileInfoMap = StringMap<FileInfo>;

  Expected<orc::JITDylib *> getOrLoadDynamicLibrary(StringRef LibPath);
  Error loadAndLinkDynamicLibrary(orc::JITDylib &JD, StringRef LibPath);

  orc::ObjectLayer &getLinkLayer(bool Lazy) {
    assert((!Lazy || LazyLinking) &&
           "Lazy linking requested but not available");
    return Lazy ? static_cast<orc::ObjectLayer &>(
                      LazyLinking->LazyObjLinkingLayer)
                : static_cast<orc::ObjectLayer &>(ObjLayer);
  }

  Expected<FileInfo &> findFileInfo(StringRef FileName);
  Expected<MemoryRegionInfo &> findSectionInfo(StringRef FileName,
                                               StringRef SectionName);
  Expected<MemoryRegionInfo &> findStubInfo(StringRef FileName,
                                            StringRef TargetName,
                                            StringRef KindNameFilter);
  Expected<MemoryRegionInfo &> findGOTEntryInfo(StringRef FileName,
                                                StringRef TargetName);

  bool isSymbolRegistered(const orc::SymbolStringPtr &Name);
  Expected<MemoryRegionInfo &> findSymbolInfo(const orc::SymbolStringPtr &Name,
                                              Twine ErrorMsgStem);

  DynLibJDMap DynLibJDs;

  std::mutex M;
  std::condition_variable ActiveLinksCV;
  size_t ActiveLinks = 0;
  SymbolInfoMap SymbolInfos;
  FileInfoMap FileInfos;

  StringSet<> HarnessFiles;
  StringSet<> HarnessExternals;
  StringSet<> HarnessDefinitions;
  DenseMap<StringRef, StringRef> CanonicalWeakDefs;

  std::optional<Regex> ShowGraphsRegex;

private:
  Session(std::unique_ptr<orc::ExecutorProcessControl> EPC, Error &Err);
};

/// Record symbols, GOT entries, stubs, and sections for ELF file.
Error registerELFGraphInfo(Session &S, jitlink::LinkGraph &G);

/// Record symbols, GOT entries, stubs, and sections for MachO file.
Error registerMachOGraphInfo(Session &S, jitlink::LinkGraph &G);

/// Record symbols, GOT entries, stubs, and sections for COFF file.
Error registerCOFFGraphInfo(Session &S, jitlink::LinkGraph &G);

/// Adds a statistics gathering plugin if any stats options are used.
void enableStatistics(Session &S, bool UsingOrcRuntime);

} // end namespace llvm

#endif // LLVM_TOOLS_LLVM_JITLINK_LLVM_JITLINK_H