rebased to master after sw 3rd party completed
[dyninst.git] / dyninstAPI_RT / src / RTheap-win.c
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include <windows.h>
32 #include "dyninstAPI_RT/src/RTheap.h"
33 #include "dyninstAPI_RT/src/RTcommon.h"
34
35 int     DYNINSTheap_align = 16;
36 Address DYNINSTheap_loAddr = 0x400000;    //4MB mark
37 Address DYNINSTheap_hiAddr = 0x7FFFFFFF;  //2GB mark
38
39 int getpagesize() {
40     SYSTEM_INFO info;
41     static int page_size = 0;
42     if (page_size)
43         return page_size;
44     GetSystemInfo(&info);
45     page_size = info.dwPageSize;
46     return page_size;
47 }
48
49
50
51 void *map_region(void *addr, int len, int fd) {
52     void *result;
53         DWORD lastError;
54         char* lpMessage;
55     result = VirtualAlloc(addr, len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
56         if(!result) {
57                 lastError = GetLastError();
58                 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
59                                 NULL,
60                                 lastError,
61                                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
62                                 (LPTSTR)(lpMessage),
63                                 0,
64                                 NULL);
65                 fprintf(stderr, "VirtualAlloc failed in RTlib: %s\n", lpMessage);
66                 LocalFree((LPVOID)lpMessage);
67         } else {
68                 fprintf(stderr, "VirtualAlloc succeeded, %p to %p mapped for RTlib heap\n",
69                         addr, (char*)(addr)+len);
70         }
71         return result;
72 }
73
74 int unmap_region(void *addr, int len) {
75     BOOL result;
76     result = VirtualFree(addr, 0, MEM_RELEASE);
77     return (int) result;
78 }
79
80 int DYNINSTheap_mmapFdOpen(void)
81 {
82    return 0;
83 }
84
85 void DYNINSTheap_mmapFdClose(int fd)
86 {
87 }
88
89 RT_Boolean DYNINSTheap_useMalloc(void *lo, void *hi)
90 {
91   return RT_FALSE;
92 }
93
94 int DYNINSTgetMemoryMap(unsigned *nump, dyninstmm_t **mapp) {
95     dyninstmm_t *map = NULL;
96     void *temp;
97     Address cur, base;
98     MEMORY_BASIC_INFORMATION mem;
99     unsigned count = 0, size = 0;
100     static unsigned alloc_size = 256;
101
102     map = (dyninstmm_t *) malloc(alloc_size * sizeof(dyninstmm_t));
103     memset(map, 0, alloc_size * sizeof(dyninstmm_t));
104
105     cur = DYNINSTheap_loAddr;
106     for (; cur < DYNINSTheap_hiAddr; cur += size) {
107         VirtualQuery((void *) cur, &mem, sizeof(MEMORY_BASIC_INFORMATION));
108         base = (Address) mem.BaseAddress;
109         size = mem.RegionSize;
110
111         if (!size) goto done_err;
112         if (mem.State & MEM_FREE) continue;
113       
114         if (count && (base <= map[count-1].pr_vaddr + map[count-1].pr_size)) {
115             //We have two continuous regions, just merge them into one
116             map[count-1].pr_size = base + size - map[count-1].pr_vaddr;
117             continue;
118         }
119
120         if (count >= alloc_size) {
121             //Grow the allocation buffer, if we need to
122             alloc_size *= 2;
123             temp = realloc(map, alloc_size * sizeof(dyninstmm_t));
124             if (!temp) goto done_err;
125             map = (dyninstmm_t *) temp;
126         }
127
128         map[count].pr_vaddr = base;
129         map[count].pr_size = size;
130         count++;
131     }
132
133     *nump = count;
134     *mapp = map;
135     return 0;
136
137 done_err:
138     free(map);
139     *nump = 0;
140     *mapp = NULL;
141     return -1;
142 }