LLVM  12.0.0git
RuntimeDyld.h
Go to the documentation of this file.
1 //===- RuntimeDyld.h - Run-time dynamic linker for MC-JIT -------*- 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 // Interface for the runtime dynamic linker facilities of the MC-JIT.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
14 #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
15 
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/Support/Error.h"
23 #include <algorithm>
24 #include <cassert>
25 #include <cstddef>
26 #include <cstdint>
27 #include <map>
28 #include <memory>
29 #include <string>
30 #include <system_error>
31 
32 namespace llvm {
33 
34 namespace object {
35 
36 template <typename T> class OwningBinary;
37 
38 } // end namespace object
39 
40 /// Base class for errors originating in RuntimeDyld, e.g. missing relocation
41 /// support.
42 class RuntimeDyldError : public ErrorInfo<RuntimeDyldError> {
43 public:
44  static char ID;
45 
46  RuntimeDyldError(std::string ErrMsg) : ErrMsg(std::move(ErrMsg)) {}
47 
48  void log(raw_ostream &OS) const override;
49  const std::string &getErrorMessage() const { return ErrMsg; }
50  std::error_code convertToErrorCode() const override;
51 
52 private:
53  std::string ErrMsg;
54 };
55 
56 class RuntimeDyldImpl;
57 
58 class RuntimeDyld {
59 protected:
60  // Change the address associated with a section when resolving relocations.
61  // Any relocations already associated with the symbol will be re-resolved.
62  void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
63 
64 public:
67  unsigned SectionID, uint32_t StubOffset)>;
68 
69  /// Information about the loaded object.
71  friend class RuntimeDyldImpl;
72 
73  public:
74  using ObjSectionToIDMap = std::map<object::SectionRef, unsigned>;
75 
78 
80  getObjectForDebug(const object::ObjectFile &Obj) const = 0;
81 
82  uint64_t
83  getSectionLoadAddress(const object::SectionRef &Sec) const override;
84 
85  protected:
86  virtual void anchor();
87 
90  };
91 
92  /// Memory Management.
93  class MemoryManager {
94  friend class RuntimeDyld;
95 
96  public:
97  MemoryManager() = default;
98  virtual ~MemoryManager() = default;
99 
100  /// Allocate a memory block of (at least) the given size suitable for
101  /// executable code. The SectionID is a unique identifier assigned by the
102  /// RuntimeDyld instance, and optionally recorded by the memory manager to
103  /// access a loaded section.
104  virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
105  unsigned SectionID,
106  StringRef SectionName) = 0;
107 
108  /// Allocate a memory block of (at least) the given size suitable for data.
109  /// The SectionID is a unique identifier assigned by the JIT engine, and
110  /// optionally recorded by the memory manager to access a loaded section.
111  virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
112  unsigned SectionID,
114  bool IsReadOnly) = 0;
115 
116  /// Inform the memory manager about the total amount of memory required to
117  /// allocate all sections to be loaded:
118  /// \p CodeSize - the total size of all code sections
119  /// \p DataSizeRO - the total size of all read-only data sections
120  /// \p DataSizeRW - the total size of all read-write data sections
121  ///
122  /// Note that by default the callback is disabled. To enable it
123  /// redefine the method needsToReserveAllocationSpace to return true.
124  virtual void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
125  uintptr_t RODataSize,
126  uint32_t RODataAlign,
127  uintptr_t RWDataSize,
128  uint32_t RWDataAlign) {}
129 
130  /// Override to return true to enable the reserveAllocationSpace callback.
131  virtual bool needsToReserveAllocationSpace() { return false; }
132 
133  /// Register the EH frames with the runtime so that c++ exceptions work.
134  ///
135  /// \p Addr parameter provides the local address of the EH frame section
136  /// data, while \p LoadAddr provides the address of the data in the target
137  /// address space. If the section has not been remapped (which will usually
138  /// be the case for local execution) these two values will be the same.
139  virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
140  size_t Size) = 0;
141  virtual void deregisterEHFrames() = 0;
142 
143  /// This method is called when object loading is complete and section page
144  /// permissions can be applied. It is up to the memory manager implementation
145  /// to decide whether or not to act on this method. The memory manager will
146  /// typically allocate all sections as read-write and then apply specific
147  /// permissions when this method is called. Code sections cannot be executed
148  /// until this function has been called. In addition, any cache coherency
149  /// operations needed to reliably use the memory are also performed.
150  ///
151  /// Returns true if an error occurred, false otherwise.
152  virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0;
153 
154  /// This method is called after an object has been loaded into memory but
155  /// before relocations are applied to the loaded sections.
156  ///
157  /// Memory managers which are preparing code for execution in an external
158  /// address space can use this call to remap the section addresses for the
159  /// newly loaded object.
160  ///
161  /// For clients that do not need access to an ExecutionEngine instance this
162  /// method should be preferred to its cousin
163  /// MCJITMemoryManager::notifyObjectLoaded as this method is compatible with
164  /// ORC JIT stacks.
165  virtual void notifyObjectLoaded(RuntimeDyld &RTDyld,
166  const object::ObjectFile &Obj) {}
167 
168  private:
169  virtual void anchor();
170 
171  bool FinalizationLocked = false;
172  };
173 
174  /// Construct a RuntimeDyld instance.
175  RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver);
176  RuntimeDyld(const RuntimeDyld &) = delete;
177  RuntimeDyld &operator=(const RuntimeDyld &) = delete;
178  ~RuntimeDyld();
179 
180  /// Add the referenced object file to the list of objects to be loaded and
181  /// relocated.
182  std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O);
183 
184  /// Get the address of our local copy of the symbol. This may or may not
185  /// be the address used for relocation (clients can copy the data around
186  /// and resolve relocatons based on where they put it).
187  void *getSymbolLocalAddress(StringRef Name) const;
188 
189  /// Get the section ID for the section containing the given symbol.
190  unsigned getSymbolSectionID(StringRef Name) const;
191 
192  /// Get the target address and flags for the named symbol.
193  /// This address is the one used for relocation.
195 
196  /// Returns a copy of the symbol table. This can be used by on-finalized
197  /// callbacks to extract the symbol table before throwing away the
198  /// RuntimeDyld instance. Because the map keys (StringRefs) are backed by
199  /// strings inside the RuntimeDyld instance, the map should be processed
200  /// before the RuntimeDyld instance is discarded.
201  std::map<StringRef, JITEvaluatedSymbol> getSymbolTable() const;
202 
203  /// Resolve the relocations for all symbols we currently know about.
204  void resolveRelocations();
205 
206  /// Map a section to its target address space value.
207  /// Map the address of a JIT section as returned from the memory manager
208  /// to the address in the target process as the running code will see it.
209  /// This is the address which will be used for relocation resolution.
210  void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
211 
212  /// Returns the section's working memory.
213  StringRef getSectionContent(unsigned SectionID) const;
214 
215  /// If the section was loaded, return the section's load address,
216  /// otherwise return None.
217  uint64_t getSectionLoadAddress(unsigned SectionID) const;
218 
219  /// Set the NotifyStubEmitted callback. This is used for debugging
220  /// purposes. A callback is made for each stub that is generated.
222  this->NotifyStubEmitted = std::move(NotifyStubEmitted);
223  }
224 
225  /// Register any EH frame sections that have been loaded but not previously
226  /// registered with the memory manager. Note, RuntimeDyld is responsible
227  /// for identifying the EH frame and calling the memory manager with the
228  /// EH frame section data. However, the memory manager itself will handle
229  /// the actual target-specific EH frame registration.
230  void registerEHFrames();
231 
232  void deregisterEHFrames();
233 
234  bool hasError();
236 
237  /// By default, only sections that are "required for execution" are passed to
238  /// the RTDyldMemoryManager, and other sections are discarded. Passing 'true'
239  /// to this method will cause RuntimeDyld to pass all sections to its
240  /// memory manager regardless of whether they are "required to execute" in the
241  /// usual sense. This is useful for inspecting metadata sections that may not
242  /// contain relocations, E.g. Debug info, stackmaps.
243  ///
244  /// Must be called before the first object file is loaded.
245  void setProcessAllSections(bool ProcessAllSections) {
246  assert(!Dyld && "setProcessAllSections must be called before loadObject.");
247  this->ProcessAllSections = ProcessAllSections;
248  }
249 
250  /// Perform all actions needed to make the code owned by this RuntimeDyld
251  /// instance executable:
252  ///
253  /// 1) Apply relocations.
254  /// 2) Register EH frames.
255  /// 3) Update memory permissions*.
256  ///
257  /// * Finalization is potentially recursive**, and the 3rd step will only be
258  /// applied by the outermost call to finalize. This allows different
259  /// RuntimeDyld instances to share a memory manager without the innermost
260  /// finalization locking the memory and causing relocation fixup errors in
261  /// outer instances.
262  ///
263  /// ** Recursive finalization occurs when one RuntimeDyld instances needs the
264  /// address of a symbol owned by some other instance in order to apply
265  /// relocations.
266  ///
268 
269 private:
270  friend void jitLinkForORC(
273  bool ProcessAllSections,
275  std::map<StringRef, JITEvaluatedSymbol>)>
276  OnLoaded,
278  std::unique_ptr<LoadedObjectInfo>, Error)>
279  OnEmitted);
280 
281  // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
282  // interface.
283  std::unique_ptr<RuntimeDyldImpl> Dyld;
284  MemoryManager &MemMgr;
286  bool ProcessAllSections;
287  NotifyStubEmittedFunction NotifyStubEmitted;
288 };
289 
290 // Asynchronous JIT link for ORC.
291 //
292 // Warning: This API is experimental and probably should not be used by anyone
293 // but ORC's RTDyldObjectLinkingLayer2. Internally it constructs a RuntimeDyld
294 // instance and uses continuation passing to perform the fix-up and finalize
295 // steps asynchronously.
296 void jitLinkForORC(
297  object::OwningBinary<object::ObjectFile> O,
298  RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
299  bool ProcessAllSections,
300  unique_function<Error(const object::ObjectFile &Obj,
301  RuntimeDyld::LoadedObjectInfo &,
302  std::map<StringRef, JITEvaluatedSymbol>)>
303  OnLoaded,
304  unique_function<void(object::OwningBinary<object::ObjectFile>,
305  std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)>
306  OnEmitted);
307 
308 } // end namespace llvm
309 
310 #endif // LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
virtual void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, uintptr_t RODataSize, uint32_t RODataAlign, uintptr_t RWDataSize, uint32_t RWDataAlign)
Inform the memory manager about the total amount of memory required to allocate all sections to be lo...
Definition: RuntimeDyld.h:124
Information about the loaded object.
Definition: RuntimeDyld.h:70
std::unique_ptr< LoadedObjectInfo > loadObject(const object::ObjectFile &O)
Add the referenced object file to the list of objects to be loaded and relocated.
void registerEHFrames()
Register any EH frame sections that have been loaded but not previously registered with the memory ma...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
StringRef getErrorString()
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: RuntimeDyld.cpp:64
This class is the base class for all object file types.
Definition: ObjectFile.h:225
JITEvaluatedSymbol getSymbol(StringRef Name) const
Get the target address and flags for the named symbol.
uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override
Obtain the Load Address of a section by SectionRef.
void setNotifyStubEmitted(NotifyStubEmittedFunction NotifyStubEmitted)
Set the NotifyStubEmitted callback.
Definition: RuntimeDyld.h:221
Definition: BitVector.h:941
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
virtual bool needsToReserveAllocationSpace()
Override to return true to enable the reserveAllocationSpace callback.
Definition: RuntimeDyld.h:131
std::function< void(StringRef FileName, StringRef SectionName, StringRef SymbolName, unsigned SectionID, uint32_t StubOffset)> NotifyStubEmittedFunction
Definition: RuntimeDyld.h:67
uint64_t Addr
uint64_t getSectionLoadAddress(unsigned SectionID) const
If the section was loaded, return the section's load address, otherwise return None.
friend void jitLinkForORC(object::OwningBinary< object::ObjectFile > O, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, bool ProcessAllSections, unique_function< Error(const object::ObjectFile &Obj, LoadedObjectInfo &, std::map< StringRef, JITEvaluatedSymbol >)> OnLoaded, unique_function< void(object::OwningBinary< object::ObjectFile > O, std::unique_ptr< LoadedObjectInfo >, Error)> OnEmitted)
RuntimeDyld & operator=(const RuntimeDyld &)=delete
RuntimeDyldError(std::string ErrMsg)
Definition: RuntimeDyld.h:46
void setProcessAllSections(bool ProcessAllSections)
By default, only sections that are "required for execution" are passed to the RTDyldMemoryManager,...
Definition: RuntimeDyld.h:245
RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver)
Construct a RuntimeDyld instance.
StringRef getSectionContent(unsigned SectionID) const
Returns the section's working memory.
virtual bool finalizeMemory(std::string *ErrMsg=nullptr)=0
This method is called when object loading is complete and section page permissions can be applied.
void * getSymbolLocalAddress(StringRef Name) const
Get the address of our local copy of the symbol.
virtual void notifyObjectLoaded(RuntimeDyld &RTDyld, const object::ObjectFile &Obj)
This method is called after an object has been loaded into memory but before relocations are applied ...
Definition: RuntimeDyld.h:165
virtual void deregisterEHFrames()=0
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Definition: Record.h:1955
Symbol resolution interface.
Definition: JITSymbol.h:371
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: RuntimeDyld.cpp:60
virtual uint8_t * allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, bool IsReadOnly)=0
Allocate a memory block of (at least) the given size suitable for data.
virtual uint8_t * allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName)=0
Allocate a memory block of (at least) the given size suitable for executable code.
virtual object::OwningBinary< object::ObjectFile > getObjectForDebug(const object::ObjectFile &Obj) const =0
unique_function is a type-erasing functor similar to std::function.
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
Definition: DIContext.h:263
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:229
Base class for user error types.
Definition: Error.h:350
std::map< StringRef, JITEvaluatedSymbol > getSymbolTable() const
Returns a copy of the symbol table.
Base class for errors originating in RuntimeDyld, e.g.
Definition: RuntimeDyld.h:42
unsigned getSymbolSectionID(StringRef Name) const
Get the section ID for the section containing the given symbol.
void finalizeWithMemoryManagerLocking()
Perform all actions needed to make the code owned by this RuntimeDyld instance executable:
void resolveRelocations()
Resolve the relocations for all symbols we currently know about.
const std::string & getErrorMessage() const
Definition: RuntimeDyld.h:49
std::map< object::SectionRef, unsigned > ObjSectionToIDMap
Definition: RuntimeDyld.h:74
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
void jitLinkForORC(object::OwningBinary< object::ObjectFile > O, RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, bool ProcessAllSections, unique_function< Error(const object::ObjectFile &Obj, RuntimeDyld::LoadedObjectInfo &, std::map< StringRef, JITEvaluatedSymbol >)> OnLoaded, unique_function< void(object::OwningBinary< object::ObjectFile >, std::unique_ptr< RuntimeDyld::LoadedObjectInfo >, Error)> OnEmitted)
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:50
void reassignSectionAddress(unsigned SectionID, uint64_t Addr)
print Print MemDeps of function
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1556
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size)=0
Register the EH frames with the runtime so that c++ exceptions work.
void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress)
Map a section to its target address space value.
LoadedObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
Definition: RuntimeDyld.h:76
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80
virtual ~MemoryManager()=default