You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,256 @@
|
||||
namespace System.Workflow.ComponentModel.Compiler
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal sealed class PDBReader : IDisposable
|
||||
{
|
||||
#region Data Members
|
||||
|
||||
private const string IMetaDataImportGuid = "7DAC8207-D3AE-4c75-9B67-92801A497D44";
|
||||
private ISymUnmanagedReader symReader;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor and Dispose
|
||||
|
||||
public PDBReader(string assemblyPath)
|
||||
{
|
||||
object metaDataImport = null;
|
||||
IMetaDataDispenser dispenser = null;
|
||||
|
||||
try
|
||||
{
|
||||
Guid metaDataImportIID = new Guid(IMetaDataImportGuid);
|
||||
|
||||
dispenser = (IMetaDataDispenser)(new MetaDataDispenser());
|
||||
dispenser.OpenScope(assemblyPath, 0, ref metaDataImportIID, out metaDataImport);
|
||||
|
||||
this.symReader = (ISymUnmanagedReader)(new CorSymReader_SxS());
|
||||
this.symReader.Initialize(metaDataImport, assemblyPath, null, null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Release COM objects so that files don't remain locked.
|
||||
if (metaDataImport != null)
|
||||
Marshal.ReleaseComObject(metaDataImport);
|
||||
|
||||
if (dispenser != null)
|
||||
Marshal.ReleaseComObject(dispenser);
|
||||
}
|
||||
}
|
||||
|
||||
~PDBReader()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose()
|
||||
{
|
||||
if (this.symReader != null)
|
||||
{
|
||||
Marshal.ReleaseComObject(this.symReader);
|
||||
this.symReader = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
|
||||
public void GetSourceLocationForOffset(uint methodDef, uint offset, out string fileLocation, out uint line, out uint column)
|
||||
{
|
||||
fileLocation = null;
|
||||
line = 0;
|
||||
column = 0;
|
||||
|
||||
ISymUnmanagedMethod symMethod = null;
|
||||
ISymUnmanagedDocument[] documents = null;
|
||||
uint sequencePointCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
symMethod = this.symReader.GetMethod(methodDef);
|
||||
sequencePointCount = symMethod.GetSequencePointCount();
|
||||
|
||||
documents = new ISymUnmanagedDocument[sequencePointCount];
|
||||
uint[] offsets = new uint[sequencePointCount];
|
||||
uint[] lines = new uint[sequencePointCount];
|
||||
uint[] columns = new uint[sequencePointCount];
|
||||
uint[] endLines = new uint[sequencePointCount];
|
||||
uint[] endColumns = new uint[sequencePointCount];
|
||||
|
||||
symMethod.GetSequencePoints(sequencePointCount, out sequencePointCount, offsets, documents, lines, columns, endLines, endColumns);
|
||||
|
||||
uint index = 1;
|
||||
for (; index < sequencePointCount; index++)
|
||||
{ if (offsets[index] > offset) break; }
|
||||
|
||||
index = index - 1;
|
||||
|
||||
// Work Around: AkashS - The SymReader returns bad line-column data for unconditional branch
|
||||
// instructions. The line number is whacky and the column number is 0. Need to verify why this is so.
|
||||
// We just look for a good sequence point data, it should be close enough in the source code.
|
||||
while (columns[index] == 0 && index > 0)
|
||||
index--;
|
||||
|
||||
while (index < sequencePointCount && columns[index] == 0)
|
||||
index++;
|
||||
|
||||
// What more can we do?
|
||||
if (index >= sequencePointCount || columns[index] == 0)
|
||||
index = 0;
|
||||
|
||||
// End Work around
|
||||
|
||||
|
||||
line = lines[index];
|
||||
column = columns[index];
|
||||
|
||||
ISymUnmanagedDocument document = documents[index];
|
||||
uint urlLength = 261;
|
||||
string url = new string('\0', (int)urlLength);
|
||||
|
||||
document.GetURL(urlLength, out urlLength, url);
|
||||
fileLocation = url.Substring(0, (int)urlLength - 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Release COM objects so that files don't remain locked.
|
||||
for (uint i = 0; i < sequencePointCount; i++)
|
||||
if (documents[i] != null)
|
||||
Marshal.ReleaseComObject(documents[i]);
|
||||
|
||||
if (symMethod != null)
|
||||
Marshal.ReleaseComObject(symMethod);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region Interop declarations
|
||||
|
||||
//
|
||||
// Note:
|
||||
// These interop declaration are sufficient for our purposes of reading the symbol information from
|
||||
// the PDB. They are not complete otherwise!
|
||||
//
|
||||
[ComImport, Guid("0A3976C5-4529-4ef8-B0B0-42EED37082CD")]
|
||||
internal class CorSymReader_SxS
|
||||
{ }
|
||||
|
||||
|
||||
[ComImport,
|
||||
CoClass(typeof(CorSymReader_SxS)),
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
|
||||
Guid("B4CE6286-2A6B-3712-A3B7-1EE1DAD467B5")]
|
||||
internal interface ISymUnmanagedReader
|
||||
{
|
||||
// NYI.
|
||||
void GetDocument();
|
||||
void GetDocuments();
|
||||
void GetUserEntryPoint();
|
||||
|
||||
ISymUnmanagedMethod GetMethod(uint methodDef);
|
||||
|
||||
// NYI.
|
||||
void GetMethodByVersion();
|
||||
void GetVariables();
|
||||
void GetGlobalVariables();
|
||||
void GetMethodFromDocumentPosition();
|
||||
void GetSymAttribute();
|
||||
void GetNamespaces();
|
||||
|
||||
// Incomplete - We don't use the Stream
|
||||
void Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object metaDataImport, [In, MarshalAs(UnmanagedType.LPWStr)] string pdbPath, [In, MarshalAs(UnmanagedType.LPWStr)] string searchPath, [In, MarshalAs(UnmanagedType.IUnknown)] object stream);
|
||||
|
||||
// NYI.
|
||||
void UpdateSymbolStore();
|
||||
void ReplaceSymbolStore();
|
||||
void GetSymbolStoreFileName();
|
||||
void GetMethodsFromDocumentPosition();
|
||||
void GetDocumentVersion();
|
||||
void GetMethodVersion();
|
||||
}
|
||||
|
||||
|
||||
[ComImport,
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
|
||||
Guid("B62B923C-B500-3158-A543-24F307A8B7E1")]
|
||||
internal interface ISymUnmanagedMethod
|
||||
{
|
||||
uint GetToken();
|
||||
uint GetSequencePointCount();
|
||||
|
||||
// Incomplete - Don't need to define ISymUnmanagedScope.
|
||||
object GetRootScope();
|
||||
|
||||
// Incomplete - Don't need to define ISymUnmanagedScope.
|
||||
object GetScopeFromOffset(uint offset);
|
||||
|
||||
uint GetOffset([In, MarshalAs(UnmanagedType.IUnknown)] ISymUnmanagedDocument document, uint line, uint column);
|
||||
void GetRanges([In, MarshalAs(UnmanagedType.IUnknown)] ISymUnmanagedDocument document, uint line, uint column, uint rangeCount, [Out] out uint actualRangeCount, [In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] ranges);
|
||||
|
||||
// NYI.
|
||||
void GetParameters();
|
||||
|
||||
// NYI.
|
||||
void GetNamespace();
|
||||
|
||||
void GetSourceStartEnd([In, Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedDocument[] documents, [In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] lines, [In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] columns, [Out, MarshalAs(UnmanagedType.Bool)] out bool positionsDefined);
|
||||
void GetSequencePoints(uint pointsCount, [Out] out uint actualPointsCount, [In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] offsets, [In, Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedDocument[] documents, [In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] lines, [In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] columns, [In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] endLines, [In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] endColumns);
|
||||
}
|
||||
|
||||
|
||||
[ComImport,
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
|
||||
Guid("40DE4037-7C81-3E1E-B022-AE1ABFF2CA08")]
|
||||
internal interface ISymUnmanagedDocument
|
||||
{
|
||||
void GetURL(uint urlLength, [Out] out uint actualUrlLength, [In, Out, MarshalAs(UnmanagedType.LPWStr)] string url);
|
||||
|
||||
// The rest are NYI.
|
||||
void GetDocumentType();
|
||||
void GetLanguage();
|
||||
void GetLanguageVendor();
|
||||
void GetCheckSumAlgorithmId();
|
||||
void GetCheckSum();
|
||||
void FindClosestLine();
|
||||
void HasEmbeddedSource();
|
||||
void GetSourceLength();
|
||||
void GetSourceRange();
|
||||
}
|
||||
|
||||
|
||||
[ComImport,
|
||||
Guid("E5CB7A31-7512-11d2-89CE-0080C792E5D8")]
|
||||
internal class MetaDataDispenser
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
[ComImport,
|
||||
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
|
||||
CoClass(typeof(MetaDataDispenser)),
|
||||
Guid("809C652E-7396-11d2-9771-00A0C9B4D50C")]
|
||||
internal interface IMetaDataDispenser
|
||||
{
|
||||
// NYI
|
||||
void DefineScope();
|
||||
|
||||
// Incomplete - I don't really need to define IMetaDataImport.
|
||||
void OpenScope([In, MarshalAs(UnmanagedType.LPWStr)] string scope, uint flags, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object unknown);
|
||||
|
||||
// NYI
|
||||
void OpenScopeOnMemory();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
Reference in New Issue
Block a user