diff --git a/Debugger/Debugger.Core/AppDomain.cs b/Debugger/Debugger.Core/AppDomain.cs new file mode 100644 index 000000000..876e27cf5 --- /dev/null +++ b/Debugger/Debugger.Core/AppDomain.cs @@ -0,0 +1,63 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using Debugger.Interop.CorDebug; +using Debugger.MetaData; +using System.Collections.Generic; + +namespace Debugger +{ + public class AppDomain: DebuggerObject + { + Process process; + + ICorDebugAppDomain corAppDomain; + + internal Dictionary DebugTypeCache = new Dictionary(); + + public Process Process { + get { return process; } + } + + public uint ID { + get { + return corAppDomain.GetID(); + } + } + + Module mscorlib; + + public Module Mscorlib { + get { + if (mscorlib != null) return mscorlib; + foreach(Module m in Process.Modules) { + if (m.Name == "mscorlib.dll" && + m.AppDomain == this) { + mscorlib = m; + return mscorlib; + } + } + throw new DebuggerException("Mscorlib not loaded"); + } + } + + internal DebugType ObjectType { + get { return DebugType.CreateFromType(this.Mscorlib, typeof(object)); } + } + + internal ICorDebugAppDomain CorAppDomain { + get { return corAppDomain; } + } + + internal ICorDebugAppDomain2 CorAppDomain2 { + get { return (ICorDebugAppDomain2)corAppDomain; } + } + + public AppDomain(Process process, ICorDebugAppDomain corAppDomain) + { + this.process = process; + this.corAppDomain = corAppDomain; + } + } +} diff --git a/Debugger/Debugger.Core/AppDomainCollection.cs b/Debugger/Debugger.Core/AppDomainCollection.cs new file mode 100644 index 000000000..19c92e40f --- /dev/null +++ b/Debugger/Debugger.Core/AppDomainCollection.cs @@ -0,0 +1,24 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public class AppDomainCollection: CollectionWithEvents + { + public AppDomainCollection(NDebugger dbgr): base(dbgr) {} + + public AppDomain this[ICorDebugAppDomain corAppDomain] { + get { + foreach(AppDomain a in this) { + if (a.CorAppDomain.Equals(corAppDomain)) { + return a; + } + } + throw new DebuggerException("AppDomain not found"); + } + } + } +} diff --git a/Debugger/Debugger.Core/ArrayDimension.cs b/Debugger/Debugger.Core/ArrayDimension.cs new file mode 100644 index 000000000..2d8ec3156 --- /dev/null +++ b/Debugger/Debugger.Core/ArrayDimension.cs @@ -0,0 +1,70 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Debugger +{ + /// + /// Specifies the range of valid indicies for an array dimension + /// + public class ArrayDimension + { + int lowerBound; + int upperBound; + + /// The smallest valid index in this dimension + public int LowerBound { + get { return lowerBound; } + } + + /// The largest valid index in this dimension. + /// Returns LowerBound - 1 if the array is empty. + public int UpperBound { + get { return upperBound; } + } + + /// The number of valid indicies of this dimension + public int Count { + get { return upperBound - lowerBound + 1; } + } + + /// Determines whether the given index is a valid index for this dimension + public bool IsIndexValid(int index) + { + return (this.LowerBound <= index && index <= this.UpperBound); + } + + public ArrayDimension(int lowerBound, int upperBound) + { + this.lowerBound = lowerBound; + this.upperBound = upperBound; + } + + public override string ToString() + { + if (this.LowerBound == 0) { + return this.Count.ToString(); + } else { + return this.LowerBound + ".." + this.UpperBound; + } + } + + public override int GetHashCode() + { + int hashCode = 0; + unchecked { + hashCode += 1000000007 * lowerBound.GetHashCode(); + hashCode += 1000000009 * upperBound.GetHashCode(); + } + return hashCode; + } + + public override bool Equals(object obj) + { + ArrayDimension other = obj as ArrayDimension; + if (other == null) return false; + return this.lowerBound == other.lowerBound && this.upperBound == other.upperBound; + } + } +} diff --git a/Debugger/Debugger.Core/ArrayDimensions.cs b/Debugger/Debugger.Core/ArrayDimensions.cs new file mode 100644 index 000000000..b7973bf87 --- /dev/null +++ b/Debugger/Debugger.Core/ArrayDimensions.cs @@ -0,0 +1,109 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Debugger +{ + /// + /// Specifies the range of valid indicies for all array dimensions + /// + public class ArrayDimensions: IEnumerable + { + List dimensions = new List(); + + public IEnumerator GetEnumerator() + { + return dimensions.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)dimensions).GetEnumerator(); + } + + /// Gets a given dimension + public ArrayDimension this[int index] { + get { + return dimensions[index]; + } + } + + /// Get the number of dimensions of the array + public int Count { + get { + return dimensions.Count; + } + } + + /// Get the total number of elements within the bounds + /// of an array specified by these dimensions. + public int TotalElementCount { + get { + int totalCount = 1; + foreach(ArrayDimension dim in this) { + totalCount *= dim.Count; + } + return totalCount; + } + } + + /// Enumerate all vaild indicies in the array + public IEnumerable Indices { + get { + foreach(ArrayDimension dim in this) { + if (dim.Count == 0) yield break; + } + + int rank = this.Count; + int[] indices = new int[rank]; + for(int i = 0; i < rank; i++) { + indices[i] = this[i].LowerBound; + } + + while(true) { // Go thought all combinations + for (int i = rank - 1; i >= 1; i--) { + if (indices[i] > this[i].UpperBound) { + indices[i] = this[i].LowerBound; + indices[i - 1]++; + } + } + if (indices[0] > this[0].UpperBound) yield break; // We are done + + yield return (int[])indices.Clone(); + + indices[rank - 1]++; + } + } + } + + /// Determines whether the given index is a valid index for the array + public bool IsIndexValid(int[] indices) + { + for (int i = 0; i < this.Count; i++) { + if (!this[i].IsIndexValid(indices[i])) return false; + } + return true; + } + + public ArrayDimensions(List dimensions) + { + this.dimensions = dimensions; + } + + public override string ToString() + { + string result = "["; + bool isFirst = true; + foreach(ArrayDimension dim in this) { + if (!isFirst) result += ", "; + result += dim.ToString(); + isFirst = false; + } + result += "]"; + return result; + } + } +} diff --git a/Debugger/Debugger.Core/Breakpoint.cs b/Debugger/Debugger.Core/Breakpoint.cs new file mode 100644 index 000000000..4c18a81de --- /dev/null +++ b/Debugger/Debugger.Core/Breakpoint.cs @@ -0,0 +1,184 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public class Breakpoint: DebuggerObject + { + NDebugger debugger; + + string fileName; + byte[] checkSum; + int line; + int column; + bool enabled; + + SourcecodeSegment originalLocation; + + List corBreakpoints = new List(); + + public event EventHandler Hit; + public event EventHandler Set; + + [Debugger.Tests.Ignore] + public NDebugger Debugger { + get { return debugger; } + } + + public string FileName { + get { return fileName; } + } + + public byte[] CheckSum { + get { return checkSum; } + } + + public int Line { + get { return line; } + set { line = value; } + } + + public int Column { + get { return column; } + } + + public bool Enabled { + get { return enabled; } + set { + enabled = value; + foreach(ICorDebugFunctionBreakpoint corBreakpoint in corBreakpoints) { + corBreakpoint.Activate(enabled ? 1 : 0); + } + } + } + + public SourcecodeSegment OriginalLocation { + get { return originalLocation; } + } + + public bool IsSet { + get { + return corBreakpoints.Count > 0; + } + } + + protected virtual void OnHit(BreakpointEventArgs e) + { + if (Hit != null) { + Hit(this, e); + } + } + + internal void NotifyHit() + { + OnHit(new BreakpointEventArgs(this)); + debugger.Breakpoints.OnHit(this); + } + + protected virtual void OnSet(BreakpointEventArgs e) + { + if (Set != null) { + Set(this, e); + } + } + + public Breakpoint(NDebugger debugger, ICorDebugFunctionBreakpoint corBreakpoint) + { + this.debugger = debugger; + this.corBreakpoints.Add(corBreakpoint); + } + + public Breakpoint(NDebugger debugger, string fileName, byte[] checkSum, int line, int column, bool enabled) + { + this.debugger = debugger; + this.fileName = fileName; + this.checkSum = checkSum; + this.line = line; + this.column = column; + this.enabled = enabled; + } + + internal bool IsOwnerOf(ICorDebugBreakpoint breakpoint) + { + foreach(ICorDebugFunctionBreakpoint corFunBreakpoint in corBreakpoints) { + if (((ICorDebugBreakpoint)corFunBreakpoint).Equals(breakpoint)) return true; + } + return false; + } + + internal void Deactivate() + { + foreach(ICorDebugFunctionBreakpoint corBreakpoint in corBreakpoints) { + #if DEBUG + // Get repro + corBreakpoint.Activate(0); + #else + try { + corBreakpoint.Activate(0); + } catch(COMException e) { + // Sometimes happens, but we had not repro yet. + // 0x80131301: Process was terminated. + if ((uint)e.ErrorCode == 0x80131301) + continue; + throw; + } + #endif + } + corBreakpoints.Clear(); + } + + internal void MarkAsDeactivated() + { + corBreakpoints.Clear(); + } + + internal bool SetBreakpoint(Module module) + { + if (this.fileName == null) + return false; + + SourcecodeSegment segment = SourcecodeSegment.Resolve(module, FileName, CheckSum, Line, Column); + if (segment == null) return false; + + originalLocation = segment; + + ICorDebugFunctionBreakpoint corBreakpoint = segment.CorFunction.GetILCode().CreateBreakpoint((uint)segment.ILStart); + corBreakpoint.Activate(enabled ? 1 : 0); + + corBreakpoints.Add(corBreakpoint); + + OnSet(new BreakpointEventArgs(this)); + + return true; + } + + /// Remove this breakpoint + public void Remove() + { + debugger.Breakpoints.Remove(this); + } + } + + [Serializable] + public class BreakpointEventArgs : DebuggerEventArgs + { + Breakpoint breakpoint; + + public Breakpoint Breakpoint { + get { + return breakpoint; + } + } + + public BreakpointEventArgs(Breakpoint breakpoint): base(breakpoint.Debugger) + { + this.breakpoint = breakpoint; + } + } +} diff --git a/Debugger/Debugger.Core/BreakpointCollection.cs b/Debugger/Debugger.Core/BreakpointCollection.cs new file mode 100644 index 000000000..41912b8ad --- /dev/null +++ b/Debugger/Debugger.Core/BreakpointCollection.cs @@ -0,0 +1,88 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public class BreakpointCollection: CollectionWithEvents + { + public event EventHandler> Hit; + + protected internal void OnHit(Breakpoint item) + { + if (Hit != null) { + Hit(this, new CollectionItemEventArgs(item)); + } + } + + public BreakpointCollection(NDebugger debugger):base(debugger) { } + + internal Breakpoint this[ICorDebugBreakpoint corBreakpoint] { + get { + foreach (Breakpoint breakpoint in this) { + if (breakpoint.IsOwnerOf(corBreakpoint)) { + return breakpoint; + } + } + return null; + } + } + + public new void Add(Breakpoint breakpoint) + { + base.Add(breakpoint); + } + + public Breakpoint Add(string filename, int line) + { + Breakpoint breakpoint = new Breakpoint(this.Debugger, filename, null, line, 0, true); + Add(breakpoint); + return breakpoint; + } + + public Breakpoint Add(string fileName, byte[] checkSum, int line, int column, bool enabled) + { + Breakpoint breakpoint = new Breakpoint(this.Debugger, fileName, checkSum, line, column, enabled); + Add(breakpoint); + return breakpoint; + } + + protected override void OnAdded(Breakpoint breakpoint) + { + foreach(Process process in this.Debugger.Processes) { + foreach(Module module in process.Modules) { + breakpoint.SetBreakpoint(module); + } + } + + base.OnAdded(breakpoint); + } + + public new void Remove(Breakpoint breakpoint) + { + base.Remove(breakpoint); + } + + protected override void OnRemoved(Breakpoint breakpoint) + { + breakpoint.Deactivate(); + + base.OnRemoved(breakpoint); + } + + internal void SetInModule(Module module) + { + // This is in case that the client modifies the collection as a response to set breakpoint + // NB: If client adds new breakpoint, it will be set directly as a result of his call, not here (because module is already loaded) + List collection = new List(); + collection.AddRange(this); + + foreach (Breakpoint b in collection) { + b.SetBreakpoint(module); + } + } + } +} diff --git a/Debugger/Debugger.Core/CollectionWithEvents.cs b/Debugger/Debugger.Core/CollectionWithEvents.cs new file mode 100644 index 000000000..1a1715f11 --- /dev/null +++ b/Debugger/Debugger.Core/CollectionWithEvents.cs @@ -0,0 +1,109 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Debugger +{ + public class CollectionItemEventArgs : EventArgs + { + T item; + + public T Item { + get { + return item; + } + } + + public CollectionItemEventArgs(T item) + { + this.item = item; + } + } + + /// + /// A collection that fires events when items are added or removed. + /// + public class CollectionWithEvents : IEnumerable + { + NDebugger debugger; + + List list = new List(); + + public event EventHandler> Added; + public event EventHandler> Removed; + + protected virtual void OnAdded(T item) + { + if (Added != null) { + Added(this, new CollectionItemEventArgs(item)); + } + } + + protected virtual void OnRemoved(T item) + { + if (Removed != null) { + Removed(this, new CollectionItemEventArgs(item)); + } + } + + public CollectionWithEvents(NDebugger debugger) + { + this.debugger = debugger; + } + + protected NDebugger Debugger { + get { + return debugger; + } + } + + public int Count { + get { + return list.Count; + } + } + + public T this[int index] { + get { + return list[index]; + } + } + + internal void Add(T item) + { + list.Add(item); + OnAdded(item); + } + + internal void Remove(T item) + { + if (list.Remove(item)) { + OnRemoved(item); + } else { + throw new DebuggerException("Item is not in the collection"); + } + } + + internal void Clear() + { + List oldList = list; + list = new List(); + foreach (T item in oldList) { + OnRemoved(item); + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return list.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return list.GetEnumerator(); + } + } +} diff --git a/Debugger/Debugger.Core/DebuggeeState.cs b/Debugger/Debugger.Core/DebuggeeState.cs new file mode 100644 index 000000000..179125c37 --- /dev/null +++ b/Debugger/Debugger.Core/DebuggeeState.cs @@ -0,0 +1,28 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +namespace Debugger +{ + /// + /// Represents span of time in which the debugger state is assumed to + /// be unchanged. + /// + /// + /// For example, although property evaluation can in theory change + /// any memory, it is assumed that they behave 'correctly' and thus + /// property evaluation does not change debugger state. + /// + public class DebuggeeState: DebuggerObject + { + Process process; + + public Process Process { + get { return process; } + } + + public DebuggeeState(Process process) + { + this.process = process; + } + } +} diff --git a/Debugger/Debugger.Core/Debugger.Core.csproj b/Debugger/Debugger.Core/Debugger.Core.csproj new file mode 100644 index 000000000..7cdfbc25f --- /dev/null +++ b/Debugger/Debugger.Core/Debugger.Core.csproj @@ -0,0 +1,212 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} + Library + Debugger + Debugger.Core + File + False + False + False + Auto + 114294784 + AnyCPU + 4096 + 4 + false + ..\..\..\..\AddIns\Debugger\ + True + http://localhost/Debugger.Core/ + true + Web + true + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + true + false + true + v4.0 + Client + + + true + Full + DEBUG;TRACE + False + + + PdbOnly + true + TRACE + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + .NET Framework Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + + + + + + + + + {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} + NRefactory + + + + \ No newline at end of file diff --git a/Debugger/Debugger.Core/Debugger.Core.csproj.user b/Debugger/Debugger.Core/Debugger.Core.csproj.user new file mode 100644 index 000000000..bf3b4c208 --- /dev/null +++ b/Debugger/Debugger.Core/Debugger.Core.csproj.user @@ -0,0 +1,21 @@ + + + 8.0.50215 + ProjectFiles + 0 + + + + + + + + + + + + + en-US + true + + \ No newline at end of file diff --git a/Debugger/Debugger.Core/Debugger.Core.shfb b/Debugger/Debugger.Core/Debugger.Core.shfb new file mode 100644 index 000000000..70784bab4 --- /dev/null +++ b/Debugger/Debugger.Core/Debugger.Core.shfb @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + This library provides features for debugging managed applications. + Summary, Parameter, Returns, AutoDocumentCtors, Namespace + InheritedMembers, Protected, SealedProtected + + + .\docs\ + + + True + True + HtmlHelp1x + True + False + 2.0.50727 + True + False + False + False + + Managed Debugger + Managed Debugger + en-US + + 2005-2008 David Srbecký + dsrbecky@gmail.com + + + Local + Msdn + Blank + Prototype + Guid + Standard + False + AboveNamespaces + + + \ No newline at end of file diff --git a/Debugger/Debugger.Core/DebuggerException.cs b/Debugger/Debugger.Core/DebuggerException.cs new file mode 100644 index 000000000..9a7784835 --- /dev/null +++ b/Debugger/Debugger.Core/DebuggerException.cs @@ -0,0 +1,45 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +namespace Debugger +{ + /// + /// Type of exception thrown by the Debugger. + /// + public class DebuggerException: System.Exception + { + public DebuggerException() {} + public DebuggerException(string message): base(message) {} + public DebuggerException(string message, params object[] args): base(string.Format(message, args)) {} + public DebuggerException(string message, System.Exception inner): base(message, inner) {} + } + + /// + /// An exception that is thrown when the debugged process unexpectedly exits. + /// + public class ProcessExitedException: DebuggerException + { + string processName = null; + + /// + /// The name of the process that has exited. + /// + public string ProcessName { + get { return processName; } + } + + /// + /// Creates a ProcessExitedException for an unnamed process. + /// + public ProcessExitedException(): base("Process exited") {} + + /// + /// Creates a ProcessExitedException for a process. + /// + /// The name of the process + public ProcessExitedException(string processName): base(string.Format("Process '{0}' exited.", processName)) { + this.processName = processName; + } + + } +} diff --git a/Debugger/Debugger.Core/DebuggerObject.cs b/Debugger/Debugger.Core/DebuggerObject.cs new file mode 100644 index 000000000..714ef2779 --- /dev/null +++ b/Debugger/Debugger.Core/DebuggerObject.cs @@ -0,0 +1,15 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Debugger +{ + /// + /// A base class for all classes declared by the debugger + /// + public class DebuggerObject: MarshalByRefObject + { + + } +} diff --git a/Debugger/Debugger.Core/Eval.cs b/Debugger/Debugger.Core/Eval.cs new file mode 100644 index 000000000..4c7059637 --- /dev/null +++ b/Debugger/Debugger.Core/Eval.cs @@ -0,0 +1,416 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +using Debugger.MetaData; +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public enum EvalState { + Evaluating, + EvaluatedSuccessfully, + EvaluatedException, + EvaluatedNoResult, + EvaluatedTimeOut, + }; + + /// + /// This class holds information about function evaluation. + /// + public class Eval: DebuggerObject + { + delegate void EvalStarter(Eval eval); + + AppDomain appDomain; + Process process; + + string description; + ICorDebugEval corEval; + Thread thread; + Value result; + EvalState state; + + public AppDomain AppDomain { + get { return appDomain; } + } + + public Process Process { + get { return process; } + } + + public string Description { + get { return description; } + } + + public ICorDebugEval CorEval { + get { return corEval; } + } + + public ICorDebugEval2 CorEval2 { + get { return (ICorDebugEval2)corEval; } + } + + /// Evaluating... + public Value Result { + get { + switch(this.State) { + case EvalState.Evaluating: throw new GetValueException("Evaluating..."); + case EvalState.EvaluatedSuccessfully: return result; + case EvalState.EvaluatedException: return result; + case EvalState.EvaluatedNoResult: return null; + case EvalState.EvaluatedTimeOut: throw new GetValueException("Timeout"); + default: throw new DebuggerException("Unknown state"); + } + } + } + + public EvalState State { + get { return state; } + } + + public bool Evaluated { + get { + return state == EvalState.EvaluatedSuccessfully || + state == EvalState.EvaluatedException || + state == EvalState.EvaluatedNoResult || + state == EvalState.EvaluatedTimeOut; + } + } + + Eval(AppDomain appDomain, string description, EvalStarter evalStarter) + { + this.appDomain = appDomain; + this.process = appDomain.Process; + this.description = description; + this.state = EvalState.Evaluating; + this.thread = GetEvaluationThread(appDomain); + this.corEval = thread.CorThread.CreateEval(); + + try { + evalStarter(this); + } catch (COMException e) { + if ((uint)e.ErrorCode == 0x80131C26) { + throw new GetValueException("Can not evaluate in optimized code"); + } else if ((uint)e.ErrorCode == 0x80131C28) { + throw new GetValueException("Object is in wrong AppDomain"); + } else if ((uint)e.ErrorCode == 0x8013130A) { + // Happens on getting of Sytem.Threading.Thread.ManagedThreadId; See SD2-1116 + throw new GetValueException("Function does not have IL code"); + } else if ((uint)e.ErrorCode == 0x80131C23) { + // The operation failed because it is a GC unsafe point. (Exception from HRESULT: 0x80131C23) + // This can probably happen when we break and the thread is in native code + throw new GetValueException("Thread is in GC unsafe point"); + } else if ((uint)e.ErrorCode == 0x80131C22) { + // The operation is illegal because of a stack overflow. + throw new GetValueException("Can not evaluate after stack overflow"); + } else if ((uint)e.ErrorCode == 0x80131313) { + // Func eval cannot work. Bad starting point. + // Reproduction circumstancess are unknown + throw new GetValueException("Func eval cannot work. Bad starting point."); + } else { + #if DEBUG + throw; // Expose for more diagnostics + #else + throw new GetValueException(e.Message); + #endif + } + } + + appDomain.Process.ActiveEvals.Add(this); + + if (appDomain.Process.Options.SuspendOtherThreads) { + appDomain.Process.AsyncContinue(DebuggeeStateAction.Keep, new Thread[] { thread }, CorDebugThreadState.THREAD_SUSPEND); + } else { + appDomain.Process.AsyncContinue(DebuggeeStateAction.Keep, this.Process.UnsuspendedThreads, CorDebugThreadState.THREAD_RUN); + } + } + + static Thread GetEvaluationThread(AppDomain appDomain) + { + appDomain.Process.AssertPaused(); + + Thread st = appDomain.Process.SelectedThread; + if (st != null && !st.Suspended && !st.IsInNativeCode && st.IsAtSafePoint && st.CorThread.GetAppDomain().GetID() == appDomain.ID) { + return st; + } + + foreach(Thread t in appDomain.Process.Threads) { + if (!t.Suspended && !t.IsInNativeCode && t.IsAtSafePoint && t.CorThread.GetAppDomain().GetID() == appDomain.ID) { + return t; + } + } + + throw new GetValueException("No suitable thread for evaluation"); + } + + internal bool IsCorEval(ICorDebugEval corEval) + { + return this.corEval == corEval; + } + + /// Evaluation can not be stopped + /// Process exited + Value WaitForResult() + { + // Note that aborting is not supported for suspended threads + try { + process.WaitForPause(TimeSpan.FromMilliseconds(500)); + if (!Evaluated) { + process.TraceMessage("Aborting eval: " + Description); + this.CorEval.Abort(); + process.WaitForPause(TimeSpan.FromMilliseconds(2500)); + if (!Evaluated) { + process.TraceMessage("Rude aborting eval: " + Description); + this.CorEval2.RudeAbort(); + process.WaitForPause(TimeSpan.FromMilliseconds(5000)); + if (!Evaluated) { + throw new DebuggerException("Evaluation can not be stopped"); + } + } + // Note that this sets Evaluated to true + state = EvalState.EvaluatedTimeOut; + } + process.AssertPaused(); + return this.Result; + } catch (ProcessExitedException) { + throw new GetValueException("Process exited"); + } + } + + internal void NotifyEvaluationComplete(bool successful) + { + // Eval result should be ICorDebugHandleValue so it should survive Continue() + if (state == EvalState.EvaluatedTimeOut) { + return; + } + if (corEval.GetResult() == null) { + state = EvalState.EvaluatedNoResult; + } else { + if (successful) { + state = EvalState.EvaluatedSuccessfully; + } else { + state = EvalState.EvaluatedException; + } + result = new Value(AppDomain, corEval.GetResult()); + } + } + + /// Synchronously calls a function and returns its return value + public static Value InvokeMethod(DebugMethodInfo method, Value thisValue, Value[] args) + { + if (method.BackingField != null) { + method.Process.TraceMessage("Using backing field for " + method.FullName); + return Value.GetMemberValue(thisValue, method.BackingField, args); + } + return AsyncInvokeMethod(method, thisValue, args).WaitForResult(); + } + + public static Eval AsyncInvokeMethod(DebugMethodInfo method, Value thisValue, Value[] args) + { + return new Eval( + method.AppDomain, + "Function call: " + method.FullName, + delegate(Eval eval) { + MethodInvokeStarter(eval, method, thisValue, args); + } + ); + } + + /// GetValueException. + static void MethodInvokeStarter(Eval eval, DebugMethodInfo method, Value thisValue, Value[] args) + { + List corArgs = new List(); + args = args ?? new Value[0]; + if (args.Length != method.ParameterCount) { + throw new GetValueException("Invalid parameter count"); + } + if (!method.IsStatic) { + if (thisValue == null) + throw new GetValueException("'this' is null"); + if (thisValue.IsNull) + throw new GetValueException("Null reference"); + // if (!(thisValue.IsObject)) // eg Can evaluate on array + if (!method.DeclaringType.IsInstanceOfType(thisValue)) { + throw new GetValueException( + "Can not evaluate because the object is not of proper type. " + + "Expected: " + method.DeclaringType.FullName + " Seen: " + thisValue.Type.FullName + ); + } + corArgs.Add(thisValue.CorValue); + } + for(int i = 0; i < args.Length; i++) { + Value arg = args[i]; + DebugType paramType = (DebugType)method.GetParameters()[i].ParameterType; + if (!arg.Type.CanImplicitelyConvertTo(paramType)) + throw new GetValueException("Inncorrect parameter type"); + // Implicitely convert to correct primitve type + if (paramType.IsPrimitive && args[i].Type != paramType) { + object oldPrimVal = arg.PrimitiveValue; + object newPrimVal = Convert.ChangeType(oldPrimVal, paramType.PrimitiveType); + arg = CreateValue(method.AppDomain, newPrimVal); + } + // It is importatnt to pass the parameted in the correct form (boxed/unboxed) + if (paramType.IsValueType) { + corArgs.Add(arg.CorGenericValue); + } else { + if (args[i].Type.IsValueType) { + corArgs.Add(arg.Box().CorValue); + } else { + corArgs.Add(arg.CorValue); + } + } + } + + ICorDebugType[] genericArgs = ((DebugType)method.DeclaringType).GenericArgumentsAsCorDebugType; + eval.CorEval2.CallParameterizedFunction( + method.CorFunction, + (uint)genericArgs.Length, genericArgs, + (uint)corArgs.Count, corArgs.ToArray() + ); + } + + public static Value CreateValue(AppDomain appDomain, object value) + { + if (value == null) { + ICorDebugClass corClass = appDomain.ObjectType.CorType.GetClass(); + Thread thread = GetEvaluationThread(appDomain); + ICorDebugEval corEval = thread.CorThread.CreateEval(); + ICorDebugValue corValue = corEval.CreateValue((uint)CorElementType.CLASS, corClass); + return new Value(appDomain, corValue); + } else if (value is string) { + return Eval.NewString(appDomain, (string)value); + } else { + if (!value.GetType().IsPrimitive) + throw new DebuggerException("Value must be primitve type. Seen " + value.GetType()); + Value val = Eval.NewObjectNoConstructor(DebugType.CreateFromType(appDomain.Mscorlib, value.GetType())); + val.PrimitiveValue = value; + return val; + } + } + + /* + // The following function create values only for the purpuse of evalutaion + // They actually do not allocate memory on the managed heap + // The advantage is that it does not continue the process + /// Can not create string this way + public static Value CreateValue(Process process, object value) + { + if (value is string) throw new DebuggerException("Can not create string this way"); + CorElementType corElemType; + ICorDebugClass corClass = null; + if (value != null) { + corElemType = DebugType.TypeNameToCorElementType(value.GetType().FullName); + } else { + corElemType = CorElementType.CLASS; + corClass = DebugType.Create(process, null, typeof(object).FullName).CorType.Class; + } + ICorDebugEval corEval = CreateCorEval(process); + ICorDebugValue corValue = corEval.CreateValue((uint)corElemType, corClass); + Value v = new Value(process, new Expressions.PrimitiveExpression(value), corValue); + if (value != null) { + v.PrimitiveValue = value; + } + return v; + } + */ + + #region Convenience methods + + public static Value NewString(AppDomain appDomain, string textToCreate) + { + return AsyncNewString(appDomain, textToCreate).WaitForResult(); + } + + #endregion + + public static Eval AsyncNewString(AppDomain appDomain, string textToCreate) + { + return new Eval( + appDomain, + "New string: " + textToCreate, + delegate(Eval eval) { + eval.CorEval2.NewStringWithLength(textToCreate, (uint)textToCreate.Length); + } + ); + } + + #region Convenience methods + + public static Value NewArray(DebugType type, uint length, uint? lowerBound) + { + return AsyncNewArray(type, length, lowerBound).WaitForResult(); + } + + #endregion + + public static Eval AsyncNewArray(DebugType type, uint length, uint? lowerBound) + { + lowerBound = lowerBound ?? 0; + return new Eval( + type.AppDomain, + "New array: " + type + "[" + length + "]", + delegate(Eval eval) { + // Multi-dimensional arrays not supported in .NET 2.0 + eval.CorEval2.NewParameterizedArray(type.CorType, 1, new uint[] { length }, new uint[] { lowerBound.Value }); + } + ); + } + + #region Convenience methods + + public static Value NewObject(DebugMethodInfo constructor, Value[] constructorArguments) + { + return AsyncNewObject(constructor, constructorArguments).WaitForResult(); + } + + #endregion + + public static Eval AsyncNewObject(DebugMethodInfo constructor, Value[] constructorArguments) + { + ICorDebugValue[] constructorArgsCorDebug = ValuesAsCorDebug(constructorArguments); + return new Eval( + constructor.AppDomain, + "New object: " + constructor.FullName, + delegate(Eval eval) { + eval.CorEval2.NewParameterizedObject( + constructor.CorFunction, + (uint)constructor.DeclaringType.GetGenericArguments().Length, ((DebugType)constructor.DeclaringType).GenericArgumentsAsCorDebugType, + (uint)constructorArgsCorDebug.Length, constructorArgsCorDebug); + } + ); + } + + #region Convenience methods + + public static Value NewObjectNoConstructor(DebugType debugType) + { + return AsyncNewObjectNoConstructor(debugType).WaitForResult(); + } + + #endregion + + public static Eval AsyncNewObjectNoConstructor(DebugType debugType) + { + return new Eval( + debugType.AppDomain, + "New object: " + debugType.FullName, + delegate(Eval eval) { + eval.CorEval2.NewParameterizedObjectNoConstructor(debugType.CorType.GetClass(), (uint)debugType.GetGenericArguments().Length, debugType.GenericArgumentsAsCorDebugType); + } + ); + } + + static ICorDebugValue[] ValuesAsCorDebug(Value[] values) + { + ICorDebugValue[] valuesAsCorDebug = new ICorDebugValue[values.Length]; + for(int i = 0; i < values.Length; i++) { + valuesAsCorDebug[i] = values[i].CorValue; + } + return valuesAsCorDebug; + } + } +} diff --git a/Debugger/Debugger.Core/EvalCollection.cs b/Debugger/Debugger.Core/EvalCollection.cs new file mode 100644 index 000000000..6004c9dab --- /dev/null +++ b/Debugger/Debugger.Core/EvalCollection.cs @@ -0,0 +1,23 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public class EvalCollection: CollectionWithEvents + { + public EvalCollection(NDebugger debugger): base(debugger) {} + + internal Eval this[ICorDebugEval corEval] { + get { + foreach(Eval eval in this) { + if (eval.IsCorEval(corEval)) { + return eval; + } + } + throw new DebuggerException("Eval not found for given ICorDebugEval"); + } + } + } +} diff --git a/Debugger/Debugger.Core/Exception.cs b/Debugger/Debugger.Core/Exception.cs new file mode 100644 index 000000000..ee75897de --- /dev/null +++ b/Debugger/Debugger.Core/Exception.cs @@ -0,0 +1,121 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System.Text; + +namespace Debugger +{ + /// This convenience class provides access to an exception within the debugee. + /// + public class Exception: DebuggerObject + { + Value exception; + + public Value Value { + get { return exception; } + } + + public Exception(Value exception) + { + this.exception = exception; + } + + /// The GetType().FullName of the exception. + /// + public string Type { + get { + return exception.Type.FullName; + } + } + + /// The Message property of the exception. + /// + public string Message { + get { + Value message = exception.GetMemberValue("_message"); + return message.IsNull ? string.Empty : message.AsString(); + } + } + + /// The InnerException property of the exception. + /// + public Exception InnerException { + get { + Value innerException = exception.GetMemberValue("_innerException"); + return innerException.IsNull ? null : new Exception(innerException); + } + } + + public void MakeValuePermanent() + { + exception = exception.GetPermanentReference(); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(this.Type); + if (!string.IsNullOrEmpty(this.Message)) { + sb.Append(": "); + sb.Append(this.Message); + } + if (this.InnerException != null) { + sb.Append(" ---> "); + sb.Append(this.InnerException.ToString()); + } + return sb.ToString(); + } + + public string GetStackTrace() + { + return GetStackTrace("--- End of inner exception stack trace ---"); + } + + /// Returs formated stacktrace for the exception + /// Getting the stacktrace involves property + /// evaluation so GetValueException can be thrown in some cicumstances. + public string GetStackTrace(string endOfInnerExceptionFormat) + { + StringBuilder sb = new StringBuilder(); + if (this.InnerException != null) { + sb.Append(this.InnerException.GetStackTrace(endOfInnerExceptionFormat)); + sb.Append(" "); + sb.Append(endOfInnerExceptionFormat); + sb.AppendLine(); + } + // Note that evaluation is not possible after a stackoverflow exception + Value stackTrace = exception.GetMemberValue("StackTrace"); + if (!stackTrace.IsNull) { + sb.Append(stackTrace.AsString()); + sb.AppendLine(); + } + return sb.ToString(); + } + } + + public class ExceptionEventArgs: ProcessEventArgs + { + readonly Exception exception; + readonly ExceptionType exceptionType; + readonly bool isUnhandled; + + public Exception Exception { + get { return exception; } + } + + public ExceptionType ExceptionType { + get { return exceptionType; } + } + + public bool IsUnhandled { + get { return isUnhandled; } + } + + public ExceptionEventArgs(Process process, Exception exception, ExceptionType exceptionType, bool isUnhandled):base(process) + { + this.exception = exception; + this.exceptionType = exceptionType; + this.isUnhandled = isUnhandled; + } + } +} diff --git a/Debugger/Debugger.Core/ExceptionType.cs b/Debugger/Debugger.Core/ExceptionType.cs new file mode 100644 index 000000000..287bcf31d --- /dev/null +++ b/Debugger/Debugger.Core/ExceptionType.cs @@ -0,0 +1,13 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +namespace Debugger +{ + public enum ExceptionType + { + FirstChance = 1, + UserFirstChance = 2, + CatchHandlerFound = 3, + Unhandled = 4, + } +} diff --git a/Debugger/Debugger.Core/GetValueException.cs b/Debugger/Debugger.Core/GetValueException.cs new file mode 100644 index 000000000..a1adb2fa4 --- /dev/null +++ b/Debugger/Debugger.Core/GetValueException.cs @@ -0,0 +1,56 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.NRefactory.Ast; + +namespace Debugger +{ + public class GetValueException: DebuggerException + { + INode expression; + string error; + + /// Expression that has caused this exception to occur + public INode Expression { + get { return expression; } + set { expression = value; } + } + + public string Error { + get { return error; } + } + + public override string Message { + get { + if (expression == null) { + return error; + } else { + return error; + // return String.Format("Error evaluating \"{0}\": {1}", expression.PrettyPrint(), error); + } + } + } + + public GetValueException(INode expression, string error):base(error) + { + this.expression = expression; + this.error = error; + } + + public GetValueException(string error, System.Exception inner):base(error, inner) + { + this.error = error; + } + + public GetValueException(string errorFmt, params object[] args):base(string.Format(errorFmt, args)) + { + this.error = string.Format(errorFmt, args); + } + + public GetValueException(string error):base(error) + { + this.error = error; + } + } +} diff --git a/Debugger/Debugger.Core/Interop/Common.cs b/Debugger/Debugger.Core/Interop/Common.cs new file mode 100644 index 000000000..a78bea07e --- /dev/null +++ b/Debugger/Debugger.Core/Interop/Common.cs @@ -0,0 +1,85 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +#pragma warning disable 108, 1591 + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Debugger.Interop +{ + // These are used in both CorDebug and CorSym + + [StructLayout(LayoutKind.Sequential, Pack=4)] + public struct _FILETIME + { + public uint dwLowDateTime; + public uint dwHighDateTime; + } + + [StructLayout(LayoutKind.Sequential, Pack=8)] + public struct _LARGE_INTEGER + { + public long QuadPart; + } + + [StructLayout(LayoutKind.Sequential, Pack=8)] + public struct _ULARGE_INTEGER + { + public ulong QuadPart; + } + + [ComImport, Guid("0C733A30-2A1C-11CE-ADE5-00AA0044773D"), InterfaceType((short) 1)] + public interface ISequentialStream + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RemoteRead(out byte pv, [In] uint cb, out uint pcbRead); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RemoteWrite([In] ref byte pv, [In] uint cb, out uint pcbWritten); + } + + [ComImport, InterfaceType((short) 1), Guid("0000000C-0000-0000-C000-000000000046")] + public interface IStream : ISequentialStream + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RemoteRead(out byte pv, [In] uint cb, out uint pcbRead); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RemoteWrite([In] ref byte pv, [In] uint cb, out uint pcbWritten); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RemoteSeek([In] _LARGE_INTEGER dlibMove, [In] uint dwOrigin, out _ULARGE_INTEGER plibNewPosition); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetSize([In] _ULARGE_INTEGER libNewSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RemoteCopyTo([In, MarshalAs(UnmanagedType.Interface)] IStream pstm, [In] _ULARGE_INTEGER cb, out _ULARGE_INTEGER pcbRead, out _ULARGE_INTEGER pcbWritten); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Commit([In] uint grfCommitFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Revert(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __LockRegion([In] _ULARGE_INTEGER libOffset, [In] _ULARGE_INTEGER cb, [In] uint dwLockType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __UnlockRegion([In] _ULARGE_INTEGER libOffset, [In] _ULARGE_INTEGER cb, [In] uint dwLockType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Stat(out tagSTATSTG pstatstg, [In] uint grfStatFlag); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out IStream ppstm); + } + + [StructLayout(LayoutKind.Sequential, Pack=8)] + public struct tagSTATSTG + { + [MarshalAs(UnmanagedType.LPWStr)] + public string pwcsName; + public uint type; + public _ULARGE_INTEGER cbSize; + public _FILETIME mtime; + public _FILETIME ctime; + public _FILETIME atime; + public uint grfMode; + public uint grfLocksSupported; + public Guid clsid; + public uint grfStateBits; + public uint reserved; + } +} diff --git a/Debugger/Debugger.Core/Interop/CorDebug.cs b/Debugger/Debugger.Core/Interop/CorDebug.cs new file mode 100644 index 000000000..fba895667 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/CorDebug.cs @@ -0,0 +1,1632 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +#pragma warning disable 108, 1591 + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Debugger.Interop.CorDebug +{ + [StructLayout(LayoutKind.Sequential, Pack=4)] + public struct _COR_IL_MAP + { + public uint oldOffset; + public uint newOffset; + public int fAccurate; + } + + [StructLayout(LayoutKind.Sequential, Pack=4)] + public struct _COR_VERSION + { + public uint dwMajor; + public uint dwMinor; + public uint dwBuild; + public uint dwSubBuild; + } + + [StructLayout(LayoutKind.Sequential, Pack=4)] + public struct _SECURITY_ATTRIBUTES + { + public uint nLength; + public IntPtr lpSecurityDescriptor; + public int bInheritHandle; + } + + [StructLayout(LayoutKind.Sequential, Pack=4)] + public struct COR_DEBUG_STEP_RANGE + { + public uint startOffset; + public uint endOffset; + } + + [ComImport, CoClass(typeof(CorDebugClass)), Guid("3D6F5F61-7538-11D3-8D5B-00104B35E7EF")] + public interface CorDebug : ICorDebug + { + } + + public enum CorDebugChainReason + { + CHAIN_CLASS_INIT = 1, + CHAIN_CONTEXT_POLICY = 8, + CHAIN_CONTEXT_SWITCH = 0x400, + CHAIN_DEBUGGER_EVAL = 0x200, + CHAIN_ENTER_MANAGED = 0x80, + CHAIN_ENTER_UNMANAGED = 0x100, + CHAIN_EXCEPTION_FILTER = 2, + CHAIN_FUNC_EVAL = 0x800, + CHAIN_INTERCEPTION = 0x10, + CHAIN_NONE = 0, + CHAIN_PROCESS_START = 0x20, + CHAIN_SECURITY = 4, + CHAIN_THREAD_START = 0x40 + } + + [Flags] + public enum CorDebugJITCompilerFlags + { + CORDEBUG_JIT_DEFAULT = 0x1, + CORDEBUG_JIT_DISABLE_OPTIMIZATION = 0x3, + CORDEBUG_JIT_ENABLE_ENC = 0x7 + } + + [ComImport, TypeLibType((short) 2), Guid("6FEF44D0-39E7-4C77-BE8E-C9F8CF988630"), ClassInterface((short) 0)] + public class CorDebugClass : ICorDebug, CorDebug + { + // Methods + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __CanLaunchOrAttach([In] uint dwProcessId, [In] int win32DebuggingEnabled); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __CreateProcess([In, MarshalAs(UnmanagedType.LPWStr)] string lpApplicationName, [In, MarshalAs(UnmanagedType.LPWStr)] string lpCommandLine, [In] ref _SECURITY_ATTRIBUTES lpProcessAttributes, [In] ref _SECURITY_ATTRIBUTES lpThreadAttributes, [In] int bInheritHandles, [In] uint dwCreationFlags, [In] IntPtr lpEnvironment, [In, MarshalAs(UnmanagedType.LPWStr)] string lpCurrentDirectory, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint lpStartupInfo, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint lpProcessInformation, [In] CorDebugCreateProcessFlags debuggingFlags, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __DebugActiveProcess([In] uint id, [In] int win32Attach, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __EnumerateProcesses([MarshalAs(UnmanagedType.Interface)] out ICorDebugProcessEnum ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetProcess([In] uint dwProcessId, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Initialize(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __SetManagedHandler([In, MarshalAs(UnmanagedType.Interface)] ICorDebugManagedCallback pCallback); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __SetUnmanagedHandler([In, MarshalAs(UnmanagedType.Interface)] ICorDebugUnmanagedCallback pCallback); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Terminate(); + } + + public enum CorDebugCreateProcessFlags + { + DEBUG_NO_SPECIAL_OPTIONS + } + + public enum CorDebugExceptionCallbackType + { + DEBUG_EXCEPTION_CATCH_HANDLER_FOUND = 3, + DEBUG_EXCEPTION_FIRST_CHANCE = 1, + DEBUG_EXCEPTION_UNHANDLED = 4, + DEBUG_EXCEPTION_USER_FIRST_CHANCE = 2 + } + + public enum CorDebugExceptionUnwindCallbackType + { + DEBUG_EXCEPTION_INTERCEPTED = 2, + DEBUG_EXCEPTION_UNWIND_BEGIN = 1 + } + + public enum CorDebugHandleType + { + HANDLE_STRONG = 1, + HANDLE_WEAK_TRACK_RESURRECTION = 2 + } + + public enum CorDebugIntercept + { + INTERCEPT_ALL = 0xffff, + INTERCEPT_CLASS_INIT = 1, + INTERCEPT_CONTEXT_POLICY = 8, + INTERCEPT_EXCEPTION_FILTER = 2, + INTERCEPT_INTERCEPTION = 0x10, + INTERCEPT_NONE = 0, + INTERCEPT_SECURITY = 4 + } + + public enum CorDebugInternalFrameType + { + STUBFRAME_NONE, + STUBFRAME_M2U, + STUBFRAME_U2M, + STUBFRAME_APPDOMAIN_TRANSITION, + STUBFRAME_LIGHTWEIGHT_FUNCTION, + STUBFRAME_FUNC_EVAL, + STUBFRAME_INTERNALCALL + } + + public enum CorDebugMappingResult + { + MAPPING_APPROXIMATE = 0x20, + MAPPING_EPILOG = 2, + MAPPING_EXACT = 0x10, + MAPPING_NO_INFO = 4, + MAPPING_PROLOG = 1, + MAPPING_UNMAPPED_ADDRESS = 8 + } + + public enum CorDebugMDAFlags + { + MDA_FLAG_SLIP = 2 + } + + public enum CorDebugRegister + { + REGISTER_AMD64_R10 = 11, + REGISTER_AMD64_R11 = 12, + REGISTER_AMD64_R12 = 13, + REGISTER_AMD64_R13 = 14, + REGISTER_AMD64_R14 = 15, + REGISTER_AMD64_R15 = 0x10, + REGISTER_AMD64_R8 = 9, + REGISTER_AMD64_R9 = 10, + REGISTER_AMD64_RAX = 3, + REGISTER_AMD64_RBP = 2, + REGISTER_AMD64_RBX = 6, + REGISTER_AMD64_RCX = 4, + REGISTER_AMD64_RDI = 8, + REGISTER_AMD64_RDX = 5, + REGISTER_AMD64_RIP = 0, + REGISTER_AMD64_RSI = 7, + REGISTER_AMD64_RSP = 1, + REGISTER_AMD64_XMM0 = 0x11, + REGISTER_AMD64_XMM1 = 0x12, + REGISTER_AMD64_XMM10 = 0x1b, + REGISTER_AMD64_XMM11 = 0x1c, + REGISTER_AMD64_XMM12 = 0x1d, + REGISTER_AMD64_XMM13 = 30, + REGISTER_AMD64_XMM14 = 0x1f, + REGISTER_AMD64_XMM15 = 0x20, + REGISTER_AMD64_XMM2 = 0x13, + REGISTER_AMD64_XMM3 = 20, + REGISTER_AMD64_XMM4 = 0x15, + REGISTER_AMD64_XMM5 = 0x16, + REGISTER_AMD64_XMM6 = 0x17, + REGISTER_AMD64_XMM7 = 0x18, + REGISTER_AMD64_XMM8 = 0x19, + REGISTER_AMD64_XMM9 = 0x1a, + REGISTER_FRAME_POINTER = 2, + REGISTER_IA64_BSP = 2, + REGISTER_IA64_F0 = 0x83, + REGISTER_IA64_R0 = 3, + REGISTER_INSTRUCTION_POINTER = 0, + REGISTER_STACK_POINTER = 1, + REGISTER_X86_EAX = 3, + REGISTER_X86_EBP = 2, + REGISTER_X86_EBX = 6, + REGISTER_X86_ECX = 4, + REGISTER_X86_EDI = 8, + REGISTER_X86_EDX = 5, + REGISTER_X86_EIP = 0, + REGISTER_X86_ESI = 7, + REGISTER_X86_ESP = 1, + REGISTER_X86_FPSTACK_0 = 9, + REGISTER_X86_FPSTACK_1 = 10, + REGISTER_X86_FPSTACK_2 = 11, + REGISTER_X86_FPSTACK_3 = 12, + REGISTER_X86_FPSTACK_4 = 13, + REGISTER_X86_FPSTACK_5 = 14, + REGISTER_X86_FPSTACK_6 = 15, + REGISTER_X86_FPSTACK_7 = 0x10 + } + + public enum CorDebugStepReason + { + STEP_NORMAL, + STEP_RETURN, + STEP_CALL, + STEP_EXCEPTION_FILTER, + STEP_EXCEPTION_HANDLER, + STEP_INTERCEPT, + STEP_EXIT + } + + public enum CorDebugThreadState + { + THREAD_RUN, + THREAD_SUSPEND + } + + public enum CorDebugUnmappedStop + { + STOP_ALL = 0xffff, + STOP_EPILOG = 2, + STOP_NO_MAPPING_INFO = 4, + STOP_NONE = 0, + STOP_OTHER_UNMAPPED = 8, + STOP_PROLOG = 1, + STOP_UNMANAGED = 0x10 + } + + public enum CorDebugUserState + { + USER_BACKGROUND = 4, + USER_STOP_REQUESTED = 1, + USER_STOPPED = 0x10, + USER_SUSPEND_REQUESTED = 2, + USER_SUSPENDED = 0x40, + USER_UNSAFE_POINT = 0x80, + USER_UNSTARTED = 8, + USER_WAIT_SLEEP_JOIN = 0x20 + } + + public enum CorElementType: uint + { + END = 0x0, + VOID = 0x1, + BOOLEAN = 0x2, + CHAR = 0x3, + I1 = 0x4, + U1 = 0x5, + I2 = 0x6, + U2 = 0x7, + I4 = 0x8, + U4 = 0x9, + I8 = 0xa, + U8 = 0xb, + R4 = 0xc, + R8 = 0xd, + STRING = 0xe, + + // every type above PTR will be simple type + PTR = 0xf, // PTR + BYREF = 0x10, // BYREF + + // Please use VALUETYPE. VALUECLASS is deprecated. + VALUETYPE = 0x11, // VALUETYPE + CLASS = 0x12, // CLASS + VAR = 0x13, + ARRAY = 0x14, // MDARRAY ... ... + GENERICINST = 0x15, + TYPEDBYREF = 0x16, // This is a simple type. + + I = 0x18, // native integer size + U = 0x19, // native unsigned integer size + FNPTR = 0x1B, // FNPTR + OBJECT = 0x1C, // Shortcut for System.Object + SZARRAY = 0x1D, // Shortcut for single dimension zero lower bound array + // SZARRAY + + // This is only for binding + CMOD_REQD = 0x1F, // required C modifier : E_T_CMOD_REQD + CMOD_OPT = 0x20, // optional C modifier : E_T_CMOD_OPT + + // This is for signatures generated internally (which will not be persisted in any way). + INTERNAL = 0x21, // INTERNAL + + // Note that this is the max of base type excluding modifiers + MAX = 0x22, // first invalid element type + + MODIFIER = 0x40, + SENTINEL = 0x01 | MODIFIER, // sentinel for varargs + PINNED = 0x05 | MODIFIER, + + } + + [ComImport, Guid("3D6F5F61-7538-11D3-8D5B-00104B35E7EF"), CoClass(typeof(EmbeddedCLRCorDebugClass))] + public interface EmbeddedCLRCorDebug : ICorDebug + { + } + + [ComImport, Guid("211F1254-BC7E-4AF5-B9AA-067308D83DD1"), ClassInterface((short) 0), TypeLibType((short) 2)] + public class EmbeddedCLRCorDebugClass : ICorDebug, EmbeddedCLRCorDebug + { + // Methods + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __CanLaunchOrAttach([In] uint dwProcessId, [In] int win32DebuggingEnabled); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __CreateProcess([In, MarshalAs(UnmanagedType.LPWStr)] string lpApplicationName, [In, MarshalAs(UnmanagedType.LPWStr)] string lpCommandLine, [In] ref _SECURITY_ATTRIBUTES lpProcessAttributes, [In] ref _SECURITY_ATTRIBUTES lpThreadAttributes, [In] int bInheritHandles, [In] uint dwCreationFlags, [In] IntPtr lpEnvironment, [In, MarshalAs(UnmanagedType.LPWStr)] string lpCurrentDirectory, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint lpStartupInfo, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint lpProcessInformation, [In] CorDebugCreateProcessFlags debuggingFlags, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __DebugActiveProcess([In] uint id, [In] int win32Attach, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __EnumerateProcesses([MarshalAs(UnmanagedType.Interface)] out ICorDebugProcessEnum ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetProcess([In] uint dwProcessId, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Initialize(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __SetManagedHandler([In, MarshalAs(UnmanagedType.Interface)] ICorDebugManagedCallback pCallback); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __SetUnmanagedHandler([In, MarshalAs(UnmanagedType.Interface)] ICorDebugUnmanagedCallback pCallback); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Terminate(); + } + + [ComImport, Guid("3D6F5F61-7538-11D3-8D5B-00104B35E7EF"), InterfaceType((short) 1)] + public interface ICorDebug + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Initialize(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Terminate(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetManagedHandler([In, MarshalAs(UnmanagedType.Interface)] ICorDebugManagedCallback pCallback); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetUnmanagedHandler([In, MarshalAs(UnmanagedType.Interface)] ICorDebugUnmanagedCallback pCallback); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateProcess([In, MarshalAs(UnmanagedType.LPWStr)] string lpApplicationName, [In, MarshalAs(UnmanagedType.LPWStr)] string lpCommandLine, [In] ref _SECURITY_ATTRIBUTES lpProcessAttributes, [In] ref _SECURITY_ATTRIBUTES lpThreadAttributes, [In] int bInheritHandles, [In] uint dwCreationFlags, [In] IntPtr lpEnvironment, [In, MarshalAs(UnmanagedType.LPWStr)] string lpCurrentDirectory, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint lpStartupInfo, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint lpProcessInformation, [In] CorDebugCreateProcessFlags debuggingFlags, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DebugActiveProcess([In] uint id, [In] int win32Attach, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateProcesses([MarshalAs(UnmanagedType.Interface)] out ICorDebugProcessEnum ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetProcess([In] uint dwProcessId, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CanLaunchOrAttach([In] uint dwProcessId, [In] int win32DebuggingEnabled); + } + + [ComImport, InterfaceType((short) 1), Guid("3D6F5F63-7538-11D3-8D5B-00104B35E7EF"), ComConversionLoss] + public interface ICorDebugAppDomain : ICorDebugController + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Stop([In] uint dwTimeoutIgnored); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Continue([In] int fIsOutOfBand); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsRunning(out int pbRunning); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __HasQueuedCallbacks([In, MarshalAs(UnmanagedType.Interface)] ICorDebugThread pThread, out int pbQueued); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateThreads([MarshalAs(UnmanagedType.Interface)] out ICorDebugThreadEnum ppThreads); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetAllThreadsDebugState([In] CorDebugThreadState state, [In, MarshalAs(UnmanagedType.Interface)] ICorDebugThread pExceptThisThread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Detach(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Terminate([In] uint exitCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CanCommitChanges([In] uint cSnapshots, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugEditAndContinueSnapshot pSnapshots, [MarshalAs(UnmanagedType.Interface)] out ICorDebugErrorInfoEnum pError); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CommitChanges([In] uint cSnapshots, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugEditAndContinueSnapshot pSnapshots, [MarshalAs(UnmanagedType.Interface)] out ICorDebugErrorInfoEnum pError); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetProcess([MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateAssemblies([MarshalAs(UnmanagedType.Interface)] out ICorDebugAssemblyEnum ppAssemblies); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetModuleFromMetaDataInterface([In, MarshalAs(UnmanagedType.IUnknown)] object pIMetaData, [MarshalAs(UnmanagedType.Interface)] out ICorDebugModule ppModule); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateBreakpoints([MarshalAs(UnmanagedType.Interface)] out ICorDebugBreakpointEnum ppBreakpoints); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateSteppers([MarshalAs(UnmanagedType.Interface)] out ICorDebugStepperEnum ppSteppers); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsAttached(out int pbAttached); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetName([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetObject([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppObject); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Attach(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetID(out uint pId); + } + + [ComImport, InterfaceType((short) 1), Guid("096E81D5-ECDA-4202-83F5-C65980A9EF75")] + public interface ICorDebugAppDomain2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetArrayOrPointerType([In] uint elementType, [In] uint nRank, [In, MarshalAs(UnmanagedType.Interface)] ICorDebugType pTypeArg, [MarshalAs(UnmanagedType.Interface)] out ICorDebugType ppType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunctionPointerType([In] uint nTypeArgs, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugType ppTypeArgs, [MarshalAs(UnmanagedType.Interface)] out ICorDebugType ppType); + } + + [ComImport, InterfaceType((short) 1), Guid("63CA1B24-4359-4883-BD57-13F815F58744"), ComConversionLoss] + public interface ICorDebugAppDomainEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr values, out uint pceltFetched); + } + + [ComImport, Guid("0405B0DF-A660-11D2-BD02-0000F80849BD"), InterfaceType((short) 1), ComConversionLoss] + public interface ICorDebugArrayValue : ICorDebugHeapValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsValid(out int pbValid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateRelocBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetElementType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRank(out uint pnRank); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pnCount); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetDimensions([In] uint cdim, [Out] IntPtr dims); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __HasBaseIndicies(out int pbHasBaseIndicies); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetBaseIndicies([In] uint cdim, [Out] IntPtr indicies); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetElement([In] uint cdim, [In] IntPtr indices, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetElementAtPosition([In] uint nPosition, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + } + + [ComImport, Guid("DF59507C-D47A-459E-BCE2-6427EAC8FD06"), InterfaceType((short) 1), ComConversionLoss] + public interface ICorDebugAssembly + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetProcess([MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAppDomain([MarshalAs(UnmanagedType.Interface)] out ICorDebugAppDomain ppAppDomain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateModules([MarshalAs(UnmanagedType.Interface)] out ICorDebugModuleEnum ppModules); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCodeBase([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetName([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + } + + [ComImport, Guid("426D1F9E-6DD4-44C8-AEC7-26CDBAF4E398"), InterfaceType((short) 1)] + public interface ICorDebugAssembly2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsFullyTrusted(out int pbFullyTrusted); + } + + [ComImport, InterfaceType((short) 1), Guid("4A2A1EC9-85EC-4BFB-9F15-A89FDFE0FE83"), ComConversionLoss] + public interface ICorDebugAssemblyEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr values, out uint pceltFetched); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCAFC-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugBoxValue : ICorDebugHeapValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsValid(out int pbValid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateRelocBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetObject([MarshalAs(UnmanagedType.Interface)] out ICorDebugObjectValue ppObject); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCAE8-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugBreakpoint + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Activate([In] int bActive); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsActive(out int pbActive); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCB03-8A68-11D2-983C-0000F808342D"), ComConversionLoss] + public interface ICorDebugBreakpointEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr breakpoints, out uint pceltFetched); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCAEE-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugChain + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetThread([MarshalAs(UnmanagedType.Interface)] out ICorDebugThread ppThread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetStackRange(out ulong pStart, out ulong pEnd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetContext([MarshalAs(UnmanagedType.Interface)] out ICorDebugContext ppContext); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCaller([MarshalAs(UnmanagedType.Interface)] out ICorDebugChain ppChain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCallee([MarshalAs(UnmanagedType.Interface)] out ICorDebugChain ppChain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetPrevious([MarshalAs(UnmanagedType.Interface)] out ICorDebugChain ppChain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetNext([MarshalAs(UnmanagedType.Interface)] out ICorDebugChain ppChain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsManaged(out int pManaged); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateFrames([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrameEnum ppFrames); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetActiveFrame([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRegisterSet([MarshalAs(UnmanagedType.Interface)] out ICorDebugRegisterSet ppRegisters); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetReason(out CorDebugChainReason pReason); + } + + [ComImport, ComConversionLoss, InterfaceType((short) 1), Guid("CC7BCB08-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugChainEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray)] ICorDebugChain[] chains, out uint pceltFetched); + } + + [ComImport, Guid("CC7BCAF5-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugClass + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetModule([MarshalAs(UnmanagedType.Interface)] out ICorDebugModule pModule); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetToken(out uint pTypeDef); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetStaticFieldValue([In] uint fieldDef, [In, MarshalAs(UnmanagedType.Interface)] ICorDebugFrame pFrame, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + } + + [ComImport, InterfaceType((short) 1), Guid("B008EA8D-7AB1-43F7-BB20-FBB5A04038AE")] + public interface ICorDebugClass2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetParameterizedType([In] uint elementType, [In] uint nTypeArgs, [In, MarshalAs(UnmanagedType.LPArray)] ICorDebugType[] ppTypeArgs, [MarshalAs(UnmanagedType.Interface)] out ICorDebugType ppType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetJMCStatus([In] int bIsJustMyCode); + } + + [ComImport, ComConversionLoss, Guid("CC7BCAF4-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugCode + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsIL(out int pbIL); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunction([MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pStart); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pcBytes); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([In] uint offset, [MarshalAs(UnmanagedType.Interface)] out ICorDebugFunctionBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCode([In] uint startOffset, [In] uint endOffset, [In] uint cBufferAlloc, [Out] IntPtr buffer, out uint pcBufferSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetVersionNumber(out uint nVersion); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetILToNativeMapping([In] uint cMap, out uint pcMap, [Out] IntPtr map); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetEnCRemapSequencePoints([In] uint cMap, out uint pcMap, [Out] IntPtr offsets); + } + + [ComImport, Guid("55E96461-9645-45E4-A2FF-0367877ABCDE"), InterfaceType((short) 1), ComConversionLoss] + public interface ICorDebugCodeEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr values, out uint pceltFetched); + } + + [ComImport, Guid("CC7BCB00-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugContext : ICorDebugObjectValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetClass([MarshalAs(UnmanagedType.Interface)] out ICorDebugClass ppClass); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFieldValue([In, MarshalAs(UnmanagedType.Interface)] ICorDebugClass pClass, [In] uint fieldDef, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetVirtualMethod([In] uint memberRef, [MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetContext([MarshalAs(UnmanagedType.Interface)] out ICorDebugContext ppContext); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsValueClass(out int pbIsValueClass); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetManagedCopy([MarshalAs(UnmanagedType.IUnknown)] out object ppObject); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetFromManagedCopy([In, MarshalAs(UnmanagedType.IUnknown)] object pObject); + } + + [ComImport, Guid("3D6F5F62-7538-11D3-8D5B-00104B35E7EF"), InterfaceType((short) 1)] + public interface ICorDebugController + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Stop([In] uint dwTimeoutIgnored); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Continue([In] int fIsOutOfBand); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsRunning(out int pbRunning); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __HasQueuedCallbacks([In, MarshalAs(UnmanagedType.Interface)] ICorDebugThread pThread, out int pbQueued); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateThreads([MarshalAs(UnmanagedType.Interface)] out ICorDebugThreadEnum ppThreads); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetAllThreadsDebugState([In] CorDebugThreadState state, [In, MarshalAs(UnmanagedType.Interface)] ICorDebugThread pExceptThisThread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Detach(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Terminate([In] uint exitCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CanCommitChanges([In] uint cSnapshots, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugEditAndContinueSnapshot pSnapshots, [MarshalAs(UnmanagedType.Interface)] out ICorDebugErrorInfoEnum pError); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CommitChanges([In] uint cSnapshots, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugEditAndContinueSnapshot pSnapshots, [MarshalAs(UnmanagedType.Interface)] out ICorDebugErrorInfoEnum pError); + } + + [ComImport, InterfaceType((short) 1), Guid("6DC3FA01-D7CB-11D2-8A95-0080C792E5D8")] + public interface ICorDebugEditAndContinueSnapshot + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CopyMetaData([In, MarshalAs(UnmanagedType.Interface)] IStream pIStream, out Guid pMvid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetMvid(out Guid pMvid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRoDataRVA(out uint pRoDataRVA); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRwDataRVA(out uint pRwDataRVA); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetPEBytes([In, MarshalAs(UnmanagedType.Interface)] IStream pIStream); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetILMap([In] uint mdFunction, [In] uint cMapSize, [In] ref _COR_IL_MAP map); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetPESymbolBytes([In, MarshalAs(UnmanagedType.Interface)] IStream pIStream); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCB01-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + } + + [ComImport, ComConversionLoss, Guid("F0E18809-72B5-11D2-976F-00A0C9B4D50C"), InterfaceType((short) 1)] + public interface ICorDebugErrorInfoEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr errors, out uint pceltFetched); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCAF6-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugEval + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CallFunction([In, MarshalAs(UnmanagedType.Interface)] ICorDebugFunction pFunction, [In] uint nArgs, [In, MarshalAs(UnmanagedType.LPArray)] ICorDebugValue[] ppArgs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __NewObject([In, MarshalAs(UnmanagedType.Interface)] ICorDebugFunction pConstructor, [In] uint nArgs, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugValue ppArgs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __NewObjectNoConstructor([In, MarshalAs(UnmanagedType.Interface)] ICorDebugClass pClass); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __NewString([In, MarshalAs(UnmanagedType.LPWStr)] string @string); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __NewArray([In] uint elementType, [In, MarshalAs(UnmanagedType.Interface)] ICorDebugClass pElementClass, [In] uint rank, [In] ref uint dims, [In] ref uint lowBounds); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsActive(out int pbActive); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Abort(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetResult([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppResult); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetThread([MarshalAs(UnmanagedType.Interface)] out ICorDebugThread ppThread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateValue([In] uint elementType, [In, MarshalAs(UnmanagedType.Interface)] ICorDebugClass pElementClass, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + } + + [ComImport, Guid("FB0D9CE7-BE66-4683-9D32-A42A04E2FD91"), InterfaceType((short) 1)] + public interface ICorDebugEval2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CallParameterizedFunction([In, MarshalAs(UnmanagedType.Interface)] ICorDebugFunction pFunction, [In] uint nTypeArgs, [In, MarshalAs(UnmanagedType.LPArray)] ICorDebugType[] ppTypeArgs, [In] uint nArgs, [In, MarshalAs(UnmanagedType.LPArray)] ICorDebugValue[] ppArgs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateValueForType([In, MarshalAs(UnmanagedType.Interface)] ICorDebugType pType, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __NewParameterizedObject([In, MarshalAs(UnmanagedType.Interface)] ICorDebugFunction pConstructor, [In] uint nTypeArgs, [In, MarshalAs(UnmanagedType.LPArray)] ICorDebugType[] ppTypeArgs, [In] uint nArgs, [In, MarshalAs(UnmanagedType.LPArray)] ICorDebugValue[] ppArgs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __NewParameterizedObjectNoConstructor([In, MarshalAs(UnmanagedType.Interface)] ICorDebugClass pClass, [In] uint nTypeArgs, [In, MarshalAs(UnmanagedType.LPArray)] ICorDebugType[] ppTypeArgs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __NewParameterizedArray([In, MarshalAs(UnmanagedType.Interface)] ICorDebugType pElementType, [In] uint rank, [In, MarshalAs(UnmanagedType.LPArray)] uint[] dims, [In, MarshalAs(UnmanagedType.LPArray)] uint[] lowBounds); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __NewStringWithLength([In, MarshalAs(UnmanagedType.LPWStr)] string @string, [In] uint uiLength); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RudeAbort(); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCAEF-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugFrame + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetChain([MarshalAs(UnmanagedType.Interface)] out ICorDebugChain ppChain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCode([MarshalAs(UnmanagedType.Interface)] out ICorDebugCode ppCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunction([MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunctionToken(out uint pToken); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetStackRange(out ulong pStart, out ulong pEnd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCaller([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCallee([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateStepper([MarshalAs(UnmanagedType.Interface)] out ICorDebugStepper ppStepper); + } + + [ComImport, InterfaceType((short) 1), ComConversionLoss, Guid("CC7BCB07-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugFrameEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray)] ICorDebugFrame[] frames, out uint pceltFetched); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCAF3-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugFunction + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetModule([MarshalAs(UnmanagedType.Interface)] out ICorDebugModule ppModule); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetClass([MarshalAs(UnmanagedType.Interface)] out ICorDebugClass ppClass); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetToken(out uint pMethodDef); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetILCode([MarshalAs(UnmanagedType.Interface)] out ICorDebugCode ppCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetNativeCode([MarshalAs(UnmanagedType.Interface)] out ICorDebugCode ppCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugFunctionBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetLocalVarSigToken(out uint pmdSig); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCurrentVersionNumber(out uint pnCurrentVersion); + } + + [ComImport, Guid("EF0C490B-94C3-4E4D-B629-DDC134C532D8"), InterfaceType((short) 1)] + public interface ICorDebugFunction2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetJMCStatus([In] int bIsJustMyCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetJMCStatus(out int pbIsJustMyCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateNativeCode([MarshalAs(UnmanagedType.Interface)] out ICorDebugCodeEnum ppCodeEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetVersionNumber(out uint pnVersion); + } + + [ComImport, Guid("CC7BCAE9-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugFunctionBreakpoint : ICorDebugBreakpoint + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Activate([In] int bActive); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsActive(out int pbActive); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunction([MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetOffset(out uint pnOffset); + } + + [ComImport, Guid("CC7BCAF8-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugGenericValue : ICorDebugValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetValue([Out] IntPtr pTo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetValue([In] IntPtr pFrom); + } + + [ComImport, InterfaceType((short) 1), Guid("029596E8-276B-46A1-9821-732E96BBB00B")] + public interface ICorDebugHandleValue : ICorDebugReferenceValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsNull(out int pbNull); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetValue(out ulong pValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetValue([In] ulong value); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Dereference([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DereferenceStrong([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetHandleType(out CorDebugHandleType pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Dispose(); + } + + [ComImport, Guid("CC7BCAFA-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugHeapValue : ICorDebugValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsValid(out int pbValid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateRelocBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + } + + [ComImport, Guid("E3AC4D6C-9CB7-43E6-96CC-B21540E5083C"), InterfaceType((short) 1)] + public interface ICorDebugHeapValue2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateHandle([In] CorDebugHandleType type, [MarshalAs(UnmanagedType.Interface)] out ICorDebugHandleValue ppHandle); + } + + [ComImport, InterfaceType((short) 1), Guid("03E26311-4F76-11D3-88C6-006097945418")] + public interface ICorDebugILFrame : ICorDebugFrame + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetChain([MarshalAs(UnmanagedType.Interface)] out ICorDebugChain ppChain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCode([MarshalAs(UnmanagedType.Interface)] out ICorDebugCode ppCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunction([MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunctionToken(out uint pToken); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetStackRange(out ulong pStart, out ulong pEnd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCaller([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCallee([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateStepper([MarshalAs(UnmanagedType.Interface)] out ICorDebugStepper ppStepper); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetIP(out uint pnOffset, out CorDebugMappingResult pMappingResult); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetIP([In] uint nOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateLocalVariables([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueEnum ppValueEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetLocalVariable([In] uint dwIndex, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateArguments([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueEnum ppValueEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetArgument([In] uint dwIndex, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetStackDepth(out uint pDepth); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetStackValue([In] uint dwIndex, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CanSetIP([In] uint nOffset); + } + + [ComImport, Guid("5D88A994-6C30-479B-890F-BCEF88B129A5"), InterfaceType((short) 1)] + public interface ICorDebugILFrame2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RemapFunction([In] uint newILOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateTypeParameters([MarshalAs(UnmanagedType.Interface)] out ICorDebugTypeEnum ppTyParEnum); + } + + [ComImport, Guid("B92CC7F7-9D2D-45C4-BC2B-621FCC9DFBF4"), InterfaceType((short) 1)] + public interface ICorDebugInternalFrame : ICorDebugFrame + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetChain([MarshalAs(UnmanagedType.Interface)] out ICorDebugChain ppChain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCode([MarshalAs(UnmanagedType.Interface)] out ICorDebugCode ppCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunction([MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunctionToken(out uint pToken); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetStackRange(out ulong pStart, out ulong pEnd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCaller([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCallee([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateStepper([MarshalAs(UnmanagedType.Interface)] out ICorDebugStepper ppStepper); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFrameType(out CorDebugInternalFrameType pType); + } + + [ComImport, ComConversionLoss, Guid("CC726F2F-1DB7-459B-B0EC-05F01D841B42"), InterfaceType((short) 1)] + public interface ICorDebugMDA + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetName([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetDescription([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetXML([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFlags([In] ref CorDebugMDAFlags pFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetOSThreadId(out uint pOsTid); + } + + [ComImport, Guid("3D6F5F60-7538-11D3-8D5B-00104B35E7EF"), InterfaceType((short) 1)] + public interface ICorDebugManagedCallback + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void Breakpoint([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] IntPtr pBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void StepComplete([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] IntPtr pStepper, [In] CorDebugStepReason reason); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void Break([In] IntPtr pAppDomain, [In] IntPtr thread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void Exception([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] int unhandled); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EvalComplete([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] IntPtr pEval); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EvalException([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] IntPtr pEval); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void CreateProcess([In] IntPtr pProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void ExitProcess([In] IntPtr pProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void CreateThread([In] IntPtr pAppDomain, [In] IntPtr thread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void ExitThread([In] IntPtr pAppDomain, [In] IntPtr thread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void LoadModule([In] IntPtr pAppDomain, [In] IntPtr pModule); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void UnloadModule([In] IntPtr pAppDomain, [In] IntPtr pModule); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void LoadClass([In] IntPtr pAppDomain, [In] IntPtr c); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void UnloadClass([In] IntPtr pAppDomain, [In] IntPtr c); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void DebuggerError([In] IntPtr pProcess, [In, MarshalAs(UnmanagedType.Error)] int errorHR, [In] uint errorCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void LogMessage([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] int lLevel, [In] IntPtr pLogSwitchName, [In] IntPtr pMessage); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void LogSwitch([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] int lLevel, [In] uint ulReason, [In] IntPtr pLogSwitchName, [In] IntPtr pParentName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void CreateAppDomain([In] IntPtr pProcess, [In] IntPtr pAppDomain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void ExitAppDomain([In] IntPtr pProcess, [In] IntPtr pAppDomain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void LoadAssembly([In] IntPtr pAppDomain, [In] IntPtr pAssembly); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void UnloadAssembly([In] IntPtr pAppDomain, [In] IntPtr pAssembly); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void ControlCTrap([In] IntPtr pProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void NameChange([In] IntPtr pAppDomain, [In] IntPtr pThread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void UpdateModuleSymbols([In] IntPtr pAppDomain, [In] IntPtr pModule, [In] IntPtr pSymbolStream); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EditAndContinueRemap([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] IntPtr pFunction, [In] int fAccurate); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void BreakpointSetError([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] IntPtr pBreakpoint, [In] uint dwError); + } + + [ComImport, Guid("250E5EEA-DB5C-4C76-B6F3-8C46F12E3203"), InterfaceType((short) 1)] + public interface ICorDebugManagedCallback2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void FunctionRemapOpportunity([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] IntPtr pOldFunction, [In] IntPtr pNewFunction, [In] uint oldILOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void CreateConnection([In] IntPtr pProcess, [In] uint dwConnectionId, [In] IntPtr pConnName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void ChangeConnection([In] IntPtr pProcess, [In] uint dwConnectionId); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void DestroyConnection([In] IntPtr pProcess, [In] uint dwConnectionId); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void Exception([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] IntPtr pFrame, [In] uint nOffset, [In] CorDebugExceptionCallbackType dwEventType, [In] uint dwFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void ExceptionUnwind([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] CorDebugExceptionUnwindCallbackType dwEventType, [In] uint dwFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void FunctionRemapComplete([In] IntPtr pAppDomain, [In] IntPtr pThread, [In] IntPtr pFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void MDANotification([In] IntPtr pController, [In] IntPtr pThread, [In] IntPtr pMDA); + } + + [ComImport, Guid("DBA2D8C1-E5C5-4069-8C13-10A7C6ABF43D"), ComConversionLoss, InterfaceType((short) 1)] + public interface ICorDebugModule + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetProcess([MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetBaseAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAssembly([MarshalAs(UnmanagedType.Interface)] out ICorDebugAssembly ppAssembly); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetName([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnableJITDebugging([In] int bTrackJITInfo, [In] int bAllowJitOpts); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnableClassLoadCallbacks([In] int bClassLoadCallbacks); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunctionFromToken([In] uint methodDef, [MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunctionFromRVA([In] ulong rva, [MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetClassFromToken([In] uint typeDef, [MarshalAs(UnmanagedType.Interface)] out ICorDebugClass ppClass); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugModuleBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetEditAndContinueSnapshot([MarshalAs(UnmanagedType.Interface)] out ICorDebugEditAndContinueSnapshot ppEditAndContinueSnapshot); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetMetaDataInterface([In] ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppObj); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetToken(out uint pToken); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsDynamic(out int pDynamic); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetGlobalVariableValue([In] uint fieldDef, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pcBytes); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsInMemory(out int pInMemory); + } + + [ComImport, InterfaceType((short) 1), Guid("7FCC5FB5-49C0-41DE-9938-3B88B5B9ADD7")] + public interface ICorDebugModule2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetJMCStatus([In] int bIsJustMyCode, [In] uint cTokens, [In] ref uint pTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __ApplyChanges([In] uint cbMetadata, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbMetadata, [In] uint cbIL, [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbIL); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetJITCompilerFlags([In] uint dwFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetJITCompilerFlags(out uint pdwFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __ResolveAssembly([In] uint tkAssemblyRef, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugAssembly ppAssembly); + } + + [ComImport, InterfaceType((short) 1), Guid("86F012BF-FF15-4372-BD30-B6F11CAAE1DD")] + public interface ICorDebugModule3 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateReaderForInMemorySymbols([In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppObj); + } + + [ComImport, Guid("CC7BCAEA-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugModuleBreakpoint : ICorDebugBreakpoint + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Activate([In] int bActive); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsActive(out int pbActive); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetModule([MarshalAs(UnmanagedType.Interface)] out ICorDebugModule ppModule); + } + + [ComImport, InterfaceType((short) 1), ComConversionLoss, Guid("CC7BCB09-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugModuleEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr modules, out uint pceltFetched); + } + + [ComImport, InterfaceType((short) 1), Guid("03E26314-4F76-11D3-88C6-006097945418")] + public interface ICorDebugNativeFrame : ICorDebugFrame + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetChain([MarshalAs(UnmanagedType.Interface)] out ICorDebugChain ppChain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCode([MarshalAs(UnmanagedType.Interface)] out ICorDebugCode ppCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunction([MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFunctionToken(out uint pToken); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetStackRange(out ulong pStart, out ulong pEnd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCaller([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCallee([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateStepper([MarshalAs(UnmanagedType.Interface)] out ICorDebugStepper ppStepper); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetIP(out uint pnOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetIP([In] uint nOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRegisterSet([MarshalAs(UnmanagedType.Interface)] out ICorDebugRegisterSet ppRegisters); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetLocalRegisterValue([In] CorDebugRegister reg, [In] uint cbSigBlob, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint pvSigBlob, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetLocalDoubleRegisterValue([In] CorDebugRegister highWordReg, [In] CorDebugRegister lowWordReg, [In] uint cbSigBlob, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint pvSigBlob, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetLocalMemoryValue([In] ulong address, [In] uint cbSigBlob, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint pvSigBlob, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetLocalRegisterMemoryValue([In] CorDebugRegister highWordReg, [In] ulong lowWordAddress, [In] uint cbSigBlob, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint pvSigBlob, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetLocalMemoryRegisterValue([In] ulong highWordAddress, [In] CorDebugRegister lowWordRegister, [In] uint cbSigBlob, [In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint pvSigBlob, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CanSetIP([In] uint nOffset); + } + + [ComImport, ComConversionLoss, InterfaceType((short) 1), Guid("CC7BCB02-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugObjectEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr objects, out uint pceltFetched); + } + + [ComImport, Guid("18AD3D6E-B7D2-11D2-BD04-0000F80849BD"), InterfaceType((short) 1)] + public interface ICorDebugObjectValue : ICorDebugValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetClass([MarshalAs(UnmanagedType.Interface)] out ICorDebugClass ppClass); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFieldValue([In, MarshalAs(UnmanagedType.Interface)] ICorDebugClass pClass, [In] uint fieldDef, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetVirtualMethod([In] uint memberRef, [MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetContext([MarshalAs(UnmanagedType.Interface)] out ICorDebugContext ppContext); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsValueClass(out int pbIsValueClass); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetManagedCopy([MarshalAs(UnmanagedType.IUnknown)] out object ppObject); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetFromManagedCopy([In, MarshalAs(UnmanagedType.IUnknown)] object pObject); + } + + [ComImport, Guid("49E4A320-4A9B-4ECA-B105-229FB7D5009F"), InterfaceType((short) 1)] + public interface ICorDebugObjectValue2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetVirtualMethodAndType([In] uint memberRef, [MarshalAs(UnmanagedType.Interface)] out ICorDebugFunction ppFunction, [MarshalAs(UnmanagedType.Interface)] out ICorDebugType ppType); + } + + [ComImport, InterfaceType((short) 1), ComConversionLoss, Guid("3D6F5F64-7538-11D3-8D5B-00104B35E7EF")] + public interface ICorDebugProcess : ICorDebugController + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Stop([In] uint dwTimeoutIgnored); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Continue([In] int fIsOutOfBand); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsRunning(out int pbRunning); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __HasQueuedCallbacks([In, MarshalAs(UnmanagedType.Interface)] ICorDebugThread pThread, out int pbQueued); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateThreads([MarshalAs(UnmanagedType.Interface)] out ICorDebugThreadEnum ppThreads); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetAllThreadsDebugState([In] CorDebugThreadState state, [In, MarshalAs(UnmanagedType.Interface)] ICorDebugThread pExceptThisThread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Detach(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Terminate([In] uint exitCode); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CanCommitChanges([In] uint cSnapshots, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugEditAndContinueSnapshot pSnapshots, [MarshalAs(UnmanagedType.Interface)] out ICorDebugErrorInfoEnum pError); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CommitChanges([In] uint cSnapshots, [In, MarshalAs(UnmanagedType.Interface)] ref ICorDebugEditAndContinueSnapshot pSnapshots, [MarshalAs(UnmanagedType.Interface)] out ICorDebugErrorInfoEnum pError); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetID(out uint pdwProcessId); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetHandle([ComAliasName("Debugger.Interop.CorDebug.long")] out uint phProcessHandle); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetThread([In] uint dwThreadId, [MarshalAs(UnmanagedType.Interface)] out ICorDebugThread ppThread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateObjects([MarshalAs(UnmanagedType.Interface)] out ICorDebugObjectEnum ppObjects); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsTransitionStub([In] ulong address, out int pbTransitionStub); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsOSSuspended([In] uint threadID, out int pbSuspended); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetThreadContext([In] uint threadID, [In] uint contextSize, [In, Out] IntPtr context); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetThreadContext([In] uint threadID, [In] uint contextSize, [In] IntPtr context); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __ReadMemory([In] ulong address, [In] uint size, [Out] IntPtr buffer, [ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] out uint read); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __WriteMemory([In] ulong address, [In] uint size, [In] IntPtr buffer, [ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] out uint written); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __ClearCurrentException([In] uint threadID); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnableLogMessages([In] int fOnOff); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __ModifyLogSwitch([In] IntPtr pLogSwitchName, [In] int lLevel); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateAppDomains([MarshalAs(UnmanagedType.Interface)] out ICorDebugAppDomainEnum ppAppDomains); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetObject([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppObject); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __ThreadForFiberCookie([In] uint fiberCookie, [MarshalAs(UnmanagedType.Interface)] out ICorDebugThread ppThread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetHelperThreadID(out uint pThreadID); + } + + [ComImport, ComConversionLoss, Guid("AD1B3588-0EF0-4744-A496-AA09A9F80371"), InterfaceType((short) 1)] + public interface ICorDebugProcess2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetThreadForTaskID([In] ulong taskid, [MarshalAs(UnmanagedType.Interface)] out ICorDebugThread2 ppThread); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetVersion(out _COR_VERSION version); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetUnmanagedBreakpoint([In] ulong address, [In] uint bufsize, [Out] IntPtr buffer, out uint bufLen); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __ClearUnmanagedBreakpoint([In] ulong address); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetDesiredNGENCompilerFlags([In] uint pdwFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetDesiredNGENCompilerFlags(out uint pdwFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetReferenceValueFromGCHandle([In, ComAliasName("Debugger.Interop.CorDebug.UINT_PTR")] uint handle, [MarshalAs(UnmanagedType.Interface)] out ICorDebugReferenceValue pOutValue); + } + + [ComImport, Guid("CC7BCB05-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1), ComConversionLoss] + public interface ICorDebugProcessEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr processes, out uint pceltFetched); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCAF9-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugReferenceValue : ICorDebugValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsNull(out int pbNull); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetValue(out ulong pValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetValue([In] ulong value); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Dereference([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DereferenceStrong([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + } + + [ComImport, Guid("CC7BCB0B-8A68-11D2-983C-0000F808342D"), ComConversionLoss, InterfaceType((short) 1)] + public interface ICorDebugRegisterSet + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRegistersAvailable(out ulong pAvailable); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRegisters([In] ulong mask, [In] uint regCount, [Out] IntPtr regBuffer); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetRegisters([In] ulong mask, [In] uint regCount, [In] ref ulong regBuffer); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetThreadContext([In] uint contextSize, [In, Out] IntPtr context); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetThreadContext([In] uint contextSize, [In] IntPtr context); + } + + [ComImport, Guid("CC7BCAEC-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugStepper + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsActive(out int pbActive); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Deactivate(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetInterceptMask([In] CorDebugIntercept mask); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetUnmappedStopMask([In] CorDebugUnmappedStop mask); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Step([In] int bStepIn); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __StepRange([In] int bStepIn, [In] IntPtr ranges, [In] uint cRangeCount); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __StepOut(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetRangeIL([In] int bIL); + } + + [ComImport, Guid("C5B6E9C3-E7D1-4A8E-873B-7F047F0706F7"), InterfaceType((short) 1)] + public interface ICorDebugStepper2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetJMC([In] int fIsJMCStepper); + } + + [ComImport, Guid("CC7BCB04-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1), ComConversionLoss] + public interface ICorDebugStepperEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr steppers, out uint pceltFetched); + } + + [ComImport, Guid("CC7BCAFD-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1), ComConversionLoss] + public interface ICorDebugStringValue : ICorDebugHeapValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsValid(out int pbValid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateRelocBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetLength(out uint pcchString); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetString([In] uint cchString, out uint pcchString, [Out] IntPtr szString); + } + + [ComImport, InterfaceType((short) 1), Guid("938C6D66-7FB6-4F69-B389-425B8987329B")] + public interface ICorDebugThread + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetProcess([MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetID(out uint pdwThreadId); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetHandle([ComAliasName("Debugger.Interop.CorDebug.long")] out uint phThreadHandle); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAppDomain([MarshalAs(UnmanagedType.Interface)] out ICorDebugAppDomain ppAppDomain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetDebugState([In] CorDebugThreadState state); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetDebugState(out CorDebugThreadState pState); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetUserState(out CorDebugUserState pState); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCurrentException([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppExceptionObject); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __ClearCurrentException(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateStepper([MarshalAs(UnmanagedType.Interface)] out ICorDebugStepper ppStepper); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateChains([MarshalAs(UnmanagedType.Interface)] out ICorDebugChainEnum ppChains); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetActiveChain([MarshalAs(UnmanagedType.Interface)] out ICorDebugChain ppChain); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetActiveFrame([MarshalAs(UnmanagedType.Interface)] out ICorDebugFrame ppFrame); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRegisterSet([MarshalAs(UnmanagedType.Interface)] out ICorDebugRegisterSet ppRegisters); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateEval([MarshalAs(UnmanagedType.Interface)] out ICorDebugEval ppEval); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetObject([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppObject); + } + + [ComImport, InterfaceType((short) 1), Guid("2BD956D9-7B07-4BEF-8A98-12AA862417C5"), ComConversionLoss] + public interface ICorDebugThread2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetActiveFunctions([In] uint cFunctions, out uint pcFunctions, [In, Out] IntPtr pFunctions); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetConnectionID(out uint pdwConnectionId); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetTaskID(out ulong pTaskId); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetVolatileOSThreadID(out uint pdwTid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __InterceptCurrentException([In, MarshalAs(UnmanagedType.Interface)] ICorDebugFrame pFrame); + } + + [ComImport, InterfaceType((short) 1), ComConversionLoss, Guid("CC7BCB06-8A68-11D2-983C-0000F808342D")] + public interface ICorDebugThreadEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray)] ICorDebugThread[] threads, out uint pceltFetched); + } + + [ComImport, Guid("D613F0BB-ACE1-4C19-BD72-E4C08D5DA7F5"), InterfaceType((short) 1)] + public interface ICorDebugType + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint ty); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetClass([MarshalAs(UnmanagedType.Interface)] out ICorDebugClass ppClass); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumerateTypeParameters([MarshalAs(UnmanagedType.Interface)] out ICorDebugTypeEnum ppTyParEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetFirstTypeParameter([MarshalAs(UnmanagedType.Interface)] out ICorDebugType value); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetBase([MarshalAs(UnmanagedType.Interface)] out ICorDebugType pBase); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetStaticFieldValue([In] uint fieldDef, [In, MarshalAs(UnmanagedType.Interface)] ICorDebugFrame pFrame, [MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRank(out uint pnRank); + } + + [ComImport, InterfaceType((short) 1), Guid("10F27499-9DF2-43CE-8333-A321D7C99CB4"), ComConversionLoss] + public interface ICorDebugTypeEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray)] ICorDebugType[] values, out uint pceltFetched); + } + + [ComImport, Guid("5263E909-8CB5-11D3-BD2F-0000F80849BD"), InterfaceType((short) 1)] + public interface ICorDebugUnmanagedCallback + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DebugEvent([In, ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] uint pDebugEvent, [In] int fOutOfBand); + } + + [ComImport, Guid("CC7BCAF7-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugValue + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetType(out uint pType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSize(out uint pSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetAddress(out ulong pAddress); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CreateBreakpoint([MarshalAs(UnmanagedType.Interface)] out ICorDebugValueBreakpoint ppBreakpoint); + } + + [ComImport, InterfaceType((short) 1), Guid("5E0B54E7-D88A-4626-9420-A691E0A78B49")] + public interface ICorDebugValue2 + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetExactType([MarshalAs(UnmanagedType.Interface)] out ICorDebugType ppType); + } + + [ComImport, Guid("CC7BCAEB-8A68-11D2-983C-0000F808342D"), InterfaceType((short) 1)] + public interface ICorDebugValueBreakpoint : ICorDebugBreakpoint + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Activate([In] int bActive); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsActive(out int pbActive); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetValue([MarshalAs(UnmanagedType.Interface)] out ICorDebugValue ppValue); + } + + [ComImport, InterfaceType((short) 1), Guid("CC7BCB0A-8A68-11D2-983C-0000F808342D"), ComConversionLoss] + public interface ICorDebugValueEnum : ICorDebugEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorDebugEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [Out] IntPtr values, out uint pceltFetched); + } +} + +#pragma warning restore 108, 1591 diff --git a/Debugger/Debugger.Core/Interop/CorDebugExtensionMethods.cs b/Debugger/Debugger.Core/Interop/CorDebugExtensionMethods.cs new file mode 100644 index 000000000..a1d4a722d --- /dev/null +++ b/Debugger/Debugger.Core/Interop/CorDebugExtensionMethods.cs @@ -0,0 +1,242 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Debugger.Interop.CorDebug +{ + public static partial class CorDebugExtensionMethods + { + const int EnumerateBufferSize = 16; + + static void ProcessOutParameter(object parameter) + { + TrackedComObjects.ProcessOutParameter(parameter); + } + + // ICorDebugArrayValue + + public static unsafe uint[] GetDimensions(this ICorDebugArrayValue corArray) + { + uint[] dimensions = new uint[corArray.GetRank()]; + fixed(uint* pDimensions = dimensions) + corArray.GetDimensions((uint)dimensions.Length, new IntPtr(pDimensions)); + return dimensions; + } + + public static unsafe uint[] GetBaseIndicies(this ICorDebugArrayValue corArray) + { + uint[] baseIndicies = new uint[corArray.GetRank()]; + fixed(uint* pBaseIndicies = baseIndicies) + corArray.GetBaseIndicies((uint)baseIndicies.Length, new IntPtr(pBaseIndicies)); + return baseIndicies; + } + + public static unsafe ICorDebugValue GetElement(this ICorDebugArrayValue corArray, uint[] indices) + { + fixed(uint* pIndices = indices) + return corArray.GetElement((uint)indices.Length, new IntPtr(pIndices)); + } + + public static unsafe ICorDebugValue GetElement(this ICorDebugArrayValue corArray, int[] indices) + { + fixed(int* pIndices = indices) + return corArray.GetElement((uint)indices.Length, new IntPtr(pIndices)); + } + + // ICorDebugClass2 + + public static ICorDebugType GetParameterizedType(this ICorDebugClass2 corClass, uint elementType, ICorDebugType[] ppTypeArgs) + { + return corClass.GetParameterizedType(elementType, (uint)ppTypeArgs.Length, ppTypeArgs); + } + + // ICorDebugCode + + public static unsafe byte[] GetCode(this ICorDebugCode corCode) + { + byte[] code = new byte[corCode.GetSize()]; + fixed(byte* pCode = code) + corCode.GetCode(0, (uint)code.Length, (uint)code.Length, new IntPtr(pCode)); + return code; + } + + // ICorDebugEnum + + public static IEnumerable GetEnumerator(this ICorDebugFrameEnum corEnum) + { + corEnum.Reset(); + while (true) { + ICorDebugFrame[] corFrames = new ICorDebugFrame[EnumerateBufferSize]; + uint fetched = corEnum.Next(EnumerateBufferSize, corFrames); + if (fetched == 0) + yield break; + for(int i = 0; i < fetched; i++) + yield return corFrames[i]; + } + } + + public static ICorDebugFrame Next(this ICorDebugFrameEnum corEnum) + { + ICorDebugFrame[] corFrames = new ICorDebugFrame[] { null }; + uint framesFetched = corEnum.Next(1, corFrames); + return corFrames[0]; + } + + public static IEnumerable GetEnumerator(this ICorDebugChainEnum corEnum) + { + corEnum.Reset(); + while (true) { + ICorDebugChain[] corChains = new ICorDebugChain[EnumerateBufferSize]; + uint fetched = corEnum.Next(EnumerateBufferSize, corChains); + if (fetched == 0) + yield break; + for(int i = 0; i < fetched; i++) + yield return corChains[i]; + } + } + + public static ICorDebugChain Next(this ICorDebugChainEnum corChainEnum) + { + ICorDebugChain[] corChains = new ICorDebugChain[] { null }; + uint chainsFetched = corChainEnum.Next(1, corChains); + return corChains[0]; + } + + // ICorDebugGenericValue + + public static unsafe Byte[] GetRawValue(this ICorDebugGenericValue corGenVal) + { + byte[] retValue = new byte[(int)corGenVal.GetSize()]; + fixed(byte* pRetValue = retValue) + corGenVal.GetValue(new IntPtr(pRetValue)); + return retValue; + } + + public static unsafe void SetRawValue(this ICorDebugGenericValue corGenVal, byte[] value) + { + if (corGenVal.GetSize() != value.Length) + throw new ArgumentException("Incorrect length"); + fixed(byte* pValue = value) + corGenVal.SetValue(new IntPtr(pValue)); + } + + public static unsafe object GetValue(this ICorDebugGenericValue corGenVal, Type type) + { + object retValue; + byte[] value = new byte[(int)corGenVal.GetSize()]; + fixed(byte* pValue = value) { + corGenVal.GetValue(new IntPtr(pValue)); + switch(type.FullName) { + case "System.Boolean": retValue = *((System.Boolean*)pValue); break; + case "System.Char": retValue = *((System.Char*) pValue); break; + case "System.SByte": retValue = *((System.SByte*) pValue); break; + case "System.Byte": retValue = *((System.Byte*) pValue); break; + case "System.Int16": retValue = *((System.Int16*) pValue); break; + case "System.UInt16": retValue = *((System.UInt16*) pValue); break; + case "System.Int32": retValue = *((System.Int32*) pValue); break; + case "System.UInt32": retValue = *((System.UInt32*) pValue); break; + case "System.Int64": retValue = *((System.Int64*) pValue); break; + case "System.UInt64": retValue = *((System.UInt64*) pValue); break; + case "System.Single": retValue = *((System.Single*) pValue); break; + case "System.Double": retValue = *((System.Double*) pValue); break; + case "System.IntPtr": retValue = *((System.IntPtr*) pValue); break; + case "System.UIntPtr": retValue = *((System.UIntPtr*)pValue); break; + default: throw new NotSupportedException(); + } + } + return retValue; + } + + public static unsafe void SetValue(this ICorDebugGenericValue corGenVal, object value) + { + if (value == null) + throw new ArgumentNullException("value"); + byte[] val = new byte[(int)corGenVal.GetSize()]; + fixed(byte* pValue = val) { + switch(value.GetType().FullName) { + case "System.Boolean": *((System.Boolean*)pValue) = (System.Boolean)value; break; + case "System.Char": *((System.Char*) pValue) = (System.Char) value; break; + case "System.SByte": *((System.SByte*) pValue) = (System.SByte) value; break; + case "System.Byte": *((System.Byte*) pValue) = (System.Byte) value; break; + case "System.Int16": *((System.Int16*) pValue) = (System.Int16) value; break; + case "System.UInt16": *((System.UInt16*) pValue) = (System.UInt16) value; break; + case "System.Int32": *((System.Int32*) pValue) = (System.Int32) value; break; + case "System.UInt32": *((System.UInt32*) pValue) = (System.UInt32) value; break; + case "System.Int64": *((System.Int64*) pValue) = (System.Int64) value; break; + case "System.UInt64": *((System.UInt64*) pValue) = (System.UInt64) value; break; + case "System.Single": *((System.Single*) pValue) = (System.Single) value; break; + case "System.Double": *((System.Double*) pValue) = (System.Double) value; break; + case "System.IntPtr": *((System.IntPtr*) pValue) = (System.IntPtr) value; break; + case "System.UIntPtr": *((System.UIntPtr*)pValue) = (System.UIntPtr)value; break; + default: throw new NotSupportedException(); + } + corGenVal.SetValue(new IntPtr(pValue)); + } + } + + // ICorDebugModule + + public static string GetName(this ICorDebugModule corModule) + { + // The 'out' parameter returns the size of the needed buffer as in other functions + return Util.GetString(corModule.GetName, 256, true); + } + + // ICorDebugProcess + + public static bool HasQueuedCallbacks(this ICorDebugProcess corProcess) + { + return corProcess.HasQueuedCallbacks(null) != 0; + } + + // ICorDebugStepper + + public static unsafe void StepRange(this ICorDebugStepper corStepper, bool bStepIn, int[] ranges) + { + fixed(int* pRanges = ranges) + corStepper.StepRange(bStepIn?1:0, (IntPtr)pRanges, (uint)ranges.Length / 2); + } + + // ICorDebugStringValue + + public static string GetString(this ICorDebugStringValue corString) + { + uint length = corString.GetLength(); + return Util.GetString(corString.GetString, length, false); + } + + // ICorDebugTypeEnum + + public static IEnumerable GetEnumerator(this ICorDebugTypeEnum corTypeEnum) + { + corTypeEnum.Reset(); + while (true) { + ICorDebugType corType = corTypeEnum.Next(); + if (corType != null) { + yield return corType; + } else { + break; + } + } + } + + public static ICorDebugType Next(this ICorDebugTypeEnum corTypeEnum) + { + ICorDebugType[] corTypes = new ICorDebugType[1]; + uint typesFetched = corTypeEnum.Next(1, corTypes); + if (typesFetched == 0) { + return null; + } else { + return corTypes[0]; + } + } + + public static List ToList(this ICorDebugTypeEnum corTypeEnum) + { + return new List(corTypeEnum.GetEnumerator()); + } + } +} diff --git a/Debugger/Debugger.Core/Interop/CorDebugExtensionMethods.generated.cs b/Debugger/Debugger.Core/Interop/CorDebugExtensionMethods.generated.cs new file mode 100644 index 000000000..9e9fab1f4 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/CorDebugExtensionMethods.generated.cs @@ -0,0 +1,3342 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Debugger.Interop.CorDebug +{ + public static partial class CorDebugExtensionMethods + { + public static void CanLaunchOrAttach(this CorDebugClass instance, uint dwProcessId, int win32DebuggingEnabled) + { + instance.__CanLaunchOrAttach(dwProcessId, win32DebuggingEnabled); + } + + public static ICorDebugProcess CreateProcess(this CorDebugClass instance, string lpApplicationName, string lpCommandLine, ref _SECURITY_ATTRIBUTES lpProcessAttributes, ref _SECURITY_ATTRIBUTES lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, uint lpStartupInfo, + uint lpProcessInformation, CorDebugCreateProcessFlags debuggingFlags) + { + ICorDebugProcess ppProcess; + instance.__CreateProcess(lpApplicationName, lpCommandLine, ref lpProcessAttributes, ref lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, + debuggingFlags, out ppProcess); + ProcessOutParameter(lpProcessAttributes); + ProcessOutParameter(lpThreadAttributes); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugProcess DebugActiveProcess(this CorDebugClass instance, uint id, int win32Attach) + { + ICorDebugProcess ppProcess; + instance.__DebugActiveProcess(id, win32Attach, out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugProcessEnum EnumerateProcesses(this CorDebugClass instance) + { + ICorDebugProcessEnum ppProcess; + instance.__EnumerateProcesses(out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugProcess GetProcess(this CorDebugClass instance, uint dwProcessId) + { + ICorDebugProcess ppProcess; + instance.__GetProcess(dwProcessId, out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static void Initialize(this CorDebugClass instance) + { + instance.__Initialize(); + } + + public static void SetManagedHandler(this CorDebugClass instance, ICorDebugManagedCallback pCallback) + { + instance.__SetManagedHandler(pCallback); + } + + public static void SetUnmanagedHandler(this CorDebugClass instance, ICorDebugUnmanagedCallback pCallback) + { + instance.__SetUnmanagedHandler(pCallback); + } + + public static void Terminate(this CorDebugClass instance) + { + instance.__Terminate(); + } + + public static void CanLaunchOrAttach(this EmbeddedCLRCorDebugClass instance, uint dwProcessId, int win32DebuggingEnabled) + { + instance.__CanLaunchOrAttach(dwProcessId, win32DebuggingEnabled); + } + + public static ICorDebugProcess CreateProcess(this EmbeddedCLRCorDebugClass instance, string lpApplicationName, string lpCommandLine, ref _SECURITY_ATTRIBUTES lpProcessAttributes, ref _SECURITY_ATTRIBUTES lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, uint lpStartupInfo, + uint lpProcessInformation, CorDebugCreateProcessFlags debuggingFlags) + { + ICorDebugProcess ppProcess; + instance.__CreateProcess(lpApplicationName, lpCommandLine, ref lpProcessAttributes, ref lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, + debuggingFlags, out ppProcess); + ProcessOutParameter(lpProcessAttributes); + ProcessOutParameter(lpThreadAttributes); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugProcess DebugActiveProcess(this EmbeddedCLRCorDebugClass instance, uint id, int win32Attach) + { + ICorDebugProcess ppProcess; + instance.__DebugActiveProcess(id, win32Attach, out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugProcessEnum EnumerateProcesses(this EmbeddedCLRCorDebugClass instance) + { + ICorDebugProcessEnum ppProcess; + instance.__EnumerateProcesses(out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugProcess GetProcess(this EmbeddedCLRCorDebugClass instance, uint dwProcessId) + { + ICorDebugProcess ppProcess; + instance.__GetProcess(dwProcessId, out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static void Initialize(this EmbeddedCLRCorDebugClass instance) + { + instance.__Initialize(); + } + + public static void SetManagedHandler(this EmbeddedCLRCorDebugClass instance, ICorDebugManagedCallback pCallback) + { + instance.__SetManagedHandler(pCallback); + } + + public static void SetUnmanagedHandler(this EmbeddedCLRCorDebugClass instance, ICorDebugUnmanagedCallback pCallback) + { + instance.__SetUnmanagedHandler(pCallback); + } + + public static void Terminate(this EmbeddedCLRCorDebugClass instance) + { + instance.__Terminate(); + } + + public static void Initialize(this ICorDebug instance) + { + instance.__Initialize(); + } + + public static void Terminate(this ICorDebug instance) + { + instance.__Terminate(); + } + + public static void SetManagedHandler(this ICorDebug instance, ICorDebugManagedCallback pCallback) + { + instance.__SetManagedHandler(pCallback); + } + + public static void SetUnmanagedHandler(this ICorDebug instance, ICorDebugUnmanagedCallback pCallback) + { + instance.__SetUnmanagedHandler(pCallback); + } + + public static ICorDebugProcess CreateProcess(this ICorDebug instance, string lpApplicationName, string lpCommandLine, ref _SECURITY_ATTRIBUTES lpProcessAttributes, ref _SECURITY_ATTRIBUTES lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, uint lpStartupInfo, + uint lpProcessInformation, CorDebugCreateProcessFlags debuggingFlags) + { + ICorDebugProcess ppProcess; + instance.__CreateProcess(lpApplicationName, lpCommandLine, ref lpProcessAttributes, ref lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, + debuggingFlags, out ppProcess); + ProcessOutParameter(lpProcessAttributes); + ProcessOutParameter(lpThreadAttributes); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugProcess DebugActiveProcess(this ICorDebug instance, uint id, int win32Attach) + { + ICorDebugProcess ppProcess; + instance.__DebugActiveProcess(id, win32Attach, out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugProcessEnum EnumerateProcesses(this ICorDebug instance) + { + ICorDebugProcessEnum ppProcess; + instance.__EnumerateProcesses(out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugProcess GetProcess(this ICorDebug instance, uint dwProcessId) + { + ICorDebugProcess ppProcess; + instance.__GetProcess(dwProcessId, out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static void CanLaunchOrAttach(this ICorDebug instance, uint dwProcessId, int win32DebuggingEnabled) + { + instance.__CanLaunchOrAttach(dwProcessId, win32DebuggingEnabled); + } + + public static void Stop(this ICorDebugAppDomain instance, uint dwTimeoutIgnored) + { + instance.__Stop(dwTimeoutIgnored); + } + + public static void Continue(this ICorDebugAppDomain instance, int fIsOutOfBand) + { + instance.__Continue(fIsOutOfBand); + } + + public static int IsRunning(this ICorDebugAppDomain instance) + { + int pbRunning; + instance.__IsRunning(out pbRunning); + return pbRunning; + } + + public static int HasQueuedCallbacks(this ICorDebugAppDomain instance, ICorDebugThread pThread) + { + int pbQueued; + instance.__HasQueuedCallbacks(pThread, out pbQueued); + return pbQueued; + } + + public static ICorDebugThreadEnum EnumerateThreads(this ICorDebugAppDomain instance) + { + ICorDebugThreadEnum ppThreads; + instance.__EnumerateThreads(out ppThreads); + ProcessOutParameter(ppThreads); + return ppThreads; + } + + public static void SetAllThreadsDebugState(this ICorDebugAppDomain instance, CorDebugThreadState state, ICorDebugThread pExceptThisThread) + { + instance.__SetAllThreadsDebugState(state, pExceptThisThread); + } + + public static void Detach(this ICorDebugAppDomain instance) + { + instance.__Detach(); + } + + public static void Terminate(this ICorDebugAppDomain instance, uint exitCode) + { + instance.__Terminate(exitCode); + } + + public static ICorDebugErrorInfoEnum CanCommitChanges(this ICorDebugAppDomain instance, uint cSnapshots, ref ICorDebugEditAndContinueSnapshot pSnapshots) + { + ICorDebugErrorInfoEnum pError; + instance.__CanCommitChanges(cSnapshots, ref pSnapshots, out pError); + ProcessOutParameter(pSnapshots); + ProcessOutParameter(pError); + return pError; + } + + public static ICorDebugErrorInfoEnum CommitChanges(this ICorDebugAppDomain instance, uint cSnapshots, ref ICorDebugEditAndContinueSnapshot pSnapshots) + { + ICorDebugErrorInfoEnum pError; + instance.__CommitChanges(cSnapshots, ref pSnapshots, out pError); + ProcessOutParameter(pSnapshots); + ProcessOutParameter(pError); + return pError; + } + + public static ICorDebugProcess GetProcess(this ICorDebugAppDomain instance) + { + ICorDebugProcess ppProcess; + instance.__GetProcess(out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugAssemblyEnum EnumerateAssemblies(this ICorDebugAppDomain instance) + { + ICorDebugAssemblyEnum ppAssemblies; + instance.__EnumerateAssemblies(out ppAssemblies); + ProcessOutParameter(ppAssemblies); + return ppAssemblies; + } + + public static ICorDebugModule GetModuleFromMetaDataInterface(this ICorDebugAppDomain instance, object pIMetaData) + { + ICorDebugModule ppModule; + instance.__GetModuleFromMetaDataInterface(pIMetaData, out ppModule); + ProcessOutParameter(ppModule); + return ppModule; + } + + public static ICorDebugBreakpointEnum EnumerateBreakpoints(this ICorDebugAppDomain instance) + { + ICorDebugBreakpointEnum ppBreakpoints; + instance.__EnumerateBreakpoints(out ppBreakpoints); + ProcessOutParameter(ppBreakpoints); + return ppBreakpoints; + } + + public static ICorDebugStepperEnum EnumerateSteppers(this ICorDebugAppDomain instance) + { + ICorDebugStepperEnum ppSteppers; + instance.__EnumerateSteppers(out ppSteppers); + ProcessOutParameter(ppSteppers); + return ppSteppers; + } + + public static int IsAttached(this ICorDebugAppDomain instance) + { + int pbAttached; + instance.__IsAttached(out pbAttached); + return pbAttached; + } + + public static void GetName(this ICorDebugAppDomain instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetName(cchName, out pcchName, szName); + } + + public static ICorDebugValue GetObject(this ICorDebugAppDomain instance) + { + ICorDebugValue ppObject; + instance.__GetObject(out ppObject); + ProcessOutParameter(ppObject); + return ppObject; + } + + public static void Attach(this ICorDebugAppDomain instance) + { + instance.__Attach(); + } + + public static uint GetID(this ICorDebugAppDomain instance) + { + uint pId; + instance.__GetID(out pId); + return pId; + } + + public static ICorDebugType GetArrayOrPointerType(this ICorDebugAppDomain2 instance, uint elementType, uint nRank, ICorDebugType pTypeArg) + { + ICorDebugType ppType; + instance.__GetArrayOrPointerType(elementType, nRank, pTypeArg, out ppType); + ProcessOutParameter(ppType); + return ppType; + } + + public static ICorDebugType GetFunctionPointerType(this ICorDebugAppDomain2 instance, uint nTypeArgs, ref ICorDebugType ppTypeArgs) + { + ICorDebugType ppType; + instance.__GetFunctionPointerType(nTypeArgs, ref ppTypeArgs, out ppType); + ProcessOutParameter(ppTypeArgs); + ProcessOutParameter(ppType); + return ppType; + } + + public static void Skip(this ICorDebugAppDomainEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugAppDomainEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugAppDomainEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugAppDomainEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugAppDomainEnum instance, uint celt, IntPtr values) + { + uint pceltFetched; + instance.__Next(celt, values, out pceltFetched); + return pceltFetched; + } + + public static uint GetTheType(this ICorDebugArrayValue instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugArrayValue instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugArrayValue instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugArrayValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static int IsValid(this ICorDebugArrayValue instance) + { + int pbValid; + instance.__IsValid(out pbValid); + return pbValid; + } + + public static ICorDebugValueBreakpoint CreateRelocBreakpoint(this ICorDebugArrayValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateRelocBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static uint GetElementType(this ICorDebugArrayValue instance) + { + uint pType; + instance.__GetElementType(out pType); + return pType; + } + + public static uint GetRank(this ICorDebugArrayValue instance) + { + uint pnRank; + instance.__GetRank(out pnRank); + return pnRank; + } + + public static uint GetCount(this ICorDebugArrayValue instance) + { + uint pnCount; + instance.__GetCount(out pnCount); + return pnCount; + } + + public static void GetDimensions(this ICorDebugArrayValue instance, uint cdim, IntPtr dims) + { + instance.__GetDimensions(cdim, dims); + } + + public static int HasBaseIndicies(this ICorDebugArrayValue instance) + { + int pbHasBaseIndicies; + instance.__HasBaseIndicies(out pbHasBaseIndicies); + return pbHasBaseIndicies; + } + + public static void GetBaseIndicies(this ICorDebugArrayValue instance, uint cdim, IntPtr indicies) + { + instance.__GetBaseIndicies(cdim, indicies); + } + + public static ICorDebugValue GetElement(this ICorDebugArrayValue instance, uint cdim, IntPtr indices) + { + ICorDebugValue ppValue; + instance.__GetElement(cdim, indices, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugValue GetElementAtPosition(this ICorDebugArrayValue instance, uint nPosition) + { + ICorDebugValue ppValue; + instance.__GetElementAtPosition(nPosition, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugProcess GetProcess(this ICorDebugAssembly instance) + { + ICorDebugProcess ppProcess; + instance.__GetProcess(out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ICorDebugAppDomain GetAppDomain(this ICorDebugAssembly instance) + { + ICorDebugAppDomain ppAppDomain; + instance.__GetAppDomain(out ppAppDomain); + ProcessOutParameter(ppAppDomain); + return ppAppDomain; + } + + public static ICorDebugModuleEnum EnumerateModules(this ICorDebugAssembly instance) + { + ICorDebugModuleEnum ppModules; + instance.__EnumerateModules(out ppModules); + ProcessOutParameter(ppModules); + return ppModules; + } + + public static void GetCodeBase(this ICorDebugAssembly instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetCodeBase(cchName, out pcchName, szName); + } + + public static void GetName(this ICorDebugAssembly instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetName(cchName, out pcchName, szName); + } + + public static int IsFullyTrusted(this ICorDebugAssembly2 instance) + { + int pbFullyTrusted; + instance.__IsFullyTrusted(out pbFullyTrusted); + return pbFullyTrusted; + } + + public static void Skip(this ICorDebugAssemblyEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugAssemblyEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugAssemblyEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugAssemblyEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugAssemblyEnum instance, uint celt, IntPtr values) + { + uint pceltFetched; + instance.__Next(celt, values, out pceltFetched); + return pceltFetched; + } + + public static uint GetTheType(this ICorDebugBoxValue instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugBoxValue instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugBoxValue instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugBoxValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static int IsValid(this ICorDebugBoxValue instance) + { + int pbValid; + instance.__IsValid(out pbValid); + return pbValid; + } + + public static ICorDebugValueBreakpoint CreateRelocBreakpoint(this ICorDebugBoxValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateRelocBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static ICorDebugObjectValue GetObject(this ICorDebugBoxValue instance) + { + ICorDebugObjectValue ppObject; + instance.__GetObject(out ppObject); + ProcessOutParameter(ppObject); + return ppObject; + } + + public static void Activate(this ICorDebugBreakpoint instance, int bActive) + { + instance.__Activate(bActive); + } + + public static int IsActive(this ICorDebugBreakpoint instance) + { + int pbActive; + instance.__IsActive(out pbActive); + return pbActive; + } + + public static void Skip(this ICorDebugBreakpointEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugBreakpointEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugBreakpointEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugBreakpointEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugBreakpointEnum instance, uint celt, IntPtr breakpoints) + { + uint pceltFetched; + instance.__Next(celt, breakpoints, out pceltFetched); + return pceltFetched; + } + + public static ICorDebugThread GetThread(this ICorDebugChain instance) + { + ICorDebugThread ppThread; + instance.__GetThread(out ppThread); + ProcessOutParameter(ppThread); + return ppThread; + } + + public static void GetStackRange(this ICorDebugChain instance, out ulong pStart, out ulong pEnd) + { + instance.__GetStackRange(out pStart, out pEnd); + } + + public static ICorDebugContext GetContext(this ICorDebugChain instance) + { + ICorDebugContext ppContext; + instance.__GetContext(out ppContext); + ProcessOutParameter(ppContext); + return ppContext; + } + + public static ICorDebugChain GetCaller(this ICorDebugChain instance) + { + ICorDebugChain ppChain; + instance.__GetCaller(out ppChain); + ProcessOutParameter(ppChain); + return ppChain; + } + + public static ICorDebugChain GetCallee(this ICorDebugChain instance) + { + ICorDebugChain ppChain; + instance.__GetCallee(out ppChain); + ProcessOutParameter(ppChain); + return ppChain; + } + + public static ICorDebugChain GetPrevious(this ICorDebugChain instance) + { + ICorDebugChain ppChain; + instance.__GetPrevious(out ppChain); + ProcessOutParameter(ppChain); + return ppChain; + } + + public static ICorDebugChain GetNext(this ICorDebugChain instance) + { + ICorDebugChain ppChain; + instance.__GetNext(out ppChain); + ProcessOutParameter(ppChain); + return ppChain; + } + + public static int IsManaged(this ICorDebugChain instance) + { + int pManaged; + instance.__IsManaged(out pManaged); + return pManaged; + } + + public static ICorDebugFrameEnum EnumerateFrames(this ICorDebugChain instance) + { + ICorDebugFrameEnum ppFrames; + instance.__EnumerateFrames(out ppFrames); + ProcessOutParameter(ppFrames); + return ppFrames; + } + + public static ICorDebugFrame GetActiveFrame(this ICorDebugChain instance) + { + ICorDebugFrame ppFrame; + instance.__GetActiveFrame(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugRegisterSet GetRegisterSet(this ICorDebugChain instance) + { + ICorDebugRegisterSet ppRegisters; + instance.__GetRegisterSet(out ppRegisters); + ProcessOutParameter(ppRegisters); + return ppRegisters; + } + + public static CorDebugChainReason GetReason(this ICorDebugChain instance) + { + CorDebugChainReason pReason; + instance.__GetReason(out pReason); + ProcessOutParameter(pReason); + return pReason; + } + + public static void Skip(this ICorDebugChainEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugChainEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugChainEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugChainEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugChainEnum instance, uint celt, ICorDebugChain[] chains) + { + uint pceltFetched; + instance.__Next(celt, chains, out pceltFetched); + ProcessOutParameter(chains); + return pceltFetched; + } + + public static ICorDebugModule GetModule(this ICorDebugClass instance) + { + ICorDebugModule pModule; + instance.__GetModule(out pModule); + ProcessOutParameter(pModule); + return pModule; + } + + public static uint GetToken(this ICorDebugClass instance) + { + uint pTypeDef; + instance.__GetToken(out pTypeDef); + return pTypeDef; + } + + public static ICorDebugValue GetStaticFieldValue(this ICorDebugClass instance, uint fieldDef, ICorDebugFrame pFrame) + { + ICorDebugValue ppValue; + instance.__GetStaticFieldValue(fieldDef, pFrame, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugType GetParameterizedType(this ICorDebugClass2 instance, uint elementType, uint nTypeArgs, ICorDebugType[] ppTypeArgs) + { + ICorDebugType ppType; + instance.__GetParameterizedType(elementType, nTypeArgs, ppTypeArgs, out ppType); + ProcessOutParameter(ppTypeArgs); + ProcessOutParameter(ppType); + return ppType; + } + + public static void SetJMCStatus(this ICorDebugClass2 instance, int bIsJustMyCode) + { + instance.__SetJMCStatus(bIsJustMyCode); + } + + public static int IsIL(this ICorDebugCode instance) + { + int pbIL; + instance.__IsIL(out pbIL); + return pbIL; + } + + public static ICorDebugFunction GetFunction(this ICorDebugCode instance) + { + ICorDebugFunction ppFunction; + instance.__GetFunction(out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static ulong GetAddress(this ICorDebugCode instance) + { + ulong pStart; + instance.__GetAddress(out pStart); + return pStart; + } + + public static uint GetSize(this ICorDebugCode instance) + { + uint pcBytes; + instance.__GetSize(out pcBytes); + return pcBytes; + } + + public static ICorDebugFunctionBreakpoint CreateBreakpoint(this ICorDebugCode instance, uint offset) + { + ICorDebugFunctionBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(offset, out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static uint GetCode(this ICorDebugCode instance, uint startOffset, uint endOffset, uint cBufferAlloc, IntPtr buffer) + { + uint pcBufferSize; + instance.__GetCode(startOffset, endOffset, cBufferAlloc, buffer, out pcBufferSize); + return pcBufferSize; + } + + public static uint GetVersionNumber(this ICorDebugCode instance) + { + uint nVersion; + instance.__GetVersionNumber(out nVersion); + return nVersion; + } + + public static void GetILToNativeMapping(this ICorDebugCode instance, uint cMap, out uint pcMap, IntPtr map) + { + instance.__GetILToNativeMapping(cMap, out pcMap, map); + } + + public static void GetEnCRemapSequencePoints(this ICorDebugCode instance, uint cMap, out uint pcMap, IntPtr offsets) + { + instance.__GetEnCRemapSequencePoints(cMap, out pcMap, offsets); + } + + public static void Skip(this ICorDebugCodeEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugCodeEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugCodeEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugCodeEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugCodeEnum instance, uint celt, IntPtr values) + { + uint pceltFetched; + instance.__Next(celt, values, out pceltFetched); + return pceltFetched; + } + + public static uint GetTheType(this ICorDebugContext instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugContext instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugContext instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugContext instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static ICorDebugClass GetClass(this ICorDebugContext instance) + { + ICorDebugClass ppClass; + instance.__GetClass(out ppClass); + ProcessOutParameter(ppClass); + return ppClass; + } + + public static ICorDebugValue GetFieldValue(this ICorDebugContext instance, ICorDebugClass pClass, uint fieldDef) + { + ICorDebugValue ppValue; + instance.__GetFieldValue(pClass, fieldDef, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugFunction GetVirtualMethod(this ICorDebugContext instance, uint memberRef) + { + ICorDebugFunction ppFunction; + instance.__GetVirtualMethod(memberRef, out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static ICorDebugContext GetContext(this ICorDebugContext instance) + { + ICorDebugContext ppContext; + instance.__GetContext(out ppContext); + ProcessOutParameter(ppContext); + return ppContext; + } + + public static int IsValueClass(this ICorDebugContext instance) + { + int pbIsValueClass; + instance.__IsValueClass(out pbIsValueClass); + return pbIsValueClass; + } + + public static object GetManagedCopy(this ICorDebugContext instance) + { + object ppObject; + instance.__GetManagedCopy(out ppObject); + ProcessOutParameter(ppObject); + return ppObject; + } + + public static void SetFromManagedCopy(this ICorDebugContext instance, object pObject) + { + instance.__SetFromManagedCopy(pObject); + } + + public static void Stop(this ICorDebugController instance, uint dwTimeoutIgnored) + { + instance.__Stop(dwTimeoutIgnored); + } + + public static void Continue(this ICorDebugController instance, int fIsOutOfBand) + { + instance.__Continue(fIsOutOfBand); + } + + public static int IsRunning(this ICorDebugController instance) + { + int pbRunning; + instance.__IsRunning(out pbRunning); + return pbRunning; + } + + public static int HasQueuedCallbacks(this ICorDebugController instance, ICorDebugThread pThread) + { + int pbQueued; + instance.__HasQueuedCallbacks(pThread, out pbQueued); + return pbQueued; + } + + public static ICorDebugThreadEnum EnumerateThreads(this ICorDebugController instance) + { + ICorDebugThreadEnum ppThreads; + instance.__EnumerateThreads(out ppThreads); + ProcessOutParameter(ppThreads); + return ppThreads; + } + + public static void SetAllThreadsDebugState(this ICorDebugController instance, CorDebugThreadState state, ICorDebugThread pExceptThisThread) + { + instance.__SetAllThreadsDebugState(state, pExceptThisThread); + } + + public static void Detach(this ICorDebugController instance) + { + instance.__Detach(); + } + + public static void Terminate(this ICorDebugController instance, uint exitCode) + { + instance.__Terminate(exitCode); + } + + public static ICorDebugErrorInfoEnum CanCommitChanges(this ICorDebugController instance, uint cSnapshots, ref ICorDebugEditAndContinueSnapshot pSnapshots) + { + ICorDebugErrorInfoEnum pError; + instance.__CanCommitChanges(cSnapshots, ref pSnapshots, out pError); + ProcessOutParameter(pSnapshots); + ProcessOutParameter(pError); + return pError; + } + + public static ICorDebugErrorInfoEnum CommitChanges(this ICorDebugController instance, uint cSnapshots, ref ICorDebugEditAndContinueSnapshot pSnapshots) + { + ICorDebugErrorInfoEnum pError; + instance.__CommitChanges(cSnapshots, ref pSnapshots, out pError); + ProcessOutParameter(pSnapshots); + ProcessOutParameter(pError); + return pError; + } + + public static Guid CopyMetaData(this ICorDebugEditAndContinueSnapshot instance, IStream pIStream) + { + Guid pMvid; + instance.__CopyMetaData(pIStream, out pMvid); + return pMvid; + } + + public static Guid GetMvid(this ICorDebugEditAndContinueSnapshot instance) + { + Guid pMvid; + instance.__GetMvid(out pMvid); + return pMvid; + } + + public static uint GetRoDataRVA(this ICorDebugEditAndContinueSnapshot instance) + { + uint pRoDataRVA; + instance.__GetRoDataRVA(out pRoDataRVA); + return pRoDataRVA; + } + + public static uint GetRwDataRVA(this ICorDebugEditAndContinueSnapshot instance) + { + uint pRwDataRVA; + instance.__GetRwDataRVA(out pRwDataRVA); + return pRwDataRVA; + } + + public static void SetPEBytes(this ICorDebugEditAndContinueSnapshot instance, IStream pIStream) + { + instance.__SetPEBytes(pIStream); + } + + public static void SetILMap(this ICorDebugEditAndContinueSnapshot instance, uint mdFunction, uint cMapSize, ref _COR_IL_MAP map) + { + instance.__SetILMap(mdFunction, cMapSize, ref map); + ProcessOutParameter(map); + } + + public static void SetPESymbolBytes(this ICorDebugEditAndContinueSnapshot instance, IStream pIStream) + { + instance.__SetPESymbolBytes(pIStream); + } + + public static void Skip(this ICorDebugEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static void Skip(this ICorDebugErrorInfoEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugErrorInfoEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugErrorInfoEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugErrorInfoEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugErrorInfoEnum instance, uint celt, IntPtr errors) + { + uint pceltFetched; + instance.__Next(celt, errors, out pceltFetched); + return pceltFetched; + } + + public static void CallFunction(this ICorDebugEval instance, ICorDebugFunction pFunction, uint nArgs, ICorDebugValue[] ppArgs) + { + instance.__CallFunction(pFunction, nArgs, ppArgs); + ProcessOutParameter(ppArgs); + } + + public static void NewObject(this ICorDebugEval instance, ICorDebugFunction pConstructor, uint nArgs, ref ICorDebugValue ppArgs) + { + instance.__NewObject(pConstructor, nArgs, ref ppArgs); + ProcessOutParameter(ppArgs); + } + + public static void NewObjectNoConstructor(this ICorDebugEval instance, ICorDebugClass pClass) + { + instance.__NewObjectNoConstructor(pClass); + } + + public static void NewString(this ICorDebugEval instance, string @string) + { + instance.__NewString(@string); + } + + public static void NewArray(this ICorDebugEval instance, uint elementType, ICorDebugClass pElementClass, uint rank, ref uint dims, ref uint lowBounds) + { + instance.__NewArray(elementType, pElementClass, rank, ref dims, ref lowBounds); + } + + public static int IsActive(this ICorDebugEval instance) + { + int pbActive; + instance.__IsActive(out pbActive); + return pbActive; + } + + public static void Abort(this ICorDebugEval instance) + { + instance.__Abort(); + } + + public static ICorDebugValue GetResult(this ICorDebugEval instance) + { + ICorDebugValue ppResult; + instance.__GetResult(out ppResult); + ProcessOutParameter(ppResult); + return ppResult; + } + + public static ICorDebugThread GetThread(this ICorDebugEval instance) + { + ICorDebugThread ppThread; + instance.__GetThread(out ppThread); + ProcessOutParameter(ppThread); + return ppThread; + } + + public static ICorDebugValue CreateValue(this ICorDebugEval instance, uint elementType, ICorDebugClass pElementClass) + { + ICorDebugValue ppValue; + instance.__CreateValue(elementType, pElementClass, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static void CallParameterizedFunction(this ICorDebugEval2 instance, ICorDebugFunction pFunction, uint nTypeArgs, ICorDebugType[] ppTypeArgs, uint nArgs, ICorDebugValue[] ppArgs) + { + instance.__CallParameterizedFunction(pFunction, nTypeArgs, ppTypeArgs, nArgs, ppArgs); + ProcessOutParameter(ppTypeArgs); + ProcessOutParameter(ppArgs); + } + + public static ICorDebugValue CreateValueForType(this ICorDebugEval2 instance, ICorDebugType pType) + { + ICorDebugValue ppValue; + instance.__CreateValueForType(pType, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static void NewParameterizedObject(this ICorDebugEval2 instance, ICorDebugFunction pConstructor, uint nTypeArgs, ICorDebugType[] ppTypeArgs, uint nArgs, ICorDebugValue[] ppArgs) + { + instance.__NewParameterizedObject(pConstructor, nTypeArgs, ppTypeArgs, nArgs, ppArgs); + ProcessOutParameter(ppTypeArgs); + ProcessOutParameter(ppArgs); + } + + public static void NewParameterizedObjectNoConstructor(this ICorDebugEval2 instance, ICorDebugClass pClass, uint nTypeArgs, ICorDebugType[] ppTypeArgs) + { + instance.__NewParameterizedObjectNoConstructor(pClass, nTypeArgs, ppTypeArgs); + ProcessOutParameter(ppTypeArgs); + } + + public static void NewParameterizedArray(this ICorDebugEval2 instance, ICorDebugType pElementType, uint rank, uint[] dims, uint[] lowBounds) + { + instance.__NewParameterizedArray(pElementType, rank, dims, lowBounds); + } + + public static void NewStringWithLength(this ICorDebugEval2 instance, string @string, uint uiLength) + { + instance.__NewStringWithLength(@string, uiLength); + } + + public static void RudeAbort(this ICorDebugEval2 instance) + { + instance.__RudeAbort(); + } + + public static ICorDebugChain GetChain(this ICorDebugFrame instance) + { + ICorDebugChain ppChain; + instance.__GetChain(out ppChain); + ProcessOutParameter(ppChain); + return ppChain; + } + + public static ICorDebugCode GetCode(this ICorDebugFrame instance) + { + ICorDebugCode ppCode; + instance.__GetCode(out ppCode); + ProcessOutParameter(ppCode); + return ppCode; + } + + public static ICorDebugFunction GetFunction(this ICorDebugFrame instance) + { + ICorDebugFunction ppFunction; + instance.__GetFunction(out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static uint GetFunctionToken(this ICorDebugFrame instance) + { + uint pToken; + instance.__GetFunctionToken(out pToken); + return pToken; + } + + public static void GetStackRange(this ICorDebugFrame instance, out ulong pStart, out ulong pEnd) + { + instance.__GetStackRange(out pStart, out pEnd); + } + + public static ICorDebugFrame GetCaller(this ICorDebugFrame instance) + { + ICorDebugFrame ppFrame; + instance.__GetCaller(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugFrame GetCallee(this ICorDebugFrame instance) + { + ICorDebugFrame ppFrame; + instance.__GetCallee(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugStepper CreateStepper(this ICorDebugFrame instance) + { + ICorDebugStepper ppStepper; + instance.__CreateStepper(out ppStepper); + ProcessOutParameter(ppStepper); + return ppStepper; + } + + public static void Skip(this ICorDebugFrameEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugFrameEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugFrameEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugFrameEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugFrameEnum instance, uint celt, ICorDebugFrame[] frames) + { + uint pceltFetched; + instance.__Next(celt, frames, out pceltFetched); + ProcessOutParameter(frames); + return pceltFetched; + } + + public static ICorDebugModule GetModule(this ICorDebugFunction instance) + { + ICorDebugModule ppModule; + instance.__GetModule(out ppModule); + ProcessOutParameter(ppModule); + return ppModule; + } + + public static ICorDebugClass GetClass(this ICorDebugFunction instance) + { + ICorDebugClass ppClass; + instance.__GetClass(out ppClass); + ProcessOutParameter(ppClass); + return ppClass; + } + + public static uint GetToken(this ICorDebugFunction instance) + { + uint pMethodDef; + instance.__GetToken(out pMethodDef); + return pMethodDef; + } + + public static ICorDebugCode GetILCode(this ICorDebugFunction instance) + { + ICorDebugCode ppCode; + instance.__GetILCode(out ppCode); + ProcessOutParameter(ppCode); + return ppCode; + } + + public static ICorDebugCode GetNativeCode(this ICorDebugFunction instance) + { + ICorDebugCode ppCode; + instance.__GetNativeCode(out ppCode); + ProcessOutParameter(ppCode); + return ppCode; + } + + public static ICorDebugFunctionBreakpoint CreateBreakpoint(this ICorDebugFunction instance) + { + ICorDebugFunctionBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static uint GetLocalVarSigToken(this ICorDebugFunction instance) + { + uint pmdSig; + instance.__GetLocalVarSigToken(out pmdSig); + return pmdSig; + } + + public static uint GetCurrentVersionNumber(this ICorDebugFunction instance) + { + uint pnCurrentVersion; + instance.__GetCurrentVersionNumber(out pnCurrentVersion); + return pnCurrentVersion; + } + + public static void SetJMCStatus(this ICorDebugFunction2 instance, int bIsJustMyCode) + { + instance.__SetJMCStatus(bIsJustMyCode); + } + + public static int GetJMCStatus(this ICorDebugFunction2 instance) + { + int pbIsJustMyCode; + instance.__GetJMCStatus(out pbIsJustMyCode); + return pbIsJustMyCode; + } + + public static ICorDebugCodeEnum EnumerateNativeCode(this ICorDebugFunction2 instance) + { + ICorDebugCodeEnum ppCodeEnum; + instance.__EnumerateNativeCode(out ppCodeEnum); + ProcessOutParameter(ppCodeEnum); + return ppCodeEnum; + } + + public static uint GetVersionNumber(this ICorDebugFunction2 instance) + { + uint pnVersion; + instance.__GetVersionNumber(out pnVersion); + return pnVersion; + } + + public static void Activate(this ICorDebugFunctionBreakpoint instance, int bActive) + { + instance.__Activate(bActive); + } + + public static int IsActive(this ICorDebugFunctionBreakpoint instance) + { + int pbActive; + instance.__IsActive(out pbActive); + return pbActive; + } + + public static ICorDebugFunction GetFunction(this ICorDebugFunctionBreakpoint instance) + { + ICorDebugFunction ppFunction; + instance.__GetFunction(out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static uint GetOffset(this ICorDebugFunctionBreakpoint instance) + { + uint pnOffset; + instance.__GetOffset(out pnOffset); + return pnOffset; + } + + public static uint GetTheType(this ICorDebugGenericValue instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugGenericValue instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugGenericValue instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugGenericValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static void GetValue(this ICorDebugGenericValue instance, IntPtr pTo) + { + instance.__GetValue(pTo); + } + + public static void SetValue(this ICorDebugGenericValue instance, IntPtr pFrom) + { + instance.__SetValue(pFrom); + } + + public static uint GetTheType(this ICorDebugHandleValue instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugHandleValue instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugHandleValue instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugHandleValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static int IsNull(this ICorDebugHandleValue instance) + { + int pbNull; + instance.__IsNull(out pbNull); + return pbNull; + } + + public static ulong GetValue(this ICorDebugHandleValue instance) + { + ulong pValue; + instance.__GetValue(out pValue); + return pValue; + } + + public static void SetValue(this ICorDebugHandleValue instance, ulong value) + { + instance.__SetValue(value); + } + + public static ICorDebugValue Dereference(this ICorDebugHandleValue instance) + { + ICorDebugValue ppValue; + instance.__Dereference(out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugValue DereferenceStrong(this ICorDebugHandleValue instance) + { + ICorDebugValue ppValue; + instance.__DereferenceStrong(out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static CorDebugHandleType GetHandleType(this ICorDebugHandleValue instance) + { + CorDebugHandleType pType; + instance.__GetHandleType(out pType); + ProcessOutParameter(pType); + return pType; + } + + public static void Dispose(this ICorDebugHandleValue instance) + { + instance.__Dispose(); + } + + public static uint GetTheType(this ICorDebugHeapValue instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugHeapValue instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugHeapValue instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugHeapValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static int IsValid(this ICorDebugHeapValue instance) + { + int pbValid; + instance.__IsValid(out pbValid); + return pbValid; + } + + public static ICorDebugValueBreakpoint CreateRelocBreakpoint(this ICorDebugHeapValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateRelocBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static ICorDebugHandleValue CreateHandle(this ICorDebugHeapValue2 instance, CorDebugHandleType type) + { + ICorDebugHandleValue ppHandle; + instance.__CreateHandle(type, out ppHandle); + ProcessOutParameter(ppHandle); + return ppHandle; + } + + public static ICorDebugChain GetChain(this ICorDebugILFrame instance) + { + ICorDebugChain ppChain; + instance.__GetChain(out ppChain); + ProcessOutParameter(ppChain); + return ppChain; + } + + public static ICorDebugCode GetCode(this ICorDebugILFrame instance) + { + ICorDebugCode ppCode; + instance.__GetCode(out ppCode); + ProcessOutParameter(ppCode); + return ppCode; + } + + public static ICorDebugFunction GetFunction(this ICorDebugILFrame instance) + { + ICorDebugFunction ppFunction; + instance.__GetFunction(out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static uint GetFunctionToken(this ICorDebugILFrame instance) + { + uint pToken; + instance.__GetFunctionToken(out pToken); + return pToken; + } + + public static void GetStackRange(this ICorDebugILFrame instance, out ulong pStart, out ulong pEnd) + { + instance.__GetStackRange(out pStart, out pEnd); + } + + public static ICorDebugFrame GetCaller(this ICorDebugILFrame instance) + { + ICorDebugFrame ppFrame; + instance.__GetCaller(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugFrame GetCallee(this ICorDebugILFrame instance) + { + ICorDebugFrame ppFrame; + instance.__GetCallee(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugStepper CreateStepper(this ICorDebugILFrame instance) + { + ICorDebugStepper ppStepper; + instance.__CreateStepper(out ppStepper); + ProcessOutParameter(ppStepper); + return ppStepper; + } + + public static void GetIP(this ICorDebugILFrame instance, out uint pnOffset, out CorDebugMappingResult pMappingResult) + { + instance.__GetIP(out pnOffset, out pMappingResult); + ProcessOutParameter(pMappingResult); + } + + public static void SetIP(this ICorDebugILFrame instance, uint nOffset) + { + instance.__SetIP(nOffset); + } + + public static ICorDebugValueEnum EnumerateLocalVariables(this ICorDebugILFrame instance) + { + ICorDebugValueEnum ppValueEnum; + instance.__EnumerateLocalVariables(out ppValueEnum); + ProcessOutParameter(ppValueEnum); + return ppValueEnum; + } + + public static ICorDebugValue GetLocalVariable(this ICorDebugILFrame instance, uint dwIndex) + { + ICorDebugValue ppValue; + instance.__GetLocalVariable(dwIndex, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugValueEnum EnumerateArguments(this ICorDebugILFrame instance) + { + ICorDebugValueEnum ppValueEnum; + instance.__EnumerateArguments(out ppValueEnum); + ProcessOutParameter(ppValueEnum); + return ppValueEnum; + } + + public static ICorDebugValue GetArgument(this ICorDebugILFrame instance, uint dwIndex) + { + ICorDebugValue ppValue; + instance.__GetArgument(dwIndex, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static uint GetStackDepth(this ICorDebugILFrame instance) + { + uint pDepth; + instance.__GetStackDepth(out pDepth); + return pDepth; + } + + public static ICorDebugValue GetStackValue(this ICorDebugILFrame instance, uint dwIndex) + { + ICorDebugValue ppValue; + instance.__GetStackValue(dwIndex, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static void CanSetIP(this ICorDebugILFrame instance, uint nOffset) + { + instance.__CanSetIP(nOffset); + } + + public static void RemapFunction(this ICorDebugILFrame2 instance, uint newILOffset) + { + instance.__RemapFunction(newILOffset); + } + + public static ICorDebugTypeEnum EnumerateTypeParameters(this ICorDebugILFrame2 instance) + { + ICorDebugTypeEnum ppTyParEnum; + instance.__EnumerateTypeParameters(out ppTyParEnum); + ProcessOutParameter(ppTyParEnum); + return ppTyParEnum; + } + + public static ICorDebugChain GetChain(this ICorDebugInternalFrame instance) + { + ICorDebugChain ppChain; + instance.__GetChain(out ppChain); + ProcessOutParameter(ppChain); + return ppChain; + } + + public static ICorDebugCode GetCode(this ICorDebugInternalFrame instance) + { + ICorDebugCode ppCode; + instance.__GetCode(out ppCode); + ProcessOutParameter(ppCode); + return ppCode; + } + + public static ICorDebugFunction GetFunction(this ICorDebugInternalFrame instance) + { + ICorDebugFunction ppFunction; + instance.__GetFunction(out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static uint GetFunctionToken(this ICorDebugInternalFrame instance) + { + uint pToken; + instance.__GetFunctionToken(out pToken); + return pToken; + } + + public static void GetStackRange(this ICorDebugInternalFrame instance, out ulong pStart, out ulong pEnd) + { + instance.__GetStackRange(out pStart, out pEnd); + } + + public static ICorDebugFrame GetCaller(this ICorDebugInternalFrame instance) + { + ICorDebugFrame ppFrame; + instance.__GetCaller(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugFrame GetCallee(this ICorDebugInternalFrame instance) + { + ICorDebugFrame ppFrame; + instance.__GetCallee(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugStepper CreateStepper(this ICorDebugInternalFrame instance) + { + ICorDebugStepper ppStepper; + instance.__CreateStepper(out ppStepper); + ProcessOutParameter(ppStepper); + return ppStepper; + } + + public static CorDebugInternalFrameType GetFrameType(this ICorDebugInternalFrame instance) + { + CorDebugInternalFrameType pType; + instance.__GetFrameType(out pType); + ProcessOutParameter(pType); + return pType; + } + + public static void GetName(this ICorDebugMDA instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetName(cchName, out pcchName, szName); + } + + public static void GetDescription(this ICorDebugMDA instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetDescription(cchName, out pcchName, szName); + } + + public static void GetXML(this ICorDebugMDA instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetXML(cchName, out pcchName, szName); + } + + public static void GetFlags(this ICorDebugMDA instance, ref CorDebugMDAFlags pFlags) + { + instance.__GetFlags(ref pFlags); + ProcessOutParameter(pFlags); + } + + public static uint GetOSThreadId(this ICorDebugMDA instance) + { + uint pOsTid; + instance.__GetOSThreadId(out pOsTid); + return pOsTid; + } + + public static void Breakpoint(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread, IntPtr pBreakpoint) + { + instance.Breakpoint(pAppDomain, pThread, pBreakpoint); + } + + public static void StepComplete(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread, IntPtr pStepper, CorDebugStepReason reason) + { + instance.StepComplete(pAppDomain, pThread, pStepper, reason); + } + + public static void Break(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr thread) + { + instance.Break(pAppDomain, thread); + } + + public static void Exception(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread, int unhandled) + { + instance.Exception(pAppDomain, pThread, unhandled); + } + + public static void EvalComplete(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread, IntPtr pEval) + { + instance.EvalComplete(pAppDomain, pThread, pEval); + } + + public static void EvalException(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread, IntPtr pEval) + { + instance.EvalException(pAppDomain, pThread, pEval); + } + + public static void CreateProcess(this ICorDebugManagedCallback instance, IntPtr pProcess) + { + instance.CreateProcess(pProcess); + } + + public static void ExitProcess(this ICorDebugManagedCallback instance, IntPtr pProcess) + { + instance.ExitProcess(pProcess); + } + + public static void CreateThread(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr thread) + { + instance.CreateThread(pAppDomain, thread); + } + + public static void ExitThread(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr thread) + { + instance.ExitThread(pAppDomain, thread); + } + + public static void LoadModule(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pModule) + { + instance.LoadModule(pAppDomain, pModule); + } + + public static void UnloadModule(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pModule) + { + instance.UnloadModule(pAppDomain, pModule); + } + + public static void LoadClass(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr c) + { + instance.LoadClass(pAppDomain, c); + } + + public static void UnloadClass(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr c) + { + instance.UnloadClass(pAppDomain, c); + } + + public static void DebuggerError(this ICorDebugManagedCallback instance, IntPtr pProcess, int errorHR, uint errorCode) + { + instance.DebuggerError(pProcess, errorHR, errorCode); + } + + public static void LogMessage(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread, int lLevel, IntPtr pLogSwitchName, IntPtr pMessage) + { + instance.LogMessage(pAppDomain, pThread, lLevel, pLogSwitchName, pMessage); + } + + public static void LogSwitch(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread, int lLevel, uint ulReason, IntPtr pLogSwitchName, IntPtr pParentName) + { + instance.LogSwitch(pAppDomain, pThread, lLevel, ulReason, pLogSwitchName, pParentName); + } + + public static void CreateAppDomain(this ICorDebugManagedCallback instance, IntPtr pProcess, IntPtr pAppDomain) + { + instance.CreateAppDomain(pProcess, pAppDomain); + } + + public static void ExitAppDomain(this ICorDebugManagedCallback instance, IntPtr pProcess, IntPtr pAppDomain) + { + instance.ExitAppDomain(pProcess, pAppDomain); + } + + public static void LoadAssembly(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pAssembly) + { + instance.LoadAssembly(pAppDomain, pAssembly); + } + + public static void UnloadAssembly(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pAssembly) + { + instance.UnloadAssembly(pAppDomain, pAssembly); + } + + public static void ControlCTrap(this ICorDebugManagedCallback instance, IntPtr pProcess) + { + instance.ControlCTrap(pProcess); + } + + public static void NameChange(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread) + { + instance.NameChange(pAppDomain, pThread); + } + + public static void UpdateModuleSymbols(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pModule, IntPtr pSymbolStream) + { + instance.UpdateModuleSymbols(pAppDomain, pModule, pSymbolStream); + } + + public static void EditAndContinueRemap(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread, IntPtr pFunction, int fAccurate) + { + instance.EditAndContinueRemap(pAppDomain, pThread, pFunction, fAccurate); + } + + public static void BreakpointSetError(this ICorDebugManagedCallback instance, IntPtr pAppDomain, IntPtr pThread, IntPtr pBreakpoint, uint dwError) + { + instance.BreakpointSetError(pAppDomain, pThread, pBreakpoint, dwError); + } + + public static void FunctionRemapOpportunity(this ICorDebugManagedCallback2 instance, IntPtr pAppDomain, IntPtr pThread, IntPtr pOldFunction, IntPtr pNewFunction, uint oldILOffset) + { + instance.FunctionRemapOpportunity(pAppDomain, pThread, pOldFunction, pNewFunction, oldILOffset); + } + + public static void CreateConnection(this ICorDebugManagedCallback2 instance, IntPtr pProcess, uint dwConnectionId, IntPtr pConnName) + { + instance.CreateConnection(pProcess, dwConnectionId, pConnName); + } + + public static void ChangeConnection(this ICorDebugManagedCallback2 instance, IntPtr pProcess, uint dwConnectionId) + { + instance.ChangeConnection(pProcess, dwConnectionId); + } + + public static void DestroyConnection(this ICorDebugManagedCallback2 instance, IntPtr pProcess, uint dwConnectionId) + { + instance.DestroyConnection(pProcess, dwConnectionId); + } + + public static void Exception(this ICorDebugManagedCallback2 instance, IntPtr pAppDomain, IntPtr pThread, IntPtr pFrame, uint nOffset, CorDebugExceptionCallbackType dwEventType, uint dwFlags) + { + instance.Exception(pAppDomain, pThread, pFrame, nOffset, dwEventType, dwFlags); + } + + public static void ExceptionUnwind(this ICorDebugManagedCallback2 instance, IntPtr pAppDomain, IntPtr pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags) + { + instance.ExceptionUnwind(pAppDomain, pThread, dwEventType, dwFlags); + } + + public static void FunctionRemapComplete(this ICorDebugManagedCallback2 instance, IntPtr pAppDomain, IntPtr pThread, IntPtr pFunction) + { + instance.FunctionRemapComplete(pAppDomain, pThread, pFunction); + } + + public static void MDANotification(this ICorDebugManagedCallback2 instance, IntPtr pController, IntPtr pThread, IntPtr pMDA) + { + instance.MDANotification(pController, pThread, pMDA); + } + + public static ICorDebugProcess GetProcess(this ICorDebugModule instance) + { + ICorDebugProcess ppProcess; + instance.__GetProcess(out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static ulong GetBaseAddress(this ICorDebugModule instance) + { + ulong pAddress; + instance.__GetBaseAddress(out pAddress); + return pAddress; + } + + public static ICorDebugAssembly GetAssembly(this ICorDebugModule instance) + { + ICorDebugAssembly ppAssembly; + instance.__GetAssembly(out ppAssembly); + ProcessOutParameter(ppAssembly); + return ppAssembly; + } + + public static void GetName(this ICorDebugModule instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetName(cchName, out pcchName, szName); + } + + public static void EnableJITDebugging(this ICorDebugModule instance, int bTrackJITInfo, int bAllowJitOpts) + { + instance.__EnableJITDebugging(bTrackJITInfo, bAllowJitOpts); + } + + public static void EnableClassLoadCallbacks(this ICorDebugModule instance, int bClassLoadCallbacks) + { + instance.__EnableClassLoadCallbacks(bClassLoadCallbacks); + } + + public static ICorDebugFunction GetFunctionFromToken(this ICorDebugModule instance, uint methodDef) + { + ICorDebugFunction ppFunction; + instance.__GetFunctionFromToken(methodDef, out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static ICorDebugFunction GetFunctionFromRVA(this ICorDebugModule instance, ulong rva) + { + ICorDebugFunction ppFunction; + instance.__GetFunctionFromRVA(rva, out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static ICorDebugClass GetClassFromToken(this ICorDebugModule instance, uint typeDef) + { + ICorDebugClass ppClass; + instance.__GetClassFromToken(typeDef, out ppClass); + ProcessOutParameter(ppClass); + return ppClass; + } + + public static ICorDebugModuleBreakpoint CreateBreakpoint(this ICorDebugModule instance) + { + ICorDebugModuleBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static ICorDebugEditAndContinueSnapshot GetEditAndContinueSnapshot(this ICorDebugModule instance) + { + ICorDebugEditAndContinueSnapshot ppEditAndContinueSnapshot; + instance.__GetEditAndContinueSnapshot(out ppEditAndContinueSnapshot); + ProcessOutParameter(ppEditAndContinueSnapshot); + return ppEditAndContinueSnapshot; + } + + public static object GetMetaDataInterface(this ICorDebugModule instance, ref Guid riid) + { + object ppObj; + instance.__GetMetaDataInterface(ref riid, out ppObj); + ProcessOutParameter(ppObj); + return ppObj; + } + + public static uint GetToken(this ICorDebugModule instance) + { + uint pToken; + instance.__GetToken(out pToken); + return pToken; + } + + public static int IsDynamic(this ICorDebugModule instance) + { + int pDynamic; + instance.__IsDynamic(out pDynamic); + return pDynamic; + } + + public static ICorDebugValue GetGlobalVariableValue(this ICorDebugModule instance, uint fieldDef) + { + ICorDebugValue ppValue; + instance.__GetGlobalVariableValue(fieldDef, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static uint GetSize(this ICorDebugModule instance) + { + uint pcBytes; + instance.__GetSize(out pcBytes); + return pcBytes; + } + + public static int IsInMemory(this ICorDebugModule instance) + { + int pInMemory; + instance.__IsInMemory(out pInMemory); + return pInMemory; + } + + public static void SetJMCStatus(this ICorDebugModule2 instance, int bIsJustMyCode, uint cTokens, ref uint pTokens) + { + instance.__SetJMCStatus(bIsJustMyCode, cTokens, ref pTokens); + } + + public static void ApplyChanges(this ICorDebugModule2 instance, uint cbMetadata, byte[] pbMetadata, uint cbIL, byte[] pbIL) + { + instance.__ApplyChanges(cbMetadata, pbMetadata, cbIL, pbIL); + ProcessOutParameter(pbMetadata); + ProcessOutParameter(pbIL); + } + + public static void SetJITCompilerFlags(this ICorDebugModule2 instance, uint dwFlags) + { + instance.__SetJITCompilerFlags(dwFlags); + } + + public static uint GetJITCompilerFlags(this ICorDebugModule2 instance) + { + uint pdwFlags; + instance.__GetJITCompilerFlags(out pdwFlags); + return pdwFlags; + } + + public static void ResolveAssembly(this ICorDebugModule2 instance, uint tkAssemblyRef, ref ICorDebugAssembly ppAssembly) + { + instance.__ResolveAssembly(tkAssemblyRef, ref ppAssembly); + ProcessOutParameter(ppAssembly); + } + + public static object CreateReaderForInMemorySymbols(this ICorDebugModule3 instance, ref Guid riid) + { + object ppObj; + instance.__CreateReaderForInMemorySymbols(ref riid, out ppObj); + ProcessOutParameter(ppObj); + return ppObj; + } + + public static void Activate(this ICorDebugModuleBreakpoint instance, int bActive) + { + instance.__Activate(bActive); + } + + public static int IsActive(this ICorDebugModuleBreakpoint instance) + { + int pbActive; + instance.__IsActive(out pbActive); + return pbActive; + } + + public static ICorDebugModule GetModule(this ICorDebugModuleBreakpoint instance) + { + ICorDebugModule ppModule; + instance.__GetModule(out ppModule); + ProcessOutParameter(ppModule); + return ppModule; + } + + public static void Skip(this ICorDebugModuleEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugModuleEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugModuleEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugModuleEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugModuleEnum instance, uint celt, IntPtr modules) + { + uint pceltFetched; + instance.__Next(celt, modules, out pceltFetched); + return pceltFetched; + } + + public static ICorDebugChain GetChain(this ICorDebugNativeFrame instance) + { + ICorDebugChain ppChain; + instance.__GetChain(out ppChain); + ProcessOutParameter(ppChain); + return ppChain; + } + + public static ICorDebugCode GetCode(this ICorDebugNativeFrame instance) + { + ICorDebugCode ppCode; + instance.__GetCode(out ppCode); + ProcessOutParameter(ppCode); + return ppCode; + } + + public static ICorDebugFunction GetFunction(this ICorDebugNativeFrame instance) + { + ICorDebugFunction ppFunction; + instance.__GetFunction(out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static uint GetFunctionToken(this ICorDebugNativeFrame instance) + { + uint pToken; + instance.__GetFunctionToken(out pToken); + return pToken; + } + + public static void GetStackRange(this ICorDebugNativeFrame instance, out ulong pStart, out ulong pEnd) + { + instance.__GetStackRange(out pStart, out pEnd); + } + + public static ICorDebugFrame GetCaller(this ICorDebugNativeFrame instance) + { + ICorDebugFrame ppFrame; + instance.__GetCaller(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugFrame GetCallee(this ICorDebugNativeFrame instance) + { + ICorDebugFrame ppFrame; + instance.__GetCallee(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugStepper CreateStepper(this ICorDebugNativeFrame instance) + { + ICorDebugStepper ppStepper; + instance.__CreateStepper(out ppStepper); + ProcessOutParameter(ppStepper); + return ppStepper; + } + + public static uint GetIP(this ICorDebugNativeFrame instance) + { + uint pnOffset; + instance.__GetIP(out pnOffset); + return pnOffset; + } + + public static void SetIP(this ICorDebugNativeFrame instance, uint nOffset) + { + instance.__SetIP(nOffset); + } + + public static ICorDebugRegisterSet GetRegisterSet(this ICorDebugNativeFrame instance) + { + ICorDebugRegisterSet ppRegisters; + instance.__GetRegisterSet(out ppRegisters); + ProcessOutParameter(ppRegisters); + return ppRegisters; + } + + public static ICorDebugValue GetLocalRegisterValue(this ICorDebugNativeFrame instance, CorDebugRegister reg, uint cbSigBlob, uint pvSigBlob) + { + ICorDebugValue ppValue; + instance.__GetLocalRegisterValue(reg, cbSigBlob, pvSigBlob, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugValue GetLocalDoubleRegisterValue(this ICorDebugNativeFrame instance, CorDebugRegister highWordReg, CorDebugRegister lowWordReg, uint cbSigBlob, uint pvSigBlob) + { + ICorDebugValue ppValue; + instance.__GetLocalDoubleRegisterValue(highWordReg, lowWordReg, cbSigBlob, pvSigBlob, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugValue GetLocalMemoryValue(this ICorDebugNativeFrame instance, ulong address, uint cbSigBlob, uint pvSigBlob) + { + ICorDebugValue ppValue; + instance.__GetLocalMemoryValue(address, cbSigBlob, pvSigBlob, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugValue GetLocalRegisterMemoryValue(this ICorDebugNativeFrame instance, CorDebugRegister highWordReg, ulong lowWordAddress, uint cbSigBlob, uint pvSigBlob) + { + ICorDebugValue ppValue; + instance.__GetLocalRegisterMemoryValue(highWordReg, lowWordAddress, cbSigBlob, pvSigBlob, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugValue GetLocalMemoryRegisterValue(this ICorDebugNativeFrame instance, ulong highWordAddress, CorDebugRegister lowWordRegister, uint cbSigBlob, uint pvSigBlob) + { + ICorDebugValue ppValue; + instance.__GetLocalMemoryRegisterValue(highWordAddress, lowWordRegister, cbSigBlob, pvSigBlob, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static void CanSetIP(this ICorDebugNativeFrame instance, uint nOffset) + { + instance.__CanSetIP(nOffset); + } + + public static void Skip(this ICorDebugObjectEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugObjectEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugObjectEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugObjectEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugObjectEnum instance, uint celt, IntPtr objects) + { + uint pceltFetched; + instance.__Next(celt, objects, out pceltFetched); + return pceltFetched; + } + + public static uint GetTheType(this ICorDebugObjectValue instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugObjectValue instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugObjectValue instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugObjectValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static ICorDebugClass GetClass(this ICorDebugObjectValue instance) + { + ICorDebugClass ppClass; + instance.__GetClass(out ppClass); + ProcessOutParameter(ppClass); + return ppClass; + } + + public static ICorDebugValue GetFieldValue(this ICorDebugObjectValue instance, ICorDebugClass pClass, uint fieldDef) + { + ICorDebugValue ppValue; + instance.__GetFieldValue(pClass, fieldDef, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugFunction GetVirtualMethod(this ICorDebugObjectValue instance, uint memberRef) + { + ICorDebugFunction ppFunction; + instance.__GetVirtualMethod(memberRef, out ppFunction); + ProcessOutParameter(ppFunction); + return ppFunction; + } + + public static ICorDebugContext GetContext(this ICorDebugObjectValue instance) + { + ICorDebugContext ppContext; + instance.__GetContext(out ppContext); + ProcessOutParameter(ppContext); + return ppContext; + } + + public static int IsValueClass(this ICorDebugObjectValue instance) + { + int pbIsValueClass; + instance.__IsValueClass(out pbIsValueClass); + return pbIsValueClass; + } + + public static object GetManagedCopy(this ICorDebugObjectValue instance) + { + object ppObject; + instance.__GetManagedCopy(out ppObject); + ProcessOutParameter(ppObject); + return ppObject; + } + + public static void SetFromManagedCopy(this ICorDebugObjectValue instance, object pObject) + { + instance.__SetFromManagedCopy(pObject); + } + + public static void GetVirtualMethodAndType(this ICorDebugObjectValue2 instance, uint memberRef, out ICorDebugFunction ppFunction, out ICorDebugType ppType) + { + instance.__GetVirtualMethodAndType(memberRef, out ppFunction, out ppType); + ProcessOutParameter(ppFunction); + ProcessOutParameter(ppType); + } + + public static void Stop(this ICorDebugProcess instance, uint dwTimeoutIgnored) + { + instance.__Stop(dwTimeoutIgnored); + } + + public static void Continue(this ICorDebugProcess instance, int fIsOutOfBand) + { + instance.__Continue(fIsOutOfBand); + } + + public static int IsRunning(this ICorDebugProcess instance) + { + int pbRunning; + instance.__IsRunning(out pbRunning); + return pbRunning; + } + + public static int HasQueuedCallbacks(this ICorDebugProcess instance, ICorDebugThread pThread) + { + int pbQueued; + instance.__HasQueuedCallbacks(pThread, out pbQueued); + return pbQueued; + } + + public static ICorDebugThreadEnum EnumerateThreads(this ICorDebugProcess instance) + { + ICorDebugThreadEnum ppThreads; + instance.__EnumerateThreads(out ppThreads); + ProcessOutParameter(ppThreads); + return ppThreads; + } + + public static void SetAllThreadsDebugState(this ICorDebugProcess instance, CorDebugThreadState state, ICorDebugThread pExceptThisThread) + { + instance.__SetAllThreadsDebugState(state, pExceptThisThread); + } + + public static void Detach(this ICorDebugProcess instance) + { + instance.__Detach(); + } + + public static void Terminate(this ICorDebugProcess instance, uint exitCode) + { + instance.__Terminate(exitCode); + } + + public static ICorDebugErrorInfoEnum CanCommitChanges(this ICorDebugProcess instance, uint cSnapshots, ref ICorDebugEditAndContinueSnapshot pSnapshots) + { + ICorDebugErrorInfoEnum pError; + instance.__CanCommitChanges(cSnapshots, ref pSnapshots, out pError); + ProcessOutParameter(pSnapshots); + ProcessOutParameter(pError); + return pError; + } + + public static ICorDebugErrorInfoEnum CommitChanges(this ICorDebugProcess instance, uint cSnapshots, ref ICorDebugEditAndContinueSnapshot pSnapshots) + { + ICorDebugErrorInfoEnum pError; + instance.__CommitChanges(cSnapshots, ref pSnapshots, out pError); + ProcessOutParameter(pSnapshots); + ProcessOutParameter(pError); + return pError; + } + + public static uint GetID(this ICorDebugProcess instance) + { + uint pdwProcessId; + instance.__GetID(out pdwProcessId); + return pdwProcessId; + } + + public static uint GetHandle(this ICorDebugProcess instance) + { + uint phProcessHandle; + instance.__GetHandle(out phProcessHandle); + return phProcessHandle; + } + + public static ICorDebugThread GetThread(this ICorDebugProcess instance, uint dwThreadId) + { + ICorDebugThread ppThread; + instance.__GetThread(dwThreadId, out ppThread); + ProcessOutParameter(ppThread); + return ppThread; + } + + public static ICorDebugObjectEnum EnumerateObjects(this ICorDebugProcess instance) + { + ICorDebugObjectEnum ppObjects; + instance.__EnumerateObjects(out ppObjects); + ProcessOutParameter(ppObjects); + return ppObjects; + } + + public static int IsTransitionStub(this ICorDebugProcess instance, ulong address) + { + int pbTransitionStub; + instance.__IsTransitionStub(address, out pbTransitionStub); + return pbTransitionStub; + } + + public static int IsOSSuspended(this ICorDebugProcess instance, uint threadID) + { + int pbSuspended; + instance.__IsOSSuspended(threadID, out pbSuspended); + return pbSuspended; + } + + public static void GetThreadContext(this ICorDebugProcess instance, uint threadID, uint contextSize, IntPtr context) + { + instance.__GetThreadContext(threadID, contextSize, context); + } + + public static void SetThreadContext(this ICorDebugProcess instance, uint threadID, uint contextSize, IntPtr context) + { + instance.__SetThreadContext(threadID, contextSize, context); + } + + public static uint ReadMemory(this ICorDebugProcess instance, ulong address, uint size, IntPtr buffer) + { + uint read; + instance.__ReadMemory(address, size, buffer, out read); + return read; + } + + public static uint WriteMemory(this ICorDebugProcess instance, ulong address, uint size, IntPtr buffer) + { + uint written; + instance.__WriteMemory(address, size, buffer, out written); + return written; + } + + public static void ClearCurrentException(this ICorDebugProcess instance, uint threadID) + { + instance.__ClearCurrentException(threadID); + } + + public static void EnableLogMessages(this ICorDebugProcess instance, int fOnOff) + { + instance.__EnableLogMessages(fOnOff); + } + + public static void ModifyLogSwitch(this ICorDebugProcess instance, IntPtr pLogSwitchName, int lLevel) + { + instance.__ModifyLogSwitch(pLogSwitchName, lLevel); + } + + public static ICorDebugAppDomainEnum EnumerateAppDomains(this ICorDebugProcess instance) + { + ICorDebugAppDomainEnum ppAppDomains; + instance.__EnumerateAppDomains(out ppAppDomains); + ProcessOutParameter(ppAppDomains); + return ppAppDomains; + } + + public static ICorDebugValue GetObject(this ICorDebugProcess instance) + { + ICorDebugValue ppObject; + instance.__GetObject(out ppObject); + ProcessOutParameter(ppObject); + return ppObject; + } + + public static ICorDebugThread ThreadForFiberCookie(this ICorDebugProcess instance, uint fiberCookie) + { + ICorDebugThread ppThread; + instance.__ThreadForFiberCookie(fiberCookie, out ppThread); + ProcessOutParameter(ppThread); + return ppThread; + } + + public static uint GetHelperThreadID(this ICorDebugProcess instance) + { + uint pThreadID; + instance.__GetHelperThreadID(out pThreadID); + return pThreadID; + } + + public static ICorDebugThread2 GetThreadForTaskID(this ICorDebugProcess2 instance, ulong taskid) + { + ICorDebugThread2 ppThread; + instance.__GetThreadForTaskID(taskid, out ppThread); + ProcessOutParameter(ppThread); + return ppThread; + } + + public static _COR_VERSION GetVersion(this ICorDebugProcess2 instance) + { + _COR_VERSION version; + instance.__GetVersion(out version); + ProcessOutParameter(version); + return version; + } + + public static uint SetUnmanagedBreakpoint(this ICorDebugProcess2 instance, ulong address, uint bufsize, IntPtr buffer) + { + uint bufLen; + instance.__SetUnmanagedBreakpoint(address, bufsize, buffer, out bufLen); + return bufLen; + } + + public static void ClearUnmanagedBreakpoint(this ICorDebugProcess2 instance, ulong address) + { + instance.__ClearUnmanagedBreakpoint(address); + } + + public static void SetDesiredNGENCompilerFlags(this ICorDebugProcess2 instance, uint pdwFlags) + { + instance.__SetDesiredNGENCompilerFlags(pdwFlags); + } + + public static uint GetDesiredNGENCompilerFlags(this ICorDebugProcess2 instance) + { + uint pdwFlags; + instance.__GetDesiredNGENCompilerFlags(out pdwFlags); + return pdwFlags; + } + + public static ICorDebugReferenceValue GetReferenceValueFromGCHandle(this ICorDebugProcess2 instance, uint handle) + { + ICorDebugReferenceValue pOutValue; + instance.__GetReferenceValueFromGCHandle(handle, out pOutValue); + ProcessOutParameter(pOutValue); + return pOutValue; + } + + public static void Skip(this ICorDebugProcessEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugProcessEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugProcessEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugProcessEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugProcessEnum instance, uint celt, IntPtr processes) + { + uint pceltFetched; + instance.__Next(celt, processes, out pceltFetched); + return pceltFetched; + } + + public static uint GetTheType(this ICorDebugReferenceValue instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugReferenceValue instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugReferenceValue instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugReferenceValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static int IsNull(this ICorDebugReferenceValue instance) + { + int pbNull; + instance.__IsNull(out pbNull); + return pbNull; + } + + public static ulong GetValue(this ICorDebugReferenceValue instance) + { + ulong pValue; + instance.__GetValue(out pValue); + return pValue; + } + + public static void SetValue(this ICorDebugReferenceValue instance, ulong value) + { + instance.__SetValue(value); + } + + public static ICorDebugValue Dereference(this ICorDebugReferenceValue instance) + { + ICorDebugValue ppValue; + instance.__Dereference(out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ICorDebugValue DereferenceStrong(this ICorDebugReferenceValue instance) + { + ICorDebugValue ppValue; + instance.__DereferenceStrong(out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static ulong GetRegistersAvailable(this ICorDebugRegisterSet instance) + { + ulong pAvailable; + instance.__GetRegistersAvailable(out pAvailable); + return pAvailable; + } + + public static void GetRegisters(this ICorDebugRegisterSet instance, ulong mask, uint regCount, IntPtr regBuffer) + { + instance.__GetRegisters(mask, regCount, regBuffer); + } + + public static void SetRegisters(this ICorDebugRegisterSet instance, ulong mask, uint regCount, ref ulong regBuffer) + { + instance.__SetRegisters(mask, regCount, ref regBuffer); + } + + public static void GetThreadContext(this ICorDebugRegisterSet instance, uint contextSize, IntPtr context) + { + instance.__GetThreadContext(contextSize, context); + } + + public static void SetThreadContext(this ICorDebugRegisterSet instance, uint contextSize, IntPtr context) + { + instance.__SetThreadContext(contextSize, context); + } + + public static int IsActive(this ICorDebugStepper instance) + { + int pbActive; + instance.__IsActive(out pbActive); + return pbActive; + } + + public static void Deactivate(this ICorDebugStepper instance) + { + instance.__Deactivate(); + } + + public static void SetInterceptMask(this ICorDebugStepper instance, CorDebugIntercept mask) + { + instance.__SetInterceptMask(mask); + } + + public static void SetUnmappedStopMask(this ICorDebugStepper instance, CorDebugUnmappedStop mask) + { + instance.__SetUnmappedStopMask(mask); + } + + public static void Step(this ICorDebugStepper instance, int bStepIn) + { + instance.__Step(bStepIn); + } + + public static void StepRange(this ICorDebugStepper instance, int bStepIn, IntPtr ranges, uint cRangeCount) + { + instance.__StepRange(bStepIn, ranges, cRangeCount); + } + + public static void StepOut(this ICorDebugStepper instance) + { + instance.__StepOut(); + } + + public static void SetRangeIL(this ICorDebugStepper instance, int bIL) + { + instance.__SetRangeIL(bIL); + } + + public static void SetJMC(this ICorDebugStepper2 instance, int fIsJMCStepper) + { + instance.__SetJMC(fIsJMCStepper); + } + + public static void Skip(this ICorDebugStepperEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugStepperEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugStepperEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugStepperEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugStepperEnum instance, uint celt, IntPtr steppers) + { + uint pceltFetched; + instance.__Next(celt, steppers, out pceltFetched); + return pceltFetched; + } + + public static uint GetTheType(this ICorDebugStringValue instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugStringValue instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugStringValue instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugStringValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static int IsValid(this ICorDebugStringValue instance) + { + int pbValid; + instance.__IsValid(out pbValid); + return pbValid; + } + + public static ICorDebugValueBreakpoint CreateRelocBreakpoint(this ICorDebugStringValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateRelocBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static uint GetLength(this ICorDebugStringValue instance) + { + uint pcchString; + instance.__GetLength(out pcchString); + return pcchString; + } + + public static void GetString(this ICorDebugStringValue instance, uint cchString, out uint pcchString, IntPtr szString) + { + instance.__GetString(cchString, out pcchString, szString); + } + + public static ICorDebugProcess GetProcess(this ICorDebugThread instance) + { + ICorDebugProcess ppProcess; + instance.__GetProcess(out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static uint GetID(this ICorDebugThread instance) + { + uint pdwThreadId; + instance.__GetID(out pdwThreadId); + return pdwThreadId; + } + + public static uint GetHandle(this ICorDebugThread instance) + { + uint phThreadHandle; + instance.__GetHandle(out phThreadHandle); + return phThreadHandle; + } + + public static ICorDebugAppDomain GetAppDomain(this ICorDebugThread instance) + { + ICorDebugAppDomain ppAppDomain; + instance.__GetAppDomain(out ppAppDomain); + ProcessOutParameter(ppAppDomain); + return ppAppDomain; + } + + public static void SetDebugState(this ICorDebugThread instance, CorDebugThreadState state) + { + instance.__SetDebugState(state); + } + + public static CorDebugThreadState GetDebugState(this ICorDebugThread instance) + { + CorDebugThreadState pState; + instance.__GetDebugState(out pState); + ProcessOutParameter(pState); + return pState; + } + + public static CorDebugUserState GetUserState(this ICorDebugThread instance) + { + CorDebugUserState pState; + instance.__GetUserState(out pState); + ProcessOutParameter(pState); + return pState; + } + + public static ICorDebugValue GetCurrentException(this ICorDebugThread instance) + { + ICorDebugValue ppExceptionObject; + instance.__GetCurrentException(out ppExceptionObject); + ProcessOutParameter(ppExceptionObject); + return ppExceptionObject; + } + + public static void ClearCurrentException(this ICorDebugThread instance) + { + instance.__ClearCurrentException(); + } + + public static ICorDebugStepper CreateStepper(this ICorDebugThread instance) + { + ICorDebugStepper ppStepper; + instance.__CreateStepper(out ppStepper); + ProcessOutParameter(ppStepper); + return ppStepper; + } + + public static ICorDebugChainEnum EnumerateChains(this ICorDebugThread instance) + { + ICorDebugChainEnum ppChains; + instance.__EnumerateChains(out ppChains); + ProcessOutParameter(ppChains); + return ppChains; + } + + public static ICorDebugChain GetActiveChain(this ICorDebugThread instance) + { + ICorDebugChain ppChain; + instance.__GetActiveChain(out ppChain); + ProcessOutParameter(ppChain); + return ppChain; + } + + public static ICorDebugFrame GetActiveFrame(this ICorDebugThread instance) + { + ICorDebugFrame ppFrame; + instance.__GetActiveFrame(out ppFrame); + ProcessOutParameter(ppFrame); + return ppFrame; + } + + public static ICorDebugRegisterSet GetRegisterSet(this ICorDebugThread instance) + { + ICorDebugRegisterSet ppRegisters; + instance.__GetRegisterSet(out ppRegisters); + ProcessOutParameter(ppRegisters); + return ppRegisters; + } + + public static ICorDebugEval CreateEval(this ICorDebugThread instance) + { + ICorDebugEval ppEval; + instance.__CreateEval(out ppEval); + ProcessOutParameter(ppEval); + return ppEval; + } + + public static ICorDebugValue GetObject(this ICorDebugThread instance) + { + ICorDebugValue ppObject; + instance.__GetObject(out ppObject); + ProcessOutParameter(ppObject); + return ppObject; + } + + public static void GetActiveFunctions(this ICorDebugThread2 instance, uint cFunctions, out uint pcFunctions, IntPtr pFunctions) + { + instance.__GetActiveFunctions(cFunctions, out pcFunctions, pFunctions); + } + + public static uint GetConnectionID(this ICorDebugThread2 instance) + { + uint pdwConnectionId; + instance.__GetConnectionID(out pdwConnectionId); + return pdwConnectionId; + } + + public static ulong GetTaskID(this ICorDebugThread2 instance) + { + ulong pTaskId; + instance.__GetTaskID(out pTaskId); + return pTaskId; + } + + public static uint GetVolatileOSThreadID(this ICorDebugThread2 instance) + { + uint pdwTid; + instance.__GetVolatileOSThreadID(out pdwTid); + return pdwTid; + } + + public static void InterceptCurrentException(this ICorDebugThread2 instance, ICorDebugFrame pFrame) + { + instance.__InterceptCurrentException(pFrame); + } + + public static void Skip(this ICorDebugThreadEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugThreadEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugThreadEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugThreadEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugThreadEnum instance, uint celt, ICorDebugThread[] threads) + { + uint pceltFetched; + instance.__Next(celt, threads, out pceltFetched); + ProcessOutParameter(threads); + return pceltFetched; + } + + public static uint GetTheType(this ICorDebugType instance) + { + uint ty; + instance.__GetType(out ty); + return ty; + } + + public static ICorDebugClass GetClass(this ICorDebugType instance) + { + ICorDebugClass ppClass; + instance.__GetClass(out ppClass); + ProcessOutParameter(ppClass); + return ppClass; + } + + public static ICorDebugTypeEnum EnumerateTypeParameters(this ICorDebugType instance) + { + ICorDebugTypeEnum ppTyParEnum; + instance.__EnumerateTypeParameters(out ppTyParEnum); + ProcessOutParameter(ppTyParEnum); + return ppTyParEnum; + } + + public static ICorDebugType GetFirstTypeParameter(this ICorDebugType instance) + { + ICorDebugType value; + instance.__GetFirstTypeParameter(out value); + ProcessOutParameter(value); + return value; + } + + public static ICorDebugType GetBase(this ICorDebugType instance) + { + ICorDebugType pBase; + instance.__GetBase(out pBase); + ProcessOutParameter(pBase); + return pBase; + } + + public static ICorDebugValue GetStaticFieldValue(this ICorDebugType instance, uint fieldDef, ICorDebugFrame pFrame) + { + ICorDebugValue ppValue; + instance.__GetStaticFieldValue(fieldDef, pFrame, out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static uint GetRank(this ICorDebugType instance) + { + uint pnRank; + instance.__GetRank(out pnRank); + return pnRank; + } + + public static void Skip(this ICorDebugTypeEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugTypeEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugTypeEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugTypeEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugTypeEnum instance, uint celt, ICorDebugType[] values) + { + uint pceltFetched; + instance.__Next(celt, values, out pceltFetched); + ProcessOutParameter(values); + return pceltFetched; + } + + public static void DebugEvent(this ICorDebugUnmanagedCallback instance, uint pDebugEvent, int fOutOfBand) + { + instance.__DebugEvent(pDebugEvent, fOutOfBand); + } + + public static uint GetTheType(this ICorDebugValue instance) + { + uint pType; + instance.__GetType(out pType); + return pType; + } + + public static uint GetSize(this ICorDebugValue instance) + { + uint pSize; + instance.__GetSize(out pSize); + return pSize; + } + + public static ulong GetAddress(this ICorDebugValue instance) + { + ulong pAddress; + instance.__GetAddress(out pAddress); + return pAddress; + } + + public static ICorDebugValueBreakpoint CreateBreakpoint(this ICorDebugValue instance) + { + ICorDebugValueBreakpoint ppBreakpoint; + instance.__CreateBreakpoint(out ppBreakpoint); + ProcessOutParameter(ppBreakpoint); + return ppBreakpoint; + } + + public static ICorDebugType GetExactType(this ICorDebugValue2 instance) + { + ICorDebugType ppType; + instance.__GetExactType(out ppType); + ProcessOutParameter(ppType); + return ppType; + } + + public static void Activate(this ICorDebugValueBreakpoint instance, int bActive) + { + instance.__Activate(bActive); + } + + public static int IsActive(this ICorDebugValueBreakpoint instance) + { + int pbActive; + instance.__IsActive(out pbActive); + return pbActive; + } + + public static ICorDebugValue GetValue(this ICorDebugValueBreakpoint instance) + { + ICorDebugValue ppValue; + instance.__GetValue(out ppValue); + ProcessOutParameter(ppValue); + return ppValue; + } + + public static void Skip(this ICorDebugValueEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorDebugValueEnum instance) + { + instance.__Reset(); + } + + public static ICorDebugEnum Clone(this ICorDebugValueEnum instance) + { + ICorDebugEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorDebugValueEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static uint Next(this ICorDebugValueEnum instance, uint celt, IntPtr values) + { + uint pceltFetched; + instance.__Next(celt, values, out pceltFetched); + return pceltFetched; + } + + } +} diff --git a/Debugger/Debugger.Core/Interop/CorPublish.cs b/Debugger/Debugger.Core/Interop/CorPublish.cs new file mode 100644 index 000000000..112485052 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/CorPublish.cs @@ -0,0 +1,138 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +#pragma warning disable 108, 1591 + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace Debugger.Interop.CorPublish +{ + [ComImport, TypeLibType((short) 2), ClassInterface((short) 0), Guid("047A9A40-657E-11D3-8D5B-00104B35E7EF")] + public class CorpubPublishClass : ICorPublish, CorpubPublish, ICorPublishProcess, ICorPublishAppDomain, ICorPublishProcessEnum, ICorPublishAppDomainEnum + { + // Methods + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorPublishEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __EnumAppDomains([MarshalAs(UnmanagedType.Interface)] out ICorPublishAppDomainEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __EnumProcesses([In, ComAliasName("CorpubProcessLib.COR_PUB_ENUMPROCESS")] COR_PUB_ENUMPROCESS Type, [MarshalAs(UnmanagedType.Interface)] out ICorPublishProcessEnum ppIEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetDisplayName([In] uint cchName, out uint pcchName, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetID(out uint puId); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetName([In] uint cchName, out uint pcchName, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetProcess([In] uint pid, [MarshalAs(UnmanagedType.Interface)] out ICorPublishProcess ppProcess); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetProcessID(out uint pid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __ICorPublishAppDomainEnum_Clone([MarshalAs(UnmanagedType.Interface)] out ICorPublishEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __ICorPublishAppDomainEnum_GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __ICorPublishAppDomainEnum_Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __ICorPublishAppDomainEnum_Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __IsManaged(out int pbManaged); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Next([In] uint celt, [MarshalAs(UnmanagedType.Interface)] out ICorPublishAppDomain objects, out uint pceltFetched); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Next([In] uint celt, [MarshalAs(UnmanagedType.Interface)] out ICorPublishProcess objects, out uint pceltFetched); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Skip([In] uint celt); + } + + [ComImport, CoClass(typeof(CorpubPublishClass)), Guid("9613A0E7-5A68-11D3-8F84-00A0C9B4D50C")] + public interface CorpubPublish : ICorPublish + { + } + + public enum COR_PUB_ENUMPROCESS + { + COR_PUB_MANAGEDONLY = 1 + } + + [ComImport, Guid("9613A0E7-5A68-11D3-8F84-00A0C9B4D50C"), InterfaceType((short) 1)] + public interface ICorPublish + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumProcesses([In, ComAliasName("CorpubProcessLib.COR_PUB_ENUMPROCESS")] COR_PUB_ENUMPROCESS Type, [MarshalAs(UnmanagedType.Interface)] out ICorPublishProcessEnum ppIEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetProcess([In] uint pid, [MarshalAs(UnmanagedType.Interface)] out ICorPublishProcess ppProcess); + } + + [ComImport, Guid("D6315C8F-5A6A-11D3-8F84-00A0C9B4D50C"), InterfaceType((short) 1)] + public interface ICorPublishAppDomain + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetID(out uint puId); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetName([In] uint cchName, out uint pcchName, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName); + } + + [ComImport, Guid("9F0C98F5-5A6A-11D3-8F84-00A0C9B4D50C"), InterfaceType((short) 1),] + public interface ICorPublishAppDomainEnum : ICorPublishEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorPublishEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [MarshalAs(UnmanagedType.Interface)] out ICorPublishAppDomain objects, out uint pceltFetched); + } + + [ComImport, Guid("C0B22967-5A69-11D3-8F84-00A0C9B4D50C"), InterfaceType((short) 1)] + public interface ICorPublishEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorPublishEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + } + + [ComImport, Guid("18D87AF1-5A6A-11D3-8F84-00A0C9B4D50C"), InterfaceType((short) 1)] + public interface ICorPublishProcess + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __IsManaged(out int pbManaged); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __EnumAppDomains([MarshalAs(UnmanagedType.Interface)] out ICorPublishAppDomainEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetProcessID(out uint pid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetDisplayName([In] uint cchName, out uint pcchName, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName); + } + + [ComImport, Guid("A37FBD41-5A69-11D3-8F84-00A0C9B4D50C"), InterfaceType((short) 1)] + public interface ICorPublishProcessEnum : ICorPublishEnum + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Skip([In] uint celt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Reset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Clone([MarshalAs(UnmanagedType.Interface)] out ICorPublishEnum ppEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCount(out uint pcelt); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Next([In] uint celt, [MarshalAs(UnmanagedType.Interface)] out ICorPublishProcess objects, out uint pceltFetched); + } +} diff --git a/Debugger/Debugger.Core/Interop/CorPublishExtensionMethods.cs b/Debugger/Debugger.Core/Interop/CorPublishExtensionMethods.cs new file mode 100644 index 000000000..728dd1868 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/CorPublishExtensionMethods.cs @@ -0,0 +1,15 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Debugger.Interop.CorPublish +{ + public static partial class CorPublishExtensionMethods + { + static void ProcessOutParameter(object parameter) + { + TrackedComObjects.ProcessOutParameter(parameter); + } + } +} diff --git a/Debugger/Debugger.Core/Interop/CorPublishExtensionMethods.generated.cs b/Debugger/Debugger.Core/Interop/CorPublishExtensionMethods.generated.cs new file mode 100644 index 000000000..3ab0500ad --- /dev/null +++ b/Debugger/Debugger.Core/Interop/CorPublishExtensionMethods.generated.cs @@ -0,0 +1,273 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace Debugger.Interop.CorPublish +{ + public static partial class CorPublishExtensionMethods + { + public static ICorPublishEnum Clone(this CorpubPublishClass instance) + { + ICorPublishEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static ICorPublishAppDomainEnum EnumAppDomains(this CorpubPublishClass instance) + { + ICorPublishAppDomainEnum ppEnum; + instance.__EnumAppDomains(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static ICorPublishProcessEnum EnumProcesses(this CorpubPublishClass instance, COR_PUB_ENUMPROCESS Type) + { + ICorPublishProcessEnum ppIEnum; + instance.__EnumProcesses(Type, out ppIEnum); + ProcessOutParameter(ppIEnum); + return ppIEnum; + } + + public static uint GetCount(this CorpubPublishClass instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static void GetDisplayName(this CorpubPublishClass instance, uint cchName, out uint pcchName, StringBuilder szName) + { + instance.__GetDisplayName(cchName, out pcchName, szName); + } + + public static uint GetID(this CorpubPublishClass instance) + { + uint puId; + instance.__GetID(out puId); + return puId; + } + + public static void GetName(this CorpubPublishClass instance, uint cchName, out uint pcchName, StringBuilder szName) + { + instance.__GetName(cchName, out pcchName, szName); + } + + public static ICorPublishProcess GetProcess(this CorpubPublishClass instance, uint pid) + { + ICorPublishProcess ppProcess; + instance.__GetProcess(pid, out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static uint GetProcessID(this CorpubPublishClass instance) + { + uint pid; + instance.__GetProcessID(out pid); + return pid; + } + + public static ICorPublishEnum ICorPublishAppDomainEnum_Clone(this CorpubPublishClass instance) + { + ICorPublishEnum ppEnum; + instance.__ICorPublishAppDomainEnum_Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint ICorPublishAppDomainEnum_GetCount(this CorpubPublishClass instance) + { + uint pcelt; + instance.__ICorPublishAppDomainEnum_GetCount(out pcelt); + return pcelt; + } + + public static void ICorPublishAppDomainEnum_Reset(this CorpubPublishClass instance) + { + instance.__ICorPublishAppDomainEnum_Reset(); + } + + public static void ICorPublishAppDomainEnum_Skip(this CorpubPublishClass instance, uint celt) + { + instance.__ICorPublishAppDomainEnum_Skip(celt); + } + + public static int IsManaged(this CorpubPublishClass instance) + { + int pbManaged; + instance.__IsManaged(out pbManaged); + return pbManaged; + } + + public static void Next(this CorpubPublishClass instance, uint celt, out ICorPublishAppDomain objects, out uint pceltFetched) + { + instance.__Next(celt, out objects, out pceltFetched); + ProcessOutParameter(objects); + } + + public static void Next(this CorpubPublishClass instance, uint celt, out ICorPublishProcess objects, out uint pceltFetched) + { + instance.__Next(celt, out objects, out pceltFetched); + ProcessOutParameter(objects); + } + + public static void Reset(this CorpubPublishClass instance) + { + instance.__Reset(); + } + + public static void Skip(this CorpubPublishClass instance, uint celt) + { + instance.__Skip(celt); + } + + public static ICorPublishProcessEnum EnumProcesses(this ICorPublish instance, COR_PUB_ENUMPROCESS Type) + { + ICorPublishProcessEnum ppIEnum; + instance.__EnumProcesses(Type, out ppIEnum); + ProcessOutParameter(ppIEnum); + return ppIEnum; + } + + public static ICorPublishProcess GetProcess(this ICorPublish instance, uint pid) + { + ICorPublishProcess ppProcess; + instance.__GetProcess(pid, out ppProcess); + ProcessOutParameter(ppProcess); + return ppProcess; + } + + public static uint GetID(this ICorPublishAppDomain instance) + { + uint puId; + instance.__GetID(out puId); + return puId; + } + + public static void GetName(this ICorPublishAppDomain instance, uint cchName, out uint pcchName, StringBuilder szName) + { + instance.__GetName(cchName, out pcchName, szName); + } + + public static void Skip(this ICorPublishAppDomainEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorPublishAppDomainEnum instance) + { + instance.__Reset(); + } + + public static ICorPublishEnum Clone(this ICorPublishAppDomainEnum instance) + { + ICorPublishEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorPublishAppDomainEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static void Next(this ICorPublishAppDomainEnum instance, uint celt, out ICorPublishAppDomain objects, out uint pceltFetched) + { + instance.__Next(celt, out objects, out pceltFetched); + ProcessOutParameter(objects); + } + + public static void Skip(this ICorPublishEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorPublishEnum instance) + { + instance.__Reset(); + } + + public static ICorPublishEnum Clone(this ICorPublishEnum instance) + { + ICorPublishEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorPublishEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static int IsManaged(this ICorPublishProcess instance) + { + int pbManaged; + instance.__IsManaged(out pbManaged); + return pbManaged; + } + + public static ICorPublishAppDomainEnum EnumAppDomains(this ICorPublishProcess instance) + { + ICorPublishAppDomainEnum ppEnum; + instance.__EnumAppDomains(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetProcessID(this ICorPublishProcess instance) + { + uint pid; + instance.__GetProcessID(out pid); + return pid; + } + + public static void GetDisplayName(this ICorPublishProcess instance, uint cchName, out uint pcchName, StringBuilder szName) + { + instance.__GetDisplayName(cchName, out pcchName, szName); + } + + public static void Skip(this ICorPublishProcessEnum instance, uint celt) + { + instance.__Skip(celt); + } + + public static void Reset(this ICorPublishProcessEnum instance) + { + instance.__Reset(); + } + + public static ICorPublishEnum Clone(this ICorPublishProcessEnum instance) + { + ICorPublishEnum ppEnum; + instance.__Clone(out ppEnum); + ProcessOutParameter(ppEnum); + return ppEnum; + } + + public static uint GetCount(this ICorPublishProcessEnum instance) + { + uint pcelt; + instance.__GetCount(out pcelt); + return pcelt; + } + + public static void Next(this ICorPublishProcessEnum instance, uint celt, out ICorPublishProcess objects, out uint pceltFetched) + { + instance.__Next(celt, out objects, out pceltFetched); + ProcessOutParameter(objects); + } + + } +} diff --git a/Debugger/Debugger.Core/Interop/CorSym.cs b/Debugger/Debugger.Core/Interop/CorSym.cs new file mode 100644 index 000000000..738bcd4ff --- /dev/null +++ b/Debugger/Debugger.Core/Interop/CorSym.cs @@ -0,0 +1,523 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +#pragma warning disable 108, 1591 + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Debugger.Interop.CorSym +{ + public enum CorSymAddrKind + { + // Fields + ADDR_BITFIELD = 9, + ADDR_IL_OFFSET = 1, + ADDR_NATIVE_ISECTOFFSET = 10, + ADDR_NATIVE_OFFSET = 5, + ADDR_NATIVE_REGISTER = 3, + ADDR_NATIVE_REGREG = 6, + ADDR_NATIVE_REGREL = 4, + ADDR_NATIVE_REGSTK = 7, + ADDR_NATIVE_RVA = 2, + ADDR_NATIVE_STKREG = 8 + } + + [ComImport, CoClass(typeof(CorSymBinder_SxSClass)), Guid("AA544D42-28CB-11D3-BD22-0000F80849BD")] + public interface CorSymBinder_SxS : ISymUnmanagedBinder + { + } + + [ComImport, Guid("0A29FF9E-7F9C-4437-8B11-F424491E3931"), ClassInterface((short) 0), TypeLibType((short) 2)] + public class CorSymBinder_SxSClass : ISymUnmanagedBinder, CorSymBinder_SxS + { + // Methods + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), PreserveSig] + public virtual extern int __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath, [Out, In, MarshalAs(UnmanagedType.IUnknown)] ref object retVal); + + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern ISymUnmanagedReader __GetReaderFromStream([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In, MarshalAs(UnmanagedType.Interface)] IStream pstream); + + } + + [ComImport, CoClass(typeof(CorSymReader_SxSClass)), Guid("B4CE6286-2A6B-3712-A3B7-1EE1DAD467B5")] + public interface CorSymReader_SxS : ISymUnmanagedReader + { + } + + [ComImport, Guid("0A3976C5-4529-4EF8-B0B0-42EED37082CD"), TypeLibType((short) 2), ClassInterface((short) 0), ComConversionLoss] + public class CorSymReader_SxSClass : ISymUnmanagedReader, CorSymReader_SxS + { + // Methods + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern ISymUnmanagedDocument __GetDocument([In] IntPtr url, [In] Guid language, [In] Guid languageVendor, [In] Guid documentType); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetDocuments([In] uint cDocs, out uint pcDocs, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedDocument[] pDocs); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetDocumentVersion([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument pDoc, out int version, out int pbCurrent); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetGlobalVariables([In] uint cVars, out uint pcVars, [Out] IntPtr pVars); + + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern ISymUnmanagedMethod __GetMethod([In] uint token); + + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern ISymUnmanagedMethod __GetMethodByVersion([In] uint token, [In] int version); + + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern ISymUnmanagedMethod __GetMethodFromDocumentPosition([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetMethodsFromDocumentPosition([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [In] uint cMethod, out uint pcMethod, [Out] IntPtr pRetVal); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetMethodVersion([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedMethod pMethod, out int version); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetNamespaces([In] uint cNameSpaces, out uint pcNameSpaces, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedNamespace[] namespaces); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetSymAttribute([In] uint parent, [In] IntPtr name, [In] uint cBuffer, out uint pcBuffer, [Out] IntPtr buffer); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetSymbolStoreFileName([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern uint __GetUserEntryPoint(); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetVariables([In] uint parent, [In] uint cVars, out uint pcVars, [Out] IntPtr pVars); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __ReplaceSymbolStore([In] IntPtr filename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __UpdateSymbolStore([In] IntPtr filename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream); + + } + + public enum CorSymSearchPolicyAttributes + { + // Fields + AllowOriginalPathAccess = 4, + AllowReferencePathAccess = 8, + AllowRegistryAccess = 1, + AllowSymbolServerAccess = 2 + } + + public enum CorSymVarFlag + { + // Fields + VAR_IS_COMP_GEN = 1 + } + + [ComImport, CoClass(typeof(CorSymWriter_SxSClass)), Guid("ED14AA72-78E2-4884-84E2-334293AE5214")] + public interface CorSymWriter_SxS : ISymUnmanagedWriter + { + } + + [ComImport, TypeLibType((short) 2), Guid("0AE2DEB0-F901-478B-BB9F-881EE8066788"), ClassInterface((short) 0), ComConversionLoss] + public class CorSymWriter_SxSClass : ISymUnmanagedWriter, CorSymWriter_SxS + { + // Methods + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Abort(); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Close(); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __CloseMethod(); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __CloseNamespace(); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __CloseScope([In] uint endOffset); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __DefineConstant([In] IntPtr name, [In, MarshalAs(UnmanagedType.Struct)] object value, [In] uint cSig, [In] ref byte signature); + + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern ISymUnmanagedDocumentWriter __DefineDocument([In] IntPtr url, [In] ref Guid language, [In] ref Guid languageVendor, [In] ref Guid documentType); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __DefineField([In] uint parent, [In] IntPtr name, [In] uint attributes, [In] uint cSig, [In] ref byte signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __DefineGlobalVariable([In] IntPtr name, [In] uint attributes, [In] uint cSig, [In] ref byte signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __DefineLocalVariable([In] IntPtr name, [In] uint attributes, [In] uint cSig, [In] ref byte signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3, [In] uint startOffset, [In] uint endOffset); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __DefineParameter([In] IntPtr name, [In] uint attributes, [In] uint sequence, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __DefineSequencePoints([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter document, [In] uint spCount, [In] ref uint offsets, [In] ref uint lines, [In] ref uint columns, [In] ref uint endLines, [In] ref uint endColumns); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __GetDebugInfo([In] ref uint pIDD, [In] uint cData, out uint pcData, [Out] IntPtr data); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object emitter, [In] IntPtr filename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream, [In] int fFullBuild); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __Initialize2([In, MarshalAs(UnmanagedType.IUnknown)] object emitter, [In] IntPtr tempfilename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream, [In] int fFullBuild, [In] IntPtr finalfilename); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __OpenMethod([In] uint method); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __OpenNamespace([In] IntPtr name); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern uint __OpenScope([In] uint startOffset); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __RemapToken([In] uint oldToken, [In] uint newToken); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __SetMethodSourceRange([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter startDoc, [In] uint startLine, [In] uint startColumn, [In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter endDoc, [In] uint endLine, [In] uint endColumn); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __SetScopeRange([In] uint scopeID, [In] uint startOffset, [In] uint endOffset); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __SetSymAttribute([In] uint parent, [In] IntPtr name, [In] uint cData, [In] ref byte data); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __SetUserEntryPoint([In] uint entryMethod); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + public virtual extern void __UsingNamespace([In] IntPtr fullName); + + } + + [ComImport, InterfaceType((short) 1), Guid("AA544D42-28CB-11D3-BD22-0000F80849BD")] + public interface ISymUnmanagedBinder + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), PreserveSig] + int __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath, [Out, In, MarshalAs(UnmanagedType.IUnknown)] ref object retVal); + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedReader __GetReaderFromStream([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In, MarshalAs(UnmanagedType.Interface)] IStream pstream); + } + + [ComImport, InterfaceType((short) 1), Guid("969708D2-05E5-4861-A3B0-96E473CDF63F")] + public interface ISymUnmanagedDispose + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Destroy(); + } + + [ComImport, Guid("40DE4037-7C81-3E1E-B022-AE1ABFF2CA08"), ComConversionLoss, InterfaceType((short) 1)] + public interface ISymUnmanagedDocument + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetURL([In] uint cchUrl, out uint pcchUrl, [Out] IntPtr szUrl); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + Guid __GetDocumentType(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + Guid __GetLanguage(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + Guid __GetLanguageVendor(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + Guid __GetCheckSumAlgorithmId(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetCheckSum([In] uint cData, out uint pcData, [Out] IntPtr data); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __FindClosestLine([In] uint line); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + int __HasEmbeddedSource(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetSourceLength(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSourceRange([In] uint startLine, [In] uint startColumn, [In] uint endLine, [In] uint endColumn, [In] uint cSourceBytes, out uint pcSourceBytes, [Out] IntPtr source); + } + + [ComImport, Guid("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006"), InterfaceType((short) 1)] + public interface ISymUnmanagedDocumentWriter + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetSource([In] uint sourceSize, [In] ref byte source); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetCheckSum([In] Guid algorithmId, [In] uint checkSumSize, [In] ref byte checkSum); + } + + [ComImport, InterfaceType((short) 1), ComConversionLoss, Guid("B62B923C-B500-3158-A543-24F307A8B7E1")] + public interface ISymUnmanagedMethod + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetToken(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetSequencePointCount(); + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedScope __GetRootScope(); + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedScope __GetScopeFromOffset([In] uint offset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetOffset([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetRanges([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [In] uint cRanges, out uint pcRanges, [Out] IntPtr ranges); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetParameters([In] uint cParams, out uint pcParams, [Out] IntPtr @params); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetNamespace([MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedNamespace pRetVal); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSourceStartEnd([In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0, SizeConst=2)] ISymUnmanagedDocument[] docs, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0, SizeConst=2)] uint[] lines, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0, SizeConst=2)] uint[] columns, out int pRetVal); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSequencePoints([In] uint cPoints, out uint pcPoints, [Out, MarshalAs(UnmanagedType.LPArray)] uint[] offsets, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedDocument[] documents, [Out, MarshalAs(UnmanagedType.LPArray)] uint[] lines, [Out, MarshalAs(UnmanagedType.LPArray)] uint[] columns, [Out, MarshalAs(UnmanagedType.LPArray)] uint[] endLines, [Out, MarshalAs(UnmanagedType.LPArray)] uint[] endColumns); + } + + [ComImport, InterfaceType((short) 1), ComConversionLoss, Guid("0DFF7289-54F8-11D3-BD28-0000F80849BD")] + public interface ISymUnmanagedNamespace + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetName([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetNamespaces([In] uint cNameSpaces, out uint pcNameSpaces, [Out] IntPtr namespaces); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetVariables([In] uint cVars, out uint pcVars, [Out] IntPtr pVars); + } + + [ComImport, InterfaceType((short) 1), ComConversionLoss, Guid("B4CE6286-2A6B-3712-A3B7-1EE1DAD467B5")] + public interface ISymUnmanagedReader + { + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedDocument __GetDocument([In] IntPtr url, [In] Guid language, [In] Guid languageVendor, [In] Guid documentType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetDocuments([In] uint cDocs, out uint pcDocs, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedDocument[] pDocs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetUserEntryPoint(); + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedMethod __GetMethod([In] uint token); + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedMethod __GetMethodByVersion([In] uint token, [In] int version); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetVariables([In] uint parent, [In] uint cVars, out uint pcVars, [Out] IntPtr pVars); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetGlobalVariables([In] uint cVars, out uint pcVars, [Out] IntPtr pVars); + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedMethod __GetMethodFromDocumentPosition([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSymAttribute([In] uint parent, [In] IntPtr name, [In] uint cBuffer, out uint pcBuffer, [Out] IntPtr buffer); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetNamespaces([In] uint cNameSpaces, out uint pcNameSpaces, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedNamespace[] namespaces); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __UpdateSymbolStore([In] IntPtr filename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __ReplaceSymbolStore([In] IntPtr filename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSymbolStoreFileName([In] uint cchName, out uint pcchName, [Out] IntPtr szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetMethodsFromDocumentPosition([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [In] uint cMethod, out uint pcMethod, [Out] IntPtr pRetVal); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetDocumentVersion([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocument pDoc, out int version, out int pbCurrent); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetMethodVersion([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedMethod pMethod, out int version); + } + + [ComImport, Guid("20D9645D-03CD-4E34-9C11-9848A5B084F1"), InterfaceType((short) 1)] + public interface ISymUnmanagedReaderSymbolSearchInfo + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSymbolSearchInfoCount(out uint pcSearchInfo); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSymbolSearchInfo([In] uint cSearchInfo, out uint pcSearchInfo, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedSymbolSearchInfo rgpSearchInfo); + } + + [ComImport, Guid("68005D0F-B8E0-3B01-84D5-A11A94154942"), ComConversionLoss, InterfaceType((short) 1)] + public interface ISymUnmanagedScope + { + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedMethod __GetMethod(); + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedScope __GetParent(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetChildren([In] uint cChildren, out uint pcChildren, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedScope[] children); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetStartOffset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetEndOffset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetLocalCount(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetLocals([In] uint cLocals, out uint pcLocals, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedVariable[] locals); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetNamespaces([In] uint cNameSpaces, out uint pcNameSpaces, [Out, MarshalAs(UnmanagedType.LPArray)] ISymUnmanagedNamespace[] namespaces); + } + + [ComImport, ComConversionLoss, InterfaceType((short) 1), Guid("F8B3534A-A46B-4980-B520-BEC4ACEABA8F")] + public interface ISymUnmanagedSymbolSearchInfo + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSearchPathLength(out uint pcchPath); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSearchPath([In] uint cchPath, out uint pcchPath, [Out] IntPtr szPath); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetHRESULT([MarshalAs(UnmanagedType.Error)] out int phr); + } + + [ComImport, Guid("9F60EEBE-2D9A-3F7C-BF58-80BC991C60BB"), InterfaceType((short) 1), ComConversionLoss] + public interface ISymUnmanagedVariable + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetName([In] uint cchName, out uint pcchName, [In] IntPtr szName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetAttributes(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetSignature([In] uint cSig, out uint pcSig, [In] IntPtr sig); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetAddressKind(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetAddressField1(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetAddressField2(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetAddressField3(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetStartOffset(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __GetEndOffset(); + } + + [ComImport, ComConversionLoss, InterfaceType((short) 1), Guid("ED14AA72-78E2-4884-84E2-334293AE5214")] + public interface ISymUnmanagedWriter + { + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedDocumentWriter __DefineDocument([In] IntPtr url, [In] ref Guid language, [In] ref Guid languageVendor, [In] ref Guid documentType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetUserEntryPoint([In] uint entryMethod); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __OpenMethod([In] uint method); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CloseMethod(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __OpenScope([In] uint startOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CloseScope([In] uint endOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetScopeRange([In] uint scopeID, [In] uint startOffset, [In] uint endOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineLocalVariable([In] IntPtr name, [In] uint attributes, [In] uint cSig, [In] ref byte signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3, [In] uint startOffset, [In] uint endOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineParameter([In] IntPtr name, [In] uint attributes, [In] uint sequence, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineField([In] uint parent, [In] IntPtr name, [In] uint attributes, [In] uint cSig, [In] ref byte signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineGlobalVariable([In] IntPtr name, [In] uint attributes, [In] uint cSig, [In] ref byte signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Close(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetSymAttribute([In] uint parent, [In] IntPtr name, [In] uint cData, [In] ref byte data); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __OpenNamespace([In] IntPtr name); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CloseNamespace(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __UsingNamespace([In] IntPtr fullName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetMethodSourceRange([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter startDoc, [In] uint startLine, [In] uint startColumn, [In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter endDoc, [In] uint endLine, [In] uint endColumn); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object emitter, [In] IntPtr filename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream, [In] int fFullBuild); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetDebugInfo([In] ref uint pIDD, [In] uint cData, out uint pcData, [Out] IntPtr data); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineSequencePoints([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter document, [In] uint spCount, [In] ref uint offsets, [In] ref uint lines, [In] ref uint columns, [In] ref uint endLines, [In] ref uint endColumns); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RemapToken([In] uint oldToken, [In] uint newToken); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Initialize2([In, MarshalAs(UnmanagedType.IUnknown)] object emitter, [In] IntPtr tempfilename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream, [In] int fFullBuild, [In] IntPtr finalfilename); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineConstant([In] IntPtr name, [In, MarshalAs(UnmanagedType.Struct)] object value, [In] uint cSig, [In] ref byte signature); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Abort(); + } + + [ComImport, Guid("0B97726E-9E6D-4F05-9A26-424022093CAA"), InterfaceType((short) 1)] + public interface ISymUnmanagedWriter2 : ISymUnmanagedWriter + { + [return: MarshalAs(UnmanagedType.Interface)] + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + ISymUnmanagedDocumentWriter __DefineDocument([In] IntPtr url, [In] ref Guid language, [In] ref Guid languageVendor, [In] ref Guid documentType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetUserEntryPoint([In] uint entryMethod); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __OpenMethod([In] uint method); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CloseMethod(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + uint __OpenScope([In] uint startOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CloseScope([In] uint endOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetScopeRange([In] uint scopeID, [In] uint startOffset, [In] uint endOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineLocalVariable([In] IntPtr name, [In] uint attributes, [In] uint cSig, [In] ref byte signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3, [In] uint startOffset, [In] uint endOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineParameter([In] IntPtr name, [In] uint attributes, [In] uint sequence, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineField([In] uint parent, [In] IntPtr name, [In] uint attributes, [In] uint cSig, [In] ref byte signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineGlobalVariable([In] IntPtr name, [In] uint attributes, [In] uint cSig, [In] ref byte signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Close(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetSymAttribute([In] uint parent, [In] IntPtr name, [In] uint cData, [In] ref byte data); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __OpenNamespace([In] IntPtr name); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __CloseNamespace(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __UsingNamespace([In] IntPtr fullName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __SetMethodSourceRange([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter startDoc, [In] uint startLine, [In] uint startColumn, [In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter endDoc, [In] uint endLine, [In] uint endColumn); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object emitter, [In] IntPtr filename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream, [In] int fFullBuild); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __GetDebugInfo([In] ref uint pIDD, [In] uint cData, out uint pcData, [Out] IntPtr data); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineSequencePoints([In, MarshalAs(UnmanagedType.Interface)] ISymUnmanagedDocumentWriter document, [In] uint spCount, [In] ref uint offsets, [In] ref uint lines, [In] ref uint columns, [In] ref uint endLines, [In] ref uint endColumns); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __RemapToken([In] uint oldToken, [In] uint newToken); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Initialize2([In, MarshalAs(UnmanagedType.IUnknown)] object emitter, [In] IntPtr tempfilename, [In, MarshalAs(UnmanagedType.Interface)] IStream pIStream, [In] int fFullBuild, [In] IntPtr finalfilename); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineConstant([In] IntPtr name, [In, MarshalAs(UnmanagedType.Struct)] object value, [In] uint cSig, [In] ref byte signature); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __Abort(); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineLocalVariable2([In] IntPtr name, [In] uint attributes, [In] uint sigToken, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3, [In] uint startOffset, [In] uint endOffset); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineGlobalVariable2([In] IntPtr name, [In] uint attributes, [In] uint sigToken, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void __DefineConstant2([In] IntPtr name, [In, MarshalAs(UnmanagedType.Struct)] object value, [In] uint sigToken); + } +} + +#pragma warning restore 108, 1591 diff --git a/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.cs b/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.cs new file mode 100644 index 000000000..eac10e2c8 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.cs @@ -0,0 +1,194 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Runtime.InteropServices; + +namespace Debugger.Interop.CorSym +{ + public static partial class CorSymExtensionMethods + { + static void ProcessOutParameter(object parameter) + { + TrackedComObjects.ProcessOutParameter(parameter); + } + + // ISymUnmanagedBinder + + public static ISymUnmanagedReader GetReaderForFile(this ISymUnmanagedBinder symBinder, object importer, string filename, string searchPath) + { + IntPtr pfilename = Marshal.StringToCoTaskMemUni(filename); + IntPtr psearchPath = Marshal.StringToCoTaskMemUni(searchPath); + object res = null; + // The method will create the object anyway so we have to use preservesig so that we can release it + // failing to do so would lock the assembly + int code = symBinder.GetReaderForFile(importer, pfilename, psearchPath, ref res); + Marshal.FreeCoTaskMem(pfilename); + Marshal.FreeCoTaskMem(psearchPath); + if (code != 0) { + Marshal.FinalReleaseComObject(res); + throw new COMException("", code); + } + return (ISymUnmanagedReader)res; + } + + // ISymUnmanagedDocument + + public static string GetURL(this ISymUnmanagedDocument symDoc) + { + return Util.GetCorSymString(symDoc.GetURL); + } + + public static unsafe byte[] GetCheckSum(this ISymUnmanagedDocument symDoc) + { + uint actualLength; + byte[] checkSum = new byte[20]; + fixed(byte* pCheckSum = checkSum) + symDoc.GetCheckSum((uint)checkSum.Length, out actualLength, new IntPtr(pCheckSum)); + if (actualLength > checkSum.Length) { + checkSum = new byte[actualLength]; + fixed(byte* pCheckSum = checkSum) + symDoc.GetCheckSum((uint)checkSum.Length, out actualLength, new IntPtr(pCheckSum)); + } + if (actualLength == 0) return null; + Array.Resize(ref checkSum, (int)actualLength); + return checkSum; + } + + // ISymUnmanagedMethod + + public static SequencePoint[] GetSequencePoints(this ISymUnmanagedMethod symMethod) + { + uint count = symMethod.GetSequencePointCount(); + + ISymUnmanagedDocument[] documents = new ISymUnmanagedDocument[count]; + uint[] offsets = new uint[count]; + uint[] lines = new uint[count]; + uint[] columns = new uint[count]; + uint[] endLines = new uint[count]; + uint[] endColumns = new uint[count]; + + symMethod.GetSequencePoints( + count, + out count, + offsets, + documents, + lines, + columns, + endLines, + endColumns + ); + + SequencePoint[] sequencePoints = new SequencePoint[count]; + + for(int i = 0; i < count; i++) { + sequencePoints[i] = new SequencePoint() { + Document = documents[i], + Offset = offsets[i], + Line = lines[i], + Column = columns[i], + EndLine = endLines[i], + EndColumn = endColumns[i] + }; + } + + return sequencePoints; + } + + // ISymUnmanagedReader + + public static ISymUnmanagedDocument GetDocument(this ISymUnmanagedReader symReader, string url, System.Guid language, System.Guid languageVendor, System.Guid documentType) + { + IntPtr p = Marshal.StringToCoTaskMemUni(url); + ISymUnmanagedDocument res = symReader.GetDocument(p, language, languageVendor, documentType); + Marshal.FreeCoTaskMem(p); + return res; + } + + // ISymUnmanagedScope + + public static ISymUnmanagedScope[] GetChildren(this ISymUnmanagedScope symScope) + { + uint count; + symScope.GetChildren(0, out count, new ISymUnmanagedScope[0]); + ISymUnmanagedScope[] children = new ISymUnmanagedScope[count]; + symScope.GetChildren(count, out count, children); + return children; + } + + public static ISymUnmanagedVariable[] GetLocals(this ISymUnmanagedScope symScope) + { + uint count; + symScope.GetLocals(0, out count, new ISymUnmanagedVariable[0]); + ISymUnmanagedVariable[] locals = new ISymUnmanagedVariable[count]; + symScope.GetLocals(count, out count, locals); + return locals; + } + + public static ISymUnmanagedNamespace[] GetNamespaces(this ISymUnmanagedScope symScope) + { + uint count; + symScope.GetNamespaces(0, out count, new ISymUnmanagedNamespace[0]); + ISymUnmanagedNamespace[] namespaces = new ISymUnmanagedNamespace[count]; + symScope.GetNamespaces(count, out count, namespaces); + return namespaces; + } + + // ISymUnmanagedNamespace + + public static string GetName(this ISymUnmanagedNamespace symNs) + { + return Util.GetCorSymString(symNs.GetName); + } + + // ISymUnmanagedVariable + + public static string GetName(this ISymUnmanagedVariable symVar) + { + return Util.GetCorSymString(symVar.GetName); + } + + const int defaultSigSize = 8; + + public static unsafe byte[] GetSignature(this ISymUnmanagedVariable symVar) + { + byte[] sig = new byte[defaultSigSize]; + uint acualSize; + fixed(byte* pSig = sig) + symVar.GetSignature((uint)sig.Length, out acualSize, new IntPtr(pSig)); + Array.Resize(ref sig, (int)acualSize); + if (acualSize > defaultSigSize) + fixed(byte* pSig = sig) + symVar.GetSignature((uint)sig.Length, out acualSize, new IntPtr(pSig)); + return sig; + } + + // ISymUnmanagedReader + + public static ISymUnmanagedNamespace[] GetNamespaces(this ISymUnmanagedReader symReader) + { + uint count; + symReader.GetNamespaces(0, out count, new ISymUnmanagedNamespace[0]); + ISymUnmanagedNamespace[] namespaces = new ISymUnmanagedNamespace[count]; + symReader.GetNamespaces(count, out count, namespaces); + return namespaces; + } + } + + public class SequencePoint: IComparable + { + public ISymUnmanagedDocument Document { get; internal set; } + public uint Offset { get; internal set; } + public uint Line { get; internal set; } + public uint Column { get; internal set; } + public uint EndLine { get; internal set; } + public uint EndColumn { get; internal set; } + + public int CompareTo(SequencePoint other) + { + if (this.Line != other.Line) return this.Line.CompareTo(other.Line); + if (this.Column != other.Column) return this.Column.CompareTo(other.Column); + return this.Offset.CompareTo(other.Offset); + } + } +} diff --git a/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs b/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs new file mode 100644 index 000000000..137e8dd2e --- /dev/null +++ b/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs @@ -0,0 +1,901 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Debugger.Interop.CorSym +{ + public static partial class CorSymExtensionMethods + { + public static int GetReaderForFile(this CorSymBinder_SxSClass instance, object importer, IntPtr filename, IntPtr searchPath, ref object retVal) + { + int returnValue = instance.__GetReaderForFile(importer, filename, searchPath, ref retVal); + ProcessOutParameter(retVal); + return returnValue; + } + + public static ISymUnmanagedReader GetReaderFromStream(this CorSymBinder_SxSClass instance, object importer, IStream pstream) + { + ISymUnmanagedReader returnValue = instance.__GetReaderFromStream(importer, pstream); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static ISymUnmanagedDocument GetDocument(this CorSymReader_SxSClass instance, IntPtr url, Guid language, Guid languageVendor, Guid documentType) + { + ISymUnmanagedDocument returnValue = instance.__GetDocument(url, language, languageVendor, documentType); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void GetDocuments(this CorSymReader_SxSClass instance, uint cDocs, out uint pcDocs, ISymUnmanagedDocument[] pDocs) + { + instance.__GetDocuments(cDocs, out pcDocs, pDocs); + ProcessOutParameter(pDocs); + } + + public static void GetDocumentVersion(this CorSymReader_SxSClass instance, ISymUnmanagedDocument pDoc, out int version, out int pbCurrent) + { + instance.__GetDocumentVersion(pDoc, out version, out pbCurrent); + } + + public static void GetGlobalVariables(this CorSymReader_SxSClass instance, uint cVars, out uint pcVars, IntPtr pVars) + { + instance.__GetGlobalVariables(cVars, out pcVars, pVars); + } + + public static ISymUnmanagedMethod GetMethod(this CorSymReader_SxSClass instance, uint token) + { + ISymUnmanagedMethod returnValue = instance.__GetMethod(token); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static ISymUnmanagedMethod GetMethodByVersion(this CorSymReader_SxSClass instance, uint token, int version) + { + ISymUnmanagedMethod returnValue = instance.__GetMethodByVersion(token, version); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static ISymUnmanagedMethod GetMethodFromDocumentPosition(this CorSymReader_SxSClass instance, ISymUnmanagedDocument document, uint line, uint column) + { + ISymUnmanagedMethod returnValue = instance.__GetMethodFromDocumentPosition(document, line, column); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void GetMethodsFromDocumentPosition(this CorSymReader_SxSClass instance, ISymUnmanagedDocument document, uint line, uint column, uint cMethod, out uint pcMethod, IntPtr pRetVal) + { + instance.__GetMethodsFromDocumentPosition(document, line, column, cMethod, out pcMethod, pRetVal); + } + + public static int GetMethodVersion(this CorSymReader_SxSClass instance, ISymUnmanagedMethod pMethod) + { + int version; + instance.__GetMethodVersion(pMethod, out version); + return version; + } + + public static void GetNamespaces(this CorSymReader_SxSClass instance, uint cNameSpaces, out uint pcNameSpaces, ISymUnmanagedNamespace[] namespaces) + { + instance.__GetNamespaces(cNameSpaces, out pcNameSpaces, namespaces); + ProcessOutParameter(namespaces); + } + + public static void GetSymAttribute(this CorSymReader_SxSClass instance, uint parent, IntPtr name, uint cBuffer, out uint pcBuffer, IntPtr buffer) + { + instance.__GetSymAttribute(parent, name, cBuffer, out pcBuffer, buffer); + } + + public static void GetSymbolStoreFileName(this CorSymReader_SxSClass instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetSymbolStoreFileName(cchName, out pcchName, szName); + } + + public static uint GetUserEntryPoint(this CorSymReader_SxSClass instance) + { + return instance.__GetUserEntryPoint(); + } + + public static void GetVariables(this CorSymReader_SxSClass instance, uint parent, uint cVars, out uint pcVars, IntPtr pVars) + { + instance.__GetVariables(parent, cVars, out pcVars, pVars); + } + + public static void Initialize(this CorSymReader_SxSClass instance, object importer, IntPtr filename, IntPtr searchPath, IStream pIStream) + { + instance.__Initialize(importer, filename, searchPath, pIStream); + } + + public static void ReplaceSymbolStore(this CorSymReader_SxSClass instance, IntPtr filename, IStream pIStream) + { + instance.__ReplaceSymbolStore(filename, pIStream); + } + + public static void UpdateSymbolStore(this CorSymReader_SxSClass instance, IntPtr filename, IStream pIStream) + { + instance.__UpdateSymbolStore(filename, pIStream); + } + + public static void Abort(this CorSymWriter_SxSClass instance) + { + instance.__Abort(); + } + + public static void Close(this CorSymWriter_SxSClass instance) + { + instance.__Close(); + } + + public static void CloseMethod(this CorSymWriter_SxSClass instance) + { + instance.__CloseMethod(); + } + + public static void CloseNamespace(this CorSymWriter_SxSClass instance) + { + instance.__CloseNamespace(); + } + + public static void CloseScope(this CorSymWriter_SxSClass instance, uint endOffset) + { + instance.__CloseScope(endOffset); + } + + public static void DefineConstant(this CorSymWriter_SxSClass instance, IntPtr name, object value, uint cSig, ref byte signature) + { + instance.__DefineConstant(name, value, cSig, ref signature); + ProcessOutParameter(signature); + } + + public static ISymUnmanagedDocumentWriter DefineDocument(this CorSymWriter_SxSClass instance, IntPtr url, ref Guid language, ref Guid languageVendor, ref Guid documentType) + { + ISymUnmanagedDocumentWriter returnValue = instance.__DefineDocument(url, ref language, ref languageVendor, ref documentType); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void DefineField(this CorSymWriter_SxSClass instance, uint parent, IntPtr name, uint attributes, uint cSig, ref byte signature, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineField(parent, name, attributes, cSig, ref signature, addrKind, addr1, addr2, addr3); + ProcessOutParameter(signature); + } + + public static void DefineGlobalVariable(this CorSymWriter_SxSClass instance, IntPtr name, uint attributes, uint cSig, ref byte signature, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineGlobalVariable(name, attributes, cSig, ref signature, addrKind, addr1, addr2, addr3); + ProcessOutParameter(signature); + } + + public static void DefineLocalVariable(this CorSymWriter_SxSClass instance, IntPtr name, uint attributes, uint cSig, ref byte signature, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, + uint endOffset) + { + instance.__DefineLocalVariable(name, attributes, cSig, ref signature, addrKind, addr1, addr2, addr3, startOffset, endOffset); + ProcessOutParameter(signature); + } + + public static void DefineParameter(this CorSymWriter_SxSClass instance, IntPtr name, uint attributes, uint sequence, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineParameter(name, attributes, sequence, addrKind, addr1, addr2, addr3); + } + + public static void DefineSequencePoints(this CorSymWriter_SxSClass instance, ISymUnmanagedDocumentWriter document, uint spCount, ref uint offsets, ref uint lines, ref uint columns, ref uint endLines, ref uint endColumns) + { + instance.__DefineSequencePoints(document, spCount, ref offsets, ref lines, ref columns, ref endLines, ref endColumns); + } + + public static void GetDebugInfo(this CorSymWriter_SxSClass instance, ref uint pIDD, uint cData, out uint pcData, IntPtr data) + { + instance.__GetDebugInfo(ref pIDD, cData, out pcData, data); + } + + public static void Initialize(this CorSymWriter_SxSClass instance, object emitter, IntPtr filename, IStream pIStream, int fFullBuild) + { + instance.__Initialize(emitter, filename, pIStream, fFullBuild); + } + + public static void Initialize2(this CorSymWriter_SxSClass instance, object emitter, IntPtr tempfilename, IStream pIStream, int fFullBuild, IntPtr finalfilename) + { + instance.__Initialize2(emitter, tempfilename, pIStream, fFullBuild, finalfilename); + } + + public static void OpenMethod(this CorSymWriter_SxSClass instance, uint method) + { + instance.__OpenMethod(method); + } + + public static void OpenNamespace(this CorSymWriter_SxSClass instance, IntPtr name) + { + instance.__OpenNamespace(name); + } + + public static uint OpenScope(this CorSymWriter_SxSClass instance, uint startOffset) + { + return instance.__OpenScope(startOffset); + } + + public static void RemapToken(this CorSymWriter_SxSClass instance, uint oldToken, uint newToken) + { + instance.__RemapToken(oldToken, newToken); + } + + public static void SetMethodSourceRange(this CorSymWriter_SxSClass instance, ISymUnmanagedDocumentWriter startDoc, uint startLine, uint startColumn, ISymUnmanagedDocumentWriter endDoc, uint endLine, uint endColumn) + { + instance.__SetMethodSourceRange(startDoc, startLine, startColumn, endDoc, endLine, endColumn); + } + + public static void SetScopeRange(this CorSymWriter_SxSClass instance, uint scopeID, uint startOffset, uint endOffset) + { + instance.__SetScopeRange(scopeID, startOffset, endOffset); + } + + public static void SetSymAttribute(this CorSymWriter_SxSClass instance, uint parent, IntPtr name, uint cData, ref byte data) + { + instance.__SetSymAttribute(parent, name, cData, ref data); + ProcessOutParameter(data); + } + + public static void SetUserEntryPoint(this CorSymWriter_SxSClass instance, uint entryMethod) + { + instance.__SetUserEntryPoint(entryMethod); + } + + public static void UsingNamespace(this CorSymWriter_SxSClass instance, IntPtr fullName) + { + instance.__UsingNamespace(fullName); + } + + public static int GetReaderForFile(this ISymUnmanagedBinder instance, object importer, IntPtr filename, IntPtr searchPath, ref object retVal) + { + int returnValue = instance.__GetReaderForFile(importer, filename, searchPath, ref retVal); + ProcessOutParameter(retVal); + return returnValue; + } + + public static ISymUnmanagedReader GetReaderFromStream(this ISymUnmanagedBinder instance, object importer, IStream pstream) + { + ISymUnmanagedReader returnValue = instance.__GetReaderFromStream(importer, pstream); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void Destroy(this ISymUnmanagedDispose instance) + { + instance.__Destroy(); + } + + public static void GetURL(this ISymUnmanagedDocument instance, uint cchUrl, out uint pcchUrl, IntPtr szUrl) + { + instance.__GetURL(cchUrl, out pcchUrl, szUrl); + } + + public static Guid GetDocumentType(this ISymUnmanagedDocument instance) + { + return instance.__GetDocumentType(); + } + + public static Guid GetLanguage(this ISymUnmanagedDocument instance) + { + return instance.__GetLanguage(); + } + + public static Guid GetLanguageVendor(this ISymUnmanagedDocument instance) + { + return instance.__GetLanguageVendor(); + } + + public static Guid GetCheckSumAlgorithmId(this ISymUnmanagedDocument instance) + { + return instance.__GetCheckSumAlgorithmId(); + } + + public static void GetCheckSum(this ISymUnmanagedDocument instance, uint cData, out uint pcData, IntPtr data) + { + instance.__GetCheckSum(cData, out pcData, data); + } + + public static uint FindClosestLine(this ISymUnmanagedDocument instance, uint line) + { + return instance.__FindClosestLine(line); + } + + public static int HasEmbeddedSource(this ISymUnmanagedDocument instance) + { + return instance.__HasEmbeddedSource(); + } + + public static uint GetSourceLength(this ISymUnmanagedDocument instance) + { + return instance.__GetSourceLength(); + } + + public static void GetSourceRange(this ISymUnmanagedDocument instance, uint startLine, uint startColumn, uint endLine, uint endColumn, uint cSourceBytes, out uint pcSourceBytes, IntPtr source) + { + instance.__GetSourceRange(startLine, startColumn, endLine, endColumn, cSourceBytes, out pcSourceBytes, source); + } + + public static void SetSource(this ISymUnmanagedDocumentWriter instance, uint sourceSize, ref byte source) + { + instance.__SetSource(sourceSize, ref source); + ProcessOutParameter(source); + } + + public static void SetCheckSum(this ISymUnmanagedDocumentWriter instance, Guid algorithmId, uint checkSumSize, ref byte checkSum) + { + instance.__SetCheckSum(algorithmId, checkSumSize, ref checkSum); + ProcessOutParameter(checkSum); + } + + public static uint GetToken(this ISymUnmanagedMethod instance) + { + return instance.__GetToken(); + } + + public static uint GetSequencePointCount(this ISymUnmanagedMethod instance) + { + return instance.__GetSequencePointCount(); + } + + public static ISymUnmanagedScope GetRootScope(this ISymUnmanagedMethod instance) + { + ISymUnmanagedScope returnValue = instance.__GetRootScope(); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static ISymUnmanagedScope GetScopeFromOffset(this ISymUnmanagedMethod instance, uint offset) + { + ISymUnmanagedScope returnValue = instance.__GetScopeFromOffset(offset); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static uint GetOffset(this ISymUnmanagedMethod instance, ISymUnmanagedDocument document, uint line, uint column) + { + return instance.__GetOffset(document, line, column); + } + + public static void GetRanges(this ISymUnmanagedMethod instance, ISymUnmanagedDocument document, uint line, uint column, uint cRanges, out uint pcRanges, IntPtr ranges) + { + instance.__GetRanges(document, line, column, cRanges, out pcRanges, ranges); + } + + public static void GetParameters(this ISymUnmanagedMethod instance, uint cParams, out uint pcParams, IntPtr @params) + { + instance.__GetParameters(cParams, out pcParams, @params); + } + + public static ISymUnmanagedNamespace GetNamespace(this ISymUnmanagedMethod instance) + { + ISymUnmanagedNamespace pRetVal; + instance.__GetNamespace(out pRetVal); + ProcessOutParameter(pRetVal); + return pRetVal; + } + + public static int GetSourceStartEnd(this ISymUnmanagedMethod instance, ISymUnmanagedDocument[] docs, uint[] lines, uint[] columns) + { + int pRetVal; + instance.__GetSourceStartEnd(docs, lines, columns, out pRetVal); + ProcessOutParameter(docs); + return pRetVal; + } + + public static void GetSequencePoints(this ISymUnmanagedMethod instance, uint cPoints, out uint pcPoints, uint[] offsets, ISymUnmanagedDocument[] documents, uint[] lines, uint[] columns, uint[] endLines, uint[] endColumns) + { + instance.__GetSequencePoints(cPoints, out pcPoints, offsets, documents, lines, columns, endLines, endColumns); + ProcessOutParameter(documents); + } + + public static void GetName(this ISymUnmanagedNamespace instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetName(cchName, out pcchName, szName); + } + + public static void GetNamespaces(this ISymUnmanagedNamespace instance, uint cNameSpaces, out uint pcNameSpaces, IntPtr namespaces) + { + instance.__GetNamespaces(cNameSpaces, out pcNameSpaces, namespaces); + } + + public static void GetVariables(this ISymUnmanagedNamespace instance, uint cVars, out uint pcVars, IntPtr pVars) + { + instance.__GetVariables(cVars, out pcVars, pVars); + } + + public static ISymUnmanagedDocument GetDocument(this ISymUnmanagedReader instance, IntPtr url, Guid language, Guid languageVendor, Guid documentType) + { + ISymUnmanagedDocument returnValue = instance.__GetDocument(url, language, languageVendor, documentType); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void GetDocuments(this ISymUnmanagedReader instance, uint cDocs, out uint pcDocs, ISymUnmanagedDocument[] pDocs) + { + instance.__GetDocuments(cDocs, out pcDocs, pDocs); + ProcessOutParameter(pDocs); + } + + public static uint GetUserEntryPoint(this ISymUnmanagedReader instance) + { + return instance.__GetUserEntryPoint(); + } + + public static ISymUnmanagedMethod GetMethod(this ISymUnmanagedReader instance, uint token) + { + ISymUnmanagedMethod returnValue = instance.__GetMethod(token); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static ISymUnmanagedMethod GetMethodByVersion(this ISymUnmanagedReader instance, uint token, int version) + { + ISymUnmanagedMethod returnValue = instance.__GetMethodByVersion(token, version); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void GetVariables(this ISymUnmanagedReader instance, uint parent, uint cVars, out uint pcVars, IntPtr pVars) + { + instance.__GetVariables(parent, cVars, out pcVars, pVars); + } + + public static void GetGlobalVariables(this ISymUnmanagedReader instance, uint cVars, out uint pcVars, IntPtr pVars) + { + instance.__GetGlobalVariables(cVars, out pcVars, pVars); + } + + public static ISymUnmanagedMethod GetMethodFromDocumentPosition(this ISymUnmanagedReader instance, ISymUnmanagedDocument document, uint line, uint column) + { + ISymUnmanagedMethod returnValue = instance.__GetMethodFromDocumentPosition(document, line, column); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void GetSymAttribute(this ISymUnmanagedReader instance, uint parent, IntPtr name, uint cBuffer, out uint pcBuffer, IntPtr buffer) + { + instance.__GetSymAttribute(parent, name, cBuffer, out pcBuffer, buffer); + } + + public static void GetNamespaces(this ISymUnmanagedReader instance, uint cNameSpaces, out uint pcNameSpaces, ISymUnmanagedNamespace[] namespaces) + { + instance.__GetNamespaces(cNameSpaces, out pcNameSpaces, namespaces); + ProcessOutParameter(namespaces); + } + + public static void Initialize(this ISymUnmanagedReader instance, object importer, IntPtr filename, IntPtr searchPath, IStream pIStream) + { + instance.__Initialize(importer, filename, searchPath, pIStream); + } + + public static void UpdateSymbolStore(this ISymUnmanagedReader instance, IntPtr filename, IStream pIStream) + { + instance.__UpdateSymbolStore(filename, pIStream); + } + + public static void ReplaceSymbolStore(this ISymUnmanagedReader instance, IntPtr filename, IStream pIStream) + { + instance.__ReplaceSymbolStore(filename, pIStream); + } + + public static void GetSymbolStoreFileName(this ISymUnmanagedReader instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetSymbolStoreFileName(cchName, out pcchName, szName); + } + + public static void GetMethodsFromDocumentPosition(this ISymUnmanagedReader instance, ISymUnmanagedDocument document, uint line, uint column, uint cMethod, out uint pcMethod, IntPtr pRetVal) + { + instance.__GetMethodsFromDocumentPosition(document, line, column, cMethod, out pcMethod, pRetVal); + } + + public static void GetDocumentVersion(this ISymUnmanagedReader instance, ISymUnmanagedDocument pDoc, out int version, out int pbCurrent) + { + instance.__GetDocumentVersion(pDoc, out version, out pbCurrent); + } + + public static int GetMethodVersion(this ISymUnmanagedReader instance, ISymUnmanagedMethod pMethod) + { + int version; + instance.__GetMethodVersion(pMethod, out version); + return version; + } + + public static uint GetSymbolSearchInfoCount(this ISymUnmanagedReaderSymbolSearchInfo instance) + { + uint pcSearchInfo; + instance.__GetSymbolSearchInfoCount(out pcSearchInfo); + return pcSearchInfo; + } + + public static void GetSymbolSearchInfo(this ISymUnmanagedReaderSymbolSearchInfo instance, uint cSearchInfo, out uint pcSearchInfo, out ISymUnmanagedSymbolSearchInfo rgpSearchInfo) + { + instance.__GetSymbolSearchInfo(cSearchInfo, out pcSearchInfo, out rgpSearchInfo); + ProcessOutParameter(rgpSearchInfo); + } + + public static ISymUnmanagedMethod GetMethod(this ISymUnmanagedScope instance) + { + ISymUnmanagedMethod returnValue = instance.__GetMethod(); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static ISymUnmanagedScope GetParent(this ISymUnmanagedScope instance) + { + ISymUnmanagedScope returnValue = instance.__GetParent(); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void GetChildren(this ISymUnmanagedScope instance, uint cChildren, out uint pcChildren, ISymUnmanagedScope[] children) + { + instance.__GetChildren(cChildren, out pcChildren, children); + ProcessOutParameter(children); + } + + public static uint GetStartOffset(this ISymUnmanagedScope instance) + { + return instance.__GetStartOffset(); + } + + public static uint GetEndOffset(this ISymUnmanagedScope instance) + { + return instance.__GetEndOffset(); + } + + public static uint GetLocalCount(this ISymUnmanagedScope instance) + { + return instance.__GetLocalCount(); + } + + public static void GetLocals(this ISymUnmanagedScope instance, uint cLocals, out uint pcLocals, ISymUnmanagedVariable[] locals) + { + instance.__GetLocals(cLocals, out pcLocals, locals); + ProcessOutParameter(locals); + } + + public static void GetNamespaces(this ISymUnmanagedScope instance, uint cNameSpaces, out uint pcNameSpaces, ISymUnmanagedNamespace[] namespaces) + { + instance.__GetNamespaces(cNameSpaces, out pcNameSpaces, namespaces); + ProcessOutParameter(namespaces); + } + + public static uint GetSearchPathLength(this ISymUnmanagedSymbolSearchInfo instance) + { + uint pcchPath; + instance.__GetSearchPathLength(out pcchPath); + return pcchPath; + } + + public static void GetSearchPath(this ISymUnmanagedSymbolSearchInfo instance, uint cchPath, out uint pcchPath, IntPtr szPath) + { + instance.__GetSearchPath(cchPath, out pcchPath, szPath); + } + + public static int GetHRESULT(this ISymUnmanagedSymbolSearchInfo instance) + { + int phr; + instance.__GetHRESULT(out phr); + return phr; + } + + public static void GetName(this ISymUnmanagedVariable instance, uint cchName, out uint pcchName, IntPtr szName) + { + instance.__GetName(cchName, out pcchName, szName); + } + + public static uint GetAttributes(this ISymUnmanagedVariable instance) + { + return instance.__GetAttributes(); + } + + public static void GetSignature(this ISymUnmanagedVariable instance, uint cSig, out uint pcSig, IntPtr sig) + { + instance.__GetSignature(cSig, out pcSig, sig); + } + + public static uint GetAddressKind(this ISymUnmanagedVariable instance) + { + return instance.__GetAddressKind(); + } + + public static uint GetAddressField1(this ISymUnmanagedVariable instance) + { + return instance.__GetAddressField1(); + } + + public static uint GetAddressField2(this ISymUnmanagedVariable instance) + { + return instance.__GetAddressField2(); + } + + public static uint GetAddressField3(this ISymUnmanagedVariable instance) + { + return instance.__GetAddressField3(); + } + + public static uint GetStartOffset(this ISymUnmanagedVariable instance) + { + return instance.__GetStartOffset(); + } + + public static uint GetEndOffset(this ISymUnmanagedVariable instance) + { + return instance.__GetEndOffset(); + } + + public static ISymUnmanagedDocumentWriter DefineDocument(this ISymUnmanagedWriter instance, IntPtr url, ref Guid language, ref Guid languageVendor, ref Guid documentType) + { + ISymUnmanagedDocumentWriter returnValue = instance.__DefineDocument(url, ref language, ref languageVendor, ref documentType); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void SetUserEntryPoint(this ISymUnmanagedWriter instance, uint entryMethod) + { + instance.__SetUserEntryPoint(entryMethod); + } + + public static void OpenMethod(this ISymUnmanagedWriter instance, uint method) + { + instance.__OpenMethod(method); + } + + public static void CloseMethod(this ISymUnmanagedWriter instance) + { + instance.__CloseMethod(); + } + + public static uint OpenScope(this ISymUnmanagedWriter instance, uint startOffset) + { + return instance.__OpenScope(startOffset); + } + + public static void CloseScope(this ISymUnmanagedWriter instance, uint endOffset) + { + instance.__CloseScope(endOffset); + } + + public static void SetScopeRange(this ISymUnmanagedWriter instance, uint scopeID, uint startOffset, uint endOffset) + { + instance.__SetScopeRange(scopeID, startOffset, endOffset); + } + + public static void DefineLocalVariable(this ISymUnmanagedWriter instance, IntPtr name, uint attributes, uint cSig, ref byte signature, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, + uint endOffset) + { + instance.__DefineLocalVariable(name, attributes, cSig, ref signature, addrKind, addr1, addr2, addr3, startOffset, endOffset); + ProcessOutParameter(signature); + } + + public static void DefineParameter(this ISymUnmanagedWriter instance, IntPtr name, uint attributes, uint sequence, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineParameter(name, attributes, sequence, addrKind, addr1, addr2, addr3); + } + + public static void DefineField(this ISymUnmanagedWriter instance, uint parent, IntPtr name, uint attributes, uint cSig, ref byte signature, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineField(parent, name, attributes, cSig, ref signature, addrKind, addr1, addr2, addr3); + ProcessOutParameter(signature); + } + + public static void DefineGlobalVariable(this ISymUnmanagedWriter instance, IntPtr name, uint attributes, uint cSig, ref byte signature, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineGlobalVariable(name, attributes, cSig, ref signature, addrKind, addr1, addr2, addr3); + ProcessOutParameter(signature); + } + + public static void Close(this ISymUnmanagedWriter instance) + { + instance.__Close(); + } + + public static void SetSymAttribute(this ISymUnmanagedWriter instance, uint parent, IntPtr name, uint cData, ref byte data) + { + instance.__SetSymAttribute(parent, name, cData, ref data); + ProcessOutParameter(data); + } + + public static void OpenNamespace(this ISymUnmanagedWriter instance, IntPtr name) + { + instance.__OpenNamespace(name); + } + + public static void CloseNamespace(this ISymUnmanagedWriter instance) + { + instance.__CloseNamespace(); + } + + public static void UsingNamespace(this ISymUnmanagedWriter instance, IntPtr fullName) + { + instance.__UsingNamespace(fullName); + } + + public static void SetMethodSourceRange(this ISymUnmanagedWriter instance, ISymUnmanagedDocumentWriter startDoc, uint startLine, uint startColumn, ISymUnmanagedDocumentWriter endDoc, uint endLine, uint endColumn) + { + instance.__SetMethodSourceRange(startDoc, startLine, startColumn, endDoc, endLine, endColumn); + } + + public static void Initialize(this ISymUnmanagedWriter instance, object emitter, IntPtr filename, IStream pIStream, int fFullBuild) + { + instance.__Initialize(emitter, filename, pIStream, fFullBuild); + } + + public static void GetDebugInfo(this ISymUnmanagedWriter instance, ref uint pIDD, uint cData, out uint pcData, IntPtr data) + { + instance.__GetDebugInfo(ref pIDD, cData, out pcData, data); + } + + public static void DefineSequencePoints(this ISymUnmanagedWriter instance, ISymUnmanagedDocumentWriter document, uint spCount, ref uint offsets, ref uint lines, ref uint columns, ref uint endLines, ref uint endColumns) + { + instance.__DefineSequencePoints(document, spCount, ref offsets, ref lines, ref columns, ref endLines, ref endColumns); + } + + public static void RemapToken(this ISymUnmanagedWriter instance, uint oldToken, uint newToken) + { + instance.__RemapToken(oldToken, newToken); + } + + public static void Initialize2(this ISymUnmanagedWriter instance, object emitter, IntPtr tempfilename, IStream pIStream, int fFullBuild, IntPtr finalfilename) + { + instance.__Initialize2(emitter, tempfilename, pIStream, fFullBuild, finalfilename); + } + + public static void DefineConstant(this ISymUnmanagedWriter instance, IntPtr name, object value, uint cSig, ref byte signature) + { + instance.__DefineConstant(name, value, cSig, ref signature); + ProcessOutParameter(signature); + } + + public static void Abort(this ISymUnmanagedWriter instance) + { + instance.__Abort(); + } + + public static ISymUnmanagedDocumentWriter DefineDocument(this ISymUnmanagedWriter2 instance, IntPtr url, ref Guid language, ref Guid languageVendor, ref Guid documentType) + { + ISymUnmanagedDocumentWriter returnValue = instance.__DefineDocument(url, ref language, ref languageVendor, ref documentType); + ProcessOutParameter(returnValue); + return returnValue; + } + + public static void SetUserEntryPoint(this ISymUnmanagedWriter2 instance, uint entryMethod) + { + instance.__SetUserEntryPoint(entryMethod); + } + + public static void OpenMethod(this ISymUnmanagedWriter2 instance, uint method) + { + instance.__OpenMethod(method); + } + + public static void CloseMethod(this ISymUnmanagedWriter2 instance) + { + instance.__CloseMethod(); + } + + public static uint OpenScope(this ISymUnmanagedWriter2 instance, uint startOffset) + { + return instance.__OpenScope(startOffset); + } + + public static void CloseScope(this ISymUnmanagedWriter2 instance, uint endOffset) + { + instance.__CloseScope(endOffset); + } + + public static void SetScopeRange(this ISymUnmanagedWriter2 instance, uint scopeID, uint startOffset, uint endOffset) + { + instance.__SetScopeRange(scopeID, startOffset, endOffset); + } + + public static void DefineLocalVariable(this ISymUnmanagedWriter2 instance, IntPtr name, uint attributes, uint cSig, ref byte signature, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, + uint endOffset) + { + instance.__DefineLocalVariable(name, attributes, cSig, ref signature, addrKind, addr1, addr2, addr3, startOffset, endOffset); + ProcessOutParameter(signature); + } + + public static void DefineParameter(this ISymUnmanagedWriter2 instance, IntPtr name, uint attributes, uint sequence, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineParameter(name, attributes, sequence, addrKind, addr1, addr2, addr3); + } + + public static void DefineField(this ISymUnmanagedWriter2 instance, uint parent, IntPtr name, uint attributes, uint cSig, ref byte signature, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineField(parent, name, attributes, cSig, ref signature, addrKind, addr1, addr2, addr3); + ProcessOutParameter(signature); + } + + public static void DefineGlobalVariable(this ISymUnmanagedWriter2 instance, IntPtr name, uint attributes, uint cSig, ref byte signature, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineGlobalVariable(name, attributes, cSig, ref signature, addrKind, addr1, addr2, addr3); + ProcessOutParameter(signature); + } + + public static void Close(this ISymUnmanagedWriter2 instance) + { + instance.__Close(); + } + + public static void SetSymAttribute(this ISymUnmanagedWriter2 instance, uint parent, IntPtr name, uint cData, ref byte data) + { + instance.__SetSymAttribute(parent, name, cData, ref data); + ProcessOutParameter(data); + } + + public static void OpenNamespace(this ISymUnmanagedWriter2 instance, IntPtr name) + { + instance.__OpenNamespace(name); + } + + public static void CloseNamespace(this ISymUnmanagedWriter2 instance) + { + instance.__CloseNamespace(); + } + + public static void UsingNamespace(this ISymUnmanagedWriter2 instance, IntPtr fullName) + { + instance.__UsingNamespace(fullName); + } + + public static void SetMethodSourceRange(this ISymUnmanagedWriter2 instance, ISymUnmanagedDocumentWriter startDoc, uint startLine, uint startColumn, ISymUnmanagedDocumentWriter endDoc, uint endLine, uint endColumn) + { + instance.__SetMethodSourceRange(startDoc, startLine, startColumn, endDoc, endLine, endColumn); + } + + public static void Initialize(this ISymUnmanagedWriter2 instance, object emitter, IntPtr filename, IStream pIStream, int fFullBuild) + { + instance.__Initialize(emitter, filename, pIStream, fFullBuild); + } + + public static void GetDebugInfo(this ISymUnmanagedWriter2 instance, ref uint pIDD, uint cData, out uint pcData, IntPtr data) + { + instance.__GetDebugInfo(ref pIDD, cData, out pcData, data); + } + + public static void DefineSequencePoints(this ISymUnmanagedWriter2 instance, ISymUnmanagedDocumentWriter document, uint spCount, ref uint offsets, ref uint lines, ref uint columns, ref uint endLines, ref uint endColumns) + { + instance.__DefineSequencePoints(document, spCount, ref offsets, ref lines, ref columns, ref endLines, ref endColumns); + } + + public static void RemapToken(this ISymUnmanagedWriter2 instance, uint oldToken, uint newToken) + { + instance.__RemapToken(oldToken, newToken); + } + + public static void Initialize2(this ISymUnmanagedWriter2 instance, object emitter, IntPtr tempfilename, IStream pIStream, int fFullBuild, IntPtr finalfilename) + { + instance.__Initialize2(emitter, tempfilename, pIStream, fFullBuild, finalfilename); + } + + public static void DefineConstant(this ISymUnmanagedWriter2 instance, IntPtr name, object value, uint cSig, ref byte signature) + { + instance.__DefineConstant(name, value, cSig, ref signature); + ProcessOutParameter(signature); + } + + public static void Abort(this ISymUnmanagedWriter2 instance) + { + instance.__Abort(); + } + + public static void DefineLocalVariable2(this ISymUnmanagedWriter2 instance, IntPtr name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset) + { + instance.__DefineLocalVariable2(name, attributes, sigToken, addrKind, addr1, addr2, addr3, startOffset, endOffset); + } + + public static void DefineGlobalVariable2(this ISymUnmanagedWriter2 instance, IntPtr name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3) + { + instance.__DefineGlobalVariable2(name, attributes, sigToken, addrKind, addr1, addr2, addr3); + } + + public static void DefineConstant2(this ISymUnmanagedWriter2 instance, IntPtr name, object value, uint sigToken) + { + instance.__DefineConstant2(name, value, sigToken); + } + + } +} diff --git a/Debugger/Debugger.Core/Interop/MTA2STA.cs b/Debugger/Debugger.Core/Interop/MTA2STA.cs new file mode 100644 index 000000000..5d08d7a52 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/MTA2STA.cs @@ -0,0 +1,252 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; +using System.Windows.Forms; + +namespace Debugger +{ + public delegate T MethodInvokerWithReturnValue(); + + public enum CallMethod {DirectCall, Manual, HiddenForm, HiddenFormWithTimeout}; + + public class MTA2STA + { + Form hiddenForm; + IntPtr hiddenFormHandle; + + System.Threading.Thread targetThread; + CallMethod callMethod = CallMethod.HiddenFormWithTimeout; + + Queue pendingCalls = new Queue(); + ManualResetEvent pendingCallsNotEmpty = new ManualResetEvent(false); + + WaitHandle EnqueueCall(MethodInvoker callDelegate) + { + lock (pendingCalls) { + ManualResetEvent callDone = new ManualResetEvent(false); + pendingCalls.Enqueue(delegate{ + callDelegate(); + callDone.Set(); + }); + pendingCallsNotEmpty.Set(); + return callDone; + } + } + + /// + /// Wait until a call a made + /// + public void WaitForCall() + { + pendingCallsNotEmpty.WaitOne(); + } + + public void WaitForCall(TimeSpan timeout) + { + pendingCallsNotEmpty.WaitOne(timeout, false); + } + + /// + /// Performs all waiting calls on the current thread + /// + public void PerformAllCalls() + { + while (true) { + if (!PerformCall()) { + return; + } + } + } + + /// + /// Performs all waiting calls on the current thread + /// + /// + /// Private - user should always drain the queue - otherwise Prcoess.RaisePausedEvents might fail + /// + bool PerformCall() + { + MethodInvoker nextMethod; + lock (pendingCalls) { + if (pendingCalls.Count > 0) { + nextMethod = pendingCalls.Dequeue(); + } else { + pendingCallsNotEmpty.Reset(); + return false; + } + } + nextMethod(); + return true; + } + + public CallMethod CallMethod { + get { + return callMethod; + } + set { + callMethod = value; + } + } + + public MTA2STA() + { + targetThread = System.Threading.Thread.CurrentThread; + + hiddenForm = new Form(); + // Force handle creation + hiddenFormHandle = hiddenForm.Handle; + } + + /// + /// SoftWait waits for any of the given WaitHandles and allows processing of calls during the wait + /// + public int SoftWait(params WaitHandle[] waitFor) + { + List waits = new List (waitFor); + waits.Add(pendingCallsNotEmpty); + while(true) { + int i = WaitHandle.WaitAny(waits.ToArray()); + PerformAllCalls(); + if (i < waits.Count - 1) { // If not pendingCallsNotEmpty + return i; + } + } + } + + /// + /// Schedules invocation of method and returns immediately + /// + public WaitHandle AsyncCall(MethodInvoker callDelegate) + { + WaitHandle callDone = EnqueueCall(callDelegate); + TriggerInvoke(); + return callDone; + } + + public T Call(MethodInvokerWithReturnValue callDelegate) + { + T returnValue = default(T); + Call(delegate { returnValue = callDelegate(); }, true); + return returnValue; + } + + public void Call(MethodInvoker callDelegate) + { + Call(callDelegate, false); + } + + void Call(MethodInvoker callDelegate, bool hasReturnValue) + { + // Enqueue the call + WaitHandle callDone = EnqueueCall(callDelegate); + + if (targetThread == System.Threading.Thread.CurrentThread) { + PerformAllCalls(); + return; + } + + // We have the call waiting in queue, we need to call it (not waiting for it to finish) + TriggerInvoke(); + + // Wait for the call to finish + if (!hasReturnValue && callMethod == CallMethod.HiddenFormWithTimeout) { + // Give it 5 seconds to run + if (!callDone.WaitOne(5000, true)) { + System.Console.WriteLine("Call time out! (continuing)"); + System.Console.WriteLine(new System.Diagnostics.StackTrace(true).ToString()); + } + } else { + callDone.WaitOne(); + } + } + + void TriggerInvoke() + { + switch (callMethod) { + case CallMethod.DirectCall: + PerformAllCalls(); + break; + case CallMethod.Manual: + // Nothing we can do - someone else must call SoftWait or Pulse + break; + case CallMethod.HiddenForm: + case CallMethod.HiddenFormWithTimeout: + hiddenForm.BeginInvoke((MethodInvoker)PerformAllCalls); + break; + } + } + + public static object MarshalParamTo(object param, Type outputType) + { + if (param is IntPtr) { + return MarshalIntPtrTo((IntPtr)param, outputType); + } else { + return param; + } + } + + public static T MarshalIntPtrTo(IntPtr param) + { + return (T)MarshalIntPtrTo(param, typeof(T)); + } + + public static object MarshalIntPtrTo(IntPtr param, Type outputType) + { + // IntPtr requested as output (must be before the null check so that we pass IntPtr.Zero) + if (outputType == typeof(IntPtr)) { + return param; + } + // The parameter is null pointer + if ((IntPtr)param == IntPtr.Zero) { + return null; + } + // String requested as output + if (outputType == typeof(string)) { + return Marshal.PtrToStringAuto((IntPtr)param); + } + // Marshal a COM object + object comObject = Marshal.GetObjectForIUnknown(param); + Debugger.Interop.TrackedComObjects.Track(comObject); + return comObject; + } + + /// + /// Uses reflection to call method. Automaticaly marshals parameters. + /// + /// Targed object which contains the method. In case of static mehod pass the Type + /// The name of the function to call + /// Parameters which should be send to the function. Parameters will be marshaled to proper type. + /// Return value of the called function + public static object InvokeMethod(object targetObject, string functionName, object[] functionParameters) + { + System.Reflection.MethodInfo method; + if (targetObject is Type) { + method = ((Type)targetObject).GetMethod(functionName); + } else { + method = targetObject.GetType().GetMethod(functionName); + } + + ParameterInfo[] methodParamsInfo = method.GetParameters(); + object[] convertedParams = new object[methodParamsInfo.Length]; + + for (int i = 0; i < convertedParams.Length; i++) { + convertedParams[i] = MarshalParamTo(functionParameters[i], methodParamsInfo[i].ParameterType); + } + + try { + if (targetObject is Type) { + return method.Invoke(null, convertedParams); + } else { + return method.Invoke(targetObject, convertedParams); + } + } catch (System.Exception exception) { + throw new Debugger.DebuggerException("Invoke of " + functionName + " failed.", exception); + } + } + } +} diff --git a/Debugger/Debugger.Core/Interop/MetaData.cs b/Debugger/Debugger.Core/Interop/MetaData.cs new file mode 100644 index 000000000..f424b99f5 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/MetaData.cs @@ -0,0 +1,278 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +#pragma warning disable 108, 1591 + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Debugger.Interop.MetaData +{ + [StructLayout(LayoutKind.Sequential, Pack=4)] + public struct COR_FIELD_OFFSET + { + public uint ridOfField; + public uint ulOffset; + } + [System.Flags()] + public enum ClassFieldAttribute: uint + { + // member access mask - Use this mask to retrieve accessibility information. + fdFieldAccessMask = 0x0007, + fdPrivateScope = 0x0000, // Member not referenceable. + fdPrivate = 0x0001, // Accessible only by the parent type. + fdFamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly. + fdAssembly = 0x0003, // Accessibly by anyone in the Assembly. + fdFamily = 0x0004, // Accessible only by type and sub-types. + fdFamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly. + fdPublic = 0x0006, // Accessibly by anyone who has visibility to this scope. + // end member access mask + + // field contract attributes. + fdStatic = 0x0010, // Defined on type, else per instance. + fdInitOnly = 0x0020, // Field may only be initialized, not written to after init. + fdLiteral = 0x0040, // Value is compile time constant. + fdNotSerialized = 0x0080, // Field does not have to be serialized when type is remoted. + + fdSpecialName = 0x0200, // field is special. Name describes how. + + // interop attributes + fdPinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke. + + // Reserved flags for runtime use only. + fdReservedMask = 0x9500, + fdRTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding. + fdHasFieldMarshal = 0x1000, // Field has marshalling information. + fdHasDefault = 0x8000, // Field has default. + fdHasFieldRVA = 0x0100, // Field has RVA. + } + public enum CorCallingConvention: uint + { + IMAGE_CEE_CS_CALLCONV_DEFAULT = 0x0, + + IMAGE_CEE_CS_CALLCONV_VARARG = 0x5, + IMAGE_CEE_CS_CALLCONV_FIELD = 0x6, + IMAGE_CEE_CS_CALLCONV_LOCAL_SIG = 0x7, + IMAGE_CEE_CS_CALLCONV_PROPERTY = 0x8, + IMAGE_CEE_CS_CALLCONV_UNMGD = 0x9, + IMAGE_CEE_CS_CALLCONV_MAX = 0x10, // first invalid calling convention + + + // The high bits of the calling convention convey additional info + IMAGE_CEE_CS_CALLCONV_MASK = 0x0f, // Calling convention is bottom 4 bits + IMAGE_CEE_CS_CALLCONV_HASTHIS = 0x20, // Top bit indicates a 'this' parameter + IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS = 0x40, // This parameter is explicitly in the signature + } + public enum CorMethodAttr: uint + { + // member access mask - Use this mask to retrieve accessibility information. + mdMemberAccessMask = 0x0007, + mdPrivateScope = 0x0000, // Member not referenceable. + mdPrivate = 0x0001, // Accessible only by the parent type. + mdFamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly. + mdAssem = 0x0003, // Accessibly by anyone in the Assembly. + mdFamily = 0x0004, // Accessible only by type and sub-types. + mdFamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly. + mdPublic = 0x0006, // Accessibly by anyone who has visibility to this scope. + // end member access mask + + // method contract attributes. + mdStatic = 0x0010, // Defined on type, else per instance. + mdFinal = 0x0020, // Method may not be overridden. + mdVirtual = 0x0040, // Method virtual. + mdHideBySig = 0x0080, // Method hides by name+sig, else just by name. + + // vtable layout mask - Use this mask to retrieve vtable attributes. + mdVtableLayoutMask = 0x0100, + mdReuseSlot = 0x0000, // The default. + mdNewSlot = 0x0100, // Method always gets a new slot in the vtable. + // end vtable layout mask + + // method implementation attributes. + mdCheckAccessOnOverride = 0x0200, // Overridability is the same as the visibility. + mdAbstract = 0x0400, // Method does not provide an implementation. + mdSpecialName = 0x0800, // Method is special. Name describes how. + + // interop attributes + mdPinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke. + mdUnmanagedExport = 0x0008, // Managed method exported via thunk to unmanaged code. + + // Reserved flags for runtime use only. + mdReservedMask = 0xd000, + mdRTSpecialName = 0x1000, // Runtime should check name encoding. + mdHasSecurity = 0x4000, // Method has security associate with it. + mdRequireSecObject = 0x8000, // Method calls another method containing security code. + + } + public enum CorTokenType: uint + { + Module = 0x00000000, // + TypeRef = 0x01000000, // + TypeDef = 0x02000000, // + FieldDef = 0x04000000, // + MethodDef = 0x06000000, // + ParamDef = 0x08000000, // + InterfaceImpl = 0x09000000, // + MemberRef = 0x0a000000, // + CustomAttribute = 0x0c000000, // + Permission = 0x0e000000, // + Signature = 0x11000000, // + Event = 0x14000000, // + Property = 0x17000000, // + ModuleRef = 0x1a000000, // + TypeSpec = 0x1b000000, // + Assembly = 0x20000000, // + AssemblyRef = 0x23000000, // + File = 0x26000000, // + ExportedType = 0x27000000, // + ManifestResource = 0x28000000, // + + String = 0x70000000, // + Name = 0x71000000, // + BaseType = 0x72000000, // Leave this on the high end value. This does not correspond to metadata table + } + + [ComImport, InterfaceType((short) 1), Guid("7DAC8207-D3AE-4C75-9B67-92801A497D44"), ComConversionLoss] + public interface IMetaDataImport + { + [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void CloseEnum(IntPtr hEnum); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void CountEnum(IntPtr hEnum, out uint pulCount); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void ResetEnum(IntPtr hEnum, uint ulPos); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumTypeDefs(ref IntPtr phEnum, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rTypeDefs, uint cMax, out uint pcTypeDefs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumInterfaceImpls(ref IntPtr phEnum, uint td, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rImpls, uint cMax, out uint pcImpls); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumTypeRefs(ref IntPtr phEnum, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rTypeRefs, uint cMax, out uint pcTypeRefs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void FindTypeDefByName([In, MarshalAs(UnmanagedType.LPWStr)] string szTypeDef, uint tkEnclosingClass, out uint ptd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetScopeProps(IntPtr szName, uint cchName, out uint pchName, out Guid pmvid); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetModuleFromScope(out uint pmd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetTypeDefProps(uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, out uint pdwTypeDefFlags, out uint ptkExtends); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetInterfaceImplProps(uint iiImpl, out uint pClass, out uint ptkIface); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetTypeRefProps(uint tr, out uint ptkResolutionScope, IntPtr szName, uint cchName, out uint pchName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void ResolveTypeRef(uint tr, [In] ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppIScope, out uint ptd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumMembers(ref IntPtr phEnum, uint cl, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rMembers, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumMembersWithName(ref IntPtr phEnum, uint cl, [In, MarshalAs(UnmanagedType.LPWStr)] string szName, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rMembers, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumMethods(ref IntPtr phEnum, uint cl, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rMethods, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumMethodsWithName(ref IntPtr phEnum, uint cl, [In, MarshalAs(UnmanagedType.LPWStr)] string szName, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rMethods, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumFields(ref IntPtr phEnum, uint cl, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rFields, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumFieldsWithName(ref IntPtr phEnum, uint cl, [In, MarshalAs(UnmanagedType.LPWStr)] string szName, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rFields, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumParams(ref IntPtr phEnum, uint mb, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rParams, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumMemberRefs(ref IntPtr phEnum, uint tkParent, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rMemberRefs, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumMethodImpls(ref IntPtr phEnum, uint td, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rMethodBody, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rMethodDecl, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumPermissionSets(ref IntPtr phEnum, uint tk, uint dwActions, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rPermission, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void FindMember(uint td, [In, MarshalAs(UnmanagedType.LPWStr)] string szName, [In] IntPtr pvSigBlob, uint cbSigBlob, out uint pmb); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void FindMethod(uint td, [In, MarshalAs(UnmanagedType.LPWStr)] string szName, [In] IntPtr pvSigBlob, uint cbSigBlob, out uint pmb); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void FindField(uint td, [In, MarshalAs(UnmanagedType.LPWStr)] string szName, [In] IntPtr pvSigBlob, uint cbSigBlob, out uint pmb); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void FindMemberRef(uint td, [In, MarshalAs(UnmanagedType.LPWStr)] string szName, [In] IntPtr pvSigBlob, uint cbSigBlob, out uint pmr); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetMethodProps(uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetMemberRefProps(uint mr, out uint ptk, IntPtr szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob, out uint pbSig); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumProperties(ref IntPtr phEnum, uint td, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rProperties, uint cMax, out uint pcProperties); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumEvents(ref IntPtr phEnum, uint td, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rEvents, uint cMax, out uint pcEvents); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetEventProps(uint ev, out uint pClass, IntPtr szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumMethodSemantics(ref IntPtr phEnum, uint mb, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rEventProp, uint cMax, out uint pcEventProp); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetMethodSemantics(uint mb, uint tkEventProp, out uint pdwSemanticsFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetClassLayout(uint td, out uint pdwPackSize, [Out] COR_FIELD_OFFSET[] rFieldOffset, uint cMax, out uint pcFieldOffset, out uint pulClassSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetFieldMarshal(uint tk, out IntPtr ppvNativeType, out uint pcbNativeType); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetRVA(uint tk, out uint pulCodeRVA, out uint pdwImplFlags); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetPermissionSetProps(uint pm, out uint pdwAction, out IntPtr ppvPermission, out uint pcbPermission); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetSigFromToken(uint mdSig, out IntPtr ppvSig, out uint pcbSig); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetModuleRefProps(uint mur, IntPtr szName, uint cchName, out uint pchName); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumModuleRefs(ref IntPtr phEnum, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rModuleRefs, uint cMax, out uint pcModuleRefs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetTypeSpecFromToken(uint typespec, out IntPtr ppvSig, out uint pcbSig); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetNameFromToken(uint tk, IntPtr pszUtf8NamePtr); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumUnresolvedMethods(ref IntPtr phEnum, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rMethods, uint cMax, out uint pcTokens); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetUserString(uint stk, IntPtr szString, uint cchString, out uint pchString); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetPinvokeMap(uint tk, out uint pdwMappingFlags, IntPtr szImportName, uint cchImportName, out uint pchImportName, out uint pmrImportDLL); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumSignatures(ref IntPtr phEnum, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rSignatures, uint cMax, out uint pcSignatures); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumTypeSpecs(ref IntPtr phEnum, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rTypeSpecs, uint cMax, out uint pcTypeSpecs); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumUserStrings(ref IntPtr phEnum, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rStrings, uint cMax, out uint pcStrings); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetParamForMethodIndex(uint md, uint ulParamSeq, out uint ppd); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumCustomAttributes(ref IntPtr phEnum, uint tk, uint tkType, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rCustomAttributes, uint cMax, out uint pcCustomAttributes); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob, out uint pcbSize); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void FindTypeRef(uint tkResolutionScope, [In, MarshalAs(UnmanagedType.LPWStr)] string szName, out uint ptr); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetMemberProps(uint mb, out uint pClass, IntPtr szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetFieldProps(uint mb, out uint pClass, [In] IntPtr szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetPropertyProps(uint prop, out uint pClass, IntPtr szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rmdOtherMethod, uint cMax, out uint pcOtherMethod); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetParamProps(uint tk, out uint pmd, out uint pulSequence, IntPtr szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue, out uint pcchValue); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetCustomAttributeByName(uint tkObj, [In, MarshalAs(UnmanagedType.LPWStr)] string szName, out IntPtr ppData, out uint pcbData); + [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + int IsValidToken(uint tk); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetNestedClassProps(uint tdNestedClass, out uint ptdEnclosingClass); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void GetNativeCallConvFromSig([In] IntPtr pvSig, uint cbSig, out uint pCallConv); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void IsGlobal(uint pd, out int pbGlobal); + + // IMetaDataImport2 + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] + void EnumGenericParams(ref IntPtr hEnum, uint tk, [Out, MarshalAsAttribute(UnmanagedType.LPArray)] uint[] rGenericParams, uint cMax, out uint pcGenericParams); + void GetGenericParamProps(); + void GetMethodSpecProps(); + void EnumGenericParamConstraints(); + void GetGenericParamConstraintProps(); + void GetPEKind(); + void GetVersionString(); + void EnumMethodSpecs(); + } +} + +#pragma warning restore 108, 1591 diff --git a/Debugger/Debugger.Core/Interop/MetaDataWrapper.cs b/Debugger/Debugger.Core/Interop/MetaDataWrapper.cs new file mode 100644 index 000000000..2cd57e6ca --- /dev/null +++ b/Debugger/Debugger.Core/Interop/MetaDataWrapper.cs @@ -0,0 +1,1122 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +// Missing XML comment for publicly visible type or member +#pragma warning disable 1591 + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +using Debugger.Interop.MetaData; +using Debugger.Interop.CorDebug; +using Debugger.Interop.CorSym; + +namespace Debugger.Interop.MetaData +{ + /// Wrapper for the unmanaged metadata API. + /// http://msdn.microsoft.com/en-us/library/ms230172.aspx + public class MetaDataImport + { + const int DefaultBufferSize = 8; + // If buffer is too small, enlarge it + const int BufferSizeMultiplier = 4; + + IMetaDataImport metaData; + + public MetaDataImport(ICorDebugModule pModule) + { + Guid guid = new Guid("{ 0x7dac8207, 0xd3ae, 0x4c75, { 0x9b, 0x67, 0x92, 0x80, 0x1a, 0x49, 0x7d, 0x44 } }"); + metaData = (IMetaDataImport)pModule.GetMetaDataInterface(ref guid); + TrackedComObjects.Track(metaData); + } + + public ISymUnmanagedReader GetSymReader(string fullname, string searchPath) + { + try { + ISymUnmanagedBinder symBinder = new Debugger.Interop.CorSym.CorSymBinder_SxSClass(); + TrackedComObjects.Track(symBinder); + return symBinder.GetReaderForFile(metaData, fullname, searchPath); + } catch (COMException) { + return null; + } + } + + public ISymUnmanagedReader GetSymReader(IStream stream) + { + try { + ISymUnmanagedBinder symBinder = new Debugger.Interop.CorSym.CorSymBinder_SxSClass(); + TrackedComObjects.Track(symBinder); + return symBinder.GetReaderFromStream(metaData, stream); + } catch (COMException) { + return null; + } + } + + // CloseEnum, CountEnum and ResetEnum are not wrapped, use them directly + // GetNameFromToken is obsolete + + public uint[] EnumCustomAttributes(uint token_Scope, uint token_TypeOfAttributes) + { + return EnumerateTokens(metaData.EnumCustomAttributes, token_Scope, token_TypeOfAttributes); + } + + public IEnumerable EnumCustomAttributeProps(uint token_Scope, uint token_TypeOfAttributes) + { + foreach(uint token in EnumerateTokens(metaData.EnumCustomAttributes, token_Scope, token_TypeOfAttributes)) { + yield return GetCustomAttributeProps(token); + } + } + + public uint[] EnumEvents(uint typeDef) + { + return EnumerateTokens(metaData.EnumEvents, typeDef); + } + + public IEnumerable EnumEventProps(uint typeDef) + { + foreach(uint token in EnumerateTokens(metaData.EnumEvents, typeDef)) { + yield return GetEventProps(token); + } + } + + public uint[] EnumFields(uint typeDef) + { + return EnumerateTokens(metaData.EnumFields, typeDef); + } + + public IEnumerable EnumFieldProps(uint typeDef) + { + foreach(uint token in EnumerateTokens(metaData.EnumFields, typeDef)) { + yield return GetFieldProps(token); + } + } + + public uint[] EnumFieldsWithName(uint typeDef, string name) + { + return EnumerateTokens(metaData.EnumFieldsWithName, typeDef, name); + } + + public IEnumerable EnumFieldPropsWithName(uint typeDef, string name) + { + foreach(uint token in EnumerateTokens(metaData.EnumFieldsWithName, typeDef, name)) { + yield return GetFieldProps(token); + } + } + + public uint[] EnumGenericParams(uint typeDef_methodDef) + { + return EnumerateTokens(metaData.EnumGenericParams, typeDef_methodDef); + } + + /// MethodDef tokens + public uint[] EnumInterfaceImpls(uint typeDef) + { + return EnumerateTokens(metaData.EnumInterfaceImpls, typeDef); + } + + public IEnumerable EnumInterfaceImplProps(uint typeDef) + { + foreach(uint token in EnumerateTokens(metaData.EnumInterfaceImpls, typeDef)) { + yield return GetInterfaceImplProps(token); + } + } + + public uint[] EnumMemberRefs(uint typeDef_typeRef_methodDef_moduleRef) + { + return EnumerateTokens(metaData.EnumMemberRefs, typeDef_typeRef_methodDef_moduleRef); + } + + public IEnumerable EnumMemberRefProps(uint typeDef_typeRef_methodDef_moduleRef) + { + foreach(uint token in EnumerateTokens(metaData.EnumMemberRefs, typeDef_typeRef_methodDef_moduleRef)) { + yield return GetMemberRefProps(token); + } + } + + public uint[] EnumMembers(uint typeDef) + { + return EnumerateTokens(metaData.EnumMembers, typeDef); + } + + public IEnumerable EnumMemberProps(uint typeDef) + { + foreach(uint token in EnumerateTokens(metaData.EnumMembers, typeDef)) { + yield return GetMemberProps(token); + } + } + + public uint[] EnumMembersWithName(uint typeDef, string name) + { + return EnumerateTokens(metaData.EnumMembersWithName, typeDef, name); + } + + public IEnumerable EnumMemberPropsWithName(uint typeDef, string name) + { + foreach(uint token in EnumerateTokens(metaData.EnumMembersWithName, typeDef, name)) { + yield return GetMemberProps(token); + } + } + + /// MethodBody and MethodDeclaration tokens + public IEnumerable EnumMethodImpls(uint typeDef) + { + IntPtr enumerator = IntPtr.Zero; + while(true) { + MethodImpl ret = new MethodImpl(); + uint[] body = new uint[1]; + uint[] decl = new uint[1]; + uint fetched; + metaData.EnumMethodImpls(ref enumerator, typeDef, body, decl, 1, out fetched); + if (fetched == 0) + break; + ret.MethodBody = body[0]; + ret.MethodDecl = decl[0]; + yield return ret; + } + metaData.CloseEnum(enumerator); + } + + public uint[] EnumMethods(uint typeDef) + { + return EnumerateTokens(metaData.EnumMethods, typeDef); + } + + public IEnumerable EnumMethodProps(uint typeDef) + { + foreach(uint token in EnumerateTokens(metaData.EnumMethods, typeDef)) { + yield return GetMethodProps(token); + } + } + + /// Events or properties + public uint[] EnumMethodSemantics(uint methodDef) + { + return EnumerateTokens(metaData.EnumMethodSemantics, methodDef); + } + + public uint[] EnumMethodsWithName(uint typeDef, string name) + { + return EnumerateTokens(metaData.EnumMethodsWithName, typeDef, name); + } + + public IEnumerable EnumMethodPropsWithName(uint typeDef, string name) + { + foreach(uint token in EnumerateTokens(metaData.EnumMethodsWithName, typeDef, name)) { + yield return GetMethodProps(token); + } + } + + public uint[] EnumModuleRefs() + { + return EnumerateTokens(metaData.EnumModuleRefs); + } + + public IEnumerable EnumModuleRefProps() + { + foreach(uint token in EnumerateTokens(metaData.EnumModuleRefs)) { + yield return GetModuleRefProps(token); + } + } + + public uint[] EnumParams(uint methodDef) + { + return EnumerateTokens(metaData.EnumParams, methodDef); + } + + public IEnumerable EnumParamProps(uint methodDef) + { + foreach(uint token in EnumerateTokens(metaData.EnumParams, methodDef)) { + yield return GetParamProps(token); + } + } + + public uint[] EnumPermissionSets(uint token_scope_nullable, uint actions) + { + return EnumerateTokens(metaData.EnumPermissionSets, token_scope_nullable, actions); + } + + public IEnumerable EnumPermissionSetProps(uint token_scope_nullable, uint actions) + { + foreach(uint token in EnumerateTokens(metaData.EnumPermissionSets, token_scope_nullable, actions)) { + yield return GetPermissionSetProps(token); + } + } + + public uint[] EnumProperties(uint typeDef) + { + return EnumerateTokens(metaData.EnumProperties, typeDef); + } + + public IEnumerable EnumPropertyProps(uint typeDef) + { + foreach(uint token in EnumerateTokens(metaData.EnumProperties, typeDef)) { + yield return GetPropertyProps(token); + } + } + + public uint[] EnumSignatures() + { + return EnumerateTokens(metaData.EnumSignatures); + } + + public uint[] EnumTypeDefs() + { + return EnumerateTokens(metaData.EnumTypeDefs); + } + + public IEnumerable EnumTypeDefProps() + { + foreach(uint token in EnumerateTokens(metaData.EnumTypeDefs)) { + yield return GetTypeDefProps(token); + } + } + + public uint[] EnumTypeRefs() + { + return EnumerateTokens(metaData.EnumTypeRefs); + } + + public IEnumerable EnumTypeRefProps() + { + foreach(uint token in EnumerateTokens(metaData.EnumTypeRefs)) { + yield return GetTypeRefProps(token); + } + } + + public uint[] EnumTypeSpecs() + { + return EnumerateTokens(metaData.EnumTypeSpecs); + } + + public IEnumerable EnumTypeSpecBlobs() + { + foreach(uint token in EnumerateTokens(metaData.EnumTypeSpecs)) { + yield return GetTypeSpecFromToken(token); + } + } + + public uint[] EnumUnresolvedMethods() + { + return EnumerateTokens(metaData.EnumUnresolvedMethods); + } + + public uint[] EnumUserStrings() + { + return EnumerateTokens(metaData.EnumUserStrings); + } + + public IEnumerable EnumUserStringProps() + { + foreach(uint token in EnumerateTokens(metaData.EnumUserStrings)) { + yield return GetUserString(token); + } + } + + public uint FindField(uint typeDef_nullable, string name, Blob sigBlob) + { + sigBlob = sigBlob ?? Blob.Empty; + uint fieldDef; + metaData.FindField(typeDef_nullable, name, sigBlob.Adress, sigBlob.Size, out fieldDef); + return fieldDef; + } + + public FieldProps FindFieldProps(uint typeDef_nullable, string name, Blob sigBlob) + { + return GetFieldProps(FindField(typeDef_nullable, name, sigBlob)); + } + + public uint FindMember(uint typeDef_nullable, string name, Blob sigBlob) + { + sigBlob = sigBlob ?? Blob.Empty; + uint memberDef; + metaData.FindMember(typeDef_nullable, name, sigBlob.Adress, sigBlob.Size, out memberDef); + return memberDef; + } + + public MemberProps FindMemberProps(uint typeDef_nullable, string name, Blob sigBlob) + { + return GetMemberProps(FindMember(typeDef_nullable, name, sigBlob)); + } + + public uint FindMemberRef(uint typeRef_nullable, string name, Blob sigBlob) + { + sigBlob = sigBlob ?? Blob.Empty; + uint memberRef; + metaData.FindMemberRef(typeRef_nullable, name, sigBlob.Adress, sigBlob.Size, out memberRef); + return memberRef; + } + + public MemberRefProps FindMemberRefProps(uint typeRef_nullable, string name, Blob sigBlob) + { + return GetMemberRefProps(FindMemberRef(typeRef_nullable, name, sigBlob)); + } + + public uint FindMethod(uint typeDef_nullable, string name, Blob sigBlob) + { + sigBlob = sigBlob ?? Blob.Empty; + uint methodDef; + metaData.FindMethod(typeDef_nullable, name, sigBlob.Adress, sigBlob.Size, out methodDef); + return methodDef; + } + + public MethodProps FindMethodProps(uint typeDef_nullable, string name, Blob sigBlob) + { + return GetMethodProps(FindMethod(typeDef_nullable, name, sigBlob)); + } + + public uint FindTypeDefByName(string name, uint typeDef_typeRef_enclosingClass_nullable) + { + uint typeDef; + metaData.FindTypeDefByName(name, typeDef_typeRef_enclosingClass_nullable, out typeDef); + return typeDef; + } + + public TypeDefProps FindTypeDefPropsByName(string name, uint typeDef_typeRef_enclosingClass_nullable) + { + return GetTypeDefProps(FindTypeDefByName(name, typeDef_typeRef_enclosingClass_nullable)); + } + + public uint FindTypeRef(uint moduleRef_assemblyRef_typeRef_scope, string name) + { + uint typeRef; + metaData.FindTypeRef(moduleRef_assemblyRef_typeRef_scope, name, out typeRef); + return typeRef; + } + + public TypeRefProps FindTypeRefProps(uint moduleRef_assemblyRef_typeRef_scope, string name) + { + return GetTypeRefProps(FindTypeRef(moduleRef_assemblyRef_typeRef_scope, name)); + } + + public ClassLayout GetClassLayout(uint typeDef) + { + ClassLayout ret = new ClassLayout(); + ret.TypeDef = typeDef; + ret.FieldOffsets = new COR_FIELD_OFFSET[DefaultBufferSize]; + uint returned; + while (true) { + metaData.GetClassLayout( + ret.TypeDef, + out ret.PackSize, + ret.FieldOffsets, (uint)ret.FieldOffsets.Length, out returned, + out ret.ClassSize + ); + if (returned < ret.FieldOffsets.Length) break; + ret.FieldOffsets = new COR_FIELD_OFFSET[ret.FieldOffsets.Length * BufferSizeMultiplier]; + } + Array.Resize(ref ret.FieldOffsets, (int)returned); + return ret; + } + + public Blob GetCustomAttributeByName(uint token_owner, string name) + { + IntPtr blobPtr; + uint blobSize; + metaData.GetCustomAttributeByName( + token_owner, + name, + out blobPtr, + out blobSize + ); + return new Blob(blobPtr, blobSize); + } + + public CustomAttributeProps GetCustomAttributeProps(uint token) + { + IntPtr blobPtr; + uint blobSize; + CustomAttributeProps ret = new CustomAttributeProps(); + ret.Token = token; + metaData.GetCustomAttributeProps( + ret.Token, + out ret.Owner, + out ret.Type, + out blobPtr, + out blobSize + ); + ret.Data = new Blob(blobPtr, blobSize); + return ret; + } + + public EventProps GetEventProps(uint eventToken) + { + EventProps ret = new EventProps(); + ret.Event = eventToken; + ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + ret.OtherMethods = new uint[DefaultBufferSize]; + uint returned; + while(true) { + metaData.GetEventProps( + ret.Event, + out ret.DeclaringClass, + pString, pStringLenght, out stringLenght, + out ret.Flags, + out ret.EventType, + out ret.AddMethod, + out ret.RemoveMethod, + out ret.FireMethod, + ret.OtherMethods, (uint)ret.OtherMethods.Length, out returned + ); + if (returned < ret.OtherMethods.Length) break; + ret.OtherMethods = new uint[ret.OtherMethods.Length * BufferSizeMultiplier]; + } + Array.Resize(ref ret.OtherMethods, (int)returned); + }); + return ret; + } + + public Blob GetFieldMarshal(uint token) + { + IntPtr blobPtr; + uint blobSize; + metaData.GetFieldMarshal( + token, + out blobPtr, + out blobSize + ); + return new Blob(blobPtr, blobSize); + } + + public FieldProps GetFieldProps(uint fieldDef) + { + FieldProps ret = new FieldProps(); + IntPtr sigPtr = IntPtr.Zero; + uint sigSize = 0; + ret.Token = fieldDef; + ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetFieldProps( + ret.Token, + out ret.DeclaringClass, + pString, pStringLenght, out stringLenght, + out ret.Flags, + out sigPtr, + out sigSize, + out ret.ConstantType, + out ret.ConstantPtr, + out ret.ConstantStringLength + ); + }); + ret.SigBlob = new Blob(sigPtr, sigSize); + return ret; + } + + public InterfaceImplProps GetInterfaceImplProps(uint method) + { + InterfaceImplProps ret = new InterfaceImplProps(); + ret.Method = method; + metaData.GetInterfaceImplProps( + ret.Method, + out ret.Class, + out ret.Interface + ); + return ret; + } + + public MemberProps GetMemberProps(uint token) + { + MemberProps ret = new MemberProps(); + IntPtr sigPtr = IntPtr.Zero; + uint sigSize = 0; + ret.Token = token; + ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetMemberProps( + ret.Token, + out ret.Class, + pString, pStringLenght, out stringLenght, + out ret.Flags, + out sigPtr, + out sigSize, + out ret.RVA, + out ret.ImplFlags, + out ret.ConstantType, + out ret.ConstantPtr, + out ret.ConstantStringLength + ); + }); + ret.SigBlob = new Blob(sigPtr, sigSize); + return ret; + } + + public MemberRefProps GetMemberRefProps(uint token) + { + MemberRefProps ret = new MemberRefProps(); + IntPtr sigPtr = IntPtr.Zero; + uint sigSize = 0; + ret.Token = token; + ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetMemberRefProps( + token, + out ret.DeclaringType, + pString, pStringLenght, out stringLenght, + out sigPtr, + out sigSize + ); + }); + ret.SigBlob = new Blob(sigPtr, sigSize); + return ret; + } + + public MethodProps GetMethodProps(uint methodToken) + { + MethodProps ret = new MethodProps(); + IntPtr sigPtr = IntPtr.Zero; + uint sigSize = 0; + ret.Token = methodToken; + ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetMethodProps( + ret.Token, + out ret.ClassToken, + pString, pStringLenght, out stringLenght, + out ret.Flags, + out sigPtr, + out sigSize, + out ret.CodeRVA, + out ret.ImplFlags + ); + }); + ret.SigBlob = new Blob(sigPtr, sigSize); + return ret; + } + + public uint GetMethodSemantics(uint methodDef, uint event_property) + { + uint semFlags; + metaData.GetMethodSemantics(methodDef, event_property, out semFlags); + return semFlags; + } + + public uint GetModuleFromScope() + { + uint module; + metaData.GetModuleFromScope(out module); + return module; + } + + public ModuleRefProps GetModuleRefProps(uint token) + { + ModuleRefProps ret = new ModuleRefProps(); + ret.Token = token; + ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetModuleRefProps( + token, + pString, pStringLenght, out stringLenght + ); + }); + return ret; + } + + public uint GetNativeCallConvFromSig(Blob sigBlob) + { + uint callConv; + metaData.GetNativeCallConvFromSig(sigBlob.Adress, sigBlob.Size, out callConv); + return callConv; + } + + public NestedClassProps GetNestedClassProps(uint nestedClass) + { + NestedClassProps ret = new NestedClassProps(); + ret.NestedClass = nestedClass; + metaData.GetNestedClassProps( + ret.NestedClass, + out ret.EnclosingClass + ); + return ret; + } + + public uint GetParamForMethodIndex(uint methodToken, uint parameterSequence) + { + uint paramToken; + metaData.GetParamForMethodIndex(methodToken, parameterSequence, out paramToken); + return paramToken; + } + + public ParamProps GetParamPropsForMethodIndex(uint methodToken, uint parameterSequence) + { + return GetParamProps(GetParamForMethodIndex(methodToken, parameterSequence)); + } + + public ParamProps GetParamProps(uint paramToken) + { + ParamProps ret = new ParamProps(); + ret.ParamDef = paramToken; + ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetParamProps( + ret.ParamDef, + out ret.MethodDef, + out ret.Sequence, + pString, pStringLenght, out stringLenght, + out ret.Flags, + out ret.ConstantType, + out ret.ConstantPtr, + out ret.ConstantStringLength + ); + }); + return ret; + } + + public PermissionSetProps GetPermissionSetProps(uint permToken) + { + PermissionSetProps ret = new PermissionSetProps(); + IntPtr permPtr; + uint permSize; + ret.PermToken = permToken; + metaData.GetPermissionSetProps( + ret.PermToken, + out ret.Action, + out permPtr, + out permSize + ); + ret.SigBlob = new Blob(permPtr, permSize); + return ret; + } + + public PinvokeMap GetPinvokeMap(uint fieldDef_methodDef) + { + PinvokeMap ret = new PinvokeMap(); + ret.Token = fieldDef_methodDef; + ret.ImportName = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetPinvokeMap( + ret.Token, + out ret.Flags, + pString, pStringLenght, out stringLenght, + out ret.ModuleRef + ); + }); + return ret; + } + + public PropertyProps GetPropertyProps(uint prop) + { + PropertyProps ret = new PropertyProps(); + IntPtr sigPtr = IntPtr.Zero; + uint sigSize = 0; + ret.Propery = prop; + ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + ret.OtherMethods = new uint[DefaultBufferSize]; + uint returned; + while(true) { + metaData.GetPropertyProps( + ret.Propery, + out ret.DeclaringClass, + pString, pStringLenght, out stringLenght, + out ret.Flags, + out sigPtr, + out sigSize, + out ret.DefaultValueType, + out ret.DefaultValuePtr, + out ret.DefaultValueStringLength, + out ret.SetterMethod, + out ret.GetterMethod, + ret.OtherMethods, (uint)ret.OtherMethods.Length, out returned + ); + if (returned < ret.OtherMethods.Length) break; + ret.OtherMethods = new uint[ret.OtherMethods.Length * BufferSizeMultiplier]; + } + Array.Resize(ref ret.OtherMethods, (int)returned); + }); + ret.SigBlob = new Blob(sigPtr, sigSize); + return ret; + } + + public RVA GetRVA(uint methodDef_fieldDef) + { + RVA ret = new RVA(); + ret.Token = methodDef_fieldDef; + metaData.GetRVA( + ret.Token, + out ret.CodeRVA, + out ret.ImplFlags + ); + return ret; + } + + public ScopeProps GetScopeProps() + { + ScopeProps ret = new ScopeProps(); + ret.Name = Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetScopeProps( + pString, pStringLenght, out stringLenght, + out ret.Guid + ); + }); + return ret; + } + + public Blob GetSigFromToken(uint token) + { + IntPtr sigPtr; + uint sigSize; + metaData.GetSigFromToken( + token, + out sigPtr, + out sigSize + ); + return new Blob(sigPtr, sigSize); + } + + public TypeDefProps GetTypeDefProps(uint typeDef) + { + TypeDefProps ret = new TypeDefProps(); + ret.Token = typeDef; + ret.Name = + Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetTypeDefProps( + ret.Token, + pString, pStringLenght, out stringLenght, + out ret.Flags, + out ret.SuperClassToken + ); + }); + + return ret; + } + + public TypeRefProps GetTypeRefProps(uint typeRef) + { + TypeRefProps ret = new TypeRefProps(); + ret.TypeRef = typeRef; + ret.Name = + Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetTypeRefProps( + ret.TypeRef, + out ret.ResolutionScope, + pString, pStringLenght, out stringLenght + ); + }); + + return ret; + } + + public Blob GetTypeSpecFromToken(uint typeSpec) + { + IntPtr sigPtr; + uint sigSize; + metaData.GetTypeSpecFromToken( + typeSpec, + out sigPtr, + out sigSize + ); + return new Blob(sigPtr, sigSize); + } + + public string GetUserString(uint stringToken) + { + return Util.GetString(delegate(uint pStringLenght, out uint stringLenght, System.IntPtr pString) { + metaData.GetUserString( + stringToken, + pString, pStringLenght, out stringLenght + ); + }); + } + + public bool IsGlobal(uint token) + { + int isGlobal; + metaData.IsGlobal(token, out isGlobal); + return isGlobal != 0; + } + + public bool IsValidToken(uint token) + { + return metaData.IsValidToken(token) != 0; + } + + public ResolvedTypeRef ResolveTypeRef(uint typeRef, Guid riid) + { + ResolvedTypeRef res = new ResolvedTypeRef(); + metaData.ResolveTypeRef( + typeRef, + ref riid, + out res.Scope, + out res.TypeDef + ); + return res; + } + + #region Util + + delegate void TokenEnumerator0(ref IntPtr phEnum, uint[] token, uint maxCount, out uint fetched); + + uint[] EnumerateTokens(TokenEnumerator0 tokenEnumerator) + { + IntPtr enumerator = IntPtr.Zero; + uint[] buffer = new uint[DefaultBufferSize]; + uint fetched; + tokenEnumerator(ref enumerator, buffer, (uint)buffer.Length, out fetched); + if (fetched < buffer.Length) { + // The tokens did fit the buffer + Array.Resize(ref buffer, (int)fetched); + } else { + // The tokens did not fit the buffer -> Refetch + uint actualCount; + metaData.CountEnum(enumerator, out actualCount); + if (actualCount > buffer.Length) { + buffer = new uint[actualCount]; + metaData.ResetEnum(enumerator, 0); + tokenEnumerator(ref enumerator, buffer, (uint)buffer.Length, out fetched); + } + } + metaData.CloseEnum(enumerator); + return buffer; + } + + delegate void TokenEnumerator1(ref IntPtr phEnum, T parameter, uint[] token, uint maxCount, out uint fetched); + + uint[] EnumerateTokens(TokenEnumerator1 tokenEnumerator, T parameter) + { + IntPtr enumerator = IntPtr.Zero; + uint[] buffer = new uint[DefaultBufferSize]; + uint fetched; + tokenEnumerator(ref enumerator, parameter, buffer, (uint)buffer.Length, out fetched); + if (fetched < buffer.Length) { + // The tokens did fit the buffer + Array.Resize(ref buffer, (int)fetched); + } else { + // The tokens did not fit the buffer -> Refetch + uint actualCount; + metaData.CountEnum(enumerator, out actualCount); + if (actualCount > buffer.Length) { + buffer = new uint[actualCount]; + metaData.ResetEnum(enumerator, 0); + tokenEnumerator(ref enumerator, parameter, buffer, (uint)buffer.Length, out fetched); + } + } + metaData.CloseEnum(enumerator); + return buffer; + } + + delegate void TokenEnumerator2(ref IntPtr phEnum, T parameter1, R parameter2, uint[] token, uint maxCount, out uint fetched); + + uint[] EnumerateTokens(TokenEnumerator2 tokenEnumerator, T parameter1, R parameter2) + { + IntPtr enumerator = IntPtr.Zero; + uint[] buffer = new uint[DefaultBufferSize]; + uint fetched; + tokenEnumerator(ref enumerator, parameter1, parameter2, buffer, (uint)buffer.Length, out fetched); + if (fetched < buffer.Length) { + // The tokens did fit the buffer + Array.Resize(ref buffer, (int)fetched); + } else { + // The tokens did not fit the buffer -> Refetch + uint actualCount; + metaData.CountEnum(enumerator, out actualCount); + if (actualCount > buffer.Length) { + buffer = new uint[actualCount]; + metaData.ResetEnum(enumerator, 0); + tokenEnumerator(ref enumerator, parameter1, parameter2, buffer, (uint)buffer.Length, out fetched); + } + } + metaData.CloseEnum(enumerator); + return buffer; + } + + #endregion + } + + public class Blob + { + public static readonly Blob Empty = new Blob(IntPtr.Zero, 0); + + IntPtr adress; + uint size; + + public IntPtr Adress { + get { return adress; } + } + + public uint Size { + get { return size; } + } + + public Blob(IntPtr adress, uint size) + { + this.adress = adress; + this.size = size; + } + + public byte[] GetData() + { + byte[] data = new byte[size]; + Marshal.Copy(adress, data, 0, (int)size); + return data; + } + } + + public class ClassLayout + { + public uint TypeDef; + public uint PackSize; + public COR_FIELD_OFFSET[] FieldOffsets; + public uint ClassSize; + } + + public class CustomAttributeProps + { + public uint Token; + public uint Owner; + public uint Type; + public Blob Data; + } + + public class EventProps + { + public uint Event; + public uint DeclaringClass; + public string Name; + public uint Flags; + public uint EventType; + public uint AddMethod; + public uint RemoveMethod; + public uint FireMethod; + public uint[] OtherMethods; + } + + public class FieldProps + { + public uint Token; + public string Name; + public uint DeclaringClass; + public uint Flags; + public Blob SigBlob; + public uint ConstantType; + public IntPtr ConstantPtr; + public uint ConstantStringLength; + } + + public class InterfaceImplProps + { + public uint Method; + public uint Class; + public uint Interface; + } + + public class MemberProps + { + public uint Token; + public uint Class; + public string Name; + public uint Flags; + public Blob SigBlob; + public uint RVA; + public uint ImplFlags; + public uint ConstantType; + public IntPtr ConstantPtr; + public uint ConstantStringLength; + } + + public class MemberRefProps + { + public uint Token; + public uint DeclaringType; + public string Name; + public Blob SigBlob; + } + + public class MethodImpl + { + public uint MethodBody; + public uint MethodDecl; + } + + public class MethodProps + { + public uint Token; + public string Name; + public uint ClassToken; + public uint Flags; + public Blob SigBlob; + public uint CodeRVA; + public uint ImplFlags; + } + + public class ModuleRefProps + { + public uint Token; + public string Name; + } + + public class NestedClassProps + { + public uint NestedClass; + public uint EnclosingClass; + } + + public class ParamProps + { + public uint ParamDef; + public uint MethodDef; + public uint Sequence; + public string Name; + public uint Flags; + public uint ConstantType; + public IntPtr ConstantPtr; + public uint ConstantStringLength; + } + + public class PermissionSetProps + { + public uint PermToken; + public uint Action; + public Blob SigBlob; + } + + public class PinvokeMap + { + public uint Token; + public uint Flags; + public string ImportName; + public uint ModuleRef; + } + + public class PropertyProps + { + public uint Propery; + public uint DeclaringClass; + public string Name; + public uint Flags; + public Blob SigBlob; + public uint DefaultValueType; + public IntPtr DefaultValuePtr; + public uint DefaultValueStringLength; + public uint SetterMethod; + public uint GetterMethod; + public uint[] OtherMethods; + } + + public class ResolvedTypeRef + { + public object Scope; + public uint TypeDef; + } + + public class RVA + { + public uint Token; + public uint CodeRVA; + public uint ImplFlags; + } + + public class ScopeProps + { + public string Name; + public Guid Guid; + } + + public class TypeDefProps + { + public uint Token; + public string Name; + public uint Flags; + public uint SuperClassToken; + } + + public class TypeRefProps + { + public uint TypeRef; + public uint ResolutionScope; + public string Name; + } +} + +#pragma warning restore 1591 diff --git a/Debugger/Debugger.Core/Interop/NativeMethods.cs b/Debugger/Debugger.Core/Interop/NativeMethods.cs new file mode 100644 index 000000000..0a541f1e6 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/NativeMethods.cs @@ -0,0 +1,28 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +#pragma warning disable 1591 + +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Debugger.Interop +{ + public static class NativeMethods + { + [DllImport("kernel32.dll")] + public static extern bool CloseHandle(IntPtr handle); + + [DllImport("mscoree.dll", CharSet=CharSet.Unicode, PreserveSig=false)] + public static extern Debugger.Interop.CorDebug.ICorDebug CreateDebuggingInterfaceFromVersion(int debuggerVersion, string debuggeeVersion); + + [DllImport("mscoree.dll", CharSet=CharSet.Unicode)] + public static extern int GetCORVersion([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName, Int32 cchBuffer, out Int32 dwLength); + + [DllImport("mscoree.dll", CharSet=CharSet.Unicode)] + public static extern int GetRequestedRuntimeVersion(string exeFilename, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pVersion, Int32 cchBuffer, out Int32 dwLength); + } +} + +#pragma warning restore 1591 diff --git a/Debugger/Debugger.Core/Interop/TrackedComObjects.cs b/Debugger/Debugger.Core/Interop/TrackedComObjects.cs new file mode 100644 index 000000000..0508d54b3 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/TrackedComObjects.cs @@ -0,0 +1,57 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +#pragma warning disable 1591 + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace Debugger.Interop +{ + public static class TrackedComObjects + { + static List objects = new List(); + + public static void ProcessOutParameter(object parameter) + { + if (parameter != null) { + if (Marshal.IsComObject(parameter)) { + Track(parameter); + } else if (parameter is Array) { + foreach(object elem in (Array)parameter) { + ProcessOutParameter(elem); + } + } + } + } + + public static void Track(object obj) + { + if (Marshal.IsComObject(obj)) { + lock(objects) { + objects.Add(new WeakReference(obj)); + } + } + } + + public static int ReleaseAll() + { + lock(objects) { + int count = 0; + foreach(WeakReference weakRef in objects) { + object obj = weakRef.Target; + if (obj != null) { + Marshal.FinalReleaseComObject(obj); + count++; + } + } + objects.Clear(); + objects.TrimExcess(); + return count; + } + } + } +} + +#pragma warning restore 1591 diff --git a/Debugger/Debugger.Core/Interop/Util.cs b/Debugger/Debugger.Core/Interop/Util.cs new file mode 100644 index 000000000..bcf764c76 --- /dev/null +++ b/Debugger/Debugger.Core/Interop/Util.cs @@ -0,0 +1,68 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +#pragma warning disable 1591 + +using System; +using System.Runtime.InteropServices; + +namespace Debugger.Interop +{ + public delegate void UnmanagedStringGetter(uint pStringLength, out uint stringLength, System.IntPtr pString); + + public static class Util + { + const uint DefaultBufferSize = 16; + + public static unsafe string GetCorSymString(UnmanagedStringGetter getter) + { + // CorSym does not support truncated result - it thorws exception and does not set actualLength (even with preserve sig) + // ICorDebugStringValue does not support 0 as buffer size + + uint actualLength; + getter(0, out actualLength, IntPtr.Zero); + char[] buffer = new char[(int)actualLength]; + string managedString; + fixed(char* pBuffer = buffer) { + getter(actualLength, out actualLength, new IntPtr(pBuffer)); + managedString = Marshal.PtrToStringUni(new IntPtr(pBuffer), (int)actualLength); + } + managedString = managedString.TrimEnd('\0'); + return managedString; + } + + public static string GetString(UnmanagedStringGetter getter) + { + return GetString(getter, DefaultBufferSize, true); + } + + public static unsafe string GetString(UnmanagedStringGetter getter, uint defaultBufferSize, bool trimNull) + { + string managedString; + + // DebugStringValue does not like buffer size of 0 + defaultBufferSize = Math.Max(defaultBufferSize, 1); + + char[] buffer = new char[(int)defaultBufferSize]; + fixed(char* pBuffer = buffer) { + uint actualLength = 0; + getter(defaultBufferSize, out actualLength, new IntPtr(pBuffer)); + + if(actualLength > defaultBufferSize) { + char[] buffer2 = new char[(int)actualLength]; + fixed(char* pBuffer2 = buffer2) { + getter(actualLength, out actualLength, new IntPtr(pBuffer2)); + managedString = Marshal.PtrToStringUni(new IntPtr(pBuffer2), (int)actualLength); + } + } else { + managedString = Marshal.PtrToStringUni(new IntPtr(pBuffer), (int)actualLength); + } + } + if (trimNull) + managedString = managedString.TrimEnd('\0'); + return managedString; + } + } +} + +#pragma warning restore 1591 diff --git a/Debugger/Debugger.Core/ManagedCallback.cs b/Debugger/Debugger.Core/ManagedCallback.cs new file mode 100644 index 000000000..5a0b7d92a --- /dev/null +++ b/Debugger/Debugger.Core/ManagedCallback.cs @@ -0,0 +1,552 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Runtime.InteropServices; +using Debugger.Interop; +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + /// + /// Handles all callbacks of a given process + /// + /// + /// Note that there can be a queued callback after almost any callback. + /// In particular: + /// - After 'break' there may be more callbacks + /// - After EvalComplete there may be more callbacks (eg CreateThread from other thread) + /// + class ManagedCallback + { + Process process; + bool pauseOnNextExit; + bool isInCallback = false; + + [Debugger.Tests.Ignore] + public Process Process { + get { return process; } + } + + public bool IsInCallback { + get { return isInCallback; } + } + + public ManagedCallback(Process process) + { + this.process = process; + } + + void EnterCallback(PausedReason pausedReason, string name, ICorDebugProcess pProcess) + { + isInCallback = true; + + process.TraceMessage("Callback: " + name); + System.Diagnostics.Debug.Assert(process.CorProcess == pProcess); + + // After break is pressed we may receive some messages that were already queued + if (process.IsPaused && process.PauseSession.PausedReason == PausedReason.ForcedBreak) { + // TODO: This does not work well if exception if being processed and the user continues it + process.TraceMessage("Processing post-break callback"); + // This compensates for the break call and we are in normal callback handling mode + process.AsyncContinue(DebuggeeStateAction.Keep, new Thread[] {}, null); + // Start of call back - create new pause session (as usual) + process.NotifyPaused(pausedReason); + // Make sure we stay pause after the callback is handled + pauseOnNextExit = true; + return; + } + + if (process.IsRunning) { + process.NotifyPaused(pausedReason); + return; + } + + throw new DebuggerException("Invalid state at the start of callback"); + } + + void EnterCallback(PausedReason pausedReason, string name, ICorDebugAppDomain pAppDomain) + { + EnterCallback(pausedReason, name, pAppDomain.GetProcess()); + } + + void EnterCallback(PausedReason pausedReason, string name, ICorDebugThread pThread) + { + EnterCallback(pausedReason, name, pThread.GetProcess()); + process.SelectedThread = process.Threads[pThread]; + } + + void ExitCallback() + { + bool hasQueuedCallbacks = process.CorProcess.HasQueuedCallbacks(); + if (hasQueuedCallbacks) + process.TraceMessage("Process has queued callbacks"); + + if (hasQueuedCallbacks) { + // Exception has Exception2 queued after it + process.AsyncContinue(DebuggeeStateAction.Keep, null, null); + } else if (process.Evaluating) { + // Ignore events during property evaluation + process.AsyncContinue(DebuggeeStateAction.Keep, null, null); + } else if (pauseOnNextExit) { + if (process.Options.Verbose) + process.TraceMessage("Callback exit: Paused"); + pauseOnNextExit = false; + Pause(); + } else { + process.AsyncContinue(DebuggeeStateAction.Keep, null, null); + } + + isInCallback = false; + } + + void Pause() + { + if (process.PauseSession.PausedReason == PausedReason.EvalComplete || + process.PauseSession.PausedReason == PausedReason.ExceptionIntercepted) { + // TODO: There might be qued callback after EvalComplete making this unrealiable + process.DisableAllSteppers(); + process.CheckSelectedStackFrames(); + // Do not set selected stack frame + // Do not raise events + } else { + // Raise the pause event outside the callback + // Warning: Make sure that process in not resumed in the meantime + process.Debugger.MTA2STA.AsyncCall(process.RaisePausedEvents); + + // The event might probably get called out of order when the process is running again + } + } + + + #region Program folow control + + public void StepComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugStepper pStepper, CorDebugStepReason reason) + { + EnterCallback(PausedReason.StepComplete, "StepComplete (" + reason.ToString() + ")", pThread); + + Thread thread = process.Threads[pThread]; + Stepper stepper = process.GetStepper(pStepper); + + StackFrame currentStackFrame = process.SelectedThread.MostRecentStackFrame; + process.TraceMessage(" - stopped at {0} because of {1}", currentStackFrame.MethodInfo.FullName, stepper.ToString()); + + process.Steppers.Remove(stepper); + stepper.OnStepComplete(reason); + + if (stepper.Ignore) { + // The stepper is ignored + process.TraceMessage(" - ignored"); + } else if (thread.CurrentStepIn != null && + thread.CurrentStepIn.StackFrame.Equals(currentStackFrame) && + thread.CurrentStepIn.IsInStepRanges((int)currentStackFrame.IP)) { + Stepper.StepIn(currentStackFrame, thread.CurrentStepIn.StepRanges, "finishing step in"); + process.TraceMessage(" - finishing step in"); + } else if (currentStackFrame.MethodInfo.StepOver) { + if (process.Options.EnableJustMyCode) { + currentStackFrame.MethodInfo.MarkAsNonUserCode(); + process.TraceMessage(" - method {0} marked as non user code", currentStackFrame.MethodInfo.FullName); + Stepper.StepIn(currentStackFrame, new int[] {0, int.MaxValue}, "seeking user code"); + process.TraceMessage(" - seeking user code"); + } else { + Stepper.StepOut(currentStackFrame, "stepping out of non-user code"); + process.TraceMessage(" - stepping out of non-user code"); + } + } else { + // User-code method + pauseOnNextExit = true; + process.TraceMessage(" - pausing in user code"); + } + + ExitCallback(); + } + + // Warning! Marshaing of ICorBreakpoint fails in .NET 1.1 + public void Breakpoint(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugBreakpoint corBreakpoint) + { + EnterCallback(PausedReason.Breakpoint, "Breakpoint", pThread); + + Breakpoint breakpoint = process.Debugger.Breakpoints[corBreakpoint]; + // The event will be risen outside the callback + process.BreakpointHitEventQueue.Enqueue(breakpoint); + + pauseOnNextExit = true; + + ExitCallback(); + } + + public void BreakpointSetError(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugBreakpoint pBreakpoint, uint dwError) + { + EnterCallback(PausedReason.Other, "BreakpointSetError", pThread); + + ExitCallback(); + } + + public void Break(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) + { + EnterCallback(PausedReason.Break, "Break", pThread); + + pauseOnNextExit = true; + ExitCallback(); + } + + public void ControlCTrap(ICorDebugProcess pProcess) + { + EnterCallback(PausedReason.ControlCTrap, "ControlCTrap", pProcess); + + pauseOnNextExit = true; + ExitCallback(); + } + + public void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int unhandled) + { + // Exception2 is used in .NET Framework 2.0 + + if (process.DebuggeeVersion.StartsWith("v1.")) { + // Forward the call to Exception2, which handles EnterCallback and ExitCallback + ExceptionType exceptionType = (unhandled != 0) ? ExceptionType.Unhandled : ExceptionType.FirstChance; + Exception2(pAppDomain, pThread, null, 0, (CorDebugExceptionCallbackType)exceptionType, 0); + } else { + // This callback should be ignored in v2 applications + EnterCallback(PausedReason.Other, "Exception", pThread); + + ExitCallback(); + } + } + + #endregion + + #region Various + + public void LogSwitch(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, uint ulReason, string pLogSwitchName, string pParentName) + { + EnterCallback(PausedReason.Other, "LogSwitch", pThread); + + ExitCallback(); + } + + public void LogMessage(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, string pLogSwitchName, string pMessage) + { + EnterCallback(PausedReason.Other, "LogMessage", pThread); + + process.OnLogMessage(new MessageEventArgs(process, lLevel, pMessage, pLogSwitchName)); + + ExitCallback(); + } + + public void EditAndContinueRemap(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction, int fAccurate) + { + EnterCallback(PausedReason.Other, "EditAndContinueRemap", pThread); + + ExitCallback(); + } + + public void EvalException(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval) + { + EnterCallback(PausedReason.EvalComplete, "EvalException", pThread); + + HandleEvalComplete(pAppDomain, pThread, corEval, true); + } + + public void EvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval) + { + EnterCallback(PausedReason.EvalComplete, "EvalComplete", pThread); + + HandleEvalComplete(pAppDomain, pThread, corEval, false); + } + + void HandleEvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval, bool exception) + { + // Let the eval know that the CorEval has finished + Eval eval = process.ActiveEvals[corEval]; + eval.NotifyEvaluationComplete(!exception); + process.ActiveEvals.Remove(eval); + + pauseOnNextExit = true; + ExitCallback(); + } + + public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode) + { + EnterCallback(PausedReason.DebuggerError, "DebuggerError", pProcess); + + string errorText = String.Format("Debugger error: \nHR = 0x{0:X} \nCode = 0x{1:X}", errorHR, errorCode); + + if ((uint)errorHR == 0x80131C30) { + errorText += "\n\nDebugging 64-bit processes is currently not supported.\n" + + "If you are running a 64-bit system, this setting might help:\n" + + "Project -> Project Options -> Compiling -> Target CPU = 32-bit Intel"; + } + + if (Environment.UserInteractive) + System.Windows.Forms.MessageBox.Show(errorText); + else + throw new DebuggerException(errorText); + + try { + pauseOnNextExit = true; + ExitCallback(); + } catch (COMException) { + } catch (InvalidComObjectException) { + // ignore errors during shutdown after debugger error + } + } + + public void UpdateModuleSymbols(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule, IStream pSymbolStream) + { + EnterCallback(PausedReason.Other, "UpdateModuleSymbols", pAppDomain); + + Module module = process.Modules[pModule]; + if (module.CorModule is ICorDebugModule3 && module.IsDynamic) { + // In .NET 4.0, we use the LoadClass callback to load dynamic modules + // because it always works - UpdateModuleSymbols does not. + // - Simple dynamic code generation seems to trigger both callbacks. + // - IronPython for some reason causes just the LoadClass callback + // so we choose to rely on it out of the two. + } else { + // In .NET 2.0, this is the the only method and it works fine + module.LoadSymbolsFromMemory(pSymbolStream); + } + + ExitCallback(); + } + + #endregion + + #region Start of Application + + public void CreateProcess(ICorDebugProcess pProcess) + { + EnterCallback(PausedReason.Other, "CreateProcess", pProcess); + + // Process is added in NDebugger.Start + + ExitCallback(); + } + + public void CreateAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain) + { + EnterCallback(PausedReason.Other, "CreateAppDomain", pAppDomain); + + pAppDomain.Attach(); + process.AppDomains.Add(new AppDomain(process, pAppDomain)); + + ExitCallback(); + } + + public void LoadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly) + { + EnterCallback(PausedReason.Other, "LoadAssembly", pAppDomain); + + ExitCallback(); + } + + public void LoadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule) + { + EnterCallback(PausedReason.Other, "LoadModule " + pModule.GetName(), pAppDomain); + + Module module = new Module(process.AppDomains[pAppDomain], pModule); + process.Modules.Add(module); + + ExitCallback(); + } + + public void NameChange(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) + { + if (pAppDomain != null) { + + EnterCallback(PausedReason.Other, "NameChange: pAppDomain", pAppDomain); + + ExitCallback(); + + } + if (pThread != null) { + + EnterCallback(PausedReason.Other, "NameChange: pThread", pThread); + + Thread thread = process.Threads[pThread]; + thread.NotifyNameChanged(); + + ExitCallback(); + + } + } + + public void CreateThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) + { + // We can not use pThread since it has not been added yet + // and we continue from this callback anyway + EnterCallback(PausedReason.Other, "CreateThread " + pThread.GetID(), pAppDomain); + + Thread thread = new Thread(process, pThread); + process.Threads.Add(thread); + + thread.CorThread.SetDebugState(process.NewThreadState); + + ExitCallback(); + } + + public void LoadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c) + { + EnterCallback(PausedReason.Other, "LoadClass", pAppDomain); + + Module module = process.Modules[c.GetModule()]; + + // Dynamic module has been extended - reload symbols to inlude new class + module.LoadSymbolsDynamic(); + + ExitCallback(); + } + + #endregion + + #region Exit of Application + + public void UnloadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c) + { + EnterCallback(PausedReason.Other, "UnloadClass", pAppDomain); + + ExitCallback(); + } + + public void UnloadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule) + { + EnterCallback(PausedReason.Other, "UnloadModule", pAppDomain); + + process.Modules.Remove(process.Modules[pModule]); + + ExitCallback(); + } + + public void UnloadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly) + { + EnterCallback(PausedReason.Other, "UnloadAssembly", pAppDomain); + + ExitCallback(); + } + + public void ExitThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) + { + // ICorDebugThread is still not dead and can be used for some operations + if (process.Threads.Contains(pThread)) { + EnterCallback(PausedReason.Other, "ExitThread " + pThread.GetID(), pThread); + + process.Threads[pThread].NotifyExited(); + } else { + EnterCallback(PausedReason.Other, "ExitThread " + pThread.GetID(), process.CorProcess); + + // .NET 4.0 - It seems that the API is reporting exits of threads without announcing their creation. + // TODO: Remove in next .NET 4.0 beta and investigate + process.TraceMessage("ERROR: Thread does not exist " + pThread.GetID()); + } + + try { + ExitCallback(); + } catch (COMException e) { + // For some reason this sometimes happens in .NET 1.1 + process.TraceMessage("Continue failed in ExitThread callback: " + e.Message); + } + } + + public void ExitAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain) + { + EnterCallback(PausedReason.Other, "ExitAppDomain", pAppDomain); + + process.AppDomains.Remove(process.AppDomains[pAppDomain]); + + ExitCallback(); + } + + public void ExitProcess(ICorDebugProcess pProcess) + { + // ExitProcess may be called at any time when debuggee is killed + process.TraceMessage("Callback: ExitProcess"); + + process.NotifyHasExited(); + } + + #endregion + + #region ICorDebugManagedCallback2 Members + + public void ChangeConnection(ICorDebugProcess pProcess, uint dwConnectionId) + { + EnterCallback(PausedReason.Other, "ChangeConnection", pProcess); + + ExitCallback(); + } + + public void CreateConnection(ICorDebugProcess pProcess, uint dwConnectionId, IntPtr pConnName) + { + EnterCallback(PausedReason.Other, "CreateConnection", pProcess); + + ExitCallback(); + } + + public void DestroyConnection(ICorDebugProcess pProcess, uint dwConnectionId) + { + EnterCallback(PausedReason.Other, "DestroyConnection", pProcess); + + ExitCallback(); + } + + public void Exception2(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFrame pFrame, uint nOffset, CorDebugExceptionCallbackType exceptionType, uint dwFlags) + { + EnterCallback(PausedReason.Exception, "Exception2 (type=" + exceptionType.ToString() + ")", pThread); + + // This callback is also called from Exception(...)!!!! (the .NET 1.1 version) + // Watch out for the zeros and null! + // Exception -> Exception2(pAppDomain, pThread, null, 0, exceptionType, 0); + + if ((ExceptionType)exceptionType == ExceptionType.Unhandled || process.PauseOnHandledException) { + process.SelectedThread.CurrentException = new Exception(new Value(process.AppDomains[pAppDomain], process.SelectedThread.CorThread.GetCurrentException()).GetPermanentReference()); + process.SelectedThread.CurrentException_DebuggeeState = process.DebuggeeState; + process.SelectedThread.CurrentExceptionType = (ExceptionType)exceptionType; + process.SelectedThread.CurrentExceptionIsUnhandled = (ExceptionType)exceptionType == ExceptionType.Unhandled; + + pauseOnNextExit = true; + } + ExitCallback(); + } + + public void ExceptionUnwind(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags) + { + EnterCallback(PausedReason.ExceptionIntercepted, "ExceptionUnwind", pThread); + + if (dwEventType == CorDebugExceptionUnwindCallbackType.DEBUG_EXCEPTION_INTERCEPTED) { + pauseOnNextExit = true; + } + ExitCallback(); + } + + public void FunctionRemapComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction) + { + EnterCallback(PausedReason.Other, "FunctionRemapComplete", pThread); + + ExitCallback(); + } + + public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction, uint oldILOffset) + { + EnterCallback(PausedReason.Other, "FunctionRemapOpportunity", pThread); + + ExitCallback(); + } + + /// Unknown callback argument + public void MDANotification(ICorDebugController c, ICorDebugThread t, ICorDebugMDA mda) + { + if (c is ICorDebugAppDomain) { + EnterCallback(PausedReason.Other, "MDANotification", (ICorDebugAppDomain)c); + } else if (c is ICorDebugProcess){ + EnterCallback(PausedReason.Other, "MDANotification", (ICorDebugProcess)c); + } else { + throw new System.Exception("Unknown callback argument"); + } + + ExitCallback(); + } + + #endregion + } +} diff --git a/Debugger/Debugger.Core/ManagedCallbackProxy.cs b/Debugger/Debugger.Core/ManagedCallbackProxy.cs new file mode 100644 index 000000000..99a5e417f --- /dev/null +++ b/Debugger/Debugger.Core/ManagedCallbackProxy.cs @@ -0,0 +1,420 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Windows.Forms; +using Debugger.Interop; +using Debugger.Interop.CorDebug; + +// Regular expresion: +// ^{\t*}{(:Ll| )*{:i} *\(((.# {:i}, |\))|())^6\)*}\n\t*\{(.|\n)@\t\} +// Output: \1 - intention \2 - declaration \3 - function name \4-9 parameters + +// Replace with: +// \1\2\n\1{\n\1\tCallbackReceived("\3", new object[] {\4, \5, \6, \7, \8, \9});\n\1} +// \1\2\n\1{\n\1\tCall(delegate {\n\1\t \trealCallback.\3(\n\1\t \t\tMTA2STA.MarshalIntPtrTo(\4),\n\1\t \t\tMTA2STA.MarshalIntPtrTo(\5),\n\1\t \t\tMTA2STA.MarshalIntPtrTo(\6),\n\1\t \t\tMTA2STA.MarshalIntPtrTo(\7),\n\1\t \t\tMTA2STA.MarshalIntPtrTo(\8),\n\1\t \t\tMTA2STA.MarshalIntPtrTo(\9),\n\1\t \t);\n\1\t });\n\1} + +namespace Debugger +{ + /// + /// This proxy marshals the callback to the appropriate thread + /// + class ManagedCallbackProxy : ICorDebugManagedCallback, ICorDebugManagedCallback2 + { + NDebugger debugger; + ManagedCallbackSwitch callbackSwitch; + + public NDebugger Debugger { + get { + return debugger; + } + } + + public ManagedCallbackProxy(NDebugger debugger, ManagedCallbackSwitch callbackSwitch) + { + this.debugger = debugger; + this.callbackSwitch = callbackSwitch; + } + + void Call(MethodInvoker callback) + { + debugger.MTA2STA.Call(callback); + } + + public void StepComplete(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pStepper, CorDebugStepReason reason) + { + Call(delegate { + callbackSwitch.StepComplete( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + MTA2STA.MarshalIntPtrTo(pStepper), + reason + ); + }); + } + + public void Break(System.IntPtr pAppDomain, System.IntPtr pThread) + { + Call(delegate { + callbackSwitch.Break( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread) + ); + }); + } + + public void ControlCTrap(System.IntPtr pProcess) + { + Call(delegate { + callbackSwitch.ControlCTrap( + MTA2STA.MarshalIntPtrTo(pProcess) + ); + }); + } + + public void Exception(System.IntPtr pAppDomain, System.IntPtr pThread, int unhandled) + { + Call(delegate { + callbackSwitch.Exception( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + unhandled + ); + }); + } + + public void Breakpoint(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pBreakpoint) + { + Call(delegate { + callbackSwitch.Breakpoint( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + // This fails in .NET 1.1: + MTA2STA.MarshalIntPtrTo(pBreakpoint) + ); + }); + } + + public void CreateProcess(System.IntPtr pProcess) + { + Call(delegate { + callbackSwitch.CreateProcess( + MTA2STA.MarshalIntPtrTo(pProcess) + ); + }); + } + + public void CreateAppDomain(System.IntPtr pProcess, System.IntPtr pAppDomain) + { + Call(delegate { + callbackSwitch.CreateAppDomain( + MTA2STA.MarshalIntPtrTo(pProcess), + MTA2STA.MarshalIntPtrTo(pAppDomain) + ); + }); + } + + public void CreateThread(System.IntPtr pAppDomain, System.IntPtr pThread) + { + Call(delegate { + callbackSwitch.CreateThread( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread) + ); + }); + } + + public void LoadAssembly(System.IntPtr pAppDomain, System.IntPtr pAssembly) + { + Call(delegate { + callbackSwitch.LoadAssembly( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pAssembly) + ); + }); + } + + public void LoadModule(System.IntPtr pAppDomain, System.IntPtr pModule) + { + Call(delegate { + callbackSwitch.LoadModule( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pModule) + ); + }); + } + + public void NameChange(System.IntPtr pAppDomain, System.IntPtr pThread) + { + Call(delegate { + callbackSwitch.NameChange( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread) + ); + }); + } + + public void LoadClass(System.IntPtr pAppDomain, System.IntPtr c) + { + Call(delegate { + callbackSwitch.LoadClass( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(c) + ); + }); + } + + public void UnloadClass(System.IntPtr pAppDomain, System.IntPtr c) + { + Call(delegate { + callbackSwitch.UnloadClass( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(c) + ); + }); + } + + public void ExitThread(System.IntPtr pAppDomain, System.IntPtr pThread) + { + Call(delegate { + callbackSwitch.ExitThread( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread) + ); + }); + } + + public void UnloadModule(System.IntPtr pAppDomain, System.IntPtr pModule) + { + Call(delegate { + callbackSwitch.UnloadModule( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pModule) + ); + }); + } + + public void UnloadAssembly(System.IntPtr pAppDomain, System.IntPtr pAssembly) + { + Call(delegate { + callbackSwitch.UnloadAssembly( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pAssembly) + ); + }); + } + + public void ExitAppDomain(System.IntPtr pProcess, System.IntPtr pAppDomain) + { + Call(delegate { + callbackSwitch.ExitAppDomain( + MTA2STA.MarshalIntPtrTo(pProcess), + MTA2STA.MarshalIntPtrTo(pAppDomain) + ); + }); + } + + public void ExitProcess(System.IntPtr pProcess) + { + Call(delegate { + callbackSwitch.ExitProcess( + MTA2STA.MarshalIntPtrTo(pProcess) + ); + }); + } + + public void BreakpointSetError(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pBreakpoint, uint dwError) + { + Call(delegate { + callbackSwitch.BreakpointSetError( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + MTA2STA.MarshalIntPtrTo(pBreakpoint), + dwError + ); + }); + } + + public void LogSwitch(System.IntPtr pAppDomain, System.IntPtr pThread, int lLevel, uint ulReason, System.IntPtr pLogSwitchName, System.IntPtr pParentName) + { + Call(delegate { + callbackSwitch.LogSwitch( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + lLevel, + ulReason, + MTA2STA.MarshalIntPtrTo(pLogSwitchName), + MTA2STA.MarshalIntPtrTo(pParentName) + ); + }); + } + + public void EvalException(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pEval) + { + Call(delegate { + callbackSwitch.EvalException( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + MTA2STA.MarshalIntPtrTo(pEval) + ); + }); + } + + public void LogMessage(System.IntPtr pAppDomain, System.IntPtr pThread, int lLevel, System.IntPtr pLogSwitchName, System.IntPtr pMessage) + { + Call(delegate { + callbackSwitch.LogMessage( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + lLevel, + MTA2STA.MarshalIntPtrTo(pLogSwitchName), + MTA2STA.MarshalIntPtrTo(pMessage) + ); + }); + } + + public void EditAndContinueRemap(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pFunction, int fAccurate) + { + Call(delegate { + callbackSwitch.EditAndContinueRemap( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + MTA2STA.MarshalIntPtrTo(pFunction), + fAccurate + ); + }); + } + + public void EvalComplete(System.IntPtr pAppDomain, System.IntPtr pThread, System.IntPtr pEval) + { + Call(delegate { + callbackSwitch.EvalComplete( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + MTA2STA.MarshalIntPtrTo(pEval) + ); + }); + } + + public void DebuggerError(System.IntPtr pProcess, int errorHR, uint errorCode) + { + Call(delegate { + callbackSwitch.DebuggerError( + MTA2STA.MarshalIntPtrTo(pProcess), + errorHR, + errorCode + ); + }); + } + + public void UpdateModuleSymbols(System.IntPtr pAppDomain, System.IntPtr pModule, System.IntPtr pSymbolStream) + { + Call(delegate { + callbackSwitch.UpdateModuleSymbols( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pModule), + MTA2STA.MarshalIntPtrTo(pSymbolStream) + ); + }); + } + + + + #region ICorDebugManagedCallback2 Members + + public void ChangeConnection(IntPtr pProcess, uint dwConnectionId) + { + Call(delegate { + callbackSwitch.ChangeConnection( + MTA2STA.MarshalIntPtrTo(pProcess), + dwConnectionId + ); + }); + } + + public void CreateConnection(IntPtr pProcess, uint dwConnectionId, IntPtr pConnName) + { + Call(delegate { + callbackSwitch.CreateConnection( + MTA2STA.MarshalIntPtrTo(pProcess), + dwConnectionId, + pConnName + ); + }); + } + + public void DestroyConnection(IntPtr pProcess, uint dwConnectionId) + { + Call(delegate { + callbackSwitch.DestroyConnection( + MTA2STA.MarshalIntPtrTo(pProcess), + dwConnectionId + ); + }); + } + + public void Exception(IntPtr pAppDomain, IntPtr pThread, IntPtr pFrame, uint nOffset, CorDebugExceptionCallbackType dwEventType, uint dwFlags) + { + Call(delegate { + callbackSwitch.Exception2( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + MTA2STA.MarshalIntPtrTo(pFrame), + nOffset, + dwEventType, + dwFlags + ); + }); + } + + public void ExceptionUnwind(IntPtr pAppDomain, IntPtr pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags) + { + Call(delegate { + callbackSwitch.ExceptionUnwind( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + dwEventType, + dwFlags + ); + }); + } + + public void FunctionRemapComplete(IntPtr pAppDomain, IntPtr pThread, IntPtr pFunction) + { + Call(delegate { + callbackSwitch.FunctionRemapComplete( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + MTA2STA.MarshalIntPtrTo(pFunction) + ); + }); + } + + public void FunctionRemapOpportunity(IntPtr pAppDomain, IntPtr pThread, IntPtr pOldFunction, IntPtr pNewFunction, uint oldILOffset) + { + Call(delegate { + callbackSwitch.FunctionRemapOpportunity( + MTA2STA.MarshalIntPtrTo(pAppDomain), + MTA2STA.MarshalIntPtrTo(pThread), + MTA2STA.MarshalIntPtrTo(pOldFunction), + MTA2STA.MarshalIntPtrTo(pNewFunction), + oldILOffset + ); + }); + } + + public void MDANotification(IntPtr pController, IntPtr pThread, IntPtr pMDA) + { + Call(delegate { + callbackSwitch.MDANotification( + MTA2STA.MarshalIntPtrTo(pController), + MTA2STA.MarshalIntPtrTo(pThread), + MTA2STA.MarshalIntPtrTo(pMDA) + ); + }); + } + + #endregion + } + +} diff --git a/Debugger/Debugger.Core/ManagedCallbackSwitch.cs b/Debugger/Debugger.Core/ManagedCallbackSwitch.cs new file mode 100644 index 000000000..c7abb5097 --- /dev/null +++ b/Debugger/Debugger.Core/ManagedCallbackSwitch.cs @@ -0,0 +1,400 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +// Regular expresion: +// ^{\t*}{(:Ll| )*{:i} *\(((.# {:i}, |\))|())^6\)*}\n\t*\{(.|\n)@^\1\} +// Output: \1 - intention \2 - declaration \3 - function name \4-9 parameters + +// Replace with: +// \1\2\n\1{\n\1\tGetProcessCallbackInterface(\4).\3(\4, \5, \6, \7, \8, \9);\n\1} + +using System; +using System.Runtime.InteropServices; +using Debugger.Interop; +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + /// + /// This class forwards the callback the the approprite process + /// + class ManagedCallbackSwitch + { + NDebugger debugger; + + public NDebugger Debugger { + get { + return debugger; + } + } + + public ManagedCallbackSwitch(NDebugger debugger) + { + this.debugger = debugger; + } + + public ManagedCallback GetProcessCallbackInterface(string name, ICorDebugController c) + { + if (c is ICorDebugAppDomain) { + return GetProcessCallbackInterface(name, (ICorDebugAppDomain)c); + } else if (c is ICorDebugProcess){ + return GetProcessCallbackInterface(name, (ICorDebugProcess)c); + } else { + throw new System.Exception("Unknown callback argument"); + } + } + + public ManagedCallback GetProcessCallbackInterface(string name, ICorDebugThread pThread) + { + ICorDebugProcess pProcess; + try { + pProcess = pThread.GetProcess(); + } catch (COMException e) { + debugger.TraceMessage("Ignoring callback \"" + name + "\": " + e.Message); + return null; + } + return GetProcessCallbackInterface(name, pProcess); + } + + public ManagedCallback GetProcessCallbackInterface(string name, ICorDebugAppDomain pAppDomain) + { + ICorDebugProcess pProcess; + try { + pProcess = pAppDomain.GetProcess(); + } catch (COMException e) { + debugger.TraceMessage("Ignoring callback \"" + name + "\": " + e.Message); + return null; + } + return GetProcessCallbackInterface(name, pProcess); + } + + public ManagedCallback GetProcessCallbackInterface(string name, ICorDebugProcess pProcess) + { + Process process; + // We have to wait until the created process is added into the collection + lock(debugger.ProcessIsBeingCreatedLock) { + process = debugger.Processes[pProcess]; + } + // Make *really* sure the process is not dead + if (process == null) { + debugger.TraceMessage("Ignoring callback \"" + name + "\": Process not found"); + return null; + } + if (process.HasExited) { + debugger.TraceMessage("Ignoring callback \"" + name + "\": Process has exited"); + return null; + } + if (process.TerminateCommandIssued && !(name == "ExitProcess")) { + debugger.TraceMessage("Ignoring callback \"" + name + "\": Terminate command was issued for the process"); + return null; + } + // Check that the process is not exited + try { + int isRunning = process.CorProcess.IsRunning(); + } catch (COMException e) { + process.TraceMessage("Ignoring callback \"" + name + "\": " + e.Message); + return null; + } + return process.CallbackInterface; + } + + public void ExitProcess(ICorDebugProcess pProcess) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("ExitProcess", pProcess); + if (managedCallback != null) { + managedCallback.ExitProcess(pProcess); + } + } + + #region Program folow control + + public void StepComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugStepper pStepper, CorDebugStepReason reason) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("StepComplete", pAppDomain); + if (managedCallback != null) { + managedCallback.StepComplete(pAppDomain, pThread, pStepper, reason); + } + } + + // Do not pass the pBreakpoint parameter as ICorDebugBreakpoint - marshaling of it fails in .NET 1.1 + public void Breakpoint(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugBreakpoint pBreakpoint) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("Breakpoint", pAppDomain); + if (managedCallback != null) { + managedCallback.Breakpoint(pAppDomain, pThread, pBreakpoint); + } + } + + public void BreakpointSetError(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugBreakpoint pBreakpoint, uint dwError) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("BreakpointSetError", pAppDomain); + if (managedCallback != null) { + managedCallback.BreakpointSetError(pAppDomain, pThread, pBreakpoint, dwError); + } + } + + public unsafe void Break(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("Break", pAppDomain); + if (managedCallback != null) { + managedCallback.Break(pAppDomain, pThread); + } + } + + public void ControlCTrap(ICorDebugProcess pProcess) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("ControlCTrap", pProcess); + if (managedCallback != null) { + managedCallback.ControlCTrap(pProcess); + } + } + + public unsafe void Exception(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int unhandled) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("Exception", pAppDomain); + if (managedCallback != null) { + managedCallback.Exception(pAppDomain, pThread, unhandled); + } + } + + #endregion + + #region Various + + public void LogSwitch(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, uint ulReason, string pLogSwitchName, string pParentName) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("LogSwitch", pAppDomain); + if (managedCallback != null) { + managedCallback.LogSwitch(pAppDomain, pThread, lLevel, ulReason, pLogSwitchName, pParentName); + } + } + + public void LogMessage(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, int lLevel, string pLogSwitchName, string pMessage) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("LogMessage", pAppDomain); + if (managedCallback != null) { + managedCallback.LogMessage(pAppDomain, pThread, lLevel, pLogSwitchName, pMessage); + } + } + + public void EditAndContinueRemap(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction, int fAccurate) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("EditAndContinueRemap", pAppDomain); + if (managedCallback != null) { + managedCallback.EditAndContinueRemap(pAppDomain, pThread, pFunction, fAccurate); + } + } + + public void EvalException(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("EvalException", pAppDomain); + if (managedCallback != null) { + managedCallback.EvalException(pAppDomain, pThread, corEval); + } + } + + public void EvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("EvalComplete", pAppDomain); + if (managedCallback != null) { + managedCallback.EvalComplete(pAppDomain, pThread, corEval); + } + } + + public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("DebuggerError", pProcess); + if (managedCallback != null) { + managedCallback.DebuggerError(pProcess, errorHR, errorCode); + } + } + + public void UpdateModuleSymbols(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule, IStream pSymbolStream) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("UpdateModuleSymbols", pAppDomain); + if (managedCallback != null) { + managedCallback.UpdateModuleSymbols(pAppDomain, pModule, pSymbolStream); + } + } + + #endregion + + #region Start of Application + + public void CreateProcess(ICorDebugProcess pProcess) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("CreateProcess", pProcess); + if (managedCallback != null) { + managedCallback.CreateProcess(pProcess); + } + } + + public void CreateAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("CreateAppDomain", pProcess); + if (managedCallback != null) { + managedCallback.CreateAppDomain(pProcess, pAppDomain); + } + } + + public void LoadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("LoadAssembly", pAppDomain); + if (managedCallback != null) { + managedCallback.LoadAssembly(pAppDomain, pAssembly); + } + } + + public unsafe void LoadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("LoadModule", pAppDomain); + if (managedCallback != null) { + managedCallback.LoadModule(pAppDomain, pModule); + } + } + + public void NameChange(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) + { + ManagedCallback managedCallback = null; + if (pAppDomain != null) { + managedCallback = GetProcessCallbackInterface("NameChange", pAppDomain); + } + if (pThread != null) { + managedCallback = GetProcessCallbackInterface("NameChange", pThread); + } + if (managedCallback != null) { + managedCallback.NameChange(pAppDomain, pThread); + } + } + + public void CreateThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("CreateThread", pAppDomain); + if (managedCallback != null) { + managedCallback.CreateThread(pAppDomain, pThread); + } + } + + public void LoadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("LoadClass", pAppDomain); + if (managedCallback != null) { + managedCallback.LoadClass(pAppDomain, c); + } + } + + #endregion + + #region Exit of Application + + public void UnloadClass(ICorDebugAppDomain pAppDomain, ICorDebugClass c) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("UnloadClass", pAppDomain); + if (managedCallback != null) { + managedCallback.UnloadClass(pAppDomain, c); + } + } + + public void UnloadModule(ICorDebugAppDomain pAppDomain, ICorDebugModule pModule) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("UnloadModule", pAppDomain); + if (managedCallback != null) { + managedCallback.UnloadModule(pAppDomain, pModule); + } + } + + public void UnloadAssembly(ICorDebugAppDomain pAppDomain, ICorDebugAssembly pAssembly) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("UnloadAssembly", pAppDomain); + if (managedCallback != null) { + managedCallback.UnloadAssembly(pAppDomain, pAssembly); + } + } + + public void ExitThread(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("ExitThread", pAppDomain); + if (managedCallback != null) { + managedCallback.ExitThread(pAppDomain, pThread); + } + } + + public void ExitAppDomain(ICorDebugProcess pProcess, ICorDebugAppDomain pAppDomain) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("ExitAppDomain", pProcess); + if (managedCallback != null) { + managedCallback.ExitAppDomain(pProcess, pAppDomain); + } + } + + #endregion + + #region ICorDebugManagedCallback2 Members + + public void ChangeConnection(ICorDebugProcess pProcess, uint dwConnectionId) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("ChangeConnection", pProcess); + if (managedCallback != null) { + managedCallback.ChangeConnection(pProcess, dwConnectionId); + } + } + + public void CreateConnection(ICorDebugProcess pProcess, uint dwConnectionId, IntPtr pConnName) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("CreateConnection", pProcess); + if (managedCallback != null) { + managedCallback.CreateConnection(pProcess, dwConnectionId, pConnName); + } + } + + public void DestroyConnection(ICorDebugProcess pProcess, uint dwConnectionId) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("DestroyConnection", pProcess); + if (managedCallback != null) { + managedCallback.DestroyConnection(pProcess, dwConnectionId); + } + } + + public void Exception2(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFrame pFrame, uint nOffset, CorDebugExceptionCallbackType exceptionType, uint dwFlags) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("Exception2", pAppDomain); + if (managedCallback != null) { + managedCallback.Exception2(pAppDomain, pThread, pFrame, nOffset, exceptionType, dwFlags); + } + } + + public void ExceptionUnwind(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, CorDebugExceptionUnwindCallbackType dwEventType, uint dwFlags) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("ExceptionUnwind", pAppDomain); + if (managedCallback != null) { + managedCallback.ExceptionUnwind(pAppDomain, pThread, dwEventType, dwFlags); + } + } + + public void FunctionRemapComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pFunction) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("FunctionRemapComplete", pAppDomain); + if (managedCallback != null) { + managedCallback.FunctionRemapComplete(pAppDomain, pThread, pFunction); + } + } + + public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction, uint oldILOffset) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("FunctionRemapOpportunity", pAppDomain); + if (managedCallback != null) { + managedCallback.FunctionRemapOpportunity(pAppDomain, pThread, pOldFunction, pNewFunction, oldILOffset); + } + } + + public void MDANotification(ICorDebugController c, ICorDebugThread t, ICorDebugMDA mda) + { + ManagedCallback managedCallback = GetProcessCallbackInterface("MDANotification", c); + if (managedCallback != null) { + managedCallback.MDANotification(c, t, mda); + } + } + + #endregion + } +} diff --git a/Debugger/Debugger.Core/MetaData/DebugConstructorInfo.cs b/Debugger/Debugger.Core/MetaData/DebugConstructorInfo.cs new file mode 100644 index 000000000..1fd877566 --- /dev/null +++ b/Debugger/Debugger.Core/MetaData/DebugConstructorInfo.cs @@ -0,0 +1,133 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; + +using Debugger.Interop.CorDebug; +using Debugger.Interop.CorSym; +using Debugger.Interop.MetaData; +using Mono.Cecil.Signatures; + +namespace Debugger.MetaData +{ + public class DebugConstructorInfo: System.Reflection.ConstructorInfo, IDebugMemberInfo + { + DebugMethodInfo methodInfo; + + internal DebugConstructorInfo(DebugMethodInfo methodInfo) + { + this.methodInfo = methodInfo; + } + + Debugger.Module IDebugMemberInfo.DebugModule { + get { return methodInfo.DebugModule; } + } + + /// + public override Type DeclaringType { + get { return methodInfo.DeclaringType; } + } + + /// + public override int MetadataToken { + get { return methodInfo.MetadataToken; } + } + + /// + public override System.Reflection.Module Module { + get { return methodInfo.Module; } + } + + /// + public override string Name { + get { return methodInfo.Name; } + } + + /// + public override Type ReflectedType { + get { return methodInfo.ReflectedType; } + } + + /// + public override MethodAttributes Attributes { + get { return methodInfo.Attributes; } + } + + /// + public override bool ContainsGenericParameters { + get { return methodInfo.ContainsGenericParameters; } + } + + /// + public override bool IsGenericMethod { + get { return methodInfo.IsGenericMethod; } + } + + /// + public override bool IsGenericMethodDefinition { + get { return methodInfo.IsGenericMethodDefinition; } + } + + /// + public override RuntimeMethodHandle MethodHandle { + get { return methodInfo.MethodHandle; } + } + + DebugType IDebugMemberInfo.MemberType { + get { return ((IDebugMemberInfo)methodInfo).MemberType; } + } + + /// + public override object[] GetCustomAttributes(bool inherit) + { + return methodInfo.GetCustomAttributes(inherit); + } + + /// + public override object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return methodInfo.GetCustomAttributes(attributeType, inherit); + } + + /// + public override bool IsDefined(Type attributeType, bool inherit) + { + return methodInfo.IsDefined(attributeType, inherit); + } + + /// + public override MethodImplAttributes GetMethodImplementationFlags() + { + return methodInfo.GetMethodImplementationFlags(); + } + + /// + public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + { + return methodInfo.Invoke(null, invokeAttr, binder, parameters, culture); + } + + /// + public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + { + return methodInfo.Invoke(null, invokeAttr, binder, parameters, culture); + } + + /// + public override ParameterInfo[] GetParameters() + { + return methodInfo.GetParameters(); + } + + /// + public override string ToString() + { + return methodInfo.ToString(); + } + } +} diff --git a/Debugger/Debugger.Core/MetaData/DebugFieldInfo.cs b/Debugger/Debugger.Core/MetaData/DebugFieldInfo.cs new file mode 100644 index 000000000..8ad8cb9cc --- /dev/null +++ b/Debugger/Debugger.Core/MetaData/DebugFieldInfo.cs @@ -0,0 +1,131 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Globalization; +using System.Reflection; + +using Debugger.Interop.MetaData; +using Mono.Cecil.Signatures; + +namespace Debugger.MetaData +{ + public class DebugFieldInfo : System.Reflection.FieldInfo, IDebugMemberInfo + { + DebugType declaringType; + FieldProps fieldProps; + + internal DebugFieldInfo(DebugType declaringType, FieldProps fieldProps) + { + this.declaringType = declaringType; + this.fieldProps = fieldProps; + } + + /// + public override Type DeclaringType { + get { return declaringType; } + } + + internal FieldProps FieldProps { + get { return fieldProps; } + } + + /// The AppDomain in which this member is declared + public AppDomain AppDomain { + get { return declaringType.AppDomain; } + } + + /// The Process in which this member is declared + public Process Process { + get { return declaringType.Process; } + } + + /// The Module in which this member is declared + public Debugger.Module DebugModule { + get { return declaringType.DebugModule; } + } + + /// + public override int MetadataToken { + get { return (int)fieldProps.Token; } + } + + /// + public override System.Reflection.Module Module { + get { throw new NotSupportedException(); } + } + + /// + public override string Name { + get { return fieldProps.Name; } + } + + /// + public override Type ReflectedType { + get { throw new NotSupportedException(); } + } + + /// + public override object[] GetCustomAttributes(bool inherit) + { + throw new NotSupportedException(); + } + + /// + public override object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotSupportedException(); + } + + /// + public override bool IsDefined(Type attributeType, bool inherit) + { + return DebugType.IsDefined(this, inherit, attributeType); + } + + /// + public override FieldAttributes Attributes { + get { return (FieldAttributes)fieldProps.Flags; } + } + + /// + public override RuntimeFieldHandle FieldHandle { + get { throw new NotSupportedException(); } + } + + /// + public override Type FieldType { + get { + SignatureReader sigReader = new SignatureReader(fieldProps.SigBlob.GetData()); + FieldSig fieldSig = sigReader.GetFieldSig(0); + return DebugType.CreateFromSignature(this.DebugModule, fieldSig.Type, declaringType); + } + } + + // public virtual Type[] GetOptionalCustomModifiers(); + // public virtual object GetRawConstantValue(); + // public virtual Type[] GetRequiredCustomModifiers(); + + /// + public override object GetValue(object obj) + { + return Value.GetFieldValue((Value)obj, this); + } + + /// + public override void SetValue(object obj, object value, System.Reflection.BindingFlags invokeAttr, Binder binder, CultureInfo culture) + { + Value.SetFieldValue((Value)obj, this, (Value)value); + } + + /// + public override string ToString() + { + return this.FieldType + " " + this.Name; + } + + DebugType IDebugMemberInfo.MemberType { + get { return (DebugType)this.FieldType; } + } + } +} diff --git a/Debugger/Debugger.Core/MetaData/DebugLocalVariableInfo.cs b/Debugger/Debugger.Core/MetaData/DebugLocalVariableInfo.cs new file mode 100644 index 000000000..72afa6444 --- /dev/null +++ b/Debugger/Debugger.Core/MetaData/DebugLocalVariableInfo.cs @@ -0,0 +1,61 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Debugger.MetaData +{ + public class DebugLocalVariableInfo: System.Reflection.LocalVariableInfo + { + ValueGetter getter; + int localIndex; + DebugType localType; + + /// + public override int LocalIndex { + get { return localIndex; } + } + + /// + public override Type LocalType { + get { return localType; } + } + + /// + public override bool IsPinned { + get { throw new NotSupportedException(); } + } + + public string Name { get; internal set; } + /// IL offset of the start of the variable scope (inclusive) + public int StartOffset { get; private set; } + /// IL offset of the end of the variable scope (exclusive) + public int EndOffset { get; private set; } + public bool IsThis { get; internal set; } + public bool IsCaptured { get; internal set; } + + public DebugLocalVariableInfo(string name, int localIndex, int startOffset, int endOffset, DebugType localType, ValueGetter getter) + { + this.Name = name; + this.localIndex = localIndex; + this.StartOffset = startOffset; + this.EndOffset = endOffset; + this.localType = localType; + this.getter = getter; + } + + public Value GetValue(StackFrame context) + { + return getter(context); + } + + /// + public override string ToString() + { + string msg = this.LocalType + " " + this.Name; + if (IsCaptured) + msg += " (captured)"; + return msg; + } + } +} diff --git a/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs b/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs new file mode 100644 index 000000000..f1bc327d7 --- /dev/null +++ b/Debugger/Debugger.Core/MetaData/DebugMethodInfo.cs @@ -0,0 +1,664 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; + +using Debugger.Interop.CorDebug; +using Debugger.Interop.CorSym; +using Debugger.Interop.MetaData; +using Mono.Cecil.Signatures; + +namespace Debugger.MetaData +{ + public class DebugMethodInfo: System.Reflection.MethodInfo, IDebugMemberInfo, IOverloadable + { + DebugType declaringType; + MethodProps methodProps; + + internal DebugMethodInfo(DebugType declaringType, MethodProps methodProps) + { + this.declaringType = declaringType; + this.methodProps = methodProps; + } + + /// + public override Type DeclaringType { + get { return declaringType; } + } + + /// The AppDomain in which this member is declared + public AppDomain AppDomain { + get { return declaringType.AppDomain; } + } + + /// The Process in which this member is declared + public Process Process { + get { return declaringType.Process; } + } + + /// The Module in which this member is declared + public Debugger.Module DebugModule { + get { return declaringType.DebugModule; } + } + + /// + public override int MetadataToken { + get { return (int)methodProps.Token; } + } + + /// + public override System.Reflection.Module Module { + get { throw new NotSupportedException(); } + } + + /// Name including the declaring type, return type and parameters + public string FullName { + get { + StringBuilder sb = new StringBuilder(); + + if (this.IsStatic) { + sb.Append("static "); + } + if (this.ReturnType != null) { + sb.Append(this.ReturnType.Name); + sb.Append(" "); + } else { + sb.Append("void "); + } + + sb.Append(this.DeclaringType.FullName); + sb.Append("."); + sb.Append(this.Name); + sb.Append("("); + bool first = true; + foreach(DebugParameterInfo p in GetParameters()) { + if (!first) + sb.Append(", "); + first = false; + sb.Append(p.ParameterType.Name); + sb.Append(" "); + sb.Append(p.Name); + } + sb.Append(")"); + return sb.ToString(); + } + } + + /// + public override string Name { + get { return methodProps.Name; } + } + + /// + public override Type ReflectedType { + get { throw new NotSupportedException(); } + } + + /// + public override object[] GetCustomAttributes(bool inherit) + { + throw new NotSupportedException(); + } + + /// + public override object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotSupportedException(); + } + + /// + public override bool IsDefined(Type attributeType, bool inherit) + { + return DebugType.IsDefined(this, inherit, attributeType); + } + + // public virtual Type[] GetGenericArguments(); + // public virtual MethodBody GetMethodBody(); + + /// + public override MethodImplAttributes GetMethodImplementationFlags() + { + return (MethodImplAttributes)methodProps.ImplFlags; + } + + /// + public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + { + List args = new List(); + foreach(object arg in parameters) { + args.Add((Value)arg); + } + if (this.IsSpecialName && this.Name == ".ctor") { + if (obj != null) + throw new GetValueException("'obj' must be null for constructor call"); + return Eval.NewObject(this, args.ToArray()); + } else { + return Eval.InvokeMethod(this, (Value)obj, args.ToArray()); + } + } + + /// + public override MethodAttributes Attributes { + get { return (MethodAttributes)methodProps.Flags; } + } + + // public virtual CallingConventions CallingConvention { get; } + + /// + public override bool ContainsGenericParameters { + get { throw new NotSupportedException(); } + } + + /// + public override bool IsGenericMethod { + get { throw new NotSupportedException(); } + } + + /// + public override bool IsGenericMethodDefinition { + get { throw new NotSupportedException(); } + } + + /// + public override RuntimeMethodHandle MethodHandle { + get { throw new NotSupportedException(); } + } + + /// + public override MethodInfo GetBaseDefinition() + { + throw new NotSupportedException(); + } + + // public override Type[] GetGenericArguments(); + // public virtual MethodInfo GetGenericMethodDefinition(); + // public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments); + // public override bool ContainsGenericParameters { get; } + + /// + public override Type ReturnType { + get { + if (this.MethodDefSig.RetType.Void) return null; + return DebugType.CreateFromSignature(this.DebugModule, this.MethodDefSig.RetType.Type, declaringType); + } + } + + /// + public override ParameterInfo ReturnParameter { + get { + if (this.MethodDefSig.RetType.Void) return null; + return new DebugParameterInfo(this, string.Empty, this.ReturnType, -1, delegate { throw new NotSupportedException(); }); + } + } + + /// + public override ICustomAttributeProvider ReturnTypeCustomAttributes { + get { throw new NotSupportedException(); } + } + + MethodDefSig methodDefSig; + + MethodDefSig MethodDefSig { + get { + if (methodDefSig == null) { + SignatureReader sigReader = new SignatureReader(methodProps.SigBlob.GetData()); + methodDefSig = sigReader.GetMethodDefSig(0); + } + return methodDefSig; + } + } + + /// Gets the number of paramters of this method + public int ParameterCount { + get { return this.MethodDefSig.ParamCount; } + } + + ParameterInfo[] parameters; + + public DebugParameterInfo GetParameter(string name) + { + foreach(DebugParameterInfo par in GetParameters()) { + if (par.Name == name) + return par; + } + return null; + } + + /// + public override ParameterInfo[] GetParameters() + { + if (parameters == null) { + parameters = new ParameterInfo[this.MethodDefSig.ParamCount]; + for(int i = 0; i < parameters.Length; i++) { + string name; + try { + // index = 0 is return parameter + name = this.DebugModule.MetaData.GetParamPropsForMethodIndex((uint)this.MetadataToken, (uint)i + 1).Name; + } catch { + name = String.Empty; + } + int iCopy = i; + parameters[i] = + new DebugParameterInfo( + this, + name, + DebugType.CreateFromSignature(this.DebugModule, this.MethodDefSig.Parameters[i].Type, declaringType), + i, + delegate (StackFrame context) { return context.GetArgumentValue(iCopy); } + ); + } + } + return parameters; + } + + internal ICorDebugFunction CorFunction { + get { + return this.DebugModule.CorModule.GetFunctionFromToken((uint)this.MetadataToken); + } + } + + /// Gets value indicating whether this method should be stepped over + /// accoring to current options + public bool StepOver { + get { + Options opt = this.Process.Options; + if (opt.StepOverNoSymbols) { + if (this.SymMethod == null) return true; + } + if (opt.StepOverDebuggerAttributes) { + if (this.IsNonUserCode) return true; + } + if (opt.StepOverAllProperties) { + if (this.IsPropertyAccessor) return true; + } + if (opt.StepOverSingleLineProperties) { + if (this.IsPropertyAccessor && this.IsSingleLine) return true; + } + if (opt.StepOverFieldAccessProperties) { + if (this.IsPropertyAccessor && this.BackingFieldToken != 0) return true; + } + return false; + } + } + + internal bool IsPropertyAccessor { get; set; } + + uint backingFieldToken; + + /// + /// Backing field that can be used to obtain the same value as by calling this method. + /// + [Tests.Ignore] + public uint BackingFieldToken { + get { + LoadBackingFieldToken(); + return backingFieldToken; + } + } + + /// + /// Backing field that can be used to obtain the same value as by calling this method. + /// It works only for fields defined in the class + /// + public DebugFieldInfo BackingField { + get { + uint token = this.BackingFieldToken; + if (token == 0) return null; + + // The token can be a field in different class (static or instance in base class) - so it might not be found in the next call + MemberInfo member; + if (!declaringType.TryGetMember(token, out member)) return null; + return (DebugFieldInfo)member; + } + } + + bool loadBackingFieldTokenCalled; + + /// Is this method in form 'return this.field;'? + void LoadBackingFieldToken() + { + if (loadBackingFieldTokenCalled) return; + loadBackingFieldTokenCalled = true; + + backingFieldToken = 0; + + if (this.ParameterCount != 0) return; + + ICorDebugCode corCode; + try { + corCode = this.CorFunction.GetILCode(); + } catch (COMException) { + return; + } + + if (corCode == null || corCode.IsIL() == 0 || corCode.GetSize() > 12) return; + + List code = new List(corCode.GetCode()); + + uint token = 0; + + bool success = + (Read(code, 0x00) || true) && // nop || nothing + (Read(code, 0x02, 0x7B) || Read(code, 0x7E)) && // ldarg.0; ldfld || ldsfld + ReadToken(code, ref token) && // + (Read(code, 0x0A, 0x2B, 0x00, 0x06) || true) && // stloc.0; br.s; offset+00; ldloc.0 || nothing + Read(code, 0x2A); // ret + + if (!success) return; + + if (this.Process.Options.Verbose) { + this.Process.TraceMessage(string.Format("Found backing field for {0}", this.FullName)); + } + + backingFieldToken = token; + } + + // Read expected sequence of bytes + static bool Read(List code, params byte[] expected) + { + if (code.Count < expected.Length) + return false; + for(int i = 0; i < expected.Length; i++) { + if (code[i] != expected[i]) + return false; + } + code.RemoveRange(0, expected.Length); + return true; + } + + // Read field token + static bool ReadToken(List code, ref uint token) + { + if (code.Count < 4) + return false; + if (code[3] != 0x04) // field token + return false; + token = ((uint)code[0]) + ((uint)code[1] << 8) + ((uint)code[2] << 16) + ((uint)code[3] << 24); + code.RemoveRange(0, 4); + return true; + } + + bool? isSingleLine; + + bool IsSingleLine { + get { + // Note symbols might get loaded manually later by the user + ISymUnmanagedMethod symMethod = this.SymMethod; + if (symMethod == null) return false; // No symbols - can not determine + + if (isSingleLine.HasValue) return isSingleLine.Value; + + List seqPoints = new List(symMethod.GetSequencePoints()); + seqPoints.Sort(); + + // Remove initial "{" + if (seqPoints.Count > 0 && + seqPoints[0].Line == seqPoints[0].EndLine && + seqPoints[0].EndColumn - seqPoints[0].Column <= 1) { + seqPoints.RemoveAt(0); + } + + // Remove last "}" + int listIndex = seqPoints.Count - 1; + if (seqPoints.Count > 0 && + seqPoints[listIndex].Line == seqPoints[listIndex].EndLine && + seqPoints[listIndex].EndColumn - seqPoints[listIndex].Column <= 1) { + seqPoints.RemoveAt(listIndex); + } + + // Is single line + isSingleLine = seqPoints.Count == 0 || seqPoints[0].Line == seqPoints[seqPoints.Count - 1].EndLine; + return isSingleLine.Value; + } + } + + bool? isNonUserCode; + + public bool IsNonUserCode { + get { + if (isNonUserCode.HasValue) return isNonUserCode.Value; + + isNonUserCode = + // Look on the method + DebugType.IsDefined( + this, + false, + typeof(System.Diagnostics.DebuggerStepThroughAttribute), + typeof(System.Diagnostics.DebuggerNonUserCodeAttribute), + typeof(System.Diagnostics.DebuggerHiddenAttribute)) + || + // Look on the type + DebugType.IsDefined( + declaringType, + false, + typeof(System.Diagnostics.DebuggerStepThroughAttribute), + typeof(System.Diagnostics.DebuggerNonUserCodeAttribute), + typeof(System.Diagnostics.DebuggerHiddenAttribute)); + + return isNonUserCode.Value; + } + } + + internal void MarkAsNonUserCode() + { + ((ICorDebugFunction2)this.CorFunction).SetJMCStatus(0 /* false */); + + if (this.Process.Options.Verbose) { + this.Process.TraceMessage("Funciton {0} marked as non-user code", this.FullName); + } + } + + internal ISymUnmanagedMethod SymMethod { + get { + if (this.DebugModule.SymReader == null) return null; + try { + return this.DebugModule.SymReader.GetMethod((uint)this.MetadataToken); + } catch { + return null; + } + } + } + + public DebugLocalVariableInfo GetLocalVariable(int offset, string name) + { + foreach(DebugLocalVariableInfo loc in GetLocalVariables(offset)) { + if (loc.Name == name) + return loc; + } + return null; + } + + [Debugger.Tests.Ignore] + public DebugLocalVariableInfo GetLocalVariableThis() + { + foreach(DebugLocalVariableInfo loc in GetLocalVariables()) { + if (loc.IsThis) + return loc; + } + return null; + } + + /// Get local variables valid at the given IL offset + public IEnumerable GetLocalVariables(int offset) + { + foreach (DebugLocalVariableInfo varInfo in GetLocalVariables()) { + if (varInfo.StartOffset <= offset && offset < varInfo.EndOffset) { + yield return varInfo; + } + } + } + + List localVariables; + + public List GetLocalVariables() + { + if (localVariables != null) return localVariables; + + // Generated constructor may not have any symbols + if (this.SymMethod == null) + return new List(); + + localVariables = GetLocalVariablesInScope(this.SymMethod.GetRootScope()); + if (declaringType.IsDisplayClass || declaringType.IsYieldEnumerator) { + // Get display class from self + AddCapturedLocalVariables( + localVariables, + 0, int.MaxValue, + delegate(StackFrame context) { + return context.GetThisValue(); + }, + declaringType + ); + // Get dispaly classes from fields + foreach(DebugFieldInfo fieldInfo in this.DeclaringType.GetFields()) { + DebugFieldInfo fieldInfoCopy = fieldInfo; + if (fieldInfo.Name.StartsWith("CS$")) { + AddCapturedLocalVariables( + localVariables, + 0, int.MaxValue, + delegate(StackFrame context) { + return context.GetThisValue().GetFieldValue(fieldInfoCopy); + }, + (DebugType)fieldInfo.FieldType + ); + } + } + } else { + // Add this + if (!this.IsStatic) { + DebugLocalVariableInfo thisVar = new DebugLocalVariableInfo( + "this", + -1, + 0, int.MaxValue, + declaringType, + delegate(StackFrame context) { + return context.GetThisValue(); + } + ); + thisVar.IsThis = true; + localVariables.Add(thisVar); + } + } + return localVariables; + } + + static void AddCapturedLocalVariables(List vars, int scopeStartOffset, int scopeEndOffset, ValueGetter getCaptureClass, DebugType captureClassType) + { + if (captureClassType.IsDisplayClass || captureClassType.IsYieldEnumerator) { + foreach(DebugFieldInfo fieldInfo in captureClassType.GetFields()) { + DebugFieldInfo fieldInfoCopy = fieldInfo; + if (fieldInfo.Name.StartsWith("CS$")) continue; // Ignore + DebugLocalVariableInfo locVar = new DebugLocalVariableInfo( + fieldInfo.Name, + -1, + scopeStartOffset, + scopeEndOffset, + (DebugType)fieldInfo.FieldType, + delegate(StackFrame context) { + return getCaptureClass(context).GetFieldValue(fieldInfoCopy); + } + ); + locVar.IsCaptured = true; + if (locVar.Name.StartsWith("<>")) { + bool hasThis = false; + foreach(DebugLocalVariableInfo l in vars) { + if (l.IsThis) { + hasThis = true; + break; + } + } + if (!hasThis && locVar.Name.EndsWith("__this")) { + locVar.Name = "this"; + locVar.IsThis = true; + } else { + continue; // Ignore + } + } + if (locVar.Name.StartsWith("<")) { + int endIndex = locVar.Name.IndexOf('>'); + if (endIndex == -1) continue; // Ignore + locVar.Name = fieldInfo.Name.Substring(1, endIndex - 1); + } + vars.Add(locVar); + } + } + } + + List GetLocalVariablesInScope(ISymUnmanagedScope symScope) + { + List vars = new List(); + foreach (ISymUnmanagedVariable symVar in symScope.GetLocals()) { + ISymUnmanagedVariable symVarCopy = symVar; + int start; + SignatureReader sigReader = new SignatureReader(symVar.GetSignature()); + LocalVarSig.LocalVariable locVarSig = sigReader.ReadLocalVariable(sigReader.Blob, 0, out start); + DebugType locVarType = DebugType.CreateFromSignature(this.DebugModule, locVarSig.Type, declaringType); + // Compiler generated? + // NB: Display class does not have the compiler-generated flag + if ((symVar.GetAttributes() & 1) == 1 || symVar.GetName().StartsWith("CS$")) { + // Get display class from local variable + if (locVarType.IsDisplayClass) { + AddCapturedLocalVariables( + vars, + (int)symScope.GetStartOffset(), + (int)symScope.GetEndOffset(), + delegate(StackFrame context) { + return GetLocalVariableValue(context, symVarCopy); + }, + locVarType + ); + } + } else { + DebugLocalVariableInfo locVar = new DebugLocalVariableInfo( + symVar.GetName(), + (int)symVar.GetAddressField1(), + // symVar also has Get*Offset methods, but the are not implemented + (int)symScope.GetStartOffset(), + (int)symScope.GetEndOffset(), + locVarType, + delegate(StackFrame context) { + return GetLocalVariableValue(context, symVarCopy); + } + ); + vars.Add(locVar); + } + } + foreach(ISymUnmanagedScope childScope in symScope.GetChildren()) { + vars.AddRange(GetLocalVariablesInScope(childScope)); + } + return vars; + } + + static Value GetLocalVariableValue(StackFrame context, ISymUnmanagedVariable symVar) + { + ICorDebugValue corVal; + try { + corVal = context.CorILFrame.GetLocalVariable((uint)symVar.GetAddressField1()); + } catch (COMException e) { + if ((uint)e.ErrorCode == 0x80131304) throw new GetValueException("Unavailable in optimized code"); + throw; + } + return new Value(context.AppDomain, corVal); + } + + /// + public override string ToString() + { + return this.FullName; + } + + IntPtr IOverloadable.GetSignarture() + { + return methodProps.SigBlob.Adress; + } + + DebugType IDebugMemberInfo.MemberType { + get { return (DebugType)this.ReturnType; } + } + } +} diff --git a/Debugger/Debugger.Core/MetaData/DebugParameterInfo.cs b/Debugger/Debugger.Core/MetaData/DebugParameterInfo.cs new file mode 100644 index 000000000..cf95f7555 --- /dev/null +++ b/Debugger/Debugger.Core/MetaData/DebugParameterInfo.cs @@ -0,0 +1,67 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Reflection; + +namespace Debugger.MetaData +{ + public class DebugParameterInfo : System.Reflection.ParameterInfo + { + ValueGetter getter; + MemberInfo member; + string name; + Type parameterType; + int position; + + /// + public override MemberInfo Member { + get { return member; } + } + + /// + public override string Name { + get { return name; } + } + + /// + public override Type ParameterType { + get { return parameterType; } + } + + /// + public override int Position { + get { return position; } + } + + public DebugParameterInfo(MemberInfo member, string name, Type parameterType, int position, ValueGetter getter) + { + this.member = member; + this.name = name; + this.parameterType = parameterType; + this.position = position; + this.getter = getter; + } + + public Value GetValue(StackFrame context) + { + return getter(context); + } + + // public virtual ParameterAttributes Attributes { get; } + // public virtual object DefaultValue { get; } + // public virtual object RawDefaultValue { get; } + // + // public virtual object[] GetCustomAttributes(bool inherit); + // public virtual object[] GetCustomAttributes(Type attributeType, bool inherit); + // public virtual Type[] GetOptionalCustomModifiers(); + // public virtual Type[] GetRequiredCustomModifiers(); + // public virtual bool IsDefined(Type attributeType, bool inherit); + + /// + public override string ToString() + { + return this.ParameterType + " " + this.Name; + } + } +} diff --git a/Debugger/Debugger.Core/MetaData/DebugPropertyInfo.cs b/Debugger/Debugger.Core/MetaData/DebugPropertyInfo.cs new file mode 100644 index 000000000..35b0bc252 --- /dev/null +++ b/Debugger/Debugger.Core/MetaData/DebugPropertyInfo.cs @@ -0,0 +1,244 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Text; + +namespace Debugger.MetaData +{ + public class DebugPropertyInfo : System.Reflection.PropertyInfo, IDebugMemberInfo, IOverloadable + { + DebugType declaringType; + string name; + MethodInfo getMethod; + MethodInfo setMethod; + + internal DebugPropertyInfo(DebugType declaringType, string name, MethodInfo getMethod, MethodInfo setMethod) + { + if (getMethod == null && setMethod == null) throw new ArgumentNullException("Both getter and setter can not be null."); + + this.declaringType = declaringType; + this.name = name; + this.getMethod = getMethod; + this.setMethod = setMethod; + } + + /// + public override Type DeclaringType { + get { return declaringType; } + } + + /// The AppDomain in which this member is declared + public AppDomain AppDomain { + get { return declaringType.AppDomain; } + } + + /// The Process in which this member is declared + public Process Process { + get { return declaringType.Process; } + } + + /// The Module in which this member is declared + public Debugger.Module DebugModule { + get { return declaringType.DebugModule; } + } + + /// + public override int MetadataToken { + get { return 0; } + } + + /// + public override System.Reflection.Module Module { + get { throw new NotSupportedException(); } + } + + /// + public override string Name { + get { return name; } + } + + /// Name including the declaring type, return type and parameters + public string FullName { + get { + StringBuilder sb = new StringBuilder(); + + if (this.IsStatic) { + sb.Append("static "); + } + sb.Append(this.PropertyType.Name); + sb.Append(" "); + + sb.Append(this.DeclaringType.FullName); + sb.Append("."); + sb.Append(this.Name); + + if (GetIndexParameters().Length > 0) { + sb.Append("["); + bool first = true; + foreach(DebugParameterInfo p in GetIndexParameters()) { + if (!first) + sb.Append(", "); + first = false; + sb.Append(p.ParameterType.Name); + sb.Append(" "); + sb.Append(p.Name); + } + sb.Append("]"); + } + return sb.ToString(); + } + } + + /// + public override Type ReflectedType { + get { throw new NotSupportedException(); } + } + + /// + public override object[] GetCustomAttributes(bool inherit) + { + throw new NotSupportedException(); + } + + /// + public override object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotSupportedException(); + } + + /// + public override bool IsDefined(Type attributeType, bool inherit) + { + return DebugType.IsDefined(this, inherit, attributeType); + } + + /// + public override PropertyAttributes Attributes { + get { throw new NotSupportedException(); } + } + + /// + public override bool CanRead { + get { return getMethod != null; } + } + + /// + public override bool CanWrite { + get { return setMethod != null; } + } + + /// + public override Type PropertyType { + get { + if (getMethod != null) { + return getMethod.ReturnType; + } else { + return setMethod.GetParameters()[setMethod.GetParameters().Length - 1].ParameterType; + } + } + } + + /// + public override MethodInfo[] GetAccessors(bool nonPublic) + { + throw new NotSupportedException(); + } + + // public virtual object GetConstantValue(); + + /// + public override MethodInfo GetGetMethod(bool nonPublic) + { + return getMethod; + } + + /// + public override ParameterInfo[] GetIndexParameters() + { + if (GetGetMethod() != null) { + return GetGetMethod().GetParameters(); + } + if (GetSetMethod() != null) { + List pars = new List(); + pars.AddRange(GetSetMethod().GetParameters()); + pars.RemoveAt(pars.Count - 1); + return pars.ToArray(); + } + return null; + } + + // public virtual Type[] GetOptionalCustomModifiers(); + // public virtual object GetRawConstantValue(); + // public virtual Type[] GetRequiredCustomModifiers(); + + /// + public override MethodInfo GetSetMethod(bool nonPublic) + { + return setMethod; + } + + /// + public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) + { + List args = new List(); + foreach(object arg in index) { + args.Add((Value)arg); + } + return Value.GetPropertyValue((Value)obj, this, args.ToArray()); + } + + /// + public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) + { + List args = new List(); + foreach(object arg in index) { + args.Add((Value)arg); + } + Value.SetPropertyValue((Value)obj, this, args.ToArray(), (Value)value); + } + + public bool IsPublic { + get { return (getMethod ?? setMethod).IsPublic; } + } + + public bool IsAssembly { + get { return (getMethod ?? setMethod).IsAssembly; } + } + + public bool IsFamily { + get { return (getMethod ?? setMethod).IsFamily; } + } + + public bool IsPrivate { + get { return (getMethod ?? setMethod).IsPrivate; } + } + + public bool IsStatic { + get { return (getMethod ?? setMethod).IsStatic; } + } + + DebugType IDebugMemberInfo.MemberType { + get { return (DebugType)this.PropertyType; } + } + + ParameterInfo[] IOverloadable.GetParameters() + { + return GetIndexParameters(); + } + + IntPtr IOverloadable.GetSignarture() + { + return ((IOverloadable)(getMethod ?? setMethod)).GetSignarture(); + } + + /// + public override string ToString() + { + return this.FullName; + } + } +} diff --git a/Debugger/Debugger.Core/MetaData/DebugType.cs b/Debugger/Debugger.Core/MetaData/DebugType.cs new file mode 100644 index 000000000..459bda427 --- /dev/null +++ b/Debugger/Debugger.Core/MetaData/DebugType.cs @@ -0,0 +1,1377 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Text; + +using Debugger.Interop.CorDebug; +using Debugger.Interop.MetaData; +using ICSharpCode.NRefactory.Ast; +using Mono.Cecil.Signatures; + +namespace Debugger.MetaData +{ + /// + /// Represents a type in a debugee. That is, a class, array, value type or a primitive type. + /// This class mimics the class. + /// + /// + /// If two types are identical, the references to DebugType will also be identical + /// Type will be loaded once per each appdomain. + /// + [Debugger.Tests.IgnoreOnException] + public class DebugType: System.Type, IDebugMemberInfo + { + public const BindingFlags BindingFlagsAll = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + public const BindingFlags BindingFlagsAllDeclared = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + public const BindingFlags BindingFlagsAllInScope = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + + Module module; + ICorDebugType corType; + CorElementType corElementType; + Type primitiveType; + TypeDefProps classProps; + string ns; + string name; + string fullName; + string fullNameWithoutGenericArguments; + DebugType declaringType; + DebugType elementType; + List genericArguments = new List(); + List interfaces = new List(); + + // Members of the type; empty if not applicable + Dictionary> membersByName = new Dictionary>(); + Dictionary membersByToken = new Dictionary(); + + internal ICorDebugType CorType { + get { return corType; } + } + + /// + public override Type DeclaringType { + get { return declaringType; } + } + + [Debugger.Tests.Ignore] + public IEnumerable GetSelfAndDeclaringTypes() + { + DebugType type = this; + while(type != null) { + yield return type; + type = (DebugType)type.DeclaringType; + } + } + + /// The AppDomain in which this type is loaded + public AppDomain AppDomain { + get { return module.AppDomain; } + } + + /// The Process in which this type is loaded + public Process Process { + get { return module.Process; } + } + + /// The Module in which this type is loaded + public Debugger.Module DebugModule { + get { return module; } + } + + /// + public override int MetadataToken { + get { return (int)classProps.Token; } + } + + /// + public override System.Reflection.Module Module { + get { throw new NotSupportedException(); } + } + + /// + public override string Name { + get { return name; } + } + + /// + public override Type ReflectedType { + get { throw new NotSupportedException(); } + } + + /// + public override object[] GetCustomAttributes(bool inherit) + { + throw new NotSupportedException(); + } + + /// + public override object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotSupportedException(); + } + + /// + public override bool IsDefined(Type attributeType, bool inherit) + { + return IsDefined(this, inherit, attributeType); + } + + public static bool IsDefined(IDebugMemberInfo member, bool inherit, params Type[] attributeTypes) + { + if (inherit) + throw new NotSupportedException("inherit"); + + MetaDataImport metaData = member.DebugModule.MetaData; + uint token = (uint)member.MetadataToken; + foreach(CustomAttributeProps ca in metaData.EnumCustomAttributeProps(token, 0)) { + CorTokenType tkType = (CorTokenType)(ca.Type & 0xFF000000); + string attributeName; + if (tkType == CorTokenType.MemberRef) { + MemberRefProps constructorMethod = metaData.GetMemberRefProps(ca.Type); + attributeName = metaData.GetTypeRefProps(constructorMethod.DeclaringType).Name; + } else if (tkType == CorTokenType.MethodDef) { + MethodProps constructorMethod = metaData.GetMethodProps(ca.Type); + attributeName = metaData.GetTypeDefProps(constructorMethod.ClassToken).Name; + } else { + throw new DebuggerException("Not expected: " + tkType); + } + foreach(Type attributeType in attributeTypes) { + if (attributeName == attributeType.FullName) + return true; + } + } + return false; + } + + /// + public override Assembly Assembly { + get { throw new NotSupportedException(); } + } + + /// + public override string AssemblyQualifiedName { + get { throw new NotSupportedException(); } + } + + /// + public override Type BaseType { + get { + // corType.Base *sometimes* does not work for object and can cause "Value does not fall within the expected range." exception + if (this.FullName == typeof(object).FullName) { + return null; + } + // corType.Base does not work for arrays + if (this.IsArray) { + return DebugType.CreateFromType(this.AppDomain.Mscorlib, typeof(Array)); + } + // corType.Base does not work for primitive types +// if (this.IsPrimitive) { +// return DebugType.CreateFromType(this.AppDomain, typeof(ValueType)); +// } + if (this.IsPointer || corElementType == CorElementType.VOID) { + return null; + } + ICorDebugType baseType = corType.GetBase(); + if (baseType != null) { + return CreateFromCorType(this.AppDomain, baseType); + } else { + return null; + } + } + } + + // public virtual bool ContainsGenericParameters { get; } + // public virtual MethodBase DeclaringMethod { get; } + + /// + public override string FullName { + get { return fullName; } + } + + [Debugger.Tests.Ignore] + public string FullNameWithoutGenericArguments { + get { return fullNameWithoutGenericArguments; } + } + + /// + public override Guid GUID { + get { throw new NotSupportedException(); } + } + + // public virtual GenericParameterAttributes GenericParameterAttributes { get; } + // public virtual int GenericParameterPosition { get; } + // public virtual bool IsGenericParameter { get; } + // public virtual bool IsGenericTypeDefinition { get; } + + /// + public override bool IsGenericType { + get { + return this.GetGenericArguments().Length > 0; + } + } + + /// + public override string Namespace { + get { return ns; } + } + + // public virtual StructLayoutAttribute StructLayoutAttribute { get; } + + /// + public override RuntimeTypeHandle TypeHandle { + get { throw new NotSupportedException(); } + } + + /// + public override Type UnderlyingSystemType { + get { return this; } + } + + /// + public override int GetArrayRank() + { + if (!IsArray) throw new ArgumentException("Type is not array"); + + return (int)corType.GetRank(); + } + + /// + protected override TypeAttributes GetAttributeFlagsImpl() + { + return (TypeAttributes)classProps.Flags; + } + + /// + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + { + if (bindingAttr == BindingFlags.Default) + bindingAttr = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; + MethodInfo ctor = GetMethodImpl(".ctor", bindingAttr, binder, callConvention, types, modifiers); + if (ctor == null) + return null; + return new DebugConstructorInfo((DebugMethodInfo)ctor); + } + + /// + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) + { + throw new NotSupportedException(); + } + + // public virtual MemberInfo[] GetDefaultMembers(); + + /// + public override Type GetElementType() + { + return elementType; + } + + const BindingFlags SupportedFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy; + + /// Return member with the given token + public MemberInfo GetMember(uint token) + { + return membersByToken[(int)token]; + } + + /// Return member with the given token + public bool TryGetMember(uint token, out MemberInfo memberInfo) + { + return membersByToken.TryGetValue((int)token, out memberInfo); + } + + public T GetMember(string name, BindingFlags bindingFlags, Predicate filter) where T:MemberInfo + { + T[] res = GetMembers(name, bindingFlags, filter); + if (res.Length > 0) { + return res[0]; + } else { + return null; + } + } + + /// + /// Note that at the moment the function will return two methods for interface implementations: + /// the acutual implementation and the method in the interface + /// + public T[] GetMembers(string name, BindingFlags bindingFlags, Predicate filter) where T:MemberInfo + { + BindingFlags unsupported = bindingFlags & ~SupportedFlags; + if (unsupported != 0) + throw new NotSupportedException("BindingFlags: " + unsupported); + + if ((bindingFlags & (BindingFlags.Public | BindingFlags.NonPublic)) == 0) + throw new ArgumentException("Public or NonPublic flag must be included", "bindingFlags"); + + if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) == 0) + throw new ArgumentException("Instance or Static flag must be included", "bindingFlags"); + + // Filter by name + IEnumerable> searchScope; + if (name != null) { + if (membersByName.ContainsKey(name)) { + searchScope = new List[] { membersByName[name] }; + } else { + searchScope = new List[] { }; + } + } else { + searchScope = membersByName.Values; + } + + List results = new List(); + foreach(List memberInfos in searchScope) { + foreach(MemberInfo memberInfo in memberInfos) { + // Filter by type + if (!(memberInfo is T)) continue; // Reject item + + // Filter by access + if (((IDebugMemberInfo)memberInfo).IsPublic) { + if ((bindingFlags & BindingFlags.Public) == 0) continue; // Reject item + } else { + if ((bindingFlags & BindingFlags.NonPublic) == 0) continue; // Reject item + } + + // Filter by static / instance + if (((IDebugMemberInfo)memberInfo).IsStatic) { + if ((bindingFlags & BindingFlags.Static) == 0) continue; // Reject item + } else { + if ((bindingFlags & BindingFlags.Instance) == 0) continue; // Reject item + } + + // Filter using predicate + if (filter != null && !filter((T)memberInfo)) continue; // Reject item + + results.Add((T)memberInfo); + } + } + + if ((bindingFlags & BindingFlags.DeclaredOnly) == 0) { + // Query supertype + if (this.BaseType != null) { + if ((bindingFlags & BindingFlags.FlattenHierarchy) == 0) { + // Do not include static types + bindingFlags = bindingFlags & ~BindingFlags.Static; + } + // Any flags left? + if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) != 0) { + T[] superResults = ((DebugType)this.BaseType).GetMembers(name, bindingFlags, filter); + results.AddRange(superResults); + } + } + // Query interfaces - needed to get inherited methods of an interface + if (this.IsInterface) { + foreach (DebugType inter in this.GetInterfaces()) { + // GetInterfaces will return all interfaces - no need to recurse + bindingFlags |= BindingFlags.DeclaredOnly; + T[] interResults = inter.GetMembers(name, bindingFlags, filter); + results.AddRange(interResults); + } + } + } + + return results.ToArray(); + } + + MemberInfo SelectOverload(MemberInfo[] candidates, Type[] argumentTypes) + { + if (candidates.Length == 0) + return null; + if (candidates.Length == 1) { + if (argumentTypes == null) + return candidates[0]; + ParameterInfo[] pars = ((IOverloadable)candidates[0]).GetParameters(); + if (pars.Length != argumentTypes.Length) + throw new GetValueException("Incorrect parameter count"); + for(int i = 0; i < pars.Length; i++) { + ParameterInfo par = pars[i]; + if (!((DebugType)argumentTypes[i]).CanImplicitelyConvertTo(par.ParameterType)) + throw new GetValueException("Incorrect parameter type for '{0}'. Excpeted {1}, seen {2}", par.Name, par.ParameterType.FullName, argumentTypes[i]); + } + return candidates[0]; + } + + List applicable = new List(); + foreach(MemberInfo candidate in candidates) { + bool isExactMatch; + if (IsApplicable(((IOverloadable)candidate).GetParameters(), argumentTypes, out isExactMatch)) + applicable.Add(candidate); + if (isExactMatch) + return candidate; + } + if (applicable.Count == 0) { + throw new GetValueException("No applicable overload found"); + } else if (applicable.Count == 1) { + return applicable[0]; + } else { + // Remove base class definitions + IntPtr sig = ((IOverloadable)applicable[0]).GetSignarture(); + for(int i = 1; i < applicable.Count;) { + if (sig == ((IOverloadable)applicable[i]).GetSignarture()) { + applicable.RemoveAt(i); + } else { + i++; + } + } + if (applicable.Count == 1) + return applicable[0]; + StringBuilder overloads = new StringBuilder(); + foreach(MemberInfo app in applicable) { + overloads.Append(Environment.NewLine); + overloads.Append(" "); + overloads.Append(app.ToString()); + } + throw new GetValueException("More then one applicable overload found:" + overloads.ToString()); + } + } + + bool IsApplicable(ParameterInfo[] parameters, Type[] argumentTypes, out bool isExactMatch) + { + isExactMatch = false; + if (argumentTypes == null) + return true; + if (argumentTypes.Length != parameters.Length) + return false; + isExactMatch = true; + for(int i = 0; i < parameters.Length; i++) { + if (argumentTypes[i] != parameters[i].ParameterType) { + isExactMatch = false; + if (!((DebugType)argumentTypes[i]).CanImplicitelyConvertTo(parameters[i].ParameterType)) + return false; + } + } + return true; + } + + static string Byte = typeof(byte).FullName; + static string Short = typeof(short).FullName; + static string Int = typeof(int).FullName; + static string Long = typeof(long).FullName; + static string SByte = typeof(sbyte).FullName; + static string UShort = typeof(ushort).FullName; + static string UInt = typeof(uint).FullName; + static string ULong = typeof(ulong).FullName; + static string Float = typeof(float).FullName; + static string Double = typeof(double).FullName; + static string Char = typeof(char).FullName; + static string Decimal = typeof(decimal).FullName; + + public bool CanImplicitelyConvertTo(Type toType) + { + if (this == toType) + return true; + if (this.IsPrimitive && toType.IsPrimitive) { + string f = this.FullName; + string t = toType.FullName; + if (f == t) + return true; + if (f == SByte && (t == Short || t == Int || t == Long || t == Float || t == Double || t == Decimal)) + return true; + if (f == Byte && (t == Short || t == UShort || t == Int || t == UInt || t == Long || t == ULong || t == Float || t == Double || t == Decimal)) + return true; + if (f == Short && (t == Int || t == Long || t == Float || t == Double || t == Decimal)) + return true; + if (f == UShort && (t == Int || t == UInt || t == Long || t == ULong || t == Float || t == Double || t == Decimal)) + return true; + if (f == Int && (t == Long || t == Float || t == Double || t == Decimal)) + return true; + if (f == UInt && (t == Long || t == ULong || t == Float || t == Double || t == Decimal)) + return true; + if ((f == Long || f == ULong) && (t == Float || t == Double || t == Decimal)) + return true; + if (f == Char && (t == UShort || t == Int || t == UInt || t == Long || t == ULong || t == Float || t == Double || t == Decimal)) + return true; + if (f == Float && t == Double) + return true; + return false; + } else { + return toType.IsAssignableFrom(this); + } + } + + /// + public override EventInfo GetEvent(string name, BindingFlags bindingAttr) + { + throw new NotSupportedException(); + } + + // public virtual EventInfo[] GetEvents(); + + /// + public override EventInfo[] GetEvents(BindingFlags bindingAttr) + { + throw new NotSupportedException(); + } + + /// + public override FieldInfo GetField(string name, BindingFlags bindingAttr) + { + return GetMember(name, bindingAttr, null); + } + + /// + public override FieldInfo[] GetFields(BindingFlags bindingAttr) + { + return GetMembers(null, bindingAttr, null); + } + + /// + public override Type[] GetGenericArguments() + { + return genericArguments.ToArray(); + } + + internal ICorDebugType[] GenericArgumentsAsCorDebugType { + get { + List types = new List(); + foreach(DebugType arg in GetGenericArguments()) { + types.Add(arg.CorType); + } + return types.ToArray(); + } + } + + // public virtual Type[] GetGenericParameterConstraints(); + // public virtual Type GetGenericTypeDefinition(); + + /// + public override Type GetInterface(string name, bool ignoreCase) + { + foreach(DebugType inter in this.GetInterfaces()) { + if (string.Equals(inter.FullName, name, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) + return inter; + if (string.Equals(inter.FullNameWithoutGenericArguments, name, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) + return inter; + } + if (BaseType != null) { + return BaseType.GetInterface(fullName); + } else { + return null; + } + } + + // public virtual InterfaceMapping GetInterfaceMap(Type interfaceType); + + /// + /// All interfaces implemented by the type + public override Type[] GetInterfaces() + { + return this.interfaces.ToArray(); + } + + /// + public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + { + return GetMembers(name, bindingAttr, delegate(MemberInfo info) { return (info.MemberType & type) != 0; }); + } + + /// + public override MemberInfo[] GetMembers(BindingFlags bindingAttr) + { + return GetMembers(null, bindingAttr, null); + } + + /// Return method with the given token + public MethodInfo GetMethod(uint token) + { + return (MethodInfo)membersByToken[(int)token]; + } + + /// Return method overload with given parameter names + /// Null if not found + public MethodInfo GetMethod(string name, string[] paramNames) + { + foreach(DebugMethodInfo candidate in GetMembers(name, BindingFlagsAll, null)) { + if (candidate.ParameterCount == paramNames.Length) { + bool match = true; + for(int i = 0; i < paramNames.Length; i++) { + if (paramNames[i] != candidate.GetParameters()[i].Name) + match = false; + } + if (match) + return candidate; + } + } + return null; + } + + /// + protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] paramTypes, ParameterModifier[] modifiers) + { + if (binder != null) + throw new NotSupportedException("binder"); + if (callConvention != CallingConventions.Any) + throw new NotSupportedException("callConvention"); + if (modifiers != null) + throw new NotSupportedException("modifiers"); + + MethodInfo[] candidates = GetMethods(name, bindingAttr); + return (MethodInfo)SelectOverload(candidates, paramTypes); + } + + public MethodInfo[] GetMethods(string name, BindingFlags bindingAttr) + { + return GetMembers(name, bindingAttr, null); + } + + /// + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) + { + return GetMembers(null, bindingAttr, null); + } + + /// + public override Type GetNestedType(string name, BindingFlags bindingAttr) + { + throw new NotSupportedException(); + } + + /// + public override Type[] GetNestedTypes(BindingFlags bindingAttr) + { + throw new NotSupportedException(); + } + + public MemberInfo[] GetFieldsAndNonIndexedProperties(BindingFlags bindingAttr) + { + return GetMembers(null, bindingAttr, IsFieldOrNonIndexedProperty); + } + + public static bool IsFieldOrNonIndexedProperty(MemberInfo info) + { + if (info is FieldInfo) + return true; + if (info is PropertyInfo) { + return ((PropertyInfo)info).GetGetMethod(true) != null && + ((PropertyInfo)info).GetGetMethod(true).GetParameters().Length == 0; + } + return false; + } + + public PropertyInfo[] GetProperties(string name, BindingFlags bindingAttr) + { + return GetMembers(name, bindingAttr, null); + } + + /// + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) + { + return GetMembers(null, bindingAttr, null); + } + + /// + protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] paramTypes, ParameterModifier[] modifiers) + { + if (binder != null) + throw new NotSupportedException("binder"); + if (returnType != null) + throw new NotSupportedException("returnType"); + if (modifiers != null) + throw new NotSupportedException("modifiers"); + + PropertyInfo[] candidates = GetProperties(name, bindingAttr); + return (PropertyInfo)SelectOverload(candidates, paramTypes); + } + + /// + protected override bool HasElementTypeImpl() + { + return elementType != null; + } + + /// + public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) + { + throw new NotSupportedException(); + } + + /// + protected override bool IsArrayImpl() + { + return corElementType == CorElementType.ARRAY || + corElementType == CorElementType.SZARRAY; + } + + /// + protected override bool IsByRefImpl() + { + return corElementType == CorElementType.BYREF; + } + + /// + protected override bool IsPointerImpl() + { + return corElementType == CorElementType.PTR; + } + +// public bool IsClass { +// get { +// return !this.IsInterface && !this.IsSubclassOf(valueType); +// } +// } +// +// public bool IsInterface { +// get { +// return ((this.GetAttributeFlagsImpl() & TypeAttributes.Interface) != 0); +// } +// } + + /// + protected override bool IsValueTypeImpl() + { + // ValueType and Enum are exceptions and are threated as classes + return this.FullName != typeof(ValueType).FullName && + this.FullName != typeof(Enum).FullName && + this.IsSubclassOf(DebugType.CreateFromType(this.AppDomain.Mscorlib, typeof(ValueType))); + } + + /// + public override bool IsSubclassOf(Type superType) + { + if (!(superType is DebugType)) { + superType = CreateFromType(this.AppDomain, superType); + } + return base.IsSubclassOf(superType); + } + + /// + protected override bool IsCOMObjectImpl() + { + throw new NotSupportedException(); + } + + /// + public override bool IsInstanceOfType(object o) + { + if (o == null) return false; + if (!(o is Value)) return false; + return this.IsAssignableFrom(((Value)o).Type); + } + + /// + public override bool IsAssignableFrom(Type c) + { + if (this == c) return true; + if (this.IsInterface) { + foreach(Type intf in c.GetInterfaces()) { + if (this == intf) + return true; + } + return false; + } else { + return c.IsSubclassOf(this); + } + } + + // protected virtual bool IsContextfulImpl(); + // protected virtual bool IsMarshalByRefImpl(); + + /// Returns simple managed type coresponding to the primitive type. + [Debugger.Tests.Ignore] + public System.Type PrimitiveType { + get { return primitiveType; } + } + + /// + protected override bool IsPrimitiveImpl() + { + return this.PrimitiveType != null; + } + + /// Gets a value indicating whether the type is an integer type + public bool IsInteger { + get { + switch (this.FullName) { + case "System.SByte": + case "System.Byte": + case "System.Int16": + case "System.UInt16": + case "System.Int32": + case "System.UInt32": + case "System.Int64": + case "System.UInt64": return true; + default: return false; + } + } + } + + public bool IsCompilerGenerated { + get { + return IsDefined(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), false); + } + } + + public bool IsDisplayClass { + get { + return this.Name.StartsWith("<>") && this.Name.Contains("__DisplayClass"); + } + } + + public bool IsYieldEnumerator { + get { + if (this.IsCompilerGenerated) { + return GetInterface(typeof(System.Collections.IEnumerator).FullName) != null; + } + return false; + } + } + + bool IDebugMemberInfo.IsAssembly { + get { return false; } + } + + bool IDebugMemberInfo.IsFamily { + get { return false; } + } + + bool IDebugMemberInfo.IsPrivate { + get { return this.IsNotPublic; } + } + + bool IDebugMemberInfo.IsStatic { + get { return false; } + } + + public static DebugType CreateFromTypeDefOrRef(Module module, bool? valueType, uint token, DebugType[] genericArguments) + { + CorTokenType tkType = (CorTokenType)(token & 0xFF000000); + if (tkType == CorTokenType.TypeDef) { + ICorDebugClass corClass = module.CorModule.GetClassFromToken(token); + return CreateFromCorClass(module.AppDomain, valueType, corClass, genericArguments); + } else if (tkType == CorTokenType.TypeRef) { + TypeRefProps refProps = module.MetaData.GetTypeRefProps(token); + string fullName = refProps.Name; + CorTokenType scopeType = (CorTokenType)(refProps.ResolutionScope & 0xFF000000); + DebugType enclosingType = null; + if (scopeType == CorTokenType.TypeDef || scopeType == CorTokenType.TypeRef) { + // Resolve the enclosing TypeRef in this scope + enclosingType = CreateFromTypeDefOrRef(module, null, refProps.ResolutionScope, genericArguments); + } + return CreateFromName(module.AppDomain, fullName, enclosingType, genericArguments); + } else { + throw new DebuggerException("TypeDef or TypeRef expected. Seen " + tkType); + } + } + + public static DebugType CreateFromType(Module module, System.Type type) + { + if (type is DebugType) + throw new DebuggerException("You already have DebugType, no need to create it."); + if (type.GetGenericArguments().Length > 0) + throw new DebuggerException("Generic arguments not allowed in this overload"); + + if (module.LoadedDebugTypes.ContainsKey(type.FullName)) + return module.LoadedDebugTypes[type.FullName]; + + DebugType declaringType = null; + if (type.DeclaringType != null) + declaringType = CreateFromType(module, type.DeclaringType); + + return CreateFromName(module, type.FullName, declaringType); + } + + public static DebugType CreateFromType(AppDomain appDomain, System.Type type, params DebugType[] genericArgumentsOverride) + { + if (type is DebugType) + throw new DebuggerException("You already have DebugType, no need to create it."); + + // Get generic arguments for the type if they are not explicitely defined + if (genericArgumentsOverride == null) { + List genArgs = new List(); + foreach(System.Type arg in type.GetGenericArguments()) { + genArgs.Add(CreateFromType(appDomain, arg, null /* implicit */)); + } + genericArgumentsOverride = genArgs.ToArray(); + } + + string name; + DebugType declaringType; + if (type.DeclaringType != null) { + name = type.Name; + declaringType = CreateFromType(appDomain, type.DeclaringType, genericArgumentsOverride); + } else { + name = string.IsNullOrEmpty(type.Namespace) ? type.Name : type.Namespace + "." + type.Name; + declaringType = null; + } + + return CreateFromName(appDomain, name, declaringType, genericArgumentsOverride); + } + + public static DebugType CreateFromName(AppDomain appDomain, string name, DebugType declaringType, params DebugType[] genericArguments) + { + DebugType type = CreateFromNameOrNull(appDomain, name, declaringType, genericArguments); + if (type == null) + throw new DebuggerException("Type not found: " + name + (declaringType != null ? " (declaring type = " + declaringType.FullName + ")" : string.Empty)); + return type; + } + + public static DebugType CreateFromNameOrNull(AppDomain appDomain, string name, DebugType declaringType, params DebugType[] genericArguments) + { + if (declaringType != null) + return CreateFromNameOrNull(declaringType.DebugModule, name, declaringType, genericArguments); + foreach(Module module in appDomain.Process.Modules) { + if (module.AppDomain != appDomain) continue; + DebugType result = CreateFromNameOrNull(module, name, declaringType, genericArguments); + if (result != null) + return result; + } + return null; + } + + public static DebugType CreateFromName(Module module, string name, DebugType declaringType, params DebugType[] genericArguments) + { + DebugType type = CreateFromNameOrNull(module, name, declaringType, genericArguments); + if (type == null) + throw new DebuggerException("Type not found: " + name + (declaringType != null ? " (declaring type = " + declaringType.FullName + ")" : string.Empty)); + return type; + } + + public static DebugType CreateFromNameOrNull(Module module, string name, DebugType declaringType, params DebugType[] genericArguments) + { + if (declaringType != null && declaringType.DebugModule != module) + throw new DebuggerException("Declaring type must be in the same module"); + + uint token; + try { + token = module.MetaData.FindTypeDefPropsByName(name, declaringType == null ? 0 : (uint)declaringType.MetadataToken).Token; + } catch { + return null; + } + return CreateFromTypeDefOrRef(module, null, token, genericArguments); + } + + public static DebugType CreateFromTypeSpec(Module module, uint token, DebugType declaringType) + { + CorTokenType tokenType = (CorTokenType)(token & 0xFF000000); + if (tokenType != CorTokenType.TypeSpec) { + throw new DebuggerException("TypeSpec expected. Seen " + tokenType); + } + + byte[] typeSpecBlob = module.MetaData.GetTypeSpecFromToken(token).GetData(); + return CreateFromSignature(module, typeSpecBlob, declaringType); + } + + public static DebugType CreateFromSignature(Module module, byte[] signature, DebugType declaringType) + { + SignatureReader sigReader = new SignatureReader(signature); + int start; + SigType sigType = sigReader.ReadType(signature, 0, out start); + return CreateFromSignature(module, sigType, declaringType); + } + + internal static DebugType CreateFromSignature(Module module, SigType sigType, DebugType declaringType) + { + System.Type sysType = CorElementTypeToManagedType((CorElementType)(uint)sigType.ElementType); + if (sysType != null) + return CreateFromType(module.AppDomain.Mscorlib, sysType); + + if (sigType is CLASS) { + return CreateFromTypeDefOrRef(module, false, ((CLASS)sigType).Type.ToUInt(), null); + } + + if (sigType is VALUETYPE) { + return CreateFromTypeDefOrRef(module, true, ((VALUETYPE)sigType).Type.ToUInt(), null); + } + + // Numbered generic reference + if (sigType is VAR) { + if (declaringType == null) throw new DebuggerException("declaringType is needed"); + return (DebugType)declaringType.GetGenericArguments()[((VAR)sigType).Index]; + } + + // Numbered generic reference + if (sigType is MVAR) { + return module.AppDomain.ObjectType; + } + + if (sigType is GENERICINST) { + GENERICINST genInst = (GENERICINST)sigType; + + List genArgs = new List(genInst.Signature.Arity); + foreach(GenericArg genArgSig in genInst.Signature.Types) { + genArgs.Add(CreateFromSignature(module, genArgSig.Type, declaringType)); + } + + return CreateFromTypeDefOrRef(module, genInst.ValueType, genInst.Type.ToUInt(), genArgs.ToArray()); + } + + if (sigType is ARRAY) { + ARRAY arraySig = (ARRAY)sigType; + DebugType elementType = CreateFromSignature(module, arraySig.Type, declaringType); + return (DebugType)elementType.MakeArrayType(arraySig.Shape.Rank); + } + + if (sigType is SZARRAY) { + SZARRAY arraySig = (SZARRAY)sigType; + DebugType elementType = CreateFromSignature(module, arraySig.Type, declaringType); + return (DebugType)elementType.MakeArrayType(); + } + + if (sigType is PTR) { + PTR ptrSig = (PTR)sigType; + DebugType elementType; + if (ptrSig.Void) { + elementType = DebugType.CreateFromType(module.AppDomain.Mscorlib, typeof(void)); + } else { + elementType = CreateFromSignature(module, ptrSig.PtrType, declaringType); + } + return (DebugType)elementType.MakePointerType(); + } + + if (sigType is FNPTR) { + // TODO: FNPTR + } + + throw new NotImplementedException(sigType.ElementType.ToString()); + } + + // public virtual Type MakeGenericType(params Type[] typeArguments); + + /// + public override Type MakeArrayType(int rank) + { + ICorDebugType res = this.AppDomain.CorAppDomain2.GetArrayOrPointerType((uint)CorElementType.ARRAY, (uint)rank, this.CorType); + return CreateFromCorType(this.AppDomain, res); + } + + /// + public override Type MakeArrayType() + { + ICorDebugType res = this.AppDomain.CorAppDomain2.GetArrayOrPointerType((uint)CorElementType.SZARRAY, 1, this.CorType); + return CreateFromCorType(this.AppDomain, res); + } + + /// + public override Type MakePointerType() + { + ICorDebugType res = this.AppDomain.CorAppDomain2.GetArrayOrPointerType((uint)CorElementType.PTR, 0, this.CorType); + return CreateFromCorType(this.AppDomain, res); + } + + /// + public override Type MakeByRefType() + { + ICorDebugType res = this.AppDomain.CorAppDomain2.GetArrayOrPointerType((uint)CorElementType.BYREF, 0, this.CorType); + return CreateFromCorType(this.AppDomain, res); + } + + public static DebugType CreateFromCorClass(AppDomain appDomain, bool? valueType, ICorDebugClass corClass, DebugType[] genericArguments) + { + MetaDataImport metaData = appDomain.Process.Modules[corClass.GetModule()].MetaData; + + if (valueType == null) { + uint superClassToken = metaData.GetTypeDefProps(corClass.GetToken()).SuperClassToken; + CorTokenType tkType = (CorTokenType)(superClassToken & 0xFF000000); + if (tkType == CorTokenType.TypeDef) { + valueType = metaData.GetTypeDefProps(superClassToken).Name == typeof(ValueType).FullName; + } + if (tkType == CorTokenType.TypeRef) { + valueType = metaData.GetTypeRefProps(superClassToken).Name == typeof(ValueType).FullName; + } + if (tkType == CorTokenType.TypeSpec) { + valueType = false; // TODO: Resolve properly + } + } + + genericArguments = genericArguments ?? new DebugType[] {}; + if (genericArguments.Length < metaData.EnumGenericParams(corClass.GetToken()).Length) { + throw new DebuggerException("Not enough generic arguments"); + } + Array.Resize(ref genericArguments, metaData.EnumGenericParams(corClass.GetToken()).Length); + + List corGenArgs = new List(genericArguments.Length); + foreach(DebugType genAgr in genericArguments) { + corGenArgs.Add(genAgr.CorType); + } + + ICorDebugType corType = ((ICorDebugClass2)corClass).GetParameterizedType((uint)(valueType.Value ? CorElementType.VALUETYPE : CorElementType.CLASS), corGenArgs.ToArray()); + + return CreateFromCorType(appDomain, corType); + } + + /// Obtains instance of DebugType. Same types will return identical instance. + public static DebugType CreateFromCorType(AppDomain appDomain, ICorDebugType corType) + { + if (appDomain.DebugTypeCache.ContainsKey(corType)) + return appDomain.DebugTypeCache[corType]; + + // Convert short-form to class-form + Type primitiveType = CorElementTypeToManagedType((CorElementType)(corType.GetTheType())); + if (primitiveType != null) { + DebugType type = CreateFromType(appDomain.Mscorlib, primitiveType); + // Use cache next time + appDomain.DebugTypeCache[corType] = type; + return type; + } else { + DebugType type = new DebugType(appDomain, corType); + // Ensure name-identity + if (type.DebugModule.LoadedDebugTypes.ContainsKey(type.FullName)) { + type = type.DebugModule.LoadedDebugTypes[type.FullName]; + // corDebug cache needs to be fixed to this type - we do not want the semi-loaded type there + appDomain.DebugTypeCache[corType] = type; + } else { + type.LoadMembers(); + type.DebugModule.LoadedDebugTypes[type.FullName] = type; + } + return type; + } + } + + DebugType(AppDomain appDomain, ICorDebugType corType) + { + if (corType == null) + throw new ArgumentNullException("corType"); + + this.corType = corType; + this.corElementType = (CorElementType)corType.GetTheType(); + + // Loading might access the type again + appDomain.DebugTypeCache[corType] = this; + + if (corElementType == CorElementType.ARRAY || + corElementType == CorElementType.SZARRAY || + corElementType == CorElementType.PTR || + corElementType == CorElementType.BYREF) + { + // CorDebugClass for arrays "is not loaded" and can not be used + this.elementType = CreateFromCorType(appDomain, corType.GetFirstTypeParameter()); + this.module = appDomain.Mscorlib; + this.classProps = new TypeDefProps(); + // Get names + string suffix = string.Empty; + if (corElementType == CorElementType.SZARRAY) suffix = "[]"; + if (corElementType == CorElementType.ARRAY) suffix = "[" + new String(',', GetArrayRank() - 1) + "]"; + if (corElementType == CorElementType.PTR) suffix = "*"; + if (corElementType == CorElementType.BYREF) suffix = "&"; + this.ns = this.GetElementType().Namespace; + this.name = this.GetElementType().Name + suffix; + this.fullNameWithoutGenericArguments = ((DebugType)this.GetElementType()).FullNameWithoutGenericArguments + suffix; + this.fullName = this.GetElementType().FullName + suffix; + } + + if (corElementType == CorElementType.CLASS || + corElementType == CorElementType.VALUETYPE) + { + // Get generic arguments + foreach(ICorDebugType t in corType.EnumerateTypeParameters().GetEnumerator()) { + genericArguments.Add(DebugType.CreateFromCorType(appDomain, t)); + } + // Get class props + this.module = appDomain.Process.Modules[corType.GetClass().GetModule()]; + this.classProps = module.MetaData.GetTypeDefProps(corType.GetClass().GetToken()); + if (this.DebugModule.AppDomain != appDomain) + throw new DebuggerException("The specified AppDomain was inccorect"); + // Get the enclosing class + if (!this.IsPublic && !this.IsNotPublic) { + uint enclosingTk = module.MetaData.GetNestedClassProps((uint)this.MetadataToken).EnclosingClass; + this.declaringType = DebugType.CreateFromTypeDefOrRef(this.DebugModule, null, enclosingTk, genericArguments.ToArray()); + } + // Get names (it depends on the previous steps) + int index = classProps.Name.LastIndexOf('.'); + if (index == -1) { + this.ns = string.Empty; + this.name = classProps.Name; + } else { + this.ns = classProps.Name.Substring(0, index); + this.name = classProps.Name.Substring(index + 1); + } + LoadFullName(); + this.primitiveType = GetPrimitiveType(this.FullName); + } + + if (module == null) + throw new DebuggerException("Unexpected: " + corElementType); + } + + internal static Type CorElementTypeToManagedType(CorElementType corElementType) + { + switch(corElementType) { + case CorElementType.BOOLEAN: return typeof(System.Boolean); + case CorElementType.CHAR: return typeof(System.Char); + case CorElementType.I1: return typeof(System.SByte); + case CorElementType.U1: return typeof(System.Byte); + case CorElementType.I2: return typeof(System.Int16); + case CorElementType.U2: return typeof(System.UInt16); + case CorElementType.I4: return typeof(System.Int32); + case CorElementType.U4: return typeof(System.UInt32); + case CorElementType.I8: return typeof(System.Int64); + case CorElementType.U8: return typeof(System.UInt64); + case CorElementType.R4: return typeof(System.Single); + case CorElementType.R8: return typeof(System.Double); + case CorElementType.I: return typeof(System.IntPtr); + case CorElementType.U: return typeof(System.UIntPtr); + case CorElementType.STRING: return typeof(System.String); + case CorElementType.OBJECT: return typeof(System.Object); + case CorElementType.VOID: return typeof(void); + default: return null; + } + } + + static Type GetPrimitiveType(string fullname) + { + switch (fullname) { + case "System.Boolean": return typeof(System.Boolean); + case "System.Char": return typeof(System.Char); + case "System.SByte": return typeof(System.SByte); + case "System.Byte": return typeof(System.Byte); + case "System.Int16": return typeof(System.Int16); + case "System.UInt16": return typeof(System.UInt16); + case "System.Int32": return typeof(System.Int32); + case "System.UInt32": return typeof(System.UInt32); + case "System.Int64": return typeof(System.Int64); + case "System.UInt64": return typeof(System.UInt64); + case "System.Single": return typeof(System.Single); + case "System.Double": return typeof(System.Double); + // String is not primitive type + default: return null; + } + } + + void LoadFullName() + { + StringBuilder sb = new StringBuilder(); + + if (declaringType != null) { + sb.Append(declaringType.FullNameWithoutGenericArguments); + sb.Append('+'); + } + + // '`' might be missing in nested generic classes + sb.Append(classProps.Name); + + this.fullNameWithoutGenericArguments = sb.ToString(); + + if (this.GetGenericArguments().Length > 0) { + sb.Append("["); + bool first = true; + foreach(DebugType arg in this.GetGenericArguments()) { + if (!first) + sb.Append(","); + first = false; + sb.Append(arg.FullName); + } + sb.Append("]"); + } + + this.fullName = sb.ToString(); + } + + void LoadMembers() + { + System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); + + if (corElementType == CorElementType.ARRAY || corElementType == CorElementType.SZARRAY) { + // Arrays are special and normal loading does not work for them + DebugType iList = DebugType.CreateFromName(this.AppDomain.Mscorlib, typeof(IList<>).FullName, null, new DebugType[] { (DebugType)this.GetElementType() }); + this.interfaces.Add(iList); + this.interfaces.AddRange(iList.interfaces); + } else { + // Load interfaces + foreach(InterfaceImplProps implProps in module.MetaData.EnumInterfaceImplProps((uint)this.MetadataToken)) { + CorTokenType tkType = (CorTokenType)(implProps.Interface & 0xFF000000); + if (tkType == CorTokenType.TypeDef || tkType == CorTokenType.TypeRef) { + // TODO: Fix properly + try { + this.interfaces.Add(DebugType.CreateFromTypeDefOrRef(module, false, implProps.Interface, null)); + } catch (DebuggerException) { + } + } else if (tkType == CorTokenType.TypeSpec) { + this.interfaces.Add(DebugType.CreateFromTypeSpec(module, implProps.Interface, this)); + } else { + throw new DebuggerException("Uknown token type for interface: " + tkType); + } + } + + // Load fields + foreach(FieldProps field in module.MetaData.EnumFieldProps((uint)this.MetadataToken)) { + DebugFieldInfo fieldInfo = new DebugFieldInfo(this, field); + AddMember(fieldInfo); + }; + + // Load methods + foreach(MethodProps m in module.MetaData.EnumMethodProps((uint)this.MetadataToken)) { + AddMember(new DebugMethodInfo(this, m)); + } + + // Load properties + foreach(PropertyProps prop in module.MetaData.EnumPropertyProps((uint)this.MetadataToken)) { + DebugPropertyInfo propInfo = new DebugPropertyInfo( + this, + prop.Name, + prop.GetterMethod != 0x06000000 ? GetMethod(prop.GetterMethod) : null, + prop.SetterMethod != 0x06000000 ? GetMethod(prop.SetterMethod) : null + ); + if (propInfo.GetGetMethod() != null) + ((DebugMethodInfo)propInfo.GetGetMethod()).IsPropertyAccessor = true; + if (propInfo.GetSetMethod() != null) + ((DebugMethodInfo)propInfo.GetSetMethod()).IsPropertyAccessor = true; + AddMember(propInfo); + } + } + + if (this.Process.Options.Verbose) + this.Process.TraceMessage("Loaded {0} ({1} ms)", this.FullName, stopwatch.ElapsedMilliseconds); + + // Load base type + Type baseType = this.BaseType; + + // Add base type's inerfaces + if (baseType != null) { + foreach (DebugType debugType in baseType.GetInterfaces()) { + if (!this.interfaces.Contains(debugType)) { + this.interfaces.Add(debugType); + } + } + } + } + + void AddMember(MemberInfo member) + { + if (!membersByName.ContainsKey(member.Name)) + membersByName.Add(member.Name, new List(1)); + membersByName[member.Name].Add(member); + membersByToken[member.MetadataToken] = member; + } + + public override bool Equals(object o) + { + DebugType other = o as DebugType; + if (other == null) + return false; + return this.MetadataToken == other.MetadataToken && // Performance optimization + this.DebugModule == other.DebugModule && + this.FullName == other.FullName; + } + + public override int GetHashCode() + { + return this.FullName.GetHashCode(); + } + + public static bool operator == (DebugType a, DebugType b) + { + if ((object)a == (object)b) + return true; + if (((object)a == null) || ((object)b == null)) + return false; + return a.Equals(b); + } + + public static bool operator != (DebugType a, DebugType b) + { + return !(a == b); + } + + /// + public override string ToString() + { + return this.FullName; + } + + DebugType IDebugMemberInfo.MemberType { + get { return null; } + } + } +} diff --git a/Debugger/Debugger.Core/MetaData/IDebugMemberInfo.cs b/Debugger/Debugger.Core/MetaData/IDebugMemberInfo.cs new file mode 100644 index 000000000..33cdf130c --- /dev/null +++ b/Debugger/Debugger.Core/MetaData/IDebugMemberInfo.cs @@ -0,0 +1,21 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Debugger.MetaData +{ + public interface IDebugMemberInfo + { + Type DeclaringType { get; } + Module DebugModule { get; } + string Name { get; } + int MetadataToken { get; } + bool IsStatic { get; } + bool IsPublic { get; } + bool IsAssembly { get; } + bool IsFamily { get; } + bool IsPrivate { get; } + DebugType MemberType { get; } + } +} diff --git a/Debugger/Debugger.Core/MetaData/IOverloadable.cs b/Debugger/Debugger.Core/MetaData/IOverloadable.cs new file mode 100644 index 000000000..357651b79 --- /dev/null +++ b/Debugger/Debugger.Core/MetaData/IOverloadable.cs @@ -0,0 +1,14 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Reflection; + +namespace Debugger.MetaData +{ + interface IOverloadable + { + ParameterInfo[] GetParameters(); + IntPtr GetSignarture(); + } +} diff --git a/Debugger/Debugger.Core/Module.cs b/Debugger/Debugger.Core/Module.cs new file mode 100644 index 000000000..193f5b781 --- /dev/null +++ b/Debugger/Debugger.Core/Module.cs @@ -0,0 +1,408 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +using Debugger.Interop; +using Debugger.Interop.CorDebug; +using Debugger.Interop.CorSym; +using Debugger.Interop.MetaData; +using Debugger.MetaData; + +namespace Debugger +{ + public class Module: DebuggerObject, IDisposable + { + AppDomain appDomain; + Process process; + + bool unloaded = false; + string name; + string fullPath = string.Empty; + + int orderOfLoading = 0; + ICorDebugModule corModule; + ISymUnmanagedReader symReader; + MetaDataImport metaData; + + internal Dictionary LoadedDebugTypes = new Dictionary(); + + /// + /// Occurs when symbols are loaded or unloaded (for memory modules) + /// + public event EventHandler SymbolsUpdated; + + public AppDomain AppDomain { + get { return appDomain; } + } + + public Process Process { + get { return process; } + } + + NDebugger Debugger { + get { return this.AppDomain.Process.Debugger; } + } + + [Debugger.Tests.Ignore] + public MetaDataImport MetaData { + get { + return metaData; + } + } + + public bool Unloaded { + get { + return unloaded; + } + } + + [Debugger.Tests.Ignore] + public ISymUnmanagedReader SymReader { + get { + return symReader; + } + } + + [Debugger.Tests.Ignore] + public ISymUnmanagedDocument[] SymDocuments { + get { + ISymUnmanagedDocument[] docs; + uint maxCount = 2; + uint fetched; + do { + maxCount *= 8; + docs = new ISymUnmanagedDocument[maxCount]; + symReader.GetDocuments(maxCount, out fetched, docs); + } while (fetched == maxCount); + Array.Resize(ref docs, (int)fetched); + return docs; + } + } + + [Debugger.Tests.Ignore] + public ICorDebugModule CorModule { + get { return corModule; } + } + + [Debugger.Tests.Ignore] + public ICorDebugModule2 CorModule2 { + get { return (ICorDebugModule2)corModule; } + } + + [Debugger.Tests.Ignore] + public ulong BaseAdress { + get { + return this.CorModule.GetBaseAddress(); + } + } + + public bool IsDynamic { + get { + return this.CorModule.IsDynamic() == 1; + } + } + + public bool IsInMemory { + get { + return this.CorModule.IsInMemory() == 1; + } + } + + internal uint AppDomainID { + get { + return this.CorModule.GetAssembly().GetAppDomain().GetID(); + } + } + + public string Name { + get { + return name; + } + } + + [Debugger.Tests.Ignore] + public string FullPath { + get { + return fullPath; + } + } + + public bool HasSymbols { + get { + return symReader != null; + } + } + + public int OrderOfLoading { + get { + return orderOfLoading; + } + set { + orderOfLoading = value; + } + } + + [Debugger.Tests.Ignore] + public CorDebugJITCompilerFlags JITCompilerFlags + { + get + { + uint retval = ((ICorDebugModule2)corModule).GetJITCompilerFlags(); + return (CorDebugJITCompilerFlags)retval; + } + set + { + // ICorDebugModule2.SetJITCompilerFlags can return successful HRESULTS other than S_OK. + // Since we have asked the COMInterop layer to preservesig, we need to marshal any failing HRESULTS. + ((ICorDebugModule2)corModule).SetJITCompilerFlags((uint)value); + } + } + + /// Returns all non-generic types defined in the module + /// Generic types can not be returned, because we do not know how to instanciate them + public List GetDefinedTypes() + { + List types = new List(); + foreach(TypeDefProps typeDef in this.MetaData.EnumTypeDefProps()) { + if (this.MetaData.EnumGenericParams(typeDef.Token).Length == 0) { + types.Add(DebugType.CreateFromTypeDefOrRef(this, null, typeDef.Token, null)); + } + } + return types; + } + + /// Get names of all generic and non-generic types defined in this module + public List GetNamesOfDefinedTypes() + { + List names = new List(); + foreach(TypeDefProps typeProps in this.MetaData.EnumTypeDefProps()) { + names.Add(typeProps.Name); + } + return names; + } + + internal Module(AppDomain appDomain, ICorDebugModule corModule) + { + this.appDomain = appDomain; + this.process = appDomain.Process; + this.corModule = corModule; + SetJITCompilerFlags(); + + metaData = new MetaDataImport(corModule); + + if (IsDynamic || IsInMemory) { + name = corModule.GetName(); + } else { + fullPath = corModule.GetName(); + name = System.IO.Path.GetFileName(FullPath); + } + + LoadSymbolsFromDisk(process.Options.SymbolsSearchPaths); + ResetJustMyCodeStatus(); + } + + public void UnloadSymbols() + { + if (symReader != null) { + // The interface is not always supported, I did not manage to reproduce it, but the + // last callbacks in the user's log were UnloadClass and UnloadModule so I guess + // it has something to do with dynamic modules. + if (symReader is ISymUnmanagedDispose) { + ((ISymUnmanagedDispose)symReader).Destroy(); + } + symReader = null; + } + } + + /// + /// Load symblos for on-disk module + /// + public void LoadSymbolsFromDisk(string[] searchPath) + { + if (!IsDynamic && !IsInMemory) { + if (symReader == null) { + symReader = metaData.GetSymReader(fullPath, string.Join("; ", searchPath ?? new string[0])); + if (symReader != null) { + process.TraceMessage("Loaded symbols from disk for " + this.Name); + OnSymbolsUpdated(); + } + } + } + } + + /// + /// Load symbols for in-memory module + /// + public void LoadSymbolsFromMemory(IStream pSymbolStream) + { + if (this.IsInMemory) { + UnloadSymbols(); + + symReader = metaData.GetSymReader(pSymbolStream); + if (symReader != null) { + process.TraceMessage("Loaded symbols from memory for " + this.Name); + } else { + process.TraceMessage("Failed to load symbols from memory"); + } + + OnSymbolsUpdated(); + } + } + + /// + /// Load symbols for dynamic module + /// (as of .NET 4.0) + /// + public void LoadSymbolsDynamic() + { + if (this.CorModule is ICorDebugModule3 && this.IsDynamic) { + Guid guid = new Guid(0, 0, 0, 0xc0, 0, 0, 0, 0, 0, 0, 70); + try { + symReader = (ISymUnmanagedReader)((ICorDebugModule3)this.CorModule).CreateReaderForInMemorySymbols(guid); + } catch (COMException e) { + // 0x80131C3B The application did not supply symbols when it loaded or created this module, or they are not yet available. + if ((uint)e.ErrorCode == 0x80131C3B) { + process.TraceMessage("Failed to load dynamic symbols for " + this.Name); + return; + } + throw; + } + TrackedComObjects.Track(symReader); + process.TraceMessage("Loaded dynamic symbols for " + this.Name); + OnSymbolsUpdated(); + } + } + + void OnSymbolsUpdated() + { + SetBreakpoints(); + ResetJustMyCodeStatus(); + if (SymbolsUpdated != null) { + SymbolsUpdated(this, new ModuleEventArgs(this)); + } + } + + void SetBreakpoints() + { + if (this.HasSymbols) { + // This is in case that the client modifies the collection as a response to set breakpoint + // NB: If client adds new breakpoint, it will be set directly as a result of his call, not here (because module is already loaded) + List collection = new List(); + collection.AddRange(this.Debugger.Breakpoints); + + foreach (Breakpoint b in collection) { + b.SetBreakpoint(this); + } + } + } + + void SetJITCompilerFlags() + { + if (Process.DebugMode != DebugModeFlag.Default) { + // translate DebugModeFlags to JITCompilerFlags + CorDebugJITCompilerFlags jcf = MapDebugModeToJITCompilerFlags(Process.DebugMode); + + try + { + this.JITCompilerFlags = jcf; + + // Flags may succeed but not set all bits, so requery. + CorDebugJITCompilerFlags jcfActual = this.JITCompilerFlags; + + #if DEBUG + if (jcf != jcfActual) + Console.WriteLine("Couldn't set all flags. Actual flags:" + jcfActual.ToString()); + else + Console.WriteLine("Actual flags:" + jcfActual.ToString()); + #endif + } + catch (COMException ex) + { + // we'll ignore the error if we cannot set the jit flags + Console.WriteLine(string.Format("Failed to set flags with hr=0x{0:x}", ex.ErrorCode)); + } + } + } + + /// Sets all code as being 'my code'. The code will be gradually + /// set to not-user-code as encountered acording to stepping options + public void ResetJustMyCodeStatus() + { + uint unused = 0; + if (process.Options.StepOverNoSymbols && !this.HasSymbols) { + // Optimization - set the code as non-user right away + this.CorModule2.SetJMCStatus(0, 0, ref unused); + return; + } + try { + this.CorModule2.SetJMCStatus(1, 0, ref unused); + } catch (COMException e) { + // Cannot use JMC on this code (likely wrong JIT settings). + if ((uint)e.ErrorCode == 0x80131323) { + process.TraceMessage("Cannot use JMC on this code. Release build?"); + return; + } + throw; + } + } + + public void ApplyChanges(byte[] metadata, byte[] il) + { + this.CorModule2.ApplyChanges((uint)metadata.Length, metadata, (uint)il.Length, il); + } + + public void Dispose() + { + UnloadSymbols(); + unloaded = true; + } + + public override string ToString() + { + return string.Format("{0}", this.Name); + } + + public static CorDebugJITCompilerFlags MapDebugModeToJITCompilerFlags(DebugModeFlag debugMode) + { + CorDebugJITCompilerFlags jcf; + switch (debugMode) + { + case DebugModeFlag.Optimized: + jcf = CorDebugJITCompilerFlags.CORDEBUG_JIT_DEFAULT; // DEFAULT really means force optimized. + break; + case DebugModeFlag.Debug: + jcf = CorDebugJITCompilerFlags.CORDEBUG_JIT_DISABLE_OPTIMIZATION; + break; + case DebugModeFlag.Enc: + jcf = CorDebugJITCompilerFlags.CORDEBUG_JIT_ENABLE_ENC; + break; + default: + // we don't have mapping from default to "default", + // therefore we'll use DISABLE_OPTIMIZATION. + jcf = CorDebugJITCompilerFlags.CORDEBUG_JIT_DISABLE_OPTIMIZATION; + break; + } + return jcf; + } + } + + [Serializable] + public class ModuleEventArgs : ProcessEventArgs + { + Module module; + + public Module Module { + get { + return module; + } + } + + public ModuleEventArgs(Module module): base(module.Process) + { + this.module = module; + } + } +} diff --git a/Debugger/Debugger.Core/ModuleCollection.cs b/Debugger/Debugger.Core/ModuleCollection.cs new file mode 100644 index 000000000..d01fd53af --- /dev/null +++ b/Debugger/Debugger.Core/ModuleCollection.cs @@ -0,0 +1,50 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public class ModuleCollection: CollectionWithEvents + { + public ModuleCollection(NDebugger debugger):base (debugger) {} + + int lastAssignedModuleOrderOfLoading = 0; + + public Module this[string filename] { + get { + foreach(Module module in this) { + if (module.Name == filename) { + return module; + } + } + throw new DebuggerException("Module \"" + filename + "\" is not in collection"); + } + } + + internal Module this[ICorDebugModule corModule] { + get { + foreach(Module module in this) { + if (module.CorModule == corModule) { + return module; + } + } + throw new DebuggerException("Module is not in collection"); + } + } + + protected override void OnAdded(Module module) + { + module.OrderOfLoading = lastAssignedModuleOrderOfLoading; + lastAssignedModuleOrderOfLoading++; + base.OnAdded(module); + } + + protected override void OnRemoved(Module module) + { + base.OnRemoved(module); + module.Dispose(); + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Binary/ImageFormatException.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Binary/ImageFormatException.cs new file mode 100644 index 000000000..1592233f3 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Binary/ImageFormatException.cs @@ -0,0 +1,53 @@ +// +// ImageFormatException.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Binary { + + using System; + + public class ImageFormatException : Exception { + + internal ImageFormatException () : base() + { + } + + internal ImageFormatException (string message) : base(message) + { + } + + internal ImageFormatException (string message, params string[] parameters) : + base(string.Format(message, parameters)) + { + } + + internal ImageFormatException (string message, Exception inner) : + base(message, inner) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/CodedIndex.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/CodedIndex.cs new file mode 100644 index 000000000..2cf557825 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/CodedIndex.cs @@ -0,0 +1,49 @@ +// +// CodedIndex.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Generated by /CodeGen/cecil-gen.rb do not edit +// Tue Mar 20 16:02:16 +0100 2007 +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Metadata { + + public enum CodedIndex { + TypeDefOrRef, + HasConstant, + HasCustomAttribute, + HasFieldMarshal, + HasDeclSecurity, + MemberRefParent, + HasSemantics, + MethodDefOrRef, + MemberForwarded, + Implementation, + CustomAttributeType, + ResolutionScope, + TypeOrMethodDef + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/ElementType.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/ElementType.cs new file mode 100644 index 000000000..4d78f435f --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/ElementType.cs @@ -0,0 +1,73 @@ +// +// ElementType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Metadata { + + public enum ElementType { + End = 0x00, // Marks end of a list + Void = 0x01, + Boolean = 0x02, + Char = 0x03, + I1 = 0x04, + U1 = 0x05, + I2 = 0x06, + U2 = 0x07, + I4 = 0x08, + U4 = 0x09, + I8 = 0x0a, + U8 = 0x0b, + R4 = 0x0c, + R8 = 0x0d, + String = 0x0e, + Ptr = 0x0f, // Followed by token + ByRef = 0x10, // Followed by token + ValueType = 0x11, // Followed by token + Class = 0x12, // Followed by token + Var = 0x13, // Followed by generic parameter number + Array = 0x14, // + GenericInst = 0x15, // ... */ + TypedByRef = 0x16, + I = 0x18, // System.IntPtr + U = 0x19, // System.UIntPtr + FnPtr = 0x1b, // Followed by full method signature + Object = 0x1c, // System.Object + SzArray = 0x1d, // Single-dim array with 0 lower bound + MVar = 0x1e, // Followed by generic parameter number + CModReqD = 0x1f, // Required modifier : followed by a TypeDef or TypeRef token + CModOpt = 0x20, // Optional modifier : followed by a TypeDef or TypeRef token + Internal = 0x21, // Implemented within the CLI + Modifier = 0x40, // Or'd with following element types + Sentinel = 0x41, // Sentinel for varargs method signature + Pinned = 0x45, // Denotes a local variable that points at a pinned object + + // special undocumented constants + Type = 0x50, + Boxed = 0x51, + Enum = 0x55 + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/MetadataFormatException.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/MetadataFormatException.cs new file mode 100644 index 000000000..dd917905f --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/MetadataFormatException.cs @@ -0,0 +1,55 @@ +// +// MetadataFormatException.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Metadata { + + using System; + + using Mono.Cecil.Binary; + + public class MetadataFormatException : ImageFormatException { + + internal MetadataFormatException () : base () + { + } + + internal MetadataFormatException (string message) : base (message) + { + } + + internal MetadataFormatException (string message, params string [] parameters) : + base (string.Format (message, parameters)) + { + } + + internal MetadataFormatException (string message, Exception inner) : + base (message, inner) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/MetadataToken.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/MetadataToken.cs new file mode 100644 index 000000000..d584fedf4 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/MetadataToken.cs @@ -0,0 +1,99 @@ +// +// MetadataToken.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Metadata { + + public struct MetadataToken { + + uint m_rid; + TokenType m_type; + + public uint RID { + get { return m_rid; } + } + + public TokenType TokenType { + get { return m_type; } + } + + public static readonly MetadataToken Zero = new MetadataToken ((TokenType) 0, 0); + + public MetadataToken (int token) + { + m_type = (TokenType) (token & 0xff000000); + m_rid = (uint) token & 0x00ffffff; + } + + public MetadataToken (TokenType table, uint rid) + { + m_type = table; + m_rid = rid; + } + + internal static MetadataToken FromMetadataRow (TokenType table, int rowIndex) + { + return new MetadataToken (table, (uint) rowIndex + 1); + } + + public uint ToUInt () + { + return (uint) m_type | m_rid; + } + + public override int GetHashCode () + { + return (int) ToUInt (); + } + + public override bool Equals (object other) + { + if (other is MetadataToken) { + MetadataToken o = (MetadataToken) other; + return o.m_rid == m_rid && o.m_type == m_type; + } + + return false; + } + + public static bool operator == (MetadataToken one, MetadataToken other) + { + return one.Equals (other); + } + + public static bool operator != (MetadataToken one, MetadataToken other) + { + return !one.Equals (other); + } + + public override string ToString () + { + return string.Format ("{0} [0x{1}]", + m_type, m_rid.ToString ("x4")); + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/TokenType.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/TokenType.cs new file mode 100644 index 000000000..44de8042f --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/TokenType.cs @@ -0,0 +1,58 @@ +// +// TokenType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Metadata { + + public enum TokenType : uint { + Module = 0x00000000, + TypeRef = 0x01000000, + TypeDef = 0x02000000, + Field = 0x04000000, + Method = 0x06000000, + Param = 0x08000000, + InterfaceImpl = 0x09000000, + MemberRef = 0x0a000000, + CustomAttribute = 0x0c000000, + Permission = 0x0e000000, + Signature = 0x11000000, + Event = 0x14000000, + Property = 0x17000000, + ModuleRef = 0x1a000000, + TypeSpec = 0x1b000000, + Assembly = 0x20000000, + AssemblyRef = 0x23000000, + File = 0x26000000, + ExportedType = 0x27000000, + ManifestResource = 0x28000000, + GenericParam = 0x2a000000, + MethodSpec = 0x2b000000, + String = 0x70000000, + Name = 0x71000000, + BaseType = 0x72000000 + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/Utilities.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/Utilities.cs new file mode 100644 index 000000000..1acc1217a --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Metadata/Utilities.cs @@ -0,0 +1,649 @@ +// +// Utilities.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Generated by /CodeGen/cecil-gen.rb do not edit +// Tue Jul 17 00:22:33 +0200 2007 +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Metadata { + + using System; + using System.Collections; + using System.IO; + + class Utilities { + + Utilities () + { + } + + public static int ReadCompressedInteger (byte [] data, int pos, out int start) + { + int integer = 0; + start = pos; + if ((data [pos] & 0x80) == 0) { + integer = data [pos]; + start++; + } else if ((data [pos] & 0x40) == 0) { + integer = (data [start] & ~0x80) << 8; + integer |= data [pos + 1]; + start += 2; + } else { + integer = (data [start] & ~0xc0) << 24; + integer |= data [pos + 1] << 16; + integer |= data [pos + 2] << 8; + integer |= data [pos + 3]; + start += 4; + } + return integer; + } + + public static int WriteCompressedInteger (BinaryWriter writer, int value) + { + if (value < 0x80) + writer.Write ((byte) value); + else if (value < 0x4000) { + writer.Write ((byte) (0x80 | (value >> 8))); + writer.Write ((byte) (value & 0xff)); + } else { + writer.Write ((byte) ((value >> 24) | 0xc0)); + writer.Write ((byte) ((value >> 16) & 0xff)); + writer.Write ((byte) ((value >> 8) & 0xff)); + writer.Write ((byte) (value & 0xff)); + } + return (int) writer.BaseStream.Position; + } + + public static MetadataToken GetMetadataToken (CodedIndex cidx, uint data) + { + uint rid = 0; + switch (cidx) { + case CodedIndex.TypeDefOrRef : + rid = data >> 2; + switch (data & 3) { + case 0 : + return new MetadataToken (TokenType.TypeDef, rid); + case 1 : + return new MetadataToken (TokenType.TypeRef, rid); + case 2 : + return new MetadataToken (TokenType.TypeSpec, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.HasConstant : + rid = data >> 2; + switch (data & 3) { + case 0 : + return new MetadataToken (TokenType.Field, rid); + case 1 : + return new MetadataToken (TokenType.Param, rid); + case 2 : + return new MetadataToken (TokenType.Property, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.HasCustomAttribute : + rid = data >> 5; + switch (data & 31) { + case 0 : + return new MetadataToken (TokenType.Method, rid); + case 1 : + return new MetadataToken (TokenType.Field, rid); + case 2 : + return new MetadataToken (TokenType.TypeRef, rid); + case 3 : + return new MetadataToken (TokenType.TypeDef, rid); + case 4 : + return new MetadataToken (TokenType.Param, rid); + case 5 : + return new MetadataToken (TokenType.InterfaceImpl, rid); + case 6 : + return new MetadataToken (TokenType.MemberRef, rid); + case 7 : + return new MetadataToken (TokenType.Module, rid); + case 8 : + return new MetadataToken (TokenType.Permission, rid); + case 9 : + return new MetadataToken (TokenType.Property, rid); + case 10 : + return new MetadataToken (TokenType.Event, rid); + case 11 : + return new MetadataToken (TokenType.Signature, rid); + case 12 : + return new MetadataToken (TokenType.ModuleRef, rid); + case 13 : + return new MetadataToken (TokenType.TypeSpec, rid); + case 14 : + return new MetadataToken (TokenType.Assembly, rid); + case 15 : + return new MetadataToken (TokenType.AssemblyRef, rid); + case 16 : + return new MetadataToken (TokenType.File, rid); + case 17 : + return new MetadataToken (TokenType.ExportedType, rid); + case 18 : + return new MetadataToken (TokenType.ManifestResource, rid); + case 19 : + return new MetadataToken (TokenType.GenericParam, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.HasFieldMarshal : + rid = data >> 1; + switch (data & 1) { + case 0 : + return new MetadataToken (TokenType.Field, rid); + case 1 : + return new MetadataToken (TokenType.Param, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.HasDeclSecurity : + rid = data >> 2; + switch (data & 3) { + case 0 : + return new MetadataToken (TokenType.TypeDef, rid); + case 1 : + return new MetadataToken (TokenType.Method, rid); + case 2 : + return new MetadataToken (TokenType.Assembly, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.MemberRefParent : + rid = data >> 3; + switch (data & 7) { + case 0 : + return new MetadataToken (TokenType.TypeDef, rid); + case 1 : + return new MetadataToken (TokenType.TypeRef, rid); + case 2 : + return new MetadataToken (TokenType.ModuleRef, rid); + case 3 : + return new MetadataToken (TokenType.Method, rid); + case 4 : + return new MetadataToken (TokenType.TypeSpec, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.HasSemantics : + rid = data >> 1; + switch (data & 1) { + case 0 : + return new MetadataToken (TokenType.Event, rid); + case 1 : + return new MetadataToken (TokenType.Property, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.MethodDefOrRef : + rid = data >> 1; + switch (data & 1) { + case 0 : + return new MetadataToken (TokenType.Method, rid); + case 1 : + return new MetadataToken (TokenType.MemberRef, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.MemberForwarded : + rid = data >> 1; + switch (data & 1) { + case 0 : + return new MetadataToken (TokenType.Field, rid); + case 1 : + return new MetadataToken (TokenType.Method, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.Implementation : + rid = data >> 2; + switch (data & 3) { + case 0 : + return new MetadataToken (TokenType.File, rid); + case 1 : + return new MetadataToken (TokenType.AssemblyRef, rid); + case 2 : + return new MetadataToken (TokenType.ExportedType, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.CustomAttributeType : + rid = data >> 3; + switch (data & 7) { + case 2 : + return new MetadataToken (TokenType.Method, rid); + case 3 : + return new MetadataToken (TokenType.MemberRef, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.ResolutionScope : + rid = data >> 2; + switch (data & 3) { + case 0 : + return new MetadataToken (TokenType.Module, rid); + case 1 : + return new MetadataToken (TokenType.ModuleRef, rid); + case 2 : + return new MetadataToken (TokenType.AssemblyRef, rid); + case 3 : + return new MetadataToken (TokenType.TypeRef, rid); + default : + return MetadataToken.Zero; + } + case CodedIndex.TypeOrMethodDef : + rid = data >> 1; + switch (data & 1) { + case 0 : + return new MetadataToken (TokenType.TypeDef, rid); + case 1 : + return new MetadataToken (TokenType.Method, rid); + default : + return MetadataToken.Zero; + } + default : + return MetadataToken.Zero; + } + } + + public static uint CompressMetadataToken (CodedIndex cidx, MetadataToken token) + { + uint ret = 0; + if (token.RID == 0) + return ret; + switch (cidx) { + case CodedIndex.TypeDefOrRef : + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.TypeDef : + return ret | 0; + case TokenType.TypeRef : + return ret | 1; + case TokenType.TypeSpec : + return ret | 2; + default : + throw new MetadataFormatException("Non valid Token for TypeDefOrRef"); + } + case CodedIndex.HasConstant : + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.Field : + return ret | 0; + case TokenType.Param : + return ret | 1; + case TokenType.Property : + return ret | 2; + default : + throw new MetadataFormatException("Non valid Token for HasConstant"); + } + case CodedIndex.HasCustomAttribute : + ret = token.RID << 5; + switch (token.TokenType) { + case TokenType.Method : + return ret | 0; + case TokenType.Field : + return ret | 1; + case TokenType.TypeRef : + return ret | 2; + case TokenType.TypeDef : + return ret | 3; + case TokenType.Param : + return ret | 4; + case TokenType.InterfaceImpl : + return ret | 5; + case TokenType.MemberRef : + return ret | 6; + case TokenType.Module : + return ret | 7; + case TokenType.Permission : + return ret | 8; + case TokenType.Property : + return ret | 9; + case TokenType.Event : + return ret | 10; + case TokenType.Signature : + return ret | 11; + case TokenType.ModuleRef : + return ret | 12; + case TokenType.TypeSpec : + return ret | 13; + case TokenType.Assembly : + return ret | 14; + case TokenType.AssemblyRef : + return ret | 15; + case TokenType.File : + return ret | 16; + case TokenType.ExportedType : + return ret | 17; + case TokenType.ManifestResource : + return ret | 18; + case TokenType.GenericParam : + return ret | 19; + default : + throw new MetadataFormatException("Non valid Token for HasCustomAttribute"); + } + case CodedIndex.HasFieldMarshal : + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Field : + return ret | 0; + case TokenType.Param : + return ret | 1; + default : + throw new MetadataFormatException("Non valid Token for HasFieldMarshal"); + } + case CodedIndex.HasDeclSecurity : + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.TypeDef : + return ret | 0; + case TokenType.Method : + return ret | 1; + case TokenType.Assembly : + return ret | 2; + default : + throw new MetadataFormatException("Non valid Token for HasDeclSecurity"); + } + case CodedIndex.MemberRefParent : + ret = token.RID << 3; + switch (token.TokenType) { + case TokenType.TypeDef : + return ret | 0; + case TokenType.TypeRef : + return ret | 1; + case TokenType.ModuleRef : + return ret | 2; + case TokenType.Method : + return ret | 3; + case TokenType.TypeSpec : + return ret | 4; + default : + throw new MetadataFormatException("Non valid Token for MemberRefParent"); + } + case CodedIndex.HasSemantics : + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Event : + return ret | 0; + case TokenType.Property : + return ret | 1; + default : + throw new MetadataFormatException("Non valid Token for HasSemantics"); + } + case CodedIndex.MethodDefOrRef : + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Method : + return ret | 0; + case TokenType.MemberRef : + return ret | 1; + default : + throw new MetadataFormatException("Non valid Token for MethodDefOrRef"); + } + case CodedIndex.MemberForwarded : + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Field : + return ret | 0; + case TokenType.Method : + return ret | 1; + default : + throw new MetadataFormatException("Non valid Token for MemberForwarded"); + } + case CodedIndex.Implementation : + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.File : + return ret | 0; + case TokenType.AssemblyRef : + return ret | 1; + case TokenType.ExportedType : + return ret | 2; + default : + throw new MetadataFormatException("Non valid Token for Implementation"); + } + case CodedIndex.CustomAttributeType : + ret = token.RID << 3; + switch (token.TokenType) { + case TokenType.Method : + return ret | 2; + case TokenType.MemberRef : + return ret | 3; + default : + throw new MetadataFormatException("Non valid Token for CustomAttributeType"); + } + case CodedIndex.ResolutionScope : + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.Module : + return ret | 0; + case TokenType.ModuleRef : + return ret | 1; + case TokenType.AssemblyRef : + return ret | 2; + case TokenType.TypeRef : + return ret | 3; + default : + throw new MetadataFormatException("Non valid Token for ResolutionScope"); + } + case CodedIndex.TypeOrMethodDef : + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.TypeDef : + return ret | 0; + case TokenType.Method : + return ret | 1; + default : + throw new MetadataFormatException("Non valid Token for TypeOrMethodDef"); + } + default : + throw new MetadataFormatException ("Non valid CodedIndex"); + } + } + + /* + + internal static Type GetCorrespondingTable (TokenType t) + { + switch (t) { + case TokenType.Assembly : + return typeof (AssemblyTable); + case TokenType.AssemblyRef : + return typeof (AssemblyRefTable); + case TokenType.CustomAttribute : + return typeof (CustomAttributeTable); + case TokenType.Event : + return typeof (EventTable); + case TokenType.ExportedType : + return typeof (ExportedTypeTable); + case TokenType.Field : + return typeof (FieldTable); + case TokenType.File : + return typeof (FileTable); + case TokenType.InterfaceImpl : + return typeof (InterfaceImplTable); + case TokenType.MemberRef : + return typeof (MemberRefTable); + case TokenType.Method : + return typeof (MethodTable); + case TokenType.Module : + return typeof (ModuleTable); + case TokenType.ModuleRef : + return typeof (ModuleRefTable); + case TokenType.Param : + return typeof (ParamTable); + case TokenType.Permission : + return typeof (DeclSecurityTable); + case TokenType.Property : + return typeof (PropertyTable); + case TokenType.Signature : + return typeof (StandAloneSigTable); + case TokenType.TypeDef : + return typeof (TypeDefTable); + case TokenType.TypeRef : + return typeof (TypeRefTable); + case TokenType.TypeSpec : + return typeof (TypeSpecTable); + default : + return null; + } + } + + internal delegate int TableRowCounter (int rid); + + internal static int GetCodedIndexSize (CodedIndex ci, TableRowCounter rowCounter, IDictionary codedIndexCache) + { + int bits = 0, max = 0; + if (codedIndexCache [ci] != null) + return (int) codedIndexCache [ci]; + + int res = 0; + int [] rids; + switch (ci) { + case CodedIndex.TypeDefOrRef : + bits = 2; + rids = new int [3]; + rids [0] = TypeDefTable.RId; + rids [1] = TypeRefTable.RId; + rids [2] = TypeSpecTable.RId; + break; + case CodedIndex.HasConstant : + bits = 2; + rids = new int [3]; + rids [0] = FieldTable.RId; + rids [1] = ParamTable.RId; + rids [2] = PropertyTable.RId; + break; + case CodedIndex.HasCustomAttribute : + bits = 5; + rids = new int [20]; + rids [0] = MethodTable.RId; + rids [1] = FieldTable.RId; + rids [2] = TypeRefTable.RId; + rids [3] = TypeDefTable.RId; + rids [4] = ParamTable.RId; + rids [5] = InterfaceImplTable.RId; + rids [6] = MemberRefTable.RId; + rids [7] = ModuleTable.RId; + rids [8] = DeclSecurityTable.RId; + rids [9] = PropertyTable.RId; + rids [10] = EventTable.RId; + rids [11] = StandAloneSigTable.RId; + rids [12] = ModuleRefTable.RId; + rids [13] = TypeSpecTable.RId; + rids [14] = AssemblyTable.RId; + rids [15] = AssemblyRefTable.RId; + rids [16] = FileTable.RId; + rids [17] = ExportedTypeTable.RId; + rids [18] = ManifestResourceTable.RId; + rids [19] = GenericParamTable.RId; + break; + case CodedIndex.HasFieldMarshal : + bits = 1; + rids = new int [2]; + rids [0] = FieldTable.RId; + rids [1] = ParamTable.RId; + break; + case CodedIndex.HasDeclSecurity : + bits = 2; + rids = new int [3]; + rids [0] = TypeDefTable.RId; + rids [1] = MethodTable.RId; + rids [2] = AssemblyTable.RId; + break; + case CodedIndex.MemberRefParent : + bits = 3; + rids = new int [5]; + rids [0] = TypeDefTable.RId; + rids [1] = TypeRefTable.RId; + rids [2] = ModuleRefTable.RId; + rids [3] = MethodTable.RId; + rids [4] = TypeSpecTable.RId; + break; + case CodedIndex.HasSemantics : + bits = 1; + rids = new int [2]; + rids [0] = EventTable.RId; + rids [1] = PropertyTable.RId; + break; + case CodedIndex.MethodDefOrRef : + bits = 1; + rids = new int [2]; + rids [0] = MethodTable.RId; + rids [1] = MemberRefTable.RId; + break; + case CodedIndex.MemberForwarded : + bits = 1; + rids = new int [2]; + rids [0] = FieldTable.RId; + rids [1] = MethodTable.RId; + break; + case CodedIndex.Implementation : + bits = 2; + rids = new int [3]; + rids [0] = FileTable.RId; + rids [1] = AssemblyRefTable.RId; + rids [2] = ExportedTypeTable.RId; + break; + case CodedIndex.CustomAttributeType : + bits = 3; + rids = new int [2]; + rids [0] = MethodTable.RId; + rids [1] = MemberRefTable.RId; + break; + case CodedIndex.ResolutionScope : + bits = 2; + rids = new int [4]; + rids [0] = ModuleTable.RId; + rids [1] = ModuleRefTable.RId; + rids [2] = AssemblyRefTable.RId; + rids [3] = TypeRefTable.RId; + break; + case CodedIndex.TypeOrMethodDef : + bits = 1; + rids = new int [2]; + rids [0] = TypeDefTable.RId; + rids [1] = MethodTable.RId; + break; + default : + throw new MetadataFormatException ("Non valid CodedIndex"); + } + + for (int i = 0; i < rids.Length; i++) { + int rows = rowCounter (rids [i]); + if (rows > max) max = rows; + } + + res = max < (1 << (16 - bits)) ? 2 : 4; + codedIndexCache [ci] = res; + return res; + } + + */ + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Array.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Array.cs new file mode 100644 index 000000000..c70896348 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Array.cs @@ -0,0 +1,43 @@ +// +// Array.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 - 2007 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class ARRAY : SigType { + + public CustomMod [] CustomMods; + public SigType Type; + public ArrayShape Shape; + + public ARRAY () : base (ElementType.Array) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ArrayShape.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ArrayShape.cs new file mode 100644 index 000000000..7cf3940c2 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ArrayShape.cs @@ -0,0 +1,43 @@ +// +// ArrayShape.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class ArrayShape { + + public int Rank; + public int NumSizes; + public int [] Sizes; + public int NumLoBounds; + public int [] LoBounds; + + public ArrayShape () + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/BaseSignatureVisitor.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/BaseSignatureVisitor.cs new file mode 100644 index 000000000..0a37a5b81 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/BaseSignatureVisitor.cs @@ -0,0 +1,53 @@ +// +// BaseSignatureVisitor.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal abstract class BaseSignatureVisitor : ISignatureVisitor { + + public virtual void VisitMethodDefSig (MethodDefSig methodDef) + { + } + + public virtual void VisitMethodRefSig (MethodRefSig methodRef) + { + } + + public virtual void VisitFieldSig (FieldSig field) + { + } + + public virtual void VisitPropertySig (PropertySig property) + { + } + + public virtual void VisitLocalVarSig (LocalVarSig localvar) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Class.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Class.cs new file mode 100644 index 000000000..ef908e60f --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Class.cs @@ -0,0 +1,41 @@ +// +// Class.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class CLASS : SigType { + + public MetadataToken Type; + + public CLASS () : base (ElementType.Class) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Constraint.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Constraint.cs new file mode 100644 index 000000000..416707b9d --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Constraint.cs @@ -0,0 +1,37 @@ +// +// Constraints.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal enum Constraint : byte { + None = 0x0, + Pinned = (byte) ElementType.Pinned + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/CustomAttrib.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/CustomAttrib.cs new file mode 100644 index 000000000..aca30e294 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/CustomAttrib.cs @@ -0,0 +1,80 @@ +// +// CustomAttrib.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class CustomAttrib { + + public const ushort StdProlog = 0x0001; + + public MethodReference Constructor; + + public ushort Prolog; + public FixedArg [] FixedArgs; + public ushort NumNamed; + public NamedArg [] NamedArgs; + public bool Read; + + public CustomAttrib (MethodReference ctor) + { + Constructor = ctor; + } + + public struct FixedArg { + + public bool SzArray; + public uint NumElem; + public Elem [] Elems; + } + + public struct Elem { + + public bool Simple; + public bool String; + public bool Type; + public bool BoxedValueType; + + public ElementType FieldOrPropType; + public object Value; + + public TypeReference ElemType; + } + + public struct NamedArg { + + public bool Field; + public bool Property; + + public ElementType FieldOrPropType; + public string FieldOrPropName; + public FixedArg FixedArg; + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/CustomMod.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/CustomMod.cs new file mode 100644 index 000000000..242f4d23d --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/CustomMod.cs @@ -0,0 +1,48 @@ +// +// CustomMod.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class CustomMod { + + public enum CMODType : byte { + None = 0x0, + OPT = (byte) ElementType.CModOpt, + REQD = (byte) ElementType.CModReqD + } + + public CMODType CMOD; + public MetadataToken TypeDefOrRef; + + public CustomMod () + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/FieldSig.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/FieldSig.cs new file mode 100644 index 000000000..a01c058f4 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/FieldSig.cs @@ -0,0 +1,50 @@ +// +// FieldSig.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class FieldSig : Signature { + + public bool Field; + public CustomMod [] CustomMods; + public SigType Type; + + public FieldSig () : base () + { + } + + public FieldSig (uint blobIndex) : base (blobIndex) + { + } + + public override void Accept (ISignatureVisitor visitor) + { + visitor.VisitFieldSig (this); + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/FnPtr.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/FnPtr.cs new file mode 100644 index 000000000..02fc3303a --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/FnPtr.cs @@ -0,0 +1,41 @@ +// +// FnPtr.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class FNPTR : SigType { + + public MethodSig Method; + + public FNPTR () : base (ElementType.FnPtr) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/GenericArg.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/GenericArg.cs new file mode 100644 index 000000000..74edb4a2a --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/GenericArg.cs @@ -0,0 +1,41 @@ +// +// GenericArg.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2006 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + class GenericArg { + + public CustomMod [] CustomMods; + public SigType Type; + + public GenericArg (SigType type) + { + Type = type; + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/GenericInst.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/GenericInst.cs new file mode 100644 index 000000000..02bd1117e --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/GenericInst.cs @@ -0,0 +1,46 @@ +// +// GenericInst.cs +// +// Author: +// Martin Baulig +// Jb Evain +// +// Copyright (C) 2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil; + using Mono.Cecil.Metadata; + + internal sealed class GENERICINST : SigType { + + public bool ValueType; + public MetadataToken Type; + + public GenericInstSignature Signature; + + public GENERICINST () : base (ElementType.GenericInst) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/GenericInstSignature.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/GenericInstSignature.cs new file mode 100644 index 000000000..94d41c480 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/GenericInstSignature.cs @@ -0,0 +1,40 @@ +// +// GenericInstSignature.cs +// +// Author: +// Martin Baulig +// +// Copyright (C) 2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class GenericInstSignature { + + public int Arity; + public GenericArg [] Types; + + public GenericInstSignature () + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ISignatureVisitable.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ISignatureVisitable.cs new file mode 100644 index 000000000..81374f07c --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ISignatureVisitable.cs @@ -0,0 +1,35 @@ +// +// ISignatureVisitable.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal interface ISignatureVisitable { + + void Accept (ISignatureVisitor visitor); + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ISignatureVisitor.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ISignatureVisitor.cs new file mode 100644 index 000000000..e473e87dc --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ISignatureVisitor.cs @@ -0,0 +1,39 @@ +// +// ISignatureVisitor.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal interface ISignatureVisitor { + + void VisitMethodDefSig (MethodDefSig methodDef); + void VisitMethodRefSig (MethodRefSig methodRef); + void VisitFieldSig (FieldSig field); + void VisitPropertySig (PropertySig property); + void VisitLocalVarSig (LocalVarSig localvar); + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/InputOutputItem.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/InputOutputItem.cs new file mode 100644 index 000000000..5240a816f --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/InputOutputItem.cs @@ -0,0 +1,38 @@ +// +// InputOutputItem.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal abstract class InputOutputItem { + + public CustomMod [] CustomMods; + public bool ByRef; + public SigType Type; + public bool TypedByRef; + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/LocalVarSig.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/LocalVarSig.cs new file mode 100644 index 000000000..071c90c4a --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/LocalVarSig.cs @@ -0,0 +1,58 @@ +// +// LocalVarSig.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class LocalVarSig : Signature { + + public bool Local; + public int Count; + public LocalVariable [] LocalVariables; + + public LocalVarSig () : base () + { + } + + public LocalVarSig (uint blobIndex) : base (blobIndex) + { + } + + public override void Accept (ISignatureVisitor visitor) + { + visitor.VisitLocalVarSig (this); + } + + public struct LocalVariable { + + public CustomMod [] CustomMods; + public Constraint Constraint; + public bool ByRef; + public SigType Type; + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MVar.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MVar.cs new file mode 100644 index 000000000..3fca4a421 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MVar.cs @@ -0,0 +1,42 @@ +// +// MVar.cs +// +// Author: +// Martin Baulig +// +// Copyright (C) 2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class MVAR : SigType { + + public int Index; + + public MVAR (int index) : base (ElementType.MVar) + { + this.Index = index; + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MarshalSig.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MarshalSig.cs new file mode 100644 index 000000000..4b99c573c --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MarshalSig.cs @@ -0,0 +1,93 @@ +// +// MarshalSig.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using System; + + using Mono.Cecil; + + internal sealed class MarshalSig { + + public NativeType NativeInstrinsic; + public IMarshalSigSpec Spec; + + public MarshalSig (NativeType nt) + { + this.NativeInstrinsic = nt; + } + + public interface IMarshalSigSpec { + } + + public sealed class Array : IMarshalSigSpec { + + public NativeType ArrayElemType; + public int ParamNum; + public int ElemMult; + public int NumElem; + + public Array () + { + this.ParamNum = 0; + this.ElemMult = 0; + this.NumElem = 0; + } + } + + public sealed class CustomMarshaler : IMarshalSigSpec { + + public string Guid; + public string UnmanagedType; + public string ManagedType; + public string Cookie; + } + + public sealed class FixedArray : IMarshalSigSpec { + + public int NumElem; + public NativeType ArrayElemType; + + public FixedArray () + { + this.NumElem = 0; + this.ArrayElemType = NativeType.NONE; + } + } + + public sealed class SafeArray : IMarshalSigSpec { + + public VariantType ArrayElemType; + } + + public sealed class FixedSysString : IMarshalSigSpec { + + public int Size; + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodDefSig.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodDefSig.cs new file mode 100644 index 000000000..b7e2e5896 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodDefSig.cs @@ -0,0 +1,48 @@ +// +// MethodDefSig.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class MethodDefSig : MethodRefSig { + + public int GenericParameterCount; + + public MethodDefSig () : this (0) + { + } + + public MethodDefSig (uint blobIndex) : base (blobIndex) + { + } + + public override void Accept (ISignatureVisitor visitor) + { + visitor.VisitMethodDefSig (this); + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodRefSig.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodRefSig.cs new file mode 100644 index 000000000..63cc35bbd --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodRefSig.cs @@ -0,0 +1,49 @@ +// +// MethodRefSig.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal class MethodRefSig : MethodSig { + + public int Sentinel; + + public MethodRefSig () : this (0) + { + } + + public MethodRefSig (uint blobIndex) : base (blobIndex) + { + Sentinel = -1; + } + + public override void Accept (ISignatureVisitor visitor) + { + visitor.VisitMethodRefSig (this); + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodSig.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodSig.cs new file mode 100644 index 000000000..3b658096d --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodSig.cs @@ -0,0 +1,50 @@ +// +// MethodSig.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using Mono.Cecil; + +namespace Mono.Cecil.Signatures { + + internal abstract class MethodSig : Signature { + + public bool HasThis; + public bool ExplicitThis; + public MethodCallingConvention MethCallConv; + public int ParamCount; + public RetType RetType; + public Param [] Parameters; + + public MethodSig () : base () + { + } + + public MethodSig (uint blobIndex) : base (blobIndex) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodSpec.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodSpec.cs new file mode 100644 index 000000000..0ad0f8b08 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/MethodSpec.cs @@ -0,0 +1,40 @@ +// +// TypeSpec.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class MethodSpec { + + public GenericInstSignature Signature; + + public MethodSpec (GenericInstSignature sig) + { + this.Signature = sig; + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Param.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Param.cs new file mode 100644 index 000000000..0bd7a0dc7 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Param.cs @@ -0,0 +1,33 @@ +// +// Param.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class Param : InputOutputItem { + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/PropertySig.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/PropertySig.cs new file mode 100644 index 000000000..5db0820ce --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/PropertySig.cs @@ -0,0 +1,52 @@ +// +// PropertySig.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class PropertySig : Signature { + + public bool Property; + public int ParamCount; + public CustomMod [] CustomMods; + public SigType Type; + public Param [] Parameters; + + public PropertySig () : base () + { + } + + public PropertySig (uint blobIndex) : base (blobIndex) + { + } + + public override void Accept (ISignatureVisitor visitor) + { + visitor.VisitPropertySig (this); + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Ptr.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Ptr.cs new file mode 100644 index 000000000..e95394d5d --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Ptr.cs @@ -0,0 +1,43 @@ +// +// Ptr.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class PTR : SigType { + + public CustomMod [] CustomMods; + public SigType PtrType; + public bool Void; + + public PTR () : base (ElementType.Ptr) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/RetType.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/RetType.cs new file mode 100644 index 000000000..654121147 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/RetType.cs @@ -0,0 +1,39 @@ +// +// RetType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class RetType : InputOutputItem { + + public bool Void; + + public RetType () + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SigType.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SigType.cs new file mode 100644 index 000000000..6e2d19b8a --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SigType.cs @@ -0,0 +1,42 @@ +// +// SigType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal class SigType { + + public ElementType ElementType; + + public SigType (ElementType elem) + { + ElementType = elem; + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Signature.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Signature.cs new file mode 100644 index 000000000..5d9e254b3 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Signature.cs @@ -0,0 +1,50 @@ +// +// Signature.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using System; + + internal abstract class Signature : ISignatureVisitable { + + public byte CallingConvention; + public uint BlobIndex; + + public Signature (uint blobIndex) + { + BlobIndex = blobIndex; + } + + public Signature () + { + BlobIndex = 0; + } + + public abstract void Accept (ISignatureVisitor visitor); + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SignatureReader.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SignatureReader.cs new file mode 100644 index 000000000..2e90b28d4 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SignatureReader.cs @@ -0,0 +1,991 @@ +// +// SignatureReader.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 - 2007 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using System; + using System.Collections; + using System.IO; + using System.Text; + + using Mono.Cecil; + using Mono.Cecil.Metadata; + + internal sealed class SignatureReader : BaseSignatureVisitor { + + byte [] m_blobData; + IDictionary m_signatures; + + public byte[] Blob { + get { + return m_blobData; + } + } + + public SignatureReader (byte [] blobData) + { + m_blobData = blobData; + m_signatures = new Hashtable (); + } + + /* + + MetadataRoot m_root; + ReflectionReader m_reflectReader; + byte [] m_blobData; + + IDictionary m_signatures; + + IAssemblyResolver AssemblyResolver { + get { return m_reflectReader.Module.Assembly.Resolver; } + } + + public SignatureReader (MetadataRoot root, ReflectionReader reflectReader) + { + m_root = root; + m_reflectReader = reflectReader; + + m_blobData = m_root.Streams.BlobHeap != null ? m_root.Streams.BlobHeap.Data : new byte [0]; + + m_signatures = new Hashtable (); + } + + */ + + public FieldSig GetFieldSig (uint index) + { + FieldSig f = m_signatures [index] as FieldSig; + if (f == null) { + f = new FieldSig (index); + f.Accept (this); + m_signatures [index] = f; + } + return f; + } + + public PropertySig GetPropSig (uint index) + { + PropertySig p = m_signatures [index] as PropertySig; + if (p == null) { + p = new PropertySig (index); + p.Accept (this); + m_signatures [index] = p; + } + return p; + } + + public MethodDefSig GetMethodDefSig (uint index) + { + MethodDefSig m = m_signatures [index] as MethodDefSig; + if (m == null) { + m = new MethodDefSig (index); + m.Accept (this); + m_signatures [index] = m; + } + return m; + } + + public MethodRefSig GetMethodRefSig (uint index) + { + MethodRefSig m = m_signatures [index] as MethodRefSig; + if (m == null) { + m = new MethodRefSig (index); + m.Accept (this); + m_signatures [index] = m; + } + return m; + } + + public TypeSpec GetTypeSpec (uint index) + { + TypeSpec ts = m_signatures [index] as TypeSpec; + + if (ts == null) { + ts = ReadTypeSpec (m_blobData, (int) index); + m_signatures [index] = ts; + } + + return ts; + } + + public MethodSpec GetMethodSpec (uint index) + { + MethodSpec ms = m_signatures [index] as MethodSpec; + + if (ms == null) { + ms = ReadMethodSpec (m_blobData, (int) index); + m_signatures [index] = ms; + } + + return ms; + } + + public LocalVarSig GetLocalVarSig (uint index) + { + LocalVarSig lv = m_signatures [index] as LocalVarSig; + if (lv == null) { + lv = new LocalVarSig (index); + lv.Accept (this); + m_signatures [index] = lv; + } + return lv; + } + + /* + + public CustomAttrib GetCustomAttrib (uint index, MethodReference ctor) + { + return GetCustomAttrib (index, ctor, false); + } + + public CustomAttrib GetCustomAttrib (uint index, MethodReference ctor, bool resolve) + { + return ReadCustomAttrib ((int) index, ctor, resolve); + } + + public CustomAttrib GetCustomAttrib (byte [] data, MethodReference ctor) + { + return GetCustomAttrib (data, ctor, false); + } + + public CustomAttrib GetCustomAttrib (byte [] data, MethodReference ctor, bool resolve) + { + BinaryReader br = new BinaryReader (new MemoryStream (data)); + return ReadCustomAttrib (br, data, ctor, resolve); + } + + */ + + public Signature GetMemberRefSig (TokenType tt, uint index) + { + int start, callconv; + Utilities.ReadCompressedInteger (m_blobData, (int) index, out start); + callconv = m_blobData [start]; + if ((callconv & 0x5) == 0x5 || (callconv & 0x10) == 0x10) // vararg || generic? + return GetMethodDefSig (index); + if ((callconv & 0x6) != 0) // field ? + return GetFieldSig (index); + + switch (tt) { + case TokenType.TypeDef : + case TokenType.TypeRef : + case TokenType.TypeSpec : + return GetMethodRefSig (index); + case TokenType.ModuleRef : + case TokenType.Method : + return GetMethodDefSig (index); + } + return null; + } + + /* + + public MarshalSig GetMarshalSig (uint index) + { + MarshalSig ms = m_signatures [index] as MarshalSig; + if (ms == null) { + byte [] data = m_root.Streams.BlobHeap.Read (index); + ms = ReadMarshalSig (data); + m_signatures [index] = ms; + } + return ms; + } + + */ + + public MethodSig GetStandAloneMethodSig (uint index) + { + int start; + if ((m_blobData [index] & 0x5) > 0) { + MethodRefSig mrs = new MethodRefSig (index); + ReadMethodRefSig (mrs, m_blobData, (int)index, out start); + return mrs; + } else { + MethodDefSig mds = new MethodDefSig (index); + ReadMethodDefSig (mds, m_blobData, (int)index, out start); + return mds; + } + } + + public override void VisitMethodDefSig (MethodDefSig methodDef) + { + int start; + ReadMethodDefSig (methodDef, m_blobData, (int)methodDef.BlobIndex, out start); + } + + public override void VisitMethodRefSig (MethodRefSig methodRef) + { + int start; + ReadMethodRefSig (methodRef, m_blobData, (int)methodRef.BlobIndex, out start); + } + + public override void VisitFieldSig (FieldSig field) + { + int start = 0; + //Utilities.ReadCompressedInteger (m_blobData, (int) field.BlobIndex, out start); + //field.CallingConvention = m_blobData [start]; + field.Field = (field.CallingConvention & 0x6) != 0; + field.CustomMods = ReadCustomMods (m_blobData, start + 1, out start); + field.Type = ReadType (m_blobData, start, out start); + } + + public override void VisitPropertySig (PropertySig property) + { + int start; + Utilities.ReadCompressedInteger (m_blobData, (int) property.BlobIndex, out start); + property.CallingConvention = m_blobData [start]; + property.Property = (property.CallingConvention & 0x8) != 0; + property.ParamCount = Utilities.ReadCompressedInteger (m_blobData, start + 1, out start); + property.CustomMods = ReadCustomMods (m_blobData, start, out start); + property.Type = ReadType (m_blobData, start, out start); + property.Parameters = ReadParameters (property.ParamCount, m_blobData, start); + } + + public override void VisitLocalVarSig (LocalVarSig localvar) + { + int start; + Utilities.ReadCompressedInteger (m_blobData, (int) localvar.BlobIndex, out start); + localvar.CallingConvention = m_blobData [start]; + localvar.Local = (localvar.CallingConvention & 0x7) != 0; + localvar.Count = Utilities.ReadCompressedInteger (m_blobData, start + 1, out start); + localvar.LocalVariables = ReadLocalVariables (localvar.Count, m_blobData, start); + } + + void ReadMethodDefSig (MethodDefSig methodDef, byte [] data, int pos, out int start) + { + methodDef.CallingConvention = data [pos]; + start = pos + 1; + methodDef.HasThis = (methodDef.CallingConvention & 0x20) != 0; + methodDef.ExplicitThis = (methodDef.CallingConvention & 0x40) != 0; + if ((methodDef.CallingConvention & 0x5) != 0) + methodDef.MethCallConv |= MethodCallingConvention.VarArg; + else if ((methodDef.CallingConvention & 0x10) != 0) { + methodDef.MethCallConv |= MethodCallingConvention.Generic; + methodDef.GenericParameterCount = Utilities.ReadCompressedInteger (data, start, out start); + } else + methodDef.MethCallConv |= MethodCallingConvention.Default; + + methodDef.ParamCount = Utilities.ReadCompressedInteger (data, start, out start); + methodDef.RetType = ReadRetType (data, start, out start); + int sentpos; + methodDef.Parameters = ReadParameters (methodDef.ParamCount, data, start, out sentpos); + methodDef.Sentinel = sentpos; + } + + void ReadMethodRefSig (MethodRefSig methodRef, byte [] data, int pos, out int start) + { + methodRef.CallingConvention = data [pos]; + start = pos + 1; + methodRef.HasThis = (methodRef.CallingConvention & 0x20) != 0; + methodRef.ExplicitThis = (methodRef.CallingConvention & 0x40) != 0; + if ((methodRef.CallingConvention & 0x1) != 0) + methodRef.MethCallConv |= MethodCallingConvention.C; + else if ((methodRef.CallingConvention & 0x2) != 0) + methodRef.MethCallConv |= MethodCallingConvention.StdCall; + else if ((methodRef.CallingConvention & 0x3) != 0) + methodRef.MethCallConv |= MethodCallingConvention.ThisCall; + else if ((methodRef.CallingConvention & 0x4) != 0) + methodRef.MethCallConv |= MethodCallingConvention.FastCall; + else if ((methodRef.CallingConvention & 0x5) != 0) + methodRef.MethCallConv |= MethodCallingConvention.VarArg; + else + methodRef.MethCallConv |= MethodCallingConvention.Default; + methodRef.ParamCount = Utilities.ReadCompressedInteger (data, start, out start); + methodRef.RetType = ReadRetType (data, start, out start); + int sentpos; + methodRef.Parameters = ReadParameters (methodRef.ParamCount, data, start, out sentpos); + methodRef.Sentinel = sentpos; + } + + LocalVarSig.LocalVariable [] ReadLocalVariables (int length, byte [] data, int pos) + { + int start = pos; + LocalVarSig.LocalVariable [] types = new LocalVarSig.LocalVariable [length]; + for (int i = 0; i < length; i++) + types [i] = ReadLocalVariable (data, start, out start); + return types; + } + + public LocalVarSig.LocalVariable ReadLocalVariable (byte [] data, int pos, out int start) + { + start = pos; + LocalVarSig.LocalVariable lv = new LocalVarSig.LocalVariable (); + lv.ByRef = false; + int cursor; + while (true) { + lv.CustomMods = ReadCustomMods (data, start, out start); + cursor = start; + int current = Utilities.ReadCompressedInteger (data, start, out start); + if (current == (int) ElementType.Pinned) // the only possible constraint + lv.Constraint |= Constraint.Pinned; + else if (current == (int) ElementType.ByRef) { + lv.ByRef = true; + + if (lv.CustomMods == null || lv.CustomMods.Length == 0) + lv.CustomMods = ReadCustomMods (data, start, out start); + } else { + lv.Type = ReadType (data, cursor, out start); + break; + } + } + return lv; + } + + TypeSpec ReadTypeSpec (byte [] data, int pos) + { + int start = pos; + Utilities.ReadCompressedInteger (data, start, out start); + TypeSpec ts = new TypeSpec (); + ts.CustomMods = ReadCustomMods (data, start, out start); + ts.Type = ReadType (data, start, out start); + return ts; + } + + MethodSpec ReadMethodSpec (byte [] data, int pos) + { + int start = pos; + + Utilities.ReadCompressedInteger (data, start, out start); + if (Utilities.ReadCompressedInteger (data, start, out start) != 0x0a) + throw new ReflectionException ("Invalid MethodSpec signature"); + + return new MethodSpec (ReadGenericInstSignature (data, start, out start)); + } + + RetType ReadRetType (byte [] data, int pos, out int start) + { + RetType rt = new RetType (); + start = pos; + rt.CustomMods = ReadCustomMods (data, start, out start); + int curs = start; + ElementType flag = (ElementType) Utilities.ReadCompressedInteger (data, start, out start); + switch (flag) { + case ElementType.Void : + rt.ByRef = rt.TypedByRef = false; + rt.Void = true; + break; + case ElementType.TypedByRef : + rt.ByRef = rt.Void = false; + rt.TypedByRef = true; + break; + case ElementType.ByRef : + rt.TypedByRef = rt.Void = false; + rt.ByRef = true; + + if (rt.CustomMods == null || rt.CustomMods.Length == 0) + rt.CustomMods = ReadCustomMods (data, start, out start); + + rt.Type = ReadType (data, start, out start); + break; + default : + rt.TypedByRef = rt.Void = rt.ByRef = false; + rt.Type = ReadType (data, curs, out start); + break; + } + return rt; + } + + Param [] ReadParameters (int length, byte [] data, int pos) + { + Param [] ret = new Param [length]; + int start = pos; + for (int i = 0; i < length; i++) + ret [i] = ReadParameter (data, start, out start); + return ret; + } + + Param [] ReadParameters (int length, byte [] data, int pos, out int sentinelpos) + { + Param [] ret = new Param [length]; + int start = pos; + sentinelpos = -1; + + for (int i = 0; i < length; i++) { + int curs = start; + int flag = Utilities.ReadCompressedInteger (data, start, out start); + + if (flag == (int) ElementType.Sentinel) { + sentinelpos = i; + curs = start; + } + + ret [i] = ReadParameter (data, curs, out start); + } + + return ret; + } + + Param ReadParameter (byte [] data, int pos, out int start) + { + Param p = new Param (); + start = pos; + + p.CustomMods = ReadCustomMods (data, start, out start); + int curs = start; + ElementType flag = (ElementType) Utilities.ReadCompressedInteger (data, start, out start); + switch (flag) { + case ElementType.TypedByRef : + p.TypedByRef = true; + p.ByRef = false; + break; + case ElementType.ByRef : + p.TypedByRef = false; + p.ByRef = true; + + if (p.CustomMods == null || p.CustomMods.Length == 0) + p.CustomMods = ReadCustomMods (data, start, out start); + + p.Type = ReadType (data, start, out start); + break; + default : + p.TypedByRef = false; + p.ByRef = false; + p.Type = ReadType (data, curs, out start); + break; + } + return p; + } + + public SigType ReadType (byte [] data, int pos, out int start) + { + start = pos; + ElementType element = (ElementType) Utilities.ReadCompressedInteger (data, start, out start); + switch (element) { + case ElementType.ValueType : + VALUETYPE vt = new VALUETYPE (); + vt.Type = Utilities.GetMetadataToken(CodedIndex.TypeDefOrRef, + (uint) Utilities.ReadCompressedInteger (data, start, out start)); + return vt; + case ElementType.Class : + CLASS c = new CLASS (); + c.Type = Utilities.GetMetadataToken (CodedIndex.TypeDefOrRef, + (uint) Utilities.ReadCompressedInteger (data, start, out start)); + return c; + case ElementType.Ptr : + PTR p = new PTR (); + int buf = start; + int flag = Utilities.ReadCompressedInteger (data, start, out start); + p.Void = flag == (int) ElementType.Void; + if (p.Void) + return p; + start = buf; + p.CustomMods = ReadCustomMods (data, start, out start); + p.PtrType = ReadType (data, start, out start); + return p; + case ElementType.FnPtr : + FNPTR fp = new FNPTR (); + if ((data [start] & 0x5) != 0) { + MethodRefSig mr = new MethodRefSig ((uint) start); + ReadMethodRefSig (mr, data, start, out start); + fp.Method = mr; + } else { + MethodDefSig md = new MethodDefSig ((uint) start); + ReadMethodDefSig (md, data, start, out start); + fp.Method = md; + } + return fp; + case ElementType.Array : + ARRAY ary = new ARRAY (); + ary.CustomMods = ReadCustomMods (data, start, out start); + ArrayShape shape = new ArrayShape (); + ary.Type = ReadType (data, start, out start); + shape.Rank = Utilities.ReadCompressedInteger (data, start, out start); + shape.NumSizes = Utilities.ReadCompressedInteger (data, start, out start); + shape.Sizes = new int [shape.NumSizes]; + for (int i = 0; i < shape.NumSizes; i++) + shape.Sizes [i] = Utilities.ReadCompressedInteger (data, start, out start); + shape.NumLoBounds = Utilities.ReadCompressedInteger (data, start, out start); + shape.LoBounds = new int [shape.NumLoBounds]; + for (int i = 0; i < shape.NumLoBounds; i++) + shape.LoBounds [i] = Utilities.ReadCompressedInteger (data, start, out start); + ary.Shape = shape; + return ary; + case ElementType.SzArray : + SZARRAY sa = new SZARRAY (); + sa.CustomMods = ReadCustomMods (data, start, out start); + sa.Type = ReadType (data, start, out start); + return sa; + case ElementType.Var: + return new VAR (Utilities.ReadCompressedInteger (data, start, out start)); + case ElementType.MVar: + return new MVAR (Utilities.ReadCompressedInteger (data, start, out start)); + case ElementType.GenericInst: + GENERICINST ginst = new GENERICINST (); + + ginst.ValueType = ((ElementType) Utilities.ReadCompressedInteger ( + data, start, out start)) == ElementType.ValueType; + + ginst.Type = Utilities.GetMetadataToken (CodedIndex.TypeDefOrRef, + (uint) Utilities.ReadCompressedInteger (data, start, out start)); + + ginst.Signature = ReadGenericInstSignature (data, start, out start); + + return ginst; + default : + return new SigType (element); + } + } + + GenericInstSignature ReadGenericInstSignature (byte [] data, int pos, out int start) + { + start = pos; + GenericInstSignature gis = new GenericInstSignature (); + gis.Arity = Utilities.ReadCompressedInteger (data, start, out start); + gis.Types = new GenericArg [gis.Arity]; + for (int i = 0; i < gis.Arity; i++) + gis.Types [i] = ReadGenericArg (data, start, out start); + + return gis; + } + + GenericArg ReadGenericArg (byte[] data, int pos, out int start) + { + start = pos; + CustomMod [] mods = ReadCustomMods (data, start, out start); + GenericArg arg = new GenericArg (ReadType (data, start, out start)); + arg.CustomMods = mods; + return arg; + } + + CustomMod [] ReadCustomMods (byte [] data, int pos, out int start) + { + ArrayList cmods = new ArrayList (); + start = pos; + while (true) { + int buf = start; + ElementType flag = (ElementType) Utilities.ReadCompressedInteger (data, start, out start); + start = buf; + if (!((flag == ElementType.CModOpt) || (flag == ElementType.CModReqD))) + break; + cmods.Add (ReadCustomMod (data, start, out start)); + } + return cmods.ToArray (typeof (CustomMod)) as CustomMod []; + } + + CustomMod ReadCustomMod (byte [] data, int pos, out int start) + { + CustomMod cm = new CustomMod (); + start = pos; + ElementType cmod = (ElementType) Utilities.ReadCompressedInteger (data, start, out start); + if (cmod == ElementType.CModOpt) + cm.CMOD = CustomMod.CMODType.OPT; + else if (cmod == ElementType.CModReqD) + cm.CMOD = CustomMod.CMODType.REQD; + else + cm.CMOD = CustomMod.CMODType.None; + cm.TypeDefOrRef = Utilities.GetMetadataToken (CodedIndex.TypeDefOrRef, + (uint) Utilities.ReadCompressedInteger (data, start, out start)); + return cm; + } + + /* + + CustomAttrib ReadCustomAttrib (int pos, MethodReference ctor, bool resolve) + { + int start, length = Utilities.ReadCompressedInteger (m_blobData, pos, out start); + byte [] data = new byte [length]; + Buffer.BlockCopy (m_blobData, start, data, 0, length); + try { + return ReadCustomAttrib (new BinaryReader ( + new MemoryStream (data)), data, ctor, resolve); + } catch { + CustomAttrib ca = new CustomAttrib (ctor); + ca.Read = false; + return ca; + } + } + + CustomAttrib ReadCustomAttrib (BinaryReader br, byte [] data, MethodReference ctor, bool resolve) + { + CustomAttrib ca = new CustomAttrib (ctor); + if (data.Length == 0) { + ca.FixedArgs = new CustomAttrib.FixedArg [0]; + ca.NamedArgs = new CustomAttrib.NamedArg [0]; + return ca; + } + + bool read = true; + + ca.Prolog = br.ReadUInt16 (); + if (ca.Prolog != CustomAttrib.StdProlog) + throw new MetadataFormatException ("Non standard prolog for custom attribute"); + + ca.FixedArgs = new CustomAttrib.FixedArg [ctor.Parameters.Count]; + for (int i = 0; i < ca.FixedArgs.Length && read; i++) + ca.FixedArgs [i] = ReadFixedArg (data, br, + ctor.Parameters [i].ParameterType, ref read, resolve); + + if (br.BaseStream.Position == br.BaseStream.Length) + read = false; + + if (!read) { + ca.Read = read; + return ca; + } + + ca.NumNamed = br.ReadUInt16 (); + ca.NamedArgs = new CustomAttrib.NamedArg [ca.NumNamed]; + for (int i = 0; i < ca.NumNamed && read; i++) + ca.NamedArgs [i] = ReadNamedArg (data, br, ref read, resolve); + + ca.Read = read; + return ca; + } + + CustomAttrib.FixedArg ReadFixedArg (byte [] data, BinaryReader br, + TypeReference param, ref bool read, bool resolve) + { + CustomAttrib.FixedArg fa = new CustomAttrib.FixedArg (); + if (param is ArrayType) { + param = ((ArrayType) param).ElementType; + fa.SzArray = true; + fa.NumElem = br.ReadUInt32 (); + + if (fa.NumElem == 0 || fa.NumElem == 0xffffffff) { + fa.Elems = new CustomAttrib.Elem [0]; + fa.NumElem = 0; + return fa; + } + + fa.Elems = new CustomAttrib.Elem [fa.NumElem]; + for (int i = 0; i < fa.NumElem; i++) + fa.Elems [i] = ReadElem (data, br, param, ref read, resolve); + } else + fa.Elems = new CustomAttrib.Elem [] { ReadElem (data, br, param, ref read, resolve) }; + + return fa; + } + + TypeReference CreateEnumTypeReference (string enumName) + { + string asmName = null; + int asmStart = enumName.IndexOf (','); + if (asmStart != -1) { + asmName = enumName.Substring (asmStart + 1); + enumName = enumName.Substring (0, asmStart); + } + // Inner class style is reflection style. + enumName = enumName.Replace ('+', '/'); + AssemblyNameReference asm; + if (asmName == null) { + // If no assembly is given then the ECMA standard says the + // assembly is either the current one or mscorlib. + if (m_reflectReader.Module.Types.Contains (enumName)) + return m_reflectReader.Module.Types [enumName]; + + asm = m_reflectReader.Corlib; + } else + asm = AssemblyNameReference.Parse (asmName); + + string [] outers = enumName.Split ('/'); + string outerfullname = outers [0]; + string ns = null; + int nsIndex = outerfullname.LastIndexOf ('.'); + if (nsIndex != -1) + ns = outerfullname.Substring (0, nsIndex); + string name = outerfullname.Substring (nsIndex + 1); + TypeReference decType = new TypeReference (name, ns, asm); + for (int i = 1; i < outers.Length; i++) { + TypeReference t = new TypeReference (outers [i], null, asm); + t.DeclaringType = decType; + decType = t; + } + decType.IsValueType = true; + + return decType; + } + + TypeReference ReadTypeReference (byte [] data, BinaryReader br, out ElementType elemType) + { + bool array = false; + elemType = (ElementType) br.ReadByte (); + if (elemType == ElementType.SzArray) { + elemType = (ElementType) br.ReadByte (); + array = true; + } + + TypeReference res; + if (elemType == ElementType.Enum) + res = CreateEnumTypeReference (ReadUTF8String (data, br)); + else + res = TypeReferenceFromElemType (elemType); + + if (array) + res = new ArrayType (res); + + return res; + } + + TypeReference TypeReferenceFromElemType (ElementType elemType) + { + switch (elemType) { + case ElementType.Boxed : + return m_reflectReader.SearchCoreType (Constants.Object); + case ElementType.String : + return m_reflectReader.SearchCoreType (Constants.String); + case ElementType.Type : + return m_reflectReader.SearchCoreType (Constants.Type); + case ElementType.Boolean : + return m_reflectReader.SearchCoreType (Constants.Boolean); + case ElementType.Char : + return m_reflectReader.SearchCoreType (Constants.Char); + case ElementType.R4 : + return m_reflectReader.SearchCoreType (Constants.Single); + case ElementType.R8 : + return m_reflectReader.SearchCoreType (Constants.Double); + case ElementType.I1 : + return m_reflectReader.SearchCoreType (Constants.SByte); + case ElementType.I2 : + return m_reflectReader.SearchCoreType (Constants.Int16); + case ElementType.I4 : + return m_reflectReader.SearchCoreType (Constants.Int32); + case ElementType.I8 : + return m_reflectReader.SearchCoreType (Constants.Int64); + case ElementType.U1 : + return m_reflectReader.SearchCoreType (Constants.Byte); + case ElementType.U2 : + return m_reflectReader.SearchCoreType (Constants.UInt16); + case ElementType.U4 : + return m_reflectReader.SearchCoreType (Constants.UInt32); + case ElementType.U8 : + return m_reflectReader.SearchCoreType (Constants.UInt64); + default : + throw new MetadataFormatException ("Non valid type in CustomAttrib.Elem: 0x{0}", + ((byte) elemType).ToString("x2")); + } + } + + internal CustomAttrib.NamedArg ReadNamedArg (byte [] data, BinaryReader br, ref bool read, bool resolve) + { + CustomAttrib.NamedArg na = new CustomAttrib.NamedArg (); + byte kind = br.ReadByte (); + if (kind == 0x53) { // field + na.Field = true; + na.Property = false; + } else if (kind == 0x54) { // property + na.Field = false; + na.Property = true; + } else + throw new MetadataFormatException ("Wrong kind of namedarg found: 0x" + kind.ToString("x2")); + + TypeReference elemType = ReadTypeReference (data, br, out na.FieldOrPropType); + na.FieldOrPropName = ReadUTF8String (data, br); + na.FixedArg = ReadFixedArg (data, br, elemType, ref read, resolve); + + return na; + } + + CustomAttrib.Elem ReadElem (byte [] data, BinaryReader br, TypeReference elemType, ref bool read, bool resolve) + { + CustomAttrib.Elem elem = new CustomAttrib.Elem (); + + string elemName = elemType.FullName; + + if (elemName == Constants.Object) { + elemType = ReadTypeReference (data, br, out elem.FieldOrPropType); + if (elemType is ArrayType) { + read = false; // Don't know how to represent arrays as an object value. + return elem; + } else if (elemType.FullName == Constants.Object) + throw new MetadataFormatException ("Non valid type in CustomAttrib.Elem after boxed prefix: 0x{0}", + ((byte) elem.FieldOrPropType).ToString("x2")); + + elem = ReadElem (data, br, elemType, ref read, resolve); + elem.String = elem.Simple = elem.Type = false; + elem.BoxedValueType = true; + return elem; + } + + elem.ElemType = elemType; + + if (elemName == Constants.Type || elemName == Constants.String) { + switch (elemType.FullName) { + case Constants.String: + elem.String = true; + elem.BoxedValueType = elem.Simple = elem.Type = false; + break; + case Constants.Type: + elem.Type = true; + elem.BoxedValueType = elem.Simple = elem.String = false; + break; + } + + if (data [br.BaseStream.Position] == 0xff) { // null + elem.Value = null; + br.BaseStream.Position++; + } else { + elem.Value = ReadUTF8String (data, br); + } + return elem; + } + + elem.String = elem.Type = elem.BoxedValueType = false; + if (!ReadSimpleValue (br, ref elem, elem.ElemType)) { + if (!resolve) { // until enums writing is implemented + read = false; + return elem; + } + TypeReference typeRef = GetEnumUnderlyingType (elem.ElemType, resolve); + if (typeRef == null || !ReadSimpleValue (br, ref elem, typeRef)) + read = false; + } + + return elem; + } + + TypeReference GetEnumUnderlyingType (TypeReference enumType, bool resolve) + { + TypeDefinition type = enumType as TypeDefinition; + if (type == null && resolve && AssemblyResolver != null) { + if (enumType.Scope is ModuleDefinition) + throw new NotSupportedException (); + + AssemblyDefinition asm = AssemblyResolver.Resolve ( + ((AssemblyNameReference) enumType.Scope).FullName); + type = asm.MainModule.Types [enumType.FullName]; + } + + if (type != null && type.IsEnum) + return type.Fields.GetField ("value__").FieldType; + + return null; + } + + bool ReadSimpleValue (BinaryReader br, ref CustomAttrib.Elem elem, TypeReference type) + { + switch (type.FullName) { + case Constants.Boolean : + elem.Value = br.ReadByte () == 1; + break; + case Constants.Char : + elem.Value = (char) br.ReadUInt16 (); + break; + case Constants.Single : + elem.Value = br.ReadSingle (); + break; + case Constants.Double : + elem.Value = br.ReadDouble (); + break; + case Constants.Byte : + elem.Value = br.ReadByte (); + break; + case Constants.Int16 : + elem.Value = br.ReadInt16 (); + break; + case Constants.Int32 : + elem.Value = br.ReadInt32 (); + break; + case Constants.Int64 : + elem.Value = br.ReadInt64 (); + break; + case Constants.SByte : + elem.Value = br.ReadSByte (); + break; + case Constants.UInt16 : + elem.Value = br.ReadUInt16 (); + break; + case Constants.UInt32 : + elem.Value = br.ReadUInt32 (); + break; + case Constants.UInt64 : + elem.Value = br.ReadUInt64 (); + break; + default : // enum + return false; + } + elem.Simple = true; + return true; + } + + MarshalSig ReadMarshalSig (byte [] data) + { + int start; + MarshalSig ms = new MarshalSig ((NativeType) Utilities.ReadCompressedInteger (data, 0, out start)); + switch (ms.NativeInstrinsic) { + case NativeType.ARRAY: + MarshalSig.Array ar = new MarshalSig.Array (); + ar.ArrayElemType = (NativeType) Utilities.ReadCompressedInteger (data, start, out start); + if (start < data.Length) + ar.ParamNum = Utilities.ReadCompressedInteger (data, start, out start); + if (start < data.Length) + ar.NumElem = Utilities.ReadCompressedInteger (data, start, out start); + if (start < data.Length) + ar.ElemMult = Utilities.ReadCompressedInteger (data, start, out start); + ms.Spec = ar; + break; + case NativeType.CUSTOMMARSHALER: + MarshalSig.CustomMarshaler cm = new MarshalSig.CustomMarshaler (); + cm.Guid = ReadUTF8String (data, start, out start); + cm.UnmanagedType = ReadUTF8String (data, start, out start); + cm.ManagedType = ReadUTF8String (data, start, out start); + cm.Cookie = ReadUTF8String (data, start, out start); + ms.Spec = cm; + break; + case NativeType.FIXEDARRAY: + MarshalSig.FixedArray fa = new MarshalSig.FixedArray (); + fa.NumElem = Utilities.ReadCompressedInteger (data, start, out start); + if (start < data.Length) + fa.ArrayElemType = (NativeType) Utilities.ReadCompressedInteger (data, start, out start); + ms.Spec = fa; + break; + case NativeType.SAFEARRAY: + MarshalSig.SafeArray sa = new MarshalSig.SafeArray (); + if (start < data.Length) + sa.ArrayElemType = (VariantType) Utilities.ReadCompressedInteger (data, start, out start); + ms.Spec = sa; + break; + case NativeType.FIXEDSYSSTRING: + MarshalSig.FixedSysString fss = new MarshalSig.FixedSysString (); + if (start < data.Length) + fss.Size = Utilities.ReadCompressedInteger (data, start, out start); + ms.Spec = fss; + break; + } + return ms; + } + + static internal string ReadUTF8String (byte [] data, BinaryReader br) + { + int start = (int)br.BaseStream.Position; + string val = ReadUTF8String (data, start, out start); + br.BaseStream.Position = start; + return val; + } + + static internal string ReadUTF8String (byte [] data, int pos, out int start) + { + int length = Utilities.ReadCompressedInteger (data, pos, out start); + pos = start; + start += length; + // COMPACT FRAMEWORK NOTE: Encoding.GetString (byte[]) is not supported. + return Encoding.UTF8.GetString (data, pos, length); + } + + */ + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SignatureWriter.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SignatureWriter.cs new file mode 100644 index 000000000..0b318190f --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SignatureWriter.cs @@ -0,0 +1,520 @@ +// +// SignatureWriter.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 - 2007 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using System; + using System.Text; + + using Mono.Cecil; + using Mono.Cecil.Binary; + using Mono.Cecil.Metadata; + + internal sealed class SignatureWriter : BaseSignatureVisitor { + + MetadataWriter m_mdWriter; + MemoryBinaryWriter m_sigWriter; + + public SignatureWriter (MetadataWriter mdWriter) + { + m_mdWriter = mdWriter; + m_sigWriter = new MemoryBinaryWriter (); + } + + uint GetPointer () + { + return m_mdWriter.AddBlob (m_sigWriter.ToArray ()); + } + + public uint AddMethodDefSig (MethodDefSig methSig) + { + return AddSignature (methSig); + } + + public uint AddMethodRefSig (MethodRefSig methSig) + { + return AddSignature (methSig); + } + + public uint AddPropertySig (PropertySig ps) + { + return AddSignature (ps); + } + + public uint AddFieldSig (FieldSig fSig) + { + return AddSignature (fSig); + } + + public uint AddLocalVarSig (LocalVarSig lvs) + { + return AddSignature (lvs); + } + + uint AddSignature (Signature s) + { + m_sigWriter.Empty (); + s.Accept (this); + return GetPointer (); + } + + public uint AddTypeSpec (TypeSpec ts) + { + m_sigWriter.Empty (); + Write (ts); + return GetPointer (); + } + + public uint AddMethodSpec (MethodSpec ms) + { + m_sigWriter.Empty (); + Write (ms); + return GetPointer (); + } + + public uint AddMarshalSig (MarshalSig ms) + { + m_sigWriter.Empty (); + Write (ms); + return GetPointer (); + } + + public uint AddCustomAttribute (CustomAttrib ca, MethodReference ctor) + { + CompressCustomAttribute (ca, ctor, m_sigWriter); + return GetPointer (); + } + + public byte [] CompressCustomAttribute (CustomAttrib ca, MethodReference ctor) + { + MemoryBinaryWriter writer = new MemoryBinaryWriter (); + CompressCustomAttribute (ca, ctor, writer); + return writer.ToArray (); + } + + public byte [] CompressFieldSig (FieldSig field) + { + m_sigWriter.Empty (); + VisitFieldSig (field); + return m_sigWriter.ToArray (); + } + + public byte [] CompressLocalVar (LocalVarSig.LocalVariable var) + { + m_sigWriter.Empty (); + Write (var); + return m_sigWriter.ToArray (); + } + + void CompressCustomAttribute (CustomAttrib ca, MethodReference ctor, MemoryBinaryWriter writer) + { + m_sigWriter.Empty (); + Write (ca, ctor, writer); + } + + public override void VisitMethodDefSig (MethodDefSig methodDef) + { + m_sigWriter.Write (methodDef.CallingConvention); + if (methodDef.GenericParameterCount > 0) + Write (methodDef.GenericParameterCount); + Write (methodDef.ParamCount); + Write (methodDef.RetType); + Write (methodDef.Parameters, methodDef.Sentinel); + } + + public override void VisitMethodRefSig (MethodRefSig methodRef) + { + m_sigWriter.Write (methodRef.CallingConvention); + Write (methodRef.ParamCount); + Write (methodRef.RetType); + Write (methodRef.Parameters, methodRef.Sentinel); + } + + public override void VisitFieldSig (FieldSig field) + { + m_sigWriter.Write (field.CallingConvention); + Write (field.CustomMods); + Write (field.Type); + } + + public override void VisitPropertySig (PropertySig property) + { + m_sigWriter.Write (property.CallingConvention); + Write (property.ParamCount); + Write (property.CustomMods); + Write (property.Type); + Write (property.Parameters); + } + + public override void VisitLocalVarSig (LocalVarSig localvar) + { + m_sigWriter.Write (localvar.CallingConvention); + Write (localvar.Count); + Write (localvar.LocalVariables); + } + + void Write (LocalVarSig.LocalVariable [] vars) + { + foreach (LocalVarSig.LocalVariable var in vars) + Write (var); + } + + void Write (LocalVarSig.LocalVariable var) + { + Write (var.CustomMods); + if ((var.Constraint & Constraint.Pinned) != 0) + Write (ElementType.Pinned); + if (var.ByRef) + Write (ElementType.ByRef); + Write (var.Type); + } + + void Write (RetType retType) + { + Write (retType.CustomMods); + if (retType.Void) + Write (ElementType.Void); + else if (retType.TypedByRef) + Write (ElementType.TypedByRef); + else if (retType.ByRef) { + Write (ElementType.ByRef); + Write (retType.Type); + } else + Write (retType.Type); + } + + void Write (Param [] parameters, int sentinel) + { + for (int i = 0; i < parameters.Length; i++) { + if (i == sentinel) + Write (ElementType.Sentinel); + + Write (parameters [i]); + } + } + + void Write (Param [] parameters) + { + foreach (Param p in parameters) + Write (p); + } + + void Write (ElementType et) + { + Write ((int) et); + } + + void Write (SigType t) + { + Write ((int) t.ElementType); + + switch (t.ElementType) { + case ElementType.ValueType : + Write ((int) Utilities.CompressMetadataToken ( + CodedIndex.TypeDefOrRef, ((VALUETYPE) t).Type)); + break; + case ElementType.Class : + Write ((int) Utilities.CompressMetadataToken ( + CodedIndex.TypeDefOrRef, ((CLASS) t).Type)); + break; + case ElementType.Ptr : + PTR p = (PTR) t; + if (p.Void) + Write (ElementType.Void); + else { + Write (p.CustomMods); + Write (p.PtrType); + } + break; + case ElementType.FnPtr : + FNPTR fp = (FNPTR) t; + if (fp.Method is MethodRefSig) + (fp.Method as MethodRefSig).Accept (this); + else + (fp.Method as MethodDefSig).Accept (this); + break; + case ElementType.Array : + ARRAY ary = (ARRAY) t; + Write (ary.CustomMods); + ArrayShape shape = ary.Shape; + Write (ary.Type); + Write (shape.Rank); + Write (shape.NumSizes); + foreach (int size in shape.Sizes) + Write (size); + Write (shape.NumLoBounds); + foreach (int loBound in shape.LoBounds) + Write (loBound); + break; + case ElementType.SzArray : + SZARRAY sa = (SZARRAY) t; + Write (sa.CustomMods); + Write (sa.Type); + break; + case ElementType.Var : + Write (((VAR) t).Index); + break; + case ElementType.MVar : + Write (((MVAR) t).Index); + break; + case ElementType.GenericInst : + GENERICINST gi = t as GENERICINST; + Write (gi.ValueType ? ElementType.ValueType : ElementType.Class); + Write ((int) Utilities.CompressMetadataToken ( + CodedIndex.TypeDefOrRef, gi.Type)); + Write (gi.Signature); + break; + } + } + + void Write (TypeSpec ts) + { + Write (ts.CustomMods); + Write (ts.Type); + } + + void Write (MethodSpec ms) + { + Write (0x0a); + Write (ms.Signature); + } + + void Write (GenericInstSignature gis) + { + Write (gis.Arity); + for (int i = 0; i < gis.Arity; i++) + Write (gis.Types [i]); + } + + void Write (GenericArg arg) + { + Write (arg.CustomMods); + Write (arg.Type); + } + + void Write (Param p) + { + Write (p.CustomMods); + if (p.TypedByRef) + Write (ElementType.TypedByRef); + else if (p.ByRef) { + Write (ElementType.ByRef); + Write (p.Type); + } else + Write (p.Type); + } + + void Write (CustomMod [] customMods) + { + foreach (CustomMod cm in customMods) + Write (cm); + } + + void Write (CustomMod cm) + { + switch (cm.CMOD) { + case CustomMod.CMODType.OPT : + Write (ElementType.CModOpt); + break; + case CustomMod.CMODType.REQD : + Write (ElementType.CModReqD); + break; + } + + Write ((int) Utilities.CompressMetadataToken ( + CodedIndex.TypeDefOrRef, cm.TypeDefOrRef)); + } + + void Write (MarshalSig ms) + { + Write ((int) ms.NativeInstrinsic); + switch (ms.NativeInstrinsic) { + case NativeType.ARRAY : + MarshalSig.Array ar = (MarshalSig.Array) ms.Spec; + Write ((int) ar.ArrayElemType); + if (ar.ParamNum != -1) + Write (ar.ParamNum); + if (ar.NumElem != -1) + Write (ar.NumElem); + if (ar.ElemMult != -1) + Write (ar.ElemMult); + break; + case NativeType.CUSTOMMARSHALER : + MarshalSig.CustomMarshaler cm = (MarshalSig.CustomMarshaler) ms.Spec; + Write (cm.Guid); + Write (cm.UnmanagedType); + Write (cm.ManagedType); + Write (cm.Cookie); + break; + case NativeType.FIXEDARRAY : + MarshalSig.FixedArray fa = (MarshalSig.FixedArray) ms.Spec; + Write (fa.NumElem); + if (fa.ArrayElemType != NativeType.NONE) + Write ((int) fa.ArrayElemType); + break; + case NativeType.SAFEARRAY : + Write ((int) ((MarshalSig.SafeArray) ms.Spec).ArrayElemType); + break; + case NativeType.FIXEDSYSSTRING : + Write (((MarshalSig.FixedSysString) ms.Spec).Size); + break; + } + } + + void Write (CustomAttrib ca, MethodReference ctor, MemoryBinaryWriter writer) + { + if (ca == null) + return; + + if (ca.Prolog != CustomAttrib.StdProlog) + return; + + writer.Write (ca.Prolog); + + for (int i = 0; i < ctor.Parameters.Count; i++) + Write (ca.FixedArgs [i], writer); + + writer.Write (ca.NumNamed); + + for (int i = 0; i < ca.NumNamed; i++) + Write (ca.NamedArgs [i], writer); + } + + void Write (CustomAttrib.FixedArg fa, MemoryBinaryWriter writer) + { + if (fa.SzArray) + writer.Write (fa.NumElem); + + foreach (CustomAttrib.Elem elem in fa.Elems) + Write (elem, writer); + } + + void Write (CustomAttrib.NamedArg na, MemoryBinaryWriter writer) + { + if (na.Field) + writer.Write ((byte) 0x53); + else if (na.Property) + writer.Write ((byte) 0x54); + else + throw new MetadataFormatException ("Unknown kind of namedarg"); + + if (na.FixedArg.SzArray) + writer.Write ((byte) ElementType.SzArray); + + if (na.FieldOrPropType == ElementType.Object) + writer.Write ((byte) ElementType.Boxed); + else + writer.Write ((byte) na.FieldOrPropType); + + if (na.FieldOrPropType == ElementType.Enum) + Write (na.FixedArg.Elems [0].ElemType.FullName); + + Write (na.FieldOrPropName); + + Write (na.FixedArg, writer); + } + + void Write (CustomAttrib.Elem elem, MemoryBinaryWriter writer) // TODO + { + if (elem.String) + elem.FieldOrPropType = ElementType.String; + else if (elem.Type) + elem.FieldOrPropType = ElementType.Type; + else if (elem.BoxedValueType) + Write (elem.FieldOrPropType); + + switch (elem.FieldOrPropType) { + case ElementType.Boolean : + writer.Write ((byte) ((bool) elem.Value ? 1 : 0)); + break; + case ElementType.Char : + writer.Write ((ushort) (char) elem.Value); + break; + case ElementType.R4 : + writer.Write ((float) elem.Value); + break; + case ElementType.R8 : + writer.Write ((double) elem.Value); + break; + case ElementType.I1 : + writer.Write ((sbyte) elem.Value); + break; + case ElementType.I2 : + writer.Write ((short) elem.Value); + break; + case ElementType.I4 : + writer.Write ((int) elem.Value); + break; + case ElementType.I8 : + writer.Write ((long) elem.Value); + break; + case ElementType.U1 : + writer.Write ((byte) elem.Value); + break; + case ElementType.U2 : + writer.Write ((ushort) elem.Value); + break; + case ElementType.U4 : + writer.Write ((uint) elem.Value); + break; + case ElementType.U8 : + writer.Write ((long) elem.Value); + break; + case ElementType.String : + case ElementType.Type : + string s = elem.Value as string; + if (s == null) + writer.Write ((byte) 0xff); + else if (s.Length == 0) + writer.Write ((byte) 0x00); + else + Write (s); + break; + case ElementType.Object : + if (elem.Value != null) + throw new NotSupportedException ("Unknown state"); + writer.Write ((byte) 0xff); + break; + default : + throw new NotImplementedException ("WriteElem " + elem.FieldOrPropType.ToString ()); + } + } + + void Write (string s) + { + byte [] str = Encoding.UTF8.GetBytes (s); + Write (str.Length); + m_sigWriter.Write (str); + } + + void Write (int i) + { + Utilities.WriteCompressedInteger (m_sigWriter, i); + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SzArray.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SzArray.cs new file mode 100644 index 000000000..08ad8f131 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/SzArray.cs @@ -0,0 +1,42 @@ +// +// SzArray.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 - 2007 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class SZARRAY : SigType { + + public CustomMod [] CustomMods; + public SigType Type; + + public SZARRAY () : base (ElementType.SzArray) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/TypeSpec.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/TypeSpec.cs new file mode 100644 index 000000000..7664df311 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/TypeSpec.cs @@ -0,0 +1,36 @@ +// +// TypeSpec.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 - 2007 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + internal sealed class TypeSpec { + + public CustomMod [] CustomMods; + public SigType Type; + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ValueType.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ValueType.cs new file mode 100644 index 000000000..36b2661bd --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/ValueType.cs @@ -0,0 +1,41 @@ +// +// ValueType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class VALUETYPE : SigType { + + public MetadataToken Type; + + public VALUETYPE () : base (ElementType.ValueType) + { + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Var.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Var.cs new file mode 100644 index 000000000..97b35b608 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil.Signatures/Var.cs @@ -0,0 +1,42 @@ +// +// Var.cs +// +// Author: +// Martin Baulig +// +// Copyright (C) 2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Signatures { + + using Mono.Cecil.Metadata; + + internal sealed class VAR : SigType { + + public int Index; + + public VAR (int index) : base (ElementType.Var) + { + this.Index = index; + } + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil/MethodCallingConvention.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil/MethodCallingConvention.cs new file mode 100644 index 000000000..c574154d8 --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil/MethodCallingConvention.cs @@ -0,0 +1,43 @@ +// +// MethodCallingConvention.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + using System; + + [Flags] + public enum MethodCallingConvention : byte { + Default = 0x0, + C = 0x1, + StdCall = 0x2, + ThisCall = 0x3, + FastCall = 0x4, + VarArg = 0x5, + Generic = 0x10 + } +} diff --git a/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil/ReflectionException.cs b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil/ReflectionException.cs new file mode 100644 index 000000000..40273134c --- /dev/null +++ b/Debugger/Debugger.Core/Mono.Cecil/Mono.Cecil/ReflectionException.cs @@ -0,0 +1,55 @@ +// +// ReflectionException.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2005 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + using System; + + using Mono.Cecil.Metadata; + + public sealed class ReflectionException : MetadataFormatException { + + internal ReflectionException () : base () + { + } + + internal ReflectionException (string message) : base (message) + { + } + + internal ReflectionException (string message, params string [] parameters) : + base (string.Format (message, parameters)) + { + } + + internal ReflectionException (string message, Exception inner) : + base (message, inner) + { + } + } +} diff --git a/Debugger/Debugger.Core/NDebugger.cs b/Debugger/Debugger.Core/NDebugger.cs new file mode 100644 index 000000000..61ecb39eb --- /dev/null +++ b/Debugger/Debugger.Core/NDebugger.cs @@ -0,0 +1,320 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.IO; +using System.Text; +using System.Threading; +using Debugger.Interop; +using Debugger.Interop.CorDebug; +using Microsoft.Win32; + +namespace Debugger +{ + public class NDebugger: DebuggerObject + { + ICorDebug corDebug; + ManagedCallbackSwitch managedCallbackSwitch; + ManagedCallbackProxy managedCallbackProxy; + + BreakpointCollection breakpoints; + ProcessCollection processes; + + MTA2STA mta2sta = new MTA2STA(); + + string debuggeeVersion; + + Options options = new Options(); + + public MTA2STA MTA2STA { + get { + return mta2sta; + } + } + + internal ICorDebug CorDebug { + get { + return corDebug; + } + } + + public string DebuggeeVersion { + get { + return debuggeeVersion; + } + } + + public Options Options { + get { return options; } + set { options = value; } + } + + public BreakpointCollection Breakpoints { + get { return breakpoints; } + } + + public ProcessCollection Processes { + get { return processes; } + } + + public NDebugger() + { + processes = new ProcessCollection(this); + breakpoints = new BreakpointCollection(this); + + if (ApartmentState.STA == System.Threading.Thread.CurrentThread.GetApartmentState()) { + mta2sta.CallMethod = CallMethod.HiddenFormWithTimeout; + } else { + mta2sta.CallMethod = CallMethod.DirectCall; + } + } + + /// + /// Get the .NET version of the process that called this function + /// + public string GetDebuggerVersion() + { + int size; + NativeMethods.GetCORVersion(null, 0, out size); + StringBuilder sb = new StringBuilder(size); + int hr = NativeMethods.GetCORVersion(sb, sb.Capacity, out size); + return sb.ToString(); + } + + /// + /// Get the .NET version of a given program - eg. "v1.1.4322" + /// + /// Returns empty string for unmanaged applications + public string GetProgramVersion(string exeFilename) + { + int size; + NativeMethods.GetRequestedRuntimeVersion(exeFilename, null, 0, out size); + StringBuilder sb = new StringBuilder(size); + NativeMethods.GetRequestedRuntimeVersion(exeFilename, sb, sb.Capacity, out size); + sb.Length = size; + return sb.ToString().TrimEnd('\0'); + } + + /// + /// Prepares the debugger + /// + /// Version of the program to debug - eg. "v1.1.4322" + /// If null, the version of the executing process will be used + internal void InitDebugger(string debuggeeVersion) + { + if (IsKernelDebuggerEnabled) { + throw new DebuggerException("Can not debug because kernel debugger is enabled"); + } + if (string.IsNullOrEmpty(debuggeeVersion)) { + debuggeeVersion = GetDebuggerVersion(); + TraceMessage("Debuggee version: Unknown (assuming " + debuggeeVersion + ")"); + } else { + TraceMessage("Debuggee version: " + debuggeeVersion); + } + this.debuggeeVersion = debuggeeVersion; + + int debuggerVersion; + // The CLR does not provide 4.0 debugger interface for older versions + if (debuggeeVersion.StartsWith("v1") || debuggeeVersion.StartsWith("v2")) { + debuggerVersion = 3; // 2.0 CLR + TraceMessage("Debugger interface version: v2.0"); + } else { + debuggerVersion = 4; // 4.0 CLR + TraceMessage("Debugger interface version: v4.0"); + } + + corDebug = NativeMethods.CreateDebuggingInterfaceFromVersion(debuggerVersion, debuggeeVersion); + TrackedComObjects.Track(corDebug); + + managedCallbackSwitch = new ManagedCallbackSwitch(this); + managedCallbackProxy = new ManagedCallbackProxy(this, managedCallbackSwitch); + + corDebug.Initialize(); + corDebug.SetManagedHandler(managedCallbackProxy); + + TraceMessage("ICorDebug initialized"); + } + + internal void TerminateDebugger() + { + // Mark breakpints as deactivated + foreach (Breakpoint b in this.Breakpoints) { + b.MarkAsDeactivated(); + } + + TraceMessage("Reset done"); + + corDebug.Terminate(); + + TraceMessage("ICorDebug terminated"); + + int released = TrackedComObjects.ReleaseAll(); + + TraceMessage("Released " + released + " tracked COM objects"); + } + + /// + /// Internal: Used to debug the debugger library. + /// + public event EventHandler DebuggerTraceMessage; + + protected internal virtual void OnDebuggerTraceMessage(MessageEventArgs e) + { + if (DebuggerTraceMessage != null) { + DebuggerTraceMessage(this, e); + } + } + + internal void TraceMessage(string message) + { + System.Diagnostics.Debug.WriteLine("Debugger:" + message); + OnDebuggerTraceMessage(new MessageEventArgs(null, message)); + } + + public void StartWithoutDebugging(System.Diagnostics.ProcessStartInfo psi) + { + System.Diagnostics.Process process; + process = new System.Diagnostics.Process(); + process.StartInfo = psi; + process.Start(); + } + + internal object ProcessIsBeingCreatedLock = new object(); + + public Process Start(string filename, string workingDirectory, string arguments) + { + InitDebugger(GetProgramVersion(filename)); + lock(ProcessIsBeingCreatedLock) { + Process process = Process.CreateProcess(this, filename, workingDirectory, arguments); + // Expose a race conditon + System.Threading.Thread.Sleep(0); + this.Processes.Add(process); + return process; + } + } + + public Process Attach(System.Diagnostics.Process existingProcess) + { + string mainModule = existingProcess.MainModule.FileName; + InitDebugger(GetProgramVersion(mainModule)); + ICorDebugProcess corDebugProcess = corDebug.DebugActiveProcess((uint)existingProcess.Id, 0); + // TODO: Can we get the acutal working directory? + Process process = new Process(this, corDebugProcess, Path.GetDirectoryName(mainModule)); + this.Processes.Add(process); + return process; + } + + public void Detach() + { + // Deactivate breakpoints + foreach (Breakpoint b in this.Breakpoints) { + b.Deactivate(); + } + + // Detach all processes. + for (int i = 0; i < this.Processes.Count; ++i) { + Process process = this.Processes[i]; + if (process == null || process.HasExited) + continue; + process.Detach(); + } + } + + public bool IsKernelDebuggerEnabled { + get { + string systemStartOptions = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\").GetValue("SystemStartOptions", string.Empty).ToString(); + // XP does not have the slash, Vista does have it + systemStartOptions = ("/" + systemStartOptions).ToLower().Replace(" ", " /"); + if (systemStartOptions.Contains("/nodebug")) { + // this option overrides the others + return false; + } + if (systemStartOptions.Contains("/debug") || + systemStartOptions.Contains("/crashdebug") || + systemStartOptions.Contains("/debugport") || + systemStartOptions.Contains("/baudrate")) { + return true; + } else { + return false; + } + } + } + + /// Try to load module symbols using the search path defined in the options + public void ReloadModuleSymbols() + { + foreach(Process process in this.Processes) { + foreach(Module module in process.Modules) { + module.LoadSymbolsFromDisk(process.Options.SymbolsSearchPaths); + } + } + TraceMessage("Reloaded symbols"); + } + + /// Reset the just my code status of modules. Use this after changing any stepping options. + public void ResetJustMyCodeStatus() + { + foreach(Process process in this.Processes) { + foreach(Module module in process.Modules) { + module.ResetJustMyCodeStatus(); + } + } + TraceMessage("Just my code reseted"); + } + } + + [Serializable] + public class DebuggerEventArgs : EventArgs + { + NDebugger debugger; + + public NDebugger Debugger { + get { + return debugger; + } + } + + public DebuggerEventArgs(NDebugger debugger) + { + this.debugger = debugger; + } + } + + [Serializable] + public class MessageEventArgs : ProcessEventArgs + { + int level; + string message; + string category; + + public int Level { + get { + return level; + } + } + + public string Message { + get { + return message; + } + } + + public string Category { + get { + return category; + } + } + + public MessageEventArgs(Process process, string message): this(process, 0, message, String.Empty) + { + this.message = message; + } + + public MessageEventArgs(Process process, int level, string message, string category): base(process) + { + this.level = level; + this.message = message; + this.category = category; + } + } +} diff --git a/Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs b/Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs new file mode 100644 index 000000000..a7cc14f17 --- /dev/null +++ b/Debugger/Debugger.Core/NRefactory/Ast/ExpressionExtensionMethods.cs @@ -0,0 +1,334 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Reflection; + +using Debugger; +using Debugger.MetaData; +using ICSharpCode.NRefactory.Ast; +using ICSharpCode.NRefactory.PrettyPrinter; +using ICSharpCode.NRefactory.Visitors; + +namespace ICSharpCode.NRefactory.Ast +{ + public static class ExpressionExtensionMethods + { + public static Value Evaluate(this Expression expression, Process process) + { + return ExpressionEvaluator.Evaluate(expression, process); + } + + static M SetStaticType(this M expr, DebugType type) where M: INode + { + expr.UserData = type; + return expr; + } + + public static DebugType GetStaticType(this INode expr) + { + return expr.UserData as DebugType; + } + + public static Expression Parenthesize(this Expression expr) + { + if (expr is IdentifierExpression || + expr is MemberReferenceExpression || + expr is IndexerExpression || + expr is ParenthesizedExpression || + expr is PrimitiveExpression) + return expr; + return new ParenthesizedExpression(expr); + } + + public static Expression CastTo(this Expression expresion, DebugType castTo) + { + // No need to cast + if (expresion.GetStaticType() == castTo) + return expresion; + if (expresion is PrimitiveExpression) { + object val = ((PrimitiveExpression)expresion).Value; + if (val != null && val.GetType().FullName == castTo.FullName) + return expresion; + } + return new CastExpression(castTo.GetTypeReference(), expresion.Parenthesize(), CastType.Cast); + } + + public static Expression GetExpression(this DebugLocalVariableInfo locVar) + { + return new IdentifierExpression(locVar.Name).SetStaticType((DebugType)locVar.LocalType); + } + + public static Expression GetExpression(this DebugParameterInfo par) + { + return new IdentifierExpression(par.Name).SetStaticType((DebugType)par.ParameterType); + } + + public static UnaryOperatorExpression AppendDereference(this Expression expression) + { + return new UnaryOperatorExpression(new ParenthesizedExpression(expression), UnaryOperatorType.Dereference); + } + + public static IndexerExpression AppendIndexer(this Expression expression, params int[] indices) + { + IndexerExpression indexerExpr = new IndexerExpression(Parenthesize(expression), new List()); + foreach(int index in indices) { + indexerExpr.Indexes.Add(new PrimitiveExpression(index)); + } + DebugType staticType = expression.GetStaticType(); + if (staticType != null && staticType.IsArray) + indexerExpr.SetStaticType((DebugType)staticType.GetElementType()); + if (staticType != null && staticType.FullNameWithoutGenericArguments == typeof(List<>).FullName) + indexerExpr.SetStaticType((DebugType)staticType.GetGenericArguments()[0]); + return indexerExpr; + } + + public static Expression AppendMemberReference(this Expression expresion, IDebugMemberInfo memberInfo, params Expression[] args) + { + Expression target; + if (memberInfo.IsStatic) { + target = new TypeReferenceExpression( + memberInfo.DeclaringType.GetTypeReference() + ); + } else { + target = expresion.CastTo((DebugType)memberInfo.DeclaringType); + } + + if (memberInfo is DebugFieldInfo) { + if (args.Length > 0) + throw new DebuggerException("No arguments expected for a field"); + return new MemberReferenceExpression(target, memberInfo.Name).SetStaticType(memberInfo.MemberType); + } + + if (memberInfo is MethodInfo) { + return new InvocationExpression( + new MemberReferenceExpression(target, memberInfo.Name), + AddExplicitTypes((MethodInfo)memberInfo, args) + ).SetStaticType(memberInfo.MemberType); + } + + if (memberInfo is PropertyInfo) { + PropertyInfo propInfo = (PropertyInfo)memberInfo; + if (args.Length > 0) { + if (memberInfo.Name != "Item") + throw new DebuggerException("Arguments expected only for the Item property"); + return new IndexerExpression( + target, + AddExplicitTypes(propInfo.GetGetMethod() ?? propInfo.GetSetMethod(), args) + ).SetStaticType(memberInfo.MemberType); + } else { + return new MemberReferenceExpression(target, memberInfo.Name).SetStaticType(memberInfo.MemberType); + } + } + + throw new DebuggerException("Unknown member type " + memberInfo.GetType().FullName); + } + + static List AddExplicitTypes(MethodInfo method, Expression[] args) + { + if (args.Length != method.GetParameters().Length) + throw new DebuggerException("Incorrect number of arguments"); + List typedArgs = new List(args.Length); + for(int i = 0; i < args.Length; i++) { + typedArgs.Add(args[i].CastTo((DebugType)method.GetParameters()[i].ParameterType)); + } + return typedArgs; + } + + public static bool Is(this Type type) + { + return type.FullName == typeof(T).FullName; + } + + public static bool CanPromoteTo(this Type type, Type toType) + { + return ((DebugType)type).CanImplicitelyConvertTo(toType); + } + + public static string PrettyPrint(this INode code) + { + if (code == null) return string.Empty; + CSharpOutputVisitor csOutVisitor = new CSharpOutputVisitor(); + code.AcceptVisitor(csOutVisitor, null); + return csOutVisitor.Text; + } + + public static TypeReference GetTypeReference(this Type type) + { + List arrayRanks = new List(); + while(type.IsArray) { + // C# uses reverse array order + arrayRanks.Add(type.GetArrayRank() - 1); + type = type.GetElementType(); + } + + int pointerNest = 0; + while(type.IsPointer) { + pointerNest++; + type = type.GetElementType(); + } + + if (type.IsArray) + throw new DebuggerException("C# does not support pointers to arrays"); + + string name = type.Name; + if (name.IndexOf('`') != -1) + name = name.Substring(0, name.IndexOf('`')); + if (!string.IsNullOrEmpty(type.Namespace)) + name = type.Namespace + "." + name; + + List genArgs = new List(); + // This inludes the generic arguments of the outter types + genArgs.AddRange(type.GetGenericArguments()); + if (type.DeclaringType != null) + genArgs.RemoveRange(0, type.DeclaringType.GetGenericArguments().Length); + List genTypeRefs = new List(); + foreach(Type genArg in genArgs) { + genTypeRefs.Add(genArg.GetTypeReference()); + } + + if (type.DeclaringType != null) { + TypeReference outterRef = type.DeclaringType.GetTypeReference(); + InnerClassTypeReference innerRef = new InnerClassTypeReference(outterRef, name, genTypeRefs); + innerRef.PointerNestingLevel = pointerNest; + innerRef.RankSpecifier = arrayRanks.ToArray(); + return innerRef.SetStaticType((DebugType)type); + } else { + return new TypeReference(name, pointerNest, arrayRanks.ToArray(), genTypeRefs).SetStaticType((DebugType)type); + } + } + + /// + /// Converts tree into nested TypeReference/InnerClassTypeReference. + /// Dotted names are split into separate nodes. + /// It does not normalize generic arguments. + /// + static TypeReference NormalizeTypeReference(this INode expr) + { + if (expr is IdentifierExpression) { + return new TypeReference( + ((IdentifierExpression)expr).Identifier, + ((IdentifierExpression)expr).TypeArguments + ); + } else if (expr is MemberReferenceExpression) { + TypeReference outter = NormalizeTypeReference(((MemberReferenceExpression)expr).TargetObject); + return new InnerClassTypeReference( + outter, + ((MemberReferenceExpression)expr).MemberName, + ((MemberReferenceExpression)expr).TypeArguments + ); + } else if (expr is TypeReferenceExpression) { + return NormalizeTypeReference(((TypeReferenceExpression)expr).TypeReference); + } else if (expr is InnerClassTypeReference) { // Frist - it is also TypeReference + InnerClassTypeReference typeRef = (InnerClassTypeReference)expr; + string[] names = typeRef.Type.Split('.'); + TypeReference newRef = NormalizeTypeReference(typeRef.BaseType); + foreach(string name in names) { + newRef = new InnerClassTypeReference(newRef, name, new List()); + } + newRef.GenericTypes.AddRange(typeRef.GenericTypes); + newRef.PointerNestingLevel = typeRef.PointerNestingLevel; + newRef.RankSpecifier = typeRef.RankSpecifier; + return newRef; + } else if (expr is TypeReference) { + TypeReference typeRef = (TypeReference)expr; + string[] names = typeRef.Type.Split('.'); + if (names.Length == 1) + return typeRef; + TypeReference newRef = null; + foreach(string name in names) { + if (newRef == null) { + newRef = new TypeReference(name, new List()); + } else { + newRef = new InnerClassTypeReference(newRef, name, new List()); + } + } + newRef.GenericTypes.AddRange(typeRef.GenericTypes); + newRef.PointerNestingLevel = typeRef.PointerNestingLevel; + newRef.RankSpecifier = typeRef.RankSpecifier; + return newRef; + } else { + throw new EvaluateException(expr, "Type expected. {0} seen.", expr.GetType().FullName); + } + } + + static string GetNameWithArgCounts(TypeReference typeRef) + { + string name = typeRef.Type; + if (typeRef.GenericTypes.Count > 0) + name += "`" + typeRef.GenericTypes.Count.ToString(); + if (typeRef is InnerClassTypeReference) { + return GetNameWithArgCounts(((InnerClassTypeReference)typeRef).BaseType) + "." + name; + } else { + return name; + } + } + + public static DebugType ResolveType(this INode expr, Debugger.AppDomain appDomain) + { + if (expr is TypeReference && expr.GetStaticType() != null) + return expr.GetStaticType(); + if (expr is TypeReferenceExpression && ((TypeReferenceExpression)expr).TypeReference.GetStaticType() != null) + return ((TypeReferenceExpression)expr).TypeReference.GetStaticType(); + + appDomain.Process.TraceMessage("Resolving {0}", expr.PrettyPrint()); + + TypeReference typeRef = NormalizeTypeReference(expr); + + List genTypeRefs; + if (typeRef is InnerClassTypeReference) { + genTypeRefs = ((InnerClassTypeReference)typeRef).CombineToNormalTypeReference().GenericTypes; + } else { + genTypeRefs = typeRef.GenericTypes; + } + + List genArgs = new List(); + foreach(TypeReference genTypeRef in genTypeRefs) { + genArgs.Add(ResolveType(genTypeRef, appDomain)); + } + + return ResolveTypeInternal(typeRef, genArgs.ToArray(), appDomain); + } + + /// + /// For performance this is separate method. + /// 'genArgs' should hold type for each generic parameter in 'typeRef'. + /// + static DebugType ResolveTypeInternal(TypeReference typeRef, DebugType[] genArgs, Debugger.AppDomain appDomain) + { + DebugType type = null; + + // Try to construct non-nested type + // If there are generic types up in the tree, it must be nested type + if (genArgs.Length == typeRef.GenericTypes.Count) { + string name = GetNameWithArgCounts(typeRef); + type = DebugType.CreateFromNameOrNull(appDomain, name, null, genArgs); + } + + // Try to construct nested type + if (type == null && typeRef is InnerClassTypeReference) { + DebugType[] outterGenArgs = genArgs; + // Do not pass our generic arguments to outter type + Array.Resize(ref outterGenArgs, genArgs.Length - typeRef.GenericTypes.Count); + + DebugType outter = ResolveTypeInternal(((InnerClassTypeReference)typeRef).BaseType, outterGenArgs, appDomain); + string nestedName = typeRef.GenericTypes.Count == 0 ? typeRef.Type : typeRef.Type + "`" + typeRef.GenericTypes.Count; + type = DebugType.CreateFromNameOrNull(appDomain, nestedName, outter, genArgs); + } + + if (type == null) + throw new GetValueException("Can not resolve " + typeRef.PrettyPrint()); + + for(int i = 0; i < typeRef.PointerNestingLevel; i++) { + type = (DebugType)type.MakePointerType(); + } + if (typeRef.RankSpecifier != null) { + for(int i = typeRef.RankSpecifier.Length - 1; i >= 0; i--) { + type = (DebugType)type.MakeArrayType(typeRef.RankSpecifier[i] + 1); + } + } + return type; + } + } +} diff --git a/Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs b/Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs new file mode 100644 index 000000000..eb858026a --- /dev/null +++ b/Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs @@ -0,0 +1,1015 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +using Debugger; +using Debugger.MetaData; +using ICSharpCode.NRefactory.Ast; + +namespace ICSharpCode.NRefactory.Visitors +{ + public class EvaluateException: GetValueException + { + public EvaluateException(INode code, string msg):base(code, msg) {} + public EvaluateException(INode code, string msgFmt, params string[] msgArgs):base(code, string.Format(msgFmt, msgArgs)) {} + } + + class TypedValue + { + Value value; + DebugType type; + + public Value Value { + get { return value; } + } + + public DebugType Type { + get { return type; } + } + + public object PrimitiveValue { + get { return value.PrimitiveValue; } + } + + public TypedValue(Value value, DebugType type) + { + this.value = value; + this.type = type; + } + } + + public class ExpressionEvaluator : NotImplementedAstVisitor + { + StackFrame context; + + public StackFrame Context { + get { return context; } + } + + ExpressionEvaluator(StackFrame context) + { + this.context = context; + } + + public static INode Parse(string code, SupportedLanguage language) + { + SnippetParser parser = new SnippetParser(language); + INode astRoot = parser.Parse(code); + if (parser.Errors.Count > 0) { + throw new GetValueException(parser.Errors.ErrorOutput); + } + if (parser.SnippetType != SnippetType.Expression && parser.SnippetType != SnippetType.Statements) { + throw new GetValueException("Code must be expression or statement"); + } + return astRoot; + } + + /// Evaluate given expression. If you have expression tree already, use overloads of this method. + /// Returned value or null for statements + public static Value Evaluate(string code, SupportedLanguage language, StackFrame context) + { + return Evaluate(Parse(code, language), context); + } + + public static Value Evaluate(INode code, Process context) + { + if (context.SelectedStackFrame != null) { + return Evaluate(code, context.SelectedStackFrame); + } else if (context.SelectedThread.MostRecentStackFrame != null ) { + return Evaluate(code, context.SelectedThread.MostRecentStackFrame); + } else { + // This can happen when needed 'dll' is missing. This causes an exception dialog to be shown even before the applicaiton starts + throw new GetValueException("Can not evaluate because the process has no managed stack frames"); + } + } + + public static Value Evaluate(INode code, StackFrame context) + { + if (context == null) throw new ArgumentNullException("context"); + if (context.IsInvalid) throw new DebuggerException("The context is no longer valid"); + + TypedValue val = new ExpressionEvaluator(context).Evaluate(code, false); + if (val == null) + return null; + return val.Value; + } + + /// + /// Parses string representation of an expression (eg. "a.b[10] + 2") into NRefactory Expression tree. + /// + public static Expression ParseExpression(string code, SupportedLanguage language) + { + SnippetParser parser = new SnippetParser(language); + INode astRoot = parser.Parse(code); + if (parser.Errors.Count > 0) { + throw new GetValueException(parser.Errors.ErrorOutput); + } + Expression astExpression = astRoot as Expression; + if (astExpression == null) { + throw new GetValueException("Code must be expression"); + } + return astExpression; + } + + public static string FormatValue(Value val) + { + if (val == null) { + return null; + } if (val.IsNull) { + return "null"; + } else if (val.Type.IsArray) { + StringBuilder sb = new StringBuilder(); + sb.Append(val.Type.Name); + sb.Append(" {"); + bool first = true; + foreach(Value item in val.GetArrayElements()) { + if (!first) sb.Append(", "); + first = false; + sb.Append(FormatValue(item)); + } + sb.Append("}"); + return sb.ToString(); + } else if (val.Type.GetInterface(typeof(ICollection).FullName) != null) { + StringBuilder sb = new StringBuilder(); + sb.Append(val.Type.Name); + sb.Append(" {"); + val = val.GetPermanentReference(); + int count = (int)val.GetMemberValue("Count").PrimitiveValue; + for(int i = 0; i < count; i++) { + if (i > 0) sb.Append(", "); + DebugPropertyInfo itemProperty = (DebugPropertyInfo)val.Type.GetProperty("Item"); + Value item = val.GetPropertyValue(itemProperty, Eval.CreateValue(val.AppDomain, i)); + sb.Append(FormatValue(item)); + } + sb.Append("}"); + return sb.ToString(); + } else if (val.Type.FullName == typeof(char).FullName) { + return "'" + val.PrimitiveValue.ToString() + "'"; + } else if (val.Type.FullName == typeof(string).FullName) { + return "\"" + val.PrimitiveValue.ToString() + "\""; + } else if (val.Type.IsPrimitive) { + return val.PrimitiveValue.ToString(); + } else { + return val.InvokeToString(); + } + } + + TypedValue Evaluate(INode expression) + { + return Evaluate(expression, true); + } + + TypedValue Evaluate(INode expression, bool permRef) + { + // Try to get the value from cache + // (the cache is cleared when the process is resumed) + TypedValue val; + if (context.Process.ExpressionsCache.TryGetValue(expression, out val)) { + if (val == null || !val.Value.IsInvalid) + return val; + } + + System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); + watch.Start(); + try { + val = (TypedValue)expression.AcceptVisitor(this, null); + if (val != null && permRef) + val = new TypedValue(val.Value.GetPermanentReference(), val.Type); + } catch (GetValueException e) { + e.Expression = expression; + throw; + } catch (NotImplementedException e) { + throw new GetValueException(expression, "Language feature not implemented: " + e.Message); + } finally { + watch.Stop(); + context.Process.TraceMessage("Evaluated: {0} in {1} ms total", expression.PrettyPrint(), watch.ElapsedMilliseconds); + } + + if (val != null && val.Value.IsInvalid) + throw new DebuggerException("Expression \"" + expression.PrettyPrint() + "\" is invalid right after evaluation"); + + // Add the result to cache + context.Process.ExpressionsCache[expression] = val; + + return val; + } + + List EvaluateAll(List exprs) + { + List vals = new List(exprs.Count); + foreach(Expression expr in exprs) { + vals.Add(Evaluate(expr)); + } + return vals; + } + + int EvaluateAsInt(INode expression) + { + if (expression is PrimitiveExpression) { + int? i = ((PrimitiveExpression)expression).Value as int?; + if (i == null) + throw new EvaluateException(expression, "Integer expected"); + return i.Value; + } else { + TypedValue typedVal = Evaluate(expression); + if (typedVal.Type.CanImplicitelyConvertTo(typeof(int))) { + int i = (int)Convert.ChangeType(typedVal.PrimitiveValue, typeof(int)); + return i; + } else { + throw new EvaluateException(expression, "Integer expected"); + } + } + } + + TypedValue EvaluateAs(INode expression, DebugType type) + { + TypedValue val = Evaluate(expression); + if (val.Type == type) + return val; + if (!val.Type.CanImplicitelyConvertTo(type)) + throw new EvaluateException(expression, "Can not implicitely cast {0} to {1}", val.Type.FullName, type.FullName); + if (type.IsPrimitive) { + object oldVal = val.PrimitiveValue; + object newVal; + try { + newVal = Convert.ChangeType(oldVal, type.PrimitiveType); + } catch (InvalidCastException) { + throw new EvaluateException(expression, "Can not cast {0} to {1}", val.GetType().FullName, type.FullName); + } catch (OverflowException) { + throw new EvaluateException(expression, "Overflow"); + } + return CreateValue(newVal); + } else { + return new TypedValue(val.Value, type); + } + } + + Value[] GetValues(List typedVals) + { + List vals = new List(typedVals.Count); + foreach(TypedValue typedVal in typedVals) { + vals.Add(typedVal.Value); + } + return vals.ToArray(); + } + + DebugType[] GetTypes(List typedVals) + { + List types = new List(typedVals.Count); + foreach(TypedValue typedVal in typedVals) { + types.Add(typedVal.Type); + } + return types.ToArray(); + } + + TypedValue CreateValue(object primitiveValue) + { + Value val = Eval.CreateValue(context.AppDomain, primitiveValue); + return new TypedValue(val, val.Type); + } + + public object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data) + { + BinaryOperatorType op; + switch (assignmentExpression.Op) { + case AssignmentOperatorType.Assign: op = BinaryOperatorType.None; break; + case AssignmentOperatorType.Add: op = BinaryOperatorType.Add; break; + case AssignmentOperatorType.ConcatString: op = BinaryOperatorType.Concat; break; + case AssignmentOperatorType.Subtract: op = BinaryOperatorType.Subtract; break; + case AssignmentOperatorType.Multiply: op = BinaryOperatorType.Multiply; break; + case AssignmentOperatorType.Divide: op = BinaryOperatorType.Divide; break; + case AssignmentOperatorType.DivideInteger: op = BinaryOperatorType.DivideInteger; break; + case AssignmentOperatorType.ShiftLeft: op = BinaryOperatorType.ShiftLeft; break; + case AssignmentOperatorType.ShiftRight: op = BinaryOperatorType.ShiftRight; break; + case AssignmentOperatorType.ExclusiveOr: op = BinaryOperatorType.ExclusiveOr; break; + case AssignmentOperatorType.Modulus: op = BinaryOperatorType.Modulus; break; + case AssignmentOperatorType.BitwiseAnd: op = BinaryOperatorType.BitwiseAnd; break; + case AssignmentOperatorType.BitwiseOr: op = BinaryOperatorType.BitwiseOr; break; + case AssignmentOperatorType.Power: op = BinaryOperatorType.Power; break; + default: throw new GetValueException("Unknown operator " + assignmentExpression.Op); + } + + TypedValue right; + if (op == BinaryOperatorType.None) { + right = Evaluate(assignmentExpression.Right); + } else { + BinaryOperatorExpression binOpExpr = new BinaryOperatorExpression(); + binOpExpr.Left = assignmentExpression.Left; + binOpExpr.Op = op; + binOpExpr.Right = assignmentExpression.Right; + right = Evaluate(binOpExpr); + } + + // We can not have perfRef because we need to be able to set the value + TypedValue left = (TypedValue)assignmentExpression.Left.AcceptVisitor(this, null); + + if (left == null) { + // Can this happen? + throw new GetValueException(string.Format("\"{0}\" can not be set", assignmentExpression.Left.PrettyPrint())); + } + if (!left.Value.IsReference && left.Type.FullName != right.Type.FullName) { + throw new GetValueException(string.Format("Type {0} expected, {1} seen", left.Type.FullName, right.Type.FullName)); + } + left.Value.SetValue(right.Value); + return right; + } + + public object VisitBlockStatement(BlockStatement blockStatement, object data) + { + foreach(INode statement in blockStatement.Children) { + Evaluate(statement); + } + return null; + } + + public object VisitEmptyStatement(EmptyStatement emptyStatement, object data) + { + return null; + } + + public object VisitExpressionStatement(ExpressionStatement expressionStatement, object data) + { + Evaluate(expressionStatement.Expression); + return null; + } + + public object VisitCastExpression(CastExpression castExpression, object data) + { + TypedValue val = Evaluate(castExpression.Expression); + DebugType castTo = castExpression.CastTo.ResolveType(context.AppDomain); + if (castTo.IsPrimitive && val.Type.IsPrimitive && castTo != val.Type) { + object oldVal = val.PrimitiveValue; + object newVal; + try { + newVal = Convert.ChangeType(oldVal, castTo.PrimitiveType); + } catch (InvalidCastException) { + throw new EvaluateException(castExpression, "Can not cast {0} to {1}", val.Type.FullName, castTo.FullName); + } catch (OverflowException) { + throw new EvaluateException(castExpression, "Overflow"); + } + val = CreateValue(newVal); + } + if (!castTo.IsAssignableFrom(val.Value.Type) && !val.Value.IsNull) + throw new GetValueException("Can not cast {0} to {1}", val.Value.Type.FullName, castTo.FullName); + return new TypedValue(val.Value, castTo); + } + + public object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data) + { + string identifier = identifierExpression.Identifier; + + if (identifier == "__exception") { + if (context.Thread.CurrentException != null) { + return new TypedValue( + context.Thread.CurrentException.Value, + DebugType.CreateFromType(context.AppDomain.Mscorlib, typeof(System.Exception)) + ); + } else { + throw new GetValueException("No current exception"); + } + } + + DebugParameterInfo par = context.MethodInfo.GetParameter(identifier); + if (par != null) + return new TypedValue(par.GetValue(context), (DebugType)par.ParameterType); + + DebugLocalVariableInfo loc = context.MethodInfo.GetLocalVariable(context.IP, identifier); + if (loc != null) + return new TypedValue(loc.GetValue(context), (DebugType)loc.LocalType); + + // Instance class members + // Note that the method might be generated instance method that represents anonymous method + TypedValue thisValue = GetThisValue(); + if (thisValue != null) { + IDebugMemberInfo instMember = (IDebugMemberInfo)thisValue.Type.GetMember(identifier, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, DebugType.IsFieldOrNonIndexedProperty); + if (instMember != null) + return new TypedValue(Value.GetMemberValue(thisValue.Value, (MemberInfo)instMember), instMember.MemberType); + } + + // Static class members + foreach(DebugType declaringType in ((DebugType)context.MethodInfo.DeclaringType).GetSelfAndDeclaringTypes()) { + IDebugMemberInfo statMember = (IDebugMemberInfo)declaringType.GetMember(identifier, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, DebugType.IsFieldOrNonIndexedProperty); + if (statMember != null) + return new TypedValue(Value.GetMemberValue(null, (MemberInfo)statMember), statMember.MemberType); + } + + throw new GetValueException("Identifier \"" + identifier + "\" not found in this context"); + } + + public object VisitIndexerExpression(IndexerExpression indexerExpression, object data) + { + TypedValue target = Evaluate(indexerExpression.TargetObject); + + if (target.Type.IsArray) { + List intIndexes = new List(); + foreach(Expression indexExpr in indexerExpression.Indexes) { + intIndexes.Add(EvaluateAsInt(indexExpr)); + } + return new TypedValue( + target.Value.GetArrayElement(intIndexes.ToArray()), + (DebugType)target.Type.GetElementType() + ); + } else if (target.Type.FullName == typeof(string).FullName) { + if (indexerExpression.Indexes.Count != 1) + throw new GetValueException("Single index expected"); + + int index = EvaluateAsInt(indexerExpression.Indexes[0]); + string str = (string)target.PrimitiveValue; + if (index < 0 || index >= str.Length) + throw new GetValueException("Index was outside the bounds of the array."); + return CreateValue(str[index]); + } else { + List indexes = EvaluateAll(indexerExpression.Indexes); + DebugPropertyInfo pi = (DebugPropertyInfo)target.Type.GetProperty("Item", GetTypes(indexes)); + if (pi == null) + throw new GetValueException("The object does not have an indexer property"); + return new TypedValue( + target.Value.GetPropertyValue(pi, GetValues(indexes)), + (DebugType)pi.PropertyType + ); + } + } + + public object VisitInvocationExpression(InvocationExpression invocationExpression, object data) + { + TypedValue target; + DebugType targetType; + string methodName; + MemberReferenceExpression memberRef = invocationExpression.TargetObject as MemberReferenceExpression; + if (memberRef != null) { + // TODO: Optimize + try { + // Instance + target = Evaluate(memberRef.TargetObject); + targetType = target.Type; + } catch (GetValueException) { + // Static + target = null; + targetType = memberRef.TargetObject.ResolveType(context.AppDomain); + } + methodName = memberRef.MemberName; + } else { + IdentifierExpression ident = invocationExpression.TargetObject as IdentifierExpression; + if (ident != null) { + target = Evaluate(new ThisReferenceExpression()); + targetType = target.Type; + methodName = ident.Identifier; + } else { + throw new GetValueException("Member reference expected for method invocation"); + } + } + List args = EvaluateAll(invocationExpression.Arguments); + MethodInfo method = targetType.GetMethod(methodName, DebugType.BindingFlagsAllInScope, null, GetTypes(args), null); + if (method == null) + throw new GetValueException("Method " + methodName + " not found"); + Value retVal = Value.InvokeMethod(target != null ? target.Value : null, method, GetValues(args)); + if (retVal == null) + return null; + return new TypedValue(retVal, (DebugType)method.ReturnType); + } + + public object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data) + { + if (!objectCreateExpression.ObjectInitializer.IsNull) + throw new EvaluateException(objectCreateExpression.ObjectInitializer, "Object initializers not supported"); + + DebugType type = objectCreateExpression.CreateType.ResolveType(context.AppDomain); + List ctorArgs = EvaluateAll(objectCreateExpression.Parameters); + ConstructorInfo ctor = type.GetConstructor(BindingFlags.Default, null, CallingConventions.Any, GetTypes(ctorArgs), null); + if (ctor == null) + throw new EvaluateException(objectCreateExpression, "Constructor not found"); + Value val = (Value)ctor.Invoke(GetValues(ctorArgs)); + return new TypedValue(val, type); + } + + public object VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data) + { + if (arrayCreateExpression.CreateType.RankSpecifier[0] != 0) + throw new EvaluateException(arrayCreateExpression, "Multi-dimensional arrays are not suppored"); + + DebugType type = arrayCreateExpression.CreateType.ResolveType(context.AppDomain); + int length = 0; + if (arrayCreateExpression.Arguments.Count == 1) { + length = EvaluateAsInt(arrayCreateExpression.Arguments[0]); + } else if (!arrayCreateExpression.ArrayInitializer.IsNull) { + length = arrayCreateExpression.ArrayInitializer.CreateExpressions.Count; + } + Value array = Eval.NewArray((DebugType)type.GetElementType(), (uint)length, null); + if (!arrayCreateExpression.ArrayInitializer.IsNull) { + List inits = arrayCreateExpression.ArrayInitializer.CreateExpressions; + if (inits.Count != length) + throw new EvaluateException(arrayCreateExpression, "Incorrect initializer length"); + for(int i = 0; i < length; i++) { + TypedValue init = EvaluateAs(inits[i], (DebugType)type.GetElementType()); + array.SetArrayElement(new int[] { i }, init.Value); + } + } + return new TypedValue(array, type); + } + + public object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data) + { + TypedValue target; + DebugType targetType; + try { + // Instance + target = Evaluate(memberReferenceExpression.TargetObject); + targetType = target.Type; + } catch (GetValueException e) { + // Static + target = null; + try { + targetType = memberReferenceExpression.TargetObject.ResolveType(context.AppDomain); + } catch (GetValueException) { + throw e; // Use the other, nicer message + } + } + MemberInfo[] memberInfos = targetType.GetMember(memberReferenceExpression.MemberName, DebugType.BindingFlagsAllInScope); + if (memberInfos.Length == 0) + throw new GetValueException("Member \"" + memberReferenceExpression.MemberName + "\" not found"); + return new TypedValue( + Value.GetMemberValue(target != null ? target.Value : null, memberInfos[0]), + ((IDebugMemberInfo)memberInfos[0]).MemberType + ); + } + + public object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data) + { + return Evaluate(parenthesizedExpression.Expression); + } + + public object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) + { + return CreateValue(primitiveExpression.Value); + } + + TypedValue GetThisValue() + { + // This is needed so that captured 'this' is supported + DebugLocalVariableInfo thisVar = context.MethodInfo.GetLocalVariableThis(); + if (thisVar != null) + return new TypedValue(thisVar.GetValue(context), (DebugType)thisVar.LocalType); + return null; + } + + public object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data) + { + TypedValue thisValue = GetThisValue(); + if (thisValue == null) + throw new GetValueException(context.MethodInfo.FullName + " is static method and does not have \"this\""); + return thisValue; + } + + #region Binary and unary expressions + + public object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data) + { + TypedValue value = Evaluate(unaryOperatorExpression.Expression); + UnaryOperatorType op = unaryOperatorExpression.Op; + + if (op == UnaryOperatorType.Dereference) { + if (!value.Type.IsPointer) + throw new GetValueException("Target object is not a pointer"); + return new TypedValue(value.Value.Dereference(), (DebugType)value.Type.GetElementType()); + } + + if (!value.Type.IsPrimitive) + throw new GetValueException("Primitive value expected"); + + if (op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostDecrement || + op == UnaryOperatorType.Increment || op == UnaryOperatorType.PostIncrement) + { + TypedValue oldValue = value; + TypedValue newValue = null; + try { + if (op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostDecrement) + newValue = (TypedValue)VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Subtract, new PrimitiveExpression(1)), null); + if (op == UnaryOperatorType.Increment || op == UnaryOperatorType.PostIncrement) + newValue = (TypedValue)VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Add, new PrimitiveExpression(1)), null); + } catch (EvaluateException e) { + throw new EvaluateException(unaryOperatorExpression, e.Message); + } + if (op == UnaryOperatorType.PostDecrement || op == UnaryOperatorType.PostIncrement) { + return oldValue; + } else { + // Note: the old unaryOparatorExpression is still cached and still has the old value + return newValue; + } + } + + if (op == UnaryOperatorType.Minus) { + object val = value.PrimitiveValue; + // Special case - it would promote the value to long otherwise + if (val is uint && (uint)val == (uint)1 << 31) + return CreateValue(int.MinValue); + + // Special case - it would overflow otherwise + if (val is ulong && (ulong)val == (ulong)1 << 63) + return CreateValue(long.MinValue); + } + + if (op == UnaryOperatorType.Plus || op == UnaryOperatorType.Minus || + op == UnaryOperatorType.BitNot || op == UnaryOperatorType.Not) + { + Type[] overloads; + if (op == UnaryOperatorType.Not) { + overloads = new Type[] { typeof(bool) }; + } else if (op == UnaryOperatorType.Minus) { + overloads = new Type[] { typeof(int), typeof(long), typeof(ulong), typeof(float), typeof(double) }; + } else { + overloads = new Type[] { typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double) }; + } + foreach(Type argType in overloads) { + if (value.Type.CanPromoteTo(argType)) { + object a = Convert.ChangeType(value.PrimitiveValue, argType); + object res; + try { + res = PerformUnaryOperation(a, op, argType); + } catch (ArithmeticException e) { + // Can happen for smaller int or long + throw new EvaluateException(unaryOperatorExpression, e.Message); + } + if (res != null) + return CreateValue(res); + break; // Match only one overload + } + } + } + + throw new EvaluateException(unaryOperatorExpression, "Can not use the unary operator {0} on type {1}", op.ToString(), value.Type.FullName); + } + + /// + /// Perform given arithmetic operation. + /// The arguments must be already converted to the correct types. + /// + object PerformUnaryOperation(object val, UnaryOperatorType op, Type argType) + { + checked { + if (argType == typeof(bool)) { + bool a = (bool)val; + switch (op) { + case UnaryOperatorType.Not: return !a; + } + } + + if (argType == typeof(float)) { + float a = (float)val; + switch (op) { + case UnaryOperatorType.Minus: return -a; + case UnaryOperatorType.Plus: return +a; + } + } + + if (argType == typeof(double)) { + double a = (double)val; + switch (op) { + case UnaryOperatorType.Minus: return -a; + case UnaryOperatorType.Plus: return +a; + } + } + + if (argType == typeof(int)) { + int a = (int)val; + switch (op) { + case UnaryOperatorType.Minus: return -a; + case UnaryOperatorType.Plus: return +a; + case UnaryOperatorType.BitNot: return ~a; + } + } + + if (argType == typeof(uint)) { + uint a = (uint)val; + switch (op) { + case UnaryOperatorType.Plus: return +a; + case UnaryOperatorType.BitNot: return ~a; + } + } + + if (argType == typeof(long)) { + long a = (long)val; + switch (op) { + case UnaryOperatorType.Minus: return -a; + case UnaryOperatorType.Plus: return +a; + case UnaryOperatorType.BitNot: return ~a; + } + } + + if (argType == typeof(ulong)) { + ulong a = (ulong)val; + switch (op) { + case UnaryOperatorType.Plus: return +a; + case UnaryOperatorType.BitNot: return ~a; + } + } + } + + return null; + } + + public object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) + { + BinaryOperatorType op = binaryOperatorExpression.Op; + + TypedValue left = Evaluate(binaryOperatorExpression.Left); + TypedValue right = Evaluate(binaryOperatorExpression.Right); + + // Try to apply any implicit binary operation + // Be careful to do these in correct order + + // ==, != + // bool operator ==(string x, string y); + // + // ==, != C is not Value type; other rules apply (must be after string) + // bool operator ==(C x, C y); + + if (op == BinaryOperatorType.Equality || op == BinaryOperatorType.InEquality) { + if (left.Type.Is() && right.Type.Is()) { + if (left.Value.IsNull || right.Value.IsNull) { + return CreateValue(left.Value.IsNull && right.Value.IsNull); + } else { + return CreateValue((string)left.PrimitiveValue == (string)right.PrimitiveValue); + } + } + if (!left.Type.IsValueType && !right.Type.IsValueType) { + // Reference comparison + if (left.Value.IsNull || right.Value.IsNull) { + return CreateValue(left.Value.IsNull && right.Value.IsNull); + } else { + return CreateValue(left.Value.Address == right.Value.Address); + } + } + } + + // + + // string operator +(string x, string y); + // string operator +(string x, object y); + // string operator +(object x, string y); + + if (op == BinaryOperatorType.Add) { + if (left.Type.Is() || right.Type.Is()) { + string a = left.Value.IsNull ? string.Empty : left.Value.InvokeToString(); + string b = right.Value.IsNull ? string.Empty : right.Value.InvokeToString(); + return CreateValue(a + b); + } + } + + // <<, >> + // int operator <<(int x, int count); + // uint operator <<(uint x, int count); + // long operator <<(long x, int count); + // ulong operator <<(ulong x, int count); + + if (op == BinaryOperatorType.ShiftLeft || op == BinaryOperatorType.ShiftRight) { + Type[] overloads = { typeof(int), typeof(uint), typeof(long), typeof(ulong)}; + foreach(Type argType in overloads) { + if (left.Type.CanPromoteTo(argType) && right.Type.CanPromoteTo(typeof(int))) { + object a = Convert.ChangeType(left.PrimitiveValue, argType); + object b = Convert.ChangeType(right.PrimitiveValue, typeof(int)); + // Shift operations never cause overflows + object res = PerformBinaryOperation(a, b, op, argType); + return CreateValue(res); + } + } + } + + // *, /, %, +, and – + // ==, !=, <, >, <=, >=, + // &, ^, and | (except float and double) + // int operator +(int x, int y); + // uint operator +(uint x, uint y); + // long operator +(long x, long y); + // ulong operator +(ulong x, ulong y); + // void operator +(long x, ulong y); + // void operator +(ulong x, long y); + // float operator +(float x, float y); + // double operator +(double x, double y); + // + // &, |, ^, &&, || + // ==, != + // bool operator &(bool x, bool y); + + if (op != BinaryOperatorType.ShiftLeft && op != BinaryOperatorType.ShiftRight) { + Type[] overloads = { typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(bool) }; + foreach(Type argType in overloads) { + if (left.Type.CanPromoteTo(argType) && right.Type.CanPromoteTo(argType)) { + if (argType == typeof(float) || argType == typeof(double)) { + // Invalid overloads + if (left.Type.CanPromoteTo(typeof(long)) && right.Type.CanPromoteTo(typeof(ulong))) + break; + if (left.Type.CanPromoteTo(typeof(ulong)) && right.Type.CanPromoteTo(typeof(long))) + break; + } + object a = Convert.ChangeType(left.PrimitiveValue, argType); + object b = Convert.ChangeType(right.PrimitiveValue, argType); + object res; + try { + res = PerformBinaryOperation(a, b, op, argType); + } catch (ArithmeticException e) { + throw new EvaluateException(binaryOperatorExpression, e.Message); + } + if (res != null) + return CreateValue(res); + break; // Match only one overload + } + } + } + + throw new EvaluateException(binaryOperatorExpression, "Can not use the binary operator {0} on types {1} and {2}", op.ToString(), left.Type.FullName, right.Type.FullName); + } + + /// + /// Perform given arithmetic operation. + /// The arguments must be already converted to the correct types. + /// + object PerformBinaryOperation(object left, object right, BinaryOperatorType op, Type argTypes) + { + checked { + if (argTypes == typeof(string)) { + string a = (string)left; + string b = (string)right; + switch (op) { + case BinaryOperatorType.Equality: return a == b; + case BinaryOperatorType.InEquality: return a != b; + case BinaryOperatorType.Add: return a + b; + } + } + + if (argTypes == typeof(bool)) { + bool a = (bool)left; + bool b = (bool)right; + switch (op) { + case BinaryOperatorType.Equality: return a == b; + case BinaryOperatorType.InEquality: return a != b; + case BinaryOperatorType.ExclusiveOr: return a ^ b; + case BinaryOperatorType.BitwiseAnd: return a & b; + case BinaryOperatorType.BitwiseOr: return a | b; + case BinaryOperatorType.LogicalAnd: return a && b; + case BinaryOperatorType.LogicalOr: return a || b; + } + } + + if (argTypes == typeof(float)) { + float a = (float)left; + float b = (float)right; + switch (op) { + case BinaryOperatorType.GreaterThan: return a > b; + case BinaryOperatorType.GreaterThanOrEqual: return a >= b; + case BinaryOperatorType.Equality: return a == b; + case BinaryOperatorType.InEquality: return a != b; + case BinaryOperatorType.LessThan: return a < b; + case BinaryOperatorType.LessThanOrEqual: return a <= b; + + case BinaryOperatorType.Add: return a + b; + case BinaryOperatorType.Subtract: return a - b; + case BinaryOperatorType.Multiply: return a * b; + case BinaryOperatorType.Divide: return a / b; + case BinaryOperatorType.Modulus: return a % b; + case BinaryOperatorType.Concat: return a + b; + } + } + + if (argTypes == typeof(double)) { + double a = (double)left; + double b = (double)right; + switch (op) { + case BinaryOperatorType.GreaterThan: return a > b; + case BinaryOperatorType.GreaterThanOrEqual: return a >= b; + case BinaryOperatorType.Equality: return a == b; + case BinaryOperatorType.InEquality: return a != b; + case BinaryOperatorType.LessThan: return a < b; + case BinaryOperatorType.LessThanOrEqual: return a <= b; + + case BinaryOperatorType.Add: return a + b; + case BinaryOperatorType.Subtract: return a - b; + case BinaryOperatorType.Multiply: return a * b; + case BinaryOperatorType.Divide: return a / b; + case BinaryOperatorType.Modulus: return a % b; + case BinaryOperatorType.Concat: return a + b; + } + } + + if (argTypes == typeof(int)) { + switch (op) { + case BinaryOperatorType.ShiftLeft: return (int)left << (int)right; + case BinaryOperatorType.ShiftRight: return (int)left >> (int)right; + } + int a = (int)left; + int b = (int)right; + switch (op) { + case BinaryOperatorType.BitwiseAnd: return a & b; + case BinaryOperatorType.BitwiseOr: return a | b; + case BinaryOperatorType.ExclusiveOr: return a ^ b; + + case BinaryOperatorType.GreaterThan: return a > b; + case BinaryOperatorType.GreaterThanOrEqual: return a >= b; + case BinaryOperatorType.Equality: return a == b; + case BinaryOperatorType.InEquality: return a != b; + case BinaryOperatorType.LessThan: return a < b; + case BinaryOperatorType.LessThanOrEqual: return a <= b; + + case BinaryOperatorType.Add: return a + b; + case BinaryOperatorType.Subtract: return a - b; + case BinaryOperatorType.Multiply: return a * b; + case BinaryOperatorType.Divide: return a / b; + case BinaryOperatorType.Modulus: return a % b; + case BinaryOperatorType.Concat: return a + b; + } + } + + if (argTypes == typeof(uint)) { + switch (op) { + case BinaryOperatorType.ShiftLeft: return (uint)left << (int)right; + case BinaryOperatorType.ShiftRight: return (uint)left >> (int)right; + } + uint a = (uint)left; + uint b = (uint)right; + switch (op) { + case BinaryOperatorType.BitwiseAnd: return a & b; + case BinaryOperatorType.BitwiseOr: return a | b; + case BinaryOperatorType.ExclusiveOr: return a ^ b; + + case BinaryOperatorType.GreaterThan: return a > b; + case BinaryOperatorType.GreaterThanOrEqual: return a >= b; + case BinaryOperatorType.Equality: return a == b; + case BinaryOperatorType.InEquality: return a != b; + case BinaryOperatorType.LessThan: return a < b; + case BinaryOperatorType.LessThanOrEqual: return a <= b; + + case BinaryOperatorType.Add: return a + b; + case BinaryOperatorType.Subtract: return a - b; + case BinaryOperatorType.Multiply: return a * b; + case BinaryOperatorType.Divide: return a / b; + case BinaryOperatorType.Modulus: return a % b; + case BinaryOperatorType.Concat: return a + b; + } + } + + if (argTypes == typeof(long)) { + switch (op) { + case BinaryOperatorType.ShiftLeft: return (long)left << (int)right; + case BinaryOperatorType.ShiftRight: return (long)left >> (int)right; + } + long a = (long)left; + long b = (long)right; + switch (op) { + case BinaryOperatorType.BitwiseAnd: return a & b; + case BinaryOperatorType.BitwiseOr: return a | b; + case BinaryOperatorType.ExclusiveOr: return a ^ b; + + case BinaryOperatorType.GreaterThan: return a > b; + case BinaryOperatorType.GreaterThanOrEqual: return a >= b; + case BinaryOperatorType.Equality: return a == b; + case BinaryOperatorType.InEquality: return a != b; + case BinaryOperatorType.LessThan: return a < b; + case BinaryOperatorType.LessThanOrEqual: return a <= b; + + case BinaryOperatorType.Add: return a + b; + case BinaryOperatorType.Subtract: return a - b; + case BinaryOperatorType.Multiply: return a * b; + case BinaryOperatorType.Divide: return a / b; + case BinaryOperatorType.Modulus: return a % b; + case BinaryOperatorType.Concat: return a + b; + } + } + + if (argTypes == typeof(ulong)) { + switch (op) { + case BinaryOperatorType.ShiftLeft: return (ulong)left << (int)right; + case BinaryOperatorType.ShiftRight: return (ulong)left >> (int)right; + } + ulong a = (ulong)left; + ulong b = (ulong)right; + switch (op) { + case BinaryOperatorType.BitwiseAnd: return a & b; + case BinaryOperatorType.BitwiseOr: return a | b; + case BinaryOperatorType.ExclusiveOr: return a ^ b; + + case BinaryOperatorType.GreaterThan: return a > b; + case BinaryOperatorType.GreaterThanOrEqual: return a >= b; + case BinaryOperatorType.Equality: return a == b; + case BinaryOperatorType.InEquality: return a != b; + case BinaryOperatorType.LessThan: return a < b; + case BinaryOperatorType.LessThanOrEqual: return a <= b; + + case BinaryOperatorType.Add: return a + b; + case BinaryOperatorType.Subtract: return a - b; + case BinaryOperatorType.Multiply: return a * b; + case BinaryOperatorType.Divide: return a / b; + case BinaryOperatorType.Modulus: return a % b; + case BinaryOperatorType.Concat: return a + b; + } + } + + return null; + } + } + + #endregion + } +} diff --git a/Debugger/Debugger.Core/Options.cs b/Debugger/Debugger.Core/Options.cs new file mode 100644 index 000000000..65169b1cc --- /dev/null +++ b/Debugger/Debugger.Core/Options.cs @@ -0,0 +1,19 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +namespace Debugger +{ + public class Options + { + public bool EnableJustMyCode = true; + public bool StepOverNoSymbols = true; + public bool StepOverDebuggerAttributes = true; + public bool StepOverAllProperties = false; + public bool StepOverSingleLineProperties = false; + public bool StepOverFieldAccessProperties = true; + public bool Verbose = false; + public string[] SymbolsSearchPaths = new string[0]; + public bool SuspendOtherThreads = true; + public bool EnableEditAndContinue = false; + } +} diff --git a/Debugger/Debugger.Core/PauseSession.cs b/Debugger/Debugger.Core/PauseSession.cs new file mode 100644 index 000000000..93500c867 --- /dev/null +++ b/Debugger/Debugger.Core/PauseSession.cs @@ -0,0 +1,29 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +namespace Debugger +{ + /// + /// Holds information about the state of paused debugger. + /// Expires when when Continue is called on debugger. + /// + public class PauseSession: DebuggerObject + { + Process process; + PausedReason pausedReason; + + public Process Process { + get { return process; } + } + + public PausedReason PausedReason { + get { return pausedReason; } + } + + public PauseSession(Process process, PausedReason pausedReason) + { + this.process = process; + this.pausedReason = pausedReason; + } + } +} diff --git a/Debugger/Debugger.Core/PausedReason.cs b/Debugger/Debugger.Core/PausedReason.cs new file mode 100644 index 000000000..c42471867 --- /dev/null +++ b/Debugger/Debugger.Core/PausedReason.cs @@ -0,0 +1,22 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +namespace Debugger +{ + public enum PausedReason : int + { + EvalComplete, + StepComplete, + Breakpoint, + Break, + ControlCTrap, + Exception, + ForcedBreak, // Process.Break called + DebuggerError, + CurrentThreadChanged, + CurrentFunctionChanged, + ExceptionIntercepted, + SetIP, + Other + } +} diff --git a/Debugger/Debugger.Core/Process.cs b/Debugger/Debugger.Core/Process.cs new file mode 100644 index 000000000..22df820e6 --- /dev/null +++ b/Debugger/Debugger.Core/Process.cs @@ -0,0 +1,694 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +using Debugger.Interop.CorDebug; +using Debugger.Interop.CorSym; +using ICSharpCode.NRefactory.Ast; +using ICSharpCode.NRefactory.Visitors; + +namespace Debugger +{ + internal enum DebuggeeStateAction { Keep, Clear } + + /// + /// Debug Mode Flags. + /// + public enum DebugModeFlag + { + /// + /// Run in the same mode as without debugger. + /// + Default, + /// + /// Run in forced optimized mode. + /// + Optimized, + /// + /// Run in debug mode (easy inspection) but slower. + /// + Debug, + /// + /// Run in ENC mode (ENC possible) but even slower than debug + /// + Enc + } + + public class Process: DebuggerObject + { + NDebugger debugger; + + ICorDebugProcess corProcess; + ManagedCallback callbackInterface; + + EvalCollection activeEvals; + ModuleCollection modules; + ThreadCollection threads; + AppDomainCollection appDomains; + + string workingDirectory; + + + public NDebugger Debugger { + get { return debugger; } + } + + internal ICorDebugProcess CorProcess { + get { return corProcess; } + } + + public Options Options { + get { return debugger.Options; } + } + + public string DebuggeeVersion { + get { return debugger.DebuggeeVersion; } + } + + internal ManagedCallback CallbackInterface { + get { return callbackInterface; } + } + + public EvalCollection ActiveEvals { + get { return activeEvals; } + } + + internal bool Evaluating { + get { return activeEvals.Count > 0; } + } + + public ModuleCollection Modules { + get { return modules; } + } + + public ThreadCollection Threads { + get { return threads; } + } + + public Thread SelectedThread { + get { return this.Threads.Selected; } + set { this.Threads.Selected = value; } + } + + public StackFrame SelectedStackFrame { + get { + if (SelectedThread == null) { + return null; + } else { + return SelectedThread.SelectedStackFrame; + } + } + } + + public SourcecodeSegment NextStatement { + get { + if (SelectedStackFrame == null || IsRunning) { + return null; + } else { + return SelectedStackFrame.NextStatement; + } + } + } + + public bool BreakAtBeginning { + get; + set; + } + + public AppDomainCollection AppDomains { + get { return appDomains; } + } + + List steppers = new List(); + + internal List Steppers { + get { return steppers; } + } + + public string WorkingDirectory { + get { return workingDirectory; } + } + + public static DebugModeFlag DebugMode { get; set; } + + internal Process(NDebugger debugger, ICorDebugProcess corProcess, string workingDirectory) + { + this.debugger = debugger; + this.corProcess = corProcess; + this.workingDirectory = workingDirectory; + + this.callbackInterface = new ManagedCallback(this); + + activeEvals = new EvalCollection(debugger); + modules = new ModuleCollection(debugger); + modules.Added += OnModulesAdded; + threads = new ThreadCollection(debugger); + appDomains = new AppDomainCollection(debugger); + } + + static unsafe public Process CreateProcess(NDebugger debugger, string filename, string workingDirectory, string arguments) + { + debugger.TraceMessage("Executing " + filename + " " + arguments); + + uint[] processStartupInfo = new uint[17]; + processStartupInfo[0] = sizeof(uint) * 17; + uint[] processInfo = new uint[4]; + + ICorDebugProcess outProcess; + + if (workingDirectory == null || workingDirectory == "") { + workingDirectory = System.IO.Path.GetDirectoryName(filename); + } + + _SECURITY_ATTRIBUTES secAttr = new _SECURITY_ATTRIBUTES(); + secAttr.bInheritHandle = 0; + secAttr.lpSecurityDescriptor = IntPtr.Zero; + secAttr.nLength = (uint)sizeof(_SECURITY_ATTRIBUTES); + + fixed (uint* pprocessStartupInfo = processStartupInfo) + fixed (uint* pprocessInfo = processInfo) + outProcess = + debugger.CorDebug.CreateProcess( + filename, // lpApplicationName + // If we do not prepend " ", the first argument migh just get lost + " " + arguments, // lpCommandLine + ref secAttr, // lpProcessAttributes + ref secAttr, // lpThreadAttributes + 1,//TRUE // bInheritHandles + 0x00000010 /*CREATE_NEW_CONSOLE*/, // dwCreationFlags + IntPtr.Zero, // lpEnvironment + workingDirectory, // lpCurrentDirectory + (uint)pprocessStartupInfo, // lpStartupInfo + (uint)pprocessInfo, // lpProcessInformation, + CorDebugCreateProcessFlags.DEBUG_NO_SPECIAL_OPTIONS // debuggingFlags + ); + + return new Process(debugger, outProcess, workingDirectory); + } + + /// Fired when System.Diagnostics.Trace.WriteLine() is called in debuged process + public event EventHandler LogMessage; + + protected internal virtual void OnLogMessage(MessageEventArgs arg) + { + TraceMessage ("Debugger event: OnLogMessage"); + if (LogMessage != null) { + LogMessage(this, arg); + } + } + + public void TraceMessage(string message, params object[] args) + { + if (args.Length > 0) + message = string.Format(message, args); + System.Diagnostics.Debug.WriteLine("Debugger:" + message); + debugger.OnDebuggerTraceMessage(new MessageEventArgs(this, message)); + } + + /// Read the specified amount of memory at the given memory address + /// The content of the memory. The amount of the read memory may be less then requested. + public unsafe byte[] ReadMemory(ulong address, int size) + { + byte[] buffer = new byte[size]; + int readCount; + fixed(byte* pBuffer = buffer) { + readCount = (int)corProcess.ReadMemory(address, (uint)size, new IntPtr(pBuffer)); + } + if (readCount != size) Array.Resize(ref buffer, readCount); + return buffer; + } + + /// Writes the given buffer at the specified memory address + /// The number of bytes written + public unsafe int WriteMemory(ulong address, byte[] buffer) + { + if (buffer.Length == 0) return 0; + int written; + fixed(byte* pBuffer = buffer) { + written = (int)corProcess.WriteMemory(address, (uint)buffer.Length, new IntPtr(pBuffer)); + } + return written; + } + + #region Exceptions + + bool pauseOnHandledException = false; + + public event EventHandler ExceptionThrown; + + public bool PauseOnHandledException { + get { return pauseOnHandledException; } + set { pauseOnHandledException = value; } + } + + protected internal virtual void OnExceptionThrown(ExceptionEventArgs e) + { + TraceMessage ("Debugger event: OnExceptionThrown()"); + if (ExceptionThrown != null) { + ExceptionThrown(this, e); + } + } + + #endregion + + // State control for the process + + internal bool TerminateCommandIssued = false; + internal Queue BreakpointHitEventQueue = new Queue(); + internal Dictionary ExpressionsCache = new Dictionary(); + + #region Events + + public event EventHandler Paused; + public event EventHandler Resumed; + + // HACK: public + public virtual void OnPaused() + { + AssertPaused(); + // No real purpose - just additional check + if (callbackInterface.IsInCallback) throw new DebuggerException("Can not raise event within callback."); + TraceMessage ("Debugger event: OnPaused()"); + if (Paused != null) { + foreach(Delegate d in Paused.GetInvocationList()) { + if (IsRunning) { + TraceMessage ("Skipping OnPaused delegate because process has resumed"); + break; + } + if (this.TerminateCommandIssued || this.HasExited) { + TraceMessage ("Skipping OnPaused delegate because process has exited"); + break; + } + d.DynamicInvoke(this, new ProcessEventArgs(this)); + } + } + } + + protected virtual void OnResumed() + { + AssertRunning(); + if (callbackInterface.IsInCallback) + throw new DebuggerException("Can not raise event within callback."); + TraceMessage ("Debugger event: OnResumed()"); + if (Resumed != null) { + Resumed(this, new ProcessEventArgs(this)); + } + } + + #endregion + + #region PauseSession & DebugeeState + + PauseSession pauseSession; + DebuggeeState debuggeeState; + + /// + /// Indentification of the current debugger session. This value changes whenever debugger is continued + /// + public PauseSession PauseSession { + get { return pauseSession; } + } + + /// + /// Indentification of the state of the debugee. This value changes whenever the state of the debugee significatntly changes + /// + public DebuggeeState DebuggeeState { + get { return debuggeeState; } + } + + /// Puts the process into a paused state + internal void NotifyPaused(PausedReason pauseReason) + { + AssertRunning(); + pauseSession = new PauseSession(this, pauseReason); + if (debuggeeState == null) { + debuggeeState = new DebuggeeState(this); + } + } + + /// Puts the process into a resumed state + internal void NotifyResumed(DebuggeeStateAction action) + { + AssertPaused(); + pauseSession = null; + if (action == DebuggeeStateAction.Clear) { + if (debuggeeState == null) throw new DebuggerException("Debugee state already cleared"); + debuggeeState = null; + this.ExpressionsCache.Clear(); + } + } + + /// Sets up the eviroment and raises user events + internal void RaisePausedEvents() + { + AssertPaused(); + DisableAllSteppers(); + CheckSelectedStackFrames(); + SelectMostRecentStackFrameWithLoadedSymbols(); + + if (this.PauseSession.PausedReason == PausedReason.Exception) { + ExceptionEventArgs args = new ExceptionEventArgs(this, this.SelectedThread.CurrentException, this.SelectedThread.CurrentExceptionType, this.SelectedThread.CurrentExceptionIsUnhandled); + OnExceptionThrown(args); + // The event could have resumed or killed the process + if (this.IsRunning || this.TerminateCommandIssued || this.HasExited) return; + } + + while(BreakpointHitEventQueue.Count > 0) { + Breakpoint breakpoint = BreakpointHitEventQueue.Dequeue(); + breakpoint.NotifyHit(); + // The event could have resumed or killed the process + if (this.IsRunning || this.TerminateCommandIssued || this.HasExited) return; + } + + OnPaused(); + // The event could have resumed the process + if (this.IsRunning || this.TerminateCommandIssued || this.HasExited) return; + } + + #endregion + + internal void AssertPaused() + { + if (IsRunning) { + throw new DebuggerException("Process is not paused."); + } + } + + internal void AssertRunning() + { + if (IsPaused) { + throw new DebuggerException("Process is not running."); + } + } + + public bool IsRunning { + get { return pauseSession == null; } + } + + public bool IsPaused { + get { return !IsRunning; } + } + + bool hasExited = false; + + public event EventHandler Exited; + + public bool HasExited { + get { + return hasExited; + } + } + + internal void NotifyHasExited() + { + if(!hasExited) { + hasExited = true; + if (Exited != null) { + Exited(this, new ProcessEventArgs(this)); + } + // Expire pause seesion first + if (IsPaused) { + NotifyResumed(DebuggeeStateAction.Clear); + } + debugger.Processes.Remove(this); + } + } + + public void Break() + { + AssertRunning(); + + corProcess.Stop(uint.MaxValue); // Infinite; ignored anyway + + NotifyPaused(PausedReason.ForcedBreak); + RaisePausedEvents(); + } + + public void Detach() + { + if (IsRunning) { + corProcess.Stop(uint.MaxValue); + NotifyPaused(PausedReason.ForcedBreak); + } + + // This is necessary for detach + foreach(Stepper s in this.Steppers) { + if (s.CorStepper.IsActive() == 1) { + s.CorStepper.Deactivate(); + } + } + this.Steppers.Clear(); + + corProcess.Detach(); + + // modules + foreach(Module m in this.Modules) + { + m.Dispose(); + } + + this.modules.Clear(); + + // threads + this.threads.Clear(); + + NotifyHasExited(); + } + + public void Continue() + { + AsyncContinue(); + WaitForPause(); + } + + internal Thread[] UnsuspendedThreads { + get { + List unsuspendedThreads = new List(this.Threads.Count); + foreach(Thread t in this.Threads) { + if (!t.Suspended) + unsuspendedThreads.Add(t); + } + return unsuspendedThreads.ToArray(); + } + } + + /// + /// Resume execution and run all threads not marked by the user as susspended. + /// + public void AsyncContinue() + { + AsyncContinue(DebuggeeStateAction.Clear, this.UnsuspendedThreads, CorDebugThreadState.THREAD_RUN); + } + + internal CorDebugThreadState NewThreadState = CorDebugThreadState.THREAD_RUN; + + /// Null to keep current setting + /// What happens to created threads. Null to keep current setting + internal void AsyncContinue(DebuggeeStateAction action, Thread[] threadsToRun, CorDebugThreadState? newThreadState) + { + AssertPaused(); + + if (threadsToRun != null) { +// corProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_SUSPEND, null); +// Note: There is unreported thread, stopping it prevents the debugee from exiting +// It is not corProcess.GetHelperThreadID +// ICorDebugThread[] ts = new ICorDebugThread[corProcess.EnumerateThreads().GetCount()]; +// corProcess.EnumerateThreads().Next((uint)ts.Length, ts); + foreach(Thread t in this.Threads) { + CorDebugThreadState state = Array.IndexOf(threadsToRun, t) == -1 ? CorDebugThreadState.THREAD_SUSPEND : CorDebugThreadState.THREAD_RUN; + try { + t.CorThread.SetDebugState(state); + } catch (COMException e) { + // The state of the thread is invalid. (Exception from HRESULT: 0x8013132D) + // It can happen for example when thread has not started yet + if ((uint)e.ErrorCode == 0x8013132D) { + // TraceMessage("Can not suspend thread - The state of the thread is invalid. Thread ID = " + t.CorThread.GetID()); + } else { + throw; + } + } + } + } + + if (newThreadState != null) { + this.NewThreadState = newThreadState.Value; + } + + NotifyResumed(action); + corProcess.Continue(0); + if (this.Options.Verbose) { + this.TraceMessage("Continue"); + } + + if (action == DebuggeeStateAction.Clear) { + OnResumed(); + } + } + + /// Terminates the execution of the process + public void Terminate() + { + AsyncTerminate(); + // Wait until ExitProcess callback is received + WaitForExit(); + } + + /// Terminates the execution of the process + public void AsyncTerminate() + { + // Resume stoped tread + if (this.IsPaused) { + // We might get more callbacks so we should maintain consistent sate + //AsyncContinue(); // Continue the process to get remaining callbacks + } + + // Expose race condition - drain callback queue + System.Threading.Thread.Sleep(0); + + // Stop&terminate - both must be called + corProcess.Stop(uint.MaxValue); + corProcess.Terminate(0); + this.TerminateCommandIssued = true; + + // Do not mark the process as exited + // This is done once ExitProcess callback is received + } + + void SelectSomeThread() + { + if (this.SelectedThread != null && !this.SelectedThread.IsInValidState) { + this.SelectedThread = null; + } + if (this.SelectedThread == null) { + foreach(Thread thread in this.Threads) { + if (thread.IsInValidState) { + this.SelectedThread = thread; + break; + } + } + } + } + + internal void CheckSelectedStackFrames() + { + foreach(Thread thread in this.Threads) { + if (thread.IsInValidState) { + if (thread.SelectedStackFrame != null && thread.SelectedStackFrame.IsInvalid) { + thread.SelectedStackFrame = null; + } + } else { + thread.SelectedStackFrame = null; + } + } + } + + internal void SelectMostRecentStackFrameWithLoadedSymbols() + { + SelectSomeThread(); + if (this.SelectedThread != null) { + this.SelectedThread.SelectedStackFrame = null; + foreach (StackFrame stackFrame in this.SelectedThread.Callstack) { + if (stackFrame.HasSymbols) { + if (this.Options.StepOverDebuggerAttributes && stackFrame.MethodInfo.IsNonUserCode) + continue; + this.SelectedThread.SelectedStackFrame = stackFrame; + break; + } + } + } + } + + internal Stepper GetStepper(ICorDebugStepper corStepper) + { + foreach(Stepper stepper in this.Steppers) { + if (stepper.IsCorStepper(corStepper)) { + return stepper; + } + } + throw new DebuggerException("Stepper is not in collection"); + } + + internal void DisableAllSteppers() + { + foreach(Thread thread in this.Threads) { + thread.CurrentStepIn = null; + } + foreach(Stepper stepper in this.Steppers) { + stepper.Ignore = true; + } + } + + /// + /// Waits until the debugger pauses unless it is already paused. + /// Use PausedReason to find out why it paused. + /// + public void WaitForPause() + { + while(this.IsRunning && !this.HasExited) { + debugger.MTA2STA.WaitForCall(); + debugger.MTA2STA.PerformAllCalls(); + } + if (this.HasExited) throw new ProcessExitedException(); + } + + public void WaitForPause(TimeSpan timeout) + { + System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); + watch.Start(); + while(this.IsRunning && !this.HasExited) { + TimeSpan timeLeft = timeout - watch.Elapsed; + if (timeLeft <= TimeSpan.FromMilliseconds(10)) break; + //this.TraceMessage("Time left: " + timeLeft.TotalMilliseconds); + debugger.MTA2STA.WaitForCall(timeLeft); + debugger.MTA2STA.PerformAllCalls(); + } + if (this.HasExited) throw new ProcessExitedException(); + } + + /// + /// Waits until the precesses exits. + /// + public void WaitForExit() + { + while(!this.HasExited) { + debugger.MTA2STA.WaitForCall(); + debugger.MTA2STA.PerformAllCalls(); + } + } + + #region Break at begining + + private void OnModulesAdded(object sender, CollectionItemEventArgs e) + { + if (BreakAtBeginning) { + if (e.Item.SymReader == null) return; // No symbols + + try { + // create a BP at entry point + uint entryPoint = e.Item.SymReader.GetUserEntryPoint(); + if (entryPoint == 0) return; // no EP + var mainFunction = e.Item.CorModule.GetFunctionFromToken(entryPoint); + var corBreakpoint = mainFunction.CreateBreakpoint(); + corBreakpoint.Activate(1); + + // create a SD BP + var breakpoint = new Breakpoint(this.debugger, corBreakpoint); + this.debugger.Breakpoints.Add(breakpoint); + breakpoint.Hit += delegate { + if (breakpoint != null) + breakpoint.Remove(); + breakpoint = null; + }; + } catch { + // the app does not have an entry point - COM exception + } + BreakAtBeginning = false; + } + } + + #endregion + } +} diff --git a/Debugger/Debugger.Core/ProcessCollection.cs b/Debugger/Debugger.Core/ProcessCollection.cs new file mode 100644 index 000000000..b15553192 --- /dev/null +++ b/Debugger/Debugger.Core/ProcessCollection.cs @@ -0,0 +1,34 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public class ProcessCollection: CollectionWithEvents + { + public ProcessCollection(NDebugger debugger): base(debugger) {} + + internal Process this[ICorDebugProcess corProcess] { + get { + foreach (Process process in this) { + if (process.CorProcess == corProcess) { + return process; + } + } + return null; + } + } + + protected override void OnRemoved(Process item) + { + base.OnRemoved(item); + + if (this.Count == 0) { + // Exit callback and then terminate the debugger + this.Debugger.MTA2STA.AsyncCall( delegate { this.Debugger.TerminateDebugger(); } ); + } + } + } +} diff --git a/Debugger/Debugger.Core/ProcessEventArgs.cs b/Debugger/Debugger.Core/ProcessEventArgs.cs new file mode 100644 index 000000000..e28f81aa1 --- /dev/null +++ b/Debugger/Debugger.Core/ProcessEventArgs.cs @@ -0,0 +1,22 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Debugger +{ + [Serializable] + public class ProcessEventArgs: DebuggerEventArgs + { + Process process; + + public Process Process { + get { return process; } + } + + public ProcessEventArgs(Process process): base(process == null ? null : process.Debugger) + { + this.process = process; + } + } +} diff --git a/Debugger/Debugger.Core/Properties/AssemblyInfo.cs b/Debugger/Debugger.Core/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..6c9f5b87c --- /dev/null +++ b/Debugger/Debugger.Core/Properties/AssemblyInfo.cs @@ -0,0 +1,17 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System.Reflection; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("Debugger Library")] +[assembly: AssemblyDescription("Library for debugging .NET applications")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyCopyright("2005-2008 David Srbecký")] +[assembly: AssemblyVersion("4.0.0.0")] diff --git a/Debugger/Debugger.Core/SourcecodeSegment.cs b/Debugger/Debugger.Core/SourcecodeSegment.cs new file mode 100644 index 000000000..d9150899e --- /dev/null +++ b/Debugger/Debugger.Core/SourcecodeSegment.cs @@ -0,0 +1,342 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; + +using Debugger.Interop.CorDebug; +using Debugger.Interop.CorSym; + +namespace Debugger +{ + public class SourcecodeSegment: DebuggerObject + { + Module module; + + string filename; + byte[] checkSum; + int startLine; + int startColumn; + int endLine; + int endColumn; + + ICorDebugFunction corFunction; + int ilStart; + int ilEnd; + int[] stepRanges; + + public Module Module { + get { return module; } + } + + public string Filename { + get { return filename; } + } + + public byte[] CheckSum { + get { return checkSum; } + } + + public int StartLine { + get { return startLine; } + } + + public int StartColumn { + get { return startColumn; } + } + + public int EndLine { + get { return endLine; } + } + + public int EndColumn { + get { return endColumn; } + } + + internal ICorDebugFunction CorFunction { + get { return corFunction; } + } + + public int ILStart { + get { return ilStart; } + } + + public int ILEnd { + get { return ilEnd; } + } + + public int[] StepRanges { + get { return stepRanges; } + } + + private SourcecodeSegment() + { + } + + /// + /// Use the module path to figure out where to look for the source file + /// + static IEnumerable RelocateSymURL(Module module, string symUrl) + { + string modulePath = module.Process.WorkingDirectory; + if (module.IsInMemory || module.IsDynamic) { + // Just use any module with symboles + foreach(Module m in module.Process.Modules) { + if (m.HasSymbols) { + if (!string.IsNullOrEmpty(m.FullPath)) { + modulePath = Path.GetDirectoryName(m.FullPath); + break; + } + } + } + } else { + if (!string.IsNullOrEmpty(module.FullPath)) + modulePath = Path.GetDirectoryName(module.FullPath); + } + if (string.IsNullOrEmpty(modulePath)) { + yield return symUrl; + yield break; + } + + if (Path.IsPathRooted(symUrl)) { + Dictionary returned = new Dictionary(); + + // Try without relocating + returned.Add(symUrl, null); + yield return symUrl; + + // The two paths to combine + string[] moduleDirs = modulePath.Split('\\'); + string[] urlDirs = symUrl.Split('\\'); + + // Join the paths at some point (joining directry must match) + for (int i = 0; i < moduleDirs.Length; i++) { + for (int j = 0; j < urlDirs.Length; j++) { + if (!string.IsNullOrEmpty(moduleDirs[i]) && + !string.IsNullOrEmpty(urlDirs[j]) && + string.Equals(moduleDirs[i], urlDirs[j], StringComparison.OrdinalIgnoreCase)) + { + // Join the paths + string[] joinedDirs = new string[i + (urlDirs.Length - j)]; + Array.Copy(moduleDirs, joinedDirs, i); + Array.Copy(urlDirs, j, joinedDirs, i, urlDirs.Length - j); + string joined = string.Join(@"\", joinedDirs); + + // Return joined path + if (!returned.ContainsKey(joined)) { + returned.Add(joined, null); + yield return joined; + } + } + } + } + } else { + if (symUrl.StartsWith(@".\")) symUrl = symUrl.Substring(2); + if (symUrl.StartsWith(@"\")) symUrl = symUrl.Substring(1); + // Try 0, 1 and 2 levels above the module directory + string dir = modulePath; + if (!string.IsNullOrEmpty(dir)) yield return Path.Combine(dir, symUrl); + dir = Path.GetDirectoryName(dir); + if (!string.IsNullOrEmpty(dir)) yield return Path.Combine(dir, symUrl); + dir = Path.GetDirectoryName(dir); + if (!string.IsNullOrEmpty(dir)) yield return Path.Combine(dir, symUrl); + } + } + + static ISymUnmanagedDocument GetSymDocumentFromFilename(Module module, string filename, byte[] checksum) + { + if (filename == null) throw new ArgumentNullException("filename"); + + if (Path.IsPathRooted(filename)) { + foreach(ISymUnmanagedDocument symDoc in module.SymDocuments) { + foreach (string url in RelocateSymURL(module, symDoc.GetURL())) { + if (string.Equals(url, filename, StringComparison.OrdinalIgnoreCase)) + return symDoc; + } + } + } else { + foreach(ISymUnmanagedDocument symDoc in module.SymDocuments) { + if (filename.StartsWith(@".\")) filename = filename.Substring(2); + if (filename.StartsWith(@"\")) filename = filename.Substring(1); + if (symDoc.GetURL().ToLowerInvariant().EndsWith(@"\" + filename.ToLowerInvariant())) { + return symDoc; + } + } + } + + return null; + } + + public static SourcecodeSegment Resolve(Module module, string fileName, byte[] checkSum, int line, int column) + { + // Do not use ISymUnmanagedReader.GetDocument! It is broken if two files have the same name + // Do not use ISymUnmanagedMethod.GetOffset! It sometimes returns negative offset + + ISymUnmanagedReader symReader = module.SymReader; + if (symReader == null) return null; // No symbols + + ISymUnmanagedDocument symDoc = GetSymDocumentFromFilename(module, fileName, checkSum); + if (symDoc == null) return null; // Document not found + + ISymUnmanagedMethod symMethod; + try { + uint validLine = symDoc.FindClosestLine((uint)line); + symMethod = symReader.GetMethodFromDocumentPosition(symDoc, (uint)validLine, (uint)column); + } catch { + return null; //Not found + } + + SequencePoint[] seqPoints = symMethod.GetSequencePoints(); + Array.Sort(seqPoints); + if (seqPoints.Length == 0) return null; + if (line < seqPoints[0].Line) return null; + foreach(SequencePoint sqPoint in seqPoints) { + if (sqPoint.Line == 0xFEEFEE) continue; + // If the desired breakpoint position is before the end of the sequence point + if (line < sqPoint.EndLine || (line == sqPoint.EndLine && column < sqPoint.EndColumn)) { + SourcecodeSegment segment = new SourcecodeSegment(); + segment.module = module; + segment.filename = symDoc.GetURL(); + segment.checkSum = symDoc.GetCheckSum(); + segment.startLine = (int)sqPoint.Line; + segment.startColumn = (int)sqPoint.Column; + segment.endLine = (int)sqPoint.EndLine; + segment.endColumn = (int)sqPoint.EndColumn; + segment.corFunction = module.CorModule.GetFunctionFromToken(symMethod.GetToken()); + segment.ilStart = (int)sqPoint.Offset; + segment.ilEnd = (int)sqPoint.Offset; + segment.stepRanges = null; + return segment; + } + } + return null; + } + + static string GetFilenameFromSymDocument(Module module, ISymUnmanagedDocument symDoc) + { + foreach (string filename in RelocateSymURL(module, symDoc.GetURL())) { + if (File.Exists(filename)) + return filename; + } + return symDoc.GetURL(); + } + + /// + /// 'ILStart <= ILOffset <= ILEnd' and this range includes at least + /// the returned area of source code. (May incude some extra compiler generated IL too) + /// + internal static SourcecodeSegment Resolve(Module module, ICorDebugFunction corFunction, int offset) + { + ISymUnmanagedReader symReader = module.SymReader; + if (symReader == null) return null; // No symbols + + ISymUnmanagedMethod symMethod; + try { + symMethod = symReader.GetMethod(corFunction.GetToken()); + } catch (COMException) { + // Can not find the method + // eg. Compiler generated constructors are not in symbol store + return null; + } + if (symMethod == null) return null; + + uint sequencePointCount = symMethod.GetSequencePointCount(); + SequencePoint[] sequencePoints = symMethod.GetSequencePoints(); + + // Get i for which: offsets[i] <= offset < offsets[i + 1] + // or fallback to first element if offset < offsets[0] + for (int i = (int)sequencePointCount - 1; i >= 0; i--) { // backwards + if ((int)sequencePoints[i].Offset <= offset || i == 0) { + // Set inforamtion about current IL range + int codeSize = (int)corFunction.GetILCode().GetSize(); + + int ilStart = (int)sequencePoints[i].Offset; + int ilEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i+1].Offset : codeSize; + + // 0xFeeFee means "code generated by compiler" + // If we are in generated sequence use to closest real one instead, + // extend the ILStart and ILEnd to include the 'real' sequence + + // Look ahead for 'real' sequence + while (i + 1 < sequencePointCount && sequencePoints[i].Line == 0xFeeFee) { + i++; + ilEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i+1].Offset : codeSize; + } + // Look back for 'real' sequence + while (i - 1 >= 0 && sequencePoints[i].Line == 0xFeeFee) { + i--; + ilStart = (int)sequencePoints[i].Offset; + } + // Wow, there are no 'real' sequences + if (sequencePoints[i].Line == 0xFeeFee) { + return null; + } + + List stepRanges = new List(); + for (int j = 0; j < sequencePointCount; j++) { + // Step over compiler generated sequences and current statement + // 0xFeeFee means "code generated by compiler" + if (sequencePoints[j].Line == 0xFeeFee || j == i) { + // Add start offset or remove last end (to connect two ranges into one) + if (stepRanges.Count > 0 && stepRanges[stepRanges.Count - 1] == sequencePoints[j].Offset) { + stepRanges.RemoveAt(stepRanges.Count - 1); + } else { + stepRanges.Add((int)sequencePoints[j].Offset); + } + // Add end offset | handle last sequence point + if (j + 1 < sequencePointCount) { + stepRanges.Add((int)sequencePoints[j+1].Offset); + } else { + stepRanges.Add(codeSize); + } + } + } + + SourcecodeSegment segment = new SourcecodeSegment(); + segment.module = module; + segment.filename = GetFilenameFromSymDocument(module, sequencePoints[i].Document); + segment.checkSum = sequencePoints[i].Document.GetCheckSum(); + segment.startLine = (int)sequencePoints[i].Line; + segment.startColumn = (int)sequencePoints[i].Column; + segment.endLine = (int)sequencePoints[i].EndLine; + segment.endColumn = (int)sequencePoints[i].EndColumn; + segment.corFunction = corFunction; + segment.ilStart = ilStart; + segment.ilEnd = ilEnd; + segment.stepRanges = stepRanges.ToArray(); + + // VB.NET sometimes produces temporary files which it then deletes + // (eg 17d14f5c-a337-4978-8281-53493378c1071.vb) + string filename = Path.GetFileName(segment.filename); + if (filename.Length == 40 && filename.EndsWith(".vb")) { + bool guidName = true; + foreach(char c in filename.Substring(0, filename.Length - 3)) { + if (('0' <= c && c <= '9') || + ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F') || + (c == '-')) + { + guidName = true; + } else { + guidName = false; + break; + } + } + if (guidName) + return null; + } + + return segment; + } + } + return null; + } + + public override string ToString() + { + return string.Format("{0}:{1},{2}-{3},{4}", Path.GetFileName(this.Filename), this.startLine, this.startColumn, this.endLine, this.endColumn); + } + } +} diff --git a/Debugger/Debugger.Core/StackFrame.cs b/Debugger/Debugger.Core/StackFrame.cs new file mode 100644 index 000000000..2f0858c23 --- /dev/null +++ b/Debugger/Debugger.Core/StackFrame.cs @@ -0,0 +1,408 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +using Debugger.MetaData; +using Debugger.Interop.CorDebug; +using Debugger.Interop.MetaData; + +namespace Debugger +{ + /// + /// A stack frame which is being executed on some thread. + /// Use to obtain arguments or local variables. + /// + public class StackFrame: DebuggerObject + { + Thread thread; + AppDomain appDomain; + Process process; + + ICorDebugILFrame corILFrame; + object corILFramePauseSession; + ICorDebugFunction corFunction; + + DebugMethodInfo methodInfo; + uint chainIndex; + uint frameIndex; + + /// The process in which this stack frame is executed + public AppDomain AppDomain { + get { return appDomain; } + } + + public Process Process { + get { return process; } + } + + /// Get the method which this stack frame is executing + public DebugMethodInfo MethodInfo { + get { return methodInfo; } + } + + /// A thread in which the stack frame is executed + public Thread Thread { + get { return thread; } + } + + /// Internal index of the stack chain. The value is increasing with age. + public uint ChainIndex { + get { return chainIndex; } + } + + /// Internal index of the stack frame. The value is increasing with age. + public uint FrameIndex { + get { return frameIndex; } + } + + + /// True if the stack frame has symbols defined. + /// (That is has accesss to the .pdb file) + public bool HasSymbols { + get { + return GetSegmentForOffet(0) != null; + } + } + + /// Returns true is this incance can not be used any more. + public bool IsInvalid { + get { + try { + object frame = this.CorILFrame; + return false; + } catch (DebuggerException) { + return true; + } + } + } + + internal StackFrame(Thread thread, ICorDebugILFrame corILFrame, uint chainIndex, uint frameIndex) + { + this.process = thread.Process; + this.thread = thread; + this.appDomain = process.AppDomains[corILFrame.GetFunction().GetClass().GetModule().GetAssembly().GetAppDomain()]; + this.corILFrame = corILFrame; + this.corILFramePauseSession = process.PauseSession; + this.corFunction = corILFrame.GetFunction(); + this.chainIndex = chainIndex; + this.frameIndex = frameIndex; + + MetaDataImport metaData = thread.Process.Modules[corFunction.GetClass().GetModule()].MetaData; + int methodGenArgs = metaData.EnumGenericParams(corFunction.GetToken()).Length; + // Class parameters are first, then the method ones + List corGenArgs = ((ICorDebugILFrame2)corILFrame).EnumerateTypeParameters().ToList(); + // Remove method parametrs at the end + corGenArgs.RemoveRange(corGenArgs.Count - methodGenArgs, methodGenArgs); + List genArgs = new List(corGenArgs.Count); + foreach(ICorDebugType corGenArg in corGenArgs) { + genArgs.Add(DebugType.CreateFromCorType(this.AppDomain, corGenArg)); + } + + DebugType debugType = DebugType.CreateFromCorClass( + this.AppDomain, + null, + corFunction.GetClass(), + genArgs.ToArray() + ); + this.methodInfo = (DebugMethodInfo)debugType.GetMember(corFunction.GetToken()); + } + + /// Returns diagnostic description of the frame + public override string ToString() + { + return this.MethodInfo.ToString(); + } + + internal ICorDebugILFrame CorILFrame { + get { + if (corILFramePauseSession != process.PauseSession) { + // Reobtain the stackframe + StackFrame stackFrame = this.Thread.GetStackFrameAt(chainIndex, frameIndex); + if (stackFrame.MethodInfo != this.MethodInfo) throw new DebuggerException("The stack frame on the thread does not represent the same method anymore"); + corILFrame = stackFrame.corILFrame; + corILFramePauseSession = stackFrame.corILFramePauseSession; + } + return corILFrame; + } + } + + [Debugger.Tests.Ignore] + public int IP { + get { + uint corInstructionPtr; + CorDebugMappingResult mappingResult; + CorILFrame.GetIP(out corInstructionPtr, out mappingResult); + return (int)corInstructionPtr; + } + } + + SourcecodeSegment GetSegmentForOffet(int offset) + { + return SourcecodeSegment.Resolve(this.MethodInfo.DebugModule, corFunction, offset); + } + + /// Step into next instruction + public void StepInto() + { + AsyncStepInto(); + process.WaitForPause(); + } + + /// Step over next instruction + public void StepOver() + { + AsyncStepOver(); + process.WaitForPause(); + } + + /// Step out of the stack frame + public void StepOut() + { + AsyncStepOut(); + process.WaitForPause(); + } + + /// Step into next instruction + public void AsyncStepInto() + { + AsyncStep(true); + } + + /// Step over next instruction + public void AsyncStepOver() + { + AsyncStep(false); + } + + /// Step out of the stack frame + public void AsyncStepOut() + { + Stepper.StepOut(this, "normal"); + + AsyncContinue(); + } + + void AsyncStep(bool stepIn) + { + if (this.MethodInfo.DebugModule.HasSymbols == false) { + throw new DebuggerException("Unable to step. No symbols loaded."); + } + + SourcecodeSegment nextSt = NextStatement; + if (nextSt == null) { + throw new DebuggerException("Unable to step. Next statement not aviable"); + } + + if (stepIn) { + Stepper stepInStepper = Stepper.StepIn(this, nextSt.StepRanges, "normal"); + this.Thread.CurrentStepIn = stepInStepper; + Stepper clearCurrentStepIn = Stepper.StepOut(this, "clear current step in"); + clearCurrentStepIn.StepComplete += delegate { + if (this.Thread.CurrentStepIn == stepInStepper) { + this.Thread.CurrentStepIn = null; + } + }; + clearCurrentStepIn.Ignore = true; + } else { + Stepper.StepOver(this, nextSt.StepRanges, "normal"); + } + + AsyncContinue(); + } + + void AsyncContinue() + { + if (process.Options.SuspendOtherThreads) { + process.AsyncContinue(DebuggeeStateAction.Clear, new Thread[] { this.Thread }, CorDebugThreadState.THREAD_SUSPEND); + } else { + process.AsyncContinue(DebuggeeStateAction.Clear, this.Process.UnsuspendedThreads, CorDebugThreadState.THREAD_RUN); + } + } + + /// + /// Get the information about the next statement to be executed. + /// + /// Returns null on error. + /// + public SourcecodeSegment NextStatement { + get { + return GetSegmentForOffet(IP); + } + } + + /// + /// Determine whether the instrustion pointer can be set to given location + /// + /// Best possible location. Null is not possible. + public SourcecodeSegment CanSetIP(string filename, int line, int column) + { + return SetIP(true, filename, line, column); + } + + /// + /// Set the instrustion pointer to given location + /// + /// Best possible location. Null is not possible. + public SourcecodeSegment SetIP(string filename, int line, int column) + { + return SetIP(false, filename, line, column); + } + + SourcecodeSegment SetIP(bool simulate, string filename, int line, int column) + { + process.AssertPaused(); + + SourcecodeSegment segment = SourcecodeSegment.Resolve(this.MethodInfo.DebugModule, filename, null, line, column); + + if (segment != null && segment.CorFunction.GetToken() == this.MethodInfo.MetadataToken) { + try { + if (simulate) { + CorILFrame.CanSetIP((uint)segment.ILStart); + } else { + // Invalidates all frames and chains for the current thread + CorILFrame.SetIP((uint)segment.ILStart); + process.NotifyResumed(DebuggeeStateAction.Keep); + process.NotifyPaused(PausedReason.SetIP); + process.RaisePausedEvents(); + } + } catch { + return null; + } + return segment; + } + return null; + } + + /// + /// Gets the instance of the class asociated with the current frame. + /// That is, 'this' in C#. + /// Note that for delegates and enumerators this returns the instance of the display class. + /// The get the captured this, use GetLocalVariableThis. + /// + [Debugger.Tests.Ignore] + public Value GetThisValue() + { + return new Value(appDomain, GetThisCorValue()); + } + + ICorDebugValue GetThisCorValue() + { + if (this.MethodInfo.IsStatic) throw new GetValueException("Static method does not have 'this'."); + ICorDebugValue corValue; + try { + corValue = CorILFrame.GetArgument(0); + } catch (COMException e) { + // System.Runtime.InteropServices.COMException (0x80131304): An IL variable is not available at the current native IP. (See Forum-8640) + if ((uint)e.ErrorCode == 0x80131304) throw new GetValueException("Not available in the current state"); + throw; + } + // This can be 'by ref' for value types + if (corValue.GetTheType() == (uint)CorElementType.BYREF) { + corValue = ((ICorDebugReferenceValue)corValue).Dereference(); + } + return corValue; + } + + /// Total number of arguments (excluding implicit 'this' argument) + public int ArgumentCount { + get { + ICorDebugValueEnum argumentEnum = CorILFrame.EnumerateArguments(); + uint argCount = argumentEnum.GetCount(); + if (!this.MethodInfo.IsStatic) { + argCount--; // Remove 'this' from count + } + return (int)argCount; + } + } + + /// Gets argument with a given name + /// Null if not found + public Value GetArgumentValue(string name) + { + DebugParameterInfo par = this.MethodInfo.GetParameter(name); + if (par == null) + return null; + return GetArgumentValue(par.Position); + } + + /// Gets argument with a given index + /// Zero-based index + public Value GetArgumentValue(int index) + { + return new Value(appDomain, GetArgumentCorValue(index)); + } + + ICorDebugValue GetArgumentCorValue(int index) + { + ICorDebugValue corValue; + try { + // Non-static methods include 'this' as first argument + corValue = CorILFrame.GetArgument((uint)(this.MethodInfo.IsStatic? index : (index + 1))); + } catch (COMException e) { + if ((uint)e.ErrorCode == 0x80131304) throw new GetValueException("Unavailable in optimized code"); + throw; + } + // Method arguments can be passed 'by ref' + if (corValue.GetTheType() == (uint)CorElementType.BYREF) { + try { + corValue = ((ICorDebugReferenceValue)corValue).Dereference(); + } catch (COMException e) { + if ((uint)e.ErrorCode == 0x80131305) { + // A reference value was found to be bad during dereferencing. + // This can sometimes happen after a stack overflow + throw new GetValueException("Bad reference"); + } else { + throw; + } + } + } + return corValue; + } + + /// Get local variable with given name + /// Null if not found + public Value GetLocalVariableValue(string name) + { + DebugLocalVariableInfo loc = this.MethodInfo.GetLocalVariable(this.IP, name); + if (loc == null) + return null; + return loc.GetValue(this); + } + + /// Get instance of 'this'. It works well with delegates and enumerators. + [Debugger.Tests.Ignore] + public Value GetLocalVariableThis() + { + DebugLocalVariableInfo thisVar = this.MethodInfo.GetLocalVariableThis(); + if (thisVar != null) + return thisVar.GetValue(this); + return null; + } + + public override bool Equals(object obj) + { + StackFrame other = obj as StackFrame; + return + other != null && + other.Thread == this.Thread && + other.ChainIndex == this.ChainIndex && + other.FrameIndex == this.FrameIndex && + other.MethodInfo == this.methodInfo; + } + + public override int GetHashCode() + { + int hashCode = 0; + unchecked { + if (thread != null) hashCode += 1000000009 * thread.GetHashCode(); + if (methodInfo != null) hashCode += 1000000093 * methodInfo.GetHashCode(); + hashCode += 1000000097 * chainIndex.GetHashCode(); + hashCode += 1000000103 * frameIndex.GetHashCode(); + } + return hashCode; + } + } +} diff --git a/Debugger/Debugger.Core/Stepper.cs b/Debugger/Debugger.Core/Stepper.cs new file mode 100644 index 000000000..c8bb8c8d9 --- /dev/null +++ b/Debugger/Debugger.Core/Stepper.cs @@ -0,0 +1,140 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + enum StepperOperation {StepIn, StepOver, StepOut}; + + class Stepper + { + StackFrame stackFrame; + StepperOperation operation; + int[] stepRanges; + string name; + + ICorDebugStepper corStepper; + + bool ignore; + + public event EventHandler StepComplete; + + public ICorDebugStepper CorStepper { + get { return corStepper; } + } + + public Process Process { + get { return stackFrame.Process; } + } + + public StackFrame StackFrame { + get { return stackFrame; } + } + + public StepperOperation Operation { + get { return operation; } + } + + public int[] StepRanges { + get { return stepRanges; } + } + + public string Name { + get { return name; } + } + + public bool Ignore { + get { return ignore; } + set { ignore = value; } + } + + private Stepper(StackFrame stackFrame, StepperOperation operation, int[] stepRanges, string name, bool justMyCode) + { + this.stackFrame = stackFrame; + this.operation = operation; + this.stepRanges = stepRanges; + this.name = name; + + this.corStepper = stackFrame.CorILFrame.CreateStepper(); + this.ignore = false; + this.StackFrame.Process.Steppers.Add(this); + + if (justMyCode) { + corStepper.SetUnmappedStopMask(CorDebugUnmappedStop.STOP_NONE); + ((ICorDebugStepper2)corStepper).SetJMC(1); + } + } + + protected internal virtual void OnStepComplete(CorDebugStepReason reason) { + this.corStepper = null; + if (StepComplete != null) { + StepComplete(this, new StepperEventArgs(this, reason)); + } + } + + internal bool IsCorStepper(ICorDebugStepper corStepper) + { + return this.corStepper == corStepper; + } + + internal bool IsInStepRanges(int offset) + { + for(int i = 0; i < stepRanges.Length / 2; i++) { + if (stepRanges[2*i] <= offset && offset < stepRanges[2*i + 1]) { + return true; + } + } + return false; + } + + public static Stepper StepOut(StackFrame stackFrame, string name) + { + // JMC off - Needed for multiple events. See docs\Stepping.txt + Stepper stepper = new Stepper(stackFrame, StepperOperation.StepOut, null, name, false); + stepper.corStepper.StepOut(); + return stepper; + } + + public static Stepper StepIn(StackFrame stackFrame, int[] stepRanges, string name) + { + Stepper stepper = new Stepper(stackFrame, StepperOperation.StepIn, stepRanges, name, stackFrame.Process.Options.EnableJustMyCode); + stepper.corStepper.StepRange(true /* step in */, stepRanges); + return stepper; + } + + public static Stepper StepOver(StackFrame stackFrame, int[] stepRanges, string name) + { + Stepper stepper = new Stepper(stackFrame, StepperOperation.StepOver, stepRanges, name, stackFrame.Process.Options.EnableJustMyCode); + stepper.corStepper.StepRange(false /* step over */, stepRanges); + return stepper; + } + + public override string ToString() + { + return string.Format("{0} from {1} name=\"{2}\"", this.Operation, this.StackFrame.ToString(), this.Name); + } + } + + [Serializable] + class StepperEventArgs: ProcessEventArgs + { + Stepper stepper; + CorDebugStepReason reason; + + public Stepper Stepper { + get { return stepper; } + } + + public CorDebugStepReason Reason { + get { return reason; } + } + + public StepperEventArgs(Stepper stepper, CorDebugStepReason reason): base(stepper.Process) + { + this.stepper = stepper; + this.reason = reason; + } + } +} diff --git a/Debugger/Debugger.Core/Stepping.txt b/Debugger/Debugger.Core/Stepping.txt new file mode 100644 index 000000000..e83afbac9 --- /dev/null +++ b/Debugger/Debugger.Core/Stepping.txt @@ -0,0 +1,7 @@ +== Notes == +- During evaluation some chains may be temporarly removed +- When two events are invoked and JMC is active, step out skips the second function +- Step out and step over works properly for exceptions +- Evaluation kills stepper overs on active frame +- StepRange callbacks go first (probably in order), StepOut callback are called after that +- StepRange is much slower then StepOut diff --git a/Debugger/Debugger.Core/Tests/ExpandAttribute.cs b/Debugger/Debugger.Core/Tests/ExpandAttribute.cs new file mode 100644 index 000000000..33e25d82d --- /dev/null +++ b/Debugger/Debugger.Core/Tests/ExpandAttribute.cs @@ -0,0 +1,13 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Debugger.Tests +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] + public class ExpandAttribute: Attribute + { + + } +} diff --git a/Debugger/Debugger.Core/Tests/IgnoreAttribute.cs b/Debugger/Debugger.Core/Tests/IgnoreAttribute.cs new file mode 100644 index 000000000..bc86ee477 --- /dev/null +++ b/Debugger/Debugger.Core/Tests/IgnoreAttribute.cs @@ -0,0 +1,13 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Debugger.Tests +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] + public class IgnoreAttribute: Attribute + { + + } +} diff --git a/Debugger/Debugger.Core/Tests/IgnoreOnExceptionAttribute.cs b/Debugger/Debugger.Core/Tests/IgnoreOnExceptionAttribute.cs new file mode 100644 index 000000000..76c1afd7b --- /dev/null +++ b/Debugger/Debugger.Core/Tests/IgnoreOnExceptionAttribute.cs @@ -0,0 +1,13 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace Debugger.Tests +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Class)] + public class IgnoreOnExceptionAttribute: Attribute + { + + } +} diff --git a/Debugger/Debugger.Core/Thread.cs b/Debugger/Debugger.Core/Thread.cs new file mode 100644 index 000000000..5ad86f2df --- /dev/null +++ b/Debugger/Debugger.Core/Thread.cs @@ -0,0 +1,388 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; + +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public class Thread: DebuggerObject + { + // AppDomain for thread can be changing + Process process; + + uint id; + ICorDebugThread corThread; + bool hasExited = false; + + Stepper currentStepIn; + + StackFrame selectedStackFrame; + + Exception currentException; + DebuggeeState currentException_DebuggeeState; + ExceptionType currentExceptionType; + bool currentExceptionIsUnhandled; + + public event EventHandler NameChanged; + public event EventHandler Exited; + + public Process Process { + get { return process; } + } + + [Debugger.Tests.Ignore] + public uint ID { + get{ return id; } + } + + public bool HasExited { + get { return hasExited; } + private set { hasExited = value; } + } + + internal Stepper CurrentStepIn { + get { return currentStepIn; } + set { currentStepIn = value; } + } + + /// From time to time the thread may be in invalid state. + public bool IsInValidState { + get { + try { + CorThread.GetUserState().ToString(); + CorThread.EnumerateChains(); + return true; + } catch (COMException e) { + // The state of the thread is invalid. + if ((uint)e.ErrorCode == 0x8013132D) { + return false; + } + throw; + } + } + } + + internal ICorDebugThread CorThread { + get { + if (hasExited) { + throw new DebuggerException("Thread has exited"); + } + return corThread; + } + } + + internal Thread(Process process, ICorDebugThread corThread) + { + this.process = process; + this.corThread = corThread; + this.id = CorThread.GetID(); + } + + internal void NotifyExited() + { + if (this.HasExited) throw new DebuggerException("Already exited"); + + process.TraceMessage("Thread " + this.ID + " exited"); + if (process.SelectedThread == this) { + process.SelectedThread = null; + } + + this.HasExited = true; + OnExited(new ThreadEventArgs(this)); + process.Threads.Remove(this); + } + + protected virtual void OnExited(ThreadEventArgs e) + { + if (Exited != null) { + Exited(this, e); + } + } + + /// If the thread is not at safe point, it is not posible to evaluate + /// on it + /// Returns false if the thread is in invalid state + public bool IsAtSafePoint { + get { + process.AssertPaused(); + + if (!IsInValidState) return false; + + return CorThread.GetUserState() != CorDebugUserState.USER_UNSAFE_POINT; + } + } + + public bool Suspended { get; set; } + + /// Returns Normal if the thread is in invalid state + public ThreadPriority Priority { + get { + process.AssertPaused(); + + if (!IsInValidState) return ThreadPriority.Normal; + + Value runTimeValue = RuntimeValue; + if (runTimeValue.IsNull) return ThreadPriority.Normal; + return (ThreadPriority)(int)runTimeValue.GetMemberValue("m_Priority").PrimitiveValue; + } + } + + /// Returns value representing the System.Threading.Thread object + /// The value is null while the thread is being created (the CreateThread callback) and + /// it may stay null during the run of the program. (probaly until the debuggee accesses + /// the System.Threading.Thread object which forces the creation) + public Value RuntimeValue { + get { + process.AssertPaused(); + + ICorDebugValue corValue = this.CorThread.GetObject(); + return new Value(process.AppDomains[this.CorThread.GetAppDomain()], corValue); + } + } + + /// Returns empty string if the thread is in invalid state + public string Name { + get { + process.AssertPaused(); + + if (!IsInValidState) return string.Empty; + Value runtimeValue = RuntimeValue; + if (runtimeValue.IsNull) return string.Empty; + Value runtimeName = runtimeValue.GetMemberValue("m_Name"); + if (runtimeName.IsNull) return string.Empty; + return runtimeName.AsString(100); + } + } + + protected virtual void OnNameChanged(ThreadEventArgs e) + { + if (NameChanged != null) { + NameChanged(this, e); + } + } + + internal void NotifyNameChanged() + { + OnNameChanged(new ThreadEventArgs(this)); + } + + public Exception CurrentException { + get { + if (currentException_DebuggeeState == process.DebuggeeState) { + return currentException; + } else { + return null; + } + } + internal set { currentException = value; } + } + + internal DebuggeeState CurrentException_DebuggeeState { + get { return currentException_DebuggeeState; } + set { currentException_DebuggeeState = value; } + } + + public ExceptionType CurrentExceptionType { + get { return currentExceptionType; } + internal set { currentExceptionType = value; } + } + + public bool CurrentExceptionIsUnhandled { + get { return currentExceptionIsUnhandled; } + internal set { currentExceptionIsUnhandled = value; } + } + + /// Tryies to intercept the current exception. + /// The intercepted expression stays available through the CurrentException property. + /// False, if the exception was already intercepted or + /// if it can not be intercepted. + public bool InterceptCurrentException() + { + if (!(this.CorThread is ICorDebugThread2)) return false; // Is the debuggee .NET 2.0? + if (this.CorThread.GetCurrentException() == null) return false; // Is there any exception + if (this.MostRecentStackFrame == null) return false; // Is frame available? It is not at StackOverflow + + try { + // Interception will expire the CorValue so keep permanent reference + currentException.MakeValuePermanent(); + ((ICorDebugThread2)this.CorThread).InterceptCurrentException(this.MostRecentStackFrame.CorILFrame); + } catch (COMException e) { + // 0x80131C02: Cannot intercept this exception + if ((uint)e.ErrorCode == 0x80131C02) + return false; + // 0x80131C33: Interception of the current exception is not legal + if ((uint)e.ErrorCode == 0x80131C33) + return false; + // 0x80004005: Error HRESULT E_FAIL has been returned from a call to a COM component. + // Use this to reproduce: new FileIOPermission(PermissionState.Unrestricted).Deny(); + if ((uint)e.ErrorCode == 0x80004005) + return false; + throw; + } catch (ArgumentException) { + // May happen in release code with does not have any symbols + return false; + } + process.AsyncContinue(DebuggeeStateAction.Keep, new Thread[] { this /* needed */ }, null); + process.WaitForPause(); + return true; + } + + public override string ToString() + { + return String.Format("Thread Name = {1} Suspended = {2}", ID, Name, Suspended); + } + + /// Gets the whole callstack of the Thread. + /// If the thread is in invalid state returns empty array + [Debugger.Tests.Ignore] + public StackFrame[] GetCallstack() + { + return new List(Callstack).ToArray(); + } + + /// Get given number of frames from the callstack + public StackFrame[] GetCallstack(int maxFrames) + { + List frames = new List(); + foreach(StackFrame frame in Callstack) { + frames.Add(frame); + if (frames.Count == maxFrames) break; + } + return frames.ToArray(); + } + + public IEnumerable Callstack { + get { + process.AssertPaused(); + + if (!IsInValidState) { + yield break; + } + + uint corChainIndex = CorThread.EnumerateChains().GetCount(); + foreach(ICorDebugChain corChain in CorThread.EnumerateChains().GetEnumerator()) { + corChainIndex--; + if (corChain.IsManaged() == 0) continue; // Only managed ones + uint corFrameIndex = corChain.EnumerateFrames().GetCount(); + foreach(ICorDebugFrame corFrame in corChain.EnumerateFrames().GetEnumerator()) { + corFrameIndex--; + if (!(corFrame is ICorDebugILFrame)) continue; // Only IL frames + StackFrame stackFrame; + try { + stackFrame = new StackFrame(this, (ICorDebugILFrame)corFrame, corChainIndex, corFrameIndex); + } catch (COMException) { // TODO: Remove + continue; + }; + yield return stackFrame; + } + } + } + } + + internal StackFrame GetStackFrameAt(uint chainIndex, uint frameIndex) + { + process.AssertPaused(); + + ICorDebugChainEnum corChainEnum = CorThread.EnumerateChains(); + if (chainIndex >= corChainEnum.GetCount()) throw new DebuggerException("The requested chain index is too big"); + corChainEnum.Skip(corChainEnum.GetCount() - chainIndex - 1); + ICorDebugChain corChain = corChainEnum.Next(); + + if (corChain.IsManaged() == 0) throw new DebuggerException("The requested chain is not managed"); + + ICorDebugFrameEnum corFrameEnum = corChain.EnumerateFrames(); + if (frameIndex >= corFrameEnum.GetCount()) throw new DebuggerException("The requested frame index is too big"); + corFrameEnum.Skip(corFrameEnum.GetCount() - frameIndex - 1); + ICorDebugFrame corFrame = corFrameEnum.Next(); + + if (!(corFrame is ICorDebugILFrame)) throw new DebuggerException("The rquested frame is not IL frame"); + + StackFrame stackFrame = new StackFrame(this, (ICorDebugILFrame)corFrame, chainIndex, frameIndex); + + return stackFrame; + } + + [Debugger.Tests.Ignore] + public string GetStackTrace() + { + return GetStackTrace("at {0} in {1}:line {2}", "at {0}"); + } + + public string GetStackTrace(string formatSymbols, string formatNoSymbols) + { + StringBuilder stackTrace = new StringBuilder(); + foreach(StackFrame stackFrame in this.GetCallstack(100)) { + SourcecodeSegment loc = stackFrame.NextStatement; + stackTrace.Append(" "); + if (loc != null) { + stackTrace.AppendFormat(formatSymbols, stackFrame.MethodInfo.FullName, loc.Filename, loc.StartLine); + } else { + stackTrace.AppendFormat(formatNoSymbols, stackFrame.MethodInfo.FullName); + } + stackTrace.AppendLine(); + } + return stackTrace.ToString(); + } + + public StackFrame SelectedStackFrame { + get { + if (selectedStackFrame != null && selectedStackFrame.IsInvalid) return null; + if (process.IsRunning) return null; + return selectedStackFrame; + } + set { + if (value != null && !value.HasSymbols) { + throw new DebuggerException("SelectedFunction must have symbols"); + } + selectedStackFrame = value; + } + } + + /// + /// Returns the most recent stack frame (the one that is currently executing). + /// Returns null if callstack is empty. + /// + public StackFrame MostRecentStackFrame { + get { + foreach(StackFrame stackFrame in Callstack) { + return stackFrame; + } + return null; + } + } + + public bool IsInNativeCode { + get { + process.AssertPaused(); + if (this.IsInValidState) { + return corThread.GetActiveChain().IsManaged() == 0; + } else { + return false; + } + } + } + } + + [Serializable] + public class ThreadEventArgs : ProcessEventArgs + { + Thread thread; + + public Thread Thread { + get { + return thread; + } + } + + public ThreadEventArgs(Thread thread): base(thread.Process) + { + this.thread = thread; + } + } +} diff --git a/Debugger/Debugger.Core/ThreadCollection.cs b/Debugger/Debugger.Core/ThreadCollection.cs new file mode 100644 index 000000000..500b52aa4 --- /dev/null +++ b/Debugger/Debugger.Core/ThreadCollection.cs @@ -0,0 +1,53 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public class ThreadCollection: CollectionWithEvents + { + public ThreadCollection(NDebugger debugger): base(debugger) {} + + Thread selected; + + public Thread Selected { + get { return selected; } + set { selected = value; } + } + + public Thread Find(Predicate predicate) + { + if (predicate == null) + return null; + + foreach (var thread in this) + { + if (predicate(thread)) + return thread; + } + + return null; + } + + internal bool Contains(ICorDebugThread corThread) + { + foreach(Thread thread in this) { + if (thread.CorThread == corThread) return true; + } + return false; + } + + internal Thread this[ICorDebugThread corThread] { + get { + foreach(Thread thread in this) { + if (thread.CorThread == corThread) { + return thread; + } + } + throw new DebuggerException("Thread is not in collection"); + } + } + } +} diff --git a/Debugger/Debugger.Core/Value.cs b/Debugger/Debugger.Core/Value.cs new file mode 100644 index 000000000..e104f05c1 --- /dev/null +++ b/Debugger/Debugger.Core/Value.cs @@ -0,0 +1,653 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Reflection; + +using Debugger.Interop.CorDebug; +using Debugger.MetaData; +using System.Runtime.InteropServices; + +namespace Debugger +{ + public delegate Value ValueGetter(StackFrame context); + + /// + /// Value class provides functions to examine value in the debuggee. + /// It has very life-time. In general, value dies whenever debugger is + /// resumed (this includes method invocation and property evaluation). + /// You can use Expressions to reobtain the value. + /// + public class Value: DebuggerObject + { + AppDomain appDomain; + ICorDebugValue corValue; + PauseSession corValue_pauseSession; + DebugType type; + + // Permanently stored as convinience so that it survives Continue + bool isNull; + + /// The appdomain that owns the value + public AppDomain AppDomain { + get { return appDomain; } + } + + public Process Process { + get { return appDomain.Process; } + } + + [Debugger.Tests.Ignore] + public ICorDebugValue CorValue { + get { + if (this.IsInvalid) + throw new GetValueException("Value is no longer valid"); + return corValue; + } + } + + [Debugger.Tests.Ignore] + public ICorDebugReferenceValue CorReferenceValue { + get { + if (IsNull) throw new GetValueException("Value is null"); + + if (!(this.CorValue is ICorDebugReferenceValue)) + throw new DebuggerException("Reference value expected"); + + return (ICorDebugReferenceValue)this.CorValue; + } + } + + [Debugger.Tests.Ignore] + public ICorDebugGenericValue CorGenericValue { + get { + if (IsNull) throw new GetValueException("Value is null"); + + ICorDebugValue corValue = this.CorValue; + // Dereference and unbox if necessary + if (corValue is ICorDebugReferenceValue) + corValue = ((ICorDebugReferenceValue)corValue).Dereference(); + if (corValue is ICorDebugBoxValue) + corValue = ((ICorDebugBoxValue)corValue).GetObject(); + if (!(corValue is ICorDebugGenericValue)) + throw new DebuggerException("Value is not an generic value"); + return (ICorDebugGenericValue)corValue; + } + } + + [Debugger.Tests.Ignore] + public ICorDebugArrayValue CorArrayValue { + get { + if (IsNull) throw new GetValueException("Value is null"); + + if (!this.Type.IsArray) throw new DebuggerException("Value is not an array"); + + return (ICorDebugArrayValue)this.CorReferenceValue.Dereference(); + } + } + + [Debugger.Tests.Ignore] + public ICorDebugObjectValue CorObjectValue { + get { + if (IsNull) throw new GetValueException("Value is null"); + + ICorDebugValue corValue = this.CorValue; + // Dereference and unbox if necessary + if (corValue is ICorDebugReferenceValue) + corValue = ((ICorDebugReferenceValue)corValue).Dereference(); + if (corValue is ICorDebugBoxValue) + return ((ICorDebugBoxValue)corValue).GetObject(); + if (!(corValue is ICorDebugObjectValue)) + throw new DebuggerException("Value is not an object"); + return (ICorDebugObjectValue)corValue; + } + } + + /// Returns the of the value + public DebugType Type { + get { return type; } + } + + /// Returns true if the Value can not be used anymore. + /// Value is valid only until the debuggee is resummed. + public bool IsInvalid { + get { + return corValue_pauseSession != this.Process.PauseSession && + !(corValue is ICorDebugHandleValue); + } + } + + /// Gets value indication whether the value is a reference + /// Value types also return true if they are boxed + public bool IsReference { + get { + return this.CorValue is ICorDebugReferenceValue; + } + } + + /// Returns true if the value is null + public bool IsNull { + get { return isNull; } + } + + /// + /// Gets the address in memory where this value is stored + /// + [Debugger.Tests.Ignore] + public ulong Address { + get { return corValue.GetAddress(); } + } + + [Debugger.Tests.Ignore] + public ulong PointerAddress { + get { + if (!(this.CorValue is ICorDebugReferenceValue)) + throw new DebuggerException("Not a pointer"); + return ((ICorDebugReferenceValue)this.CorValue).GetValue(); + } + } + + /// Gets a string representation of the value + /// + /// The maximum length of the result string. + /// + public string AsString(int maxLength = int.MaxValue) + { + if (this.IsNull) return "null"; + if (this.Type.IsPrimitive || this.Type.FullName == typeof(string).FullName) { + string text = PrimitiveValue.ToString(); + if (text != null && text.Length > maxLength) + text = text.Substring(0, Math.Max(0, maxLength - 3)) + "..."; + return text; + } else { + string name = this.Type.FullName; + if (name != null && name.Length > maxLength) + return "{" + name.Substring(0, Math.Max(0, maxLength - 5)) + "...}"; + else + return "{" + name + "}"; + } + } + + internal Value(AppDomain appDomain, ICorDebugValue corValue) + { + if (corValue == null) + throw new ArgumentNullException("corValue"); + this.appDomain = appDomain; + this.corValue = corValue; + this.corValue_pauseSession = this.Process.PauseSession; + + this.isNull = corValue is ICorDebugReferenceValue && ((ICorDebugReferenceValue)corValue).IsNull() != 0; + + if (corValue is ICorDebugReferenceValue && + ((ICorDebugReferenceValue)corValue).GetValue() == 0 && + ((ICorDebugValue2)corValue).GetExactType() == null) + { + // We were passed null reference and no metadata description + // (happens during CreateThread callback for the thread object) + this.type = appDomain.ObjectType; + } else { + ICorDebugType exactType = ((ICorDebugValue2)this.CorValue).GetExactType(); + this.type = DebugType.CreateFromCorType(appDomain, exactType); + } + } + + // Box value type + public Value Box() + { + byte[] rawValue = this.CorGenericValue.GetRawValue(); + // The type must not be a primive type (always true in current design) + ICorDebugReferenceValue corRefValue = Eval.NewObjectNoConstructor(this.Type).CorReferenceValue; + // Make the reference to box permanent + corRefValue = ((ICorDebugHeapValue2)corRefValue.Dereference()).CreateHandle(CorDebugHandleType.HANDLE_STRONG); + // Create new value + Value newValue = new Value(appDomain, corRefValue); + // Copy the data inside the box + newValue.CorGenericValue.SetRawValue(rawValue); + return newValue; + } + + [Debugger.Tests.Ignore] + public Value GetPermanentReference() + { + if (this.CorValue is ICorDebugHandleValue) { + return this; + } else if (this.CorValue is ICorDebugReferenceValue) { + if (this.IsNull) + return this; // ("null" expression) It isn't permanent + ICorDebugValue deRef = this.CorReferenceValue.Dereference(); + if (deRef is ICorDebugHeapValue2) { + return new Value(appDomain, ((ICorDebugHeapValue2)deRef).CreateHandle(CorDebugHandleType.HANDLE_STRONG)); + } else { + // For exampe int* is a refernce not pointing to heap + // TODO: It isn't permanent + return this; + } + } else { + return this.Box(); + } + } + + /// Dereferences a pointer type + /// Returns null for a null pointer + public Value Dereference() + { + if (!this.Type.IsPointer) throw new DebuggerException("Not a pointer"); + ICorDebugReferenceValue corRef = (ICorDebugReferenceValue)this.CorValue; + if (corRef.GetValue() == 0 || corRef.Dereference() == null) { + return null; + } else { + return new Value(this.AppDomain, corRef.Dereference()); + } + } + + /// Copy the acutal value from some other Value object + public void SetValue(Value newValue) + { + ICorDebugValue newCorValue = newValue.CorValue; + + if (this.CorValue is ICorDebugReferenceValue) { + if (!(newCorValue is ICorDebugReferenceValue)) + newCorValue = newValue.Box().CorValue; + ((ICorDebugReferenceValue)this.CorValue).SetValue(((ICorDebugReferenceValue)newCorValue).GetValue()); + } else { + this.CorGenericValue.SetRawValue(newValue.CorGenericValue.GetRawValue()); + } + } + + #region Primitive + + /// + /// Gets or sets the value of a primitive type. + /// + /// If setting of a value fails, NotSupportedException is thrown. + /// + public object PrimitiveValue { + get { + if (this.Type.FullName == typeof(string).FullName) { + if (this.IsNull) return null; + return ((ICorDebugStringValue)this.CorReferenceValue.Dereference()).GetString(); + } else { + if (this.Type.PrimitiveType == null) + throw new DebuggerException("Value is not a primitive type"); + return CorGenericValue.GetValue(this.Type.PrimitiveType); + } + } + set { + if (this.Type.FullName == typeof(string).FullName) { + this.SetValue(Eval.NewString(this.AppDomain, value.ToString())); + } else { + if (this.Type.PrimitiveType == null) + throw new DebuggerException("Value is not a primitive type"); + if (value == null) + throw new DebuggerException("Can not set primitive value to null"); + object newValue; + try { + newValue = Convert.ChangeType(value, this.Type.PrimitiveType); + } catch { + throw new NotSupportedException("Can not convert " + value.GetType().ToString() + " to " + this.Type.PrimitiveType.ToString()); + } + CorGenericValue.SetValue(newValue); + } + } + } + + #endregion + + #region Array + + /// + /// Gets the number of elements in the array. + /// eg new object[4,5] returns 20 + /// + /// 0 for non-arrays + public int ArrayLength { + get { + if (!this.Type.IsArray) return 0; + return (int)CorArrayValue.GetCount(); + } + } + + /// + /// Gets the number of dimensions of the array. + /// eg new object[4,5] returns 2 + /// + /// 0 for non-arrays + public int ArrayRank { + get { + if (!this.Type.IsArray) return 0; + return (int)CorArrayValue.GetRank(); + } + } + + /// Gets the dimensions of the array + /// null for non-arrays + public ArrayDimensions ArrayDimensions { + get { + if (!this.Type.IsArray) return null; + int rank = this.ArrayRank; + uint[] baseIndicies; + if (CorArrayValue.HasBaseIndicies() == 1) { + baseIndicies = CorArrayValue.GetBaseIndicies(); + } else { + baseIndicies = new uint[this.ArrayRank]; + } + uint[] dimensionCounts = CorArrayValue.GetDimensions(); + + List dimensions = new List(); + for(int i = 0; i < rank; i++) { + dimensions.Add(new ArrayDimension((int)baseIndicies[i], (int)baseIndicies[i] + (int)dimensionCounts[i] - 1)); + } + + return new ArrayDimensions(dimensions); + } + } + + /// Returns an element of a single-dimensional array + public Value GetArrayElement(int index) + { + return GetArrayElement(new int[] {index}); + } + + /// Returns an element of an array + public Value GetArrayElement(int[] elementIndices) + { + int[] indices = (int[])elementIndices.Clone(); + + return new Value(this.AppDomain, GetCorValueOfArrayElement(indices)); + } + + // May be called later + ICorDebugValue GetCorValueOfArrayElement(int[] indices) + { + if (indices.Length != ArrayRank) { + throw new GetValueException("Given indicies do not have the same dimension as array."); + } + if (!this.ArrayDimensions.IsIndexValid(indices)) { + throw new GetValueException("Given indices are out of range of the array"); + } + + return CorArrayValue.GetElement(indices); + } + + public void SetArrayElement(int[] elementIndices, Value newVal) + { + Value elem = GetArrayElement(elementIndices); + elem.SetValue(newVal); + } + + /// Returns all elements in the array + public Value[] GetArrayElements() + { + if (!this.Type.IsArray) return null; + List values = new List(); + foreach(int[] indices in this.ArrayDimensions.Indices) { + values.Add(GetArrayElement(indices)); + } + return values.ToArray(); + } + + #endregion + + #region Object + + static void CheckObject(Value objectInstance, MemberInfo memberInfo) + { + if (memberInfo == null) + throw new DebuggerException("memberInfo"); + IDebugMemberInfo debugMemberInfo = memberInfo as IDebugMemberInfo; + if (debugMemberInfo == null) + throw new DebuggerException("DebugMemberInfo must be used"); + if (!debugMemberInfo.IsStatic) { + if (objectInstance == null) + throw new DebuggerException("No target object specified"); + if (objectInstance.IsNull) + throw new GetValueException("Null reference"); + //if (!objectInstance.IsObject) // eg Array.Length can be called + if (!debugMemberInfo.DeclaringType.IsInstanceOfType(objectInstance)) + throw new GetValueException("Object is not of type " + debugMemberInfo.DeclaringType.FullName); + } + } + + #region Convenience overload methods + + /// Get a field or property of an object with a given name. + /// Null if not found + public Value GetMemberValue(string name) + { + MemberInfo memberInfo = this.Type.GetMember(name, DebugType.BindingFlagsAllInScope, DebugType.IsFieldOrNonIndexedProperty); + if (memberInfo == null) + return null; + return GetMemberValue(memberInfo); + } + + /// Get the value of given member. + public Value GetMemberValue(MemberInfo memberInfo, params Value[] arguments) + { + return GetMemberValue(this, memberInfo, arguments); + } + + #endregion + + /// Get the value of given member. + /// null if member is static + public static Value GetMemberValue(Value objectInstance, MemberInfo memberInfo, params Value[] arguments) + { + if (memberInfo is FieldInfo) { + if (arguments.Length > 0) + throw new GetValueException("Arguments can not be used for a field"); + return GetFieldValue(objectInstance, (FieldInfo)memberInfo); + } else if (memberInfo is PropertyInfo) { + return GetPropertyValue(objectInstance, (PropertyInfo)memberInfo, arguments); + } else if (memberInfo is MethodInfo) { + return InvokeMethod(objectInstance, (MethodInfo)memberInfo, arguments); + } + throw new DebuggerException("Unknown member type: " + memberInfo.GetType()); + } + + #region Convenience overload methods + + /// Get the value of given field. + public Value GetFieldValue(FieldInfo fieldInfo) + { + return Value.GetFieldValue(this, fieldInfo); + } + + #endregion + + public static void SetFieldValue(Value objectInstance, FieldInfo fieldInfo, Value newValue) + { + Value val = GetFieldValue(objectInstance, fieldInfo); + if (!fieldInfo.FieldType.IsAssignableFrom(newValue.Type)) + throw new GetValueException("Can not assign {0} to {1}", newValue.Type.FullName, fieldInfo.FieldType.FullName); + val.SetValue(newValue); + } + + /// Get the value of given field. + /// null if field is static + public static Value GetFieldValue(Value objectInstance, FieldInfo fieldInfo) + { + CheckObject(objectInstance, fieldInfo); + + if (fieldInfo.IsStatic && fieldInfo.IsLiteral) { + return GetLiteralValue((DebugFieldInfo)fieldInfo); + } else { + return new Value( + ((DebugFieldInfo)fieldInfo).AppDomain, + GetFieldCorValue(objectInstance, fieldInfo) + ); + } + } + + static ICorDebugValue GetFieldCorValue(Value objectInstance, FieldInfo fieldInfo) + { + Process process = ((DebugFieldInfo)fieldInfo).Process; + + // Current frame is used to resolve context specific static values (eg. ThreadStatic) + ICorDebugFrame curFrame = null; + if (process.IsPaused && + process.SelectedThread != null && + process.SelectedThread.MostRecentStackFrame != null && + process.SelectedThread.MostRecentStackFrame.CorILFrame != null) + { + curFrame = process.SelectedThread.MostRecentStackFrame.CorILFrame; + } + + try { + if (fieldInfo.IsStatic) { + return ((DebugType)fieldInfo.DeclaringType).CorType.GetStaticFieldValue((uint)fieldInfo.MetadataToken, curFrame); + } else { + return objectInstance.CorObjectValue.GetFieldValue(((DebugType)fieldInfo.DeclaringType).CorType.GetClass(), (uint)fieldInfo.MetadataToken); + } + } catch (COMException e) { + throw new GetValueException("Can not get value of field", e); + } + } + + static Value GetLiteralValue(DebugFieldInfo fieldInfo) + { + CorElementType corElemType = (CorElementType)fieldInfo.FieldProps.ConstantType; + if (corElemType == CorElementType.CLASS) { + // Only null literals are allowed + return Eval.CreateValue(fieldInfo.AppDomain, null); + } else if (corElemType == CorElementType.STRING) { + string str = Marshal.PtrToStringUni(fieldInfo.FieldProps.ConstantPtr, (int)fieldInfo.FieldProps.ConstantStringLength); + return Eval.CreateValue(fieldInfo.AppDomain, str); + } else { + DebugType type = DebugType.CreateFromType(fieldInfo.AppDomain.Mscorlib, DebugType.CorElementTypeToManagedType(corElemType)); + if (fieldInfo.FieldType.IsEnum && fieldInfo.FieldType.GetEnumUnderlyingType() == type) { + Value val = Eval.NewObjectNoConstructor((DebugType)fieldInfo.FieldType); + Value backingField = val.GetMemberValue("value__"); + backingField.CorGenericValue.SetValue(fieldInfo.FieldProps.ConstantPtr); + return val; + } else { + Value val = Eval.NewObjectNoConstructor(type); + val.CorGenericValue.SetValue(fieldInfo.FieldProps.ConstantPtr); + return val; + } + } + } + + #region Convenience overload methods + + /// Get the value of the property using the get accessor + public Value GetPropertyValue(PropertyInfo propertyInfo, params Value[] arguments) + { + return GetPropertyValue(this, propertyInfo, arguments); + } + + #endregion + + /// Get the value of the property using the get accessor + public static Value GetPropertyValue(Value objectInstance, PropertyInfo propertyInfo, params Value[] arguments) + { + CheckObject(objectInstance, propertyInfo); + + if (propertyInfo.GetGetMethod() == null) throw new GetValueException("Property does not have a get method"); + + Value val = Value.InvokeMethod(objectInstance, (DebugMethodInfo)propertyInfo.GetGetMethod(), arguments); + + return val; + } + + #region Convenience overload methods + + /// Set the value of the property using the set accessor + public Value SetPropertyValue(PropertyInfo propertyInfo, Value newValue) + { + return SetPropertyValue(this, propertyInfo, null, newValue); + } + + /// Set the value of the property using the set accessor + public Value SetPropertyValue(PropertyInfo propertyInfo, Value[] arguments, Value newValue) + { + return SetPropertyValue(this, propertyInfo, arguments, newValue); + } + + /// Set the value of the property using the set accessor + public static Value SetPropertyValue(Value objectInstance, PropertyInfo propertyInfo, Value newValue) + { + return SetPropertyValue(objectInstance, propertyInfo, null, newValue); + } + + #endregion + + /// Set the value of the property using the set accessor + public static Value SetPropertyValue(Value objectInstance, PropertyInfo propertyInfo, Value[] arguments, Value newValue) + { + CheckObject(objectInstance, propertyInfo); + + if (propertyInfo.GetSetMethod() == null) throw new GetValueException("Property does not have a set method"); + + arguments = arguments ?? new Value[0]; + + Value[] allParams = new Value[1 + arguments.Length]; + allParams[0] = newValue; + arguments.CopyTo(allParams, 1); + + return Value.InvokeMethod(objectInstance, (DebugMethodInfo)propertyInfo.GetSetMethod(), allParams); + } + + #region Convenience overload methods + + /// Synchronously invoke the method + public Value InvokeMethod(MethodInfo methodInfo, params Value[] arguments) + { + return InvokeMethod(this, methodInfo, arguments); + } + + #endregion + + /// Synchronously invoke the method + public static Value InvokeMethod(Value objectInstance, MethodInfo methodInfo, params Value[] arguments) + { + CheckObject(objectInstance, methodInfo); + + return Eval.InvokeMethod( + (DebugMethodInfo)methodInfo, + methodInfo.IsStatic ? null : objectInstance, + arguments ?? new Value[0] + ); + } + + /// Invoke the ToString() method + public string InvokeToString(int maxLength = int.MaxValue) + { + if (this.Type.IsPrimitive) return AsString(maxLength); + if (this.Type.FullName == typeof(string).FullName) return AsString(maxLength); + if (this.Type.IsPointer) return "0x" + this.PointerAddress.ToString("X"); + // if (!IsObject) // Can invoke on primitives + DebugMethodInfo methodInfo = (DebugMethodInfo)this.AppDomain.ObjectType.GetMethod("ToString", new DebugType[] {}); + return Eval.InvokeMethod(methodInfo, this, new Value[] {}).AsString(maxLength); + } + + #region Convenience overload methods + + /// Asynchronously invoke the method + public Eval AsyncInvokeMethod(MethodInfo methodInfo, params Value[] arguments) + { + return AsyncInvokeMethod(this, methodInfo, arguments); + } + + #endregion + + /// Asynchronously invoke the method + public static Eval AsyncInvokeMethod(Value objectInstance, MethodInfo methodInfo, params Value[] arguments) + { + CheckObject(objectInstance, methodInfo); + + return Eval.AsyncInvokeMethod( + (DebugMethodInfo)methodInfo, + methodInfo.IsStatic ? null : objectInstance, + arguments ?? new Value[0] + ); + } + + #endregion + + public override string ToString() + { + return this.AsString(); + } + } +} diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/Editor/AvalonEditDocumentAdapter.cs b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/AvalonEditDocumentAdapter.cs new file mode 100644 index 000000000..48ee61f54 --- /dev/null +++ b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/AvalonEditDocumentAdapter.cs @@ -0,0 +1,442 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.NRefactory; + +namespace ILSpy.Debugger.AvalonEdit.Editor +{ + /// + /// Wraps the AvalonEdit TextDocument to provide the IDocument interface. + /// + public class AvalonEditDocumentAdapter : IDocument + { + internal readonly TextDocument document; + + /// + /// Creates a new AvalonEditDocumentAdapter instance. + /// + /// The document to wrap. + public AvalonEditDocumentAdapter(TextDocument document) + { + if (document == null) + throw new ArgumentNullException("document"); + this.document = document; + } + + /// + /// Creates a new document. + /// + public AvalonEditDocumentAdapter() + { + this.document = new TextDocument(); + } + + sealed class LineAdapter : IDocumentLine + { + readonly TextDocument document; + readonly DocumentLine line; + + public LineAdapter(TextDocument document, DocumentLine line) + { + Debug.Assert(document != null); + Debug.Assert(line != null); + this.document = document; + this.line = line; + } + + public int Offset { + get { return line.Offset; } + } + + public int Length { + get { return line.Length; } + } + + public int EndOffset { + get { return line.EndOffset; } + } + + public int TotalLength { + get { return line.TotalLength; } + } + + public int DelimiterLength { + get { return line.DelimiterLength; } + } + + public int LineNumber { + get { return line.LineNumber; } + } + + public string Text { + get { return document.GetText(line); } + } + } + + public int TextLength { + get { return document.TextLength; } + } + + public int TotalNumberOfLines { + get { return document.LineCount; } + } + + public string Text { + get { return document.Text; } + set { document.Text = value; } + } + + public event EventHandler TextChanged { + add { document.TextChanged += value; } + remove { document.TextChanged -= value; } + } + + public IDocumentLine GetLine(int lineNumber) + { + return new LineAdapter(document, document.GetLineByNumber(lineNumber)); + } + + public IDocumentLine GetLineForOffset(int offset) + { + return new LineAdapter(document, document.GetLineByOffset(offset)); + } + + public int PositionToOffset(int line, int column) + { + try { + return document.GetOffset(new TextLocation(line, column)); + } catch (ArgumentOutOfRangeException e) { + // for UDC: re-throw exception so that stack trace identifies the caller (instead of the adapter) + throw new ArgumentOutOfRangeException(e.ParamName, e.ActualValue, e.Message); + } + } + + public Location OffsetToPosition(int offset) + { + try { + return ToLocation(document.GetLocation(offset)); + } catch (ArgumentOutOfRangeException e) { + // for UDC: re-throw exception so that stack trace identifies the caller (instead of the adapter) + throw new ArgumentOutOfRangeException(e.ParamName, e.ActualValue, e.Message); + } + } + + public static Location ToLocation(TextLocation position) + { + return new Location(position.Column, position.Line); + } + + public static TextLocation ToPosition(Location location) + { + return new TextLocation(location.Line, location.Column); + } + + public void Insert(int offset, string text) + { + document.Insert(offset, text); + } + + public void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType) + { + if (defaultAnchorMovementType == AnchorMovementType.BeforeInsertion) { + document.Replace(offset, 0, text, OffsetChangeMappingType.KeepAnchorBeforeInsertion); + } else { + document.Insert(offset, text); + } + } + + public void Remove(int offset, int length) + { + document.Remove(offset, length); + } + + public void Replace(int offset, int length, string newText) + { + document.Replace(offset, length, newText); + } + + public void Replace(int offset, int length, string newText, AnchorMovementType defaultAnchorMovementType) + { + document.Replace(offset, length, newText); + } + + public char GetCharAt(int offset) + { + return document.GetCharAt(offset); + } + + public string GetText(int offset, int length) + { + return document.GetText(offset, length); + } + + public System.IO.TextReader CreateReader() + { + return document.CreateSnapshot().CreateReader(); + } + + public System.IO.TextReader CreateReader(int offset, int length) + { + return document.CreateSnapshot(offset, length).CreateReader(); + } + + #region Snapshots and ITextBufferVersion + public ITextBuffer CreateSnapshot() + { + ChangeTrackingCheckpoint checkpoint; + ITextSource textSource = document.CreateSnapshot(out checkpoint); + return new Snapshot(textSource, checkpoint); + } + + public ITextBuffer CreateSnapshot(int offset, int length) + { + return new AvalonEditTextSourceAdapter(document.CreateSnapshot(offset, length)); + } + + public ITextBufferVersion Version { + get { + return new SnapshotVersion(ChangeTrackingCheckpoint.Create(document)); + } + } + + sealed class Snapshot : AvalonEditTextSourceAdapter + { + readonly ITextBufferVersion version; + + public Snapshot(ITextSource textSource, ChangeTrackingCheckpoint checkpoint) + : base(textSource) + { + this.version = new SnapshotVersion(checkpoint); + } + + public override ITextBuffer CreateSnapshot() + { + // Snapshot is immutable + return this; + } + + public override ITextBufferVersion Version { + get { return version; } + } + } + + sealed class SnapshotVersion : ITextBufferVersion + { + readonly ChangeTrackingCheckpoint checkpoint; + + public SnapshotVersion(ChangeTrackingCheckpoint checkpoint) + { + Debug.Assert(checkpoint != null); + this.checkpoint = checkpoint; + } + + public bool BelongsToSameDocumentAs(ITextBufferVersion other) + { + SnapshotVersion otherVersion = other as SnapshotVersion; + return otherVersion != null && checkpoint.BelongsToSameDocumentAs(otherVersion.checkpoint); + } + + public int CompareAge(ITextBufferVersion other) + { + SnapshotVersion otherVersion = other as SnapshotVersion; + if (otherVersion == null) + throw new ArgumentException("Does not belong to same document"); + return checkpoint.CompareAge(otherVersion.checkpoint); + } + + public IEnumerable GetChangesTo(ITextBufferVersion other) + { + SnapshotVersion otherVersion = other as SnapshotVersion; + if (otherVersion == null) + throw new ArgumentException("Does not belong to same document"); + return checkpoint.GetChangesTo(otherVersion.checkpoint).Select(c => new TextChangeEventArgs(c.Offset, c.RemovedText, c.InsertedText)); + } + + public int MoveOffsetTo(ITextBufferVersion other, int oldOffset, AnchorMovementType movement) + { + SnapshotVersion otherVersion = other as SnapshotVersion; + if (otherVersion == null) + throw new ArgumentException("Does not belong to same document"); + switch (movement) { + case AnchorMovementType.AfterInsertion: + return checkpoint.MoveOffsetTo(otherVersion.checkpoint, oldOffset, ICSharpCode.AvalonEdit.Document.AnchorMovementType.AfterInsertion); + case AnchorMovementType.BeforeInsertion: + return checkpoint.MoveOffsetTo(otherVersion.checkpoint, oldOffset, ICSharpCode.AvalonEdit.Document.AnchorMovementType.BeforeInsertion); + default: + throw new NotSupportedException(); + } + } + } + #endregion + + public void StartUndoableAction() + { + document.BeginUpdate(); + } + + public void EndUndoableAction() + { + document.EndUpdate(); + } + + public IDisposable OpenUndoGroup() + { + return document.RunUpdate(); + } + + public ITextAnchor CreateAnchor(int offset) + { + return new AnchorAdapter(document.CreateAnchor(offset)); + } + + #region AnchorAdapter + sealed class AnchorAdapter : ITextAnchor + { + readonly TextAnchor anchor; + + public AnchorAdapter(TextAnchor anchor) + { + this.anchor = anchor; + } + + #region Forward Deleted Event + EventHandler deleted; + + public event EventHandler Deleted { + add { + // we cannot simply forward the event handler because + // that would raise the event with an incorrect sender + if (deleted == null && value != null) + anchor.Deleted += OnDeleted; + deleted += value; + } + remove { + deleted -= value; + if (deleted == null) + anchor.Deleted -= OnDeleted; + } + } + + void OnDeleted(object sender, EventArgs e) + { + // raise event with correct sender + if (deleted != null) + deleted(this, e); + } + #endregion + + public Location Location { + get { return ToLocation(anchor.Location); } + } + + public int Offset { + get { return anchor.Offset; } + } + + public ILSpy.Debugger.AvalonEdit.Editor.AnchorMovementType MovementType { + get { + return (ILSpy.Debugger.AvalonEdit.Editor.AnchorMovementType)anchor.MovementType; + } + set { + anchor.MovementType = (ICSharpCode.AvalonEdit.Document.AnchorMovementType)value; + } + } + + public bool SurviveDeletion { + get { return anchor.SurviveDeletion; } + set { anchor.SurviveDeletion = value; } + } + + public bool IsDeleted { + get { return anchor.IsDeleted; } + } + + public int Line { + get { return anchor.Line; } + } + + public int Column { + get { return anchor.Column; } + } + } + #endregion + + #region Changing/Changed events + EventHandler changing, changed; + bool eventsAreAttached; + + void AttachEvents() + { + if (!eventsAreAttached && (changing != null || changed != null)) { + eventsAreAttached = true; + document.Changing += document_Changing; + document.Changed += document_Changed; + } + } + + void DetachEvents() + { + if (eventsAreAttached && changing == null && changed == null) { + eventsAreAttached = false; + document.Changing -= document_Changing; + document.Changed -= document_Changed; + } + } + + void document_Changing(object sender, DocumentChangeEventArgs e) + { + if (changing != null) + changing(this, new TextChangeEventArgs(e.Offset, e.RemovedText, e.InsertedText)); + } + + void document_Changed(object sender, DocumentChangeEventArgs e) + { + if (changed != null) + changed(this, new TextChangeEventArgs(e.Offset, e.RemovedText, e.InsertedText)); + } + + public event EventHandler Changing { + add { + changing += value; + AttachEvents(); + } + remove { + changing -= value; + DetachEvents(); + } + } + + public event EventHandler Changed { + add { + changed += value; + AttachEvents(); + } + remove { + changed -= value; + DetachEvents(); + } + } + #endregion + } +} diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/Editor/AvalonEditTextSourceAdapter.cs b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/AvalonEditTextSourceAdapter.cs new file mode 100644 index 000000000..4a4f55424 --- /dev/null +++ b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/AvalonEditTextSourceAdapter.cs @@ -0,0 +1,98 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using ICSharpCode.AvalonEdit.Document; +using System; + +namespace ILSpy.Debugger.AvalonEdit.Editor +{ + public class AvalonEditTextSourceAdapter : ITextBuffer + { + internal readonly ITextSource textSource; + + public AvalonEditTextSourceAdapter(ITextSource textSource) + { + if (textSource == null) + throw new ArgumentNullException("textSource"); + this.textSource = textSource; + } + + public virtual ITextBufferVersion Version { + get { return null; } + } + + /// + /// Creates an immutable snapshot of this text buffer. + /// + public virtual ITextBuffer CreateSnapshot() + { + return new AvalonEditTextSourceAdapter(textSource.CreateSnapshot()); + } + + /// + /// Creates an immutable snapshot of a part of this text buffer. + /// Unlike all other methods in this interface, this method is thread-safe. + /// + public ITextBuffer CreateSnapshot(int offset, int length) + { + return new AvalonEditTextSourceAdapter(textSource.CreateSnapshot(offset, length)); + } + + /// + /// Creates a new TextReader to read from this text buffer. + /// + public System.IO.TextReader CreateReader() + { + return textSource.CreateReader(); + } + + /// + /// Creates a new TextReader to read from this text buffer. + /// + public System.IO.TextReader CreateReader(int offset, int length) + { + return textSource.CreateSnapshot(offset, length).CreateReader(); + } + + public int TextLength { + get { return textSource.TextLength; } + } + + public string Text { + get { return textSource.Text; } + } + + /// + /// Is raised when the Text property changes. + /// + public event EventHandler TextChanged { + add { textSource.TextChanged += value; } + remove { textSource.TextChanged -= value; } + } + + public char GetCharAt(int offset) + { + return textSource.GetCharAt(offset); + } + + public string GetText(int offset, int length) + { + return textSource.GetText(offset, length); + } + } +} diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/Editor/IDocument.cs b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/IDocument.cs new file mode 100644 index 000000000..77ddf5999 --- /dev/null +++ b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/IDocument.cs @@ -0,0 +1,85 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using ICSharpCode.NRefactory; + +namespace ILSpy.Debugger.AvalonEdit.Editor +{ + /// + /// A document representing a source code file for refactoring. + /// Line and column counting starts at 1. + /// Offset counting starts at 0. + /// + public interface IDocument : ITextBuffer + { + /// + /// Gets/Sets the whole text as string. + /// + new string Text { get; set; } // hides TextBuffer.Text to add the setter + + /// + /// Gets the total number of lines in the document. + /// + int TotalNumberOfLines { get; } + + /// + /// Gets the document line with the specified number. + /// + /// The number of the line to retrieve. The first line has number 1. + IDocumentLine GetLine(int lineNumber); + + /// + /// Gets the document line that contains the specified offset. + /// + IDocumentLine GetLineForOffset(int offset); + + int PositionToOffset(int line, int column); + Location OffsetToPosition(int offset); + + void Insert(int offset, string text); + void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType); + void Remove(int offset, int length); + void Replace(int offset, int length, string newText); + + /// + /// Make the document combine the following actions into a single + /// action for undo purposes. + /// + void StartUndoableAction(); + + /// + /// Ends the undoable action started with . + /// + void EndUndoableAction(); + + /// + /// Creates an undo group. Dispose the returned value to close the undo group. + /// + /// An object that closes the undo group when Dispose() is called. + IDisposable OpenUndoGroup(); + + /// + /// Creates a new text anchor at the specified position. + /// + ITextAnchor CreateAnchor(int offset); + + event EventHandler Changing; + event EventHandler Changed; + } +} diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/Editor/IDocumentLine.cs b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/IDocumentLine.cs new file mode 100644 index 000000000..7ebb5674a --- /dev/null +++ b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/IDocumentLine.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ILSpy.Debugger.AvalonEdit.Editor +{ + /// + /// A line inside a . + /// + public interface IDocumentLine + { + /// + /// Gets the starting offset of the line in the document's text. + /// + int Offset { get; } + + /// + /// Gets the length of this line (=the number of characters on the line). + /// + int Length { get; } + + /// + /// Gets the ending offset of the line in the document's text (= Offset + Length). + /// + int EndOffset { get; } + + /// + /// Gets the length of this line, including the line delimiter. + /// + int TotalLength { get; } + + /// + /// Gets the length of the line terminator. + /// Returns 1 or 2; or 0 at the end of the document. + /// + int DelimiterLength { get; } + + /// + /// Gets the number of this line. + /// The first line has the number 1. + /// + int LineNumber { get; } + + /// + /// Gets the text on this line. + /// + string Text { get; } + } +} diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/Editor/ITextAnchor.cs b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/ITextAnchor.cs new file mode 100644 index 000000000..41cd4cb83 --- /dev/null +++ b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/ITextAnchor.cs @@ -0,0 +1,98 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using ICSharpCode.NRefactory; +using System; + +namespace ILSpy.Debugger.AvalonEdit.Editor +{ + /// + /// Represents an anchored location inside an . + /// + public interface ITextAnchor + { + /// + /// Gets the text location of this anchor. + /// + /// Thrown when trying to get the Offset from a deleted anchor. + Location Location { get; } + + /// + /// Gets the offset of the text anchor. + /// + /// Thrown when trying to get the Offset from a deleted anchor. + int Offset { get; } + + /// + /// Controls how the anchor moves. + /// + AnchorMovementType MovementType { get; set; } + + /// + /// Specifies whether the anchor survives deletion of the text containing it. + /// false: The anchor is deleted when the a selection that includes the anchor is deleted. + /// true: The anchor is not deleted. + /// + bool SurviveDeletion { get; set; } + + /// + /// Gets whether the anchor was deleted. + /// + bool IsDeleted { get; } + + /// + /// Occurs after the anchor was deleted. + /// + event EventHandler Deleted; + + /// + /// Gets the line number of the anchor. + /// + /// Thrown when trying to get the Offset from a deleted anchor. + int Line { get; } + + /// + /// Gets the column number of this anchor. + /// + /// Thrown when trying to get the Offset from a deleted anchor. + int Column { get; } + } + + /// + /// Defines how a text anchor moves. + /// + public enum AnchorMovementType + { + /// + /// When text is inserted at the anchor position, the type of the insertion + /// determines where the caret moves to. For normal insertions, the anchor will stay + /// behind the inserted text. + /// + Default = ICSharpCode.AvalonEdit.Document.AnchorMovementType.Default, + /// + /// Behaves like a start marker - when text is inserted at the anchor position, the anchor will stay + /// before the inserted text. + /// + BeforeInsertion = ICSharpCode.AvalonEdit.Document.AnchorMovementType.BeforeInsertion, + /// + /// Behave like an end marker - when text is insered at the anchor position, the anchor will move + /// after the inserted text. + /// + AfterInsertion = ICSharpCode.AvalonEdit.Document.AnchorMovementType.AfterInsertion + } +} diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/Editor/ITextBuffer.cs b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/ITextBuffer.cs new file mode 100644 index 000000000..9ca640874 --- /dev/null +++ b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/ITextBuffer.cs @@ -0,0 +1,136 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.IO; + +namespace ILSpy.Debugger.AvalonEdit.Editor +{ + /// + /// A read-only view on a (potentially mutable) text buffer. + /// The IDocument interfaces derives from this interface. + /// + public interface ITextBuffer + { + /// + /// Gets a version identifier for this text buffer. + /// Returns null for unversioned text buffers. + /// + ITextBufferVersion Version { get; } + + /// + /// Creates an immutable snapshot of this text buffer. + /// Unlike all other methods in this interface, this method is thread-safe. + /// + ITextBuffer CreateSnapshot(); + + /// + /// Creates an immutable snapshot of a part of this text buffer. + /// Unlike all other methods in this interface, this method is thread-safe. + /// + ITextBuffer CreateSnapshot(int offset, int length); + + /// + /// Creates a new TextReader to read from this text buffer. + /// + TextReader CreateReader(); + + /// + /// Creates a new TextReader to read from this text buffer. + /// + TextReader CreateReader(int offset, int length); + + /// + /// Gets the total text length. + /// + /// The length of the text, in characters. + /// This is the same as Text.Length, but is more efficient because + /// it doesn't require creating a String object. + int TextLength { get; } + + /// + /// Gets the whole text as string. + /// + string Text { get; } + + /// + /// Is raised when the Text property changes. + /// + event EventHandler TextChanged; + + /// + /// Gets a character at the specified position in the document. + /// + /// The index of the character to get. + /// Offset is outside the valid range (0 to TextLength-1). + /// The character at the specified position. + /// This is the same as Text[offset], but is more efficient because + /// it doesn't require creating a String object. + char GetCharAt(int offset); + + /// + /// Retrieves the text for a portion of the document. + /// + /// offset or length is outside the valid range. + /// This is the same as Text.Substring, but is more efficient because + /// it doesn't require creating a String object for the whole document. + string GetText(int offset, int length); + } + + /// + /// Represents a version identifier for a text buffer. + /// + /// + /// This is SharpDevelop's equivalent to AvalonEdit ChangeTrackingCheckpoint. + /// It is used by the ParserService to efficiently detect whether a document has changed and needs reparsing. + /// It is a separate class from ITextBuffer to allow the GC to collect the text buffer while the version checkpoint + /// is still in use. + /// + public interface ITextBufferVersion + { + /// + /// Gets whether this checkpoint belongs to the same document as the other checkpoint. + /// + bool BelongsToSameDocumentAs(ITextBufferVersion other); + + /// + /// Compares the age of this checkpoint to the other checkpoint. + /// + /// This method is thread-safe. + /// Raised if 'other' belongs to a different document than this version. + /// -1 if this version is older than . + /// 0 if this version instance represents the same version as . + /// 1 if this version is newer than . + int CompareAge(ITextBufferVersion other); + + /// + /// Gets the changes from this checkpoint to the other checkpoint. + /// If 'other' is older than this checkpoint, reverse changes are calculated. + /// + /// This method is thread-safe. + /// Raised if 'other' belongs to a different document than this checkpoint. + IEnumerable GetChangesTo(ITextBufferVersion other); + + /// + /// Calculates where the offset has moved in the other buffer version. + /// + /// Raised if 'other' belongs to a different document than this checkpoint. + int MoveOffsetTo(ITextBufferVersion other, int oldOffset, AnchorMovementType movement); + } +} diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/Editor/TextChangeEventArgs.cs b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/TextChangeEventArgs.cs new file mode 100644 index 000000000..c8fa5cfd5 --- /dev/null +++ b/Debugger/ILSpy.Debugger/AvalonEdit/Editor/TextChangeEventArgs.cs @@ -0,0 +1,68 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ILSpy.Debugger.AvalonEdit.Editor +{ + /// + /// Describes a change of the document text. + /// This class is thread-safe. + /// + public class TextChangeEventArgs : EventArgs + { + /// + /// The offset at which the change occurs. + /// + public int Offset { get; private set; } + + /// + /// The text that was inserted. + /// + public string RemovedText { get; private set; } + + /// + /// The number of characters removed. + /// + public int RemovalLength { + get { return RemovedText.Length; } + } + + /// + /// The text that was inserted. + /// + public string InsertedText { get; private set; } + + /// + /// The number of characters inserted. + /// + public int InsertionLength { + get { return InsertedText.Length; } + } + + /// + /// Creates a new TextChangeEventArgs object. + /// + public TextChangeEventArgs(int offset, string removedText, string insertedText) + { + this.Offset = offset; + this.RemovedText = removedText ?? string.Empty; + this.InsertedText = insertedText ?? string.Empty; + } + } +} diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/IconBarManager.cs b/Debugger/ILSpy.Debugger/AvalonEdit/IconBarManager.cs new file mode 100644 index 000000000..d0e11b678 --- /dev/null +++ b/Debugger/ILSpy.Debugger/AvalonEdit/IconBarManager.cs @@ -0,0 +1,66 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; + +using ILSpy.Debugger.Bookmarks; + +namespace ILSpy.Debugger.AvalonEdit +{ + public class IconBarManager : IBookmarkMargin + { + static object syncLock = new object(); + + static IconBarManager instance; + + public static IconBarManager Instance { + get { + if (instance == null) + lock(syncLock) + if(instance == null) + instance = new IconBarManager(); + + return instance; + } + } + + private IconBarManager() + { + } + + public IList Bookmarks { + get { return BookmarkManager.Bookmarks; } + } + + void bookmarks_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + Redraw(); + } + + public void Redraw() + { + if (RedrawRequested != null) + RedrawRequested(this, EventArgs.Empty); + } + + public event EventHandler RedrawRequested; + } +} diff --git a/Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs b/Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs new file mode 100644 index 000000000..dca94d67a --- /dev/null +++ b/Debugger/ILSpy.Debugger/AvalonEdit/IconBarMargin.cs @@ -0,0 +1,253 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Windows; +using System.Windows.Input; +using System.Windows.Media; + +using ICSharpCode.AvalonEdit.Editing; +using ICSharpCode.AvalonEdit.Rendering; +using ICSharpCode.AvalonEdit.Utils; +using ILSpy.Debugger.Bookmarks; +using ILSpy.Debugger.Debugging; +using ILSpy.Debugger.Services; + +namespace ILSpy.Debugger.AvalonEdit +{ + public class IconBarMargin : AbstractMargin, IDisposable + { + readonly IconBarManager manager; + + public IconBarMargin(IconBarManager manager) + { + if (manager == null) + throw new ArgumentNullException("manager"); + this.manager = manager; + } + + #region OnTextViewChanged + /// + protected override void OnTextViewChanged(TextView oldTextView, TextView newTextView) + { + if (oldTextView != null) { + oldTextView.VisualLinesChanged -= OnRedrawRequested; + manager.RedrawRequested -= OnRedrawRequested; + } + base.OnTextViewChanged(oldTextView, newTextView); + if (newTextView != null) { + newTextView.VisualLinesChanged += OnRedrawRequested; + manager.RedrawRequested += OnRedrawRequested; + } + InvalidateVisual(); + } + + void OnRedrawRequested(object sender, EventArgs e) + { + InvalidateVisual(); + } + + public virtual void Dispose() + { + this.TextView = null; // detach from TextView (will also detach from manager) + } + #endregion + + /// + protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) + { + // accept clicks even when clicking on the background + return new PointHitTestResult(this, hitTestParameters.HitPoint); + } + + /// + protected override Size MeasureOverride(Size availableSize) + { + return new Size(18, 0); + } + + protected override void OnRender(DrawingContext drawingContext) + { + Size renderSize = this.RenderSize; + drawingContext.DrawRectangle(SystemColors.ControlBrush, null, + new Rect(0, 0, renderSize.Width, renderSize.Height)); + drawingContext.DrawLine(new Pen(SystemColors.ControlDarkBrush, 1), + new Point(renderSize.Width - 0.5, 0), + new Point(renderSize.Width - 0.5, renderSize.Height)); + + TextView textView = this.TextView; + if (textView != null && textView.VisualLinesValid) { + // create a dictionary line number => first bookmark + Dictionary bookmarkDict = new Dictionary(); + foreach (IBookmark bm in manager.Bookmarks) { + int line = bm.LineNumber; + IBookmark existingBookmark; + if (!bookmarkDict.TryGetValue(line, out existingBookmark) || bm.ZOrder > existingBookmark.ZOrder) + bookmarkDict[line] = bm; + } + Size pixelSize = PixelSnapHelpers.GetPixelSize(this); + foreach (VisualLine line in textView.VisualLines) { + int lineNumber = line.FirstDocumentLine.LineNumber; + IBookmark bm; + if (bookmarkDict.TryGetValue(lineNumber, out bm)) { + Rect rect = new Rect(0, PixelSnapHelpers.Round(line.VisualTop - textView.VerticalOffset, pixelSize.Height), 16, 16); + if (dragDropBookmark == bm && dragStarted) + drawingContext.PushOpacity(0.5); + drawingContext.DrawImage(bm.Image, rect); + if (dragDropBookmark == bm && dragStarted) + drawingContext.Pop(); + } + } + if (dragDropBookmark != null && dragStarted) { + Rect rect = new Rect(0, PixelSnapHelpers.Round(dragDropCurrentPoint - 8, pixelSize.Height), 16, 16); + drawingContext.DrawImage(dragDropBookmark.Image, rect); + } + } + } + + IBookmark dragDropBookmark; // bookmark being dragged (!=null if drag'n'drop is active) + double dragDropStartPoint; + double dragDropCurrentPoint; + bool dragStarted; // whether drag'n'drop operation has started (mouse was moved minimum distance) + + protected override void OnMouseDown(MouseButtonEventArgs e) + { + CancelDragDrop(); + base.OnMouseDown(e); + int line = GetLineFromMousePosition(e); + if (!e.Handled && line > 0) { + IBookmark bm = GetBookmarkFromLine(line); + if (bm != null) { + bm.MouseDown(e); + if (!e.Handled) { + if (e.ChangedButton == MouseButton.Left && bm.CanDragDrop && CaptureMouse()) { + StartDragDrop(bm, e); + e.Handled = true; + } + } + } + } + // don't allow selecting text through the IconBarMargin + if (e.ChangedButton == MouseButton.Left) + e.Handled = true; + } + + IBookmark GetBookmarkFromLine(int line) + { + IBookmark result = null; + foreach (IBookmark bm in manager.Bookmarks) { + if (bm.LineNumber == line) { + if (result == null || bm.ZOrder > result.ZOrder) + result = bm; + } + } + return result; + } + + protected override void OnLostMouseCapture(MouseEventArgs e) + { + CancelDragDrop(); + base.OnLostMouseCapture(e); + } + + void StartDragDrop(IBookmark bm, MouseEventArgs e) + { + dragDropBookmark = bm; + dragDropStartPoint = dragDropCurrentPoint = e.GetPosition(this).Y; + if (TextView != null) { + TextArea area = TextView.Services.GetService(typeof(TextArea)) as TextArea; + if (area != null) + area.PreviewKeyDown += TextArea_PreviewKeyDown; + } + } + + void CancelDragDrop() + { + if (dragDropBookmark != null) { + dragDropBookmark = null; + dragStarted = false; + if (TextView != null) { + TextArea area = TextView.Services.GetService(typeof(TextArea)) as TextArea; + if (area != null) + area.PreviewKeyDown -= TextArea_PreviewKeyDown; + } + ReleaseMouseCapture(); + InvalidateVisual(); + } + } + + void TextArea_PreviewKeyDown(object sender, KeyEventArgs e) + { + // any key press cancels drag'n'drop + CancelDragDrop(); + if (e.Key == Key.Escape) + e.Handled = true; + } + + int GetLineFromMousePosition(MouseEventArgs e) + { + TextView textView = this.TextView; + if (textView == null) + return 0; + VisualLine vl = textView.GetVisualLineFromVisualTop(e.GetPosition(textView).Y + textView.ScrollOffset.Y); + if (vl == null) + return 0; + return vl.FirstDocumentLine.LineNumber; + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + if (dragDropBookmark != null) { + dragDropCurrentPoint = e.GetPosition(this).Y; + if (Math.Abs(dragDropCurrentPoint - dragDropStartPoint) > SystemParameters.MinimumVerticalDragDistance) + dragStarted = true; + InvalidateVisual(); + } + } + + protected override void OnMouseUp(MouseButtonEventArgs e) + { + base.OnMouseUp(e); + int line = GetLineFromMousePosition(e); + if (!e.Handled && dragDropBookmark != null) { + if (dragStarted) { + if (line != 0) + dragDropBookmark.Drop(line); + e.Handled = true; + } + CancelDragDrop(); + } + if (!e.Handled && line != 0) { + IBookmark bm = GetBookmarkFromLine(line); + if (bm != null) { + bm.MouseUp(e); + InvalidateVisual(); + if (e.Handled) + return; + } + if (e.ChangedButton == MouseButton.Left && TextView != null) { + // no bookmark on the line: create a new breakpoint + DebuggerService.ToggleBreakpointAt("test", line); + } + InvalidateVisual(); + } + } + } +} diff --git a/Debugger/ILSpy.Debugger/Bookmarks/BookmarkBase.cs b/Debugger/ILSpy.Debugger/Bookmarks/BookmarkBase.cs new file mode 100644 index 000000000..6f62a356d --- /dev/null +++ b/Debugger/ILSpy.Debugger/Bookmarks/BookmarkBase.cs @@ -0,0 +1,189 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Windows.Input; +using System.Windows.Media; + +using ICSharpCode.NRefactory; +using ILSpy.Debugger.AvalonEdit; +using ILSpy.Debugger.AvalonEdit.Editor; + +namespace ILSpy.Debugger.Bookmarks +{ + /// + /// A bookmark that can be attached to an AvalonEdit TextDocument. + /// + public class BookmarkBase : IBookmark + { + Location location; + + IDocument document; + ITextAnchor anchor; + + public IDocument Document { + get { + return document; + } + set { + if (document != value) { + if (anchor != null) { + location = anchor.Location; + anchor = null; + } + document = value; + CreateAnchor(); + OnDocumentChanged(EventArgs.Empty); + } + } + } + + void CreateAnchor() + { + if (document != null) { + int lineNumber = Math.Max(1, Math.Min(location.Line, document.TotalNumberOfLines)); + int lineLength = document.GetLine(lineNumber).Length; + int offset = document.PositionToOffset( + lineNumber, + Math.Max(1, Math.Min(location.Column, lineLength + 1)) + ); + anchor = document.CreateAnchor(offset); + // after insertion: keep bookmarks after the initial whitespace (see DefaultFormattingStrategy.SmartReplaceLine) + anchor.MovementType = AnchorMovementType.AfterInsertion; + anchor.Deleted += AnchorDeleted; + } else { + anchor = null; + } + } + + void AnchorDeleted(object sender, EventArgs e) + { + // the anchor just became invalid, so don't try to use it again + location = Location.Empty; + anchor = null; + RemoveMark(); + } + + protected virtual void RemoveMark() + { + IconBarManager.Instance.Bookmarks.Remove(this); + } + + /// + /// Gets the TextAnchor used for this bookmark. + /// Is null if the bookmark is not connected to a document. + /// + public ITextAnchor Anchor { + get { return anchor; } + } + + public Location Location { + get { + if (anchor != null) + return anchor.Location; + else + return location; + } + set { + location = value; + CreateAnchor(); + } + } + + public event EventHandler DocumentChanged; + + protected virtual void OnDocumentChanged(EventArgs e) + { + if (DocumentChanged != null) { + DocumentChanged(this, e); + } + } + + protected virtual void Redraw() + { + if (document != null) { + IBookmarkMargin bookmarkMargin = IconBarManager.Instance; + if (bookmarkMargin != null) + bookmarkMargin.Redraw(); + } + } + + public string TypeName { get; set; } + + public int LineNumber { + get { + if (anchor != null) + return anchor.Line; + else + return location.Line; + } + } + + public int ColumnNumber { + get { + if (anchor != null) + return anchor.Column; + else + return location.Column; + } + } + + public virtual int ZOrder { + get { return 0; } + } + + /// + /// Gets if the bookmark can be toggled off using the 'set/unset bookmark' command. + /// + public virtual bool CanToggle { + get { + return true; + } + } + + public BookmarkBase(string typeName, Location location) + { + this.TypeName = typeName; + this.Location = location; + } + + public virtual ImageSource Image { + get { return null; } + } + + public virtual void MouseDown(MouseButtonEventArgs e) + { + } + + public virtual void MouseUp(MouseButtonEventArgs e) + { + if (e.ChangedButton == MouseButton.Left && CanToggle) { + RemoveMark(); + e.Handled = true; + } + } + + public virtual bool CanDragDrop { + get { return false; } + } + + public virtual void Drop(int lineNumber) + { + } + } +} diff --git a/Debugger/ILSpy.Debugger/Bookmarks/BookmarkEventHandler.cs b/Debugger/ILSpy.Debugger/Bookmarks/BookmarkEventHandler.cs new file mode 100644 index 000000000..cd24ee861 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Bookmarks/BookmarkEventHandler.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ILSpy.Debugger.Bookmarks +{ + public delegate void BookmarkEventHandler(object sender, BookmarkEventArgs e); + + /// + /// Description of BookmarkEventHandler. + /// + public class BookmarkEventArgs : EventArgs + { + BookmarkBase bookmark; + + public BookmarkBase Bookmark { + get { + return bookmark; + } + } + + public BookmarkEventArgs(BookmarkBase bookmark) + { + this.bookmark = bookmark; + } + } +} diff --git a/Debugger/ILSpy.Debugger/Bookmarks/BookmarkManager.cs b/Debugger/ILSpy.Debugger/Bookmarks/BookmarkManager.cs new file mode 100644 index 000000000..96dfe4921 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Bookmarks/BookmarkManager.cs @@ -0,0 +1,127 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using ICSharpCode.NRefactory; + +namespace ILSpy.Debugger.Bookmarks +{ + /// + /// Static class that maintains the list of bookmarks and breakpoints. + /// + public static class BookmarkManager + { + static List bookmarks = new List(); + + public static List Bookmarks { + get { + return bookmarks; + } + } + + public static List GetBookmarks(string typeName) + { + if (typeName == null) + throw new ArgumentNullException("typeName"); + + List marks = new List(); + + foreach (BookmarkBase mark in bookmarks) { + if (typeName == mark.TypeName) { + marks.Add(mark); + } + } + + return marks; + } + + public static void AddMark(BookmarkBase bookmark) + { + if (bookmark == null) return; + if (bookmarks.Contains(bookmark)) return; + if (bookmarks.Exists(b => IsEqualBookmark(b, bookmark))) return; + bookmarks.Add(bookmark); + OnAdded(new BookmarkEventArgs(bookmark)); + } + + static bool IsEqualBookmark(BookmarkBase a, BookmarkBase b) + { + if (a == b) + return true; + if (a == null || b == null) + return false; + if (a.GetType() != b.GetType()) + return false; + if (a.TypeName != b.TypeName) + return false; + return a.LineNumber == b.LineNumber; + } + + public static void RemoveMark(BookmarkBase bookmark) + { + bookmarks.Remove(bookmark); + OnRemoved(new BookmarkEventArgs(bookmark)); + } + + public static void Clear() + { + while (bookmarks.Count > 0) { + var b = bookmarks[bookmarks.Count - 1]; + bookmarks.RemoveAt(bookmarks.Count - 1); + OnRemoved(new BookmarkEventArgs(b)); + } + } + + internal static void Initialize() + { + + } + + static void OnRemoved(BookmarkEventArgs e) + { + if (Removed != null) { + Removed(null, e); + } + } + + static void OnAdded(BookmarkEventArgs e) + { + if (Added != null) { + Added(null, e); + } + } + + public static void ToggleBookmark(string typeName, int line, + Predicate canToggle, + Func bookmarkFactory) + { + foreach (BookmarkBase bookmark in GetBookmarks(typeName)) { + if (canToggle(bookmark) && bookmark.LineNumber == line) { + BookmarkManager.RemoveMark(bookmark); + return; + } + } + // no bookmark at that line: create a new bookmark + BookmarkManager.AddMark(bookmarkFactory(new Location(0, line))); + } + + public static event BookmarkEventHandler Removed; + public static event BookmarkEventHandler Added; + } +} diff --git a/Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmark.cs b/Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmark.cs new file mode 100644 index 000000000..26e93978a --- /dev/null +++ b/Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmark.cs @@ -0,0 +1,99 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Windows.Input; +using System.Windows.Media; + +using ICSharpCode.NRefactory; +using ILSpy.Debugger.Services; + +namespace ILSpy.Debugger.Bookmarks +{ + public enum BreakpointAction + { + Break, +// Trace, +// Condition + } + + public class BreakpointBookmark : BookmarkBase + { + bool isHealthy = true; + bool isEnabled = true; + string tooltip; + + BreakpointAction action = BreakpointAction.Break; + + public BreakpointAction Action { + get { + return action; + } + set { + if (action != value) { + action = value; + Redraw(); + } + } + } + + public virtual bool IsHealthy { + get { + return isHealthy; + } + set { + if (isHealthy != value) { + isHealthy = value; + Redraw(); + } + } + } + + public virtual bool IsEnabled { + get { + return isEnabled; + } + set { + if (isEnabled != value) { + isEnabled = value; + if (IsEnabledChanged != null) + IsEnabledChanged(this, EventArgs.Empty); + Redraw(); + } + } + } + + public event EventHandler IsEnabledChanged; + + public string Tooltip { + get { return tooltip; } + set { tooltip = value; } + } + + public BreakpointBookmark(string typeName, Location location, BreakpointAction action) : base(typeName, location) + { + this.action = action; + } + + public override ImageSource Image { + get { + return ImageService.Breakpoint; + } + } + } +} diff --git a/Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmarkEventArgs.cs b/Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmarkEventArgs.cs new file mode 100644 index 000000000..3fd723206 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Bookmarks/BreakpointBookmarkEventArgs.cs @@ -0,0 +1,23 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ILSpy.Debugger.Bookmarks +{ + public class BreakpointBookmarkEventArgs : EventArgs + { + BreakpointBookmark breakpointBookmark; + + public BreakpointBookmark BreakpointBookmark { + get { + return breakpointBookmark; + } + } + + public BreakpointBookmarkEventArgs(BreakpointBookmark breakpointBookmark) + { + this.breakpointBookmark = breakpointBookmark; + } + } +} diff --git a/Debugger/ILSpy.Debugger/Bookmarks/CurrentLineBookmark.cs b/Debugger/ILSpy.Debugger/Bookmarks/CurrentLineBookmark.cs new file mode 100644 index 000000000..ca67b5127 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Bookmarks/CurrentLineBookmark.cs @@ -0,0 +1,95 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Windows.Media; +using ICSharpCode.NRefactory; +using ILSpy.Debugger.Services; + +namespace ILSpy.Debugger.Bookmarks +{ + public class CurrentLineBookmark : BookmarkBase + { + static CurrentLineBookmark instance; + + static int startLine; + static int startColumn; + static int endLine; + static int endColumn; + +// public static void SetPosition(IViewContent viewContent, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn) +// { +// ITextEditorProvider tecp = viewContent as ITextEditorProvider; +// if (tecp != null) +// SetPosition(tecp.TextEditor.FileName, tecp.TextEditor.Document, makerStartLine, makerStartColumn, makerEndLine, makerEndColumn); +// else +// Remove(); +// } +// +// public static void SetPosition(FileName fileName, IDocument document, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn) +// { +// Remove(); +// +// startLine = makerStartLine; +// startColumn = makerStartColumn; +// endLine = makerEndLine; +// endColumn = makerEndColumn; +// +// if (startLine < 1 || startLine > document.TotalNumberOfLines) +// return; +// if (endLine < 1 || endLine > document.TotalNumberOfLines) { +// endLine = startLine; +// endColumn = int.MaxValue; +// } +// if (startColumn < 1) +// startColumn = 1; +// +// IDocumentLine line = document.GetLine(startLine); +// if (endColumn < 1 || endColumn > line.Length) +// endColumn = line.Length; +// instance = new CurrentLineBookmark(fileName, new Location(startColumn, startLine)); +// BookmarkManager.AddMark(instance); +// } +// + public static void Remove() + { + if (instance != null) { + BookmarkManager.RemoveMark(instance); + instance = null; + } + } + + public override bool CanToggle { + get { + return false; + } + } + + public override int ZOrder { + get { return 100; } + } + + public CurrentLineBookmark(string typeName, Location location) : base(typeName, location) + { + + } + + public override ImageSource Image { + get { return ImageService.CurrentLine; } + } + + public override bool CanDragDrop { + get { return true; } + } + + public override void Drop(int lineNumber) + { + // call async because the Debugger seems to use Application.DoEvents(), but we don't want to process events + // because Drag'N'Drop operation has finished +// WorkbenchSingleton.SafeThreadAsyncCall( +// delegate { +// DebuggerService.CurrentDebugger.SetInstructionPointer(this.FileName, lineNumber, 1); +// }); + } + } +} diff --git a/Debugger/ILSpy.Debugger/Bookmarks/IBookmark.cs b/Debugger/ILSpy.Debugger/Bookmarks/IBookmark.cs new file mode 100644 index 000000000..3fcc713fd --- /dev/null +++ b/Debugger/ILSpy.Debugger/Bookmarks/IBookmark.cs @@ -0,0 +1,84 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.Windows.Input; +using System.Windows.Media; + +namespace ILSpy.Debugger.Bookmarks +{ + /// + /// The bookmark margin. + /// + public interface IBookmarkMargin + { + /// + /// Gets the list of bookmarks. + /// + IList Bookmarks { get; } + + /// + /// Redraws the bookmark margin. Bookmarks need to call this method when the Image changes. + /// + void Redraw(); + } + + /// + /// Represents a bookmark in the bookmark margin. + /// + public interface IBookmark + { + /// + /// Gets the line number of the bookmark. + /// + int LineNumber { get; } + + /// + /// Gets the image. + /// + ImageSource Image { get; } + + /// + /// Gets the Z-Order of the bookmark icon. + /// + int ZOrder { get; } + + /// + /// Handles the mouse down event. + /// + void MouseDown(MouseButtonEventArgs e); + + /// + /// Handles the mouse up event. + /// + void MouseUp(MouseButtonEventArgs e); + + /// + /// Gets whether this bookmark can be dragged around. + /// + bool CanDragDrop { get; } + + /// + /// Notifies the bookmark that it was dropped on the specified line. + /// + void Drop(int lineNumber); + } +} diff --git a/Debugger/ILSpy.Debugger/ILSpy.Debugger.csproj b/Debugger/ILSpy.Debugger/ILSpy.Debugger.csproj new file mode 100644 index 000000000..b06302c9a --- /dev/null +++ b/Debugger/ILSpy.Debugger/ILSpy.Debugger.csproj @@ -0,0 +1,115 @@ + + + + {6D3D0F0D-348D-456A-A6ED-E9BD5EFABB6A} + Debug + x86 + Library + ILSpy.Debugger + ILSpy.Debugger + v4.0 + Properties + + + x86 + + + bin\Debug\ + True + Full + False + True + DEBUG;TRACE + + + bin\Release\ + False + None + True + False + TRACE + + + + + + + 3.5 + + + 4.0 + + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AttachToProcessWindow.xaml + Code + + + + + + + + + + + + + + + + + + + + + {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1} + ICSharpCode.AvalonEdit + + + {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} + NRefactory + + + {1D18D788-F7EE-4585-A23B-34DC8EC63CB8} + Debugger.Core + + + + + + + + \ No newline at end of file diff --git a/Debugger/ILSpy.Debugger/Images/Breakpoint.png b/Debugger/ILSpy.Debugger/Images/Breakpoint.png new file mode 100644 index 000000000..a3360ed4b Binary files /dev/null and b/Debugger/ILSpy.Debugger/Images/Breakpoint.png differ diff --git a/Debugger/ILSpy.Debugger/Images/CurrentLine.png b/Debugger/ILSpy.Debugger/Images/CurrentLine.png new file mode 100644 index 000000000..78d8848ce Binary files /dev/null and b/Debugger/ILSpy.Debugger/Images/CurrentLine.png differ diff --git a/Debugger/ILSpy.Debugger/Models/RunningProcess.cs b/Debugger/ILSpy.Debugger/Models/RunningProcess.cs new file mode 100644 index 000000000..da2e57c48 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Models/RunningProcess.cs @@ -0,0 +1,41 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Windows.Controls; + +namespace ILSpy.Debugger.Models +{ + sealed class RunningProcess + { + public int ProcessId { get; set; } + + public string WindowTitle { get; set; } + + public string ProcessName { get; set; } + + public string FileName { get; set; } + + public string Managed { get; set; } + + public Process Process { get; set; } + } +} diff --git a/Debugger/ILSpy.Debugger/Properties/AssemblyInfo.cs b/Debugger/ILSpy.Debugger/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..036d12a47 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +#region Using directives + +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +#endregion + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ILSpy.Debugger")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ILSpy.Debugger")] +[assembly: AssemblyCopyright("Copyright 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all the values or you can use the default the Revision and +// Build Numbers by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] diff --git a/Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs b/Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs new file mode 100644 index 000000000..35f85fb58 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Services/Debugger/DebuggerService.cs @@ -0,0 +1,364 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Text; + +using ICSharpCode.NRefactory; +using ILSpy.Debugger.Bookmarks; + +namespace ILSpy.Debugger.Services +{ + public static class DebuggerService + { + static IDebugger currentDebugger; + + static DebuggerService() + { + BookmarkManager.Added += BookmarkAdded; + BookmarkManager.Removed += BookmarkRemoved; + } + + static IDebugger GetCompatibleDebugger() + { + return new DefaultDebugger(); + } + + /// + /// Gets the current debugger. The debugger addin is loaded on demand; so if you + /// just want to check a property like IsDebugging, check + /// before using this property. + /// + public static IDebugger CurrentDebugger { + get { + if (currentDebugger == null) { + currentDebugger = GetCompatibleDebugger(); + currentDebugger.DebugStarting += new EventHandler(OnDebugStarting); + currentDebugger.DebugStarted += new EventHandler(OnDebugStarted); + currentDebugger.DebugStopped += new EventHandler(OnDebugStopped); + } + return currentDebugger; + } + } + + /// + /// Returns true if debugger is already loaded. + /// + public static bool IsDebuggerLoaded { + get { + return currentDebugger != null; + } + } + + static bool debuggerStarted; + + /// + /// Gets whether the debugger is currently active. + /// + public static bool IsDebuggerStarted { + get { return debuggerStarted; } + } + + public static event EventHandler DebugStarting; + public static event EventHandler DebugStarted; + public static event EventHandler DebugStopped; + + static void OnDebugStarting(object sender, EventArgs e) + { + ClearDebugMessages(); + + if (DebugStarting != null) + DebugStarting(null, e); + } + + static void OnDebugStarted(object sender, EventArgs e) + { + debuggerStarted = true; + if (DebugStarted != null) + DebugStarted(null, e); + } + + static void OnDebugStopped(object sender, EventArgs e) + { + debuggerStarted = false; + + RemoveCurrentLineMarker(); + + if (DebugStopped != null) + DebugStopped(null, e); + } + + public static void ClearDebugMessages() + { + + } + + public static void PrintDebugMessage(string msg) + { + + } + + public static event EventHandler BreakPointChanged; + public static event EventHandler BreakPointAdded; + public static event EventHandler BreakPointRemoved; + + static void OnBreakPointChanged(BreakpointBookmarkEventArgs e) + { + if (BreakPointChanged != null) { + BreakPointChanged(null, e); + } + } + + static void OnBreakPointAdded(BreakpointBookmarkEventArgs e) + { + if (BreakPointAdded != null) { + BreakPointAdded(null, e); + } + } + + static void OnBreakPointRemoved(BreakpointBookmarkEventArgs e) + { + if (BreakPointRemoved != null) { + BreakPointRemoved(null, e); + } + } + + public static IList Breakpoints { + get { + List breakpoints = new List(); + foreach (var bookmark in BookmarkManager.Bookmarks) { + BreakpointBookmark breakpoint = bookmark as BreakpointBookmark; + if (breakpoint != null) { + breakpoints.Add(breakpoint); + } + } + return breakpoints.AsReadOnly(); + } + } + + static void BookmarkAdded(object sender, BookmarkEventArgs e) + { + BreakpointBookmark bb = e.Bookmark as BreakpointBookmark; + if (bb != null) { + OnBreakPointAdded(new BreakpointBookmarkEventArgs(bb)); + } + } + + static void BookmarkRemoved(object sender, BookmarkEventArgs e) + { + BreakpointBookmark bb = e.Bookmark as BreakpointBookmark; + if (bb != null) { + OnBreakPointRemoved(new BreakpointBookmarkEventArgs(bb)); + } + } + + static void BookmarkChanged(object sender, EventArgs e) + { + BreakpointBookmark bb = sender as BreakpointBookmark; + if (bb != null) { + OnBreakPointChanged(new BreakpointBookmarkEventArgs(bb)); + } + } + + public static void ToggleBreakpointAt(string typeName, int lineNumber) + { + BookmarkManager.ToggleBookmark( + typeName, lineNumber, + b => b.CanToggle && b is BreakpointBookmark, + location => new BreakpointBookmark(typeName, location, BreakpointAction.Break)); + } + + /* TODO: reimplement this stuff + static void ViewContentOpened(object sender, ViewContentEventArgs e) + { + textArea.IconBarMargin.MouseDown += IconBarMouseDown; + textArea.ToolTipRequest += TextAreaToolTipRequest; + textArea.MouseLeave += TextAreaMouseLeave; + }*/ + + public static void RemoveCurrentLineMarker() + { + CurrentLineBookmark.Remove(); + } + + public static void JumpToCurrentLine(string SourceFullFilename, int StartLine, int StartColumn, int EndLine, int EndColumn) + { +// IViewContent viewContent = FileService.OpenFile(SourceFullFilename); +// if (viewContent is ITextEditorProvider) +// ((ITextEditorProvider)viewContent).TextEditor.JumpTo(StartLine, StartColumn); +// CurrentLineBookmark.SetPosition(viewContent, StartLine, StartColumn, EndLine, EndColumn); + } + + #region Tool tips + /// + /// Gets debugger tooltip information for the specified position. + /// A descriptive string for the element or a DebuggerTooltipControl + /// showing its current value (when in debugging mode) can be returned + /// through the ToolTipRequestEventArgs.SetTooltip() method. + /// +// internal static void HandleToolTipRequest(ToolTipRequestEventArgs e) +// { +// if (!e.InDocument) +// return; +// Location logicPos = e.LogicalPosition; +// var doc = e.Editor.Document; +// IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(e.Editor.FileName); +// if (expressionFinder == null) +// return; +// var currentLine = doc.GetLine(logicPos.Y); +// if (logicPos.X > currentLine.Length) +// return; +// string textContent = doc.Text; +// ExpressionResult expressionResult = expressionFinder.FindFullExpression(textContent, doc.PositionToOffset(logicPos.Line, logicPos.Column)); +// string expression = (expressionResult.Expression ?? "").Trim(); +// if (expression.Length > 0) { +// // Look if it is variable +// ResolveResult result = ParserService.Resolve(expressionResult, logicPos.Y, logicPos.X, e.Editor.FileName, textContent); +// bool debuggerCanShowValue; +// string toolTipText = GetText(result, expression, out debuggerCanShowValue); +// if (Control.ModifierKeys == Keys.Control) { +// toolTipText = "expr: " + expressionResult.ToString() + "\n" + toolTipText; +// debuggerCanShowValue = false; +// } +// if (toolTipText != null) { +// if (debuggerCanShowValue && currentDebugger != null) { +// object toolTip = currentDebugger.GetTooltipControl(e.LogicalPosition, expressionResult.Expression); +// if (toolTip != null) +// e.SetToolTip(toolTip); +// else +// e.SetToolTip(toolTipText); +// } else { +// e.SetToolTip(toolTipText); +// } +// } +// } else { +// #if DEBUG +// if (Control.ModifierKeys == Keys.Control) { +// e.SetToolTip("no expr: " + expressionResult.ToString()); +// } +// #endif +// } +// } +// +// static string GetText(ResolveResult result, string expression, out bool debuggerCanShowValue) +// { +// debuggerCanShowValue = false; +// if (result == null) { +// // when pressing control, show the expression even when it could not be resolved +// return (Control.ModifierKeys == Keys.Control) ? "" : null; +// } +// if (result is MixedResolveResult) +// return GetText(((MixedResolveResult)result).PrimaryResult, expression, out debuggerCanShowValue); +// else if (result is DelegateCallResolveResult) +// return GetText(((DelegateCallResolveResult)result).Target, expression, out debuggerCanShowValue); +// +// IAmbience ambience = AmbienceService.GetCurrentAmbience(); +// ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.UseFullyQualifiedMemberNames; +// if (result is MemberResolveResult) { +// return GetMemberText(ambience, ((MemberResolveResult)result).ResolvedMember, expression, out debuggerCanShowValue); +// } else if (result is LocalResolveResult) { +// LocalResolveResult rr = (LocalResolveResult)result; +// ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedTypeNames +// | ConversionFlags.ShowReturnType | ConversionFlags.ShowDefinitionKeyWord; +// StringBuilder b = new StringBuilder(); +// if (rr.IsParameter) +// b.Append("parameter "); +// else +// b.Append("local variable "); +// b.Append(ambience.Convert(rr.Field)); +// if (currentDebugger != null) { +// string currentValue = currentDebugger.GetValueAsString(rr.VariableName); +// if (currentValue != null) { +// debuggerCanShowValue = true; +// b.Append(" = "); +// if (currentValue.Length > 256) +// currentValue = currentValue.Substring(0, 256) + "..."; +// b.Append(currentValue); +// } +// } +// return b.ToString(); +// } else if (result is NamespaceResolveResult) { +// return "namespace " + ((NamespaceResolveResult)result).Name; +// } else if (result is TypeResolveResult) { +// IClass c = ((TypeResolveResult)result).ResolvedClass; +// if (c != null) +// return GetMemberText(ambience, c, expression, out debuggerCanShowValue); +// else +// return ambience.Convert(result.ResolvedType); +// } else if (result is MethodGroupResolveResult) { +// MethodGroupResolveResult mrr = result as MethodGroupResolveResult; +// IMethod m = mrr.GetMethodIfSingleOverload(); +// IMethod m2 = mrr.GetMethodWithEmptyParameterList(); +// if (m != null) +// return GetMemberText(ambience, m, expression, out debuggerCanShowValue); +// else if (ambience is VBNetAmbience && m2 != null) +// return GetMemberText(ambience, m2, expression, out debuggerCanShowValue); +// else +// return "Overload of " + ambience.Convert(mrr.ContainingType) + "." + mrr.Name; +// } else { +// if (Control.ModifierKeys == Keys.Control) { +// if (result.ResolvedType != null) +// return "expression of type " + ambience.Convert(result.ResolvedType); +// else +// return "ResolveResult without ResolvedType"; +// } else { +// return null; +// } +// } +// } +// +// static string GetMemberText(IAmbience ambience, IEntity member, string expression, out bool debuggerCanShowValue) +// { +// bool tryDisplayValue = false; +// debuggerCanShowValue = false; +// StringBuilder text = new StringBuilder(); +// if (member is IField) { +// text.Append(ambience.Convert(member as IField)); +// tryDisplayValue = true; +// } else if (member is IProperty) { +// text.Append(ambience.Convert(member as IProperty)); +// tryDisplayValue = true; +// } else if (member is IEvent) { +// text.Append(ambience.Convert(member as IEvent)); +// } else if (member is IMethod) { +// text.Append(ambience.Convert(member as IMethod)); +// } else if (member is IClass) { +// text.Append(ambience.Convert(member as IClass)); +// } else { +// text.Append("unknown member "); +// text.Append(member.ToString()); +// } +// if (tryDisplayValue && currentDebugger != null) { +// LoggingService.Info("asking debugger for value of '" + expression + "'"); +// string currentValue = currentDebugger.GetValueAsString(expression); +// if (currentValue != null) { +// debuggerCanShowValue = true; +// text.Append(" = "); +// text.Append(currentValue); +// } +// } +// string documentation = member.Documentation; +// if (documentation != null && documentation.Length > 0) { +// text.Append('\n'); +// text.Append(ICSharpCode.SharpDevelop.Editor.CodeCompletion.CodeCompletionItem.ConvertDocumentation(documentation)); +// } +// return text.ToString(); +// } + #endregion + } + + /// + /// Provides the default debugger tooltips on the text area. + /// + /// + /// This class must be public because it is accessed via the AddInTree. + /// +// public class DebuggerTextAreaToolTipProvider : ITextAreaToolTipProvider +// { +// public void HandleToolTipRequest(ToolTipRequestEventArgs e) +// { +// DebuggerService.HandleToolTipRequest(e); +// } +// } +} diff --git a/Debugger/ILSpy.Debugger/Services/Debugger/DefaultDebugger.cs b/Debugger/ILSpy.Debugger/Services/Debugger/DefaultDebugger.cs new file mode 100644 index 000000000..66301471e --- /dev/null +++ b/Debugger/ILSpy.Debugger/Services/Debugger/DefaultDebugger.cs @@ -0,0 +1,188 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Diagnostics; +using System.Threading; + +using ICSharpCode.NRefactory; + +namespace ILSpy.Debugger.Services +{ + public class DefaultDebugger : IDebugger + { + Process attachedProcess = null; + + public bool IsDebugging { + get { + return attachedProcess != null; + } + } + + public bool IsProcessRunning { + get { + return IsDebugging; + } + } + + /// + public bool BreakAtBeginning { + get; set; + } + + public void Start(ProcessStartInfo processStartInfo) + { + if (attachedProcess != null) { + return; + } + + OnDebugStarting(EventArgs.Empty); + try { + attachedProcess = new Process(); + attachedProcess.StartInfo = processStartInfo; + attachedProcess.Exited += new EventHandler(AttachedProcessExited); + attachedProcess.EnableRaisingEvents = true; + attachedProcess.Start(); + OnDebugStarted(EventArgs.Empty); + } catch (Exception) { + OnDebugStopped(EventArgs.Empty); + throw new ApplicationException("Can't execute \"" + processStartInfo.FileName + "\"\n"); + } + } + + public void ShowAttachDialog() + { + } + + public void Attach(Process process) + { + } + + public void Detach() + { + } + + void AttachedProcessExited(object sender, EventArgs e) + { + attachedProcess.Exited -= new EventHandler(AttachedProcessExited); + attachedProcess.Dispose(); + attachedProcess = null; + OnDebugStopped(EventArgs.Empty); + } + + public void StartWithoutDebugging(ProcessStartInfo processStartInfo) + { + Process.Start(processStartInfo); + } + + public void Stop() + { + if (attachedProcess != null) { + attachedProcess.Exited -= new EventHandler(AttachedProcessExited); + attachedProcess.Kill(); + attachedProcess.Close(); + attachedProcess.Dispose(); + attachedProcess = null; + } + } + + // ExecutionControl: + + public void Break() + { + throw new NotSupportedException(); + } + + public void Continue() + { + throw new NotSupportedException(); + } + // Stepping: + + public void StepInto() + { + throw new NotSupportedException(); + } + + public void StepOver() + { + throw new NotSupportedException(); + } + + public void StepOut() + { + throw new NotSupportedException(); + } + + /// + /// Gets the current value of the variable as string that can be displayed in tooltips. + /// + public string GetValueAsString(string variable) + { + return null; + } + + /// + /// Gets the tooltip control that shows the value of given variable. + /// Return null if no tooltip is available. + /// + public object GetTooltipControl(Location logicalPosition, string variable) + { + return null; + } + + public bool CanSetInstructionPointer(string filename, int line, int column) + { + return false; + } + + public bool SetInstructionPointer(string filename, int line, int column) + { + return false; + } + + + public event EventHandler DebugStarted; + + protected virtual void OnDebugStarted(EventArgs e) + { + if (DebugStarted != null) { + DebugStarted(this, e); + } + } + + + public event EventHandler IsProcessRunningChanged; + + protected virtual void OnIsProcessRunningChanged(EventArgs e) + { + if (IsProcessRunningChanged != null) { + IsProcessRunningChanged(this, e); + } + } + + + public event EventHandler DebugStopped; + + protected virtual void OnDebugStopped(EventArgs e) + { + if (DebugStopped != null) { + DebugStopped(this, e); + } + } + + public event EventHandler DebugStarting; + + protected virtual void OnDebugStarting(EventArgs e) + { + if (DebugStarting != null) { + DebugStarting(this, e); + } + } + + public void Dispose() + { + Stop(); + } + } +} diff --git a/Debugger/ILSpy.Debugger/Services/Debugger/IDebugger.cs b/Debugger/ILSpy.Debugger/Services/Debugger/IDebugger.cs new file mode 100644 index 000000000..a783a6298 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Services/Debugger/IDebugger.cs @@ -0,0 +1,115 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Diagnostics; +using ICSharpCode.NRefactory; + +namespace ILSpy.Debugger.Services +{ + public interface IDebugger : IDisposable + { + /// + /// Returns true if debuger is attached to a process + /// + bool IsDebugging { + get; + } + + /// + /// Returns true if process is running + /// Returns false if breakpoint is hit, program is breaked, program is stepped, etc... + /// + bool IsProcessRunning { + get; + } + + /// + /// Gets or sets whether the debugger should break at the first line of execution. + /// + bool BreakAtBeginning { + get; set; + } + + /// + /// Starts process and attaches debugger + /// + void Start(ProcessStartInfo processStartInfo); + + void StartWithoutDebugging(ProcessStartInfo processStartInfo); + + /// + /// Stops/terminates attached process + /// + void Stop(); + + // ExecutionControl: + + void Break(); + + void Continue(); + + // Stepping: + + void StepInto(); + + void StepOver(); + + void StepOut(); + + /// + /// Shows a dialog so the user can attach to a process. + /// + void ShowAttachDialog(); + + /// + /// Used to attach to an existing process. + /// + void Attach(Process process); + + void Detach(); + + /// + /// Gets the current value of the variable as string that can be displayed in tooltips. + /// + string GetValueAsString(string variable); + + /// + /// Gets the tooltip control that shows the value of given variable. + /// Return null if no tooltip is available. + /// + object GetTooltipControl(Location logicalPosition, string variable); + + /// + /// Queries the debugger whether it is possible to set the instruction pointer to a given position. + /// + /// True if possible. False otherwise + bool CanSetInstructionPointer(string filename, int line, int column); + + /// + /// Set the instruction pointer to a given position. + /// + /// True if successful. False otherwise + bool SetInstructionPointer(string filename, int line, int column); + + /// + /// Ocurrs when the debugger is starting. + /// + event EventHandler DebugStarting; + + /// + /// Ocurrs after the debugger has started. + /// + event EventHandler DebugStarted; + + /// + /// Ocurrs when the value of IsProcessRunning changes. + /// + event EventHandler IsProcessRunningChanged; + + /// + /// Ocurrs after the debugging of program is finished. + /// + event EventHandler DebugStopped; + } +} diff --git a/Debugger/ILSpy.Debugger/Services/Debugger/Tooltips/ITreeNode.cs b/Debugger/ILSpy.Debugger/Services/Debugger/Tooltips/ITreeNode.cs new file mode 100644 index 000000000..93e164b09 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Services/Debugger/Tooltips/ITreeNode.cs @@ -0,0 +1,41 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Windows.Media; + +namespace ILSpy.Debugger.Debugging +{ + /// + /// Node that can be bound to . + /// + public interface ITreeNode : IComparable + { + string Name { get; } + + string FullName { get; } + + string ImageName { get; } + + string Text { get; } + + bool CanSetText { get; } + + string Type { get; } + + ImageSource ImageSource { get; } + + IEnumerable ChildNodes { get; } + + bool HasChildNodes { get; } + + IEnumerable VisualizerCommands { get; } + + bool HasVisualizerCommands { get; } + + bool IsPinned { get; set; } + + bool SetText(string newValue); + } +} diff --git a/Debugger/ILSpy.Debugger/Services/Debugger/Tooltips/IVisualizerCommand.cs b/Debugger/ILSpy.Debugger/Services/Debugger/Tooltips/IVisualizerCommand.cs new file mode 100644 index 000000000..df25c392f --- /dev/null +++ b/Debugger/ILSpy.Debugger/Services/Debugger/Tooltips/IVisualizerCommand.cs @@ -0,0 +1,25 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ILSpy.Debugger.Debugging +{ + /// + /// Command called from . + /// + public interface IVisualizerCommand + { + /// + /// Can this command execute? + /// + bool CanExecute { get; } + + /// + /// Executes this visualizer command. + /// + void Execute(); + } +} diff --git a/Debugger/ILSpy.Debugger/Services/ImageService/ImageService.cs b/Debugger/ILSpy.Debugger/Services/ImageService/ImageService.cs new file mode 100644 index 000000000..585e3f4b4 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Services/ImageService/ImageService.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Windows.Media.Imaging; + +namespace ILSpy.Debugger.Services +{ + static class ImageService + { + static BitmapImage LoadBitmap(string name) + { + BitmapImage image = new BitmapImage(new Uri("pack://application:,,,/ILSpy.Debugger;component/Images/" + name + ".png")); + image.Freeze(); + return image; + } + + public static readonly BitmapImage Breakpoint = LoadBitmap("Breakpoint"); + public static readonly BitmapImage CurrentLine = LoadBitmap("CurrentLine"); + } +} diff --git a/Debugger/ILSpy.Debugger/Services/ParserService/IParser.cs b/Debugger/ILSpy.Debugger/Services/ParserService/IParser.cs new file mode 100644 index 000000000..55370b5e0 --- /dev/null +++ b/Debugger/ILSpy.Debugger/Services/ParserService/IParser.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ILSpy.Debugger.Services +{ + /// + /// Description of IParser. + /// + public class IParser + { + public IParser() + { + } + } +} diff --git a/Debugger/ILSpy.Debugger/Services/ParserService/ParserService.cs b/Debugger/ILSpy.Debugger/Services/ParserService/ParserService.cs new file mode 100644 index 000000000..f670c4b2e --- /dev/null +++ b/Debugger/ILSpy.Debugger/Services/ParserService/ParserService.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; + +namespace ILSpy.Debugger.Services +{ + /// + /// Description of ParserService. + /// + public static class ParserService + { + + } +} diff --git a/Debugger/ILSpy.Debugger/UI/AttachToProcessWindow.xaml b/Debugger/ILSpy.Debugger/UI/AttachToProcessWindow.xaml new file mode 100644 index 000000000..48082cd66 --- /dev/null +++ b/Debugger/ILSpy.Debugger/UI/AttachToProcessWindow.xaml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + +