Parcourir la source

Win64 exception handling works

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7417 8c9fc860-2736-0410-a75d-ab315db34111
felixf il y a 7 ans
Parent
commit
17bfd4b1b8

+ 4 - 4
source/BitSets.Mod

@@ -7,7 +7,7 @@ CONST Elements = MAX (SET) - MIN (SET) + 1;
 TYPE Data = POINTER TO ARRAY OF SET;
 
 TYPE BitSet* = OBJECT
-	VAR size: SIZE;
+	VAR size: LONGINT;
 	VAR data: Data;
 
 	PROCEDURE & InitBitSet* (size: LONGINT);
@@ -19,7 +19,7 @@ TYPE BitSet* = OBJECT
 	BEGIN FOR i := 0 TO LEN(data)-1 DO data[i] := {} END;
 	END Zero;
 
-	PROCEDURE Resize* (size: SIZE);
+	PROCEDURE Resize* (size: LONGINT);
 	VAR newData: Data; i: SIZE;
 	BEGIN
 		ASSERT (size >= 0);
@@ -36,7 +36,7 @@ TYPE BitSet* = OBJECT
 		data := newData;
 	END Resize;
 
-	PROCEDURE GetSize* (): SIZE;
+	PROCEDURE GetSize* (): LONGINT;
 	BEGIN RETURN size;
 	END GetSize;
 
@@ -112,7 +112,7 @@ TYPE BitSet* = OBJECT
 
 END BitSet;
 
-PROCEDURE CopyBits* (source: BitSet; sourcePos: LONGINT; dest: BitSet; destPos, count: LONGINT);
+PROCEDURE CopyBits* (source: BitSet; sourcePos: SIZE; dest: BitSet; destPos, count: SIZE);
 CONST setSize= MAX(SET)+1;
 BEGIN
 	ASSERT (count >= 0);

+ 15 - 3
source/Builds.Tool

@@ -24,7 +24,9 @@ LINUX32G -- 32 bit linux a2 using generic object files
 	Release.Build -b Linux32G ~
 	
 	## X11 bootconsole ##
-		StaticLinker.Link -p=Linux32G Runtime Trace Glue Unix Machine Heaps Modules Objects Kernel KernelLog  Streams Commands Pipes StdIO TrapWriters Reflection Traps Files UnixFiles Clock Dates Reals Strings Diagnostics BitSets StringPool ObjectFile GenericLinker   GenericLoader  BootConsole ~
+		StaticLinker.Link -p=Linux32G Runtime Trace Glue Unix Machine Heaps Modules Objects Kernel 
+		KernelLog  Streams Commands Pipes StdIO TrapWriters Reflection Traps Files UnixFiles Clock Dates 
+		Reals Strings Diagnostics BitSets StringPool ObjectFile GenericLinker   GenericLoader  BootConsole ~
 	
 	## Command line shell including compiler (and linker) ##
 		StaticLinker.Link -p=Linux32G 
@@ -41,15 +43,25 @@ SystemTools.DoCommands
 Compiler.Compile -b=AMD --bits=64 --objectFile=Generic --newObjectFile  --symbolFile=Textual  --objectFileExtension=.GofWw --symbolFileExtension=.SymWw 
 	--traceModule=Trace
 	AMD64.Runtime.Mod Trace.Mod Generic.Win64.Kernel32.Mod Win64.Machine.Mod Heaps.Mod Generic.Modules.Mod 
-	Win64.Objects.Mod Win32.Kernel.Mod ~
+	Win64.Objects.Mod Win32.Kernel.Mod  
+	KernelLog.Mod Streams.Mod Commands.Mod Files.Mod Win32.WinFS.Mod Win32.Clock.Mod Dates.Mod 
+	AMD64.Reals.Mod Strings.Mod Diagnostics.Mod BitSets.Mod
+	StringPool.Mod ObjectFile.Mod GenericLinker.Mod Reflection.Mod GenericLoader.Mod BootConsole.Mod 
+	Win32.WinTrace.Mod Pipes.Mod Win32.StdIO.Mod Shell.Mod StdIOShell.Mod 
+	~
 
 StaticLinker.Link --fileFormat=PE64CUI --fileName=A264.exe --extension=GofWw --displacement=401000H  
 	Runtime Trace Kernel32 
-	Heaps Modules Objects Kernel ~
+	Heaps Modules Objects Kernel
+	KernelLog Streams Commands Files WinFS Clock Dates Reals Strings Diagnostics BitSets 
+	StringPool ObjectFile GenericLinker Reflection  GenericLoader Shell  StdIOShell ~
 
 FSTools.CloseFiles A264.exe  ~
 ~
 
 	KernelLog Streams Commands Files WinFS Clock Dates Reals Strings Diagnostics BitSets StringPool ObjectFile GenericLinker Reflection  GenericLoader  BootConsole ~
 	~
+	 ConsumerProducer TestBoot ~
+	ProducerConsumer.Mod TestBoot.Mod 	
 
+~ BootConsole ~			

+ 3 - 3
source/Generic.Modules.Mod

@@ -26,7 +26,7 @@ CONST
 	DefaultContext* = "A2";
 	NoLoader=3400;
 
-	TraceBoot=FALSE;
+	TraceBoot=TRUE;
 
 	(* flags *)
 	PreciseGC* = 0;
@@ -684,7 +684,7 @@ BEGIN
 			IF m # NIL THEN term := m.term; m.term := NIL END; (* finalizer only called once *)
 			Machine.Release(Machine.Modules);
 			IF m = NIL THEN EXIT END;
-			IF trace THEN
+			IF TraceBoot OR trace THEN
 				Machine.Acquire (Machine.TraceOutput);
 				Trace.String("TermHandler "); Trace.StringLn (m.name);
 				Machine.Release (Machine.TraceOutput);
@@ -699,7 +699,7 @@ BEGIN
 			END;
 			m := m.next
 		END;
-		IF trace THEN
+		IF TraceBoot OR trace THEN
 			Machine.Acquire (Machine.TraceOutput);
 			Trace.StringLn ("Modules.Shutdown finished");
 			Machine.Release (Machine.TraceOutput);

+ 88 - 9
source/Generic.Win64.Kernel32.Mod

@@ -166,6 +166,8 @@ TYPE
 	HANDLE* = ADDRESS;  HMODULE* = ADDRESS;
 	HINSTANCE* = ADDRESS;  ATOM* = INTEGER;  HGLOBAL* = HANDLE;
 	LPSTR* = ADDRESS;
+	DWORD* = LONGINT;
+	ULONG*= UNSIGNED32;
 
 	(** The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601. *)
 	FileTime* = RECORD
@@ -208,20 +210,76 @@ TYPE
 		Cr0NpxState*: LONGINT
 	END;
 
+	ContextPtr*= POINTER {UNSAFE} TO Context;
+	(* 32 bit
 	Context* = RECORD
 		ContextFlags*: SET;
 		DR0*, DR1*, DR2*, DR3*, DR6*, DR7*: SIZE;
 		FloatSave*: FloatingSaveArea;
-		GS*, FS*, ES*, DS*: SIZE;
-		EDI*, ESI*, EBX*, EDX*, ECX*, EAX*: SIZE;
-		BP*, PC*, CS*, FLAGS*, SP*, SS*: SIZE; (* whereas BP is EBP and SP is ESP *)
+		GS*, FS*, ES*, DS*: ADDRESS;
+		EDI*, ESI*, EBX*, EDX*, ECX*, EAX*: ADDRESS;
+		BP*, PC*, CS*, FLAGS*, SP*, SS*: ADDRESS; (* whereas BP is EBP and SP is ESP *)
 	END;
+	*) 
+	
+	Context*= RECORD
+		P1Home, P2Home, P3Home, P4Home, P5Home, P6Home: SIZE; 
+		
+		ContextFlags*: DWORD; 
+		MxCsr*: DWORD; 
+		
+		SegCs*, SegDs*, SegEs*, SegFs*, SegGs*, SegSs*: INTEGER; 
+		EFlags*: DWORD;
+		
+		Dr0*, Dr1*, Dr2*, Dr3*, Dr6*, Dr7*: SIZE;
+		
+		RAX*, RCX*, RDX*, RBX*, SP*, BP*, RSI*, RDI*, R8*, R9*, R10*, R11*, R12*, R13*, R14*, R15*: ADDRESS;
+		PC*: ADDRESS; 
+		
+		remainder (* leave enough space for the rest here *): ARRAY 1024 OF CHAR;
+		
+		(*    union {
+        XMM_SAVE_AREA32 FltSave;
+        struct {
+            M128A Header[2];
+            M128A Legacy[8];
+            M128A Xmm0;
+            M128A Xmm1;
+            M128A Xmm2;
+            M128A Xmm3;
+            M128A Xmm4;
+            M128A Xmm5;
+            M128A Xmm6;
+            M128A Xmm7;
+            M128A Xmm8;
+            M128A Xmm9;
+            M128A Xmm10;
+            M128A Xmm11;
+            M128A Xmm12;
+            M128A Xmm13;
+            M128A Xmm14;
+            M128A Xmm15;
+        };
+    };
+
+    M128A VectorRegister[26];
+    DWORD64 VectorControl;
+
+    DWORD64 DebugControl;
+    DWORD64 LastBranchToRip;
+    DWORD64 LastBranchFromRip;
+    DWORD64 LastExceptionToRip;
+    DWORD64 LastExceptionFromRip;
+} CONTEXT, *PCONTEXT;
+	*)
+	END; 
+				
 
 	Wow64Context*= RECORD (Context)
 		extension: ARRAY 512 (* MaxWOW64Extension *) OF CHAR;
 	END;
 	
-	ExceptionRecordPtr* = POINTER TO ExceptionRecord;
+	ExceptionRecordPtr* = POINTER {UNSAFE} TO ExceptionRecord;
 	ExceptionRecord* = RECORD
 		ExceptionCode*, ExceptionFlags*: LONGINT;
 		nextExceptionRecord*: ExceptionRecordPtr;
@@ -235,6 +293,14 @@ TYPE
 																														   excpFrame: ExcpFrmPtr;
 																														   VAR context: Context;
 																														   dispatch: LONGINT ): LONGINT;
+
+	ExceptionPointers* = RECORD
+		exception*: ExceptionRecordPtr;
+		context*: ContextPtr;
+	END; 																														   
+
+	VectoredExceptionHandler* = PROCEDURE {WINAPI} ( CONST e: ExceptionPointers): DWORD;
+
 	ExcpFrm* = RECORD
 		link*: ExcpFrmPtr;
 		handler*: ExcpFrmHandler
@@ -299,6 +365,7 @@ TYPE
 		exc*: ExceptionRecord;
 		cont*: Context
 	END;
+	
 
 	CommTimeouts* = RECORD
 		ReadIntervalTimeout*, ReadTotalTimeoutMultiplier*, ReadTotalTimeoutConstant*, WriteTotalTimeoutMultiplier*, WriteTotalTimeoutConstant*: LONGINT
@@ -361,8 +428,10 @@ VAR
 	getProcAddress-: PROCEDURE {WINAPI} ( hModule: HMODULE;  CONST  lpProcName: ARRAY   OF CHAR ): ADDRESS;
 	(** The LoadLibrary function maps the specified executable module into the address space of the calling process. *)
 	LoadLibrary-: PROCEDURE {WINAPI} ( CONST lpLibFileName: ARRAY   OF CHAR ): HINSTANCE;   (* must be patched by linker / PE loader *)
-
-
+	(** registers a vectored continue handler. **)
+	AddVectoredContinueHandler-: PROCEDURE {WINAPI} (firstHandler: ULONG; vectoredHandler: VectoredExceptionHandler); 
+	(** registers a vectored exception handler. **)
+	AddVectoredExceptionHandler-: PROCEDURE {WINAPI} (firstHandler: ULONG; vectoredHandler: VectoredExceptionHandler); 
 	(** The AllocConsole function allocates a new console for the calling process. *)
 	AllocConsole-: PROCEDURE {WINAPI} ( ): BOOL;
 	(** The AttachConsole function attaches the calling process to the console of the specified process. *)
@@ -495,7 +564,7 @@ VAR
 	GetExitCodeProcess-: PROCEDURE {WINAPI} ( hProcess: HANDLE;
 																				  VAR lpExitCode: LONGINT ): BOOL;
 	(** The GetFileAttributes function returns attributes for a specified file or directory. *)
-	GetFileAttributes-: PROCEDURE {WINAPI} ( VAR lpFileName: ARRAY   OF CHAR ): SET;
+	GetFileAttributes-: PROCEDURE {WINAPI} ( CONST lpFileName: ARRAY   OF CHAR ): DWORD;
 	(** The GetFileSize function retrieves the size, in bytes, of the specified file. *)
 	GetFileSize-: PROCEDURE {WINAPI} ( hFile: HANDLE;  VAR lpFileSizeHigh: LONGINT ): LONGINT;
 	GetFileSizeEx-: PROCEDURE {WINAPI} ( hFile: HANDLE;  VAR lpFileSize: HUGEINT ): BOOL;
@@ -519,7 +588,7 @@ VAR
 	(* The GetLogicalDrives function retrieves a bitmask representing the currently available disk drives.
 *)
 
-	GetLogicalDrives-: PROCEDURE {WINAPI} ( ): SET;
+	GetLogicalDrives-: PROCEDURE {WINAPI} ( ): DWORD;
 	GetModuleFileName-: PROCEDURE {WINAPI} ( hModule: HMODULE;
 																				    VAR lpFileName: ARRAY   OF CHAR;
 																				    nSize: LONGINT ): LONGINT;
@@ -684,6 +753,10 @@ VAR
 	ReleaseSemaphore-: PROCEDURE {WINAPI} ( hSemaphore: HANDLE; lReleaseCount: LONGINT; lpPreviousCount: ADDRESS): BOOL;
 	(** The RemoveDirectory function deletes an existing empty directory. *)
 	RemoveDirectory-: PROCEDURE {WINAPI} ( VAR lpPathName: ARRAY   OF CHAR ): BOOL;
+	(** unregisters a vectored continue handler. **)
+	RemoveVectoredContinueHandler-: PROCEDURE {WINAPI} (vectoredHandler: VectoredExceptionHandler): ULONG; 
+	(** unregisters a vectored exception handler. **)
+	RemoveVectoredExceptionHandler-: PROCEDURE {WINAPI} (vectoredHandler: VectoredExceptionHandler): ULONG; 
 	(** The ResetEvent function sets the state of the specified event object to nonsignaled. *)
 	ResetEvent-: PROCEDURE {WINAPI} ( hEvent: HANDLE ): BOOL;
 	(** The ResumeThread function decrements a thread's suspend count. *)
@@ -860,8 +933,10 @@ VAR
 	END SendToDebugger;
 
 	PROCEDURE ShutdownP(l: LONGINT);
+	VAR i: LONGINT;
 	BEGIN
-		outputDebugString("Kernel32.Shutdown");
+		(* FOR i := 0 TO 0x10000000 DO END;*) 
+		OutputString("Kernel32.Shutdown");
 		ExitProcess(l);
 	END ShutdownP;
 	
@@ -871,6 +946,8 @@ VAR
 		Shutdown := ShutdownP;
 		mod := LoadLibrary("Kernel32.DLL");
 		GetProcAddress(mod, "AllocConsole",SYSTEM.VAL(ADDRESS,AllocConsole));
+		GetProcAddress(mod, "AddVectoredExceptionHandler",SYSTEM.VAL(ADDRESS,AddVectoredExceptionHandler));
+		GetProcAddress(mod, "AddVectoredContinueHandler",SYSTEM.VAL(ADDRESS,AddVectoredContinueHandler));
 		GetProcAddress(mod, "AttachConsole",SYSTEM.VAL(ADDRESS,AttachConsole));
 		GetProcAddress(mod, "Beep",SYSTEM.VAL(ADDRESS,Beep));
 		GetProcAddress(mod, "ClearCommBreak",SYSTEM.VAL(ADDRESS,ClearCommBreak));
@@ -977,6 +1054,8 @@ VAR
 		GetProcAddress(mod, "ReadProcessMemory",SYSTEM.VAL(ADDRESS,ReadProcessMemory));
 		GetProcAddress(mod, "ReleaseSemaphore",SYSTEM.VAL(ADDRESS,ReleaseSemaphore));
 		GetProcAddress(mod, "RemoveDirectoryA",SYSTEM.VAL(ADDRESS,RemoveDirectory));
+		GetProcAddress(mod, "RemoveVectoredExceptionHandler",SYSTEM.VAL(ADDRESS,RemoveVectoredExceptionHandler));
+		GetProcAddress(mod, "RemoveVectoredExceptionHandler",SYSTEM.VAL(ADDRESS,RemoveVectoredContinueHandler));
 		GetProcAddress(mod, "ResetEvent",SYSTEM.VAL(ADDRESS,ResetEvent));
 		GetProcAddress(mod, "ResumeThread",SYSTEM.VAL(ADDRESS,ResumeThread));
 		GetProcAddress(mod, "SearchPathA",SYSTEM.VAL(ADDRESS,SearchPath));

+ 4 - 3
source/Win64.Machine.Mod

@@ -315,9 +315,9 @@ VAR
 		
 		IF (name = "ObjectFileExtension") & (val = "") THEN
 			IF Kernel32.Generic THEN
-				val := ".GofW";
+				val := ".GofWw";
 			ELSE
-				val := ".Obw"
+				val := ".Obww"
 			END;
 		END;
 	END GetConfig;
@@ -534,7 +534,7 @@ END SetupTraceName;
 PROCEDURE RemoveTraceFile;
 VAR res: LONGINT;
 BEGIN
-	IF traceName[0] # 0X THEN
+	IF (traceName # "") & (traceName # "Console") THEN
 		Trace.String("removing "); Trace.String(traceName); Trace.Ln;
 		(*Trace.Char := LogChar;*)
 		res := Kernel32.CloseHandle(hout);
@@ -551,6 +551,7 @@ BEGIN
 		END;
 		TRACE(res);
 	END;
+	TRACE(traceName);
 END RemoveTraceFile;
 
 PROCEDURE ToExecutablePath(CONST name: ARRAY OF CHAR; VAR fullName: ARRAY OF CHAR);

+ 99 - 53
source/Win64.Objects.Mod

@@ -6,7 +6,7 @@ IMPORT SYSTEM, Trace, Kernel32, Machine, Modules, Heaps;
 
 CONST
 	HandleExcp = TRUE;   (* FALSE -> we asume that it is done correctly by Traps *)
-	TraceVerbose = FALSE;
+	TraceVerbose = TRUE;
 	StrongChecks = FALSE;  defaultStackSize = 0;
 	TraceOpenClose = FALSE;
 
@@ -189,17 +189,17 @@ TYPE
 					ASSERT(res # -1);
 				END;
 
-				state.ContextFlags := Kernel32.ContextControl + Kernel32.ContextInteger;
+				state.ContextFlags := SYSTEM.VAL(LONGINT, Kernel32.ContextControl + Kernel32.ContextInteger);
 				res := Kernel32.GetThreadContext( handle, state );
 				
-				context.ContextFlags := Kernel32.ContextControl + Kernel32.ContextInteger;
+				context.ContextFlags := SYSTEM.VAL(LONGINT, Kernel32.ContextControl + Kernel32.ContextInteger);
 				IF isWow64 THEN 
 					res := Kernel32.Wow64GetThreadContext( handle, context );
 				ELSE
 					res := Kernel32.GetThreadContext( handle, context );
 				END;
 				ASSERT(res # 0);
-				sp := context.SP; bp := context.BP; pc := context.PC;
+				sp :=  context.SP; bp := context.BP; pc := context.PC;
 				
 				mod := Modules.ThisModuleByAdr0(pc);
 				IF mod # NIL THEN
@@ -220,9 +220,9 @@ TYPE
 			(* stack garbage collection *)
 
 			IF Heaps.GCType= Heaps.HeuristicStackInspectionGC THEN
-				Heaps.Candidate( context.EDI );  Heaps.Candidate( context.ESI );
-				Heaps.Candidate( context.EBX ); Heaps.Candidate( context.EDX );
-				Heaps.Candidate( context.ECX ); Heaps.Candidate( context.EAX );
+				Heaps.Candidate( context.RDI );  Heaps.Candidate( context.RSI );
+				Heaps.Candidate( context.RBX ); Heaps.Candidate( context.RDX );
+				Heaps.Candidate( context.RCX ); Heaps.Candidate( context.RAX );
 				IF (stackBottom # 0) & (sp # 0) THEN
 					Heaps.RegisterCandidates( sp, stackBottom - sp );
 				END;
@@ -264,9 +264,7 @@ TYPE
 	END Process;
 
 TYPE
-	ExceptionHandler* = PROCEDURE(	VAR context: Kernel32.Context;
-										VAR excpRec: Kernel32.ExceptionRecord;
-										VAR handled: BOOLEAN);
+	ExceptionHandler* = PROCEDURE( CONST exceptionPointers: Kernel32.ExceptionPointers): Kernel32.DWORD;
 
 
 	GCStatusExt = OBJECT(Heaps.GCStatus)
@@ -513,10 +511,10 @@ CODE {SYSTEM.i386}
 	DB	000H
 END StackBottom;
 
-PROCEDURE {WINAPI} ExcpFrmHandler( VAR  excpRec: Kernel32.ExceptionRecord; excpFrame: Kernel32.ExcpFrmPtr;
- 										VAR context: Kernel32.Context;  dispatch: LONGINT ): LONGINT;
+PROCEDURE {WINAPI} ExcpFrmHandler( CONST exceptionPointers: Kernel32.ExceptionPointers): Kernel32.DWORD ;
 VAR m: Modules.Module;  eip, ebp, stack: ADDRESS;  pc, handler, fp, sp: ADDRESS;  handled: BOOLEAN;  t: Process;
 BEGIN
+	TRACE("TRAP"); 
 	handled := FALSE;
 
 	Kernel32.EnterCriticalSection( excplock );
@@ -533,45 +531,64 @@ BEGIN
 		Trace.StringLn ( "Objects: No exception handler installed" );
 		IF HandleExcp THEN
 
-			Trace.String( "EXCEPTION " );  Trace.Hex( excpRec.ExceptionCode, 1 );
-			Trace.String( " at " );  Trace.Hex( excpRec.ExceptionAddress, 1 );
-			Trace.Ln();  Trace.String( "EAX " );  Trace.Hex( context.EAX, 1 );
-			Trace.String( "  EBX " );  Trace.Hex( context.EBX, 1 );  Trace.Ln();
-			Trace.String( "ECX " );  Trace.Hex( context.ECX, 1 );  Trace.String( "  EDX " );
-			Trace.Hex( context.EDX, 1 );  Trace.Ln();  Trace.String( "EDI " );
-			Trace.Hex( context.EDI, 1 );  Trace.String( "  ESI " );
-			Trace.Hex( context.ESI, 1 );  Trace.Ln();  Trace.String( "EBP " );
-			Trace.Hex( context.BP, 1 );  Trace.String( "  ESP " );
-			Trace.Hex( context.SP, 1 );  Trace.Ln();  Trace.String( "EIP " );
-			Trace.Hex( context.PC, 1 );  Trace.Ln();  Trace.Ln();
-			eip := excpRec.ExceptionAddress;  ebp := context.BP;
-			IF eip = 0 THEN SYSTEM.GET( context.SP, eip ) END;
+			Trace.String( "EXCEPTION " );  Trace.Address(exceptionPointers.exception.ExceptionCode);
+			Trace.String( " at " );  Trace.Address(exceptionPointers.exception.ExceptionAddress);
+			Trace.Ln();  Trace.String( "RAX " );  Trace.Address(exceptionPointers.context.RAX);
+			Trace.String( "  RBX " );  Trace.Address(exceptionPointers.context.RBX);  Trace.Ln();
+			Trace.String( "RCX " );  Trace.Address(exceptionPointers.context.RCX);  Trace.String( "  RDX " );
+			Trace.Address(exceptionPointers.context.RDX);  Trace.Ln();  Trace.String( "RDI " );
+			Trace.Address(exceptionPointers.context.RDI);  Trace.String( "  RSI " );
+			Trace.Address(exceptionPointers.context.RSI);  Trace.Ln(); 
+			
+			Trace.String( "R8 " ); Trace.Address(exceptionPointers.context.R8);
+			Trace.String( " R9 " ); Trace.Address(exceptionPointers.context.R9);  Trace.Ln();  
+			Trace.String( "R10 " ); Trace.Address(exceptionPointers.context.R10);
+			Trace.String( " R11 " ); Trace.Address(exceptionPointers.context.R11);  Trace.Ln();  
+			Trace.String( "R12 " ); Trace.Address(exceptionPointers.context.R12);
+			Trace.String( " R13 " ); Trace.Address(exceptionPointers.context.R13);  Trace.Ln();  
+			Trace.String( "R14 " ); Trace.Address(exceptionPointers.context.R14);
+			Trace.String( " R15 " ); Trace.Address(exceptionPointers.context.R15);  Trace.Ln();  
+			Trace.Ln; 
+			
+			Trace.String( "RBP " );
+			Trace.Address(exceptionPointers.context.BP);  Trace.String( "  RSP " );
+			Trace.Address(exceptionPointers.context.SP);  Trace.Ln();  Trace.String( "PC " );
+			Trace.Address(exceptionPointers.context.PC);  Trace.Ln();  
+			
+			
+			Trace.Ln();
+
+			
+			eip := exceptionPointers.exception.ExceptionAddress;  ebp := exceptionPointers.context.BP;
+			IF eip = 0 THEN SYSTEM.GET( exceptionPointers.context.SP, eip ) END;
 			stack := StackBottom();
 			LOOP
-				Trace.String( "at ebp= " );  Trace.Hex( ebp, 1 );  Trace.String( "H : " );
+				Trace.String( "at ebp= " );  Trace.Address(ebp);  Trace.String( "H : " );
 				m := Modules.ThisModuleByAdr( eip );
 				IF m # NIL THEN
 					Trace.String( m.name );  Trace.String( " " );
-					Trace.Hex( eip - SYSTEM.VAL( LONGINT, ADDRESSOF( m.code[0] ) ), 1 );
-				ELSE Trace.String( "EIP " );  Trace.Hex( eip, 1 )
+					Trace.Address(eip - SYSTEM.VAL( LONGINT, ADDRESSOF( m.code[0] ) ));
+				ELSE Trace.String( "EIP " );  Trace.Address(eip)
 				END;
 				Trace.Ln();
 				IF (ebp # 0) & (ebp < stack) THEN  (* if ebp is 0 in first frame *)
-					SYSTEM.GET( ebp + 4, eip );   (* return addr from stack *)
+					SYSTEM.GET( ebp + SIZEOF(ADDRESS), eip );   (* return addr from stack *)
 					SYSTEM.GET( ebp, ebp );   (* follow dynamic link *)
 				ELSE EXIT
 				END
 			END;
 			Trace.Ln();
 
-			handled := FALSE;  fp := context.BP;  sp := context.SP;
-			pc := context.PC;  handler := Modules.GetExceptionHandler( pc );
+			(* finally and all that ...
+
+			handled := FALSE;  fp := exceptionPointers.context.BP;  sp := exceptionPointers.context.SP;
+			pc := exceptionPointers.context.PC;  handler := Modules.GetExceptionHandler( pc );
 			IF handler # -1 THEN  (* Handler in the current PAF *)
-				context.PC := handler;  handled := TRUE;
+				exceptionPointers.context.PC := handler;  handled := TRUE;
 				(*SetTrapVariable(pc, fp);  SetLastExceptionState(exc)*)
 			ELSE
 				WHILE (fp # 0) & (handler = -1) DO
-					SYSTEM.GET( fp + 4, pc );
+					SYSTEM.GET( fp + SIZEOF(ADDRESS), pc );
 					pc := pc - 1;   (*  CALL instruction, machine dependant!!! *)
 					handler := Modules.GetExceptionHandler( pc );
 					sp := fp;   (* Save the old framepointer into the stack pointer *)
@@ -579,33 +596,41 @@ BEGIN
 				END;
 				IF handler = -1 THEN handled := FALSE;
 				ELSE
-					context.PC := handler;  context.BP := fp;  context.SP := sp;
+					TRACE("CHANGED HANDLER ADR "); 
+					exceptionPointers.context.PC := handler;  exceptionPointers.context.BP := fp;  exceptionPointers.context.SP := sp;
 					(* SetTrapVariable(pc, fp); SetLastExceptionState(exc);*)
 					handled := TRUE
 				END
 			END;
+			
+			*)
+			
+			
 		ELSE Trace.StringLn ( "Warning: FINALLY statement cannot be treated !" );
 		END
-	ELSE exceptionhandler( context, excpRec, handled );
+	ELSE RETURN exceptionhandler(exceptionPointers);
 	END;
-	IF ~handled THEN
-		context.PC := t.restartPC;  context.SP := t.restartSP;
-		context.BP := t.stackBottom;
+	TRACE(handled); 
+	IF ~handled THEN 
+		exceptionPointers.context.PC := (*TerminateProc*)  t.restartPC ; 
+		exceptionPointers.context.SP := t.restartSP;
+		exceptionPointers.context.BP := t.stackBottom;
 	ELSIF TraceVerbose THEN Trace.StringLn ( "trying to jump to FINALLY pc..." );
 	END;
 	Kernel32.LeaveCriticalSection( excplock );
 
 	IF TraceVerbose THEN
 		Machine.Acquire (Machine.TraceOutput);
-		Trace.String( "recover process; eip=" );  Trace.Int( context.PC, 10 );
-		Trace.String( "; sp= " );  Trace.Int( context.SP, 10 );  Trace.String( "; ebp= " );
-		Trace.Int( context.BP, 10 ); Trace.Ln;
+		Trace.String( "recover process; pc=" );  Trace.Address( exceptionPointers.context.PC );
+		Trace.String( "; sp= " );  Trace.Address( exceptionPointers.context.SP);  Trace.String( "; bp= " );
+		Trace.Address( exceptionPointers.context.BP); Trace.Ln;
 		Machine.Release (Machine.TraceOutput);
 	END;
 
-	RETURN Kernel32.ExceptionContinueSearch; (* sets thread context and continues where specified in context *)
+	RETURN Kernel32.ExceptionContinueExecution; (* sets thread context and continues where specified in context *)
 END ExcpFrmHandler;
 
+(*
 (* get the currently installed execption frame *)
 (*	PROCEDURE -GetCur 64H, 8BH, 0DH, 0, 0, 0, 0;   (* MOV ECX, FS:[0] *) *)
 (* Better *)
@@ -620,10 +645,12 @@ VAR cur: Kernel32.ExcpFrmPtr;
 BEGIN
 	GetCur;
 	cur := SYSTEM.VAL(Kernel32.ExcpFrmPtr,Machine.GetRCX());
+	TRACE(cur);
 	(* RETURN ECX *)
 	RETURN cur
 END GetCurrent;
-
+*)
+(*
 (* install a new exception frame *)
 (*	PROCEDURE -SetCur 64H, 0A3H, 0, 0, 0, 0;   (* MOV FS:[0], EAX *)*)
 (* Better *)
@@ -635,25 +662,38 @@ END SetCur;
 
 PROCEDURE SetCurrent( cur: Kernel32.ExcpFrmPtr );
 BEGIN
-	Machine.SetRAX(SYSTEM.VAL(LONGINT,cur));
+	TRACE(cur);
+	Machine.SetRAX(cur);
 	 (* EAX := cur *)
-	SetCur
+	CODE{SYSTEM.AMD64}
+		MOV [GS:0], RAX
+	END;
+	TRACE(GetCurrent());
+	(*SetCur*)
 END SetCurrent;
-
+*)
 PROCEDURE RemoveExcpFrm( VAR excpfrm: Kernel32.ExcpFrm );
 VAR this: Kernel32.ExcpFrmPtr;
 BEGIN
+	(*
 	this := GetCurrent();
 	(* ASSERT ( this = ADDRESSOF( excpfrm ) );  *)
 	IF this # ADDRESSOF( excpfrm ) THEN Trace.StringLn ( "RemoveExcpFrm: Problem with excpfrm pointer" );
 	ELSE SetCurrent( excpfrm.link )
 	END;
+	*)
+	(*
+	Kernel32.RemoveVectoredExceptionHandler(ExcpFrmHandler);
+	*)
 END RemoveExcpFrm;
 
 PROCEDURE InstallExcpFrm( VAR excpfrm: Kernel32.ExcpFrm );
 BEGIN
+	Kernel32.AddVectoredContinueHandler(1, ExcpFrmHandler); 
+	(*
 	excpfrm.link := GetCurrent();  excpfrm.handler := ExcpFrmHandler;
 	SetCurrent( ADDRESSOF( excpfrm ) )
+	*)
 END InstallExcpFrm;
 
 PROCEDURE InQueue( queue: ProcessQueue;  t: Process ): BOOLEAN;
@@ -694,6 +734,7 @@ END WriteType;
 PROCEDURE terminate( t: Process );
 VAR hdr {UNTRACED}: Heaps.ProtRecBlock; res: Kernel32.BOOL; shutdown: BOOLEAN;
 BEGIN
+	TRACE("terminate"); 
 	IF t = NIL THEN RETURN END;
 	(* see Objects.TerminateThis *)
 	Machine.Acquire( Machine.Objects );
@@ -742,21 +783,21 @@ BEGIN
 	res := Kernel32.TlsSetValue(tlsIndex, SYSTEM.VAL(LONGINT, lpParameter));
 	t := lpParameter(Process);  obj := t.obj;
 	ASSERT(res # 0);
-	InstallExcpFrm(excpfrm);
+
 	SetPriority(t.priority);
 
 	bp := Machine.CurrentBP();
 	sp := Machine.CurrentSP();
 	t.restartSP := sp;
 	t.stackBottom := bp;
-	IF t.restartPC = SYSTEM.VAL(ADDRESS, terminateProc) THEN DEC(t.restartSP, 4)
-	ELSE DEC(t.restartSP, 8)
+	IF t.restartPC = SYSTEM.VAL(ADDRESS, terminateProc) THEN DEC(t.restartSP, SIZEOF(ADDRESS))
+	ELSE DEC(t.restartSP, 2*SIZEOF(ADDRESS))
 	END;
 	IF TraceVerbose THEN
 		Machine.Acquire(Machine.TraceOutput);
-		Trace.String("New process; restartPC= "); Trace.Int(t.restartPC, 15);
-		Trace.String("; restartSP= "); Trace.Int(t.restartSP, 15); Trace.String("; stackBottom= ");
-		Trace.Int(t.stackBottom, 15); Trace.Ln;
+		Trace.String("New process; restartPC= "); Trace.Address(t.restartPC);
+		Trace.String("; stackBottom= ");
+		Trace.Address(t.stackBottom); Trace.Ln;
 		Machine.Release(Machine.TraceOutput);
 	END;
 	t.mode := Running;
@@ -809,6 +850,7 @@ END FinalizeProcess;
 
 PROCEDURE TerminateProc;
 BEGIN
+	TRACE("TerminateProc");
 	terminate(CurrentProcess());
 	Kernel32.ExitThread(0);
 	Kernel32.Sleep(999999);   (* wait until dependent threads terminated *)
@@ -842,6 +884,8 @@ BEGIN
 		t.restartPC := SYSTEM.VAL(ADDRESS, terminateProc);
 	END;
 	
+
+		(* t.restartPC := SYSTEM.VAL(ADDRESS, terminateProc);*) 
 	
 	t.handle := Kernel32.CreateThread(0, defaultStackSize, Wrapper, t, {}, t.id);
 
@@ -1064,7 +1108,7 @@ END Await;
 				ELSE
 					retBOOL := Kernel32.SuspendThread( t.handle );
 				END;
-				t.state.ContextFlags := Kernel32.ContextControl;
+				t.state.ContextFlags := SYSTEM.VAL(LONGINT, Kernel32.ContextControl);
 				retBOOL := Kernel32.GetThreadContext( t.handle, t.state );
 				mod := Modules.ThisModuleByAdr( t.state.PC );  Trace.String( "Objects Break at adr: " );
 				Trace.Int( t.state.PC, 5 );  Trace.Ln;
@@ -1119,6 +1163,8 @@ PROCEDURE Init;   (* can not use NEW *)
 VAR t: Process;  fn: Heaps.FinalizerNode;  proc: Kernel32.HANDLE;
 	res: Kernel32.BOOL;
 BEGIN
+	Kernel32.AddVectoredExceptionHandler(1, ExcpFrmHandler); 
+
 	Kernel32.InitializeCriticalSection(excplock);
 	numberOfProcessors := Machine.NumberOfProcessors();
 (*	lock := Lock; unlock := Unlock; await := Await; create := CreateProcess;*)