genode/base-foc/patches/foc_single_step_x86.patch
2012-09-18 10:53:16 +02:00

224 lines
6.3 KiB
Diff

Index: kernel/fiasco/src/Kconfig
===================================================================
--- kernel/fiasco/src/Kconfig (revision 40)
+++ kernel/fiasco/src/Kconfig (working copy)
@@ -685,6 +685,14 @@
prevent some P4 processors from being overheated. This option
requires a working timer IRQ to wakeup getchar periodically.
+config USER_SINGLE_STEP
+ bool "Enable user level single stepping support"
+ depends on IA32
+ default n
+ help
+ This option enables single stepping of user level applications outside of
+ JDB.
+
choice
prompt "Warn levels"
default WARN_WARNING
Index: kernel/fiasco/src/kern/ia32/config-ia32.cpp
===================================================================
--- kernel/fiasco/src/kern/ia32/config-ia32.cpp (revision 40)
+++ kernel/fiasco/src/kern/ia32/config-ia32.cpp (working copy)
@@ -86,6 +86,12 @@
// static const bool hlt_works_ok = false;
static bool hlt_works_ok;
+#ifdef CONFIG_USER_SINGLE_STEP
+ static const bool user_single_step = true;
+#else
+ static const bool user_single_step = false;
+#endif
+
// the default uart to use for serial console
static const unsigned default_console_uart = 1;
static const unsigned default_console_uart_baudrate = 115200;
Index: kernel/fiasco/src/kern/ia32/32/entry-native.S
===================================================================
--- kernel/fiasco/src/kern/ia32/32/entry-native.S (revision 40)
+++ kernel/fiasco/src/kern/ia32/32/entry-native.S (working copy)
@@ -46,6 +46,30 @@
jmp slowtraps
.endm
+#ifdef CONFIG_USER_SINGLE_STEP
+.macro HANDLE_USER_TRAP1
+ /* Save EFLAGS, this may trap if user task had single stepping activated
+ * test for single stepping
+ */
+ pushf
+ addl $4, %esp
+ testl $EFLAGS_TF, -4(%esp)
+.endm
+
+.macro RESTORE_USER_TRAP1
+ /* Restore single stepping if it has been set */
+ je 1f
+ orl $EFLAGS_TF, (%esp)
+1:
+.endm
+#else
+.macro HANDLE_USER_TRAP1
+.endm
+
+.macro RESTORE_USER_TRAP1
+.endm
+#endif
+
.p2align 4
.globl entry_vec01_debug
entry_vec01_debug:
@@ -59,6 +83,15 @@
cmpl $entry_sys_fast_ipc_log, (%esp)
je 2f
#endif
+
+ /* test if trap was raised within kernel */
+ testl $3, 4(%esp)
+ jne 1f
+
+ /* turn of EFLAGS.TF */
+ btrl $7, 8(%esp)
+ iret
+
1: pushl $0
pushl $1
pusha
@@ -227,11 +260,17 @@
.p2align(4)
.global entry_sys_fast_ipc_c
entry_sys_fast_ipc_c:
+
+ HANDLE_USER_TRAP1
+
pop %esp
pushl $(GDT_DATA_USER|SEL_PL_U) /* user ss */
pushl %ebp // push user SP (get in ebp)
// Fake user eflags, set IOPL to 3
pushl $(EFLAGS_IOPL_U | EFLAGS_IF)
+
+ RESTORE_USER_TRAP1
+
cld
// Fake user cs. This cs value is never used with exception
// that the thread is ex_regs'd before we leave with sysexit.
Index: kernel/fiasco/src/kern/ia32/thread-ia32.cpp
===================================================================
--- kernel/fiasco/src/kern/ia32/thread-ia32.cpp (revision 40)
+++ kernel/fiasco/src/kern/ia32/thread-ia32.cpp (working copy)
@@ -189,6 +189,10 @@
goto generic_debug;
}
+ if (Config::user_single_step && ts->_trapno == 1 && from_user)
+ if (send_exception(ts))
+ goto success;
+
if (from_user && _space.user_mode())
{
if (ts->_trapno == 14 && Kmem::is_io_bitmap_page_fault(ts->_cr2))
@@ -438,7 +442,8 @@
// thread (not alien) and it's a debug trap,
// debug traps for aliens are always reflected as exception IPCs
if (!(state() & Thread_alien)
- && (ts->_trapno == 1 || ts->_trapno == 3))
+ && ((ts->_trapno == 1 && !Config::user_single_step)
+ || ts->_trapno == 3))
return 0; // we do not handle this
if (ts->_trapno == 3)
@@ -491,6 +496,11 @@
}
}
+IMPLEMENT inline
+void
+Thread::user_single_step(bool)
+{}
+
//----------------------------------------------------------------------------
IMPLEMENTATION [(ia32,amd64,ux) && !io]:
@@ -819,3 +829,16 @@
int
Thread::call_nested_trap_handler(Trap_state *)
{ return -1; }
+
+//---------------------------------------------------------------------------
+IMPLEMENTATION [ia32]:
+
+IMPLEMENT inline
+void
+Thread::user_single_step(bool enable)
+{
+ if (!Config::user_single_step)
+ return;
+
+ regs()->flags(enable ? user_flags() | EFLAGS_TF : user_flags() & ~EFLAGS_TF);
+}
Index: kernel/fiasco/src/kern/thread_object.cpp
===================================================================
--- kernel/fiasco/src/kern/thread_object.cpp (revision 40)
+++ kernel/fiasco/src/kern/thread_object.cpp (working copy)
@@ -520,6 +520,8 @@
if (o_ip) *o_ip = user_ip();
if (o_flags) *o_flags = user_flags();
+ (ops & Exr_single_step) ? user_single_step(true) : user_single_step(false);
+
// Changing the run state is only possible when the thread is not in
// an exception.
if (!(ops & Exr_cancel) && (state() & Thread_in_exception))
Index: kernel/fiasco/src/kern/thread.cpp
===================================================================
--- kernel/fiasco/src/kern/thread.cpp (revision 40)
+++ kernel/fiasco/src/kern/thread.cpp (working copy)
@@ -72,6 +72,7 @@
{
Exr_cancel = 0x10000,
Exr_trigger_exception = 0x20000,
+ Exr_single_step = 0x40000,
};
enum Vcpu_ctl_flags
@@ -139,6 +140,8 @@
inline Mword user_flags() const;
+ inline void user_single_step(bool);
+
/** nesting level in debugger (always critical) if >1 */
static Per_cpu<unsigned long> nested_trap_recover;
static void handle_remote_requests_irq() asm ("handle_remote_cpu_requests");
Index: kernel/fiasco/src/kern/arm/thread-arm.cpp
===================================================================
--- kernel/fiasco/src/kern/arm/thread-arm.cpp (revision 40)
+++ kernel/fiasco/src/kern/arm/thread-arm.cpp (working copy)
@@ -590,6 +590,10 @@
return (v[insn >> 28] >> (psr >> 28)) & 1;
}
+IMPLEMENT inline
+void Thread::user_single_step(bool)
+{}
+
// ------------------------------------------------------------------------
IMPLEMENTATION [arm && armv6plus]:
Index: kernel/fiasco/src/kern/ppc32/thread-ppc32.cpp
===================================================================
--- kernel/fiasco/src/kern/ppc32/thread-ppc32.cpp (revision 40)
+++ kernel/fiasco/src/kern/ppc32/thread-ppc32.cpp (working copy)
@@ -308,6 +308,10 @@
}
}
+IMPLEMENT inline
+void Thread::user_single_step(bool)
+{}
+
PUBLIC inline NEEDS ["trap_state.h"]
int
Thread::send_exception_arch(Trap_state * /*ts*/)