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