genode/base-foc/patches/foc_single_step_x86.patch

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*/)