summaryrefslogtreecommitdiff
path: root/msim/fault.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-09-30 18:52:25 -0400
committerFreya Murphy <freya@freyacat.org>2024-09-30 18:52:25 -0400
commit4af200b00188e02b2c6207dfe494a3dd12556c5f (patch)
tree25d993117e6306907d1d3821ef4fca729390d221 /msim/fault.c
parentupdate runtime to return exit code from main (diff)
downloadmips-4af200b00188e02b2c6207dfe494a3dd12556c5f.tar.gz
mips-4af200b00188e02b2c6207dfe494a3dd12556c5f.tar.bz2
mips-4af200b00188e02b2c6207dfe494a3dd12556c5f.zip
msim done (ish)
Diffstat (limited to 'msim/fault.c')
-rw-r--r--msim/fault.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/msim/fault.c b/msim/fault.c
new file mode 100644
index 0000000..88cd340
--- /dev/null
+++ b/msim/fault.c
@@ -0,0 +1,56 @@
+#include "fault.h"
+#include "sim.h"
+#include <signal.h>
+#include <time.h>
+
+static struct simulator *sim;
+
+static void sigsegv_handler(int sig, siginfo_t *info, void *ucontext)
+{
+ (void) sig;
+ (void) ucontext;
+
+ const char *inner = "";
+ switch (info->si_code) {
+ case SEGV_MAPERR:
+ inner = ": address not mapped to object";
+ break;
+ case SEGV_ACCERR:
+ inner = ": invalid premissions for mapped object";
+ break;
+ case SEGV_BNDERR:
+ inner = ": failed address bound checks";
+ break;
+ case SEGV_PKUERR:
+ inner = ": access was denied by memory protection";
+ break;
+ }
+
+ sim_dump(sim, "page fault at %p%s", info->si_addr, inner);
+}
+
+static void sigfpe_handler(int sig, siginfo_t *info, void *ucontext)
+{
+ (void) sig;
+ (void) info;
+ (void) ucontext;
+
+ sim_dump(sim, "floating point exception");
+
+}
+
+void init_handlers(struct simulator *s)
+{
+ struct sigaction act = {0};
+ sim = s;
+
+ /* sigsegv */
+ act.sa_sigaction = sigsegv_handler;
+ act.sa_flags = SA_SIGINFO;
+ sigaction(SIGSEGV, &act, NULL);
+
+ /* sigfpe */
+ act.sa_sigaction = sigfpe_handler;
+ act.sa_flags = SA_SIGINFO;
+ sigaction(SIGFPE, &act, NULL);
+}