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