LCOV - code coverage report
Current view: top level - include/llvm/ExecutionEngine - SectionMemoryManager.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 1 1 100.0 %
Date: 2018-07-13 00:08:38 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- 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             : // This file contains the declaration of a section-based memory manager used by
      11             : // the MCJIT execution engine and RuntimeDyld.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
      16             : #define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
      17             : 
      18             : #include "llvm/ADT/SmallVector.h"
      19             : #include "llvm/ADT/StringRef.h"
      20             : #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
      21             : #include "llvm/Support/Memory.h"
      22             : #include <cstdint>
      23             : #include <string>
      24             : #include <system_error>
      25             : 
      26             : namespace llvm {
      27             : 
      28             : /// This is a simple memory manager which implements the methods called by
      29             : /// the RuntimeDyld class to allocate memory for section-based loading of
      30             : /// objects, usually those generated by the MCJIT execution engine.
      31             : ///
      32             : /// This memory manager allocates all section memory as read-write.  The
      33             : /// RuntimeDyld will copy JITed section memory into these allocated blocks
      34             : /// and perform any necessary linking and relocations.
      35             : ///
      36             : /// Any client using this memory manager MUST ensure that section-specific
      37             : /// page permissions have been applied before attempting to execute functions
      38             : /// in the JITed object.  Permissions can be applied either by calling
      39             : /// MCJIT::finalizeObject or by calling SectionMemoryManager::finalizeMemory
      40             : /// directly.  Clients of MCJIT should call MCJIT::finalizeObject.
      41             : class SectionMemoryManager : public RTDyldMemoryManager {
      42             : public:
      43             :   /// This enum describes the various reasons to allocate pages from
      44             :   /// allocateMappedMemory.
      45             :   enum class AllocationPurpose {
      46             :     Code,
      47             :     ROData,
      48             :     RWData,
      49             :   };
      50             : 
      51             :   /// Implementations of this interface are used by SectionMemoryManager to
      52             :   /// request pages from the operating system.
      53             :   class MemoryMapper {
      54             :   public:
      55             :     /// This method attempts to allocate \p NumBytes bytes of virtual memory for
      56             :     /// \p Purpose.  \p NearBlock may point to an existing allocation, in which
      57             :     /// case an attempt is made to allocate more memory near the existing block.
      58             :     /// The actual allocated address is not guaranteed to be near the requested
      59             :     /// address.  \p Flags is used to set the initial protection flags for the
      60             :     /// block of the memory.  \p EC [out] returns an object describing any error
      61             :     /// that occurs.
      62             :     ///
      63             :     /// This method may allocate more than the number of bytes requested.  The
      64             :     /// actual number of bytes allocated is indicated in the returned
      65             :     /// MemoryBlock.
      66             :     ///
      67             :     /// The start of the allocated block must be aligned with the system
      68             :     /// allocation granularity (64K on Windows, page size on Linux).  If the
      69             :     /// address following \p NearBlock is not so aligned, it will be rounded up
      70             :     /// to the next allocation granularity boundary.
      71             :     ///
      72             :     /// \r a non-null MemoryBlock if the function was successful, otherwise a
      73             :     /// null MemoryBlock with \p EC describing the error.
      74             :     virtual sys::MemoryBlock
      75             :     allocateMappedMemory(AllocationPurpose Purpose, size_t NumBytes,
      76             :                          const sys::MemoryBlock *const NearBlock,
      77             :                          unsigned Flags, std::error_code &EC) = 0;
      78             : 
      79             :     /// This method sets the protection flags for a block of memory to the state
      80             :     /// specified by \p Flags.  The behavior is not specified if the memory was
      81             :     /// not allocated using the allocateMappedMemory method.
      82             :     /// \p Block describes the memory block to be protected.
      83             :     /// \p Flags specifies the new protection state to be assigned to the block.
      84             :     ///
      85             :     /// If \p Flags is MF_WRITE, the actual behavior varies with the operating
      86             :     /// system (i.e. MF_READ | MF_WRITE on Windows) and the target architecture
      87             :     /// (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386).
      88             :     ///
      89             :     /// \r error_success if the function was successful, or an error_code
      90             :     /// describing the failure if an error occurred.
      91             :     virtual std::error_code protectMappedMemory(const sys::MemoryBlock &Block,
      92             :                                                 unsigned Flags) = 0;
      93             : 
      94             :     /// This method releases a block of memory that was allocated with the
      95             :     /// allocateMappedMemory method. It should not be used to release any memory
      96             :     /// block allocated any other way.
      97             :     /// \p Block describes the memory to be released.
      98             :     ///
      99             :     /// \r error_success if the function was successful, or an error_code
     100             :     /// describing the failure if an error occurred.
     101             :     virtual std::error_code releaseMappedMemory(sys::MemoryBlock &M) = 0;
     102             : 
     103             :     virtual ~MemoryMapper();
     104             :   };
     105             : 
     106             :   /// Creates a SectionMemoryManager instance with \p MM as the associated
     107             :   /// memory mapper.  If \p MM is nullptr then a default memory mapper is used
     108             :   /// that directly calls into the operating system.
     109             :   SectionMemoryManager(MemoryMapper *MM = nullptr);
     110             :   SectionMemoryManager(const SectionMemoryManager &) = delete;
     111             :   void operator=(const SectionMemoryManager &) = delete;
     112             :   ~SectionMemoryManager() override;
     113             : 
     114             :   /// Allocates a memory block of (at least) the given size suitable for
     115             :   /// executable code.
     116             :   ///
     117             :   /// The value of \p Alignment must be a power of two.  If \p Alignment is zero
     118             :   /// a default alignment of 16 will be used.
     119             :   uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
     120             :                                unsigned SectionID,
     121             :                                StringRef SectionName) override;
     122             : 
     123             :   /// Allocates a memory block of (at least) the given size suitable for
     124             :   /// executable code.
     125             :   ///
     126             :   /// The value of \p Alignment must be a power of two.  If \p Alignment is zero
     127             :   /// a default alignment of 16 will be used.
     128             :   uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
     129             :                                unsigned SectionID, StringRef SectionName,
     130             :                                bool isReadOnly) override;
     131             : 
     132             :   /// Update section-specific memory permissions and other attributes.
     133             :   ///
     134             :   /// This method is called when object loading is complete and section page
     135             :   /// permissions can be applied.  It is up to the memory manager implementation
     136             :   /// to decide whether or not to act on this method.  The memory manager will
     137             :   /// typically allocate all sections as read-write and then apply specific
     138             :   /// permissions when this method is called.  Code sections cannot be executed
     139             :   /// until this function has been called.  In addition, any cache coherency
     140             :   /// operations needed to reliably use the memory are also performed.
     141             :   ///
     142             :   /// \returns true if an error occurred, false otherwise.
     143             :   bool finalizeMemory(std::string *ErrMsg = nullptr) override;
     144             : 
     145             :   /// Invalidate instruction cache for code sections.
     146             :   ///
     147             :   /// Some platforms with separate data cache and instruction cache require
     148             :   /// explicit cache flush, otherwise JIT code manipulations (like resolved
     149             :   /// relocations) will get to the data cache but not to the instruction cache.
     150             :   ///
     151             :   /// This method is called from finalizeMemory.
     152             :   virtual void invalidateInstructionCache();
     153             : 
     154             : private:
     155             :   struct FreeMemBlock {
     156             :     // The actual block of free memory
     157             :     sys::MemoryBlock Free;
     158             :     // If there is a pending allocation from the same reservation right before
     159             :     // this block, store it's index in PendingMem, to be able to update the
     160             :     // pending region if part of this block is allocated, rather than having to
     161             :     // create a new one
     162             :     unsigned PendingPrefixIndex;
     163             :   };
     164             : 
     165         462 :   struct MemoryGroup {
     166             :     // PendingMem contains all blocks of memory (subblocks of AllocatedMem)
     167             :     // which have not yet had their permissions applied, but have been given
     168             :     // out to the user. FreeMem contains all block of memory, which have
     169             :     // neither had their permissions applied, nor been given out to the user.
     170             :     SmallVector<sys::MemoryBlock, 16> PendingMem;
     171             :     SmallVector<FreeMemBlock, 16> FreeMem;
     172             : 
     173             :     // All memory blocks that have been requested from the system
     174             :     SmallVector<sys::MemoryBlock, 16> AllocatedMem;
     175             : 
     176             :     sys::MemoryBlock Near;
     177             :   };
     178             : 
     179             :   uint8_t *allocateSection(AllocationPurpose Purpose, uintptr_t Size,
     180             :                            unsigned Alignment);
     181             : 
     182             :   std::error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup,
     183             :                                               unsigned Permissions);
     184             : 
     185             :   void anchor() override;
     186             : 
     187             :   MemoryGroup CodeMem;
     188             :   MemoryGroup RWDataMem;
     189             :   MemoryGroup RODataMem;
     190             :   MemoryMapper &MMapper;
     191             : };
     192             : 
     193             : } // end namespace llvm
     194             : 
     195             : #endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H

Generated by: LCOV version 1.13