|
@@ -3,6 +3,8 @@
|
|
|
* Copyright (c) 2011 The Chromium OS Authors.
|
|
|
*/
|
|
|
|
|
|
+#define _GNU_SOURCE
|
|
|
+
|
|
|
#include <dirent.h>
|
|
|
#include <errno.h>
|
|
|
#include <fcntl.h>
|
|
@@ -15,11 +17,13 @@
|
|
|
#include <string.h>
|
|
|
#include <termios.h>
|
|
|
#include <time.h>
|
|
|
+#include <ucontext.h>
|
|
|
#include <unistd.h>
|
|
|
#include <sys/mman.h>
|
|
|
#include <sys/stat.h>
|
|
|
#include <sys/time.h>
|
|
|
#include <sys/types.h>
|
|
|
+#include <linux/compiler_attributes.h>
|
|
|
#include <linux/types.h>
|
|
|
|
|
|
#include <asm/getopt.h>
|
|
@@ -191,6 +195,42 @@ static void os_sigint_handler(int sig)
|
|
|
raise(SIGINT);
|
|
|
}
|
|
|
|
|
|
+static void os_signal_handler(int sig, siginfo_t *info, void *con)
|
|
|
+{
|
|
|
+ ucontext_t __maybe_unused *context = con;
|
|
|
+ unsigned long pc;
|
|
|
+
|
|
|
+#if defined(__x86_64__)
|
|
|
+ pc = context->uc_mcontext.gregs[REG_RIP];
|
|
|
+#elif defined(__aarch64__)
|
|
|
+ pc = context->uc_mcontext.pc;
|
|
|
+#elif defined(__riscv)
|
|
|
+ pc = context->uc_mcontext.__gregs[REG_PC];
|
|
|
+#else
|
|
|
+ const char msg[] =
|
|
|
+ "\nUnsupported architecture, cannot read program counter\n";
|
|
|
+
|
|
|
+ os_write(1, msg, sizeof(msg));
|
|
|
+ pc = 0;
|
|
|
+#endif
|
|
|
+
|
|
|
+ os_signal_action(sig, pc);
|
|
|
+}
|
|
|
+
|
|
|
+int os_setup_signal_handlers(void)
|
|
|
+{
|
|
|
+ struct sigaction act;
|
|
|
+
|
|
|
+ act.sa_sigaction = os_signal_handler;
|
|
|
+ sigemptyset(&act.sa_mask);
|
|
|
+ act.sa_flags = SA_SIGINFO | SA_NODEFER;
|
|
|
+ if (sigaction(SIGILL, &act, NULL) ||
|
|
|
+ sigaction(SIGBUS, &act, NULL) ||
|
|
|
+ sigaction(SIGSEGV, &act, NULL))
|
|
|
+ return -1;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/* Put tty into raw mode so <tab> and <ctrl+c> work */
|
|
|
void os_tty_raw(int fd, bool allow_sigs)
|
|
|
{
|