Usermode/libaxwin4 - Handle demarshal failure
[tpg/acess2.git] / AcessNative / ld-acess_src / memory.c
index 627f902..99238a5 100644 (file)
@@ -1,5 +1,6 @@
 /*
  */
+#define _GNU_SOURCE    // needed for MAP_ANONYMOUS to be avaliable
 #include "common.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -21,49 +22,73 @@ int AllocateMemory(uintptr_t VirtAddr, size_t ByteCount)
        size_t  size = (VirtAddr & 0xFFF) + ByteCount;
        void    *tmp;
        #if __WIN32__
-       tmp = VirtualAlloc(base, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+       do
+       {
+               MEMORY_BASIC_INFORMATION        info;
+               VirtualQuery( (void*)base, &info, sizeof(info) );
+               if( info.State != MEM_FREE ) {
+                       printf("ERROR: Unable to allocate memory %p+0x%x, already allocated\n",
+                               (void*)base, size);
+                       base += 0x1000;
+                       if( size < 0x1000 )
+                               return 0;
+                       size -= 0x1000;
+               }
+               else
+                       break;
+       } while( size >= 0x1000 );
+       tmp = VirtualAlloc((void*)base, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if( tmp == NULL ) {
-               printf("ERROR: Unable to allocate memory (%i)\n", GetLastError());
+               printf("ERROR: Unable to allocate memory %p+%x (0x%x)\n",
+                       (void*)base, size,
+                       (int)GetLastError());
                return -1;
        }
        #else
+//     printf("AllocateMemory: mmap(%p, 0x%lx, ...)\n", (void*)base, ByteCount);
        tmp = mmap((void*)base, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
        if( tmp == MAP_FAILED ) {
+               printf("ERROR: Unable to allocate memory\n");
+               perror("AllocateMemory");
                return -1;
        }
+//     printf("AllocateMemory: RETURN 0\n");
        #endif
        return 0;
 }
 
 uintptr_t FindFreeRange(size_t ByteCount, int MaxBits)
 {
-       #if __WIN32__
-       # error "Windows FindFreeRange() unimplemented"
-       #else
        uintptr_t       base, ofs, size;
        uintptr_t       end = -1;
-       const int       PAGE_SIZE = 0x1000;
+       static const int        PAGE_SIZE = 0x1000;
        
        size = (ByteCount + PAGE_SIZE - 1) / PAGE_SIZE;
        size *= PAGE_SIZE;
 
        end <<= (sizeof(intptr_t)*8-MaxBits);
        end >>= (sizeof(intptr_t)*8-MaxBits);
-       printf("end = %p\n", (void*)end);
+//     printf("end = %p\n", (void*)end);
        
 //     for( base = 0; base < end - size; base -= PAGE_SIZE )
        for( base = end - size + 1; base > 0; base -= PAGE_SIZE )
        {
                for( ofs = 0; ofs < size; ofs += PAGE_SIZE ) {
+                       #if __WIN32__
+                       MEMORY_BASIC_INFORMATION        info;
+                       VirtualQuery( (void*)(base + ofs), &info, sizeof(info) );
+                       if( info.State != MEM_FREE )
+                               break;
+                       #else
                        if( msync( (void*)(base+ofs), 1, 0) == 0 )
                                break;
                        if( errno != ENOMEM )
                                perror("FindFreeRange, msync");
+                       #endif
                }
                if( ofs >= size ) {
                        return base;
                }
        }
        return 0;
-       #endif
 }

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