From 7d7620405324693b7f6e9690e75ccede66b8f757 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 24 Apr 2019 23:49:13 -0700 Subject: [PATCH] Add debugging kernel monitor functions --- kern/monitor.c | 42 +++++++++++++++++++++++++++++++++++++++++- kern/monitor.h | 2 ++ kern/trap.c | 2 +- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/kern/monitor.c b/kern/monitor.c index d2affd9..89e6efd 100644 --- a/kern/monitor.c +++ b/kern/monitor.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -31,7 +32,9 @@ static struct Command commands[] = { { "kerninfo", "Display information about the kernel", mon_kerninfo }, { "backtrace", "Display current backtrace", mon_backtrace }, { "showmappings", "Display the physical mappings for range", mon_showmappings }, - { "mperms", "Change the permissions of a memory range", mon_mperms } + { "mperms", "Change the permissions of a memory range", mon_mperms }, + { "resume", "Resume from a breakpoint", mon_resume }, + { "step", "Step to next instruction", mon_step } }; @@ -188,6 +191,43 @@ int mon_mperms(int argc, char** argv, struct Trapframe* tf) { return 0; } +// This is a nice thought and all... +// But we should modify the trap frame. +// I feel stupid. +static inline void +set_eflag(uint16_t flagno, int value) { + uint32_t temp; + uint32_t mask = ~(1 << flagno); + uint32_t regv = value << flagno; + asm volatile("pushfl\n\t" + "pop %w0\n\t" + "and %w1, %w0\n\t" + "or %w2, %w0\n\t" + "push %w0\n\t" + "popfl\n\t" + : "=r" (temp) + : "r" (mask), "r" (regv)); +} + +#define EXPECT_BRKPT if(!(tf->tf_trapno == T_BRKPT || tf->tf_trapno == T_DEBUG)) { \ + cprintf(ACOL_ERR("I don't think I should resume from this.\n")); \ + return 0; } +#define EFLAGS_TF 0x8 + +int mon_resume(int argc, char** argv, struct Trapframe* tf) { + EXPECT_BRKPT; + tf->tf_eflags &= ~(1 << EFLAGS_TF); + env_pop_tf(tf); + return 0; +} + +int mon_step(int argc, char** argv, struct Trapframe* tf) { + EXPECT_BRKPT; + tf->tf_eflags |= 1 << EFLAGS_TF; + env_pop_tf(tf); + return 0; +} + /***** Kernel monitor command interpreter *****/ #define WHITESPACE "\t\r\n " diff --git a/kern/monitor.h b/kern/monitor.h index 4da7606..0e51db1 100644 --- a/kern/monitor.h +++ b/kern/monitor.h @@ -17,5 +17,7 @@ int mon_kerninfo(int argc, char **argv, struct Trapframe *tf); int mon_backtrace(int argc, char **argv, struct Trapframe *tf); int mon_showmappings(int argc, char **argv, struct Trapframe *tf); int mon_mperms(int argc, char** argv, struct Trapframe* tf); +int mon_resume(int argc, char** argv, struct Trapframe* tf); +int mon_step(int argc, char** argv, struct Trapframe* tf); #endif // !JOS_KERN_MONITOR_H diff --git a/kern/trap.c b/kern/trap.c index 88ca879..4ce2170 100644 --- a/kern/trap.c +++ b/kern/trap.c @@ -199,7 +199,7 @@ trap_dispatch(struct Trapframe *tf) if (tf->tf_trapno == T_PGFLT) { page_fault_handler(tf); return; - } else if (tf->tf_trapno == T_BRKPT) { + } else if (tf->tf_trapno == T_BRKPT || tf->tf_trapno == T_DEBUG) { monitor(tf); return; } else if (tf->tf_trapno == T_SYSCALL) {