using System; using System.Linq; using Cosmos.Assembler; using Cosmos.Assembler.x86; namespace Cosmos.Debug.DebugStub { public class CmdSend : Cosmos.Assembler.Code { public CmdSend(Assembler.Assembler aAssembler) : base(aAssembler) {} public override void Assemble() { new Comment("X#: Group DebugStub"); new Comment("X#: procedure SendRegisters {"); new LiteralAssemblerCode("DebugStub_SendRegisters:"); new LiteralAssemblerCode("; Send the actual started signal"); new Comment("X#: AL = #Ds2Vs_Registers"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_Registers"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new Comment("X#: ESI = .PushAllPtr"); new LiteralAssemblerCode("Mov ESI, [DebugStub_PushAllPtr]"); new Comment("X#: ECX = 32"); new LiteralAssemblerCode("Mov ECX, 32"); new Comment("X#: ComWriteX()"); new LiteralAssemblerCode("Call DebugStub_ComWriteX"); new Comment("X#: ESI = @.CallerESP"); new LiteralAssemblerCode("Mov ESI, DebugStub_CallerESP"); new Comment("X#: ComWrite32()"); new LiteralAssemblerCode("Call DebugStub_ComWrite32"); new Comment("X#: ESI = @.CallerEIP"); new LiteralAssemblerCode("Mov ESI, DebugStub_CallerEIP"); new Comment("X#: ComWrite32()"); new LiteralAssemblerCode("Call DebugStub_ComWrite32"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendRegisters_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendFrame2 {"); new LiteralAssemblerCode("DebugStub_SendFrame2:"); new Comment("X#: AL = #Ds2Vs_Frame"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_Frame"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new Comment("X#: EAX = 32"); new LiteralAssemblerCode("Mov EAX, 32"); new Comment("X#: ComWriteAX()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAX"); new Comment("X#: ESI = .CallerEBP"); new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerEBP]"); new LiteralAssemblerCode("; Dont transmit EIP or old EBP"); new Comment("X#: ESI + 8"); new LiteralAssemblerCode("Add ESI, 8"); new Comment("X#: ECX = 32"); new LiteralAssemblerCode("Mov ECX, 32"); new Comment("X#: ComWriteX()"); new LiteralAssemblerCode("Call DebugStub_ComWriteX"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendFrame2_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendStack2 {"); new LiteralAssemblerCode("DebugStub_SendStack2:"); new Comment("X#: AL = #Ds2Vs_Stack"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_Stack"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; Send size of bytes"); new Comment("X#: ESI = .CallerESP"); new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerESP]"); new Comment("X#: EAX = .CallerEBP"); new LiteralAssemblerCode("Mov EAX, [DebugStub_CallerEBP]"); new Comment("X#: EAX - ESI"); new LiteralAssemblerCode("Sub EAX, ESI"); new Comment("X#: ComWriteAX()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAX"); new LiteralAssemblerCode("; Send actual bytes"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; Need to reload ESI, WriteAXToCompPort modifies it"); new Comment("X#: ESI = .CallerESP"); new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerESP]"); new Comment("X#: SendByte:"); new LiteralAssemblerCode("DebugStub_SendStack2_SendByte:"); new LiteralAssemblerCode("; if ESI = CallerEBP exit"); new Comment("X#: ComWrite8()"); new LiteralAssemblerCode("Call DebugStub_ComWrite8"); new Comment("X#: goto SendByte"); new LiteralAssemblerCode("Jp DebugStub_SendStack2_SendByte"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendStack2_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendMethodContext2 {"); new LiteralAssemblerCode("DebugStub_SendMethodContext2:"); new LiteralAssemblerCode("; // sends a stack value"); new LiteralAssemblerCode("; // Serial Params:"); new LiteralAssemblerCode("; // 1: x32 - offset relative to EBP"); new LiteralAssemblerCode("; // 2: x32 - size of data to send"); new LiteralAssemblerCode("; [XSharp(PreserveStack = true)]"); new LiteralAssemblerCode("; AL = Ds2Vs_MethodContext"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; // offset relative to ebp"); new LiteralAssemblerCode("; // size of data to send"); new LiteralAssemblerCode("; Call(\"DebugStub_ComReadEAX()"); new LiteralAssemblerCode("; ECX = EAX"); new LiteralAssemblerCode("; Call(\"DebugStub_ComReadEAX()"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; // now ECX contains size of data (count)"); new LiteralAssemblerCode("; // EAX contains relative to EBP"); new LiteralAssemblerCode("; ESI = CallerEBP.Value"); new LiteralAssemblerCode("; ESI.Add(EAX) //TODO: ESI = ESI + EAX"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; Label = \".SendByte\""); new LiteralAssemblerCode("; ECX.Compare(0)"); new LiteralAssemblerCode("; JumpIf(Flags.Equal, \".AfterSendByte\")"); new Comment("X#: ComWrite8()"); new LiteralAssemblerCode("Call DebugStub_ComWrite8"); new LiteralAssemblerCode("; ECX--"); new LiteralAssemblerCode("; Jump(\".SendByte\")"); new LiteralAssemblerCode("; Label = \".AfterSendByte\""); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendMethodContext2_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendMemory2 {"); new LiteralAssemblerCode("DebugStub_SendMemory2:"); new LiteralAssemblerCode("; // sends a stack value"); new LiteralAssemblerCode("; // Serial Params:"); new LiteralAssemblerCode("; // 1: x32 - offset relative to EBP"); new LiteralAssemblerCode("; // 2: x32 - size of data to send"); new LiteralAssemblerCode("; [XSharp(PreserveStack = true)]"); new LiteralAssemblerCode("; procedure"); new LiteralAssemblerCode("; Call(\"DebugStub_ComReadEAX()"); new LiteralAssemblerCode("; ECX = EAX"); new LiteralAssemblerCode("; AL = Ds2Vs_MemoryData"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; Call(\"DebugStub_ComReadEAX()"); new LiteralAssemblerCode("; ESI = EAX"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; // now ECX contains size of data (count)"); new LiteralAssemblerCode("; // ESI contains address"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; Label = \"DebugStub_SendMemory_SendByte\""); new LiteralAssemblerCode("; new Compare { DestinationReg = Registers.ECX, SourceValue = 0 }"); new LiteralAssemblerCode("; JumpIf(Flags.Equal, \"DebugStub_SendMemory_After_SendByte\")"); new Comment("X#: ComWrite8()"); new LiteralAssemblerCode("Call DebugStub_ComWrite8"); new LiteralAssemblerCode("; ECX--"); new LiteralAssemblerCode("; Jump(\"DebugStub_SendMemory_SendByte\")"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; Label = \"DebugStub_SendMemory_After_SendByte\""); new LiteralAssemblerCode("; }"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendMemory2_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendTrace2 {"); new LiteralAssemblerCode("DebugStub_SendTrace2:"); new LiteralAssemblerCode("; // Modifies: EAX, ESI"); new LiteralAssemblerCode("; DebugStatus.Value.Compare(Status.Run)"); new LiteralAssemblerCode("; JumpIf(Flags.Equal, \".Normal\")"); new LiteralAssemblerCode("; AL = Ds2Vs_BreakPoint"); new LiteralAssemblerCode("; Jump(\".Type\")"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; Label = \".Normal\""); new LiteralAssemblerCode("; AL = Ds2Vs_TracePoint"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; Label = \".Type\""); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; // Send Calling EIP."); new LiteralAssemblerCode("; ESI = CallerEIP.Address"); new LiteralAssemblerCode("; DebugStub_ComWrite32()"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendTrace2_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendText2 {"); new LiteralAssemblerCode("DebugStub_SendText2:"); new LiteralAssemblerCode("; // Input: Stack"); new LiteralAssemblerCode("; // Output: None"); new LiteralAssemblerCode("; // Modifies: EAX, ECX, EDX, ESI"); new LiteralAssemblerCode("; // Write the type"); new LiteralAssemblerCode("; AL = Ds2Vs_Message"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; // Write Length"); new LiteralAssemblerCode("; ESI = EBP"); new LiteralAssemblerCode("; ESI = ESI + 12"); new LiteralAssemblerCode("; ECX = ESI[0]"); new Comment("X#: ComWrite16()"); new LiteralAssemblerCode("Call DebugStub_ComWrite16"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; // Address of string"); new LiteralAssemblerCode("; ESI = EBP[8]"); new LiteralAssemblerCode("; Label = \".WriteChar\""); new LiteralAssemblerCode("; ECX.Compare(0)"); new LiteralAssemblerCode("; JumpIf(Flags.Equal, \".Exit\")"); new Comment("X#: ComWrite8()"); new LiteralAssemblerCode("Call DebugStub_ComWrite8"); new LiteralAssemblerCode("; ECX--"); new LiteralAssemblerCode("; // We are storing as 16 bits, but for now I will transmit 8 bits"); new LiteralAssemblerCode("; // So we inc again to skip the 0"); new LiteralAssemblerCode("; ESI++"); new LiteralAssemblerCode("; Jump(\".WriteChar\")"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendText2_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendPtr2 {"); new LiteralAssemblerCode("DebugStub_SendPtr2:"); new LiteralAssemblerCode("; // Input: Stack"); new LiteralAssemblerCode("; // Output: None"); new LiteralAssemblerCode("; // Modifies: EAX, ECX, EDX, ESI"); new LiteralAssemblerCode("; // Write the type"); new LiteralAssemblerCode("; AL = Ds2Vs_Pointer"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; // pointer value"); new LiteralAssemblerCode("; ESI = EBP[8]"); new LiteralAssemblerCode("; DebugStub_ComWrite32()"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendPtr2_Exit:"); new LiteralAssemblerCode("Ret"); } } }