CVS: winex/relay32 snoop.c,1.12,1.13
[email protected] 31 Jul 2007 18:01:47 -0000
| Newsgroups | gmane.comp.emulators.winex.cvs |
|---|---|
| Message-ID | <[email protected]> |
Subject: winex/relay32 snoop.c,1.12,1.13Update of /var/lib/cvsd/cvsroot/winex/relay32
In directory agravaine:/tmp/cvs-serv25179/relay32
Modified Files:
snoop.c
Log Message:
- make snoop threadsafe so that it can be used reliably on the Mac
Index: snoop.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/relay32/snoop.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- snoop.c 29 Mar 2007 14:03:39 -0000 1.12
+++ snoop.c 31 Jul 2007 18:01:45 -0000 1.13
@@ -81,15 +81,24 @@
DWORD *args; /* saved args across a stdcall */
} SNOOP_RETURNENTRY;
+#define NUMENTRIES 10
+
typedef struct tagSNOOP_RETURNENTRIES {
- SNOOP_RETURNENTRY entry[4092/sizeof(SNOOP_RETURNENTRY)];
+ SNOOP_RETURNENTRY entry[NUMENTRIES];
struct tagSNOOP_RETURNENTRIES *next;
} SNOOP_RETURNENTRIES;
#include "poppack.h"
+#define TMPBUFSIZE 256
+
+typedef struct {
+ char TmpBuf[TMPBUFSIZE];
+ SNOOP_RETURNENTRIES Entries;
+} SNOOP_ThreadData_t;
+
static SNOOP_DLL *firstdll = NULL;
-static SNOOP_RETURNENTRIES *firstrets = NULL;
+static DWORD SnoopTLS = TLS_OUT_OF_INDEXES;
/***********************************************************************
* SNOOP_ShowDebugmsgSnoop
@@ -140,6 +149,15 @@
return; /* already registered */
dll = &((*dll)->next);
}
+
+ if (SnoopTLS == TLS_OUT_OF_INDEXES)
+ SnoopTLS = TlsAlloc ();
+ if (SnoopTLS == TLS_OUT_OF_INDEXES)
+ {
+ ERR ("Unable to allocate TLS entry for snoop!\n");
+ return;
+ }
+
*dll = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SNOOP_DLL)+strlen(name));
(*dll)->next = NULL;
(*dll)->hmod = hmod;
@@ -210,12 +228,35 @@
return (FARPROC)&(fun->lcall);
}
+
+void SNOOP_ThreadExit ()
+{
+ SNOOP_ThreadData_t *pThreadData;
+ SNOOP_RETURNENTRIES *entries;
+
+ pThreadData = TlsGetValue (SnoopTLS);
+ if (pThreadData == NULL)
+ return;
+
+ entries = pThreadData->Entries.next;
+ while (entries)
+ {
+ SNOOP_RETURNENTRIES *next = entries->next;
+ HeapFree (GetProcessHeap (), 0, entries);
+ entries = next;
+ }
+ HeapFree (GetProcessHeap (), 0, pThreadData);
+}
+
+
static char*
-SNOOP_PrintArg(DWORD x) {
- static char buf[200];
+SNOOP_PrintArg(DWORD x, SNOOP_ThreadData_t *pThreadData) {
+ char *buf;
int i,nostring;
char * volatile ret=0;
+ buf = pThreadData->TmpBuf;
+
/* Strings have a non zero HIWORD. Is this trivially a number? */
if ( !HIWORD(x) ) {
sprintf(buf,"%08lx",x);
@@ -232,7 +273,7 @@
}
if (!nostring) {
if (i>5) {
- snprintf(buf,sizeof(buf),"%08lx %s",x,debugstr_an((LPSTR)x,sizeof(buf)-10));
+ snprintf(buf,TMPBUFSIZE,"%08lx %s",x,debugstr_an((LPSTR)x,TMPBUFSIZE-10));
ret=buf;
}
}
@@ -252,8 +293,8 @@
}
if (!nostring) {
if (i>5) {
- snprintf(buf,sizeof(buf),"%08lx %s",x,debugstr_wn((LPWSTR)x,sizeof(buf)-10));
- ret=buf;
+ snprintf(buf,TMPBUFSIZE, "%08lx %s", x, debugstr_wn((LPWSTR)x, TMPBUFSIZE-10));
+ ret=buf;
}
}
}
@@ -272,9 +313,25 @@
DWORD ordinal=0,entry = context->Eip - 5; /* 5 is sizeof(BYTE)+sizeof(DWORD) which is call instruction on x86 */
SNOOP_DLL *dll = firstdll;
SNOOP_FUN *fun = NULL;
- SNOOP_RETURNENTRIES **rets = &firstrets;
+ SNOOP_RETURNENTRIES *rets,*prev;
SNOOP_RETURNENTRY *ret;
int i=0, max;
+ SNOOP_ThreadData_t *pThreadData;
+
+ pThreadData = TlsGetValue (SnoopTLS);
+ if (pThreadData == NULL)
+ {
+ pThreadData = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+ sizeof (*pThreadData));
+ if (pThreadData == NULL)
+ {
+ ERR ("Unable to allocate thread data for snoop!\n");
+ return;
+ }
+ TlsSetValue (SnoopTLS, pThreadData);
+ }
+ rets = &pThreadData->Entries;
+ prev = NULL;
while (dll) {
if ( ((char*)entry>=(char*)dll->funs) &&
@@ -305,21 +362,24 @@
}
}
-
- while (*rets) {
- for (i=0;i<sizeof((*rets)->entry)/sizeof((*rets)->entry[0]);i++)
- if (!(*rets)->entry[i].origreturn)
- break;
- if (i!=sizeof((*rets)->entry)/sizeof((*rets)->entry[0]))
- break;
- rets = &((*rets)->next);
+ while (rets) {
+ for (i = 0; i < NUMENTRIES; i++)
+ {
+ if (!rets->entry[i].origreturn)
+ break;
+ }
+ if (i != NUMENTRIES)
+ break;
+ prev = rets;
+ rets = rets->next;
}
- if (!*rets) {
- *rets = VirtualAlloc(NULL,4096,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
- memset(*rets,0,4096);
- i = 0; /* entry 0 is free */
+ if (!rets) {
+ rets = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
+ sizeof (SNOOP_RETURNENTRIES));
+ i = 0; /* entry 0 is free */
+ prev->next = rets;
}
- ret = &((*rets)->entry[i]);
+ ret = &(rets->entry[i]);
ret->lcall = 0xe8;
/* NOTE: origreturn struct member MUST come directly after snoopret */
ret->snoopret = ((char*)SNOOP_Return)-(char*)(&ret->origreturn);
@@ -338,7 +398,7 @@
if (fun->nrofargs>0) {
max = fun->nrofargs; if (max>16) max=16;
for (i=0;i<max;i++)
- DPRINTF("%s%s",SNOOP_PrintArg(*(DWORD*)(context->Esp + 4 + sizeof(DWORD)*i)),(i<fun->nrofargs-1)?",":"");
+ DPRINTF("%s%s",SNOOP_PrintArg(*(DWORD*)(context->Esp + 4 + sizeof(DWORD)*i), pThreadData),(i<fun->nrofargs-1)?",":"");
if (max!=fun->nrofargs)
DPRINTF(" ...");
} else if (fun->nrofargs<0) {
@@ -353,6 +413,9 @@
void WINAPI SNOOP_DoReturn( CONTEXT86 *context )
{
SNOOP_RETURNENTRY *ret = (SNOOP_RETURNENTRY*)(context->Eip - 5);
+ SNOOP_ThreadData_t *pThreadData;
+
+ pThreadData = TlsGetValue (SnoopTLS);
/* We haven't found out the nrofargs yet. If we called a cdecl
* function it is too late anyway and we can just set '0' (which
@@ -374,7 +437,7 @@
if (max>16) max=16;
for (i=0;i<max;i++)
- DPRINTF("%s%s",SNOOP_PrintArg(ret->args[i]),(i<max-1)?",":"");
+ DPRINTF("%s%s",SNOOP_PrintArg(ret->args[i], pThreadData),(i<max-1)?",":"");
DPRINTF(") retval = %08lx ret=%08lx\n",
context->Eax,(DWORD)ret->origreturn );
HeapFree(GetProcessHeap(),0,ret->args);