Adding modules/functions to the debugger.
This commit is contained in:
@@ -6,10 +6,14 @@ using System.Threading.Tasks;
|
||||
using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class Breakpoint : Changeable {
|
||||
public class Breakpoint : Changeable<Breakpoint> {
|
||||
// type code/data/kernel
|
||||
// address+[end address]
|
||||
// conditions? script?
|
||||
// action (suspend, trace, etc)
|
||||
|
||||
public Breakpoint() {
|
||||
this.self = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,12 @@ using System.Threading.Tasks;
|
||||
using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class BreakpointList : Changeable, IReadOnlyCollection<Breakpoint> {
|
||||
public class BreakpointList : Changeable<BreakpointList>, IReadOnlyCollection<Breakpoint> {
|
||||
private readonly Debugger debugger;
|
||||
private readonly List<Breakpoint> breakpoints = new List<Breakpoint>();
|
||||
|
||||
public BreakpointList(Debugger debugger) {
|
||||
this.self = this;
|
||||
this.debugger = debugger;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,11 @@ namespace Xenia.Debug {
|
||||
Paused,
|
||||
}
|
||||
|
||||
public class Context : Changeable {
|
||||
public class Context : Changeable<Context> {
|
||||
private readonly Debugger debugger;
|
||||
|
||||
public Context(Debugger debugger) {
|
||||
this.self = this;
|
||||
this.debugger = debugger;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,14 +193,19 @@ namespace Xenia.Debug {
|
||||
|
||||
// Read body.
|
||||
var bodyBuffer = new byte[length];
|
||||
receiveLength = await Task.Factory.FromAsync(
|
||||
(callback, state) => socket.BeginReceive(bodyBuffer, 0, bodyBuffer.Length, SocketFlags.None, callback, state),
|
||||
asyncResult => socket.EndReceive(asyncResult),
|
||||
null);
|
||||
if (receiveLength == 0 || receiveLength != bodyBuffer.Length) {
|
||||
// Failed?
|
||||
ReceivePump();
|
||||
return;
|
||||
int bodyOffset = 0;
|
||||
while (bodyOffset != bodyBuffer.Length) {
|
||||
receiveLength = await Task.Factory.FromAsync(
|
||||
(callback, state) => socket.BeginReceive(
|
||||
bodyBuffer, bodyOffset, bodyBuffer.Length - bodyOffset,
|
||||
SocketFlags.None, callback, state),
|
||||
asyncResult => socket.EndReceive(asyncResult), null);
|
||||
if (receiveLength == 0) {
|
||||
// Failed?
|
||||
ReceivePump();
|
||||
return;
|
||||
}
|
||||
bodyOffset += receiveLength;
|
||||
}
|
||||
|
||||
// Emit message.
|
||||
|
||||
@@ -3,18 +3,21 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using xe.debug.proto;
|
||||
using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class Function : Changeable {
|
||||
public class Function : Changeable<Function> {
|
||||
// status: declared, defined, failed
|
||||
// module
|
||||
// name
|
||||
// startAddress
|
||||
// endAddress
|
||||
// behavior: default, prolog, epilog, epilog_return, extern
|
||||
// extern info?
|
||||
|
||||
public readonly Debugger Debugger;
|
||||
public readonly Module Module;
|
||||
public readonly ulong Identifier;
|
||||
public readonly uint AddressStart;
|
||||
public readonly uint AddressEnd;
|
||||
|
||||
// source map
|
||||
|
||||
// disasm:
|
||||
@@ -29,5 +32,79 @@ namespace Xenia.Debug {
|
||||
// call count
|
||||
// caller history
|
||||
// instruction execution counts
|
||||
|
||||
public string DisasmPpc {
|
||||
get; private set;
|
||||
}
|
||||
public string DisasmHirUnoptimized {
|
||||
get; private set;
|
||||
}
|
||||
public string DisasmHirOptimized {
|
||||
get; private set;
|
||||
}
|
||||
public string DisasmMachineCode {
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public Function(Debugger debugger, Module module, xe.debug.proto.FunctionEntry functionEntry) {
|
||||
this.self = this;
|
||||
this.Debugger = debugger;
|
||||
this.Module = module;
|
||||
Identifier = functionEntry.Identifier;
|
||||
AddressStart = functionEntry.AddressStart;
|
||||
AddressEnd = functionEntry.AddressEnd;
|
||||
Name = functionEntry.Name;
|
||||
}
|
||||
|
||||
private string name;
|
||||
public string Name {
|
||||
get {
|
||||
return name;
|
||||
}
|
||||
set {
|
||||
name = value;
|
||||
if (value == null) {
|
||||
name = "sub_" + AddressStart.ToString("X8");
|
||||
}
|
||||
LowerName = name.ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
public string LowerName {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
public async Task Invalidate() {
|
||||
var fbb = Debugger.BeginRequest();
|
||||
int requestDataOffset = GetFunctionRequest.CreateGetFunctionRequest(fbb, Identifier);
|
||||
var response = await Debugger.CommitRequest(
|
||||
fbb, RequestData.GetFunctionRequest, requestDataOffset);
|
||||
|
||||
var responseData = new GetFunctionResponse();
|
||||
response.GetResponseData(responseData);
|
||||
var functionData = responseData.Function;
|
||||
|
||||
this.DisasmPpc = functionData.DisasmPpc;
|
||||
this.DisasmHirUnoptimized = functionData.DisasmHirRaw;
|
||||
this.DisasmHirOptimized = functionData.DisasmHirOpt;
|
||||
this.DisasmMachineCode = functionData.DisasmMachineCode;
|
||||
if (DisasmPpc != null) {
|
||||
DisasmPpc = DisasmPpc.Replace("\n", "\r\n");
|
||||
}
|
||||
if (DisasmHirUnoptimized != null) {
|
||||
DisasmHirUnoptimized = DisasmHirUnoptimized.Replace("\n", "\r\n");
|
||||
}
|
||||
if (DisasmHirOptimized != null) {
|
||||
DisasmHirOptimized = DisasmHirOptimized.Replace("\n", "\r\n");
|
||||
}
|
||||
if (DisasmMachineCode != null) {
|
||||
DisasmMachineCode = DisasmMachineCode.Replace("\n", "\r\n");
|
||||
}
|
||||
|
||||
OnChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@ using System.Threading.Tasks;
|
||||
using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class KernelObject : Changeable {
|
||||
public class KernelObject : Changeable<KernelObject> {
|
||||
public readonly Debugger Debugger;
|
||||
public readonly uint Handle;
|
||||
|
||||
public KernelObject(Debugger debugger, uint handle) {
|
||||
this.self = this;
|
||||
this.Debugger = debugger;
|
||||
this.Handle = handle;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class Memory : Changeable, IDisposable {
|
||||
public class Memory : Changeable<Memory>, IDisposable {
|
||||
private readonly Debugger debugger;
|
||||
|
||||
private class MapInfo {
|
||||
@@ -41,6 +41,7 @@ namespace Xenia.Debug {
|
||||
public UIntPtr PhysicalMembase;
|
||||
|
||||
public Memory(Debugger debugger) {
|
||||
this.self = this;
|
||||
this.debugger = debugger;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,11 @@ using System.Threading.Tasks;
|
||||
using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class MemoryView : Changeable {
|
||||
public class MemoryView : Changeable<MemoryView> {
|
||||
private readonly Memory memory;
|
||||
|
||||
public MemoryView(Memory memory) {
|
||||
this.self = this;
|
||||
this.memory = memory;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,26 +9,95 @@ using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class Module : KernelObject, IReadOnlyCollection<Function> {
|
||||
private bool hasFetched = false;
|
||||
private uint functionCount = 0;
|
||||
private readonly List<Function> functions = new List<Function>();
|
||||
|
||||
// xobject: handle
|
||||
// path
|
||||
// type: user, kernel
|
||||
// if user:
|
||||
// xex header?
|
||||
|
||||
public Module(Debugger debugger, uint moduleHandle) : base(debugger, moduleHandle) {
|
||||
}
|
||||
|
||||
public async Task Invalidate() {
|
||||
public async Task Invalidate(uint newFunctionCount) {
|
||||
if (hasFetched && newFunctionCount == functionCount) {
|
||||
// No-op.
|
||||
return;
|
||||
}
|
||||
|
||||
var pendingTasks = new List<Task>();
|
||||
|
||||
if (!hasFetched) {
|
||||
pendingTasks.Add(InvalidateModule());
|
||||
hasFetched = true;
|
||||
}
|
||||
|
||||
if (newFunctionCount != functionCount) {
|
||||
uint functionIndexStart = functionCount;
|
||||
uint functionIndexEnd = newFunctionCount - 1;
|
||||
functionCount = newFunctionCount;
|
||||
pendingTasks.Add(InvalidateFunctions(functionIndexStart, functionIndexEnd));
|
||||
}
|
||||
|
||||
await Task.WhenAll(pendingTasks);
|
||||
|
||||
OnChanged();
|
||||
}
|
||||
|
||||
private async Task InvalidateModule() {
|
||||
var fbb = Debugger.BeginRequest();
|
||||
int requestDataOffset = GetModuleRequest.CreateGetModuleRequest(fbb, Handle);
|
||||
var response = await Debugger.CommitRequest(
|
||||
fbb, RequestData.GetModuleRequest, requestDataOffset);
|
||||
GetModuleResponse responseData = new GetModuleResponse();
|
||||
|
||||
var responseData = new GetModuleResponse();
|
||||
response.GetResponseData(responseData);
|
||||
|
||||
//
|
||||
ModuleType = responseData.Module.Type;
|
||||
Name = responseData.Module.Name;
|
||||
Path = responseData.Module.Path;
|
||||
}
|
||||
|
||||
private async Task InvalidateFunctions(uint functionIndexStart, uint functionIndexEnd) {
|
||||
var fbb = Debugger.BeginRequest();
|
||||
int requestDataOffset = ListFunctionsRequest.CreateListFunctionsRequest(
|
||||
fbb, Handle, functionIndexStart, functionIndexEnd);
|
||||
var response = await Debugger.CommitRequest(
|
||||
fbb, RequestData.ListFunctionsRequest, requestDataOffset);
|
||||
|
||||
var responseData = new ListFunctionsResponse();
|
||||
response.GetResponseData(responseData);
|
||||
|
||||
var functionEntry = new xe.debug.proto.FunctionEntry();
|
||||
for (int i = 0; i < responseData.EntryLength; ++i) {
|
||||
responseData.GetEntry(functionEntry, i);
|
||||
var function = new Function(Debugger, this, functionEntry);
|
||||
functions.Add(function);
|
||||
}
|
||||
|
||||
functions.Sort((Function a, Function b) => {
|
||||
return (int)((long)a.AddressStart - (long)b.AddressStart);
|
||||
});
|
||||
}
|
||||
|
||||
public ModuleType ModuleType {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Path {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return ToShortString();
|
||||
}
|
||||
|
||||
public string ToShortString() {
|
||||
return string.Format("[{0:X4}] {1}", Handle, Name);
|
||||
}
|
||||
|
||||
public int Count {
|
||||
|
||||
@@ -8,11 +8,12 @@ using xe.debug.proto;
|
||||
using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class ModuleList : Changeable, IReadOnlyCollection<Module> {
|
||||
public class ModuleList : Changeable<ModuleList>, IReadOnlyCollection<Module> {
|
||||
private readonly Debugger debugger;
|
||||
private readonly List<Module> modules = new List<Module>();
|
||||
|
||||
public ModuleList(Debugger debugger) {
|
||||
this.self = this;
|
||||
this.debugger = debugger;
|
||||
}
|
||||
|
||||
@@ -26,20 +27,23 @@ namespace Xenia.Debug {
|
||||
response.GetResponseData(responseData);
|
||||
|
||||
var pendingTasks = new List<Task>();
|
||||
for (int i = 0; i < responseData.ModuleIdsLength; ++i) {
|
||||
uint moduleHandle = responseData.GetModuleIds(i);
|
||||
var module = modules.Find((m) => m.Handle == moduleHandle);
|
||||
for (int i = 0; i < responseData.EntryLength; ++i) {
|
||||
var moduleEntry = responseData.GetEntry(i);
|
||||
var module = modules.Find((m) => m.Handle == moduleEntry.Handle);
|
||||
if (module == null) {
|
||||
// Module not found.
|
||||
module = new Module(debugger, moduleHandle);
|
||||
pendingTasks.Add(module.Invalidate());
|
||||
module = new Module(debugger, moduleEntry.Handle);
|
||||
pendingTasks.Add(module.Invalidate(moduleEntry.FunctionCount));
|
||||
modules.Add(module);
|
||||
} else {
|
||||
// Module already present.
|
||||
// Modules are immutable, so ignore?
|
||||
pendingTasks.Add(module.Invalidate(moduleEntry.FunctionCount));
|
||||
}
|
||||
}
|
||||
|
||||
await Task.WhenAll(pendingTasks);
|
||||
|
||||
OnChanged();
|
||||
}
|
||||
|
||||
public int Count {
|
||||
|
||||
59
src/Xenia.Debug/Proto/xe/debug/proto/Function.cs
Normal file
59
src/Xenia.Debug/Proto/xe/debug/proto/Function.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
namespace xe.debug.proto
|
||||
{
|
||||
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class Function : Table {
|
||||
public static Function GetRootAsFunction(ByteBuffer _bb) { return GetRootAsFunction(_bb, new Function()); }
|
||||
public static Function GetRootAsFunction(ByteBuffer _bb, Function obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public Function __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public ulong Identifier { get { int o = __offset(4); return o != 0 ? bb.GetUlong(o + bb_pos) : (ulong)0; } }
|
||||
public uint AddressStart { get { int o = __offset(6); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint AddressEnd { get { int o = __offset(8); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public string Name { get { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public string DisasmPpc { get { int o = __offset(12); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public string DisasmHirRaw { get { int o = __offset(14); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public string DisasmHirOpt { get { int o = __offset(16); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public string DisasmMachineCode { get { int o = __offset(18); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
|
||||
public static int CreateFunction(FlatBufferBuilder builder,
|
||||
ulong identifier = 0,
|
||||
uint address_start = 0,
|
||||
uint address_end = 0,
|
||||
int name = 0,
|
||||
int disasm_ppc = 0,
|
||||
int disasm_hir_raw = 0,
|
||||
int disasm_hir_opt = 0,
|
||||
int disasm_machine_code = 0) {
|
||||
builder.StartObject(8);
|
||||
Function.AddIdentifier(builder, identifier);
|
||||
Function.AddDisasmMachineCode(builder, disasm_machine_code);
|
||||
Function.AddDisasmHirOpt(builder, disasm_hir_opt);
|
||||
Function.AddDisasmHirRaw(builder, disasm_hir_raw);
|
||||
Function.AddDisasmPpc(builder, disasm_ppc);
|
||||
Function.AddName(builder, name);
|
||||
Function.AddAddressEnd(builder, address_end);
|
||||
Function.AddAddressStart(builder, address_start);
|
||||
return Function.EndFunction(builder);
|
||||
}
|
||||
|
||||
public static void StartFunction(FlatBufferBuilder builder) { builder.StartObject(8); }
|
||||
public static void AddIdentifier(FlatBufferBuilder builder, ulong identifier) { builder.AddUlong(0, identifier, 0); }
|
||||
public static void AddAddressStart(FlatBufferBuilder builder, uint addressStart) { builder.AddUint(1, addressStart, 0); }
|
||||
public static void AddAddressEnd(FlatBufferBuilder builder, uint addressEnd) { builder.AddUint(2, addressEnd, 0); }
|
||||
public static void AddName(FlatBufferBuilder builder, int nameOffset) { builder.AddOffset(3, nameOffset, 0); }
|
||||
public static void AddDisasmPpc(FlatBufferBuilder builder, int disasmPpcOffset) { builder.AddOffset(4, disasmPpcOffset, 0); }
|
||||
public static void AddDisasmHirRaw(FlatBufferBuilder builder, int disasmHirRawOffset) { builder.AddOffset(5, disasmHirRawOffset, 0); }
|
||||
public static void AddDisasmHirOpt(FlatBufferBuilder builder, int disasmHirOptOffset) { builder.AddOffset(6, disasmHirOptOffset, 0); }
|
||||
public static void AddDisasmMachineCode(FlatBufferBuilder builder, int disasmMachineCodeOffset) { builder.AddOffset(7, disasmMachineCodeOffset, 0); }
|
||||
public static int EndFunction(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
43
src/Xenia.Debug/Proto/xe/debug/proto/FunctionEntry.cs
Normal file
43
src/Xenia.Debug/Proto/xe/debug/proto/FunctionEntry.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
namespace xe.debug.proto
|
||||
{
|
||||
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class FunctionEntry : Table {
|
||||
public static FunctionEntry GetRootAsFunctionEntry(ByteBuffer _bb) { return GetRootAsFunctionEntry(_bb, new FunctionEntry()); }
|
||||
public static FunctionEntry GetRootAsFunctionEntry(ByteBuffer _bb, FunctionEntry obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public FunctionEntry __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public ulong Identifier { get { int o = __offset(4); return o != 0 ? bb.GetUlong(o + bb_pos) : (ulong)0; } }
|
||||
public uint AddressStart { get { int o = __offset(6); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint AddressEnd { get { int o = __offset(8); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public string Name { get { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
|
||||
public static int CreateFunctionEntry(FlatBufferBuilder builder,
|
||||
ulong identifier = 0,
|
||||
uint address_start = 0,
|
||||
uint address_end = 0,
|
||||
int name = 0) {
|
||||
builder.StartObject(4);
|
||||
FunctionEntry.AddIdentifier(builder, identifier);
|
||||
FunctionEntry.AddName(builder, name);
|
||||
FunctionEntry.AddAddressEnd(builder, address_end);
|
||||
FunctionEntry.AddAddressStart(builder, address_start);
|
||||
return FunctionEntry.EndFunctionEntry(builder);
|
||||
}
|
||||
|
||||
public static void StartFunctionEntry(FlatBufferBuilder builder) { builder.StartObject(4); }
|
||||
public static void AddIdentifier(FlatBufferBuilder builder, ulong identifier) { builder.AddUlong(0, identifier, 0); }
|
||||
public static void AddAddressStart(FlatBufferBuilder builder, uint addressStart) { builder.AddUint(1, addressStart, 0); }
|
||||
public static void AddAddressEnd(FlatBufferBuilder builder, uint addressEnd) { builder.AddUint(2, addressEnd, 0); }
|
||||
public static void AddName(FlatBufferBuilder builder, int nameOffset) { builder.AddOffset(3, nameOffset, 0); }
|
||||
public static int EndFunctionEntry(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
31
src/Xenia.Debug/Proto/xe/debug/proto/GetFunctionRequest.cs
Normal file
31
src/Xenia.Debug/Proto/xe/debug/proto/GetFunctionRequest.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
namespace xe.debug.proto
|
||||
{
|
||||
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class GetFunctionRequest : Table {
|
||||
public static GetFunctionRequest GetRootAsGetFunctionRequest(ByteBuffer _bb) { return GetRootAsGetFunctionRequest(_bb, new GetFunctionRequest()); }
|
||||
public static GetFunctionRequest GetRootAsGetFunctionRequest(ByteBuffer _bb, GetFunctionRequest obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public GetFunctionRequest __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public ulong Identifier { get { int o = __offset(4); return o != 0 ? bb.GetUlong(o + bb_pos) : (ulong)0; } }
|
||||
|
||||
public static int CreateGetFunctionRequest(FlatBufferBuilder builder,
|
||||
ulong identifier = 0) {
|
||||
builder.StartObject(1);
|
||||
GetFunctionRequest.AddIdentifier(builder, identifier);
|
||||
return GetFunctionRequest.EndGetFunctionRequest(builder);
|
||||
}
|
||||
|
||||
public static void StartGetFunctionRequest(FlatBufferBuilder builder) { builder.StartObject(1); }
|
||||
public static void AddIdentifier(FlatBufferBuilder builder, ulong identifier) { builder.AddUlong(0, identifier, 0); }
|
||||
public static int EndGetFunctionRequest(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
32
src/Xenia.Debug/Proto/xe/debug/proto/GetFunctionResponse.cs
Normal file
32
src/Xenia.Debug/Proto/xe/debug/proto/GetFunctionResponse.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
namespace xe.debug.proto
|
||||
{
|
||||
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class GetFunctionResponse : Table {
|
||||
public static GetFunctionResponse GetRootAsGetFunctionResponse(ByteBuffer _bb) { return GetRootAsGetFunctionResponse(_bb, new GetFunctionResponse()); }
|
||||
public static GetFunctionResponse GetRootAsGetFunctionResponse(ByteBuffer _bb, GetFunctionResponse obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public GetFunctionResponse __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public Function Function { get { return GetFunction(new Function()); } }
|
||||
public Function GetFunction(Function obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
|
||||
public static int CreateGetFunctionResponse(FlatBufferBuilder builder,
|
||||
int function = 0) {
|
||||
builder.StartObject(1);
|
||||
GetFunctionResponse.AddFunction(builder, function);
|
||||
return GetFunctionResponse.EndGetFunctionResponse(builder);
|
||||
}
|
||||
|
||||
public static void StartGetFunctionResponse(FlatBufferBuilder builder) { builder.StartObject(1); }
|
||||
public static void AddFunction(FlatBufferBuilder builder, int functionOffset) { builder.AddOffset(0, functionOffset, 0); }
|
||||
public static int EndGetFunctionResponse(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
39
src/Xenia.Debug/Proto/xe/debug/proto/ListFunctionsRequest.cs
Normal file
39
src/Xenia.Debug/Proto/xe/debug/proto/ListFunctionsRequest.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
namespace xe.debug.proto
|
||||
{
|
||||
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class ListFunctionsRequest : Table {
|
||||
public static ListFunctionsRequest GetRootAsListFunctionsRequest(ByteBuffer _bb) { return GetRootAsListFunctionsRequest(_bb, new ListFunctionsRequest()); }
|
||||
public static ListFunctionsRequest GetRootAsListFunctionsRequest(ByteBuffer _bb, ListFunctionsRequest obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public ListFunctionsRequest __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public uint ModuleId { get { int o = __offset(4); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint FunctionIndexStart { get { int o = __offset(6); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint FunctionIndexEnd { get { int o = __offset(8); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
|
||||
public static int CreateListFunctionsRequest(FlatBufferBuilder builder,
|
||||
uint module_id = 0,
|
||||
uint function_index_start = 0,
|
||||
uint function_index_end = 0) {
|
||||
builder.StartObject(3);
|
||||
ListFunctionsRequest.AddFunctionIndexEnd(builder, function_index_end);
|
||||
ListFunctionsRequest.AddFunctionIndexStart(builder, function_index_start);
|
||||
ListFunctionsRequest.AddModuleId(builder, module_id);
|
||||
return ListFunctionsRequest.EndListFunctionsRequest(builder);
|
||||
}
|
||||
|
||||
public static void StartListFunctionsRequest(FlatBufferBuilder builder) { builder.StartObject(3); }
|
||||
public static void AddModuleId(FlatBufferBuilder builder, uint moduleId) { builder.AddUint(0, moduleId, 0); }
|
||||
public static void AddFunctionIndexStart(FlatBufferBuilder builder, uint functionIndexStart) { builder.AddUint(1, functionIndexStart, 0); }
|
||||
public static void AddFunctionIndexEnd(FlatBufferBuilder builder, uint functionIndexEnd) { builder.AddUint(2, functionIndexEnd, 0); }
|
||||
public static int EndListFunctionsRequest(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
namespace xe.debug.proto
|
||||
{
|
||||
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class ListFunctionsResponse : Table {
|
||||
public static ListFunctionsResponse GetRootAsListFunctionsResponse(ByteBuffer _bb) { return GetRootAsListFunctionsResponse(_bb, new ListFunctionsResponse()); }
|
||||
public static ListFunctionsResponse GetRootAsListFunctionsResponse(ByteBuffer _bb, ListFunctionsResponse obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public ListFunctionsResponse __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public FunctionEntry GetEntry(int j) { return GetEntry(new FunctionEntry(), j); }
|
||||
public FunctionEntry GetEntry(FunctionEntry obj, int j) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
|
||||
public int EntryLength { get { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } }
|
||||
|
||||
public static int CreateListFunctionsResponse(FlatBufferBuilder builder,
|
||||
int entry = 0) {
|
||||
builder.StartObject(1);
|
||||
ListFunctionsResponse.AddEntry(builder, entry);
|
||||
return ListFunctionsResponse.EndListFunctionsResponse(builder);
|
||||
}
|
||||
|
||||
public static void StartListFunctionsResponse(FlatBufferBuilder builder) { builder.StartObject(1); }
|
||||
public static void AddEntry(FlatBufferBuilder builder, int entryOffset) { builder.AddOffset(0, entryOffset, 0); }
|
||||
public static int CreateEntryVector(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i]); return builder.EndVector(); }
|
||||
public static void StartEntryVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
|
||||
public static int EndListFunctionsResponse(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
23
src/Xenia.Debug/Proto/xe/debug/proto/ListModuleEntry.cs
Normal file
23
src/Xenia.Debug/Proto/xe/debug/proto/ListModuleEntry.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
// automatically generated, do not modify
|
||||
|
||||
namespace xe.debug.proto
|
||||
{
|
||||
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class ListModuleEntry : Struct {
|
||||
public ListModuleEntry __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public uint Handle { get { return bb.GetUint(bb_pos + 0); } }
|
||||
public uint FunctionCount { get { return bb.GetUint(bb_pos + 4); } }
|
||||
|
||||
public static int CreateListModuleEntry(FlatBufferBuilder builder, uint Handle, uint FunctionCount) {
|
||||
builder.Prep(4, 8);
|
||||
builder.PutUint(FunctionCount);
|
||||
builder.PutUint(Handle);
|
||||
return builder.Offset;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -10,20 +10,20 @@ public sealed class ListModulesResponse : Table {
|
||||
public static ListModulesResponse GetRootAsListModulesResponse(ByteBuffer _bb, ListModulesResponse obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public ListModulesResponse __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public uint GetModuleIds(int j) { int o = __offset(4); return o != 0 ? bb.GetUint(__vector(o) + j * 4) : (uint)0; }
|
||||
public int ModuleIdsLength { get { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } }
|
||||
public ListModuleEntry GetEntry(int j) { return GetEntry(new ListModuleEntry(), j); }
|
||||
public ListModuleEntry GetEntry(ListModuleEntry obj, int j) { int o = __offset(4); return o != 0 ? obj.__init(__vector(o) + j * 8, bb) : null; }
|
||||
public int EntryLength { get { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } }
|
||||
|
||||
public static int CreateListModulesResponse(FlatBufferBuilder builder,
|
||||
int module_ids = 0) {
|
||||
int entry = 0) {
|
||||
builder.StartObject(1);
|
||||
ListModulesResponse.AddModuleIds(builder, module_ids);
|
||||
ListModulesResponse.AddEntry(builder, entry);
|
||||
return ListModulesResponse.EndListModulesResponse(builder);
|
||||
}
|
||||
|
||||
public static void StartListModulesResponse(FlatBufferBuilder builder) { builder.StartObject(1); }
|
||||
public static void AddModuleIds(FlatBufferBuilder builder, int moduleIdsOffset) { builder.AddOffset(0, moduleIdsOffset, 0); }
|
||||
public static int CreateModuleIdsVector(FlatBufferBuilder builder, uint[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddUint(data[i]); return builder.EndVector(); }
|
||||
public static void StartModuleIdsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
|
||||
public static void AddEntry(FlatBufferBuilder builder, int entryOffset) { builder.AddOffset(0, entryOffset, 0); }
|
||||
public static void StartEntryVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 4); }
|
||||
public static int EndListModulesResponse(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
|
||||
@@ -13,10 +13,12 @@ public enum RequestData : byte
|
||||
RemoveBreakpointsRequest = 5,
|
||||
ListModulesRequest = 6,
|
||||
GetModuleRequest = 7,
|
||||
StopRequest = 8,
|
||||
BreakRequest = 9,
|
||||
ContinueRequest = 10,
|
||||
StepRequest = 11,
|
||||
ListFunctionsRequest = 8,
|
||||
GetFunctionRequest = 9,
|
||||
StopRequest = 10,
|
||||
BreakRequest = 11,
|
||||
ContinueRequest = 12,
|
||||
StepRequest = 13,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -13,12 +13,14 @@ public enum ResponseData : byte
|
||||
RemoveBreakpointsResponse = 5,
|
||||
ListModulesResponse = 6,
|
||||
GetModuleResponse = 7,
|
||||
StopResponse = 8,
|
||||
BreakResponse = 9,
|
||||
ContinueResponse = 10,
|
||||
StepResponse = 11,
|
||||
BreakpointEvent = 12,
|
||||
AccessViolationEvent = 13,
|
||||
ListFunctionsResponse = 8,
|
||||
GetFunctionResponse = 9,
|
||||
StopResponse = 10,
|
||||
BreakResponse = 11,
|
||||
ContinueResponse = 12,
|
||||
StepResponse = 13,
|
||||
BreakpointEvent = 14,
|
||||
AccessViolationEvent = 15,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -7,11 +7,12 @@ using System.Threading.Tasks;
|
||||
using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class ThreadList : Changeable, IReadOnlyCollection<Thread> {
|
||||
public class ThreadList : Changeable<ThreadList>, IReadOnlyCollection<Thread> {
|
||||
private readonly Debugger debugger;
|
||||
private readonly List<Thread> threads = new List<Thread>();
|
||||
|
||||
public ThreadList(Debugger debugger) {
|
||||
this.self = this;
|
||||
this.debugger = debugger;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,13 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xenia.Debug.Utilities {
|
||||
public delegate void ChangedEventHandler();
|
||||
public delegate void ChangedEventHandler<T>(T sender);
|
||||
|
||||
public class Changeable {
|
||||
public class Changeable<T> {
|
||||
protected T self;
|
||||
private int changeDepth;
|
||||
public event ChangedEventHandler Changed;
|
||||
|
||||
public event ChangedEventHandler<T> Changed;
|
||||
|
||||
protected void BeginChanging() {
|
||||
++changeDepth;
|
||||
@@ -24,7 +26,7 @@ namespace Xenia.Debug.Utilities {
|
||||
protected void OnChanged() {
|
||||
System.Diagnostics.Debug.Assert(changeDepth == 0);
|
||||
if (Changed != null) {
|
||||
Changed();
|
||||
Changed(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,10 +84,17 @@
|
||||
<Compile Include="Proto\xe\debug\proto\ContinueAction.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ContinueRequest.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ContinueResponse.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\Function.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\FunctionEntry.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\GetFunctionRequest.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\GetFunctionResponse.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\GetModuleRequest.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\GetModuleResponse.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ListBreakpointsRequest.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ListBreakpointsResponse.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ListFunctionsRequest.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ListFunctionsResponse.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ListModuleEntry.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ListModulesRequest.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ListModulesResponse.cs" />
|
||||
<Compile Include="Proto\xe\debug\proto\ListThreadsRequest.cs" />
|
||||
|
||||
Reference in New Issue
Block a user