summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mooney <patrick.f.mooney@gmail.com>2015-06-24 04:08:08 +0000
committerPatrick Mooney <patrick.f.mooney@gmail.com>2015-06-25 15:29:03 +0000
commit945735f3c8c4944360c91ce32140a36bb6bdf092 (patch)
treedc150eb57efaf89544d086253205b0bf1dbc5242
parent7ac3986f377338d615c1af749610302e254bf3f0 (diff)
downloadillumos-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.h1
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/ptrace.c1
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_misc.c97
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_ptrace.c34
-rw-r--r--usr/src/uts/common/brand/lx/sys/lx_misc.h4
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_wait.c102
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));
}
}