Beispiel #1
0
        public static void Main()
        {
            // The serial ports should have already been initialised
            MsgPort   = Serial.COM2;
            NotifPort = Serial.COM3;

            // This looks silly, but the host debugger is actually waiting for this
            //  to determine the OS has connected and is ready
            MsgPort.Write("Debug thread :D\n");

            //MsgPort.Write("Enabling...\n");
            // Everything is initialised and connected, so enable the debugger
            Enabled = true;
            //MsgPort.Write("Enabled.\n");

            // Note: It doesn't actually matter if the host hasn't connected
            //  because the debugger has near-zero effective cost to the rest of the system
            //  unless it is sent a command (unlike the old debugger, which slowed everything
            //  down to the point of being unusable).

            while (!Terminating)
            {
                // Read in a line from the host
                FOS_System.String line = "";
                char c = (char)MsgPort.Read();
                while (c != '\n' && c != '\r')
                {
                    line += c;
                    c     = (char)MsgPort.Read();
                }

                // Echo the command back to the host for verification
                MsgPort.Write("START OF COMMAND\n");
                MsgPort.Write(line);
                MsgPort.Write("\n");

                // Filter the line
                line = line.Trim().ToLower();

                // Split it up into relevant parts
                List lineParts = line.Split(' ');
                if (lineParts.Count > 0)
                {
                    FOS_System.String cmd = (FOS_System.String)lineParts[0];

                    if (cmd == "ping")
                    {
                        MsgPort.Write("pong\n");
                    }
                    else if (cmd == "help")
                    {
                        #region Help

                        MsgPort.Write("Available commands:\n");
                        MsgPort.Write(" - ping\n");
                        MsgPort.Write(" - threads\n");
                        MsgPort.Write(" - suspend (processId) (threadId | -1 for all threads)\n");
                        MsgPort.Write(" - resume (processId) (threadId | -1 for all threads)\n");
                        MsgPort.Write(" - step (processId) (threadId | -1 for all threads)\n");
                        MsgPort.Write(" - ss (processId) (threadId | -1 for all threads)\n");
                        MsgPort.Write(" - sta (processId) (threadId | -1 for all threads) (address)\n");
                        MsgPort.Write(" - bps (address:hex)\n");
                        MsgPort.Write(" - bpc (address:hex)\n");
                        MsgPort.Write(" - regs (processId) (threadId)\n");
                        MsgPort.Write(" - memory (processId) (address:hex) (length) (units:1,2,4)\n");

                        #endregion
                    }
                    else if (cmd == "threads")
                    {
                        #region Threads

                        for (int i = 0; i < ProcessManager.Processes.Count; i++)
                        {
                            Process AProcess = (Process)ProcessManager.Processes[i];
                            MsgPort.Write(" - Process : ");
                            MsgPort.Write((FOS_System.String)AProcess.Id);
                            MsgPort.Write(" : ");
                            MsgPort.Write(AProcess.Name);
                            MsgPort.Write(" : ");
                            switch (AProcess.Priority)
                            {
                            case Scheduler.Priority.ZeroTimed:
                                MsgPort.Write("Zero Timed");
                                break;

                            case Scheduler.Priority.Low:
                                MsgPort.Write("Low");
                                break;

                            case Scheduler.Priority.Normal:
                                MsgPort.Write("Normal");
                                break;

                            case Scheduler.Priority.High:
                                MsgPort.Write("High");
                                break;
                            }
                            MsgPort.Write("\n");
                            for (int j = 0; j < AProcess.Threads.Count; j++)
                            {
                                Thread AThread = (Thread)AProcess.Threads[j];

                                MsgPort.Write("      - Thread : ");
                                MsgPort.Write((FOS_System.String)AThread.Id);
                                MsgPort.Write(" : ");

                                switch (AThread.ActiveState)
                                {
                                case Thread.ActiveStates.Active:
                                    MsgPort.Write("Active");
                                    break;

                                case Thread.ActiveStates.Inactive:
                                    MsgPort.Write("Inactive");
                                    break;

                                case Thread.ActiveStates.NotStarted:
                                    MsgPort.Write("Not Started");
                                    break;

                                case Thread.ActiveStates.Suspended:
                                    MsgPort.Write("Suspended");
                                    break;

                                case Thread.ActiveStates.Terminated:
                                    MsgPort.Write("Terminated");
                                    break;
                                }

                                MsgPort.Write(" : ");
                                MsgPort.Write(AThread.Name);
                                MsgPort.Write("\n");
                            }
                        }

                        #endregion
                    }
                    else if (cmd == "suspend")
                    {
                        #region Suspend

                        if (lineParts.Count == 3)
                        {
                            uint ProcessId = FOS_System.Int32.Parse_DecimalUnsigned((FOS_System.String)lineParts[1], 0);
                            int  ThreadId  = FOS_System.Int32.Parse_DecimalSigned((FOS_System.String)lineParts[2]);

                            Process TheProcess = ProcessManager.GetProcessById(ProcessId);

                            if (TheProcess != null)
                            {
                                if (ThreadId == -1)
                                {
                                    for (int i = 0; i < TheProcess.Threads.Count; i++)
                                    {
                                        Thread AThread = ((Thread)TheProcess.Threads[i]);

                                        if (AThread != MainThread)
                                        {
                                            UInt64 ProcessThreadId = (((UInt64)ProcessId) << 32) | AThread.Id;
                                            if (ThreadsToSuspend.IndexOf(ProcessThreadId) == -1)
                                            {
                                                ThreadsToSuspend.Add(ProcessThreadId);
                                            }

                                            AThread.Debug_Suspend = true;

                                            MsgPort.Write(" > Suspended ");
                                            MsgPort.Write(AThread.Name);
                                            MsgPort.Write(" thread\n");
                                        }
                                    }
                                }
                                else
                                {
                                    UInt64 ProcessThreadId = (((UInt64)ProcessId) << 32) | (uint)ThreadId;
                                    if (ThreadsToSuspend.IndexOf(ProcessThreadId) == -1)
                                    {
                                        ThreadsToSuspend.Add(ProcessThreadId);
                                    }

                                    Thread TheThread = ProcessManager.GetThreadById((uint)ThreadId, TheProcess);

                                    if (TheThread != null)
                                    {
                                        if (TheThread != MainThread)
                                        {
                                            TheThread.Debug_Suspend = true;

                                            MsgPort.Write(" > Suspended ");
                                            MsgPort.Write(TheThread.Name);
                                            MsgPort.Write(" thread\n");
                                        }
                                    }
                                    else
                                    {
                                        MsgPort.Write("Thread not found.\n");
                                    }
                                }
                            }
                            else
                            {
                                MsgPort.Write("Process not found.\n");
                            }
                        }
                        else
                        {
                            MsgPort.Write("Incorrect arguments, see help.\n");
                        }

                        #endregion
                    }
                    else if (cmd == "resume")
                    {
                        #region Resume

                        if (lineParts.Count == 3)
                        {
                            uint ProcessId = FOS_System.Int32.Parse_DecimalUnsigned((FOS_System.String)lineParts[1], 0);
                            int  ThreadId  = FOS_System.Int32.Parse_DecimalSigned((FOS_System.String)lineParts[2]);

                            Process TheProcess = ProcessManager.GetProcessById(ProcessId);

                            if (TheProcess != null)
                            {
                                if (ThreadId == -1)
                                {
                                    for (int i = 0; i < TheProcess.Threads.Count; i++)
                                    {
                                        Thread AThread = ((Thread)TheProcess.Threads[i]);

                                        UInt64 ProcessThreadId = (((UInt64)ProcessId) << 32) | AThread.Id;
                                        ThreadsToSuspend.Remove(ProcessThreadId);

                                        AThread.Debug_Suspend = false;

                                        MsgPort.Write(" > Resumed ");
                                        MsgPort.Write(AThread.Name);
                                        MsgPort.Write(" thread\n");
                                    }
                                }
                                else
                                {
                                    UInt64 ProcessThreadId = (((UInt64)ProcessId) << 32) | (uint)ThreadId;
                                    ThreadsToSuspend.Remove(ProcessThreadId);

                                    Thread TheThread = ProcessManager.GetThreadById((uint)ThreadId, TheProcess);

                                    if (TheThread != null)
                                    {
                                        TheThread.Debug_Suspend = false;

                                        MsgPort.Write(" > Resumed ");
                                        MsgPort.Write(TheThread.Name);
                                        MsgPort.Write(" thread\n");
                                    }
                                    else
                                    {
                                        MsgPort.Write("Thread not found.\n");
                                    }
                                }
                            }
                            else
                            {
                                MsgPort.Write("Process not found.\n");
                            }
                        }
                        else
                        {
                            MsgPort.Write("Incorrect arguments, see help.\n");
                        }

                        #endregion
                    }
                    else if (cmd == "step")
                    {
                        #region Step

                        if (lineParts.Count == 3)
                        {
                            uint ProcessId = FOS_System.Int32.Parse_DecimalUnsigned((FOS_System.String)lineParts[1], 0);
                            int  ThreadId  = FOS_System.Int32.Parse_DecimalSigned((FOS_System.String)lineParts[2]);

                            Process TheProcess = ProcessManager.GetProcessById(ProcessId);

                            if (TheProcess != null)
                            {
                                if (ThreadId == -1)
                                {
                                    for (int i = 0; i < TheProcess.Threads.Count; i++)
                                    {
                                        Thread AThread = ((Thread)TheProcess.Threads[i]);

                                        if (AThread.Debug_Suspend)
                                        {
                                            AThread.Debug_Suspend = false;

                                            MsgPort.Write(" > Stepping ");
                                            MsgPort.Write(AThread.Name);
                                            MsgPort.Write(" thread\n");
                                        }
                                        else
                                        {
                                            MsgPort.Write("Thread must be suspended first.\n");
                                        }
                                    }
                                }
                                else
                                {
                                    Thread TheThread = ProcessManager.GetThreadById((uint)ThreadId, TheProcess);

                                    if (TheThread != null)
                                    {
                                        if (TheThread.Debug_Suspend)
                                        {
                                            TheThread.Debug_Suspend = false;

                                            MsgPort.Write(" > Stepping ");
                                            MsgPort.Write(TheThread.Name);
                                            MsgPort.Write(" thread\n");
                                        }
                                        else
                                        {
                                            MsgPort.Write("Thread must be suspended first.\n");
                                        }
                                    }
                                    else
                                    {
                                        MsgPort.Write("Thread not found.\n");
                                    }
                                }
                            }
                            else
                            {
                                MsgPort.Write("Process not found.\n");
                            }
                        }
                        else
                        {
                            MsgPort.Write("Incorrect arguments, see help.\n");
                        }

                        #endregion
                    }
                    else if (cmd == "ss")
                    {
                        #region Single Step

                        if (lineParts.Count == 3)
                        {
                            uint ProcessId = FOS_System.Int32.Parse_DecimalUnsigned((FOS_System.String)lineParts[1], 0);
                            int  ThreadId  = FOS_System.Int32.Parse_DecimalSigned((FOS_System.String)lineParts[2]);

                            Process TheProcess = ProcessManager.GetProcessById(ProcessId);

                            if (TheProcess != null)
                            {
                                if (ThreadId == -1)
                                {
                                    for (int i = 0; i < TheProcess.Threads.Count; i++)
                                    {
                                        Thread AThread = ((Thread)TheProcess.Threads[i]);

                                        if (AThread.Debug_Suspend)
                                        {
                                            // Set trap flag (int1)
                                            AThread.EFLAGSFromInterruptStack |= 0x0100;
                                            AThread.Debug_Suspend             = false;

                                            MsgPort.Write(" > Single stepping ");
                                            MsgPort.Write(AThread.Name);
                                            MsgPort.Write(" thread\n");
                                        }
                                        else
                                        {
                                            MsgPort.Write("Thread must be suspended first.\n");
                                        }
                                    }
                                }
                                else
                                {
                                    Thread TheThread = ProcessManager.GetThreadById((uint)ThreadId, TheProcess);

                                    if (TheThread != null)
                                    {
                                        if (TheThread.Debug_Suspend)
                                        {
                                            // Set trap flag (int1)
                                            TheThread.EFLAGSFromInterruptStack |= 0x0100;
                                            TheThread.Debug_Suspend             = false;

                                            MsgPort.Write(" > Single stepping ");
                                            MsgPort.Write(TheThread.Name);
                                            MsgPort.Write(" thread\n");
                                        }
                                        else
                                        {
                                            MsgPort.Write("Thread must be suspended first.\n");
                                        }
                                    }
                                    else
                                    {
                                        MsgPort.Write("Thread not found.\n");
                                    }
                                }
                            }
                            else
                            {
                                MsgPort.Write("Process not found.\n");
                            }
                        }
                        else
                        {
                            MsgPort.Write("Incorrect arguments, see help.\n");
                        }

                        #endregion
                    }
                    else if (cmd == "sta")
                    {
                        #region Step To Address

                        if (lineParts.Count == 4)
                        {
                            uint ProcessId = FOS_System.Int32.Parse_DecimalUnsigned((FOS_System.String)lineParts[1], 0);
                            int  ThreadId  = FOS_System.Int32.Parse_DecimalSigned((FOS_System.String)lineParts[2]);
                            uint Address   = FOS_System.Int32.Parse_HexadecimalUnsigned((FOS_System.String)lineParts[3], 0);

                            Process TheProcess = ProcessManager.GetProcessById(ProcessId);

                            if (TheProcess != null)
                            {
                                if (ThreadId == -1)
                                {
                                    for (int i = 0; i < TheProcess.Threads.Count; i++)
                                    {
                                        Thread AThread = ((Thread)TheProcess.Threads[i]);

                                        if (AThread.Debug_Suspend)
                                        {
                                            // Set trap flag (int1)
                                            UInt64 ProcessThreadId = (((UInt64)ProcessId) << 32) | (uint)ThreadId;
                                            ThreadsToSuspendAtAddresses.Add(ProcessThreadId, Address);
                                            AThread.EFLAGSFromInterruptStack |= 0x0100;
                                            AThread.Debug_Suspend             = false;

                                            MsgPort.Write(" > Single stepping ");
                                            MsgPort.Write(AThread.Name);
                                            MsgPort.Write(" thread to address ");
                                            MsgPort.Write(Address);
                                            MsgPort.Write("\n");
                                        }
                                        else
                                        {
                                            MsgPort.Write("Thread must be suspended first.\n");
                                        }
                                    }
                                }
                                else
                                {
                                    Thread TheThread = ProcessManager.GetThreadById((uint)ThreadId, TheProcess);

                                    if (TheThread != null)
                                    {
                                        if (TheThread.Debug_Suspend)
                                        {
                                            // Set trap flag (int1)
                                            UInt64 ProcessThreadId = (((UInt64)ProcessId) << 32) | (uint)ThreadId;
                                            ThreadsToSuspendAtAddresses.Add(ProcessThreadId, Address);
                                            TheThread.EFLAGSFromInterruptStack |= 0x0100;
                                            TheThread.Debug_Suspend             = false;

                                            MsgPort.Write(" > Single stepping ");
                                            MsgPort.Write(TheThread.Name);
                                            MsgPort.Write(" thread to address ");
                                            MsgPort.Write(Address);
                                            MsgPort.Write("\n");
                                        }
                                        else
                                        {
                                            MsgPort.Write("Thread must be suspended first.\n");
                                        }
                                    }
                                    else
                                    {
                                        MsgPort.Write("Thread not found.\n");
                                    }
                                }
                            }
                            else
                            {
                                MsgPort.Write("Process not found.\n");
                            }
                        }
                        else
                        {
                            MsgPort.Write("Incorrect arguments, see help.\n");
                        }

                        #endregion
                    }
                    else if (cmd == "bps")
                    {
                        #region Set Breakpoint

                        if (lineParts.Count == 2)
                        {
                            uint Address = FOS_System.Int32.Parse_HexadecimalUnsigned((FOS_System.String)lineParts[1], 0);

                            MsgPort.Write(" > Breakpoint to be set at ");
                            MsgPort.Write(Address);
                            MsgPort.Write("\n");

                            *((byte *)Address) = 0xCC;
                        }
                        else
                        {
                            MsgPort.Write("Incorrect arguments, see help.\n");
                        }

                        #endregion
                    }
                    else if (cmd == "bpc")
                    {
                        #region Clear Breakpoint

                        if (lineParts.Count == 2)
                        {
                            uint Address = FOS_System.Int32.Parse_HexadecimalUnsigned((FOS_System.String)lineParts[1], 0);

                            MsgPort.Write(" > Breakpoint to be cleared at ");
                            MsgPort.Write(Address);
                            MsgPort.Write("\n");

                            *((byte *)Address) = 0x90;
                        }
                        else
                        {
                            MsgPort.Write("Incorrect arguments, see help.\n");
                        }

                        #endregion
                    }
                    else if (cmd == "regs")
                    {
                        #region Registers

                        if (lineParts.Count == 3)
                        {
                            uint ProcessId = FOS_System.Int32.Parse_DecimalUnsigned((FOS_System.String)lineParts[1], 0);
                            uint ThreadId  = FOS_System.Int32.Parse_DecimalUnsigned((FOS_System.String)lineParts[2], 0);

                            Process TheProcess = ProcessManager.GetProcessById(ProcessId);

                            if (TheProcess != null)
                            {
                                Thread TheThread = ProcessManager.GetThreadById((uint)ThreadId, TheProcess);

                                if (TheThread != null)
                                {
                                    if (TheThread.Debug_Suspend)
                                    {
                                        MsgPort.Write("Registers of ");
                                        MsgPort.Write(TheThread.Name);
                                        MsgPort.Write(" : \n");

                                        MsgPort.Write(" > EAX : ");
                                        MsgPort.Write(TheThread.EAXFromInterruptStack);
                                        MsgPort.Write("\n > EBX : ");
                                        MsgPort.Write(TheThread.EBXFromInterruptStack);
                                        MsgPort.Write("\n > ECX : ");
                                        MsgPort.Write(TheThread.ECXFromInterruptStack);
                                        MsgPort.Write("\n > EDX : ");
                                        MsgPort.Write(TheThread.EDXFromInterruptStack);
                                        MsgPort.Write("\n");

                                        MsgPort.Write("\n > ESP : ");
                                        MsgPort.Write(TheThread.ESPFromInterruptStack);
                                        MsgPort.Write("\n > EBP : ");
                                        MsgPort.Write(TheThread.EBPFromInterruptStack);
                                        MsgPort.Write("\n > EIP : ");
                                        MsgPort.Write(TheThread.EIPFromInterruptStack);
                                        MsgPort.Write("\n");
                                    }
                                    else
                                    {
                                        MsgPort.Write("Thread must be suspended first.\n");
                                    }
                                }
                                else
                                {
                                    MsgPort.Write("Thread not found.\n");
                                }
                            }
                            else
                            {
                                MsgPort.Write("Process not found.\n");
                            }
                        }
                        else
                        {
                            MsgPort.Write("Incorrect arguments, see help.\n");
                        }

                        #endregion
                    }
                    else if (cmd == "mem")
                    {
                        #region Memory

                        if (lineParts.Count == 5)
                        {
                            uint ProcessId = FOS_System.Int32.Parse_DecimalUnsigned((FOS_System.String)lineParts[1], 0);

                            Process TheProcess = ProcessManager.GetProcessById(ProcessId);

                            if (TheProcess != null && false)
                            {
                                // Need access to specified process' memory
                                //TODO: Erm... MemoryLayout OriginalMemoryLayout = SystemCallsHelpers.EnableAccessToMemoryOfProcess(TheProcess);

                                uint Address = FOS_System.Int32.Parse_HexadecimalUnsigned((FOS_System.String)lineParts[2], 0);
                                int  length  = FOS_System.Int32.Parse_DecimalSigned((FOS_System.String)lineParts[3]);
                                int  units   = FOS_System.Int32.Parse_DecimalSigned((FOS_System.String)lineParts[4]);

                                MsgPort.Write(" Memory from ");
                                MsgPort.Write(Address);
                                MsgPort.Write(" for ");
                                MsgPort.Write(length);
                                MsgPort.Write(" units with ");
                                MsgPort.Write(units);
                                MsgPort.Write(" bytes/unit:\n");

                                if (units == 1)
                                {
                                    byte *AddrPtr = (byte *)Address;
                                    for (int i = 0; i < length; i++)
                                    {
                                        MsgPort.Write((FOS_System.String)AddrPtr[i]);
                                        MsgPort.Write(" ");
                                    }
                                }
                                else if (units == 2)
                                {
                                    ushort *AddrPtr = (ushort *)Address;
                                    for (int i = 0; i < length; i++)
                                    {
                                        MsgPort.Write((FOS_System.String)AddrPtr[i]);
                                        MsgPort.Write(" ");
                                    }
                                }
                                else if (units == 4)
                                {
                                    uint *AddrPtr = (uint *)Address;
                                    for (int i = 0; i < length; i++)
                                    {
                                        MsgPort.Write((FOS_System.String)AddrPtr[i]);
                                        MsgPort.Write(" ");
                                    }
                                }

                                MsgPort.Write("\n");

                                //TODO: Erm... SystemCallsHelpers.DisableAccessToMemoryOfProcess(OriginalMemoryLayout);
                            }
                            else
                            {
                                MsgPort.Write("Process not found.\n");
                            }
                        }
                        else
                        {
                            MsgPort.Write("Incorrect arguments, see help.\n");
                        }

                        #endregion
                    }
                    else
                    {
                        MsgPort.Write("Unrecognised command. (Note: Backspace not supported!)\n");
                    }
                }

                // Always issue end of command signal, even if something else went wrong
                //  - Keeps the host in sync.
                MsgPort.Write("END OF COMMAND\n");
            }
        }