diff options
author | Warner Losh <imp@bsdimp.com> | 2022-01-08 21:48:25 -0700 |
---|---|---|
committer | Warner Losh <imp@bsdimp.com> | 2022-01-28 15:53:41 -0700 |
commit | 08eb66d5d837c2db9d5d57553da8448fd8e36571 (patch) | |
tree | 43024629fc5b409a8348a53e64a9af445d9a42e7 /bsd-user/signal.c | |
parent | 6c6d4b5616b391934851f049f41a7cbde12140d9 (diff) |
bsd-user/signal.c: tswap_siginfo
Convert siginfo from targer to host.
Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'bsd-user/signal.c')
-rw-r--r-- | bsd-user/signal.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/bsd-user/signal.c b/bsd-user/signal.c index 366e047ccc..34e8c811ad 100644 --- a/bsd-user/signal.c +++ b/bsd-user/signal.c @@ -256,6 +256,59 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, tinfo->si_code = deposit32(si_code, 24, 8, si_type); } +static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info) +{ + int si_type = extract32(info->si_code, 24, 8); + int si_code = sextract32(info->si_code, 0, 24); + + __put_user(info->si_signo, &tinfo->si_signo); + __put_user(info->si_errno, &tinfo->si_errno); + __put_user(si_code, &tinfo->si_code); /* Zero out si_type, it's internal */ + __put_user(info->si_pid, &tinfo->si_pid); + __put_user(info->si_uid, &tinfo->si_uid); + __put_user(info->si_status, &tinfo->si_status); + __put_user(info->si_addr, &tinfo->si_addr); + /* + * Unswapped, because we passed it through mostly untouched. si_value is + * opaque to the kernel, so we didn't bother with potentially wasting cycles + * to swap it into host byte order. + */ + tinfo->si_value.sival_ptr = info->si_value.sival_ptr; + + /* + * We can use our internal marker of which fields in the structure + * are valid, rather than duplicating the guesswork of + * host_to_target_siginfo_noswap() here. + */ + switch (si_type) { + case QEMU_SI_NOINFO: /* No additional info */ + break; + case QEMU_SI_FAULT: + __put_user(info->_reason._fault._trapno, + &tinfo->_reason._fault._trapno); + break; + case QEMU_SI_TIMER: + __put_user(info->_reason._timer._timerid, + &tinfo->_reason._timer._timerid); + __put_user(info->_reason._timer._overrun, + &tinfo->_reason._timer._overrun); + break; + case QEMU_SI_MESGQ: + __put_user(info->_reason._mesgq._mqd, &tinfo->_reason._mesgq._mqd); + break; + case QEMU_SI_POLL: + /* Note: Not generated on FreeBSD */ + __put_user(info->_reason._poll._band, &tinfo->_reason._poll._band); + break; + case QEMU_SI_CAPSICUM: + __put_user(info->_reason._capsicum._syscall, + &tinfo->_reason._capsicum._syscall); + break; + default: + g_assert_not_reached(); + } +} + /* Returns 1 if given signal should dump core if not handled. */ static int core_dump_signal(int sig) { |