mirror of https://github.com/icsharpcode/ILSpy.git
9 changed files with 269 additions and 68 deletions
@ -0,0 +1,155 @@
@@ -0,0 +1,155 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Reflection.Metadata; |
||||
using System.Reflection.Metadata.Ecma335; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
using ICSharpCode.Decompiler.Metadata; |
||||
using ICSharpCode.Decompiler.Util; |
||||
using Microsoft.DiaSymReader; |
||||
|
||||
namespace ICSharpCode.ILSpy.DebugInfo |
||||
{ |
||||
class DiaSymNativeDebugInfoProvider : IDebugInfoProvider, ISymReaderMetadataProvider |
||||
{ |
||||
PEFile module; |
||||
string pdbFileName; |
||||
Stream stream; |
||||
MetadataReader metadata; |
||||
ISymUnmanagedReader5 reader; |
||||
|
||||
public DiaSymNativeDebugInfoProvider(PEFile module, string pdbFileName, Stream stream) |
||||
{ |
||||
this.module = module; |
||||
this.pdbFileName = pdbFileName; |
||||
this.stream = stream; |
||||
this.metadata = module.GetMetadataReader(); |
||||
this.reader = SymUnmanagedReaderFactory.CreateReader<ISymUnmanagedReader5>(stream, this); |
||||
} |
||||
|
||||
public IList<Decompiler.Metadata.SequencePoint> GetSequencePoints(MethodDefinitionHandle handle) |
||||
{ |
||||
var method = reader.GetMethod(MetadataTokens.GetToken(handle)); |
||||
if (method.GetSequencePointCount(out int count) != 0) |
||||
return Empty<Decompiler.Metadata.SequencePoint>.Array; |
||||
var sequencePoints = new Decompiler.Metadata.SequencePoint[count]; |
||||
var points = method.GetSequencePoints(); |
||||
int i = 0; |
||||
var buffer = new char[1024]; |
||||
foreach (var point in points) { |
||||
string url; |
||||
if (point.Document.GetUrl(buffer.Length, out int length, buffer) == 0) { |
||||
url = new string(buffer, 0, length - 1); |
||||
} else { |
||||
url = ""; |
||||
} |
||||
sequencePoints[i] = new Decompiler.Metadata.SequencePoint() { |
||||
Offset = point.Offset, |
||||
StartLine = point.StartLine, |
||||
StartColumn = point.StartColumn, |
||||
EndLine = point.EndLine, |
||||
EndColumn = point.EndColumn, |
||||
DocumentUrl = url |
||||
}; |
||||
|
||||
i++; |
||||
} |
||||
return sequencePoints; |
||||
} |
||||
|
||||
public IList<Variable> GetVariables(MethodDefinitionHandle handle) |
||||
{ |
||||
var method = reader.GetMethod(MetadataTokens.GetToken(handle)); |
||||
var scopes = new Queue<ISymUnmanagedScope>(new[] { method.GetRootScope() }); |
||||
var variables = new List<Variable>(); |
||||
|
||||
while (scopes.Count > 0) { |
||||
var scope = scopes.Dequeue(); |
||||
|
||||
foreach (var local in scope.GetLocals()) { |
||||
variables.Add(new Variable() { Name = local.GetName() }); |
||||
} |
||||
|
||||
foreach (var s in scope.GetChildren()) |
||||
scopes.Enqueue(s); |
||||
} |
||||
|
||||
return variables; |
||||
} |
||||
|
||||
public bool TryGetName(MethodDefinitionHandle handle, int index, out string name) |
||||
{ |
||||
var method = reader.GetMethod(MetadataTokens.GetToken(handle)); |
||||
var scopes = new Queue<ISymUnmanagedScope>(new[] { method.GetRootScope() }); |
||||
name = null; |
||||
|
||||
while (scopes.Count > 0) { |
||||
var scope = scopes.Dequeue(); |
||||
|
||||
foreach (var local in scope.GetLocals()) { |
||||
if (local.GetSlot() == index) { |
||||
name = local.GetName(); |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
foreach (var s in scope.GetChildren()) |
||||
scopes.Enqueue(s); |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
unsafe bool ISymReaderMetadataProvider.TryGetStandaloneSignature(int standaloneSignatureToken, out byte* signature, out int length) |
||||
{ |
||||
var handle = (StandaloneSignatureHandle)MetadataTokens.Handle(standaloneSignatureToken); |
||||
if (handle.IsNil) { |
||||
signature = null; |
||||
length = 0; |
||||
return false; |
||||
} |
||||
|
||||
var sig = metadata.GetStandaloneSignature(handle); |
||||
var blob = metadata.GetBlobReader(sig.Signature); |
||||
|
||||
signature = blob.StartPointer; |
||||
length = blob.Length; |
||||
return true; |
||||
} |
||||
|
||||
bool ISymReaderMetadataProvider.TryGetTypeDefinitionInfo(int typeDefinitionToken, out string namespaceName, out string typeName, out TypeAttributes attributes) |
||||
{ |
||||
var handle = (TypeDefinitionHandle)MetadataTokens.Handle(typeDefinitionToken); |
||||
if (handle.IsNil) { |
||||
namespaceName = null; |
||||
typeName = null; |
||||
attributes = 0; |
||||
return false; |
||||
} |
||||
|
||||
var typeDefinition = metadata.GetTypeDefinition(handle); |
||||
namespaceName = metadata.GetString(typeDefinition.Namespace); |
||||
typeName = metadata.GetString(typeDefinition.Name); |
||||
attributes = typeDefinition.Attributes; |
||||
return true; |
||||
} |
||||
|
||||
bool ISymReaderMetadataProvider.TryGetTypeReferenceInfo(int typeReferenceToken, out string namespaceName, out string typeName) |
||||
{ |
||||
var handle = (TypeReferenceHandle)MetadataTokens.Handle(typeReferenceToken); |
||||
if (handle.IsNil) { |
||||
namespaceName = null; |
||||
typeName = null; |
||||
return false; |
||||
} |
||||
|
||||
var typeReference = metadata.GetTypeReference(handle); |
||||
namespaceName = metadata.GetString(typeReference.Namespace); |
||||
typeName = metadata.GetString(typeReference.Name); |
||||
return true; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Reflection.Metadata; |
||||
using ICSharpCode.Decompiler.Metadata; |
||||
|
||||
namespace ICSharpCode.ILSpy.DebugInfo |
||||
{ |
||||
class PortableDebugInfoProvider : IDebugInfoProvider |
||||
{ |
||||
string pdbFileName; |
||||
MetadataReaderProvider provider; |
||||
|
||||
public PortableDebugInfoProvider(string pdbFileName, MetadataReaderProvider provider) |
||||
{ |
||||
this.pdbFileName = pdbFileName; |
||||
this.provider = provider; |
||||
} |
||||
|
||||
public IList<Decompiler.Metadata.SequencePoint> GetSequencePoints(MethodDefinitionHandle method) |
||||
{ |
||||
var metadata = provider.GetMetadataReader(); |
||||
var debugInfo = metadata.GetMethodDebugInformation(method); |
||||
var sequencePoints = new List<Decompiler.Metadata.SequencePoint>(); |
||||
|
||||
foreach (var point in debugInfo.GetSequencePoints()) { |
||||
string documentFileName; |
||||
|
||||
if (!point.Document.IsNil) { |
||||
var document = metadata.GetDocument(point.Document); |
||||
documentFileName = metadata.GetString(document.Name); |
||||
} else { |
||||
documentFileName = ""; |
||||
} |
||||
|
||||
sequencePoints.Add(new Decompiler.Metadata.SequencePoint() { |
||||
Offset = point.Offset, |
||||
StartLine = point.StartLine, |
||||
StartColumn = point.StartColumn, |
||||
EndLine = point.EndLine, |
||||
EndColumn = point.EndColumn, |
||||
DocumentUrl = documentFileName |
||||
}); |
||||
} |
||||
|
||||
return sequencePoints; |
||||
} |
||||
|
||||
public IList<Variable> GetVariables(MethodDefinitionHandle method) |
||||
{ |
||||
var metadata = provider.GetMetadataReader(); |
||||
var variables = new List<Variable>(); |
||||
|
||||
foreach (var h in metadata.GetLocalScopes(method)) { |
||||
var scope = metadata.GetLocalScope(h); |
||||
foreach (var v in scope.GetLocalVariables()) { |
||||
var var = metadata.GetLocalVariable(v); |
||||
variables.Add(new Variable { Name = metadata.GetString(var.Name) }); |
||||
} |
||||
} |
||||
|
||||
return variables; |
||||
} |
||||
|
||||
public bool TryGetName(MethodDefinitionHandle method, int index, out string name) |
||||
{ |
||||
var metadata = provider.GetMetadataReader(); |
||||
name = null; |
||||
|
||||
foreach (var h in metadata.GetLocalScopes(method)) { |
||||
var scope = metadata.GetLocalScope(h); |
||||
foreach (var v in scope.GetLocalVariables()) { |
||||
var var = metadata.GetLocalVariable(v); |
||||
if (var.Index == index) { |
||||
name = metadata.GetString(var.Name); |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
} |
Binary file not shown.
Loading…
Reference in new issue