Exemple #1
0
        public static unsafe void NMIError_2_Handler(ulong return_rip, ulong return_cs,
                                                     ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regsa)
        {
            Formatter.WriteLine("NMI", Program.arch.BootInfoOutput);
            Formatter.WriteLine("NMI received", Program.arch.DebugOutput);

            // Switch to protected heap and unwind stack
            if (Program.arch.CurrentCpu != null)
            {
                Program.arch.CurrentCpu.UseCpuAlloc = true;
            }
            Unwind.DumpUnwindInfo(((libsupcs.x86_64.Unwinder)Program.arch.GetUnwinder().Init()).UnwindOneWithErrorCode().DoUnwind((UIntPtr)Program.arch.ExitAddress), Program.arch.DebugOutput);
            libsupcs.OtherOperations.Halt();
        }
Exemple #2
0
        public static unsafe void InvalidOpcode_6_Handler(ulong return_rip, ulong return_cs,
                                                          ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
        {
            Formatter.WriteLine("Invalid opcode", Program.arch.BootInfoOutput);

            /* Unwind the stack */
            Formatter.WriteLine("Invalid opcode", Program.arch.DebugOutput);
            Arch.unwinding = true;
            Formatter.WriteLine("Stack trace: ", Program.arch.DebugOutput);

            // Switch to protected heap and unwind stack
            if (Program.arch.CurrentCpu != null)
            {
                Program.arch.CurrentCpu.UseCpuAlloc = true;
            }
            Unwind.DumpUnwindInfo(Program.arch.GetUnwinder().Init().UnwindOne().DoUnwind((UIntPtr)Program.arch.ExitAddress), Program.arch.DebugOutput);
            libsupcs.OtherOperations.Halt();
        }
Exemple #3
0
        public static unsafe void DoubleFault_8_Handler(ulong ec, ulong return_rip, ulong return_cs,
                                                        ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
        {
            Formatter.WriteLine("Double fault", Program.arch.BootInfoOutput);

            DumpExceptionData(ec, return_rip, return_cs, rflags, return_rsp, return_ss,
                              *(ulong *)libsupcs.x86_64.Cpu.RBP, regs);

            Formatter.WriteLine("Stack trace:", Program.arch.DebugOutput);

            // Switch to protected heap and unwind stack
            if (Program.arch.CurrentCpu != null)
            {
                Program.arch.CurrentCpu.UseCpuAlloc = true;
            }
            Unwind.DumpUnwindInfo(Program.arch.GetUnwinder().Init().UnwindOne().DoUnwind((UIntPtr)Program.arch.ExitAddress), Program.arch.DebugOutput);
            libsupcs.OtherOperations.Halt();
        }
Exemple #4
0
        public static unsafe void GeneralProtection_13_Handler(ulong ec, ulong return_rip, ulong return_cs,
                                                               ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
        {
            if (Arch.unwinding)
            {
                Formatter.WriteLine("General protection fault during stack unwinding", Program.arch.DebugOutput);
                libsupcs.OtherOperations.Halt();
            }

            Formatter.WriteLine("General protection error", Program.arch.BootInfoOutput);
            Formatter.WriteLine("General protection error", Program.arch.DebugOutput);

            ulong rbp = libsupcs.x86_64.Cpu.RBP;
            ulong ecode, rip;

            unsafe
            {
                ecode = *(ulong *)(rbp + 8);
                rip   = *(ulong *)(rbp + 16);
            }
            Formatter.Write("Error code: ", Program.arch.DebugOutput);
            Formatter.Write(ecode, Program.arch.DebugOutput);
            Formatter.WriteLine(Program.arch.DebugOutput);
            Formatter.Write("RIP: ", Program.arch.DebugOutput);
            Formatter.Write(rip, "X", Program.arch.DebugOutput);
            Formatter.WriteLine(Program.arch.DebugOutput);

            DumpExceptionData(ec, return_rip, return_cs, rflags, return_rsp, return_ss, *(ulong *)libsupcs.x86_64.Cpu.RBP, regs);

            //libsupcs.x86_64.Cpu.Break();

            Formatter.WriteLine("Stack trace:", Program.arch.DebugOutput);

            // Switch to protected heap and unwind stack

            /*if (Program.arch.CurrentCpu != null)
            *   Program.arch.CurrentCpu.UseCpuAlloc = true;
            *  else
            *   gc.gc.Heap = gc.gc.HeapType.Startup;*/
            Unwind.DumpUnwindInfo(((libsupcs.x86_64.Unwinder)Program.arch.GetUnwinder().Init()).UnwindOneWithErrorCode().DoUnwind((UIntPtr)Program.arch.ExitAddress), Program.arch.DebugOutput);
            libsupcs.OtherOperations.Halt();
        }
Exemple #5
0
        public static unsafe void SIMD_19_Handler(ulong return_rip, ulong return_cs,
                                                  ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
        {
            if (Arch.unwinding)
            {
                libsupcs.OtherOperations.Halt();
            }

            Formatter.WriteLine("SIMD error", Program.arch.BootInfoOutput);
            Formatter.Write("SIMD error, MXCSR: ", Program.arch.DebugOutput);
            Formatter.Write((ulong)libsupcs.x86_64.Cpu.Mxcsr, "X", Program.arch.DebugOutput);
            Formatter.WriteLine(Program.arch.DebugOutput);

            // Switch to protected heap and unwind stack
            if (Program.arch.CurrentCpu != null)
            {
                Program.arch.CurrentCpu.UseCpuAlloc = true;
            }
            Unwind.DumpUnwindInfo(Program.arch.GetUnwinder().Init().UnwindOne().DoUnwind((UIntPtr)Program.arch.ExitAddress), Program.arch.DebugOutput);
            libsupcs.OtherOperations.Halt();
        }
Exemple #6
0
        public unsafe static void PFHandler(ulong error_code, ulong return_rip, ulong return_cs,
                                            ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
        {
            ulong fault_address = libsupcs.x86_64.Cpu.Cr2;

            /*Formatter.Write("PFault: ", Program.arch.DebugOutput);
             * Formatter.Write(fault_address, "X", Program.arch.DebugOutput);
             * Formatter.WriteLine(Program.arch.DebugOutput);*/

            // Adjust the tss segment's ist1 pointer
            if (ist_stack != null)
            {
                cur_ist_idx++;

                if (cur_ist_idx >= 4)
                {
                    Formatter.Write("kernel: Warning, increasing number of page fault virtual stacks being used, fault_address: ", Program.arch.DebugOutput);
                    Formatter.Write(fault_address, "X", Program.arch.DebugOutput);
                    Formatter.WriteLine(Program.arch.DebugOutput);
                }
                if (cur_ist_idx >= ist_stack.Count)
                {
                    /* Catch page faults in this final unwind */
                    if (unwind_fail)
                    {
                        Formatter.WriteLine("kernel: Page fault: stack unwind failed", Program.arch.DebugOutput);
                        libsupcs.OtherOperations.Halt();
                    }
                    unwind_fail = true;

                    Formatter.Write("Page fault.  Address: 0x", Program.arch.DebugOutput);
                    Formatter.Write(fault_address, "X", Program.arch.DebugOutput);

                    Formatter.WriteLine("Page fault handler has run out of virtual stacks!", Program.arch.BootInfoOutput);
                    Formatter.WriteLine("kernel: Page fault handler has run out of virtual stacks!", Program.arch.DebugOutput);
                    Formatter.WriteLine("kernel: Stack dump", Program.arch.DebugOutput);

                    // Switch to protected heap
                    if (Program.arch.CurrentCpu != null)
                    {
                        Program.arch.CurrentCpu.UseCpuAlloc = true;
                    }
                    else
                    {
                        tysos.gc.gc.Heap = gc.gc.HeapType.Startup;
                    }
                    Unwind.DumpUnwindInfo(pf_unwinder.Init().UnwindOne().DoUnwind((UIntPtr)Program.arch.ExitAddress), Program.arch.DebugOutput);
                    libsupcs.OtherOperations.Halt();
                }

                unsafe
                {
                    *(ulong *)(tss_addr + ist1_offset) = ist_stack[cur_ist_idx];
                }
            }

            if (Program.arch.VirtualRegions.heap.contains(fault_address))
            {
                // If the faulting address is in the heap, map a new page
                //Program.arch.VirtMem.map_page(fault_address);
                //Formatter.WriteLine("IN HEAP", Program.arch.DebugOutput);
                do_map(fault_address, error_code);
            }
            else
            {
                //Formatter.WriteLine("NOT IN HEAP", Program.arch.DebugOutput);

                /* Check if it something we can allocate, i.e. stack space or SSE storage space or cpu-specific space */
                Virtual_Regions.Region cur_reg = Program.arch.VirtualRegions.list_start;
                bool success = false;
                while ((cur_reg != null) && !success)
                {
                    if (cur_reg.contains(fault_address))
                    {
                        if ((cur_reg.type == Virtual_Regions.Region.RegionType.SSE_state) ||
                            (cur_reg.type == Virtual_Regions.Region.RegionType.CPU_specific) ||
                            (cur_reg.type == Virtual_Regions.Region.RegionType.IPC) ||
                            cur_reg.type == Virtual_Regions.Region.RegionType.ModuleSection)
                        {
                            //Program.arch.VirtMem.map_page(fault_address);
                            do_map(fault_address, error_code);
                            success = true;
                        }
                        else if (cur_reg.type == Virtual_Regions.Region.RegionType.Stack)
                        {
                            /* Check for stack overflow into the guard page */
                            if (fault_address < (cur_reg.start + cur_reg.stack_protect))
                            {
                                Formatter.Write("Page fault.  Address: 0x", Program.arch.BootInfoOutput);
                                Formatter.Write(fault_address, "X", Program.arch.BootInfoOutput);
                                Formatter.WriteLine(Program.arch.BootInfoOutput);
                                Formatter.WriteLine("Stack overflow!", Program.arch.BootInfoOutput);

                                Formatter.Write("Page fault.  Address: 0x", Program.arch.DebugOutput);
                                Formatter.Write(fault_address, "X", Program.arch.DebugOutput);
                                Formatter.WriteLine(Program.arch.DebugOutput);
                                Formatter.WriteLine("Stack overflow!", Program.arch.DebugOutput);

                                /* Unwind the stack */
                                if (pf_unwinder != null)
                                {
                                    if (Program.arch.CurrentCpu != null)
                                    {
                                        Program.arch.CurrentCpu.UseCpuAlloc = true;
                                    }
                                    else
                                    {
                                        tysos.gc.gc.Heap = gc.gc.HeapType.Startup;
                                    }
                                    Formatter.WriteLine("Stack trace: ", Program.arch.DebugOutput);
                                    pf_unwinder.Init();
                                    Unwind.DumpUnwindInfo(((libsupcs.x86_64.Unwinder)pf_unwinder).UnwindOneWithErrorCode().DoUnwind((UIntPtr)Program.arch.ExitAddress, false),
                                                          Program.arch.DebugOutput);
                                }

                                libsupcs.OtherOperations.Halt();
                            }
                            else
                            {
                                //Program.arch.VirtMem.map_page(fault_address);
                                do_map(fault_address, error_code);
                                success = true;
                            }
                        }
                    }

                    cur_reg = cur_reg.next;
                }

                if (!success)
                {
                    if (Arch.unwinding)
                    {
                        // If we are in the middle of unwinding a previous page fault then
                        //  any new fault is caught when we reach the end of the stack, so we
                        //  should stop.

                        Formatter.Write("Invalid page fault whilst unwinding.  Address: 0x", Program.arch.DebugOutput);
                        Formatter.Write(fault_address, "X", Program.arch.DebugOutput);
                        Formatter.WriteLine(Program.arch.DebugOutput);
                        Formatter.Write("Invalid page fault whilst unwinding.  Address: 0x", Program.arch.BootInfoOutput);
                        Formatter.Write(fault_address, "X", Program.arch.BootInfoOutput);
                        Formatter.WriteLine(Program.arch.BootInfoOutput);

                        libsupcs.OtherOperations.Halt();
                    }

                    Formatter.Write("Page fault.  Address: 0x", Program.arch.BootInfoOutput);
                    Formatter.Write(fault_address, "X", Program.arch.BootInfoOutput);
                    Formatter.WriteLine(Program.arch.BootInfoOutput);
                    Formatter.WriteLine("Address not allowed!", Program.arch.BootInfoOutput);

                    Formatter.Write("Page fault.  Address: 0x", Program.arch.DebugOutput);
                    Formatter.Write(fault_address, "X", Program.arch.DebugOutput);
                    Formatter.WriteLine(" - address not allowed!", Program.arch.DebugOutput);

                    // Extract error code and return eip
                    ulong rbp = libsupcs.x86_64.Cpu.RBP;
                    ulong ec, rip;
                    unsafe
                    {
                        ec  = *(ulong *)(rbp + 8);
                        rip = *(ulong *)(rbp + 16);
                        rbp = *(ulong *)rbp;
                    }
                    Formatter.Write("Error code: ", Program.arch.DebugOutput);
                    Formatter.Write(ec, Program.arch.DebugOutput);
                    Formatter.WriteLine(Program.arch.DebugOutput);
                    Formatter.Write("RIP: ", Program.arch.DebugOutput);
                    Formatter.Write(rip, "X", Program.arch.DebugOutput);
                    Formatter.WriteLine(Program.arch.DebugOutput);

                    tysos.x86_64.Exceptions.DumpExceptionData(error_code, return_rip, return_cs, rflags,
                                                              return_rsp, return_ss, rbp, regs);


                    //Program.arch.VirtualRegions.Dump(Program.arch.DebugOutput);

                    if (pf_unwinder != null)
                    {
                        if (Program.arch.CurrentCpu != null)
                        {
                            Program.arch.CurrentCpu.UseCpuAlloc = true;
                        }
                        else
                        {
                            tysos.gc.gc.Heap = gc.gc.HeapType.Startup;
                        }

                        Arch.unwinding = true;
                        Formatter.WriteLine("Stack trace: ", Program.arch.DebugOutput);
                        pf_unwinder.Init();
                        //Unwind.DumpUnwindInfo(((libsupcs.x86_64.Unwinder)pf_unwinder).UnwindOneWithErrorCode().DoUnwind((UIntPtr)Program.arch.ExitAddress),
                        //    Program.arch.DebugOutput);
                        Unwind.DumpUnwindInfo(pf_unwinder.DoUnwind((UIntPtr)Program.arch.ExitAddress), Program.arch.DebugOutput);
                    }

                    /* Unwind the stack */

                    /*Unwind u2 = new Unwind();
                    *
                    *  DumpIP(u2.UnwindOneWithErrorCode());
                    *  ulong next_rip2;
                    *  do
                    *  {
                    *   next_rip2 = u2.UnwindOne();
                    *   DumpIP(next_rip2);
                    *  } while (next_rip2 != 0);*/

                    libsupcs.OtherOperations.Halt();
                }
            }

            // Restore the tss segment's ist1 pointer
            if (ist_stack != null)
            {
                cur_ist_idx--;

                unsafe
                {
                    *(ulong *)(tss_addr + ist1_offset) = ist_stack[cur_ist_idx];
                }
            }
        }