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 
22 namespace llvm {
23 
24 class Module;
25 class JITSymbolResolver;
26 
27 namespace 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.
36 template <typename BaseLayerT>
37 class GlobalMappingLayer {
38 public:
39 
40   /// Handle to an added module.
41   using ModuleHandleT = typename BaseLayerT::ModuleHandleT;
42 
43   /// Construct an GlobalMappingLayer with the given BaseLayer
GlobalMappingLayer(BaseLayerT & 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>
addModule(std::shared_ptr<Module> M,std::shared_ptr<JITSymbolResolver> Resolver)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.
removeModule(ModuleHandleT H)55   Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); }
56 
57   /// Manually set the address to return for the given symbol.
setGlobalMapping(const std::string & Name,JITTargetAddress Addr)58   void setGlobalMapping(const std::string &Name, JITTargetAddress Addr) {
59     SymbolTable[Name] = Addr;
60   }
61 
62   /// Remove the given symbol from the global mapping.
eraseGlobalMapping(const std::string & Name)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.
findSymbol(const std::string & Name,bool ExportedSymbolsOnly)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.
findSymbolIn(ModuleHandleT H,const std::string & Name,bool ExportedSymbolsOnly)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.
emitAndFinalize(ModuleHandleT H)99   Error emitAndFinalize(ModuleHandleT H) {
100     return BaseLayer.emitAndFinalize(H);
101   }
102 
103 private:
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