-
Notifications
You must be signed in to change notification settings - Fork 0
/
DebuggerView.cs
executable file
·137 lines (113 loc) · 4.01 KB
/
DebuggerView.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// This file is part of bugreport.
// Copyright (c) 2006-2009 The bugreport Developers.
// See AUTHORS.txt for details.
// Licensed under the GNU General Public License, Version 3 (GPLv3).
// See LICENSE.txt for details.
using System;
namespace bugreport
{
internal sealed class DebuggerView
{
private readonly Boolean interactive;
private MachineState state;
public DebuggerView(Boolean interactive)
{
this.interactive = interactive;
}
public void PrintInfo(object sender, EmulationEventArgs emulationEvent)
{
var address = GetEffectiveAddressFor(emulationEvent);
Console.Write(address + ":");
Console.Write("\t");
var code = GetCodeFor(emulationEvent);
PrintOpcodeInfoFor(code);
Console.WriteLine(state.Registers);
Console.WriteLine();
HandleInputIfNecessary();
}
private void HandleInputIfNecessary()
{
if (!interactive)
{
return;
}
// TODO: cover this with a system-level test
var enterPressed = false;
while (!enterPressed)
{
var input = GetInput();
var command = new DebuggerCommand(input);
if (command.IsEnter)
{
enterPressed = true;
continue;
}
if (command.IsStackPrint)
{
PrintStackFor(state);
continue;
}
if (command.IsDisassemble)
{
var hex = input.Substring("disasm".Length + 1);
var code = DumpFileParser.GetByteArrayFor(hex);
PrintOpcodeInfoFor(code);
continue;
}
if (command.IsQuit)
{
Environment.Exit(0);
}
Console.WriteLine("invalid command");
}
}
private void PrintOpcodeInfoFor(byte[] code)
{
foreach (var codeByte in code)
{
Console.Write(String.Format("{0:x2}", codeByte) + " ");
}
// magic numbers that happen to look good :)
var numberOfTabs = 3 - (code.Length / 3);
for (var i = 0; i < numberOfTabs; i++)
{
Console.Write("\t");
}
Console.Write(OpcodeFormatter.GetInstructionName(code));
Console.Write("\t");
var operands = OpcodeFormatter.GetOperands(code, state.InstructionPointer);
Console.Write(operands);
if (operands.Length < 8)
{
Console.Write("\t");
}
var encoding = OpcodeFormatter.GetEncodingFor(code);
Console.Write("\t");
Console.WriteLine(encoding);
}
private static Byte[] GetCodeFor(EmulationEventArgs e)
{
var code = new Byte[e.Code.Count];
e.Code.CopyTo(code, 0);
return code;
}
private string GetEffectiveAddressFor(EmulationEventArgs e)
{
state = e.MachineState;
var address = String.Format("{0:x8}", state.InstructionPointer);
return address;
}
private string GetInput()
{
Console.Write("0x{0:x8} > ", state.InstructionPointer);
return Console.ReadLine();
}
private static void PrintStackFor(MachineState state)
{
var esp = state.Registers[RegisterName.ESP];
Console.WriteLine("Stack dump");
Console.WriteLine("esp-8\t\t esp-4\t\t esp");
Console.WriteLine("{0}\t\t {1}\t\t {2}", esp.PointsTo[-2], esp.PointsTo[-1], esp.PointsTo[0]);
}
}
}