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);