diff options
author | Patrick Mooney <patrick.f.mooney@gmail.com> | 2015-06-24 04:08:08 +0000 |
---|---|---|
committer | Patrick Mooney <patrick.f.mooney@gmail.com> | 2015-06-25 15:29:03 +0000 |
commit | 945735f3c8c4944360c91ce32140a36bb6bdf092 (patch) | |
tree | dc150eb57efaf89544d086253205b0bf1dbc5242 | |
parent | 7ac3986f377338d615c1af749610302e254bf3f0 (diff) | |
download | illumos-joyent-945735f3c8c4944360c91ce32140a36bb6bdf092.tar.gz |
OS-4438 lxbrand ptrace should support PTRACE_GETSIGINFO
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
-rw-r--r-- | usr/src/common/brand/lx/lx_syscall.h | 1 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/ptrace.c | 1 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_misc.c | 97 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_ptrace.c | 34 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_misc.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_wait.c | 102 |
6 files changed, 140 insertions, 99 deletions
diff --git a/usr/src/common/brand/lx/lx_syscall.h b/usr/src/common/brand/lx/lx_syscall.h index e9d06fd9bc..54fb196b5a 100644 --- a/usr/src/common/brand/lx/lx_syscall.h +++ b/usr/src/common/brand/lx/lx_syscall.h @@ -66,6 +66,7 @@ extern "C" { #define LX_PTRACE_SYSCALL 24 #define LX_PTRACE_SETOPTIONS 0x4200 #define LX_PTRACE_GETEVENTMSG 0x4201 +#define LX_PTRACE_GETSIGINFO 0x4202 /* * For clone(2): diff --git a/usr/src/lib/brand/lx/lx_brand/common/ptrace.c b/usr/src/lib/brand/lx/lx_brand/common/ptrace.c index 57bcb5a2da..8680563c26 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/ptrace.c +++ b/usr/src/lib/brand/lx/lx_brand/common/ptrace.c @@ -839,6 +839,7 @@ lx_ptrace(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4) */ case LX_PTRACE_SETOPTIONS: case LX_PTRACE_GETEVENTMSG: + case LX_PTRACE_GETSIGINFO: case LX_PTRACE_GETREGS: case LX_PTRACE_SETREGS: return (lx_ptrace_kernel(ptrace_op, lxpid, p3, p4)); diff --git a/usr/src/uts/common/brand/lx/os/lx_misc.c b/usr/src/uts/common/brand/lx/os/lx_misc.c index a53282921b..797bf7ce7d 100644 --- a/usr/src/uts/common/brand/lx/os/lx_misc.c +++ b/usr/src/uts/common/brand/lx/os/lx_misc.c @@ -37,6 +37,7 @@ #include <sys/brand.h> #include <sys/lx_brand.h> #include <sys/lx_misc.h> +#include <sys/lx_siginfo.h> #include <sys/lx_futex.h> #include <lx_errno.h> #include <sys/cmn_err.h> @@ -806,3 +807,99 @@ lx_sigfd_translate(k_siginfo_t *infop) infop->si_pid = 0; } } + +int +stol_ksiginfo_copyout(k_siginfo_t *sip, void *ulxsip) +{ + lx_siginfo_t lsi; + + bzero(&lsi, sizeof (lsi)); + lsi.lsi_signo = lx_stol_signo(sip->si_signo, SIGCLD); + lsi.lsi_code = lx_stol_sigcode(sip->si_code); + lsi.lsi_errno = lx_errno(sip->si_errno, EINVAL); + + switch (lsi.lsi_signo) { + case LX_SIGPOLL: + lsi.lsi_band = sip->si_band; + lsi.lsi_fd = sip->si_fd; + break; + + case LX_SIGCHLD: + lsi.lsi_pid = sip->si_pid; + if (sip->si_code <= 0 || sip->si_code == CLD_EXITED) { + lsi.lsi_status = sip->si_status; + } else { + lsi.lsi_status = lx_stol_status(sip->si_status, + SIGKILL); + } + lsi.lsi_utime = sip->si_utime; + lsi.lsi_stime = sip->si_stime; + break; + + case LX_SIGILL: + case LX_SIGBUS: + case LX_SIGFPE: + case LX_SIGSEGV: + lsi.lsi_addr = sip->si_addr; + break; + + default: + lsi.lsi_pid = sip->si_pid; + lsi.lsi_uid = LX_UID32_TO_UID16(sip->si_uid); + } + + if (copyout(&lsi, ulxsip, sizeof (lsi)) != 0) { + return (set_errno(EFAULT)); + } + + return (0); +} + +#if defined(_SYSCALL32_IMPL) +int +stol_ksiginfo32_copyout(k_siginfo_t *sip, void *ulxsip) +{ + lx_siginfo32_t lsi; + + bzero(&lsi, sizeof (lsi)); + lsi.lsi_signo = lx_stol_signo(sip->si_signo, SIGCLD); + lsi.lsi_code = lx_stol_sigcode(sip->si_code); + lsi.lsi_errno = lx_errno(sip->si_errno, EINVAL); + + switch (lsi.lsi_signo) { + case LX_SIGPOLL: + lsi.lsi_band = sip->si_band; + lsi.lsi_fd = sip->si_fd; + break; + + case LX_SIGCHLD: + lsi.lsi_pid = sip->si_pid; + if (sip->si_code <= 0 || sip->si_code == CLD_EXITED) { + lsi.lsi_status = sip->si_status; + } else { + lsi.lsi_status = lx_stol_status(sip->si_status, + SIGKILL); + } + lsi.lsi_utime = sip->si_utime; + lsi.lsi_stime = sip->si_stime; + break; + + case LX_SIGILL: + case LX_SIGBUS: + case LX_SIGFPE: + case LX_SIGSEGV: + lsi.lsi_addr = (caddr32_t)(uintptr_t)sip->si_addr; + break; + + default: + lsi.lsi_pid = sip->si_pid; + lsi.lsi_uid = LX_UID32_TO_UID16(sip->si_uid); + } + + if (copyout(&lsi, ulxsip, sizeof (lsi)) != 0) { + return (set_errno(EFAULT)); + } + + return (0); +} +#endif diff --git a/usr/src/uts/common/brand/lx/os/lx_ptrace.c b/usr/src/uts/common/brand/lx/os/lx_ptrace.c index e6135c48f3..49f46d6271 100644 --- a/usr/src/uts/common/brand/lx/os/lx_ptrace.c +++ b/usr/src/uts/common/brand/lx/os/lx_ptrace.c @@ -870,6 +870,36 @@ lx_ptrace_setregs(lx_lwp_data_t *remote, void *uregsp) } } +static int +lx_ptrace_getsiginfo(lx_lwp_data_t *remote, void *usiginfo) +{ + klwp_t *lwp = remote->br_lwp; + int lx_sig; + + lx_sig = lx_stol_signo(lwp->lwp_cursig, 0); + if (lx_sig < 1 || lwp->lwp_curinfo == NULL) { + return (EINVAL); + } + +#if defined(_SYSCALL32_IMPL) + if (get_udatamodel() != DATAMODEL_NATIVE) { + if (stol_ksiginfo32_copyout(&lwp->lwp_curinfo->sq_info, + usiginfo) != 0) { + return (EFAULT); + } + } else +#endif + { + if (stol_ksiginfo_copyout(&lwp->lwp_curinfo->sq_info, + usiginfo) != 0) { + return (EFAULT); + } + } + + return (0); +} + + /* * Implements the PTRACE_CONT subcommand of the Linux ptrace(2) interface. */ @@ -2357,6 +2387,10 @@ lx_ptrace_kernel(int ptrace_op, pid_t lxpid, uintptr_t addr, uintptr_t data) error = lx_ptrace_setregs(remote, (void *)data); break; + case LX_PTRACE_GETSIGINFO: + error = lx_ptrace_getsiginfo(remote, (void *)data); + break; + default: error = EINVAL; } diff --git a/usr/src/uts/common/brand/lx/sys/lx_misc.h b/usr/src/uts/common/brand/lx/sys/lx_misc.h index 74a3e7a97b..de90962b32 100644 --- a/usr/src/uts/common/brand/lx/sys/lx_misc.h +++ b/usr/src/uts/common/brand/lx/sys/lx_misc.h @@ -44,6 +44,10 @@ extern uintptr_t lx_fsbase(klwp_t *, uintptr_t); extern void lx_exit_with_sig(proc_t *, sigqueue_t *); extern boolean_t lx_wait_filter(proc_t *, proc_t *); extern void lx_sigfd_translate(k_siginfo_t *); +extern int stol_ksiginfo_copyout(k_siginfo_t *, void *); +#if defined(_SYSCALL32_IMPL) +extern int stol_ksiginfo32_copyout(k_siginfo_t *, void *); +#endif typedef enum lx_if_action { LX_IF_FROMNATIVE, diff --git a/usr/src/uts/common/brand/lx/syscall/lx_wait.c b/usr/src/uts/common/brand/lx/syscall/lx_wait.c index e6c5607e43..e8358f9f69 100644 --- a/usr/src/uts/common/brand/lx/syscall/lx_wait.c +++ b/usr/src/uts/common/brand/lx/syscall/lx_wait.c @@ -70,7 +70,7 @@ #include <sys/brand.h> #include <sys/lx_brand.h> #include <sys/lx_types.h> -#include <sys/lx_siginfo.h> +#include <sys/lx_misc.h> #include <lx_signum.h> #include <lx_errno.h> #include <lx_syscall.h> @@ -325,102 +325,6 @@ lx_waitpid(uintptr_t p1, uintptr_t p2, uintptr_t p3) return (lx_wait4(p1, p2, p3, NULL)); } -static int -stol_ksiginfo(k_siginfo_t *sip, uintptr_t lxsip) -{ - lx_siginfo_t lsi; - - bzero(&lsi, sizeof (lsi)); - lsi.lsi_signo = lx_stol_signo(sip->si_signo, SIGCLD); - lsi.lsi_code = lx_stol_sigcode(sip->si_code); - lsi.lsi_errno = lx_errno(sip->si_errno, EINVAL); - - switch (lsi.lsi_signo) { - case LX_SIGPOLL: - lsi.lsi_band = sip->si_band; - lsi.lsi_fd = sip->si_fd; - break; - - case LX_SIGCHLD: - lsi.lsi_pid = sip->si_pid; - if (sip->si_code <= 0 || sip->si_code == CLD_EXITED) { - lsi.lsi_status = sip->si_status; - } else { - lsi.lsi_status = lx_stol_status(sip->si_status, - SIGKILL); - } - lsi.lsi_utime = sip->si_utime; - lsi.lsi_stime = sip->si_stime; - break; - - case LX_SIGILL: - case LX_SIGBUS: - case LX_SIGFPE: - case LX_SIGSEGV: - lsi.lsi_addr = sip->si_addr; - break; - - default: - lsi.lsi_pid = sip->si_pid; - lsi.lsi_uid = LX_UID32_TO_UID16(sip->si_uid); - } - - if (copyout(&lsi, (void *)lxsip, sizeof (lsi)) != 0) { - return (set_errno(EFAULT)); - } - - return (0); -} - -#if defined(_SYSCALL32_IMPL) -static int -stol_ksiginfo32(k_siginfo_t *sip, uintptr_t lxsip) -{ - lx_siginfo32_t lsi; - - bzero(&lsi, sizeof (lsi)); - lsi.lsi_signo = lx_stol_signo(sip->si_signo, SIGCLD); - lsi.lsi_code = lx_stol_sigcode(sip->si_code); - lsi.lsi_errno = lx_errno(sip->si_errno, EINVAL); - - switch (lsi.lsi_signo) { - case LX_SIGPOLL: - lsi.lsi_band = sip->si_band; - lsi.lsi_fd = sip->si_fd; - break; - - case LX_SIGCHLD: - lsi.lsi_pid = sip->si_pid; - if (sip->si_code <= 0 || sip->si_code == CLD_EXITED) { - lsi.lsi_status = sip->si_status; - } else { - lsi.lsi_status = lx_stol_status(sip->si_status, - SIGKILL); - } - lsi.lsi_utime = sip->si_utime; - lsi.lsi_stime = sip->si_stime; - break; - - case LX_SIGILL: - case LX_SIGBUS: - case LX_SIGFPE: - case LX_SIGSEGV: - lsi.lsi_addr = (caddr32_t)(uintptr_t)sip->si_addr; - break; - - default: - lsi.lsi_pid = sip->si_pid; - lsi.lsi_uid = LX_UID32_TO_UID16(sip->si_uid); - } - - if (copyout(&lsi, (void *)lxsip, sizeof (lsi)) != 0) { - return (set_errno(EFAULT)); - } - - return (0); -} -#endif - long lx_waitid(uintptr_t idtype, uintptr_t id, uintptr_t infop, uintptr_t opt) { @@ -464,10 +368,10 @@ lx_waitid(uintptr_t idtype, uintptr_t id, uintptr_t infop, uintptr_t opt) #if defined(_SYSCALL32_IMPL) if (get_udatamodel() != DATAMODEL_NATIVE) { - return (stol_ksiginfo32(&info, infop)); + return (stol_ksiginfo32_copyout(&info, (void *)infop)); } else #endif { - return (stol_ksiginfo(&info, infop)); + return (stol_ksiginfo_copyout(&info, (void *)infop)); } } |