Author: martin
Date: 2007-10-15 17:00:01 -0400 (Mon, 15 Oct 2007)
New Revision: 87534

Modified:
   trunk/debugger/ChangeLog
   trunk/debugger/backend/SingleSteppingEngine.cs
   trunk/debugger/backend/arch/Architecture.cs
   trunk/debugger/backend/arch/Architecture_I386.cs
   trunk/debugger/backend/arch/Architecture_X86_64.cs
   trunk/debugger/backend/arch/Bfd.cs
Log:
2007-10-15  Martin Baulig  <[EMAIL PROTECTED]>

        * backend/Architecture.cs
        (Architecture.CallTargetType): New internal enum.
        (Architecture.GetCallTarget): Merge GetJumpTarget() and
        GetCallTarget() into a new GetCallTarget(); we now return a
        `CallTargetType'.       



Modified: trunk/debugger/ChangeLog
===================================================================
--- trunk/debugger/ChangeLog    2007-10-15 20:52:10 UTC (rev 87533)
+++ trunk/debugger/ChangeLog    2007-10-15 21:00:01 UTC (rev 87534)
@@ -1,5 +1,13 @@
 2007-10-15  Martin Baulig  <[EMAIL PROTECTED]>
 
+       * backend/Architecture.cs
+       (Architecture.CallTargetType): New internal enum.
+       (Architecture.GetCallTarget): Merge GetJumpTarget() and
+       GetCallTarget() into a new GetCallTarget(); we now return a
+       `CallTargetType'.       
+
+2007-10-15  Martin Baulig  <[EMAIL PROTECTED]>
+
        HEADS UP: The debugger currently doesn't work with the latest mono
                  from SVN HEAD.  You need to use r87189 for the moment.
 

Modified: trunk/debugger/backend/SingleSteppingEngine.cs
===================================================================
--- trunk/debugger/backend/SingleSteppingEngine.cs      2007-10-15 20:52:10 UTC 
(rev 87533)
+++ trunk/debugger/backend/SingleSteppingEngine.cs      2007-10-15 21:00:01 UTC 
(rev 87534)
@@ -1134,14 +1134,15 @@
 
                        // Check whether this is a call instruction.
                        int insn_size;
-                       TargetAddress call = 
inferior.Architecture.GetCallTarget (
-                               inferior, address, out insn_size);
+                       TargetAddress target;
+                       CallTargetType type = 
inferior.Architecture.GetCallTarget (
+                               inferior, address, out target, out insn_size);
 
-                       Report.Debug (DebugFlags.SSE, "{0} do_next_native: {1} 
{2}", this,
-                                     address, call);
+                       Report.Debug (DebugFlags.SSE, "{0} do_next_native: {1} 
{2} {3}", this,
+                                     address, type, target);
 
                        // Step one instruction unless this is a call
-                       if (call.IsNull) {
+                       if (type != CallTargetType.Call) {
                                do_step_native ();
                                return;
                        }
@@ -2399,14 +2400,15 @@
                                return false;
 
                        int insn_size;
-                       TargetAddress call = 
inferior.Architecture.GetCallTarget (
-                               inferior, inferior.CurrentFrame, out insn_size);
-                       if (call.IsNull)
+                       TargetAddress target;
+                       CallTargetType type = 
inferior.Architecture.GetCallTarget (
+                               inferior, inferior.CurrentFrame, out target, 
out insn_size);
+                       if (type != CallTargetType.Call)
                                return false;
 
                        bool is_start;
                        TargetAddress trampoline = 
sse.process.MonoLanguage.GetTrampolineAddress (
-                               inferior, call, out is_start);
+                               inferior, target, out is_start);
 
                        if (trampoline.IsNull)
                                return false;
@@ -2704,16 +2706,17 @@
                         * the specified step frame.
                         */
                        int insn_size;
-                       TargetAddress call = 
inferior.Architecture.GetCallTarget (
-                               inferior, current_frame, out insn_size);
-                       if (call.IsNull) {
+                       TargetAddress target;
+                       CallTargetType type = 
inferior.Architecture.GetCallTarget (
+                               inferior, current_frame, out target, out 
insn_size);
+                       if (type != CallTargetType.Call) {
                                sse.do_step_native ();
                                return false;
                        }
 
                        if ((sse.current_method != null) && 
(sse.current_method.HasMethodBounds) &&
-                           (call >= sse.current_method.MethodStartAddress) &&
-                           (call < sse.current_method.MethodEndAddress)) {
+                           (target >= sse.current_method.MethodStartAddress) &&
+                           (target < sse.current_method.MethodEndAddress)) {
                                /* Intra-method call (we stay outside the 
prologue/epilogue code, so this also
                                 * can't be a recursive call). */
                                sse.do_step_native ();
@@ -2732,7 +2735,7 @@
                         * If we have a source language, check for trampolines.
                         * This will trigger a JIT compilation if neccessary.
                         */
-                       if (CheckTrampoline (call))
+                       if (CheckTrampoline (target))
                                return false;
 
                        /*
@@ -2749,7 +2752,7 @@
                         * If it can't be found in the symbol tables, assume 
it's a system function
                         * and step over it.
                         */
-                       Method method = sse.Lookup (call);
+                       Method method = sse.Lookup (target);
 
                        /*
                         * If this is a PInvoke/icall wrapper, check whether we 
want to step into
@@ -3521,10 +3524,11 @@
                        done = true;
 
                        int insn_size;
-                       TargetAddress jump_target = 
sse.Architecture.GetJumpTarget (
-                               inferior, frame.Address, out insn_size);
+                       TargetAddress jump_target;
+                       CallTargetType type = sse.Architecture.GetCallTarget (
+                               inferior, frame.Address, out jump_target, out 
insn_size);
 
-                       if (!jump_target.IsNull) {
+                       if (type != CallTargetType.Jump) {
                                sse.do_step_native ();
                                return EventResult.Running;
                        }
@@ -3692,9 +3696,10 @@
                         * the current method.
                         */
                        int insn_size;
-                       TargetAddress call = 
inferior.Architecture.GetCallTarget (
-                               inferior, current_frame, out insn_size);
-                       if (!call.IsNull && CheckTrampoline (call))
+                       TargetAddress target;
+                       CallTargetType type = 
inferior.Architecture.GetCallTarget (
+                               inferior, current_frame, out target, out 
insn_size);
+                       if ((type == CallTargetType.Call) && CheckTrampoline 
(target))
                                return false;
 
                        sse.do_step_native ();

Modified: trunk/debugger/backend/arch/Architecture.cs
===================================================================
--- trunk/debugger/backend/arch/Architecture.cs 2007-10-15 20:52:10 UTC (rev 
87533)
+++ trunk/debugger/backend/arch/Architecture.cs 2007-10-15 21:00:01 UTC (rev 
87534)
@@ -1,8 +1,14 @@
 using System;
 using Mono.Debugger.Backends;
 
-namespace Mono.Debugger
+namespace Mono.Debugger.Backends
 {
+       internal enum CallTargetType {
+               None,
+               Call,
+               Jump
+       }
+
        // <summary>
        //   Architecture-dependent interface.
        // </summary>
@@ -90,30 +96,6 @@
                                                             TargetAddress 
address);
 
                // <summary>
-               //   Check whether the instruction at target address @address 
is a `call'
-               //   instruction and returns the destination of the call or 
TargetAddress.Null.
-               //
-               //   The out parameter @insn_size is set to the size on bytes 
of the call
-               //   instructions.  This can be used to set a breakpoint 
immediately after
-               //   the function.
-               // </summary>
-               internal abstract TargetAddress GetCallTarget 
(TargetMemoryAccess target,
-                                                              TargetAddress 
address,
-                                                              out int 
insn_size);
-
-               // <summary>
-               //   Check whether the instruction at target address @address 
is a `jump'
-               //   instruction and returns the destination of the call or 
TargetAddress.Null.
-               //
-               //   The out parameter @insn_size is set to the size on bytes 
of the jump
-               //   instructions.  This can be used to set a breakpoint 
immediately after
-               //   the jump.
-               // </summary>
-               internal abstract TargetAddress GetJumpTarget 
(TargetMemoryAccess target,
-                                                              TargetAddress 
address,
-                                                              out int 
insn_size);
-
-               // <summary>
                //   Check whether the instruction at target address @address 
is a trampoline method.
                //   If it's a trampoline, return the address of the 
corresponding method's
                //   code.  For JIT trampolines, this should do a JIT 
compilation of the method.
@@ -122,6 +104,11 @@
                                                               TargetAddress 
address,
                                                               TargetAddress 
generic_trampoline_address);
 
+               internal abstract CallTargetType GetCallTarget 
(TargetMemoryAccess memory,
+                                                               TargetAddress 
address,
+                                                               out 
TargetAddress target,
+                                                               out int 
insn_size);
+
                internal abstract int MaxPrologueSize {
                        get;
                }

Modified: trunk/debugger/backend/arch/Architecture_I386.cs
===================================================================
--- trunk/debugger/backend/arch/Architecture_I386.cs    2007-10-15 20:52:10 UTC 
(rev 87533)
+++ trunk/debugger/backend/arch/Architecture_I386.cs    2007-10-15 21:00:01 UTC 
(rev 87534)
@@ -56,126 +56,120 @@
                        }
                }
 
-               internal override TargetAddress GetCallTarget 
(TargetMemoryAccess target,
-                                                              TargetAddress 
address,
-                                                              out int 
insn_size)
+               internal override CallTargetType GetCallTarget 
(TargetMemoryAccess memory,
+                                                               TargetAddress 
address,
+                                                               out 
TargetAddress target,
+                                                               out int 
insn_size)
                {
                        if (address.Address == 0xffffe002) {
                                insn_size = 0;
-                               return TargetAddress.Null;
+                               target = TargetAddress.Null;
+                               return CallTargetType.None;
                        }
 
-                       TargetBinaryReader reader = target.ReadMemory (address, 
6).GetReader ();
+                       TargetBinaryReader reader = memory.ReadMemory (address, 
6).GetReader ();
 
                        byte opcode = reader.ReadByte ();
 
-                       if (opcode == 0xe8) {
+                       if ((opcode == 0xe8) || (opcode == 0xe9)) {
                                int call_target = reader.ReadInt32 ();
                                insn_size = 5;
-                               return address + reader.Position + call_target;
+                               target = address + reader.Position + 
call_target;
+                               return (opcode == 0xe8) ? CallTargetType.Call : 
CallTargetType.Jump;
                        } else if (opcode != 0xff) {
                                insn_size = 0;
-                               return TargetAddress.Null;
+                               target = TargetAddress.Null;
+                               return CallTargetType.None;
                        }
 
+                       CallTargetType type;
                        byte address_byte = reader.ReadByte ();
+                       if ((address_byte & 0x38) == 0x10)
+                               type = CallTargetType.Call;
+                       else if ((address_byte & 0x38) == 0x20)
+                               type = CallTargetType.Jump;
+                       else {
+                               insn_size = 0;
+                               target = TargetAddress.Null;
+                               return CallTargetType.None;
+                       }
+
                        byte register;
                        int disp;
                        bool dereference_addr;
 
-                       if (((address_byte & 0x38) == 0x10) && ((address_byte 
>> 6) == 1)) {
+                       if ((address_byte >> 6) == 1) {
                                register = (byte) (address_byte & 0x07);
                                disp = reader.ReadByte ();
                                insn_size = 3;
                                dereference_addr = true;
-                       } else if (((address_byte & 0x38) == 0x10) && 
((address_byte >> 6) == 2)) {
+                       } else if ((address_byte >> 6) == 2) {
                                register = (byte) (address_byte & 0x07);
                                disp = reader.ReadInt32 ();
                                insn_size = 6;
                                dereference_addr = true;
-                       } else if (((address_byte & 0x38) == 0x10) && 
((address_byte >> 6) == 3)) {
+                       } else if ((address_byte >> 6) == 3) {
                                register = (byte) (address_byte & 0x07);
                                disp = 0;
                                insn_size = 2;
                                dereference_addr = false;
-                       } else if (((address_byte & 0x38) == 0x10) && 
((address_byte >> 6) == 0)) {
+                       } else if ((address_byte >> 6) == 0) {
                                register = (byte) (address_byte & 0x07);
                                disp = 0;
                                insn_size = 2;
                                dereference_addr = true;
                        } else {
-                               insn_size = 0;
-                               return TargetAddress.Null;
+                               // Can never happen
+                               throw new InvalidOperationException ();
                        }
 
                        I386Register reg;
                        switch (register) {
-                       case 0:
+                       case 0: /* eax */
                                reg = I386Register.EAX;
                                break;
-
-                       case 1:
+                       case 1: /* ecx */
                                reg = I386Register.ECX;
                                break;
-
-                       case 2:
+                       case 2: /* edx */
                                reg = I386Register.EDX;
                                break;
-
-                       case 3:
+                       case 3: /* ebx */
                                reg = I386Register.EBX;
                                break;
+                       case 5:
+                               if ((address_byte >> 6) == 0) {
+                                       disp = reader.ReadInt32 ();
+                                       target = address + disp + 6;
+                                       return type;
+                               } else {
+                                       reg = I386Register.EBP;
+                               }
+                               break;
 
-                       case 6:
+                       case 6: /* esi */
                                reg = I386Register.ESI;
                                break;
-
-                       case 7:
+                       case 7: /* edi */
                                reg = I386Register.EDI;
                                break;
-
                        default:
-                               insn_size = 0;
-                               return TargetAddress.Null;
+                               throw new InvalidOperationException ();
                        }
 
-                       Registers regs = target.GetRegisters ();
+                       Registers regs = memory.GetRegisters ();
                        Register addr = regs [(int) reg];
 
                        TargetAddress vtable_addr = new TargetAddress 
(AddressDomain, addr.Value);
                        vtable_addr += disp;
 
                        if (dereference_addr)
-                               return target.ReadAddress (vtable_addr);
+                               target = memory.ReadAddress (vtable_addr);
                        else
-                               return vtable_addr;
+                               target = vtable_addr;
+                       return type;
                }
 
-               internal override TargetAddress GetJumpTarget 
(TargetMemoryAccess target,
-                                                              TargetAddress 
address,
-                                                              out int 
insn_size)
-               {
-                       TargetBinaryReader reader = target.ReadMemory (address, 
10).GetReader ();
-
-                       byte opcode = reader.ReadByte ();
-                       byte opcode2 = reader.ReadByte ();
-
-                       if ((opcode == 0xff) && (opcode2 == 0x25)) {
-                               insn_size = 2 + TargetAddressSize;
-                               return new TargetAddress (AddressDomain, 
reader.ReadAddress ());
-                       } else if ((opcode == 0xff) && (opcode2 == 0xa3)) {
-                               int offset = reader.ReadInt32 ();
-                               Registers regs = target.GetRegisters ();
-                               long ebx = regs [(int) I386Register.EBX].Value;
-
-                               insn_size = 6;
-                               return new TargetAddress (AddressDomain, ebx + 
offset);
-                       }
-
-                       insn_size = 0;
-                       return TargetAddress.Null;
-               }
-
                internal override TargetAddress GetTrampoline 
(TargetMemoryAccess target,
                                                               TargetAddress 
location,
                                                               TargetAddress 
trampoline_address)

Modified: trunk/debugger/backend/arch/Architecture_X86_64.cs
===================================================================
--- trunk/debugger/backend/arch/Architecture_X86_64.cs  2007-10-15 20:52:10 UTC 
(rev 87533)
+++ trunk/debugger/backend/arch/Architecture_X86_64.cs  2007-10-15 21:00:01 UTC 
(rev 87534)
@@ -63,11 +63,19 @@
                        }
                }
 
-               TargetAddress GetJumpOrCallTarget (TargetMemoryAccess target, 
TargetAddress address,
-                                                  bool is_call, out int 
insn_size)
+               internal override CallTargetType GetCallTarget 
(TargetMemoryAccess memory,
+                                                               TargetAddress 
address,
+                                                               out 
TargetAddress target,
+                                                               out int 
insn_size)
                {
-                       TargetBinaryReader reader = target.ReadMemory (address, 
10).GetReader ();
+                       if (address.Address == 0xffffe002) {
+                               insn_size = 0;
+                               target = TargetAddress.Null;
+                               return CallTargetType.None;
+                       }
 
+                       TargetBinaryReader reader = memory.ReadMemory (address, 
10).GetReader ();
+
                        byte opcode = reader.ReadByte ();
                        byte original_opcode = opcode;
 
@@ -75,16 +83,27 @@
                        if (has_rex_prefix)
                                opcode = reader.ReadByte ();
 
-                       if (opcode == (is_call ? 0xe8 : 0xe9)) {
+                       if ((opcode == 0xe8) || (opcode == 0xe9)) {
                                int call_target = reader.ReadInt32 ();
                                insn_size = 5;
-                               return address + reader.Position + call_target;
+                               target = address + reader.Position + 
call_target;
+                               return (opcode == 0xe8) ? CallTargetType.Call : 
CallTargetType.Jump;
+                       } else if (opcode != 0xff) {
+                               insn_size = 0;
+                               target = TargetAddress.Null;
+                               return CallTargetType.None;
                        }
 
+                       CallTargetType type;
                        byte address_byte = reader.ReadByte ();
-                       if ((opcode != 0xff) || ((address_byte & 0x38) != 
(is_call ? 0x10 : 0x20))) {
+                       if ((address_byte & 0x38) == 0x10)
+                               type = CallTargetType.Call;
+                       else if ((address_byte & 0x38) == 0x20)
+                               type = CallTargetType.Jump;
+                       else {
                                insn_size = 0;
-                               return TargetAddress.Null;
+                               target = TargetAddress.Null;
+                               return CallTargetType.None;
                        }
 
                        byte register;
@@ -163,7 +182,8 @@
                                case 5:
                                        if ((address_byte >> 6) == 0) {
                                                disp = reader.ReadInt32 ();
-                                               return address + disp + 6;
+                                               target = address + disp + 6;
+                                               return type;
                                        } else {
                                                reg = X86_64_Register.RBP;
                                        }
@@ -183,38 +203,20 @@
                        if (has_rex_prefix)
                                insn_size++;
 
-                       Registers regs = target.GetRegisters ();
+                       Registers regs = memory.GetRegisters ();
                        Register addr = regs [(int) reg];
 
                        TargetAddress vtable_addr = new TargetAddress 
(AddressDomain, addr.Value);
                        vtable_addr += disp;
 
                        if (dereference_addr)
-                               return target.ReadAddress (vtable_addr);
+                               target = memory.ReadAddress (vtable_addr);
                        else
-                               return vtable_addr;
-               }
+                               target = vtable_addr;
 
-
-               internal override TargetAddress GetCallTarget 
(TargetMemoryAccess target,
-                                                              TargetAddress 
address,
-                                                              out int 
insn_size)
-               {
-                       if (address.Address == 0xffffe002) {
-                               insn_size = 0;
-                               return TargetAddress.Null;
-                       }
-
-                       return GetJumpOrCallTarget (target, address, true, out 
insn_size);
+                       return type;
                }
 
-               internal override TargetAddress GetJumpTarget 
(TargetMemoryAccess target,
-                                                              TargetAddress 
address,
-                                                              out int 
insn_size)
-               {
-                       return GetJumpOrCallTarget (target, address, false, out 
insn_size);
-               }
-
                internal override TargetAddress GetTrampoline 
(TargetMemoryAccess target,
                                                               TargetAddress 
location,
                                                               TargetAddress 
trampoline_address)

Modified: trunk/debugger/backend/arch/Bfd.cs
===================================================================
--- trunk/debugger/backend/arch/Bfd.cs  2007-10-15 20:52:10 UTC (rev 87533)
+++ trunk/debugger/backend/arch/Bfd.cs  2007-10-15 21:00:01 UTC (rev 87534)
@@ -972,8 +972,11 @@
                        }
 
                        int insn_size;
-                       TargetAddress jmp_target = arch.GetJumpTarget (memory, 
address, out insn_size);
-                       if (jmp_target.IsNull) {
+                       CallTargetType type;
+                       TargetAddress jmp_target;
+
+                       type = arch.GetCallTarget (memory, address, out 
jmp_target, out insn_size);
+                       if (type != CallTargetType.Jump) {
                                is_start = false;
                                return TargetAddress.Null;
                        }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to