Skip to content

Commit

Permalink
i#3544 RV64: Fix signal mask restoring after detection of RVV (#6890)
Browse files Browse the repository at this point in the history
We detect the RISC-V vector extension using SIGILL (PR #6836). However,
using `dr_longjmp` to exit the signal handler would miss to restore the
signal mask, which is operated by the OS after exiting the signal
handle. Therefore, we need to manually save and restore the signal mask.

Issue: #3544
  • Loading branch information
chenhy0106 authored Jul 19, 2024
1 parent 577db95 commit 8d5e61c
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 1 deletion.
2 changes: 1 addition & 1 deletion core/unix/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ setitimer_syscall(int which, struct itimerval *val, struct itimerval *old)
return dynamorio_syscall(SYS_setitimer, 3, which, val, old);
}

static inline int
int
sigprocmask_syscall(int how, kernel_sigset_t *set, kernel_sigset_t *oset,
size_t sigsetsize)
{
Expand Down
9 changes: 9 additions & 0 deletions core/unix/signal_linux_riscv64.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,19 @@ sigill_detected(void *func)
set_handler_sigact(&act, SIGILL, (handler_t)catch_sigill);
sigaction_syscall(SIGILL, &act, &old_act);

/* We use dr_longjmp to exit the SIGILL handler, which skips the signal mask restoring
* of OS. Manually save and restore the signal mask here.
* XXX: Add dr_longjmp_sigmask() to make this easier?
*/
kernel_sigset_t oset;
sigprocmask_syscall(SIG_SETMASK, NULL, &oset, sizeof(oset));

if (dr_setjmp(&jmpbuf) == 0) {
((void (*)(void))func)();
}

sigprocmask_syscall(SIG_SETMASK, &oset, NULL, sizeof(oset));

sigaction_syscall(SIGILL, &old_act, NULL);

return sigill_caught;
Expand Down
4 changes: 4 additions & 0 deletions core/unix/signal_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,10 @@ sigaction_syscall(int sig, kernel_sigaction_t *act, kernel_sigaction_t *oact);
void
set_handler_sigact(kernel_sigaction_t *act, int sig, handler_t handler);

int
sigprocmask_syscall(int how, kernel_sigset_t *set, kernel_sigset_t *oset,
size_t sigsetsize);

/***************************************************************************
* OS-SPECIFIC ROUTINES (in signal_<os>.c)
*/
Expand Down

0 comments on commit 8d5e61c

Please sign in to comment.