Fix for bug#4312. Conditionalized patching of StackSpace so it's only done when patching is allowed. Use FindSymbol to dynamically lookup NewRoutineDescriptor and CallOSTrapUniversalProc so we can link against CarbonLib. SeaMonkey_M6_BASE
authorgordon%netscape.com
Fri, 21 May 1999 20:08:09 +0000
changeset 634 fdf058d383ff86d7f0ce4999bc5c32fa07dc67ed
parent 632 739366dc13f08c25774c606921d9d166b2591784
child 635 4a8dd7cfb76eae40c0c1cfda3dfe1a5a5dc20765
child 636 0efe8e13621a704006a0a7e104a2c960d4e8b127
child 637 3c86f4c089de1690993dbcacf39b58356e3df37c
push idunknown
push userunknown
push dateunknown
bugs4312
Fix for bug#4312. Conditionalized patching of StackSpace so it's only done when patching is allowed. Use FindSymbol to dynamically lookup NewRoutineDescriptor and CallOSTrapUniversalProc so we can link against CarbonLib.
pr/src/md/mac/mdmac.c
--- a/pr/src/md/mac/mdmac.c
+++ b/pr/src/md/mac/mdmac.c
@@ -36,75 +36,132 @@
 #include <unix.h>
 
 #include "MacErrorHandling.h"
 
 #include "primpl.h"
 #include "prgc.h"
 
 
-
-enum {
-	uppExitToShellProcInfo 				= kPascalStackBased,
-	uppStackSpaceProcInfo				= kRegisterBased 
-										  | RESULT_SIZE(SIZE_CODE(sizeof(long)))
-										  | REGISTER_RESULT_LOCATION(kRegisterD0)
-		 								  | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(UInt16)))
-};
-
-
 #define UNIMPLEMENTED_ROUTINE			\
 	DebugStr("\pNot Implemented Yet");	\
 	return 0;
 
 //
 // Local routines
 //
 void PStrFromCStr(const char *, Str255);
 unsigned char GarbageCollectorCacheFlusher(PRUint32 size);
 
 extern PRThread *gPrimaryThread;
 
 
-UniversalProcPtr	gStackSpacePatchCallThru = NULL;
-pascal long StackSpacePatch(UInt16);
-
-typedef CALLBACK_API( long , StackSpacePatchPtr )(UInt16 trapNo);
-typedef REGISTER_UPP_TYPE(StackSpacePatchPtr)	StackSpacePatchUPP;
-#define NewStackSpaceProc(userRoutine)	(StackSpacePatchUPP)NewRoutineDescriptor((ProcPtr)(userRoutine), uppStackSpaceProcInfo, GetCurrentArchitecture())
-StackSpacePatchUPP	gStackSpacePatchUPP = NULL;
 
 //##############################################################################
 //##############################################################################
 #pragma mark -
 #pragma mark CREATING MACINTOSH THREAD STACKS
 
 
+enum {
+	uppExitToShellProcInfo 				= kPascalStackBased,
+	uppStackSpaceProcInfo				= kRegisterBased 
+										  | RESULT_SIZE(SIZE_CODE(sizeof(long)))
+										  | REGISTER_RESULT_LOCATION(kRegisterD0)
+		 								  | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(UInt16)))
+};
+
+typedef CALLBACK_API( long , StackSpacePatchPtr )(UInt16 trapNo);
+typedef REGISTER_UPP_TYPE(StackSpacePatchPtr)	StackSpacePatchUPP;
+
+StackSpacePatchUPP	  gStackSpacePatchUPP = NULL;
+UniversalProcPtr	  gStackSpacePatchCallThru = NULL;
+long				(*gCallOSTrapUniversalProc)(UniversalProcPtr,ProcInfoType,...) = NULL;
+
 
 pascal long StackSpacePatch(UInt16 trapNo)
 {
 	char		tos;
 	PRThread	*thisThread;
 	
 	thisThread = PR_CurrentThread();
 	
 	//	If we are the primary thread, then call through to the
 	//	good ol' fashion stack space implementation.  Otherwise,
 	//	compute it by hand.
 	if ((thisThread == gPrimaryThread) || 	
 		(&tos < thisThread->stack->stackBottom) || 
 		(&tos > thisThread->stack->stackTop)) {
-		return CallOSTrapUniversalProc(gStackSpacePatchCallThru, uppStackSpaceProcInfo, trapNo);
+		return gCallOSTrapUniversalProc(gStackSpacePatchCallThru, uppStackSpaceProcInfo, trapNo);
 	}
 	else {
 		return &tos - thisThread->stack->stackBottom;
 	}
 }
 
 
+static void InstallStackSpacePatch(void)
+{
+	long				systemVersion;
+	OSErr				err;
+	CFragConnectionID	connID;
+	Str255				errMessage;
+	Ptr					interfaceLibAddr;
+	CFragSymbolClass	symClass;
+	UniversalProcPtr	(*getOSTrapAddressProc)(UInt16);
+	void				(*setOSTrapAddressProc)(UniversalProcPtr, UInt16);
+	UniversalProcPtr	(*newRoutineDescriptorProc)(ProcPtr,ProcInfoType,ISAType);
+	
+
+	err = Gestalt(gestaltSystemVersion,&systemVersion);
+	if (systemVersion >= 0x00000A00)	// we don't need to patch StackSpace()
+		return;
+
+	// open connection to "InterfaceLib"
+	err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
+											&connID, &interfaceLibAddr, errMessage);
+	PR_ASSERT(err == noErr);
+	if (err != noErr)
+		return;
+
+	// get symbol GetOSTrapAddress
+	err = FindSymbol(connID, "\pGetOSTrapAddress", &(Ptr)getOSTrapAddressProc, &symClass);
+	if (err != noErr)
+		return;
+
+	// get symbol SetOSTrapAddress
+	err = FindSymbol(connID, "\pSetOSTrapAddress", &(Ptr)setOSTrapAddressProc, &symClass);
+	if (err != noErr)
+		return;
+	
+	// get symbol NewRoutineDescriptor
+	err = FindSymbol(connID, "\pNewRoutineDescriptor", &(Ptr)newRoutineDescriptorProc, &symClass);
+	if (err != noErr)
+		return;
+	
+	// get symbol CallOSTrapUniversalProc
+	err = FindSymbol(connID, "\pCallOSTrapUniversalProc", &(Ptr)gCallOSTrapUniversalProc, &symClass);
+	if (err != noErr)
+		return;
+
+	// get and set trap address for StackSpace (A065)
+	gStackSpacePatchCallThru = getOSTrapAddressProc(0x0065);
+	if (gStackSpacePatchCallThru)
+	{
+		gStackSpacePatchUPP =
+			(StackSpacePatchUPP)newRoutineDescriptorProc((ProcPtr)(StackSpacePatch), uppStackSpaceProcInfo, GetCurrentArchitecture());
+		setOSTrapAddressProc(gStackSpacePatchUPP, 0x0065);
+	}
+
+#if DEBUG
+	StackSpace();
+#endif
+}
+
+
 //##############################################################################
 //##############################################################################
 #pragma mark -
 #pragma mark ENVIRONMENT VARIABLES
 
 
 typedef struct EnvVariable EnvVariable;
 
@@ -208,18 +265,16 @@ PRWord *_MD_HomeGCRegisters(PRThread *t,
 void _MD_GetRegisters(PRUint32 *to)
 {
   (void) setjmp((void*) to);
 }
 
 void _MD_EarlyInit()
 {
 	Handle				environmentVariables;
-	long				systemVersion;
-	OSErr				err;
 
 #if !defined(MAC_NSPR_STANDALONE)
 	// MacintoshInitializeMemory();  Moved to mdmacmem.c: AllocateRawMemory(Size blockSize)
 #else
 	MacintoshInitializeMemory();
 #endif
 	MacintoshInitializeTime();
 	
@@ -251,50 +306,17 @@ void _MD_EarlyInit()
 		DisposeHandle(environmentVariables);
 
 	}
 
 #ifdef PR_INTERNAL_LOGGING
 	_MD_PutEnv ("NSPR_LOG_MODULES=clock:6,cmon:6,io:6,mon:6,linker:6,cvar:6,sched:6,thread:6");
 #endif
 
-	err = Gestalt(gestaltSystemVersion,&systemVersion);
-	if (systemVersion < 0x00000A00)	// we still need to patch StackSpace()
-	{
-		CFragConnectionID	connID;
-		Str255				errMessage;
-		Ptr					interfaceLibAddr;
-		CFragSymbolClass	symClass;
-		UniversalProcPtr	(*getOSTrapAddressProc)(UInt16);
-		void				(*setOSTrapAddressProc)(UniversalProcPtr, UInt16);
-
-		// open connection to "InterfaceLib"
-		err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
-												&connID, &interfaceLibAddr, errMessage);
-		PR_ASSERT(err == noErr);
-
-		// get symbol GetOSTrapAddress and get trap address for StackSpace (A065)
-		err = FindSymbol(connID, "\pGetOSTrapAddress", &(Ptr)getOSTrapAddressProc, &symClass);
-		PR_ASSERT(err == noErr);
-		PR_ASSERT(symClass == kTVectorCFragSymbol);
-		if (err == noErr)
-		{
-			gStackSpacePatchCallThru = getOSTrapAddressProc(0x0065); 
-		}
-		
-		// get symbol SetOSTrapAddress and set trap address for _StackSpace (A065)
-		err = FindSymbol(connID, "\pSetOSTrapAddress", &(Ptr)setOSTrapAddressProc, &symClass);
-		PR_ASSERT(err == noErr);
-		PR_ASSERT(symClass == kTVectorCFragSymbol);
-		if (err == noErr && gStackSpacePatchCallThru)
-		{
-			gStackSpacePatchUPP = NewStackSpaceProc(StackSpacePatch);
-			setOSTrapAddressProc(gStackSpacePatchUPP, 0x0065);
-		}
-	}
+	InstallStackSpacePatch();
 }
 
 void _MD_FinalInit()
 {
 	_MD_InitNetAccess();
 }
 
 void PR_InitMemory(void) {
@@ -430,19 +452,17 @@ void debugstr(const char *debuggerMsg)
 }
 
 
 char *strdup(const char *source)
 {
 	char 	*newAllocation;
 	size_t	stringLength;
 
-#ifdef DEBUG
 	PR_ASSERT(source);
-#endif
 	
 	stringLength = strlen(source) + 1;
 	
 	newAllocation = (char *)PR_MALLOC(stringLength);
 	if (newAllocation == NULL)
 		return NULL;
 	BlockMoveData(source, newAllocation, stringLength);
 	return newAllocation;