1//===- GlobalMappingLayer.h - Run all IR through a functor ------*- 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// Convenience layer for injecting symbols that will appear in calls to
10// findSymbol.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
15#define LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
16
17#include "llvm/ExecutionEngine/JITSymbol.h"
18#include <map>
19#include <memory>
20#include <string>
21
22namespace llvm {
23
24class Module;
25class JITSymbolResolver;
26
27namespace orc {
28
29/// Global mapping layer.
30///
31///   This layer overrides the findSymbol method to first search a local symbol
32/// table that the client can define. It can be used to inject new symbol
33/// mappings into the JIT. Beware, however: symbols within a single IR module or
34/// object file will still resolve locally (via RuntimeDyld's symbol table) -
35/// such internal references cannot be overriden via this layer.
36template <typename BaseLayerT>
37class GlobalMappingLayer {
38public:
39
40  /// Handle to an added module.
41  using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
42
43  /// Construct an GlobalMappingLayer with the given BaseLayer
44  GlobalMappingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
45
46  /// Add the given module to the JIT.
47  /// @return A handle for the added modules.
48  Expected<ModuleHandleT>
49  addModule(std::shared_ptr<Module> M,
50            std::shared_ptr<JITSymbolResolver> Resolver) {
51    return BaseLayer.addModule(std::move(M), std::move(Resolver));
52  }
53
54  /// Remove the module set associated with the handle H.
55  Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); }
56
57  /// Manually set the address to return for the given symbol.
58  void setGlobalMapping(const std::string &Name, JITTargetAddress Addr) {
59    SymbolTable[Name] = Addr;
60  }
61
62  /// Remove the given symbol from the global mapping.
63  void eraseGlobalMapping(const std::string &Name) {
64    SymbolTable.erase(Name);
65  }
66
67  /// Search for the given named symbol.
68  ///
69  ///          This method will first search the local symbol table, returning
70  ///        any symbol found there. If the symbol is not found in the local
71  ///        table then this call will be passed through to the base layer.
72  ///
73  /// @param Name The name of the symbol to search for.
74  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
75  /// @return A handle for the given named symbol, if it exists.
76  JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
77    auto I = SymbolTable.find(Name);
78    if (I != SymbolTable.end())
79      return JITSymbol(I->second, JITSymbolFlags::Exported);
80    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
81  }
82
83  /// Get the address of the given symbol in the context of the of the
84  ///        module represented by the handle H. This call is forwarded to the
85  ///        base layer's implementation.
86  /// @param H The handle for the module to search in.
87  /// @param Name The name of the symbol to search for.
88  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
89  /// @return A handle for the given named symbol, if it is found in the
90  ///         given module.
91  JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
92                         bool ExportedSymbolsOnly) {
93    return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
94  }
95
96  /// Immediately emit and finalize the module set represented by the
97  ///        given handle.
98  /// @param H Handle for module set to emit/finalize.
99  Error emitAndFinalize(ModuleHandleT H) {
100    return BaseLayer.emitAndFinalize(H);
101  }
102
103private:
104  BaseLayerT &BaseLayer;
105  std::map<std::string, JITTargetAddress> SymbolTable;
106};
107
108} // end namespace orc
109} // end namespace llvm
110
111#endif // LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H
112