2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
24 #ifndef PROT_NONE /* FreeBSD doesn't define PROT_NONE */
33 virtual_mem_t
*mem
= 0;
37 /*******************************************************************
39 * A VRANGE denotes a contiguous part of the address space. It is used
40 * for house keeping, and will be obtained by higher-level memory allocation
41 * functions (VirtualAlloc, MapViewOfFile)
42 * There can be at most one VRANGE object covering any address at any time.
43 * Currently, all VRANGE objects are stored in a sorted list. Wine does not
44 * attempt to give a complete list of in-use address ranges, only those
45 * allocated via Win32.
46 * An exception is IsVrangeFree, which should test the OS specific
47 * mappings, too. As a default, an range not known to be allocated is
49 *******************************************************************/
51 VRANGE_OBJECT
*MEMORY_ranges
=0;
53 VRANGE_OBJECT
*MEMORY_FindVrange(DWORD start
)
56 for(range
=MEMORY_ranges
;range
&& range
->start
<start
;range
=range
->next
)
58 if(range
->start
<start
&& start
<range
->start
+range
->size
)
64 static int MEMORY_IsVrangeFree(DWORD start
,DWORD size
)
70 /* First, check our lists*/
72 for(range
=MEMORY_ranges
;range
&& range
->start
<start
;range
=range
->next
)
74 if((range
->start
<start
&& start
<range
->start
+range
->size
) ||
75 (range
->start
<end
&& end
<range
->start
+range
->size
))
78 /* Now, check the maps that are not under our control */
81 FILE *f
=fopen("/proc/self/maps","r");
88 if(!fgets(line
,sizeof(line
),f
))
91 lower
=strtoul(it
,&it
,16);
93 fprintf(stderr
,"Format of /proc/self/maps changed\n");
94 upper
=strtoul(it
,&it
,16);
95 if((lower
<start
&& start
<upper
) || (lower
<start
+size
&& start
+size
<upper
))
109 fprintf(stdnimp
, "Don't know how to perform MEMORY_IsVrangeFree on "
110 "this system.\n Please fix\n");
118 /* FIXME: might need to consolidate ranges */
119 void MEMORY_InsertVrange(VRANGE_OBJECT
*r
)
121 VRANGE_OBJECT
*it
,*last
;
122 if(!MEMORY_ranges
|| r
->start
<MEMORY_ranges
->start
)
124 r
->next
=MEMORY_ranges
;
127 for(it
=MEMORY_ranges
,last
=0;it
&& it
->start
<r
->start
;it
=it
->next
)
134 VRANGE_OBJECT
*MEMORY_AllocVrange(int start
,int size
)
136 VRANGE_OBJECT
*ret
=CreateKernelObject(sizeof(VRANGE_OBJECT
));
137 ret
->common
.magic
=KERNEL_OBJECT_VRANGE
;
138 MEMORY_InsertVrange(ret
);
142 void MEMORY_ReleaseVrange(VRANGE_OBJECT
*r
)
147 MEMORY_ranges
=r
->next
;
148 ReleaseKernelObject(r
);
151 for(it
=MEMORY_ranges
;it
;it
=it
->next
)
152 if(it
->next
==r
)break;
155 fprintf(stderr
,"VRANGE not found\n");
159 ReleaseKernelObject(r
);
162 /***********************************************************************
163 * VirtualAlloc (KERNEL32.548)
165 int TranslateProtectionFlags(DWORD
);
166 LPVOID
VirtualAlloc(LPVOID lpvAddress
, DWORD cbSize
,
167 DWORD fdwAllocationType
, DWORD fdwProtect
)
171 virtual_mem_t
*tmp_mem
;
173 static int fdzero
= -1;
177 if ((fdzero
= open( "/dev/zero", O_RDONLY
)) == -1)
179 perror( "/dev/zero: open" );
184 dprintf_win32(stddeb
, "VirtualAlloc: size = %ld, address=%p\n", cbSize
, lpvAddress
);
185 if (fdwAllocationType
& MEM_RESERVE
|| !lpvAddress
) {
186 ptr
= mmap((void *)((((unsigned long)lpvAddress
-1) & 0xFFFF0000L
)
188 cbSize
, PROT_NONE
, MAP_PRIVATE
, fdzero
, 0 );
189 if (ptr
== (caddr_t
) -1) {
190 dprintf_win32(stddeb
, "VirtualAlloc: returning NULL");
191 return (LPVOID
) NULL
;
193 if (lpvAddress
&& ((unsigned long)ptr
& 0xFFFF0000L
)) {
196 ptr
= mmap(lpvAddress
, cbSize
,
197 PROT_NONE
, MAP_PRIVATE
, fdzero
, 0 );
198 if (ptr
== (caddr_t
) -1) {
199 dprintf_win32(stddeb
, "VirtualAlloc: returning NULL");
200 return (LPVOID
) NULL
;
202 ptr
= (void *)((((unsigned long)ptr
-1) & 0xFFFF0000L
)+0x00010000L
);
204 /* remember the size for VirtualFree since it's going to be handed
207 if (mem_count
== mem_used
) {
208 tmp_mem
= realloc(mem
,(mem_count
+10)*sizeof(virtual_mem_t
));
209 if (!tmp_mem
) return 0;
211 memset(mem
+mem_count
, 0, 10*sizeof(virtual_mem_t
));
214 for (i
=0; i
<mem_count
; i
++) {
217 (mem
+i
)->size
= cbSize
;
226 if (fdwAllocationType
& MEM_COMMIT
) {
227 prot
= TranslateProtectionFlags(fdwProtect
&
228 ~(PAGE_GUARD
| PAGE_NOCACHE
));
229 mprotect(ptr
, cbSize
, prot
);
232 /* kludge for gnu-win32 */
233 if (fdwAllocationType
& MEM_RESERVE
) return sbrk(0);
234 ptr
= malloc(cbSize
+ 65536);
237 /* Round it up to the next 64K boundary and zero it.
239 ptr
= (void *)(((unsigned long)ptr
& 0xFFFF0000L
) + 0x00010000L
);
240 memset(ptr
, 0, cbSize
);
243 dprintf_win32(stddeb
, "VirtualAlloc: got pointer %p\n", ptr
);
247 /***********************************************************************
248 * VirtualFree (KERNEL32.550)
250 BOOL
VirtualFree(LPVOID lpvAddress
, DWORD cbSize
, DWORD fdwFreeType
)
254 if (fdwFreeType
& MEM_RELEASE
) {
255 for (i
=0; i
<mem_count
; i
++) {
256 if ((mem
+i
)->ptr
== lpvAddress
) {
257 munmap(lpvAddress
, (mem
+i
)->size
);
264 mprotect(lpvAddress
, cbSize
, PROT_NONE
);
273 int TranslateProtectionFlags(DWORD protection_flags
)
277 switch(protection_flags
) {
282 prot
=PROT_READ
|PROT_WRITE
;
290 case PAGE_EXECUTE_READ
:
291 prot
=PROT_EXEC
|PROT_READ
;
293 case PAGE_EXECUTE_READWRITE
:
294 prot
=PROT_EXEC
|PROT_READ
|PROT_WRITE
;
296 case PAGE_EXECUTE_WRITECOPY
:
297 prot
=PROT_EXEC
|PROT_WRITE
;
308 /******************************************************************
311 BOOL
WIN32_IsBadReadPtr(void* ptr
, unsigned int bytes
)
313 dprintf_global(stddeb
,"IsBadReadPtr(%x,%x)\n",ptr
,bytes
);
314 /* FIXME: Should make check based on actual mappings, here */
318 /******************************************************************
321 BOOL
WIN32_IsBadWritePtr(void* ptr
, unsigned int bytes
)
323 dprintf_global(stddeb
,"IsBadWritePtr(%x,%x)\n",ptr
,bytes
);
324 /* FIXME: Should make check based on actual mappings, here */
327 /******************************************************************
330 BOOL
WIN32_IsBadCodePtr(void* ptr
, unsigned int bytes
)
332 dprintf_global(stddeb
,"IsBadCodePtr(%x,%x)\n",ptr
,bytes
);
333 /* FIXME: Should make check based on actual mappings, here */