source: proiecte/swift/trunk/lib/hoard-371/src/winhoard.cpp @ 176

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 6.0 KB
Line 
1/* -*- C++ -*- */
2
3/*
4  The Hoard Multiprocessor Memory Allocator
5  www.hoard.org
6
7  Author: Emery Berger, http://www.cs.umass.edu/~emery
8 
9  Copyright (c) 1998-2006 Emery Berger, The University of Texas at Austin
10
11  This program is free software; you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 2 of the License, or
14  (at your option) any later version.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
25*/
26
27#ifdef _DEBUG
28#error "This library must be compiled in release mode."
29#endif 
30
31/*
32
33  Compile with compile-winhoard.cmd.
34
35 */
36
37
38#include <windows.h>
39
40#define WIN32_LEAN_AND_MEAN
41
42#if (_WIN32_WINNT < 0x0500)
43#define _WIN32_WINNT 0x0500
44#endif
45
46#pragma inline_depth(255)
47
48#pragma warning(disable: 4273)
49#pragma warning(disable: 4098)  // Library conflict.
50#pragma warning(disable: 4355)  // 'this' used in base member initializer list.
51#pragma warning(disable: 4074)  // initializers put in compiler reserved area.
52
53void (*hoard_memcpy_ptr)(void *dest, const void *src, size_t count);
54void (*hoard_memset_ptr)(void *dest, int c, size_t count);
55
56const char *RlsCRTLibraryName[] = {"MSVCR71.DLL", "MSVCR80.DLL", "MSVCR90.DLL" };
57const int RlsCRTLibraryNameLength = 3;
58
59#define IAX86_NEARJMP_OPCODE      0xe9
60#define MakeIAX86Offset(to,from)  ((unsigned)((char*)(to)-(char*)(from)) - 5)
61
62typedef struct
63{
64  const char *import;           // import name of patch routine
65  FARPROC replacement;          // pointer to replacement function
66  FARPROC original;             // pointer to original function
67  unsigned char codebytes[5];   // 5 bytes of original code storage
68} PATCH;
69
70
71static bool PatchMeIn (void);
72
73#define CUSTOM_PREFIX(n) hoard_##n
74#define HOARD_PRE_ACTION {PatchMeIn();}
75#define HOARD_POST_ACTION {HeapAlloc (GetProcessHeap(), 0, 1); }
76
77// DisableThreadLibraryCalls ((HMODULE)hinstDLL);
78
79#define CUSTOM_DLLNAME HoardDllMain
80
81#include "libhoard.cpp"
82
83// Intercept the exit functions.
84
85static const int HOARD_MAX_EXIT_FUNCTIONS = 255;
86static int exitCount = 0;
87
88extern "C" {
89
90  __declspec(dllexport) int ReferenceHoardStub;
91
92  typedef void (*exitFunctionType) (void);
93  exitFunctionType exitFunctionBuffer[255];
94
95  void hoard_onexit (void (*function)(void)) {
96    if (exitCount < HOARD_MAX_EXIT_FUNCTIONS) {
97      exitFunctionBuffer[exitCount] = function;
98      exitCount++;
99    }
100  }
101
102  void hoard_exit (int code) {
103    while (exitCount > 0) {
104      exitCount--;
105      (exitFunctionBuffer[exitCount])();
106    }
107  }
108
109  void * hoard_expand (void * ptr) {
110    return NULL;
111  }
112
113}
114
115
116/* ------------------------------------------------------------------------ */
117
118static PATCH rls_patches[] = 
119  {
120    // RELEASE CRT library routines supported by this memory manager.
121
122    {"_expand",         (FARPROC) hoard_expand,    0},
123    {"_onexit",         (FARPROC) hoard_onexit,    0},
124    {"_exit",           (FARPROC) hoard_exit,      0},
125
126    // operator new, new[], delete, delete[].
127
128#ifdef _WIN64
129
130    {"??2@YAPEAX_K@Z",  (FARPROC) hoard_malloc,    0},
131    {"??_U@YAPEAX_K@Z", (FARPROC) hoard_malloc,    0},
132    {"??3@YAXPEAX@Z",   (FARPROC) hoard_free,      0},
133    {"??_V@YAXPEAX@Z",  (FARPROC) hoard_free,      0},
134
135#else
136
137    {"??2@YAPAXI@Z",    (FARPROC) hoard_malloc,    0},
138    {"??_U@YAPAXI@Z",   (FARPROC) hoard_malloc,    0},
139    {"??3@YAXPAX@Z",    (FARPROC) hoard_free,      0},
140    {"??_V@YAXPAX@Z",   (FARPROC) hoard_free,      0},
141
142#endif
143
144    // the nothrow variants new, new[].
145
146    {"??2@YAPAXIABUnothrow_t@std@@@Z",  (FARPROC) hoard_malloc, 0},
147    {"??_U@YAPAXIABUnothrow_t@std@@@Z", (FARPROC) hoard_malloc, 0},
148
149    {"_msize",  (FARPROC) hoard_malloc_usable_size,             0},
150    {"calloc",  (FARPROC) hoard_calloc,         0},
151    {"malloc",  (FARPROC) hoard_malloc,         0},
152    {"realloc", (FARPROC) hoard_realloc,                0},
153    {"free",    (FARPROC) hoard_free,              0},
154  };
155
156
157static void PatchIt (PATCH *patch)
158{
159  // Change rights on CRT Library module to execute/read/write.
160
161  MEMORY_BASIC_INFORMATION mbi_thunk;
162  VirtualQuery((void*)patch->original, &mbi_thunk, 
163               sizeof(MEMORY_BASIC_INFORMATION));
164  VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, 
165                 PAGE_EXECUTE_READWRITE, &mbi_thunk.Protect);
166
167  // Patch CRT library original routine:
168  //    save original 5 code bytes for exit restoration
169  //            write jmp <patch_routine> (5 bytes long) to original.
170
171  memcpy(patch->codebytes, patch->original, sizeof(patch->codebytes));
172  unsigned char *patchloc = (unsigned char*)patch->original;
173  *patchloc++ = IAX86_NEARJMP_OPCODE;
174  *(unsigned*)patchloc = MakeIAX86Offset(patch->replacement, patch->original);
175       
176  // Reset CRT library code to original page protection.
177
178  VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, 
179                 mbi_thunk.Protect, &mbi_thunk.Protect);
180}
181
182
183static bool PatchMeIn (void)
184{
185  bool patchedIn = false;
186
187  // acquire the module handles for the CRT libraries (release and debug)
188  for (int i = 0; i < RlsCRTLibraryNameLength; i++) {
189
190    HMODULE RlsCRTLibrary = GetModuleHandle(RlsCRTLibraryName[i]);
191
192    HMODULE DefCRTLibrary = 
193      RlsCRTLibrary;
194
195    // assign function pointers for required CRT support functions
196    if (DefCRTLibrary) {
197      hoard_memcpy_ptr = (void(*)(void*,const void*,size_t))
198        GetProcAddress(DefCRTLibrary, "memcpy");
199      hoard_memset_ptr = (void(*)(void*,int,size_t))
200        GetProcAddress(DefCRTLibrary, "memset");
201    }
202
203    // patch all relevant Release CRT Library entry points
204    if (RlsCRTLibrary) {
205      for (int i = 0; i < sizeof(rls_patches) / sizeof(*rls_patches); i++) {
206        if (rls_patches[i].original = GetProcAddress(RlsCRTLibrary, rls_patches[i].import)) {
207          PatchIt(&rls_patches[i]);
208          patchedIn = true;
209        }
210      }
211    }
212  }
213  return patchedIn;
214}
Note: See TracBrowser for help on using the repository browser.