Moving PPC disasm to on-demand in debugger.

This commit is contained in:
Ben Vanik
2015-06-16 20:18:48 -07:00
parent 5f33087a12
commit 165d49ad3a
18 changed files with 389 additions and 337 deletions

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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;