c8166af4fb9bc2bf7f5da71f3e8d88000960f759
[tpg/acess2.git] / AcessNative / ld-acess_src / memory.c
1 /*
2  */
3 #include "common.h"
4 #include <stdio.h>
5 #include <stdlib.h>
6 #if __WIN32__
7 # include <windows.h>
8 #else
9 # include <sys/mman.h>
10 # include <errno.h>
11 #endif
12
13 // === PROTOTYPES ===
14  int    AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
15 uintptr_t       FindFreeRange(size_t ByteCount, int MaxBits);
16
17 // === CODE ===
18 int AllocateMemory(uintptr_t VirtAddr, size_t ByteCount)
19 {
20         uintptr_t       base = (VirtAddr >> 12) << 12;
21         size_t  size = (VirtAddr & 0xFFF) + ByteCount;
22         void    *tmp;
23         #if __WIN32__
24         do
25         {
26                 MEMORY_BASIC_INFORMATION        info;
27                 VirtualQuery( (void*)base, &info, sizeof(info) );
28                 if( info.State != MEM_FREE ) {
29                         printf("ERROR: Unable to allocate memory %p+0x%x, already allocated\n",
30                                 (void*)base, size);
31                         base += 0x1000;
32                         if( size < 0x1000 )
33                                 return 0;
34                         size -= 0x1000;
35                 }
36                 else
37                         break;
38         } while( size >= 0x1000 );
39         tmp = VirtualAlloc((void*)base, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
40         if( tmp == NULL ) {
41                 printf("ERROR: Unable to allocate memory %p+%x (0x%x)\n",
42                         (void*)base, size,
43                         (int)GetLastError());
44                 return -1;
45         }
46         #else
47 //      printf("AllocateMemory: mmap(%p, 0x%lx, ...)\n", (void*)base, ByteCount);
48         tmp = mmap((void*)base, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
49         if( tmp == MAP_FAILED ) {
50                 printf("ERROR: Unable to allocate memory\n");
51                 perror("AllocateMemory");
52                 return -1;
53         }
54 //      printf("AllocateMemory: RETURN 0\n");
55         #endif
56         return 0;
57 }
58
59 uintptr_t FindFreeRange(size_t ByteCount, int MaxBits)
60 {
61         uintptr_t       base, ofs, size;
62         uintptr_t       end = -1;
63         static const int        PAGE_SIZE = 0x1000;
64         
65         size = (ByteCount + PAGE_SIZE - 1) / PAGE_SIZE;
66         size *= PAGE_SIZE;
67
68         end <<= (sizeof(intptr_t)*8-MaxBits);
69         end >>= (sizeof(intptr_t)*8-MaxBits);
70 //      printf("end = %p\n", (void*)end);
71         
72 //      for( base = 0; base < end - size; base -= PAGE_SIZE )
73         for( base = end - size + 1; base > 0; base -= PAGE_SIZE )
74         {
75                 for( ofs = 0; ofs < size; ofs += PAGE_SIZE ) {
76                         #if __WIN32__
77                         MEMORY_BASIC_INFORMATION        info;
78                         VirtualQuery( (void*)(base + ofs), &info, sizeof(info) );
79                         if( info.State != MEM_FREE )
80                                 break;
81                         #else
82                         if( msync( (void*)(base+ofs), 1, 0) == 0 )
83                                 break;
84                         if( errno != ENOMEM )
85                                 perror("FindFreeRange, msync");
86                         #endif
87                 }
88                 if( ofs >= size ) {
89                         return base;
90                 }
91         }
92         return 0;
93 }

UCC git Repository :: git.ucc.asn.au