Skeleton support for resolving symbols
This commit is contained in:
parent
d822b23562
commit
d3e5c0644d
|
@ -63,6 +63,7 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DebuggerSymbols\Kernel\KernelSymbolProvider.cs" />
|
||||
<Compile Include="Debugger\Debugger.cs" />
|
||||
<Compile Include="Debugger\DebuggerEventInterfaces.cs" />
|
||||
<Compile Include="Debugger\DebuggerInstance.cs" />
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace CxbxDebugger
|
|||
List<IDebuggerExceptionEvents> ExceptionEvents = new List<IDebuggerExceptionEvents>();
|
||||
|
||||
DebuggerSymbolServer SymbolSrv;
|
||||
KernelProvider KernelSymbolProvider;
|
||||
|
||||
private void Init()
|
||||
{
|
||||
|
@ -48,6 +49,9 @@ namespace CxbxDebugger
|
|||
|
||||
SymbolSrv = new DebuggerSymbolServer();
|
||||
|
||||
KernelSymbolProvider = new KernelProvider();
|
||||
SymbolSrv.RegisterProvider(KernelSymbolProvider);
|
||||
|
||||
RegisterEventInterfaces(this);
|
||||
}
|
||||
|
||||
|
@ -115,19 +119,20 @@ namespace CxbxDebugger
|
|||
}
|
||||
|
||||
static string CxbxDebuggerPrefix = "CxbxDebugger! ";
|
||||
static string KernelImportPrefix = "KernelImport_";
|
||||
public void OnDebugOutput(string Message)
|
||||
{
|
||||
if (Message.StartsWith(CxbxDebuggerPrefix))
|
||||
{
|
||||
string Payload = Message.Substring(CxbxDebuggerPrefix.Length);
|
||||
|
||||
if (Payload.StartsWith("IoCreateFile@"))
|
||||
if (Payload.StartsWith(KernelImportPrefix))
|
||||
{
|
||||
Payload = Payload.Substring("IoCreateFile@".Length);
|
||||
// TODO: Something with payload
|
||||
KernelSymbolProvider.AddKernelSymbolFromMessage(Payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO Ensure this
|
||||
SetupHLECacheProvider(Payload);
|
||||
}
|
||||
}
|
||||
|
@ -482,6 +487,16 @@ namespace CxbxDebugger
|
|||
}
|
||||
}
|
||||
|
||||
public DebuggerSymbol ResolveSymbol(uint Address)
|
||||
{
|
||||
return SymbolSrv.FindSymbol(Address);
|
||||
}
|
||||
|
||||
public DebuggerSymbol ResolveSymbol(IntPtr Address)
|
||||
{
|
||||
return SymbolSrv.FindSymbol((uint)Address);
|
||||
}
|
||||
|
||||
public void RegisterEventInterfaces(object EventClass)
|
||||
{
|
||||
IDebuggerGeneralEvents GeneralListener = EventClass as IDebuggerGeneralEvents;
|
||||
|
|
|
@ -7,31 +7,50 @@ namespace CxbxDebugger
|
|||
{
|
||||
public class DebuggerSymbolServer
|
||||
{
|
||||
List<DebuggerSymbolProvider> Providers = new List<DebuggerSymbolProvider>();
|
||||
|
||||
public DebuggerSymbolServer() { }
|
||||
|
||||
public DebuggerSymbolResult ResolveAddress(uint Address)
|
||||
List<DebuggerSymbolProviderBase> Providers = new List<DebuggerSymbolProviderBase>();
|
||||
|
||||
public DebuggerSymbol FindSymbol(uint Address)
|
||||
{
|
||||
DebuggerSymbolResult Result = new DebuggerSymbolResult();
|
||||
if (Providers.Count == 0)
|
||||
return null;
|
||||
|
||||
foreach (DebuggerSymbolProvider SymbolProvider in Providers)
|
||||
DebuggerSymbol BestResult = null;
|
||||
|
||||
// Find the first provider who can give a symbol for this address
|
||||
|
||||
int ProviderIndex = 0;
|
||||
do
|
||||
{
|
||||
Result = SymbolProvider.ResolveAddress(Address);
|
||||
|
||||
if (Result.Success)
|
||||
BestResult = Providers[ProviderIndex].FindSymbolFromAddress(Address);
|
||||
if (BestResult != null)
|
||||
break;
|
||||
}
|
||||
while (ProviderIndex < Providers.Count);
|
||||
|
||||
return Result;
|
||||
// Try to find another symbol which is closer to the given address
|
||||
// TODO Investigate adding symbol size metadata this can just check if Address is within a given range
|
||||
|
||||
for (int i = ProviderIndex + 1; i < Providers.Count; ++i)
|
||||
{
|
||||
DebuggerSymbol OtherResult = Providers[i].FindSymbolFromAddress(Address);
|
||||
if (OtherResult == null)
|
||||
continue;
|
||||
|
||||
if(OtherResult.AddrBegin < BestResult.AddrBegin )
|
||||
{
|
||||
BestResult = OtherResult;
|
||||
}
|
||||
}
|
||||
|
||||
return BestResult;
|
||||
}
|
||||
|
||||
public void RegisterProvider(DebuggerSymbolProvider Provider)
|
||||
public void RegisterProvider(DebuggerSymbolProviderBase Provider)
|
||||
{
|
||||
Providers.Add(Provider);
|
||||
}
|
||||
|
||||
public void UnregisterProvider(DebuggerSymbolProvider Provider)
|
||||
public void UnregisterProvider(DebuggerSymbolProviderBase Provider)
|
||||
{
|
||||
Providers.Remove(Provider);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,51 @@
|
|||
// Written by x1nixmzeng for the Cxbx-Reloaded project
|
||||
//
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CxbxDebugger
|
||||
{
|
||||
public class DebuggerSymbolResult
|
||||
public class DebuggerSymbol
|
||||
{
|
||||
public bool Success { get; set; } = false;
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
public uint AddrBegin { get; set; } = 0;
|
||||
public uint AddrEnd { get; set; } = 0;
|
||||
}
|
||||
|
||||
public abstract class DebuggerSymbolProvider
|
||||
public class DebuggerSymbolProviderBase
|
||||
{
|
||||
public virtual DebuggerSymbolResult ResolveAddress(uint Address) { return new DebuggerSymbolResult(); }
|
||||
// Stored in a map so the addresses are sorted
|
||||
Dictionary<uint, DebuggerSymbol> Symbols = new Dictionary<uint, DebuggerSymbol>();
|
||||
|
||||
protected void AddSymbol(DebuggerSymbol Symbol)
|
||||
{
|
||||
Symbols.Add(Symbol.AddrBegin, Symbol);
|
||||
}
|
||||
|
||||
protected void RemoveSymbol(DebuggerSymbol Symbol)
|
||||
{
|
||||
Symbols.Remove(Symbol.AddrBegin);
|
||||
}
|
||||
|
||||
// TODO Find an inbuilt lower bound method
|
||||
public DebuggerSymbol FindSymbolFromAddress(uint Address)
|
||||
{
|
||||
uint BestAddr = 0;
|
||||
|
||||
foreach (uint SymbolAddr in Symbols.Keys)
|
||||
{
|
||||
if (SymbolAddr > Address)
|
||||
break;
|
||||
|
||||
BestAddr = SymbolAddr;
|
||||
}
|
||||
|
||||
if (!Symbols.ContainsKey(BestAddr))
|
||||
return null;
|
||||
|
||||
return Symbols[BestAddr];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,32 @@
|
|||
// Written by x1nixmzeng for the Cxbx-Reloaded project
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace CxbxDebugger
|
||||
{
|
||||
public class HLECacheProvider : DebuggerSymbolProvider
|
||||
public class HLECacheProvider : DebuggerSymbolProviderBase
|
||||
{
|
||||
HLECacheFile CacheFile;
|
||||
|
||||
public bool Load(string FileName)
|
||||
{
|
||||
CacheFile = new HLECacheFile();
|
||||
return CacheFile.Load(FileName);
|
||||
}
|
||||
if (!File.Exists(FileName))
|
||||
return false;
|
||||
|
||||
public override DebuggerSymbolResult ResolveAddress(uint Address)
|
||||
{
|
||||
var SymbolResult = new DebuggerSymbolResult();
|
||||
HLECacheFile CacheFile = new HLECacheFile();
|
||||
if (!CacheFile.Load(FileName))
|
||||
return false;
|
||||
|
||||
// TODO: Resolve me
|
||||
SymbolResult.Success = false;
|
||||
foreach(KeyValuePair<uint, string> Item in CacheFile.AddressMap)
|
||||
{
|
||||
DebuggerSymbol NewSymbol = new DebuggerSymbol();
|
||||
NewSymbol.Name = Item.Value;
|
||||
NewSymbol.AddrBegin = Item.Key;
|
||||
|
||||
return SymbolResult;
|
||||
AddSymbol(NewSymbol);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// Written by x1nixmzeng for the Cxbx-Reloaded project
|
||||
//
|
||||
|
||||
namespace CxbxDebugger
|
||||
{
|
||||
public class KernelProvider : DebuggerSymbolProviderBase
|
||||
{
|
||||
public void AddKernelSymbolFromMessage(string Message)
|
||||
{
|
||||
var Parts = Message.Split('@');
|
||||
if( Parts.Length == 2 )
|
||||
{
|
||||
uint Address = 0;
|
||||
if( uint.TryParse(Parts[1], out Address) )
|
||||
{
|
||||
DebuggerSymbol NewSymbol = new DebuggerSymbol();
|
||||
NewSymbol.Name = Parts[0];
|
||||
NewSymbol.AddrBegin = Address;
|
||||
|
||||
AddSymbol(NewSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -260,6 +260,9 @@ namespace CxbxDebugger
|
|||
public void OnAccessViolation()
|
||||
{
|
||||
frm.DebugEvent("Access violation exception occured");
|
||||
|
||||
// Already suspended at this point, so we can rebuild the callstack list
|
||||
frm.PopulateThreadList(frm.cbThreads.Items);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,9 +300,17 @@ namespace CxbxDebugger
|
|||
var Callstack = DebugThreads[Index].CallstackCache;
|
||||
foreach(DebuggerStackFrame StackFrame in Callstack.StackFrames)
|
||||
{
|
||||
// TODO Resolve symbol names
|
||||
string FrameString = string.Format("{0:X8} {1:X8}", (uint)StackFrame.Base, (uint)StackFrame.PC);
|
||||
|
||||
// Try to resolve the symbol name
|
||||
var Symbol = DebuggerInst.ResolveSymbol(StackFrame.Base);
|
||||
if( Symbol != null)
|
||||
{
|
||||
uint Offset = Symbol.AddrBegin - (uint)StackFrame.Base;
|
||||
|
||||
FrameString = string.Format("{0} + 0x{1:X}", Symbol.Name, Offset);
|
||||
}
|
||||
|
||||
lbRegisters.Items.Add(FrameString);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue