diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/imgact_elf.c | 36 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 1 | ||||
-rw-r--r-- | sys/kern/kern_kthread.c | 1 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 28 | ||||
-rw-r--r-- | sys/kern/kern_thr.c | 1 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 4 | ||||
-rw-r--r-- | sys/sys/elf_common.h | 2 | ||||
-rw-r--r-- | sys/sys/proc.h | 3 |
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 { |