mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-26 08:51:08 +00:00
224 lines
6.3 KiB
Diff
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*/)
|