Author: martin
Date: 2007-10-15 18:25:01 -0400 (Mon, 15 Oct 2007)
New Revision: 87541
Modified:
trunk/debugger/ChangeLog
trunk/debugger/backend/ILanguageBackend.cs
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
trunk/debugger/backend/arch/BfdContainer.cs
trunk/debugger/languages/mono/MonoLanguageBackend.cs
Log:
2007-10-16 Martin Baulig <[EMAIL PROTECTED]>
* backend/arch/Architecture.cs
(Architecture.CallTargetType): Add `NativeTrampoline',
`NativeTrampolineStart' and `MonoTrampoline'.
(Architecture.GetCallTarget): Also check for trampolines here.
(Architecture.GetTrampoline): Removed.
* backend/ILanguageBackend.cs
(ILanguageBackend.GetTrampolineAddress): Removed.
Modified: trunk/debugger/ChangeLog
===================================================================
--- trunk/debugger/ChangeLog 2007-10-15 22:20:59 UTC (rev 87540)
+++ trunk/debugger/ChangeLog 2007-10-15 22:25:01 UTC (rev 87541)
@@ -1,6 +1,17 @@
+2007-10-16 Martin Baulig <[EMAIL PROTECTED]>
+
+ * backend/arch/Architecture.cs
+ (Architecture.CallTargetType): Add `NativeTrampoline',
+ `NativeTrampolineStart' and `MonoTrampoline'.
+ (Architecture.GetCallTarget): Also check for trampolines here.
+ (Architecture.GetTrampoline): Removed.
+
+ * backend/ILanguageBackend.cs
+ (ILanguageBackend.GetTrampolineAddress): Removed.
+
2007-10-15 Martin Baulig <[EMAIL PROTECTED]>
- * backend/Architecture.cs
+ * backend/arch/Architecture.cs
(Architecture.CallTargetType): New internal enum.
(Architecture.GetCallTarget): Merge GetJumpTarget() and
GetCallTarget() into a new GetCallTarget(); we now return a
Modified: trunk/debugger/backend/ILanguageBackend.cs
===================================================================
--- trunk/debugger/backend/ILanguageBackend.cs 2007-10-15 22:20:59 UTC (rev
87540)
+++ trunk/debugger/backend/ILanguageBackend.cs 2007-10-15 22:25:01 UTC (rev
87541)
@@ -37,10 +37,6 @@
get;
}
- TargetAddress GetTrampolineAddress (TargetMemoryAccess memory,
- TargetAddress address,
- out bool is_start);
-
MethodSource GetTrampoline (TargetMemoryAccess memory,
TargetAddress address);
}
Modified: trunk/debugger/backend/SingleSteppingEngine.cs
===================================================================
--- trunk/debugger/backend/SingleSteppingEngine.cs 2007-10-15 22:20:59 UTC
(rev 87540)
+++ trunk/debugger/backend/SingleSteppingEngine.cs 2007-10-15 22:25:01 UTC
(rev 87541)
@@ -1142,7 +1142,7 @@
address, type, target);
// Step one instruction unless this is a call
- if (type != CallTargetType.Call) {
+ if (!Architecture.IsCall (type)) {
do_step_native ();
return;
}
@@ -1194,42 +1194,33 @@
inferior.Step ();
}
- void do_trampoline (ILanguageBackend language, TargetAddress
call,
- TargetAddress trampoline, TrampolineHandler
handler,
- bool is_start)
+ protected bool CheckTrampoline (CallTargetType type,
TargetAddress call_site,
+ TargetAddress call_target,
TrampolineHandler handler)
{
+ if (!Architecture.IsTrampoline (type))
+ return false;
+
Report.Debug (DebugFlags.SSE,
- "{0} found trampoline {1}/{2} while
running {3}",
- this, trampoline, is_start,
current_operation);
+ "{0} found trampoline {1}:{2} at {3}
while running {4}",
+ this, type, call_target, call_site,
current_operation);
- if (!language.Language.IsManaged) {
- if (is_start) {
- PushOperation (new
OperationNativeTrampoline (
- this, trampoline, handler));
- return;
- }
-
- Method method = Lookup (trampoline);
- if (!MethodHasSource (method)) {
+ if (type == CallTargetType.NativeTrampolineStart) {
+ PushOperation (new OperationNativeTrampoline (
+ this, call_target,
handler));
+ return true;
+ } else if (type == CallTargetType.NativeTrampoline) {
+ Method method = Lookup (call_target);
+ if (!MethodHasSource (method))
do_next_native ();
- return;
- }
-
- do_continue (trampoline);
- return;
+ else
+ do_continue (call_target);
+ return true;
+ } else if (type == CallTargetType.MonoTrampoline) {
+ PushOperation (new OperationTrampoline (this,
call_target, handler));
+ return true;
}
- if (is_start) {
- do_continue (trampoline);
- return;
- }
-
- Report.Debug (DebugFlags.SSE,
- "{0} doing trampoline: {1} {2} {3}",
this, current_operation,
- call, trampoline);
-
- PushOperation (new OperationTrampoline (this,
trampoline, handler));
- return;
+ return false;
}
void trampoline_callback (TargetAddress address)
@@ -2403,18 +2394,12 @@
TargetAddress target;
CallTargetType type =
inferior.Architecture.GetCallTarget (
inferior, inferior.CurrentFrame, out target,
out insn_size);
- if (type != CallTargetType.Call)
- return false;
+ if (Architecture.IsTrampoline (type)) {
+ sse.PushOperation (new OperationTrampoline
(sse, target, null));
+ return true;
+ }
- bool is_start;
- TargetAddress trampoline =
sse.process.MonoLanguage.GetTrampolineAddress (
- inferior, target, out is_start);
-
- if (trampoline.IsNull)
- return false;
-
- sse.PushOperation (new OperationTrampoline (sse,
trampoline, null));
- return true;
+ return false;
}
protected override void DoExecute ()
@@ -2529,31 +2514,6 @@
protected abstract bool DoProcessEvent ();
- protected bool CheckTrampoline (TargetAddress call)
- {
- foreach (ILanguageBackend language in
sse.process.Languages) {
- bool is_start;
- TargetAddress trampoline =
language.GetTrampolineAddress (
- inferior, call, out is_start);
-
- /*
- * If this is a trampoline, insert a breakpoint
at the start of
- * the corresponding method and continue.
- *
- * We don't need to distinguish between
StepMode.SingleInstruction
- * and StepMode.StepFrame here since we'd leave
the step frame anyways
- * when entering the method.
- */
- if (!trampoline.IsNull) {
- sse.do_trampoline (
- language, call, trampoline,
TrampolineHandler, is_start);
- return true;
- }
- }
-
- return false;
- }
-
protected abstract bool TrampolineHandler (Method method);
}
@@ -2709,7 +2669,7 @@
TargetAddress target;
CallTargetType type =
inferior.Architecture.GetCallTarget (
inferior, current_frame, out target, out
insn_size);
- if (type != CallTargetType.Call) {
+ if (!Architecture.IsCall (type)) {
sse.do_step_native ();
return false;
}
@@ -2731,11 +2691,7 @@
return false;
}
- /*
- * If we have a source language, check for trampolines.
- * This will trigger a JIT compilation if neccessary.
- */
- if (CheckTrampoline (target))
+ if (sse.CheckTrampoline (type, current_frame, target,
TrampolineHandler))
return false;
/*
@@ -3699,7 +3655,7 @@
TargetAddress target;
CallTargetType type =
inferior.Architecture.GetCallTarget (
inferior, current_frame, out target, out
insn_size);
- if ((type == CallTargetType.Call) && CheckTrampoline
(target))
+ if (sse.CheckTrampoline (type, current_frame, target,
TrampolineHandler))
return false;
sse.do_step_native ();
Modified: trunk/debugger/backend/arch/Architecture.cs
===================================================================
--- trunk/debugger/backend/arch/Architecture.cs 2007-10-15 22:20:59 UTC (rev
87540)
+++ trunk/debugger/backend/arch/Architecture.cs 2007-10-15 22:25:01 UTC (rev
87541)
@@ -6,7 +6,10 @@
internal enum CallTargetType {
None,
Call,
- Jump
+ Jump,
+ NativeTrampoline,
+ NativeTrampolineStart,
+ MonoTrampoline
}
// <summary>
@@ -95,20 +98,63 @@
internal abstract bool IsSyscallInstruction (TargetMemoryAccess
memory,
TargetAddress
address);
- // <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.
- // </summary>
- internal abstract TargetAddress GetTrampoline
(TargetMemoryAccess target,
- TargetAddress
address,
- TargetAddress
generic_trampoline_address);
+ public static bool IsTrampoline (CallTargetType type)
+ {
+ return (type == CallTargetType.NativeTrampoline) ||
+ (type == CallTargetType.NativeTrampolineStart)
||
+ (type == CallTargetType.MonoTrampoline);
+ }
- internal abstract CallTargetType GetCallTarget
(TargetMemoryAccess memory,
- TargetAddress
address,
- out
TargetAddress target,
- out int
insn_size);
+ public static bool IsCall (CallTargetType type)
+ {
+ return (type == CallTargetType.Call) ||
+ (type == CallTargetType.NativeTrampoline) ||
+ (type == CallTargetType.NativeTrampolineStart)
||
+ (type == CallTargetType.MonoTrampoline);
+ }
+ internal CallTargetType GetCallTarget (TargetMemoryAccess
memory,
+ TargetAddress address,
+ out TargetAddress target,
+ out int insn_size)
+ {
+ CallTargetType type = DoGetCallTarget (memory, address,
out target, out insn_size);
+ if (type == CallTargetType.None)
+ return CallTargetType.None;
+
+ if (type == CallTargetType.Jump) {
+ bool is_start;
+ TargetAddress trampoline;
+ if (process.BfdContainer.GetTrampoline (
+ memory, address, target, out
trampoline, out is_start)) {
+ target = trampoline;
+ return is_start ?
+
CallTargetType.NativeTrampolineStart :
+ CallTargetType.NativeTrampoline;
+ }
+ }
+
+ if (process.IsManagedApplication) {
+ TargetAddress trampoline;
+ if (DoGetMonoTrampoline (memory, address,
target, out trampoline)) {
+ target = trampoline;
+ return CallTargetType.MonoTrampoline;
+ }
+ }
+
+ return type;
+ }
+
+ protected abstract CallTargetType DoGetCallTarget
(TargetMemoryAccess memory,
+
TargetAddress address,
+ out
TargetAddress target,
+ out int
insn_size);
+
+ protected abstract bool DoGetMonoTrampoline (TargetMemoryAccess
memory,
+ TargetAddress
call_site,
+ TargetAddress
call_target,
+ out TargetAddress
trampoline);
+
internal abstract int MaxPrologueSize {
get;
}
Modified: trunk/debugger/backend/arch/Architecture_I386.cs
===================================================================
--- trunk/debugger/backend/arch/Architecture_I386.cs 2007-10-15 22:20:59 UTC
(rev 87540)
+++ trunk/debugger/backend/arch/Architecture_I386.cs 2007-10-15 22:25:01 UTC
(rev 87541)
@@ -56,10 +56,10 @@
}
}
- internal override CallTargetType GetCallTarget
(TargetMemoryAccess memory,
- TargetAddress
address,
- out
TargetAddress target,
- out int
insn_size)
+ protected override CallTargetType DoGetCallTarget
(TargetMemoryAccess memory,
+
TargetAddress address,
+ out
TargetAddress target,
+ out int
insn_size)
{
if (address.Address == 0xffffe002) {
insn_size = 0;
@@ -170,31 +170,38 @@
return type;
}
- internal override TargetAddress GetTrampoline
(TargetMemoryAccess target,
- TargetAddress
location,
- TargetAddress
trampoline_address)
+ protected override bool DoGetMonoTrampoline (TargetMemoryAccess
memory,
+ TargetAddress
call_site,
+ TargetAddress
call_target,
+ out TargetAddress
trampoline)
{
- if (trampoline_address.IsNull)
- return TargetAddress.Null;
+ TargetBinaryReader reader = memory.ReadMemory
(call_target, 10).GetReader ();
- TargetBinaryReader reader = target.ReadMemory
(location, 10).GetReader ();
-
byte opcode = reader.ReadByte ();
- if (opcode != 0x68)
- return TargetAddress.Null;
+ if (opcode != 0x68) {
+ trampoline = TargetAddress.Null;
+ return false;
+ }
int method_info = reader.ReadInt32 ();
opcode = reader.ReadByte ();
- if (opcode != 0xe9)
- return TargetAddress.Null;
+ if (opcode != 0xe9) {
+ trampoline = TargetAddress.Null;
+ return false;
+ }
int call_disp = reader.ReadInt32 ();
- if (location + call_disp + 10 != trampoline_address)
- return TargetAddress.Null;
+ foreach (TargetAddress address in
process.MonoLanguage.Trampolines) {
+ if (call_target + call_disp + 10 == address) {
+ trampoline = new TargetAddress
(AddressDomain, method_info);
+ return true;
+ }
+ }
- return new TargetAddress (AddressDomain, method_info);
+ trampoline = TargetAddress.Null;
+ return false;
}
public override string[] RegisterNames {
Modified: trunk/debugger/backend/arch/Architecture_X86_64.cs
===================================================================
--- trunk/debugger/backend/arch/Architecture_X86_64.cs 2007-10-15 22:20:59 UTC
(rev 87540)
+++ trunk/debugger/backend/arch/Architecture_X86_64.cs 2007-10-15 22:25:01 UTC
(rev 87541)
@@ -63,10 +63,10 @@
}
}
- internal override CallTargetType GetCallTarget
(TargetMemoryAccess memory,
- TargetAddress
address,
- out
TargetAddress target,
- out int
insn_size)
+ protected override CallTargetType DoGetCallTarget
(TargetMemoryAccess memory,
+
TargetAddress address,
+ out
TargetAddress target,
+ out int
insn_size)
{
if (address.Address == 0xffffe002) {
insn_size = 0;
@@ -217,33 +217,38 @@
return type;
}
- internal override TargetAddress GetTrampoline
(TargetMemoryAccess target,
- TargetAddress
location,
- TargetAddress
trampoline_address)
+ protected override bool DoGetMonoTrampoline (TargetMemoryAccess
memory,
+ TargetAddress
call_site,
+ TargetAddress
call_target,
+ out TargetAddress
trampoline)
{
- if (trampoline_address.IsNull)
- return TargetAddress.Null;
-
- TargetBinaryReader reader = target.ReadMemory
(location, 19).GetReader ();
-
+ TargetBinaryReader reader = memory.ReadMemory
(call_target, 19).GetReader ();
reader.Position = 9;
byte opcode = reader.ReadByte ();
- if (opcode != 0x68)
- return TargetAddress.Null;
+ if (opcode != 0x68) {
+ trampoline = TargetAddress.Null;
+ return false;
+ }
int method_info = reader.ReadInt32 ();
opcode = reader.ReadByte ();
- if (opcode != 0xe9)
- return TargetAddress.Null;
+ if (opcode != 0xe9) {
+ trampoline = TargetAddress.Null;
+ return false;
+ }
int call_disp = reader.ReadInt32 ();
+ foreach (TargetAddress address in
process.MonoLanguage.Trampolines) {
+ if (call_target + call_disp + 19 == address) {
+ trampoline = new TargetAddress
(AddressDomain, method_info);
+ return true;
+ }
+ }
- if (location + call_disp + 19 != trampoline_address)
- return TargetAddress.Null;
-
- return new TargetAddress (AddressDomain, method_info);
+ trampoline = TargetAddress.Null;
+ return false;
}
public override string[] RegisterNames {
Modified: trunk/debugger/backend/arch/Bfd.cs
===================================================================
--- trunk/debugger/backend/arch/Bfd.cs 2007-10-15 22:20:59 UTC (rev 87540)
+++ trunk/debugger/backend/arch/Bfd.cs 2007-10-15 22:25:01 UTC (rev 87541)
@@ -950,46 +950,34 @@
}
}
- TargetAddress ILanguageBackend.GetTrampolineAddress
(TargetMemoryAccess memory,
-
TargetAddress address,
- out bool
is_start)
- {
- return GetTrampoline (memory, address, out is_start);
- }
-
MethodSource ILanguageBackend.GetTrampoline (TargetMemoryAccess
memory,
TargetAddress
address)
{
return null;
}
- public TargetAddress GetTrampoline (TargetMemoryAccess memory,
- TargetAddress address, out
bool is_start)
+ internal bool GetTrampoline (TargetMemoryAccess memory,
+ TargetAddress call_site,
+ TargetAddress call_target,
+ out TargetAddress trampoline,
+ out bool is_start)
{
- if (!has_got || (address < plt_start) || (address >
plt_end)) {
+ if (!has_got || (call_site < plt_start) || (call_site >
plt_end)) {
is_start = false;
- return TargetAddress.Null;
+ trampoline = TargetAddress.Null;
+ return false;
}
- int insn_size;
- CallTargetType type;
- TargetAddress jmp_target;
-
- type = arch.GetCallTarget (memory, address, out
jmp_target, out insn_size);
- if (type != CallTargetType.Jump) {
+ TargetAddress method = memory.ReadAddress (call_target);
+ if (method != call_site + 6) {
is_start = false;
- return TargetAddress.Null;
+ trampoline = method;
+ return true;
}
- TargetAddress method = memory.ReadAddress (jmp_target);
-
- if (method != address + 6) {
- is_start = false;
- return method;
- }
-
is_start = true;
- return memory.ReadAddress (got_start + 3 *
info.TargetAddressSize);
+ trampoline = memory.ReadAddress (got_start + 3 *
info.TargetAddressSize);
+ return true;
}
internal override StackFrame UnwindStack (StackFrame frame,
TargetMemoryAccess memory)
Modified: trunk/debugger/backend/arch/BfdContainer.cs
===================================================================
--- trunk/debugger/backend/arch/BfdContainer.cs 2007-10-15 22:20:59 UTC (rev
87540)
+++ trunk/debugger/backend/arch/BfdContainer.cs 2007-10-15 22:25:01 UTC (rev
87541)
@@ -126,6 +126,23 @@
return null;
}
+ public bool GetTrampoline (TargetMemoryAccess memory,
+ TargetAddress call_site,
+ TargetAddress call_target,
+ out TargetAddress trampoline,
+ out bool is_start)
+ {
+ foreach (Bfd bfd in bfd_hash.Values) {
+ if (bfd.GetTrampoline (memory, call_site,
call_target,
+ out trampoline, out
is_start))
+ return true;
+ }
+
+ is_start = false;
+ trampoline = TargetAddress.Null;
+ return false;
+ }
+
//
// IDisposable
//
Modified: trunk/debugger/languages/mono/MonoLanguageBackend.cs
===================================================================
--- trunk/debugger/languages/mono/MonoLanguageBackend.cs 2007-10-15
22:20:59 UTC (rev 87540)
+++ trunk/debugger/languages/mono/MonoLanguageBackend.cs 2007-10-15
22:25:01 UTC (rev 87541)
@@ -255,6 +255,10 @@
get { return corlib.TargetInfo; }
}
+ internal TargetAddress[] Trampolines {
+ get { return trampolines; }
+ }
+
internal bool TryFindImage (Thread thread, string filename)
{
Cecil.AssemblyDefinition ass =
Cecil.AssemblyFactory.GetAssembly (filename);
@@ -915,28 +919,10 @@
get { return info.RuntimeInvoke; }
}
- public TargetAddress GetTrampolineAddress (TargetMemoryAccess
memory,
- TargetAddress
address,
- out bool is_start)
- {
- is_start = false;
-
- if (trampolines == null)
- return TargetAddress.Null;
-
- foreach (TargetAddress trampoline in trampolines) {
- TargetAddress result =
memory.Architecture.GetTrampoline (
- memory, address, trampoline);
- if (!result.IsNull)
- return result;
- }
-
- return TargetAddress.Null;
- }
-
public MethodSource GetTrampoline (TargetMemoryAccess memory,
TargetAddress address)
{
+#if FIXME
bool is_start;
TargetAddress trampoline = GetTrampolineAddress
(memory, address, out is_start);
if (trampoline.IsNull)
@@ -952,6 +938,7 @@
return file.GetMethodByToken (token);
}
+#endif
return null;
}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches