Esempio n. 1
0
        public static unsafe void DumpExceptionData(ulong ec, ulong return_rip, ulong return_cs,
                                                    ulong rflags, ulong return_rsp, ulong return_ss, ulong return_rbp,
                                                    libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
        {
            Formatter.WriteLine("Exception information:", Program.arch.DebugOutput);

            DumpRegister("EC    ", ec);
            DumpRegister("RIP   ", return_rip);
            DumpRegister("CS    ", return_cs);
            DumpRegister("RFLAGS", rflags);
            DumpRegister("RSP   ", return_rsp);
            DumpRegister("RBP   ", return_rbp);
            DumpRegister("SS    ", return_ss);
            DumpRegister("REGS  ", (ulong)regs);

            if (regs < (void *)0x1000)
            {
                System.Diagnostics.Debugger.Break();
            }

            DumpRegister("RAX   ", regs->rax);
            DumpRegister("RBX   ", regs->rbx);
            DumpRegister("RCX   ", regs->rcx);
            DumpRegister("RDX   ", regs->rdx);
            DumpRegister("RSI   ", regs->rsi);
            DumpRegister("RDI   ", regs->rdi);
            DumpRegister("R8    ", regs->r8);
            DumpRegister("R9    ", regs->r9);
            DumpRegister("R10   ", regs->r10);
            DumpRegister("R11   ", regs->r11);
            DumpRegister("R12   ", regs->r12);
            DumpRegister("R13   ", regs->r13);
            DumpRegister("R14   ", regs->r14);
            DumpRegister("R15   ", regs->r15);
            DumpRegister("XMM0  ", regs->xmm0);
            DumpRegister("XMM1  ", regs->xmm1);
            DumpRegister("XMM2  ", regs->xmm2);
            DumpRegister("XMM3  ", regs->xmm3);
            DumpRegister("XMM4  ", regs->xmm4);
            DumpRegister("XMM5  ", regs->xmm5);
            DumpRegister("XMM6  ", regs->xmm6);
            DumpRegister("XMM7  ", regs->xmm7);
            DumpRegister("XMM8  ", regs->xmm8);
            DumpRegister("XMM9  ", regs->xmm9);
            DumpRegister("XMM10 ", regs->xmm10);
            DumpRegister("XMM11 ", regs->xmm11);
            DumpRegister("XMM12 ", regs->xmm12);
            DumpRegister("XMM13 ", regs->xmm13);
            DumpRegister("XMM14 ", regs->xmm14);
            DumpRegister("XMM15 ", regs->xmm15);
        }
Esempio n. 2
0
        private static unsafe void gdb_append_reg_string(StringBuilder sb,
                                                         libsupcs.x86_64.Cpu.InterruptRegisters64 *regs,
                                                         ulong *rbp, ulong *rip, uint *rflags, ulong *rsp, int reg_no, bool stop_response)
        {
            if (stop_response)
            {
                sb.Append(reg_no.ToString("x"));
                sb.Append(":");
            }

            // RFLAGS is passed as a 32 bit value
            if (reg_no == 17)
            {
                gdb_append_uint_lsb_value(sb, (uint)*gdb_get_reg_address(regs, rbp, rip, rflags, rsp, reg_no));
            }
            else
            {
                gdb_append_ulong_lsb_value(sb, *gdb_get_reg_address(regs, rbp, rip, rflags, rsp, reg_no));
            }
        }
Esempio n. 3
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();
        }
Esempio n. 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();
        }
Esempio n. 5
0
 public static unsafe void StackeFaultError_12_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("Stack Fault", Program.arch.BootInfoOutput);
     libsupcs.OtherOperations.Halt();
 }
Esempio n. 6
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();
        }
Esempio n. 7
0
 public static unsafe void DefaultHandlerErrorCode(ulong error_code, ulong return_rip, ulong return_cs,
                                                   ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
 {
     Formatter.WriteLine("A default handler with error code was called", Program.arch.DebugOutput);
 }
Esempio n. 8
0
 public static unsafe void BoundCheckError_5_Handler(ulong return_rip, ulong return_cs,
                                                     ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
 {
     Formatter.WriteLine("Bound check error", Program.arch.BootInfoOutput);
     libsupcs.OtherOperations.Halt();
 }
Esempio n. 9
0
        static unsafe void gdb_loop(libsupcs.x86_64.Cpu.InterruptRegisters64 *regs,
                                    ulong *rbp, ulong *rip, uint *rflags, ulong *rsp, int sig_no)
        {
            if (saved_bps == null)
            {
                saved_bps = new Dictionary <ulong, byte[]>(new Program.MyGenericEqualityComparer <ulong>());
            }

#if GDB_DEBUG
            Formatter.Write("gdb_stub: entering main loop, RIP: ", Program.arch.DebugOutput);
            Formatter.Write(*rip, "x", Program.arch.DebugOutput);
            Formatter.WriteLine(Program.arch.DebugOutput);
#endif
            bool cont = true;

            if (bp_to_reset != 0)
            {
#if GDB_DEBUG
                Formatter.Write("gdb_stub: resetting breakpoint at ", Program.arch.DebugOutput);
                Formatter.Write(bp_to_reset, "x", Program.arch.DebugOutput);
                Formatter.WriteLine(Program.arch.DebugOutput);
#endif
                set_bp(bp_to_reset, 1);
                bp_to_reset = 0;
            }
            if (saved_bps.ContainsKey(*rip - 1))
            {
                bp_to_reset = *rip - 1;
#if GDB_DEBUG
                Formatter.Write("gdb_stub: hit breakpoint at ", Program.arch.DebugOutput);
                Formatter.Write(bp_to_reset, "x", Program.arch.DebugOutput);
                Formatter.WriteLine(", temporarily unsetting", Program.arch.DebugOutput);
#endif
                unset_bp(bp_to_reset, 1);

                if (!previous_was_step)
                {
                    *rip = bp_to_reset;
                }
            }

            if (in_stop_command)
            {
                gdb_send_message("T" + sig_no.ToString("x2") + gdb_reg_string(regs, rbp, rip, rflags, rsp, true));
            }

            while (cont)
            {
                string message = gdb_read_message();

#if GDB_DEBUG
                Formatter.WriteLine("gdb_stub: received message: " + message, Program.arch.DebugOutput);
#endif
                if (message == "?")
                {
                    gdb_send_message("T" + sig_no.ToString("x2") + gdb_reg_string(regs, rbp, rip, rflags, rsp, true));
                }
                else if (message.StartsWith("m"))
                {
                    string   rest_msg  = message.Substring(1);
                    string[] msg_parts = rest_msg.Split(new char[] { ',' }, StringSplitOptions.None);

                    ulong addr   = ulong.Parse(msg_parts[0], System.Globalization.NumberStyles.HexNumber);
                    int   length = int.Parse(msg_parts[1], System.Globalization.NumberStyles.HexNumber);

#if GDB_DEBUG
                    Formatter.WriteLine("gdb_stub: memory read at " + addr.ToString("X2") + " (" + length.ToString() + " bytes)", Program.arch.DebugOutput);
#endif

                    StringBuilder ret = new StringBuilder();

                    for (int i = 0; i < length; i++, addr++)
                    {
                        ret.Append(libsupcs.MemoryOperations.PeekU1((UIntPtr)addr).ToString("x2"));
                    }

                    gdb_send_message(ret.ToString());
                }
                else if (message == "g")
                {
                    gdb_send_message(gdb_reg_string(regs, rbp, rip, rflags, rsp, false));
                }
                else if (message.StartsWith("G"))
                {
                    int idx    = 1;
                    int reg_no = 0;

                    while (reg_no < 18)
                    {
                        int length = 8;
                        if (reg_no == 17)
                        {
                            length = 4;
                        }

                        ulong val = 0;
                        for (int i = 0; i < length; i++)
                        {
                            ulong bval = ulong.Parse(message.Substring(idx, 2), System.Globalization.NumberStyles.HexNumber);
                            val |= (bval << (i * 8));
                            idx += 2;
                        }

                        *gdb_get_reg_address(regs, rbp, rip, rflags, rsp, reg_no) = val;

                        reg_no++;
                    }

                    gdb_send_message("OK");
                }
                else if (message.StartsWith("c"))
                {
                    if (message.Length > 1)
                    {
                        ulong cont_addr = ulong.Parse(message.Substring(1), System.Globalization.NumberStyles.HexNumber);
                        *     rip       = cont_addr;
                    }
                    cont              = false;
                    in_stop_command   = true;
                    previous_was_step = false;

                    // TODO: have rflags also be a pointer
                    *rflags &= 0xfffffeff;   // clear trap flag
                    if (interrupts_were_enabled)
                    {
                        *rflags |= 0x200;    // restore IF if it was on previously
                    }
                }
                else if (message.StartsWith("Z"))
                {
                    string   rest_msg  = message.Substring(1);
                    string[] msg_parts = rest_msg.Split(new char[] { ',' });

                    ulong addr = ulong.Parse(msg_parts[1], System.Globalization.NumberStyles.HexNumber);
                    int   kind = int.Parse(msg_parts[2], System.Globalization.NumberStyles.HexNumber);

                    if (msg_parts[0] == "0")
                    {
                        // memory break point
#if GDB_DEBUG
                        Formatter.WriteLine("gdb_stub: memory breakpoint at " + addr.ToString("X2") + " kind " + kind.ToString(), Program.arch.DebugOutput);
#endif

                        set_bp(addr, kind);

                        gdb_send_message("OK");
                    }
                    else
                    {
                        gdb_send_message(string.Empty);
                    }
                }
                else if (message.StartsWith("z"))
                {
                    string   rest_msg  = message.Substring(1);
                    string[] msg_parts = rest_msg.Split(new char[] { ',' });

                    ulong addr = ulong.Parse(msg_parts[1], System.Globalization.NumberStyles.HexNumber);
                    int   kind = int.Parse(msg_parts[2], System.Globalization.NumberStyles.HexNumber);

                    if (msg_parts[0] == "0")
                    {
                        // remove memory break point

#if GDB_DEBUG
                        Formatter.WriteLine("gdb_stub: remove memory breakpoint at " + addr.ToString("X2") + " kind " + kind.ToString(), Program.arch.DebugOutput);
#endif

                        if (bp_to_reset == addr)
                        {
                            bp_to_reset = 0;
                        }

                        if (!saved_bps.ContainsKey(addr))
                        {
#if GDB_DEBUG
                            Formatter.WriteLine("gdb_stub: memory breakpoint not found", Program.arch.DebugOutput);
#endif
                            gdb_send_message(string.Empty);
                        }
                        else
                        {
                            for (int i = 0; i < kind; i++)
                            {
                                libsupcs.MemoryOperations.Poke((UIntPtr)(addr + (ulong)i), saved_bps[addr][i]);
                            }
                            gdb_send_message("OK");

                            saved_bps.Remove(addr);
                        }
                    }
                    else
                    {
                        gdb_send_message(string.Empty);
                    }
                }
                else if (message.StartsWith("s"))
                {
                    if (message.Length > 1)
                    {
                        ulong cont_addr = ulong.Parse(message.Substring(1), System.Globalization.NumberStyles.HexNumber);
                        *     rip       = cont_addr;
                    }
                    cont            = false;
                    in_stop_command = true;

                    unsafe
                    {
                        *rflags |= 0x100;        // set trap flag

                        if (!previous_was_step)
                        {
                            if ((*rflags & 0x200) == 0x200)
                            {
                                interrupts_were_enabled = true;
                            }
                            else
                            {
                                interrupts_were_enabled = false;
                            }
                        }

                        *rflags &= 0xfffffdff;   // clear interrupt flag
                    }

                    previous_was_step = true;
                }
                else if (message.StartsWith("qSupported"))
                {
                    // report that we support the qXfer:symbol_from_address:read packet
                    gdb_send_message("qXfer:symbol_from_address:read+");
                }
                else if (message.StartsWith("qXfer:symbol_from_address:read"))
                {
                    string addr   = message.Substring("qXfer:symbol_from_address:read:".Length, 16);
                    ulong  u_addr = ulong.Parse(addr, System.Globalization.NumberStyles.HexNumber);
                    if (Program.stab == null)
                    {
                        gdb_send_message("unknown");
                    }
                    else
                    {
                        ulong  offset;
                        string sym = Program.stab.GetSymbolAndOffset(u_addr, out offset);
                        if (offset >= 0x100000)    // arbritrary large value for upper limit of function
                        {
                            gdb_send_message("unknown");
                        }
                        else
                        {
                            gdb_send_message(sym + ";" + offset.ToString("X16"));
                        }
                    }
                }
                else
                {
                    // packet not supported
                    gdb_send_message(string.Empty);
                }
            }
        }
Esempio n. 10
0
        private static unsafe void GDB_BP_handler(ulong return_rip, ulong return_cs,
                                                  ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regsa)
        {
            ulong rbp = libsupcs.x86_64.Cpu.RBP;

            ulong *ret_rbp    = (ulong *)rbp;
            ulong *ret_rip    = (ulong *)(rbp + 8);
            uint * ret_rflags = (uint *)(rbp + 24);
            ulong *ret_rsp    = (ulong *)(rbp + 32);

            gdb_loop(regsa, ret_rbp, ret_rip, ret_rflags, ret_rsp, 5);      // signal 5 is SIGTRAP
        }
Esempio n. 11
0
        private static unsafe ulong *gdb_get_reg_address(libsupcs.x86_64.Cpu.InterruptRegisters64 *regs,
                                                         ulong *rbp, ulong *rip, uint *rflags, ulong *rsp, int reg_no)
        {
            switch (reg_no)
            {
            case 0:
                return(&regs->rax);

            case 1:
                return(&regs->rbx);

            case 2:
                return(&regs->rcx);

            case 3:
                return(&regs->rdx);

            case 4:
                return(&regs->rsi);

            case 5:
                return(&regs->rdi);

            case 6:
                return(rbp);

            case 7:
                return(rsp);

            case 8:
                return(&regs->r8);

            case 9:
                return(&regs->r9);

            case 10:
                return(&regs->r10);

            case 11:
                return(&regs->r11);

            case 12:
                return(&regs->r12);

            case 13:
                return(&regs->r13);

            case 14:
                return(&regs->r14);

            case 15:
                return(&regs->r15);

            case 16:
                return(rip);

            case 17:
                return((ulong *)rflags);

            default:
                throw new Exception("gdb_stub: gdb_get_reg_address: unsupported register number: " + reg_no.ToString());
            }
        }
Esempio n. 12
0
        private static unsafe string gdb_reg_string(libsupcs.x86_64.Cpu.InterruptRegisters64 *regs,
                                                    ulong *rbp, ulong *rip, uint *rflags, ulong *rsp, bool stop_response)
        {
            StringBuilder sb = new StringBuilder();

            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 0, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 1, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 2, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 3, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 4, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 5, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 6, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 7, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 8, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 9, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 10, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 11, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 12, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 13, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 14, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 15, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 16, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }
            gdb_append_reg_string(sb, regs, rbp, rip, rflags, rsp, 17, stop_response);
            if (stop_response)
            {
                sb.Append(";");
            }

            return(sb.ToString());
        }
Esempio n. 13
0
        internal static unsafe void TimerInterrupt(ulong return_rip, ulong return_cs,
                                                   ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
        {
            LApic cur_lapic = ((x86_64.x86_64_cpu)Program.arch.CurrentCpu).CurrentLApic;

            cur_lapic.ticks += cur_lapic._interval;
            cur_lapic.SendEOI();
            if (cur_lapic.callback != null)
            {
                cur_lapic.callback(cur_lapic._interval);
            }
        }
Esempio n. 14
0
        public static unsafe void SpuriousApicInterrupt(ulong return_rip, ulong return_cs,
                                                        ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
        {
            Formatter.WriteLine("Spurious LAPIC interrupt", Program.arch.DebugOutput);

            /* Spurious vector ISR does not generate an EOI */
        }
Esempio n. 15
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();
        }
Esempio n. 16
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];
                }
            }
        }
Esempio n. 17
0
 public static unsafe void BreakPoint_3_Handler(ulong return_rip, ulong return_cs,
                                                ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
 {
     Formatter.WriteLine("Breakpoint", Program.arch.BootInfoOutput);
     DumpExceptionData(0, return_rip, return_cs, rflags, return_rsp, return_ss, *(ulong *)libsupcs.x86_64.Cpu.RBP, regs);
     libsupcs.OtherOperations.Halt();
 }
Esempio n. 18
0
 public static unsafe void DeviceNotPresentError_7_Handler(ulong return_rip, ulong return_cs,
                                                           ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
 {
     Formatter.WriteLine("Device not present error", Program.arch.BootInfoOutput);
     libsupcs.OtherOperations.Halt();
 }
Esempio n. 19
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();
        }
Esempio n. 20
0
 public static unsafe void DefaultHandlerLapic(ulong return_rip, ulong return_cs,
                                               ulong rflags, ulong return_rsp, ulong return_ss, libsupcs.x86_64.Cpu.InterruptRegisters64 *regs)
 {
     Formatter.WriteLine("A default handler which acknowledged the LAPIC was called", Program.arch.DebugOutput);
     ((x86_64.x86_64_cpu)Program.arch.CurrentCpu).CurrentLApic.SendEOI();
 }