mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-25 08:21:08 +00:00
233 lines
6.4 KiB
Diff
233 lines
6.4 KiB
Diff
|
Index: kernel/fiasco/src/Kconfig
|
||
|
===================================================================
|
||
|
--- kernel/fiasco/src/Kconfig (revision 38)
|
||
|
+++ kernel/fiasco/src/Kconfig (working copy)
|
||
|
@@ -694,6 +694,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 38)
|
||
|
+++ kernel/fiasco/src/kern/ia32/config-ia32.cpp (working copy)
|
||
|
@@ -98,6 +98,12 @@
|
||
|
static const bool kinfo_timer_uses_rdtsc = false;
|
||
|
#endif
|
||
|
|
||
|
+#ifdef CONFIG_USER_SINGLE_STEP
|
||
|
+ static const bool user_single_step = true;
|
||
|
+#else
|
||
|
+ static const bool user_single_step = false;
|
||
|
+#endif
|
||
|
+
|
||
|
static const bool old_sigma0_adapter_hack = false;
|
||
|
|
||
|
// the default uart to use for serial console
|
||
|
Index: kernel/fiasco/src/kern/ia32/32/entry-native.S
|
||
|
===================================================================
|
||
|
--- kernel/fiasco/src/kern/ia32/32/entry-native.S (revision 38)
|
||
|
+++ 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:
|
||
|
@@ -55,6 +79,15 @@
|
||
|
cmpl $VAL__MEM_LAYOUT__TCBS_END, %esp
|
||
|
jbe 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
|
||
|
@@ -214,11 +247,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 38)
|
||
|
+++ kernel/fiasco/src/kern/ia32/thread-ia32.cpp (working copy)
|
||
|
@@ -196,12 +196,19 @@
|
||
|
Address ip;
|
||
|
int from_user = ts->cs() & 3;
|
||
|
|
||
|
+ //if (ts->_trapno != 3)
|
||
|
+ // LOG_MSG_3VAL(this, "trap", ts->_trapno, from_user, ts->ip());
|
||
|
+
|
||
|
if (EXPECT_FALSE(ts->_trapno == 0xee)) //debug IPI
|
||
|
{
|
||
|
Ipi::eoi(Ipi::Debug);
|
||
|
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))
|
||
|
@@ -521,7 +528,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)
|
||
|
@@ -574,6 +582,11 @@
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+IMPLEMENT inline
|
||
|
+void
|
||
|
+Thread::user_single_step(bool)
|
||
|
+{}
|
||
|
+
|
||
|
//----------------------------------------------------------------------------
|
||
|
IMPLEMENTATION [ia32]:
|
||
|
|
||
|
@@ -586,6 +599,16 @@
|
||
|
_gs = _fs = Utcb_init::utcb_segment();
|
||
|
}
|
||
|
|
||
|
+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);
|
||
|
+}
|
||
|
+
|
||
|
//----------------------------------------------------------------------------
|
||
|
IMPLEMENTATION [amd64]:
|
||
|
|
||
|
Index: kernel/fiasco/src/kern/thread_object.cpp
|
||
|
===================================================================
|
||
|
--- kernel/fiasco/src/kern/thread_object.cpp (revision 38)
|
||
|
+++ kernel/fiasco/src/kern/thread_object.cpp (working copy)
|
||
|
@@ -524,6 +524,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 38)
|
||
|
+++ kernel/fiasco/src/kern/thread.cpp (working copy)
|
||
|
@@ -70,6 +70,7 @@
|
||
|
{
|
||
|
Exr_cancel = 0x10000,
|
||
|
Exr_trigger_exception = 0x20000,
|
||
|
+ Exr_single_step = 0x40000,
|
||
|
};
|
||
|
|
||
|
enum Vcpu_ctl_flags
|
||
|
@@ -137,6 +138,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 38)
|
||
|
+++ kernel/fiasco/src/kern/arm/thread-arm.cpp (working copy)
|
||
|
@@ -549,6 +549,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 38)
|
||
|
+++ kernel/fiasco/src/kern/ppc32/thread-ppc32.cpp (working copy)
|
||
|
@@ -307,6 +307,10 @@
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+IMPLEMENT inline
|
||
|
+void Thread::user_single_step(bool)
|
||
|
+{}
|
||
|
+
|
||
|
PUBLIC inline NEEDS ["trap_state.h"]
|
||
|
int
|
||
|
Thread::send_exception_arch(Trap_state * /*ts*/)
|