public static unsafe void Throw(FOS_System.Exception ex) { Kernel.FOS_System.GC.IncrementRefCount(ex); //BasicConsole.WriteLine("Exception thrown:"); //BasicConsole.WriteLine(ex.Message); if (State->CurrentHandlerPtr->Ex != null) { //GC ref count remains consistent because the Ex pointer below is going to be replaced but // same pointer stored in InnerException. // Result is ref count goes: +1 here, -1 below ex.InnerException = (Kernel.FOS_System.Exception)Utilities.ObjectUtilities.GetObject(State->CurrentHandlerPtr->Ex); } if (ex.InstructionAddress == 0) { ex.InstructionAddress = *((uint *)BasePointer + 1); } State->CurrentHandlerPtr->Ex = Utilities.ObjectUtilities.GetHandle(ex); State->CurrentHandlerPtr->ExPending = 1; HandleException(); // We never expect to get here... HaltReason = "HandleException returned!"; BasicConsole.WriteLine(HaltReason); // Try to cause fault *((byte *)0x800000000) = 0; }
/// <summary> /// Throws a stack exception. /// </summary> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_StackException() { HaltReason = "Stack exception."; BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.StackException()); }
/// <summary> /// Throws an invalid op code exception. /// </summary> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_InvalidOpCodeException() { HaltReason = "Invalid op code exception."; BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.InvalidOpCodeException()); }
/// <summary> /// Throws an overflow exception. /// </summary> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_OverflowException() { HaltReason = "Overflow exception."; BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.OverflowException("Processor reported an overflow.")); }
/// <summary> /// Throws a divide by zero exception storing the specified exception address. /// </summary> /// <param name="address">The address of the code that caused the exception.</param> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_DivideByZeroException(uint address) { HaltReason = "Divide by zero exception."; BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.DivideByZeroException(address)); }
public static unsafe void HandleException() { //BasicConsole.WriteLine("Handle exception"); if (State != null) { if (State->CurrentHandlerPtr != null) { if (State->CurrentHandlerPtr->InHandler != 0) { State->CurrentHandlerPtr->InHandler = 0; if (State->CurrentHandlerPtr->PrevHandlerPtr != null) { State->CurrentHandlerPtr->PrevHandlerPtr->Ex = State->CurrentHandlerPtr->Ex; State->CurrentHandlerPtr->PrevHandlerPtr->ExPending = State->CurrentHandlerPtr->ExPending; } State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; State->depth--; State->history[State->history_pos++] = (uint)State->CurrentHandlerPtr->HandlerAddress; if (State->history_pos > 31) { State->history_pos = 0; } } } ExceptionHandlerInfo *CurrHandlerPtr = State->CurrentHandlerPtr; if (CurrHandlerPtr != null) { if ((uint)CurrHandlerPtr->HandlerAddress != 0x00000000u) { if ((uint)CurrHandlerPtr->FilterAddress != 0x00000000u) { //Catch handler CurrHandlerPtr->ExPending = 0; } CurrHandlerPtr->InHandler = 1; ArbitaryReturn(CurrHandlerPtr->EBP, CurrHandlerPtr->ESP, CurrHandlerPtr->HandlerAddress); } } } // If we get to here, it's an unhandled exception HaltReason = "Unhandled / improperly handled exception!"; BasicConsole.WriteLine(HaltReason); // Try to cause fault *((byte *)0x800000000) = 0; }
public static void Throw_NullReferenceException(uint address) { HaltReason = "Null reference exception. Instruction: 0x "; FillString(address, 48, HaltReason); bool BCPOEnabled = BasicConsole.PrimaryOutputEnabled; BasicConsole.PrimaryOutputEnabled = true; BasicConsole.WriteLine(HaltReason); BasicConsole.DelayOutput(10); BasicConsole.PrimaryOutputEnabled = BCPOEnabled; FOS_System.Exception ex = new FOS_System.Exceptions.NullReferenceException(); ex.InstructionAddress = address; Throw(ex); }
public static void PrintStackTrace() { uint *EBP = (uint *)BasePointer; while ((uint)EBP % 4096 != 0) { FOS_System.String msg = "EBP: 0x , Return Address: 0x , Prev EBP: 0x "; //EBP: 14 //Return address: 42 //Prev EBP: 64 uint ReturnAddress = *(EBP + 1); uint PrevEBP = *(EBP); FillString((uint)EBP, 14, msg); FillString(ReturnAddress, 42, msg); FillString(PrevEBP, 64, msg); BasicConsole.WriteLine(msg); EBP = (uint *)PrevEBP; } }
static unsafe void Main() { ExceptionMethods.AddExceptionHandlerInfo(null, null); try { Hardware.IO.Serial.Serial.InitCOM1(); Hardware.IO.Serial.Serial.InitCOM2(); Hardware.IO.Serial.Serial.InitCOM3(); BasicConsole.SecondaryOutput = BasicConsole_SecondaryOutput; BasicConsole.SecondaryOutputEnabled = true; Hardware.Devices.CPU.InitDefault(); BasicConsole.WriteLine("Creating kernel process..."); Process KernelProcess = ProcessManager.CreateProcess(Tasks.KernelTask.Main, "Kernel Task", false); KernelProcess.TheMemoryLayout.NoUnload = true; ProcessManager.KernelProcess = KernelProcess; BasicConsole.WriteLine("Getting kernel thread..."); Thread KernelThread = ((Thread)KernelProcess.Threads[0]); BasicConsole.WriteLine("Initialising kernel thread stack..."); Hardware.VirtMemManager.Unmap(KernelThread.State->ThreadStackTop - 4092); KernelProcess.TheMemoryLayout.RemovePage((uint)KernelThread.State->ThreadStackTop - 4092); KernelThread.State->ThreadStackTop = GetKernelStackPtr(); KernelThread.State->ESP = (uint)KernelThread.State->ThreadStackTop; BasicConsole.WriteLine("Initialising kernel process heap..."); KernelProcess.HeapLock = Heap.AccessLock; KernelProcess.HeapPtr = Heap.FBlock; BasicConsole.WriteLine("Initialising kernel process GC..."); KernelProcess.TheGCState = FOS_System.GC.State; BasicConsole.WriteLine("Registering kernel process..."); ProcessManager.RegisterProcess(KernelProcess, Scheduler.Priority.Normal); BasicConsole.WriteLine("Initialising kernel ISRs..."); KernelProcess.ISRHandler = Tasks.KernelTask.HandleISR; KernelProcess.SwitchProcessForISRs = false; KernelProcess.ISRsToHandle.Set(48); BasicConsole.WriteLine("Initialising kernel IRQs..."); KernelProcess.IRQHandler = Tasks.KernelTask.HandleIRQ; KernelProcess.SwitchProcessForIRQs = false; KernelProcess.IRQsToHandle.Set(0); BasicConsole.WriteLine("Initialising default timer..."); Hardware.Devices.Timer.InitDefault(); BasicConsole.PrimaryOutputEnabled = true; BasicConsole.SecondaryOutputEnabled = false; BasicConsole.WriteLine(); BasicConsole.WriteLine(); BasicConsole.WriteLine(TextSplashScreen); BasicConsole.SecondaryOutputEnabled = true; BasicConsole.PrimaryOutputEnabled = false; for (int i = 0; i < TextSplashScreen.length; i += 80) { TextSplashScreen[i] = '\n'; } BasicConsole.WriteLine(TextSplashScreen); BasicConsole.PrimaryOutputEnabled = true; BasicConsole.SecondaryOutputEnabled = true; for (int i = 0; i < 37; i++) { BasicConsole.Write(' '); } char num = '1'; for (int i = 0; i < 3; i++) { BasicConsole.Write(num++); Hardware.Devices.Timer.Default.Wait(1000); BasicConsole.Write(' '); } BasicConsole.WriteLine(); BasicConsole.WriteLine("FlingOS(TM)"); BasicConsole.WriteLine("Copyright (C) 2014-15 Edward Nutting"); BasicConsole.WriteLine("This program comes with ABSOLUTELY NO WARRANTY;."); BasicConsole.WriteLine("This is free software, and you are welcome to redistribute it"); BasicConsole.WriteLine("under certain conditions; See GPL V2 for details, a copy of"); BasicConsole.WriteLine("which should have been provided with the executable."); BasicConsole.WriteLine("Fling OS Running..."); BasicConsole.WriteLine(); #if MIPS BasicConsole.WriteLine("MIPS Kernel"); #elif x86 || AnyCPU BasicConsole.WriteLine("x86 Kernel"); #endif BasicConsole.WriteLine(); //uint bpm = 140; //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.C4, // Hardware.Timers.PIT.MusicalNoteValue.Quaver, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.Silent, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.E4, // Hardware.Timers.PIT.MusicalNoteValue.Quaver, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.Silent, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.G4, // Hardware.Timers.PIT.MusicalNoteValue.Quaver, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.Silent, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.C5, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.Silent, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.G4, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); //Hardware.Timers.PIT.ThePIT.PlayNote( // Hardware.Timers.PIT.MusicalNote.C5, // Hardware.Timers.PIT.MusicalNoteValue.Minim, // bpm); BasicConsole.WriteLine("Initialising scheduler..."); Scheduler.Init(); // Busy wait until the scheduler interrupts us. while (true) { ; } // We will never return to this point since there is no way for the scheduler to point // to it. } catch { BasicConsole.SetTextColour(BasicConsole.error_colour); if (ExceptionMethods.CurrentException is FOS_System.Exceptions.PageFaultException) { BasicConsole.WriteLine("Page fault exception unhandled!"); } else { BasicConsole.WriteLine("Startup error! " + ExceptionMethods.CurrentException.Message); } BasicConsole.WriteLine("FlingOS forced to halt!"); BasicConsole.SetTextColour(BasicConsole.default_colour); } BasicConsole.WriteLine("Fling OS Ended."); //Necessary - no way of returning from this method since add exception info // at start cannot be "undone" so stack is "corrupted" if we try // to "ret" //So we just halt the CPU for want of a better solution later when ACPI is //implemented. ExceptionMethods.HaltReason = "End of Main"; Halt(0xFFFFFFFF); //TODO: Proper shutdown method }
static Kernel() { BasicConsole.Init(); BasicConsole.Clear(); }
public static void Halt(uint lastAddress) { BasicConsole.PrimaryOutputEnabled = true; try { Hardware.Devices.Keyboard.CleanDefault(); Hardware.Devices.Timer.CleanDefault(); } catch { } BasicConsole.SetTextColour(BasicConsole.warning_colour); BasicConsole.Write("Halt Reason: "); BasicConsole.WriteLine(ExceptionMethods.HaltReason); FOS_System.String LastAddressStr = "Last address: 0x "; uint y = lastAddress; int offset = 23; #region Address while (offset > 15) { uint rem = y & 0xFu; switch (rem) { case 0: LastAddressStr[offset] = '0'; break; case 1: LastAddressStr[offset] = '1'; break; case 2: LastAddressStr[offset] = '2'; break; case 3: LastAddressStr[offset] = '3'; break; case 4: LastAddressStr[offset] = '4'; break; case 5: LastAddressStr[offset] = '5'; break; case 6: LastAddressStr[offset] = '6'; break; case 7: LastAddressStr[offset] = '7'; break; case 8: LastAddressStr[offset] = '8'; break; case 9: LastAddressStr[offset] = '9'; break; case 10: LastAddressStr[offset] = 'A'; break; case 11: LastAddressStr[offset] = 'B'; break; case 12: LastAddressStr[offset] = 'C'; break; case 13: LastAddressStr[offset] = 'D'; break; case 14: LastAddressStr[offset] = 'E'; break; case 15: LastAddressStr[offset] = 'F'; break; } y >>= 4; offset--; } #endregion BasicConsole.WriteLine(LastAddressStr); BasicConsole.SetTextColour(BasicConsole.default_colour); if (ExceptionMethods.CurrentException != null) { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(ExceptionMethods.CurrentException.Message); if (ExceptionMethods.CurrentException is FOS_System.Exceptions.PageFaultException) { BasicConsole.Write("Address: "); BasicConsole.WriteLine(((FOS_System.Exceptions.PageFaultException)ExceptionMethods.CurrentException).address); BasicConsole.Write("Code: "); BasicConsole.WriteLine(((FOS_System.Exceptions.PageFaultException)ExceptionMethods.CurrentException).errorCode); } else if (ExceptionMethods.CurrentException is FOS_System.Exceptions.DoubleFaultException) { BasicConsole.Write("Code: "); BasicConsole.WriteLine(((FOS_System.Exceptions.DoubleFaultException)ExceptionMethods.CurrentException).ErrorCode); } BasicConsole.SetTextColour(BasicConsole.default_colour); } BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("Kernel halting!"); BasicConsole.SetTextColour(BasicConsole.default_colour); PreReqs.Reset(); }
public static unsafe void AddExceptionHandlerInfo( void *handlerPtr, void *filterPtr) { if (State == null) { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("Error! ExceptionMethods.State is null."); BasicConsole.DelayOutput(10); BasicConsole.SetTextColour(BasicConsole.default_colour); } State->depth++; //if (filterPtr != null) //{ // BasicConsole.WriteLine("Enter try-catch block"); //} //else //{ // BasicConsole.WriteLine("Enter try-finally block"); //} AddExceptionHandlerInfo_EntryStackState *BasePtr = (AddExceptionHandlerInfo_EntryStackState *)BasePointer; uint LocalsSize = (uint)BasePtr - (uint)StackPointer; // Create space for setting up handler info StackPointer -= sizeof(ExceptionHandlerInfo); // Setup handler info ExceptionHandlerInfo *ExHndlrPtr = (ExceptionHandlerInfo *)StackPointer; ExHndlrPtr->EBP = BasePtr->EBP; // EBP + 8 (for ret addr, ebp) + 8 (for args) - sizeof(ExceptionHandlerInfo) ExHndlrPtr->ESP = (uint)BasePtr + 8 + 8 - (uint)sizeof(ExceptionHandlerInfo); ExHndlrPtr->FilterAddress = (byte *)filterPtr; ExHndlrPtr->HandlerAddress = (byte *)handlerPtr; ExHndlrPtr->PrevHandlerPtr = State->CurrentHandlerPtr; ExHndlrPtr->InHandler = 0; ExHndlrPtr->ExPending = 0; ExHndlrPtr->Ex = null; State->CurrentHandlerPtr = (ExceptionHandlerInfo *)((byte *)ExHndlrPtr + (LocalsSize + 12)); StackPointer -= 8; // For duplicate (empty) args StackPointer -= 8; // For duplicate ebp, ret addr // Setup the duplicate stack data // - Nothing to do for args - duplicate values don't matter // - Copy over ebp and return address uint *DuplicateValsStackPointer = (uint *)StackPointer; *DuplicateValsStackPointer = BasePtr->EBP; *(DuplicateValsStackPointer + 1) = BasePtr->RetAddr; ShiftStack((byte *)ExHndlrPtr + sizeof(ExceptionHandlerInfo) - 4, LocalsSize + 12); // Shift stack pointer to correct position - eliminates "empty space" of duplicates StackPointer += 16; // MethodEnd will: // - Add size of locals to esp // - Pop EBP // - Ret to ret address // Caller will: // - Add size of args to esp // Which should leave the stack at the bottom of the (shifted up) ex handler info }
/// <summary> /// Throws a page fault exception. /// </summary> /// <param name="errorCode">The error code associated with the page fault.</param> /// <param name="address">The address which caused the fault.</param> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_PageFaultException(uint eip, uint errorCode, uint address) { if (ThePageFaultHandler != null) { ThePageFaultHandler(eip, errorCode, address); } else { BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine("Page fault exception!"); BasicConsole.DelayOutput(10); HaltReason = "Page fault exception. Address: 0x , errorCode: 0x , eip: 0x "; uint y = address; int offset = 40; #region Address while (offset > 32) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion y = errorCode; offset = 63; #region Error Code while (offset > 55) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion y = eip; offset = 80; #region EIP while (offset > 72) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.PageFaultException(errorCode, address)); } }
/// <summary> /// Throws a double fault exception. /// </summary> /// <remarks> /// Used by CPU interrupts to handle the creation of the exception object and calling Throw. /// </remarks> public static void Throw_DoubleFaultException(uint address, uint errorCode) { HaltReason = "Double fault exception. Address: 0x Error code: 0x "; uint y = address; int offset = 42; #region Address while (offset > 34) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion y = errorCode; offset = 65; #region Error Code while (offset > 57) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion BasicConsole.SetTextColour(BasicConsole.error_colour); BasicConsole.WriteLine(HaltReason); BasicConsole.SetTextColour(BasicConsole.default_colour); Throw(new FOS_System.Exceptions.DoubleFaultException(errorCode)); }
public static unsafe void HandleEndFinally() { if (State == null || State->CurrentHandlerPtr == null) { // If we get to here, it's an unhandled exception if (State == null) { HaltReason = "Cannot end finally in null state!"; } else if (State->CurrentHandlerPtr == null) { HaltReason = "Cannot end finally on null handler!"; } else { HaltReason = "Cannot end finally for unexpected reason!"; } BasicConsole.WriteLine(HaltReason); BasicConsole.DelayOutput(5); // Try to cause fault *((byte *)0x800000000) = 0; } // Leaving a "finally" critical section cleanly // We need to handle 2 cases: // Case 1 : Pending exception // Case 2 : No pending exception //BasicConsole.WriteLine("Handle end finally"); if (State->CurrentHandlerPtr->ExPending != 0) { // Case 1 : Pending exception HandleException(); } else { // Case 2 : No pending exception State->CurrentHandlerPtr->InHandler = 0; uint EBP = State->CurrentHandlerPtr->EBP; uint ESP = State->CurrentHandlerPtr->ESP; byte *retAddr = State->CurrentHandlerPtr->HandlerAddress;//(byte*)*((uint*)(BasePointer + 4)); //BasicConsole.Write("Continue ptr (from HandlerAddress): "); //BasicConsole.WriteLine((uint)State->CurrentHandlerPtr->HandlerAddress); //BasicConsole.Write("Actual continue addr (from EBP): "); //BasicConsole.WriteLine(*((uint*)(BasePointer + 4))); State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; State->depth--; State->history[State->history_pos++] = (uint)State->CurrentHandlerPtr->HandlerAddress; if (State->history_pos > 31) { State->history_pos = 0; } ArbitaryReturn(EBP, ESP + (uint)sizeof(ExceptionHandlerInfo), retAddr); } }
public static unsafe void HandleLeave(void *continuePtr) { if (State == null || State->CurrentHandlerPtr == null) { // If we get to here, it's an unhandled exception HaltReason = ""; if (State == null) { HaltReason = "Cannot leave on null handler! Address: 0x - Null state"; } else if (State->CurrentHandlerPtr == null) { HaltReason = "Cannot leave on null handler! Address: 0x - Null handler"; } else { HaltReason = "Cannot leave on null handler! Address: 0x - Unexpected reason"; } uint y = *((uint *)(BasePointer + 4)); int offset = 48; #region Address while (offset > 40) { uint rem = y & 0xFu; switch (rem) { case 0: HaltReason[offset] = '0'; break; case 1: HaltReason[offset] = '1'; break; case 2: HaltReason[offset] = '2'; break; case 3: HaltReason[offset] = '3'; break; case 4: HaltReason[offset] = '4'; break; case 5: HaltReason[offset] = '5'; break; case 6: HaltReason[offset] = '6'; break; case 7: HaltReason[offset] = '7'; break; case 8: HaltReason[offset] = '8'; break; case 9: HaltReason[offset] = '9'; break; case 10: HaltReason[offset] = 'A'; break; case 11: HaltReason[offset] = 'B'; break; case 12: HaltReason[offset] = 'C'; break; case 13: HaltReason[offset] = 'D'; break; case 14: HaltReason[offset] = 'E'; break; case 15: HaltReason[offset] = 'F'; break; } y >>= 4; offset--; } #endregion BasicConsole.WriteLine(HaltReason); if (State != null) { if (State->depth > 0) { BasicConsole.WriteLine(" -- Positive depth"); } else if (State->depth == 0) { BasicConsole.WriteLine(" -- Zero depth"); } else if (State->depth < 0) { BasicConsole.WriteLine(" -- Negative depth"); } int pos = State->history_pos; do { BasicConsole.Write(State->history[pos]); BasicConsole.Write(" "); pos--; if (pos == -1) { pos = 31; } }while (pos != State->history_pos); } BasicConsole.DelayOutput(5); // Try to cause fault *((byte *)0x800000000) = 0; } // Leaving a critical section cleanly // We need to handle 2 cases: // Case 1 : Leaving "try" or "catch" of a try-catch // Case 2 : Leaving the "try" of a try-finally if ((uint)State->CurrentHandlerPtr->FilterAddress != 0x0u) { // Case 1 : Leaving "try" or "catch" of a try-catch //BasicConsole.WriteLine("Leave try or catch of try-catch"); if (State->CurrentHandlerPtr->Ex != null) { FOS_System.GC.DecrementRefCount((FOS_System.Object)Utilities.ObjectUtilities.GetObject(State->CurrentHandlerPtr->Ex)); State->CurrentHandlerPtr->Ex = null; } State->CurrentHandlerPtr->InHandler = 0; uint EBP = State->CurrentHandlerPtr->EBP; uint ESP = State->CurrentHandlerPtr->ESP; State->CurrentHandlerPtr = State->CurrentHandlerPtr->PrevHandlerPtr; State->depth--; State->history[State->history_pos++] = (uint)State->CurrentHandlerPtr->HandlerAddress; if (State->history_pos > 31) { State->history_pos = 0; } ArbitaryReturn(EBP, ESP + (uint)sizeof(ExceptionHandlerInfo), (byte *)continuePtr); } else { // Case 2 : Leaving the "try" of a try-finally State->CurrentHandlerPtr->InHandler = 1; byte *handlerAddress = State->CurrentHandlerPtr->HandlerAddress; //BasicConsole.WriteLine("Leave try of try-finally"); //BasicConsole.Write("Handler address: "); //BasicConsole.WriteLine((uint)handlerAddress); //BasicConsole.Write("Continue ptr: "); //BasicConsole.WriteLine((uint)continuePtr); State->CurrentHandlerPtr->HandlerAddress = (byte *)continuePtr; ArbitaryReturn(State->CurrentHandlerPtr->EBP, State->CurrentHandlerPtr->ESP, handlerAddress); } }