LCOV - code coverage report
Current view: top level - include/llvm/ExecutionEngine - RuntimeDyld.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 6 11 54.5 %
Date: 2018-10-20 13:21:21 Functions: 2 5 40.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- RuntimeDyld.h - Run-time dynamic linker for MC-JIT -------*- 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             : // Interface for the runtime dynamic linker facilities of the MC-JIT.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
      15             : #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
      16             : 
      17             : #include "llvm/ADT/STLExtras.h"
      18             : #include "llvm/ADT/StringRef.h"
      19             : #include "llvm/DebugInfo/DIContext.h"
      20             : #include "llvm/ExecutionEngine/JITSymbol.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           0 :   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 RuntimeDyldCheckerImpl;
      57             : class RuntimeDyldImpl;
      58             : 
      59             : class RuntimeDyld {
      60             :   friend class RuntimeDyldCheckerImpl;
      61             : 
      62             : protected:
      63             :   // Change the address associated with a section when resolving relocations.
      64             :   // Any relocations already associated with the symbol will be re-resolved.
      65             :   void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
      66             : 
      67             : public:
      68             :   /// Information about the loaded object.
      69           0 :   class LoadedObjectInfo : public llvm::LoadedObjectInfo {
      70             :     friend class RuntimeDyldImpl;
      71             : 
      72             :   public:
      73             :     using ObjSectionToIDMap = std::map<object::SectionRef, unsigned>;
      74             : 
      75             :     LoadedObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
      76         350 :         : RTDyld(RTDyld), ObjSecToIDMap(std::move(ObjSecToIDMap)) {}
      77             : 
      78             :     virtual object::OwningBinary<object::ObjectFile>
      79             :     getObjectForDebug(const object::ObjectFile &Obj) const = 0;
      80             : 
      81             :     uint64_t
      82             :     getSectionLoadAddress(const object::SectionRef &Sec) const override;
      83             : 
      84             :   protected:
      85             :     virtual void anchor();
      86             : 
      87             :     RuntimeDyldImpl &RTDyld;
      88             :     ObjSectionToIDMap ObjSecToIDMap;
      89             :   };
      90             : 
      91             :   /// Memory Management.
      92             :   class MemoryManager {
      93             :     friend class RuntimeDyld;
      94             : 
      95             :   public:
      96         402 :     MemoryManager() = default;
      97           0 :     virtual ~MemoryManager() = default;
      98             : 
      99             :     /// Allocate a memory block of (at least) the given size suitable for
     100             :     /// executable code. The SectionID is a unique identifier assigned by the
     101             :     /// RuntimeDyld instance, and optionally recorded by the memory manager to
     102             :     /// access a loaded section.
     103             :     virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
     104             :                                          unsigned SectionID,
     105             :                                          StringRef SectionName) = 0;
     106             : 
     107             :     /// Allocate a memory block of (at least) the given size suitable for data.
     108             :     /// The SectionID is a unique identifier assigned by the JIT engine, and
     109             :     /// optionally recorded by the memory manager to access a loaded section.
     110             :     virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
     111             :                                          unsigned SectionID,
     112             :                                          StringRef SectionName,
     113             :                                          bool IsReadOnly) = 0;
     114             : 
     115             :     /// Inform the memory manager about the total amount of memory required to
     116             :     /// allocate all sections to be loaded:
     117             :     /// \p CodeSize - the total size of all code sections
     118             :     /// \p DataSizeRO - the total size of all read-only data sections
     119             :     /// \p DataSizeRW - the total size of all read-write data sections
     120             :     ///
     121             :     /// Note that by default the callback is disabled. To enable it
     122             :     /// redefine the method needsToReserveAllocationSpace to return true.
     123           0 :     virtual void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
     124             :                                         uintptr_t RODataSize,
     125             :                                         uint32_t RODataAlign,
     126             :                                         uintptr_t RWDataSize,
     127           0 :                                         uint32_t RWDataAlign) {}
     128             : 
     129             :     /// Override to return true to enable the reserveAllocationSpace callback.
     130         316 :     virtual bool needsToReserveAllocationSpace() { return false; }
     131             : 
     132             :     /// Register the EH frames with the runtime so that c++ exceptions work.
     133             :     ///
     134             :     /// \p Addr parameter provides the local address of the EH frame section
     135             :     /// data, while \p LoadAddr provides the address of the data in the target
     136             :     /// address space.  If the section has not been remapped (which will usually
     137             :     /// be the case for local execution) these two values will be the same.
     138             :     virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
     139             :                                   size_t Size) = 0;
     140             :     virtual void deregisterEHFrames() = 0;
     141             : 
     142             :     /// This method is called when object loading is complete and section page
     143             :     /// permissions can be applied.  It is up to the memory manager implementation
     144             :     /// to decide whether or not to act on this method.  The memory manager will
     145             :     /// typically allocate all sections as read-write and then apply specific
     146             :     /// permissions when this method is called.  Code sections cannot be executed
     147             :     /// until this function has been called.  In addition, any cache coherency
     148             :     /// operations needed to reliably use the memory are also performed.
     149             :     ///
     150             :     /// Returns true if an error occurred, false otherwise.
     151             :     virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0;
     152             : 
     153             :     /// This method is called after an object has been loaded into memory but
     154             :     /// before relocations are applied to the loaded sections.
     155             :     ///
     156             :     /// Memory managers which are preparing code for execution in an external
     157             :     /// address space can use this call to remap the section addresses for the
     158             :     /// newly loaded object.
     159             :     ///
     160             :     /// For clients that do not need access to an ExecutionEngine instance this
     161             :     /// method should be preferred to its cousin
     162             :     /// MCJITMemoryManager::notifyObjectLoaded as this method is compatible with
     163             :     /// ORC JIT stacks.
     164         320 :     virtual void notifyObjectLoaded(RuntimeDyld &RTDyld,
     165         320 :                                     const object::ObjectFile &Obj) {}
     166             : 
     167             :   private:
     168             :     virtual void anchor();
     169             : 
     170             :     bool FinalizationLocked = false;
     171             :   };
     172             : 
     173             :   /// Construct a RuntimeDyld instance.
     174             :   RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver);
     175             :   RuntimeDyld(const RuntimeDyld &) = delete;
     176             :   RuntimeDyld &operator=(const RuntimeDyld &) = delete;
     177             :   ~RuntimeDyld();
     178             : 
     179             :   /// Add the referenced object file to the list of objects to be loaded and
     180             :   /// relocated.
     181             :   std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O);
     182             : 
     183             :   /// Get the address of our local copy of the symbol. This may or may not
     184             :   /// be the address used for relocation (clients can copy the data around
     185             :   /// and resolve relocatons based on where they put it).
     186             :   void *getSymbolLocalAddress(StringRef Name) const;
     187             : 
     188             :   /// Get the target address and flags for the named symbol.
     189             :   /// This address is the one used for relocation.
     190             :   JITEvaluatedSymbol getSymbol(StringRef Name) const;
     191             : 
     192             :   /// Returns a copy of the symbol table. This can be used by on-finalized
     193             :   /// callbacks to extract the symbol table before throwing away the
     194             :   /// RuntimeDyld instance. Because the map keys (StringRefs) are backed by
     195             :   /// strings inside the RuntimeDyld instance, the map should be processed
     196             :   /// before the RuntimeDyld instance is discarded.
     197             :   std::map<StringRef, JITEvaluatedSymbol> getSymbolTable() const;
     198             : 
     199             :   /// Resolve the relocations for all symbols we currently know about.
     200             :   void resolveRelocations();
     201             : 
     202             :   /// Map a section to its target address space value.
     203             :   /// Map the address of a JIT section as returned from the memory manager
     204             :   /// to the address in the target process as the running code will see it.
     205             :   /// This is the address which will be used for relocation resolution.
     206             :   void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
     207             : 
     208             :   /// Register any EH frame sections that have been loaded but not previously
     209             :   /// registered with the memory manager.  Note, RuntimeDyld is responsible
     210             :   /// for identifying the EH frame and calling the memory manager with the
     211             :   /// EH frame section data.  However, the memory manager itself will handle
     212             :   /// the actual target-specific EH frame registration.
     213             :   void registerEHFrames();
     214             : 
     215             :   void deregisterEHFrames();
     216             : 
     217             :   bool hasError();
     218             :   StringRef getErrorString();
     219             : 
     220             :   /// By default, only sections that are "required for execution" are passed to
     221             :   /// the RTDyldMemoryManager, and other sections are discarded. Passing 'true'
     222             :   /// to this method will cause RuntimeDyld to pass all sections to its
     223             :   /// memory manager regardless of whether they are "required to execute" in the
     224             :   /// usual sense. This is useful for inspecting metadata sections that may not
     225             :   /// contain relocations, E.g. Debug info, stackmaps.
     226             :   ///
     227             :   /// Must be called before the first object file is loaded.
     228             :   void setProcessAllSections(bool ProcessAllSections) {
     229             :     assert(!Dyld && "setProcessAllSections must be called before loadObject.");
     230         175 :     this->ProcessAllSections = ProcessAllSections;
     231             :   }
     232             : 
     233             :   /// Perform all actions needed to make the code owned by this RuntimeDyld
     234             :   /// instance executable:
     235             :   ///
     236             :   /// 1) Apply relocations.
     237             :   /// 2) Register EH frames.
     238             :   /// 3) Update memory permissions*.
     239             :   ///
     240             :   /// * Finalization is potentially recursive**, and the 3rd step will only be
     241             :   ///   applied by the outermost call to finalize. This allows different
     242             :   ///   RuntimeDyld instances to share a memory manager without the innermost
     243             :   ///   finalization locking the memory and causing relocation fixup errors in
     244             :   ///   outer instances.
     245             :   ///
     246             :   /// ** Recursive finalization occurs when one RuntimeDyld instances needs the
     247             :   ///   address of a symbol owned by some other instance in order to apply
     248             :   ///   relocations.
     249             :   ///
     250             :   void finalizeWithMemoryManagerLocking();
     251             : 
     252             : private:
     253             :   friend void
     254             :   jitLinkForORC(object::ObjectFile &Obj,
     255             :                 std::unique_ptr<MemoryBuffer> UnderlyingBuffer,
     256             :                 RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
     257             :                 bool ProcessAllSections,
     258             :                 std::function<Error(std::unique_ptr<LoadedObjectInfo>,
     259             :                                     std::map<StringRef, JITEvaluatedSymbol>)>
     260             :                     OnLoaded,
     261             :                 std::function<void(Error)> OnEmitted);
     262             : 
     263             :   // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
     264             :   // interface.
     265             :   std::unique_ptr<RuntimeDyldImpl> Dyld;
     266             :   MemoryManager &MemMgr;
     267             :   JITSymbolResolver &Resolver;
     268             :   bool ProcessAllSections;
     269             :   RuntimeDyldCheckerImpl *Checker;
     270             : };
     271             : 
     272             : // Asynchronous JIT link for ORC.
     273             : //
     274             : // Warning: This API is experimental and probably should not be used by anyone
     275             : // but ORC's RTDyldObjectLinkingLayer2. Internally it constructs a RuntimeDyld
     276             : // instance and uses continuation passing to perform the fix-up and finalize
     277             : // steps asynchronously.
     278             : void jitLinkForORC(object::ObjectFile &Obj,
     279             :                    std::unique_ptr<MemoryBuffer> UnderlyingBuffer,
     280             :                    RuntimeDyld::MemoryManager &MemMgr,
     281             :                    JITSymbolResolver &Resolver, bool ProcessAllSections,
     282             :                    std::function<Error(std::unique_ptr<LoadedObjectInfo>,
     283             :                                        std::map<StringRef, JITEvaluatedSymbol>)>
     284             :                        OnLoaded,
     285             :                    std::function<void(Error)> OnEmitted);
     286             : 
     287             : } // end namespace llvm
     288             : 
     289             : #endif // LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H

Generated by: LCOV version 1.13