Moving PPC disasm to on-demand in debugger.
This commit is contained in:
@@ -44,6 +44,8 @@ namespace Xenia.Debug {
|
||||
private uint nextRequestId = 1;
|
||||
|
||||
private FileMappingHandle memoryHandle;
|
||||
private FileMappingHandle codeCacheHandle;
|
||||
private IntPtr codeCachePtr;
|
||||
|
||||
public unsafe byte* TranslateVirtual(uint address) {
|
||||
return (byte*)Memory.VirtualMembase.ToPointer() + address;
|
||||
@@ -140,7 +142,7 @@ namespace Xenia.Debug {
|
||||
var attachResponse = new AttachResponse();
|
||||
response.GetResponseData(attachResponse);
|
||||
|
||||
// Open mmap to share memroy.
|
||||
// Open mmap to share memory.
|
||||
memoryHandle = FileMapping.OpenFileMapping(
|
||||
FileMapAccess.FILE_MAP_ALL_ACCESS, false, attachResponse.MemoryFile);
|
||||
if (memoryHandle.IsInvalid) {
|
||||
@@ -149,6 +151,19 @@ namespace Xenia.Debug {
|
||||
return;
|
||||
}
|
||||
|
||||
// Open mmap to code cache.
|
||||
codeCacheHandle =
|
||||
FileMapping.OpenFileMapping(FileMapAccess.FILE_MAP_ALL_ACCESS, false,
|
||||
attachResponse.CodeCacheFile);
|
||||
if (codeCacheHandle.IsInvalid) {
|
||||
System.Diagnostics.Debug.Fail("Unable to open target code cache");
|
||||
Detach();
|
||||
return;
|
||||
}
|
||||
codeCachePtr = FileMapping.MapViewOfFileEx(
|
||||
codeCacheHandle, FileMapAccess.FILE_MAP_ALL_ACCESS, 0, 0,
|
||||
attachResponse.CodeCacheSize, attachResponse.CodeCacheBase);
|
||||
|
||||
// Setup the memory system. This maps the emulator memory into our address
|
||||
// space.
|
||||
if (!Memory.InitializeMapping(memoryHandle)) {
|
||||
@@ -166,6 +181,11 @@ namespace Xenia.Debug {
|
||||
|
||||
Memory.UninitializeMapping();
|
||||
|
||||
if (codeCacheHandle != null) {
|
||||
FileMapping.UnmapViewOfFile(codeCachePtr);
|
||||
codeCacheHandle.Close();
|
||||
codeCacheHandle = null;
|
||||
}
|
||||
if (memoryHandle != null) {
|
||||
memoryHandle.Close();
|
||||
memoryHandle = null;
|
||||
|
||||
@@ -17,6 +17,8 @@ using Xenia.Debug.Utilities;
|
||||
|
||||
namespace Xenia.Debug {
|
||||
public class Function : Changeable<Function> {
|
||||
private static Native.Disassembler disassembler = new Native.Disassembler();
|
||||
|
||||
// status: declared, defined, failed
|
||||
// behavior: default, prolog, epilog, epilog_return, extern
|
||||
// extern info?
|
||||
@@ -25,7 +27,16 @@ namespace Xenia.Debug {
|
||||
public readonly Module Module;
|
||||
public readonly ulong Identifier;
|
||||
public readonly uint AddressStart;
|
||||
public readonly uint AddressEnd;
|
||||
public uint AddressEnd {
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public uint MachineCodeStart {
|
||||
get; private set;
|
||||
}
|
||||
public uint MachineCodeEnd {
|
||||
get; private set;
|
||||
}
|
||||
|
||||
// source map
|
||||
|
||||
@@ -42,17 +53,43 @@ namespace Xenia.Debug {
|
||||
// caller history
|
||||
// instruction execution counts
|
||||
|
||||
public string DisasmPpc {
|
||||
get; private set;
|
||||
private string disasmPpc;
|
||||
public unsafe string DisasmPpc {
|
||||
get {
|
||||
if (disasmPpc != null) {
|
||||
return disasmPpc;
|
||||
}
|
||||
if (AddressEnd == 0) {
|
||||
return "(unavailable)";
|
||||
}
|
||||
disasmPpc = disassembler.DisassemblePPC(
|
||||
new IntPtr(Debugger.TranslateVirtual(AddressStart)),
|
||||
AddressEnd - AddressStart + 4);
|
||||
return disasmPpc;
|
||||
}
|
||||
}
|
||||
|
||||
public string DisasmHirUnoptimized {
|
||||
get; private set;
|
||||
}
|
||||
public string DisasmHirOptimized {
|
||||
get; private set;
|
||||
}
|
||||
|
||||
private string disasmMachineCode;
|
||||
public string DisasmMachineCode {
|
||||
get; private set;
|
||||
get {
|
||||
if (disasmMachineCode != null) {
|
||||
return disasmMachineCode;
|
||||
}
|
||||
if (MachineCodeStart == 0) {
|
||||
return null;
|
||||
}
|
||||
disasmMachineCode = disassembler.DisassembleX64(
|
||||
new IntPtr(MachineCodeStart), MachineCodeEnd - MachineCodeStart + 1);
|
||||
disasmMachineCode = disasmMachineCode.Replace("\n", "\r\n");
|
||||
return disasmMachineCode;
|
||||
}
|
||||
}
|
||||
|
||||
public Function(Debugger debugger, Module module, xe.debug.proto.FunctionEntry functionEntry) {
|
||||
@@ -96,33 +133,21 @@ namespace Xenia.Debug {
|
||||
response.GetResponseData(responseData);
|
||||
var functionData = responseData.Function;
|
||||
|
||||
this.DisasmPpc = functionData.DisasmPpc;
|
||||
this.AddressEnd = functionData.AddressEnd;
|
||||
|
||||
this.MachineCodeStart = functionData.MachineCodeStart;
|
||||
this.MachineCodeEnd = functionData.MachineCodeEnd;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
DisassembleX64();
|
||||
|
||||
OnChanged();
|
||||
}
|
||||
|
||||
private static Native.X64Disassembler disassembler = new Native.X64Disassembler();
|
||||
|
||||
private void DisassembleX64() {
|
||||
var str = disassembler.GenerateString(IntPtr.Zero, 0);
|
||||
System.Diagnostics.Debug.WriteLine(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,24 +11,36 @@ public sealed class AttachResponse : Table {
|
||||
public AttachResponse __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
|
||||
public string MemoryFile { get { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public string FunctionsFile { get { int o = __offset(6); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public string FunctionsTraceFile { get { int o = __offset(8); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public string CodeCacheFile { get { int o = __offset(6); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public uint CodeCacheBase { get { int o = __offset(8); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint CodeCacheSize { get { int o = __offset(10); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public string FunctionsFile { get { int o = __offset(12); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public string FunctionsTraceFile { get { int o = __offset(14); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
|
||||
public static int CreateAttachResponse(FlatBufferBuilder builder,
|
||||
int memory_file = 0,
|
||||
int code_cache_file = 0,
|
||||
uint code_cache_base = 0,
|
||||
uint code_cache_size = 0,
|
||||
int functions_file = 0,
|
||||
int functions_trace_file = 0) {
|
||||
builder.StartObject(3);
|
||||
builder.StartObject(6);
|
||||
AttachResponse.AddFunctionsTraceFile(builder, functions_trace_file);
|
||||
AttachResponse.AddFunctionsFile(builder, functions_file);
|
||||
AttachResponse.AddCodeCacheSize(builder, code_cache_size);
|
||||
AttachResponse.AddCodeCacheBase(builder, code_cache_base);
|
||||
AttachResponse.AddCodeCacheFile(builder, code_cache_file);
|
||||
AttachResponse.AddMemoryFile(builder, memory_file);
|
||||
return AttachResponse.EndAttachResponse(builder);
|
||||
}
|
||||
|
||||
public static void StartAttachResponse(FlatBufferBuilder builder) { builder.StartObject(3); }
|
||||
public static void StartAttachResponse(FlatBufferBuilder builder) { builder.StartObject(6); }
|
||||
public static void AddMemoryFile(FlatBufferBuilder builder, int memoryFileOffset) { builder.AddOffset(0, memoryFileOffset, 0); }
|
||||
public static void AddFunctionsFile(FlatBufferBuilder builder, int functionsFileOffset) { builder.AddOffset(1, functionsFileOffset, 0); }
|
||||
public static void AddFunctionsTraceFile(FlatBufferBuilder builder, int functionsTraceFileOffset) { builder.AddOffset(2, functionsTraceFileOffset, 0); }
|
||||
public static void AddCodeCacheFile(FlatBufferBuilder builder, int codeCacheFileOffset) { builder.AddOffset(1, codeCacheFileOffset, 0); }
|
||||
public static void AddCodeCacheBase(FlatBufferBuilder builder, uint codeCacheBase) { builder.AddUint(2, codeCacheBase, 0); }
|
||||
public static void AddCodeCacheSize(FlatBufferBuilder builder, uint codeCacheSize) { builder.AddUint(3, codeCacheSize, 0); }
|
||||
public static void AddFunctionsFile(FlatBufferBuilder builder, int functionsFileOffset) { builder.AddOffset(4, functionsFileOffset, 0); }
|
||||
public static void AddFunctionsTraceFile(FlatBufferBuilder builder, int functionsTraceFileOffset) { builder.AddOffset(5, functionsTraceFileOffset, 0); }
|
||||
public static int EndAttachResponse(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
|
||||
@@ -14,26 +14,26 @@ public sealed class Function : Table {
|
||||
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 uint MachineCodeStart { get { int o = __offset(12); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public uint MachineCodeEnd { get { int o = __offset(14); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public string DisasmHirRaw { get { int o = __offset(16); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public string DisasmHirOpt { 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,
|
||||
uint machine_code_start = 0,
|
||||
uint machine_code_end = 0,
|
||||
int disasm_hir_raw = 0,
|
||||
int disasm_hir_opt = 0,
|
||||
int disasm_machine_code = 0) {
|
||||
int disasm_hir_opt = 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.AddMachineCodeEnd(builder, machine_code_end);
|
||||
Function.AddMachineCodeStart(builder, machine_code_start);
|
||||
Function.AddName(builder, name);
|
||||
Function.AddAddressEnd(builder, address_end);
|
||||
Function.AddAddressStart(builder, address_start);
|
||||
@@ -45,10 +45,10 @@ public sealed class Function : Table {
|
||||
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 void AddMachineCodeStart(FlatBufferBuilder builder, uint machineCodeStart) { builder.AddUint(4, machineCodeStart, 0); }
|
||||
public static void AddMachineCodeEnd(FlatBufferBuilder builder, uint machineCodeEnd) { builder.AddUint(5, machineCodeEnd, 0); }
|
||||
public static void AddDisasmHirRaw(FlatBufferBuilder builder, int disasmHirRawOffset) { builder.AddOffset(6, disasmHirRawOffset, 0); }
|
||||
public static void AddDisasmHirOpt(FlatBufferBuilder builder, int disasmHirOptOffset) { builder.AddOffset(7, disasmHirOptOffset, 0); }
|
||||
public static int EndFunction(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return o;
|
||||
|
||||
Reference in New Issue
Block a user