Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be included
  13.  * in all copies or substantial portions of the Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21.  * OTHER DEALINGS IN THE SOFTWARE.
  22.  *
  23.  **************************************************************************/
  24.  
  25.  
  26. /**
  27.  * \file exemem.c
  28.  * Functions for allocating executable memory.
  29.  *
  30.  * \author Keith Whitwell
  31.  */
  32.  
  33.  
  34. #include "pipe/p_compiler.h"
  35. #include "util/u_debug.h"
  36. #include "os/os_thread.h"
  37. #include "util/u_memory.h"
  38.  
  39. #include "rtasm_execmem.h"
  40.  
  41. #ifndef MAP_ANONYMOUS
  42. #define MAP_ANONYMOUS MAP_ANON
  43. #endif
  44.  
  45. #if defined(PIPE_OS_WINDOWS)
  46. #ifndef WIN32_LEAN_AND_MEAN
  47. #define WIN32_LEAN_AND_MEAN 1
  48. #endif
  49. #include <windows.h>
  50. #endif
  51.  
  52. #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
  53.  
  54.  
  55. /*
  56.  * Allocate a large block of memory which can hold code then dole it out
  57.  * in pieces by means of the generic memory manager code.
  58.  */
  59.  
  60. #include <unistd.h>
  61. #include <sys/mman.h>
  62. #include "util/u_mm.h"
  63.  
  64. #define EXEC_HEAP_SIZE (10*1024*1024)
  65.  
  66. pipe_static_mutex(exec_mutex);
  67.  
  68. static struct mem_block *exec_heap = NULL;
  69. static unsigned char *exec_mem = NULL;
  70.  
  71.  
  72. static int
  73. init_heap(void)
  74. {
  75.    if (!exec_heap)
  76.       exec_heap = u_mmInit( 0, EXEC_HEAP_SIZE );
  77.    
  78.    if (!exec_mem)
  79.       exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE,
  80.                                         PROT_EXEC | PROT_READ | PROT_WRITE,
  81.                                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  82.  
  83.    return (exec_mem != MAP_FAILED);
  84. }
  85.  
  86.  
  87. void *
  88. rtasm_exec_malloc(size_t size)
  89. {
  90.    struct mem_block *block = NULL;
  91.    void *addr = NULL;
  92.  
  93.    pipe_mutex_lock(exec_mutex);
  94.  
  95.    if (!init_heap())
  96.       goto bail;
  97.  
  98.    if (exec_heap) {
  99.       size = (size + 31) & ~31;  /* next multiple of 32 bytes */
  100.       block = u_mmAllocMem( exec_heap, size, 5, 0 ); /* 5 -> 32-byte alignment */
  101.    }
  102.  
  103.    if (block)
  104.       addr = exec_mem + block->ofs;
  105.    else
  106.       debug_printf("rtasm_exec_malloc failed\n");
  107.  
  108. bail:
  109.    pipe_mutex_unlock(exec_mutex);
  110.    
  111.    return addr;
  112. }
  113.  
  114.  
  115. void
  116. rtasm_exec_free(void *addr)
  117. {
  118.    pipe_mutex_lock(exec_mutex);
  119.  
  120.    if (exec_heap) {
  121.       struct mem_block *block = u_mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem);
  122.    
  123.       if (block)
  124.          u_mmFreeMem(block);
  125.    }
  126.  
  127.    pipe_mutex_unlock(exec_mutex);
  128. }
  129.  
  130.  
  131. #elif defined(PIPE_OS_WINDOWS)
  132.  
  133.  
  134. /*
  135.  * Avoid Data Execution Prevention.
  136.  */
  137.  
  138. void *
  139. rtasm_exec_malloc(size_t size)
  140. {
  141.    return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  142. }
  143.  
  144.  
  145. void
  146. rtasm_exec_free(void *addr)
  147. {
  148.    VirtualFree(addr, 0, MEM_RELEASE);
  149. }
  150.  
  151.  
  152. #else
  153.  
  154.  
  155. /*
  156.  * Just use regular memory.
  157.  */
  158.  
  159. void *
  160. rtasm_exec_malloc(size_t size)
  161. {
  162.    return MALLOC( size );
  163. }
  164.  
  165.  
  166. void
  167. rtasm_exec_free(void *addr)
  168. {
  169.    FREE(addr);
  170. }
  171.  
  172.  
  173. #endif
  174.