summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/imgact_elf.c36
-rw-r--r--sys/kern/kern_fork.c1
-rw-r--r--sys/kern/kern_kthread.c1
-rw-r--r--sys/kern/kern_sig.c28
-rw-r--r--sys/kern/kern_thr.c1
-rw-r--r--sys/kern/sys_process.c4
-rw-r--r--sys/sys/elf_common.h2
-rw-r--r--sys/sys/proc.h3
8 files changed, 68 insertions, 8 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 3a7460b..6a5ba55 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2017 Dell EMC
* Copyright (c) 2000 David O'Brien
* Copyright (c) 1995-1996 Søren Schmidt
* Copyright (c) 1996 Peter Wemm
@@ -52,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <sys/pioctl.h>
#include <sys/proc.h>
#include <sys/procfs.h>
+#include <sys/ptrace.h>
#include <sys/racct.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
@@ -1205,6 +1207,7 @@ static void __elfN(note_prpsinfo)(void *, struct sbuf *, size_t *);
static void __elfN(note_prstatus)(void *, struct sbuf *, size_t *);
static void __elfN(note_threadmd)(void *, struct sbuf *, size_t *);
static void __elfN(note_thrmisc)(void *, struct sbuf *, size_t *);
+static void __elfN(note_ptlwpinfo)(void *, struct sbuf *, size_t *);
static void __elfN(note_procstat_auxv)(void *, struct sbuf *, size_t *);
static void __elfN(note_procstat_proc)(void *, struct sbuf *, size_t *);
static void __elfN(note_procstat_psstrings)(void *, struct sbuf *, size_t *);
@@ -1634,6 +1637,8 @@ __elfN(prepare_notes)(struct thread *td, struct note_info_list *list,
__elfN(note_fpregset), thr);
size += register_note(list, NT_THRMISC,
__elfN(note_thrmisc), thr);
+ size += register_note(list, NT_PTLWPINFO,
+ __elfN(note_ptlwpinfo), thr);
size += register_note(list, -1,
__elfN(note_threadmd), thr);
@@ -1995,6 +2000,37 @@ __elfN(note_thrmisc)(void *arg, struct sbuf *sb, size_t *sizep)
*sizep = sizeof(thrmisc);
}
+static void
+__elfN(note_ptlwpinfo)(void *arg, struct sbuf *sb, size_t *sizep)
+{
+ struct thread *td;
+ size_t size;
+ int structsize;
+ struct ptrace_lwpinfo pl;
+
+ td = (struct thread *)arg;
+ size = sizeof(structsize) + sizeof(struct ptrace_lwpinfo);
+ if (sb != NULL) {
+ KASSERT(*sizep == size, ("invalid size"));
+ structsize = sizeof(struct ptrace_lwpinfo);
+ sbuf_bcat(sb, &structsize, sizeof(structsize));
+ bzero(&pl, sizeof(pl));
+ pl.pl_lwpid = td->td_tid;
+ pl.pl_event = PL_EVENT_NONE;
+ pl.pl_sigmask = td->td_sigmask;
+ pl.pl_siglist = td->td_siglist;
+ if (td->td_si.si_signo != 0) {
+ pl.pl_event = PL_EVENT_SIGNAL;
+ pl.pl_flags |= PL_FLAG_SI;
+ pl.pl_siginfo = td->td_si;
+ }
+ strcpy(pl.pl_tdname, td->td_name);
+ /* XXX TODO: supply more information in struct ptrace_lwpinfo*/
+ sbuf_bcat(sb, &pl, sizeof(struct ptrace_lwpinfo));
+ }
+ *sizep = size;
+}
+
/*
* Allow for MD specific notes, as well as any MD
* specific preparations for writing MI notes.
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index b63bc65..1ce89e9 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -475,6 +475,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *
bzero(&td2->td_startzero,
__rangeof(struct thread, td_startzero, td_endzero));
td2->td_sleeptimo = 0;
+ bzero(&td2->td_si, sizeof(td2->td_si));
bcopy(&td->td_startcopy, &td2->td_startcopy,
__rangeof(struct thread, td_startcopy, td_endcopy));
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c
index 69c1140..f5c62cc 100644
--- a/sys/kern/kern_kthread.c
+++ b/sys/kern/kern_kthread.c
@@ -274,6 +274,7 @@ kthread_add(void (*func)(void *), void *arg, struct proc *p,
bzero(&newtd->td_startzero,
__rangeof(struct thread, td_startzero, td_endzero));
newtd->td_sleeptimo = 0;
+ bzero(&newtd->td_si, sizeof(newtd->td_si));
bcopy(&oldtd->td_startcopy, &newtd->td_startcopy,
__rangeof(struct thread, td_startcopy, td_endcopy));
newtd->td_sa = oldtd->td_sa;
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index d2c8013..ac26312 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1243,6 +1243,19 @@ sys_sigwaitinfo(struct thread *td, struct sigwaitinfo_args *uap)
return (error);
}
+static void
+proc_td_siginfo_capture(struct thread *td, siginfo_t *si)
+{
+ struct thread *thr;
+
+ FOREACH_THREAD_IN_PROC(td->td_proc, thr) {
+ if (thr == td)
+ thr->td_si = *si;
+ else
+ thr->td_si.si_signo = 0;
+ }
+}
+
int
kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi,
struct timespec *timeout)
@@ -1351,8 +1364,10 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi,
ktrpsig(sig, action, &td->td_sigmask, ksi->ksi_code);
}
#endif
- if (sig == SIGKILL)
+ if (sig == SIGKILL) {
+ proc_td_siginfo_capture(td, &ksi->ksi_info);
sigexit(td, sig);
+ }
}
PROC_UNLOCK(p);
return (error);
@@ -2805,6 +2820,7 @@ issignal(struct thread *td)
struct sigqueue *queue;
sigset_t sigpending;
int prop, sig, traced;
+ ksiginfo_t ksi;
p = td->td_proc;
ps = p->p_sigacts;
@@ -2860,14 +2876,15 @@ issignal(struct thread *td)
* be thrown away.
*/
queue = &td->td_sigqueue;
- td->td_dbgksi.ksi_signo = 0;
- if (sigqueue_get(queue, sig, &td->td_dbgksi) == 0) {
+ ksiginfo_init(&ksi);
+ if (sigqueue_get(queue, sig, &ksi) == 0) {
queue = &p->p_sigqueue;
- sigqueue_get(queue, sig, &td->td_dbgksi);
+ sigqueue_get(queue, sig, &ksi);
}
+ td->td_si = ksi.ksi_info;
mtx_unlock(&ps->ps_mtx);
- sig = ptracestop(td, sig, &td->td_dbgksi);
+ sig = ptracestop(td, sig, &ksi);
mtx_lock(&ps->ps_mtx);
/*
@@ -3039,6 +3056,7 @@ postsig(int sig)
* the process. (Other cases were ignored above.)
*/
mtx_unlock(&ps->ps_mtx);
+ proc_td_siginfo_capture(td, &ksi.ksi_info);
sigexit(td, sig);
/* NOTREACHED */
} else {
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index 6bebac9..e434487 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -233,6 +233,7 @@ thread_create(struct thread *td, struct rtprio *rtp,
bzero(&newtd->td_startzero,
__rangeof(struct thread, td_startzero, td_endzero));
newtd->td_sleeptimo = 0;
+ bzero(&newtd->td_si, sizeof(newtd->td_si));
bcopy(&td->td_startcopy, &newtd->td_startcopy,
__rangeof(struct thread, td_startcopy, td_endcopy));
newtd->td_sa = td->td_sa;
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index ab592c4..7979da1 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1335,7 +1335,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
pl->pl_flags = 0;
if (td2->td_dbgflags & TDB_XSIG) {
pl->pl_event = PL_EVENT_SIGNAL;
- if (td2->td_dbgksi.ksi_signo != 0 &&
+ if (td2->td_si.si_signo != 0 &&
#ifdef COMPAT_FREEBSD32
((!wrap32 && data >= offsetof(struct ptrace_lwpinfo,
pl_siginfo) + sizeof(pl->pl_siginfo)) ||
@@ -1347,7 +1347,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
#endif
){
pl->pl_flags |= PL_FLAG_SI;
- pl->pl_siginfo = td2->td_dbgksi.ksi_info;
+ pl->pl_siginfo = td2->td_si;
}
}
if ((pl->pl_flags & PL_FLAG_SI) == 0)
diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h
index e8a8709..90e9de6 100644
--- a/sys/sys/elf_common.h
+++ b/sys/sys/elf_common.h
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2017 Dell EMC
* Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien
* Copyright (c) 1998 John D. Polstra.
* All rights reserved.
@@ -753,6 +754,7 @@ typedef struct {
#define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */
#define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */
#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */
+#define NT_PTLWPINFO 17 /* Thread ptrace miscellaneous info. */
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
#define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 11947db6..e17c249 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -275,7 +275,7 @@ struct thread {
char td_name[MAXCOMLEN + 1]; /* (*) Thread name. */
struct file *td_fpop; /* (k) file referencing cdev under op */
int td_dbgflags; /* (c) Userland debugger flags */
- struct ksiginfo td_dbgksi; /* (c) ksi reflected to debugger. */
+ uint64_t padding3[14];
int td_ng_outbound; /* (k) Thread entered ng from above. */
struct osd td_osd; /* (k) Object specific data. */
struct vm_map_entry *td_map_def_user; /* (k) Deferred entries. */
@@ -346,6 +346,7 @@ struct thread {
#define td_siglist td_sigqueue.sq_signals
struct syscall_args td_sa; /* (kx) Syscall parameters. Copied on
fork for child tracing. */
+ siginfo_t td_si; /* (c) For debugger or core file */
};
struct thread0_storage {
OpenPOWER on IntegriCloud