LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Darwin/Memory.cpp

Go to the documentation of this file.
00001 //===- Darwin/Memory.cpp - Darwin Memory Implementation ---------*- C++ -*-===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by Reid Spencer and is distributed under the 
00006 // University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file provides the Darwin specific implementation of various Memory
00011 // management utilities
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 // Include the generic unix implementation
00016 #include "../Unix/Memory.cpp"
00017 #include "llvm/System/Process.h"
00018 #include <sys/mman.h>
00019 
00020 namespace llvm {
00021 using namespace sys;
00022 
00023 //===----------------------------------------------------------------------===//
00024 //=== WARNING: Implementation here must contain only Darwin-specific code 
00025 //===          and must not be generic UNIX code (see ../Unix/Memory.cpp)
00026 //===----------------------------------------------------------------------===//
00027 
00028 /// AllocateRWXMemory - Allocate a slab of memory with read/write/execute
00029 /// permissions.  This is typically used for JIT applications where we want
00030 /// to emit code to the memory and then jump to it.  Getting this type of memory
00031 /// is very OS-specific.
00032 ///
00033 MemoryBlock Memory::AllocateRWX(unsigned NumBytes) {
00034   if (NumBytes == 0) return MemoryBlock();
00035 
00036   static const long pageSize = Process::GetPageSize();
00037   unsigned NumPages = (NumBytes+pageSize-1)/pageSize;
00038 
00039   void *pa = mmap(0, pageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
00040                   MAP_PRIVATE|MAP_ANON, -1, 0);
00041   if (pa == MAP_FAILED) {
00042     char msg[MAXPATHLEN];
00043     strerror_r(errno, msg, MAXPATHLEN-1);
00044     throw std::string("Can't allocate RWX Memory: ") + msg;
00045   }
00046   MemoryBlock result;
00047   result.Address = pa;
00048   result.Size = NumPages*pageSize;
00049   return result;
00050 }
00051 
00052 void Memory::ReleaseRWX(MemoryBlock& M) {
00053   if (M.Address == 0 || M.Size == 0) return;
00054   if (0 != munmap(M.Address, M.Size)) {
00055     char msg[MAXPATHLEN];
00056     strerror_r(errno, msg, MAXPATHLEN-1);
00057     throw std::string("Can't release RWX Memory: ") + msg;
00058   }
00059 }
00060 
00061 }
00062 
00063 // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab