source: trunk/nom/src/nomgc.c@ 326

Last change on this file since 326 was 326, checked in by cinc, 17 years ago

Portability patches for Windows, Linux, Darwin by Bird.

File size: 11.0 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2* Version: CDDL 1.0/LGPL 2.1
3*
4* The contents of this file are subject to the COMMON DEVELOPMENT AND
5* DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
6* this file except in compliance with the License. You may obtain a copy of
7* the License at http://www.sun.com/cddl/
8*
9* Software distributed under the License is distributed on an "AS IS" basis,
10* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11* for the specific language governing rights and limitations under the
12* License.
13*
14* The Original Code is "NOM" Netlabs Object Model
15*
16* The Initial Developer of the Original Code is
17* netlabs.org: Chris Wohlgemuth <cinc-ml@netlabs.org>.
18* Portions created by the Initial Developer are Copyright (C) 2005-2006
19* the Initial Developer. All Rights Reserved.
20*
21* Contributor(s):
22*
23* Alternatively, the contents of this file may be used under the terms of
24* the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
25* case the provisions of the LGPL are applicable instead of those above. If
26* you wish to allow use of your version of this file only under the terms of
27* the LGPL, and not to allow others to use your version of this file under
28* the terms of the CDDL, indicate your decision by deleting the provisions
29* above and replace them with the notice and other provisions required by the
30* LGPL. If you do not delete the provisions above, a recipient may use your
31* version of this file under the terms of any one of the CDDL or the LGPL.
32*
33* ***** END LICENSE BLOCK ***** */
34
35/*
36 This file contains functions for working with the garbage collector.
37 */
38
39#ifdef __OS2__
40# define INCL_DOS
41# define INCL_DOSERRORS
42# define INCL_DOSMEMMGR
43# include <os2.h>
44#endif /* __OS2__ */
45
46#include <stdio.h>
47#include <string.h>
48#include <stdlib.h>
49
50/* For nomToken etc. */
51#include <nom.h>
52#include "nomtk.h"
53#include "nomgc.h"
54
55/* Garbage collector */
56#include <gc.h>
57
58gboolean bUseGC=FALSE; /* Mark if we use the garbage collector */
59GTree* treeRegisteredDLL;
60
61static gpointer gcMalloc(gulong ulBytes)
62{
63 //printf("Hi there...\n");
64 // return malloc(ulBytes);
65 return (gpointer) GC_malloc(ulBytes);
66}
67
68static gpointer gcRealloc(gpointer mem, gulong ulBytes)
69{
70 // printf("...and here\n");
71 // return realloc(mem, ulBytes);
72 return (gpointer) GC_realloc(mem, ulBytes);
73}
74
75static void gcFree(gpointer mem)
76{
77 // printf("free(): %x\n", mem);
78 return;
79 GC_free(mem);
80}
81
82
83/*
84 This is called from the EMX wrapper to set the garbage collector
85 memory functions as the GLIB default allocation function.
86 */
87#ifdef __OS2__
88void _System nomInitGarbageCollection(void* pMemInExe)
89#else
90void nomInitGarbageCollection(void* pMemInExe)
91#endif
92{
93 GMemVTable vtbl={0};
94
95 /* Init the garbage collector */
96 GC_init();
97
98 vtbl.malloc=(gpointer)gcMalloc;
99 vtbl.realloc=(gpointer)gcRealloc;
100 vtbl.free=(gpointer)gcFree;
101
102 g_mem_set_vtable(&vtbl);
103 /* fprintf(stderr, " GC memory functions set for GLIB. (%s: %d)\n", __FILE__, __LINE__); */
104
105 /* Cretea tree holding the already registered DLLs */
106#ifdef _MSC_VER
107 treeRegisteredDLL=g_tree_new((GCompareFunc)stricmp);
108#else
109 treeRegisteredDLL=g_tree_new((GCompareFunc)strcasecmp);
110#endif
111
112 bUseGC=TRUE;
113}
114
115
116#ifdef __OS2__
117void test()
118{
119 gulong ulObj, ulOffset;
120 gchar thePath[CCHMAXPATH];
121 HMODULE hModule;
122
123 if(DosQueryModFromEIP( &hModule, &ulObj, CCHMAXPATH, thePath, &ulOffset, (gulong)test)!=0) {
124 hModule=0;
125 return ; /* Error */
126 }
127
128}
129#endif /* __OS2__ */
130
131NOMEXTERN void NOMLINK nomRegisterDataAreaForGC(char* pStart, char* pEnd)
132{
133 GC_add_roots(pStart, pEnd);
134}
135
136#ifdef __OS2__
137
138static void qsAddDLLToList(HREGDLL hReg, qsLrec_t* rec)
139{
140 if(NULL==g_slist_find(hReg->dllList, rec))
141 hReg->dllList=g_slist_append(hReg->dllList, rec);
142}
143
144#if 0
145static void qsPrintDLLList(HREGDLL hReg)
146{
147 GSList* lTemp;
148 int a=0;
149
150 lTemp=hReg->dllList;
151 while(lTemp)
152 {
153 qsLrec_t* rec;
154 rec=(qsLrec_t*)lTemp->data;
155 a++;
156 g_message(" %d: %s", a, rec->pName);
157 lTemp=g_slist_next(lTemp);
158 }
159}
160#endif
161
162/**
163 Find a library record in the buffer filled by DosQuerySysState(). This function
164 searches in the list of all known libs, not in the process libs list.
165 */
166static qsLrec_t* qsFindModuleRec(const qsPtrRec_t * hRegisterDLL, USHORT hMod){
167 qsLrec_t * pModRec;
168 int a=0;
169
170 pModRec=hRegisterDLL->pLibRec;
171 while(NULL!=pModRec)
172 {
173 a++;
174 /* g_message("%d Checking: %x -> %04X (%s)", a, pModRec, pModRec->hmte, pModRec->pName); */
175
176 if (NULL==pModRec->pObjInfo && pModRec->ctObj > 0)
177 {
178 pModRec->pObjInfo = (qsLObjrec_t*)((char*)pModRec
179 + ((sizeof(qsLrec_t)
180 + pModRec->ctImpMod * sizeof(short)
181 + strlen((char*)pModRec->pName) + 1 /* filename */
182 + 3) & ~3));
183 pModRec->pNextRec = (void*)((char*)pModRec->pObjInfo
184 + sizeof(qsLObjrec_t) * pModRec->ctObj);
185 }
186 if(pModRec->hmte==hMod)
187 break;
188
189 pModRec=(qsLrec_t *)pModRec->pNextRec;
190 }
191
192 return pModRec;
193}
194
195
196/**
197 Get the info about the current DLLs from OS/2. Go over all found
198 DLLs and insert them in a list. For all found DLLs go over the imports
199 of them and add them to the list etc. Duplicates are ignored.
200 */
201#define BUFSIZE 1024*1024
202NOMEXTERN HREGDLL NOMLINK nomBeginRegisterDLLWithGC(void)
203{
204 gulong rc;
205 HREGDLL hReg=NULL;
206 PTIB ptib;
207 PPIB ppib;
208 char * buf;
209 HREGDLL pRegDLL=NULL;
210
211 rc = DosGetInfoBlocks(&ptib, &ppib);
212 if (rc!=NO_ERROR)
213 return NULL;
214
215 buf = malloc(BUFSIZE);
216 if(!buf)
217 return NULL;
218
219 pRegDLL =(HREGDLL) malloc(sizeof(REGDLL));
220 if(!pRegDLL){
221 free(buf);
222 return NULL;
223 }
224 pRegDLL->dllList=NULL;
225
226 memset(buf,0,BUFSIZE);
227
228 rc = DosQuerySysState(QS_PROCESS | QS_SEMAPHORE | QS_MTE | QS_FILESYS | QS_SHMEMORY ,
229 QS_MTE, /*0x96*/ ppib->pib_ulpid , 1UL, (PCHAR)buf, BUFSIZE);
230 if (rc==NO_ERROR) {
231 qsPrec_t * p;
232 GSList* lTemp;
233
234 pRegDLL->pMainAnchor=(qsPtrRec_t*) buf;
235
236 /* Pointer to process information */
237 p=pRegDLL->pMainAnchor->pProcRec;
238
239 while(p && p->RecType == 1)
240 {
241 qsLrec_t * pModRec; /* Info about a DLL */
242
243 /* Get record for executable */
244 pModRec=qsFindModuleRec(pRegDLL->pMainAnchor, p->hMte);
245 if(pModRec){
246 //if(pModRec->pName)
247 //g_message("exe) %s", pModRec->pName);
248 qsAddDLLToList(pRegDLL, pModRec);
249 }
250
251 if (p->cLib) { /* Number of lib imports */
252 int i;
253
254 for (i=0; i<p->cLib; i++){
255 pModRec=qsFindModuleRec(pRegDLL->pMainAnchor, p->pLibRec[i]);
256
257 if(pModRec){
258 //if(pModRec->pName)
259 //g_message("a) %s", pModRec->pName);
260 qsAddDLLToList(pRegDLL, pModRec);
261 }
262 }/* for() */
263 }/* if(p->clib) */
264 break;
265 };/* while() */
266
267 /* Ok, got directly imported DLLs. Now go over these and check them for additional imports.
268 Every import is added to the end of the list (except duplicates). So while going over
269 the list we touch every DLL and check every import. Import cycles are no problem, because
270 later duplicates are ignored. */
271 //g_message("\n\n");
272 lTemp=pRegDLL->dllList;
273 while(lTemp)
274 {
275 qsLrec_t* rec;
276
277 rec=(qsLrec_t*)lTemp->data;
278
279 /* Check the imports of this DLL if any */
280 if(rec->ctImpMod >0)
281 {
282 int iImps;
283 PUSHORT pImpHmte;
284
285 pImpHmte=(PUSHORT)((void*)rec + sizeof(qsLrec_t));
286 for(iImps=0; iImps < rec->ctImpMod; iImps++)
287 {
288 qsLrec_t * pModImp;
289
290 pModImp=qsFindModuleRec(pRegDLL->pMainAnchor, pImpHmte[iImps]);
291 if(pModImp){
292 //if(pModImp->pName)
293 //g_message("b) %s", pModImp->pName);
294 qsAddDLLToList(pRegDLL, pModImp);
295 }
296 }/* for()*/
297 }/* if() */
298 lTemp=g_slist_next(lTemp);
299 };/* while() */
300 // qsPrintDLLList();
301 hReg=pRegDLL;
302 }
303 else{
304 free(pRegDLL);
305 free(buf);
306 }
307 return hReg;
308}
309
310NOMEXTERN void NOMLINK nomEndRegisterDLLWithGC(const HREGDLL hRegisterDLL )
311{
312 g_slist_free(hRegisterDLL->dllList);
313 free((char*)hRegisterDLL->pMainAnchor);
314 free((char*)hRegisterDLL);
315}
316
317#define OBJREAD 0x0001L
318#define OBJWRITE 0x0002L
319#define OBJINVALID 0x0080L
320NOMEXTERN gboolean NOMLINK nomRegisterDLLByName(const HREGDLL hRegisterDLL, const char* chrDLLName)
321{
322 GSList* lTemp;
323
324 //g_message("Trying to register DLL %s", chrDLLName);
325 lTemp=hRegisterDLL->dllList;
326 while(lTemp)
327 {
328 qsLrec_t* pModRec;
329
330 pModRec=(qsLrec_t*)lTemp->data;
331 if(pModRec){
332 // g_message("DLL name: %s", pModRec->pName);
333 if(pModRec->pName && (NULL!=strstr( pModRec->pName, chrDLLName)))
334 {
335 qsLObjrec_t *pObjInfo;
336 //g_message(" --> Found DLL %s", pModRec->pName);
337 pObjInfo=pModRec->pObjInfo;
338 if(NULL!=pObjInfo)
339 {
340 int iObj;
341 for(iObj=0; iObj<pModRec->ctObj ;iObj++)
342 {
343 if (!(pObjInfo[iObj].oflags & OBJWRITE)) continue;
344 if (!(pObjInfo[iObj].oflags & OBJREAD)) continue;
345 if ((pObjInfo[iObj].oflags & OBJINVALID)) continue;
346 //g_message(" #%d: %04lX, size: %04lX %04lX",
347 // iObj, pObjInfo[iObj].oaddr, pObjInfo[iObj].osize, pObjInfo[iObj].oflags);
348 nomRegisterDataAreaForGC((char*)pObjInfo[iObj].oaddr,
349 (char*)(pObjInfo[iObj].oaddr+pObjInfo[iObj].osize));
350 g_tree_insert(treeRegisteredDLL, g_strdup(chrDLLName), GUINT_TO_POINTER((guint)pModRec->hmte));
351 }
352 }
353 return TRUE;
354 }
355 }
356 lTemp=g_slist_next(lTemp);
357 };/* while() */
358 return FALSE;
359}
360
361//#elif defined(_WIN32)
362#else /* PORTME */
363
364NOMEXTERN HREGDLL NOMLINK nomBeginRegisterDLLWithGC(void)
365{
366 HREGDLL pRegDLL;
367
368 pRegDLL =(HREGDLL) malloc(sizeof(REGDLL));
369 if(pRegDLL)
370 pRegDLL->dllList=NULL;
371 return pRegDLL;
372}
373
374NOMEXTERN void NOMLINK nomEndRegisterDLLWithGC(const HREGDLL hRegisterDLL )
375{
376}
377
378NOMEXTERN gboolean NOMLINK nomRegisterDLLByName(const HREGDLL hRegisterDLL, const char* chrDLLName)
379{
380 return TRUE;
381}
382
383#endif
384
385NOMEXTERN gboolean NOMLINK nomQueryUsingNameIsDLLRegistered(const gchar *chrName)
386{
387 if(NULL!=g_tree_lookup(treeRegisteredDLL, chrName))
388 return TRUE;
389
390 return FALSE;
391}
Note: See TracBrowser for help on using the repository browser.