diff options
Diffstat (limited to 'arch/sandbox/cpu/os.c')
| -rw-r--r-- | arch/sandbox/cpu/os.c | 40 | 
1 files changed, 40 insertions, 0 deletions
| diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 0d8efd83f62..b56fa04a34b 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -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)  { | 
