Author: martin
Date: 2007-11-22 05:24:51 -0500 (Thu, 22 Nov 2007)
New Revision: 90138
Modified:
trunk/debugger/ChangeLog
trunk/debugger/backend/SingleSteppingEngine.cs
trunk/debugger/backend/arch/Instruction.cs
trunk/debugger/backend/arch/Instruction_X86_64.cs
trunk/debugger/languages/mono/MonoLanguageBackend.cs
trunk/debugger/test/testsuite/TestDelegate.cs
Log:
2007-11-22 Martin Baulig <[EMAIL PROTECTED]>
* backend/SingleSteppingEngine.cs
(OperationDelegateInvoke): New operation; step through a delegate
invocation trampoline.
* backend/arch/Instruction.cs
(Instruction.TrampolineType): Added `DelegateInvoke'.
Modified: trunk/debugger/ChangeLog
===================================================================
--- trunk/debugger/ChangeLog 2007-11-22 10:21:00 UTC (rev 90137)
+++ trunk/debugger/ChangeLog 2007-11-22 10:24:51 UTC (rev 90138)
@@ -1,3 +1,12 @@
+2007-11-22 Martin Baulig <[EMAIL PROTECTED]>
+
+ * backend/SingleSteppingEngine.cs
+ (OperationDelegateInvoke): New operation; step through a delegate
+ invocation trampoline.
+
+ * backend/arch/Instruction.cs
+ (Instruction.TrampolineType): Added `DelegateInvoke'.
+
2007-11-20 Martin Baulig <[EMAIL PROTECTED]>
* test/testsuite/TestDelegate.cs: Temporarily disable this.
Modified: trunk/debugger/backend/SingleSteppingEngine.cs
===================================================================
--- trunk/debugger/backend/SingleSteppingEngine.cs 2007-11-22 10:21:00 UTC
(rev 90137)
+++ trunk/debugger/backend/SingleSteppingEngine.cs 2007-11-22 10:24:51 UTC
(rev 90138)
@@ -1260,6 +1260,9 @@
PushOperation (new OperationMonoTrampoline (
this, instruction, trampoline,
handler));
return true;
+ } else if (type ==
Instruction.TrampolineType.DelegateInvoke) {
+ PushOperation (new OperationDelegateInvoke
(this));
+ return true;
}
return false;
@@ -3635,6 +3638,61 @@
}
}
+ protected class OperationDelegateInvoke : OperationStepBase
+ {
+ public OperationDelegateInvoke (SingleSteppingEngine sse)
+ : base (sse, null)
+ { }
+
+ public override bool IsSourceOperation {
+ get { return true; }
+ }
+
+ protected override void DoExecute ()
+ {
+ sse.do_step_native ();
+ }
+
+ bool finished;
+
+ protected override bool DoProcessEvent ()
+ {
+ TargetAddress current_frame = inferior.CurrentFrame;
+
+ Report.Debug (DebugFlags.SSE, "{0} delegate impl
stopped at {1}",
+ sse, current_frame);
+
+ if (finished)
+ return true;
+
+ /*
+ * If this is not a call instruction, continue stepping
until we leave
+ * the current method.
+ */
+ Instruction instruction =
inferior.Architecture.ReadInstruction (
+ inferior, current_frame);
+ if ((instruction == null) ||
!instruction.HasInstructionSize) {
+ sse.do_step_native ();
+ return false;
+ }
+
+ Report.Debug (DebugFlags.SSE, "{0} delegate impl
stopped at {1}: {2}",
+ sse, current_frame, instruction);
+
+ if ((instruction.InstructionType ==
Instruction.Type.IndirectJump) ||
+ (instruction.InstructionType ==
Instruction.Type.IndirectCall))
+ finished = true;
+
+ sse.do_step_native ();
+ return false;
+ }
+
+ protected override bool TrampolineHandler (Method method)
+ {
+ return false;
+ }
+ }
+
protected class OperationReturn : OperationCallback
{
public readonly MonoLanguageBackend Language;
Modified: trunk/debugger/backend/arch/Instruction.cs
===================================================================
--- trunk/debugger/backend/arch/Instruction.cs 2007-11-22 10:21:00 UTC (rev
90137)
+++ trunk/debugger/backend/arch/Instruction.cs 2007-11-22 10:24:51 UTC (rev
90138)
@@ -23,7 +23,8 @@
None,
NativeTrampolineStart,
NativeTrampoline,
- MonoTrampoline
+ MonoTrampoline,
+ DelegateInvoke
}
public abstract TargetAddress Address {
Modified: trunk/debugger/backend/arch/Instruction_X86_64.cs
===================================================================
--- trunk/debugger/backend/arch/Instruction_X86_64.cs 2007-11-22 10:21:00 UTC
(rev 90137)
+++ trunk/debugger/backend/arch/Instruction_X86_64.cs 2007-11-22 10:24:51 UTC
(rev 90138)
@@ -142,16 +142,9 @@
}
}
- protected bool GetMonoTrampoline (TargetMemoryAccess memory,
+ protected bool GetMonoTrampoline (TargetMemoryAccess memory,
TargetAddress call_target,
out TargetAddress trampoline)
{
- if ((InstructionType != Type.Call) && (InstructionType
!= Type.IndirectCall)) {
- trampoline = TargetAddress.Null;
- return false;
- }
-
- TargetAddress call_target = GetEffectiveAddress
(memory);
-
TargetBinaryReader reader = memory.ReadMemory
(call_target, 14).GetReader ();
byte opcode = reader.ReadByte ();
if (opcode != 0xe8) {
@@ -189,8 +182,24 @@
}
}
+ if ((InstructionType != Type.Call) && (InstructionType
!= Type.IndirectCall)) {
+ trampoline = TargetAddress.Null;
+ return TrampolineType.None;
+ }
+
if (Opcodes.Process.IsManagedApplication) {
- if (GetMonoTrampoline (memory, out trampoline))
+ TargetAddress target = GetEffectiveAddress
(memory);
+ if (target.IsNull) {
+ trampoline = TargetAddress.Null;
+ return TrampolineType.None;
+ }
+
+ if
(Opcodes.Process.MonoLanguage.IsDelegateTrampoline (target)) {
+ trampoline = target;
+ return TrampolineType.DelegateInvoke;
+ }
+
+ if (GetMonoTrampoline (memory, target, out
trampoline))
return TrampolineType.MonoTrampoline;
}
Modified: trunk/debugger/languages/mono/MonoLanguageBackend.cs
===================================================================
--- trunk/debugger/languages/mono/MonoLanguageBackend.cs 2007-11-22
10:21:00 UTC (rev 90137)
+++ trunk/debugger/languages/mono/MonoLanguageBackend.cs 2007-11-22
10:24:51 UTC (rev 90138)
@@ -108,22 +108,27 @@
internal abstract class MonoDataTable
{
public readonly TargetAddress TableAddress;
- public readonly TargetAddress FirstChunk;
+ TargetAddress first_chunk;
TargetAddress current_chunk;
int last_offset;
protected MonoDataTable (TargetAddress address, TargetAddress
first_chunk)
{
- this.TableAddress =address;
- this.FirstChunk = first_chunk;
-
- current_chunk = first_chunk;
+ this.TableAddress = address;
+ this.first_chunk = first_chunk;
+ this.current_chunk = first_chunk;
}
public void Read (TargetMemoryAccess memory)
{
- int header_size = 16 +
memory.TargetMemoryInfo.TargetAddressSize;
+ int address_size =
memory.TargetMemoryInfo.TargetAddressSize;
+ int header_size = 16 + address_size;
+ if (first_chunk.IsNull) {
+ first_chunk = memory.ReadAddress (TableAddress
+ address_size);
+ current_chunk = first_chunk;
+ }
+
again:
TargetReader reader = new TargetReader (
memory.ReadMemory (current_chunk, header_size));
@@ -174,7 +179,8 @@
protected enum DataItemType {
Unknown = 0,
Class,
- Method
+ Method,
+ DelegateInvoke
}
protected abstract void ReadDataItem (TargetMemoryAccess
memory, DataItemType type,
@@ -188,7 +194,7 @@
public override string ToString ()
{
return String.Format ("{0} ({1}:{2}:{3}{4})", GetType
(), TableAddress,
- FirstChunk, current_chunk,
MyToString ());
+ first_chunk, current_chunk,
MyToString ());
}
}
@@ -208,6 +214,7 @@
MonoFunctionType main_method;
Hashtable data_tables;
+ GlobalDataTable global_data_table;
ProcessServant process;
MonoDebuggerInfo info;
@@ -265,6 +272,14 @@
return false;
}
+ internal bool IsDelegateTrampoline (TargetAddress address)
+ {
+ if (global_data_table == null)
+ return false;
+
+ return global_data_table.IsDelegateInvoke (address);
+ }
+
internal bool TryFindImage (Thread thread, string filename)
{
Cecil.AssemblyDefinition ass =
Cecil.AssemblyFactory.GetAssembly (filename);
@@ -421,6 +436,7 @@
table.Read (target);
foreach (MonoSymbolFile symfile in
symfile_by_index.Values)
symfile.TypeTable.Read (target);
+ global_data_table.Read (target);
data_table_time += DateTime.Now - start;
}
@@ -530,9 +546,9 @@
"expected {1}.", total_size,
info.SymbolTableSize);
TargetAddress corlib_address = header.ReadAddress ();
+ TargetAddress global_data_table_ptr =
header.ReadAddress ();
+ TargetAddress data_table_list = header.ReadAddress ();
- TargetAddress data_table = header.ReadAddress ();
-
TargetAddress symfile_by_index = header.ReadAddress ();
if (corlib_address.IsNull)
@@ -551,7 +567,7 @@
load_symfile (memory, address);
}
- ptr = data_table;
+ ptr = data_table_list;
while (!ptr.IsNull) {
TargetAddress next_ptr = memory.ReadAddress
(ptr);
TargetAddress address = memory.ReadAddress (
@@ -560,6 +576,8 @@
ptr = next_ptr;
add_data_table (memory, address);
}
+
+ global_data_table = new GlobalDataTable (this,
global_data_table_ptr);
}
void add_data_table (TargetMemoryAccess memory, TargetAddress
ptr)
@@ -621,6 +639,54 @@
}
}
+ protected class GlobalDataTable : MonoDataTable
+ {
+ public readonly MonoLanguageBackend Mono;
+ ArrayList delegate_impl_list;
+
+ public GlobalDataTable (MonoLanguageBackend mono,
TargetAddress address)
+ : base (address, TargetAddress.Null)
+ {
+ this.Mono = mono;
+
+ delegate_impl_list = new ArrayList ();
+ }
+
+ protected override void ReadDataItem
(TargetMemoryAccess memory,
+ DataItemType
type, TargetReader reader)
+ {
+ if (type != DataItemType.DelegateInvoke)
+ throw new InternalError (
+ "Got unknown data item: {0}",
type);
+
+ TargetAddress code = reader.ReadAddress ();
+ int size = reader.BinaryReader.ReadInt32 ();
+ Report.Debug (DebugFlags.JitSymtab, "READ
DELEGATE IMPL: {0} {1}",
+ code, size);
+ delegate_impl_list.Add (new DelegateInvokeEntry
(code, size));
+ }
+
+ public bool IsDelegateInvoke (TargetAddress address)
+ {
+ foreach (DelegateInvokeEntry entry in
delegate_impl_list)
+ if ((address >= entry.Code) && (address
< entry.Code + entry.Size))
+ return true;
+
+ return false;
+ }
+
+ struct DelegateInvokeEntry {
+ public readonly TargetAddress Code;
+ public readonly int Size;
+
+ public DelegateInvokeEntry (TargetAddress code,
int size)
+ {
+ this.Code = code;
+ this.Size = size;
+ }
+ }
+ }
+
static int manual_update_count;
static int full_update_count;
static int update_count;
Modified: trunk/debugger/test/testsuite/TestDelegate.cs
===================================================================
--- trunk/debugger/test/testsuite/TestDelegate.cs 2007-11-22 10:21:00 UTC
(rev 90137)
+++ trunk/debugger/test/testsuite/TestDelegate.cs 2007-11-22 10:24:51 UTC
(rev 90138)
@@ -15,7 +15,7 @@
{ }
[Test]
- [Category("NotWorking")]
+ [Category("ManagedTypes")]
public void Main ()
{
Process process = Start ();
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches