Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Jun 2017 21:31:14 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r320481 - in head: sys/compat/freebsd32 sys/kern sys/sys usr.bin/gcore
Message-ID:  <201706292131.v5TLVEcF018300@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Thu Jun 29 21:31:13 2017
New Revision: 320481
URL: https://svnweb.freebsd.org/changeset/base/320481

Log:
  Store a 32-bit PT_LWPINFO struct for 32-bit process core dumps.
  
  Process core notes for a 32-bit process running on a 64-bit host need to
  use 32-bit structures so that the note layout matches the layout of notes
  of a core dump of a 32-bit process under a 32-bit kernel.
  
  Reviewed by:	kib
  Differential Revision:	https://reviews.freebsd.org/D11407

Modified:
  head/sys/compat/freebsd32/freebsd32_signal.h
  head/sys/kern/imgact_elf.c
  head/sys/kern/sys_process.c
  head/sys/sys/ptrace.h
  head/sys/sys/signal.h
  head/usr.bin/gcore/elf32core.c
  head/usr.bin/gcore/elfcore.c

Modified: head/sys/compat/freebsd32/freebsd32_signal.h
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_signal.h	Thu Jun 29 19:43:27 2017	(r320480)
+++ head/sys/compat/freebsd32/freebsd32_signal.h	Thu Jun 29 21:31:13 2017	(r320481)
@@ -35,44 +35,6 @@ struct sigaltstack32 {
 	int		ss_flags;	/* SS_DISABLE and/or SS_ONSTACK */
 };
 
-union sigval32 {
-	int			sival_int;
-	u_int32_t		sival_ptr;
-	/* 6.0 compatibility */
-	int			sigval_int;
-	u_int32_t		sigval_ptr;
-};
-
-struct siginfo32 {
-	int			si_signo;	/* signal number */
-	int			si_errno;	/* errno association */
-	int			si_code;	/* signal code */
-	int32_t			si_pid;		/* sending process */
-	u_int32_t		si_uid;		/* sender's ruid */
-	int			si_status;	/* exit value */
-	u_int32_t		si_addr;	/* faulting instruction */
-	union sigval32		si_value;	/* signal value */
-	union	{
-		struct {
-			int	_trapno;/* machine specific trap code */
-		} _fault;
-		struct {
-			int	_timerid;
-			int	_overrun;
-		} _timer;
-		struct {
-			int	_mqd;
-		} _mesgq;
-		struct {
-			int	_band;		/* band event for SIGPOLL */
-		} _poll;			/* was this ever used ? */
-		struct {
-			int	__spare1__;
-			int	__spare2__[7];
-		} __spare__;
-	} _reason;
-};
-
 struct osigevent32 {
 	int	sigev_notify;		/* Notification type */
 	union {

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c	Thu Jun 29 19:43:27 2017	(r320480)
+++ head/sys/kern/imgact_elf.c	Thu Jun 29 21:31:13 2017	(r320481)
@@ -1875,6 +1875,7 @@ __elfN(putnote)(struct note_info *ninfo, struct sbuf *
 
 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
 #include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_signal.h>
 
 typedef struct prstatus32 elf_prstatus_t;
 typedef struct prpsinfo32 elf_prpsinfo_t;
@@ -2029,13 +2030,17 @@ __elfN(note_ptlwpinfo)(void *arg, struct sbuf *sb, siz
 	struct thread *td;
 	size_t size;
 	int structsize;
+#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
+	struct ptrace_lwpinfo32 pl;
+#else
 	struct ptrace_lwpinfo pl;
+#endif
 
 	td = (struct thread *)arg;
-	size = sizeof(structsize) + sizeof(struct ptrace_lwpinfo);
+	size = sizeof(structsize) + sizeof(pl);
 	if (sb != NULL) {
 		KASSERT(*sizep == size, ("invalid size"));
-		structsize = sizeof(struct ptrace_lwpinfo);
+		structsize = sizeof(pl);
 		sbuf_bcat(sb, &structsize, sizeof(structsize));
 		bzero(&pl, sizeof(pl));
 		pl.pl_lwpid = td->td_tid;
@@ -2045,11 +2050,15 @@ __elfN(note_ptlwpinfo)(void *arg, struct sbuf *sb, siz
 		if (td->td_si.si_signo != 0) {
 			pl.pl_event = PL_EVENT_SIGNAL;
 			pl.pl_flags |= PL_FLAG_SI;
+#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
+			siginfo_to_siginfo32(&td->td_si, &pl.pl_siginfo);
+#else
 			pl.pl_siginfo = td->td_si;
+#endif
 		}
 		strcpy(pl.pl_tdname, td->td_name);
 		/* XXX TODO: supply more information in struct ptrace_lwpinfo*/
-		sbuf_bcat(sb, &pl, sizeof(struct ptrace_lwpinfo));
+		sbuf_bcat(sb, &pl, sizeof(pl));
 	}
 	*sizep = size;
 }

Modified: head/sys/kern/sys_process.c
==============================================================================
--- head/sys/kern/sys_process.c	Thu Jun 29 19:43:27 2017	(r320480)
+++ head/sys/kern/sys_process.c	Thu Jun 29 21:31:13 2017	(r320481)
@@ -87,20 +87,6 @@ struct ptrace_vm_entry32 {
 	u_int		pve_fsid;
 	uint32_t	pve_path;
 };
-
-struct ptrace_lwpinfo32 {
-	lwpid_t	pl_lwpid;	/* LWP described. */
-	int	pl_event;	/* Event that stopped the LWP. */
-	int	pl_flags;	/* LWP flags. */
-	sigset_t	pl_sigmask;	/* LWP signal mask */
-	sigset_t	pl_siglist;	/* LWP pending signal */
-	struct siginfo32 pl_siginfo;	/* siginfo for signal */
-	char	pl_tdname[MAXCOMLEN + 1];	/* LWP name. */
-	pid_t	pl_child_pid;		/* New child pid */
-	u_int		pl_syscall_code;
-	u_int		pl_syscall_narg;
-};
-
 #endif
 
 /*

Modified: head/sys/sys/ptrace.h
==============================================================================
--- head/sys/sys/ptrace.h	Thu Jun 29 19:43:27 2017	(r320480)
+++ head/sys/sys/ptrace.h	Thu Jun 29 21:31:13 2017	(r320481)
@@ -138,6 +138,21 @@ struct ptrace_lwpinfo {
 	u_int		pl_syscall_narg;
 };
 
+#if defined(_WANT_LWPINFO32) || (defined(_KERNEL) && defined(__LP64__))
+struct ptrace_lwpinfo32 {
+	lwpid_t	pl_lwpid;	/* LWP described. */
+	int	pl_event;	/* Event that stopped the LWP. */
+	int	pl_flags;	/* LWP flags. */
+	sigset_t	pl_sigmask;	/* LWP signal mask */
+	sigset_t	pl_siglist;	/* LWP pending signal */
+	struct siginfo32 pl_siginfo;	/* siginfo for signal */
+	char		pl_tdname[MAXCOMLEN + 1]; /* LWP name. */
+	pid_t		pl_child_pid;	/* New child pid */
+	u_int		pl_syscall_code;
+	u_int		pl_syscall_narg;
+};
+#endif
+
 /* Argument structure for PT_VM_ENTRY. */
 struct ptrace_vm_entry {
 	int		pve_entry;	/* Entry number used for iteration. */

Modified: head/sys/sys/signal.h
==============================================================================
--- head/sys/sys/signal.h	Thu Jun 29 19:43:27 2017	(r320480)
+++ head/sys/sys/signal.h	Thu Jun 29 21:31:13 2017	(r320481)
@@ -174,7 +174,17 @@ union sigval {
 	int     sigval_int;
 	void    *sigval_ptr;
 };
+
+#if defined(_WANT_LWPINFO32) || (defined(_KERNEL) && defined(__LP64__))
+union sigval32 {
+	int	sival_int;
+	uint32_t sival_ptr;
+	/* 6.0 compatibility */
+	int	sigval_int;
+	uint32_t sigval_ptr;
+};
 #endif
+#endif
 
 #if __POSIX_VISIBLE >= 199309
 
@@ -255,6 +265,38 @@ typedef	struct __siginfo {
 #define si_overrun	_reason._timer._overrun
 #define si_mqd		_reason._mesgq._mqd
 #define si_band		_reason._poll._band
+
+#if defined(_WANT_LWPINFO32) || (defined(_KERNEL) && defined(__LP64__))
+struct siginfo32 {
+	int	si_signo;		/* signal number */
+	int	si_errno;		/* errno association */
+	int	si_code;		/* signal code */
+	__pid_t	si_pid;			/* sending process */
+	__uid_t	si_uid;			/* sender's ruid */
+	int	si_status;		/* exit value */
+	uint32_t si_addr;		/* faulting instruction */
+	union sigval32 si_value;	/* signal value */
+	union	{
+		struct {
+			int	_trapno;/* machine specific trap code */
+		} _fault;
+		struct {
+			int	_timerid;
+			int	_overrun;
+		} _timer;
+		struct {
+			int	_mqd;
+		} _mesgq;
+		struct {
+			int32_t	_band;		/* band event for SIGPOLL */
+		} _poll;			/* was this ever used ? */
+		struct {
+			int32_t	__spare1__;
+			int	__spare2__[7];
+		} __spare__;
+	} _reason;
+};
+#endif
 
 /** si_code **/
 /* codes for SIGILL */

Modified: head/usr.bin/gcore/elf32core.c
==============================================================================
--- head/usr.bin/gcore/elf32core.c	Thu Jun 29 19:43:27 2017	(r320480)
+++ head/usr.bin/gcore/elf32core.c	Thu Jun 29 21:31:13 2017	(r320481)
@@ -5,6 +5,7 @@
 
 #define __ELF_WORD_SIZE 32
 #define _MACHINE_ELF_WANT_32BIT
+#define	_WANT_LWPINFO32
 
 #include <sys/procfs.h>
 
@@ -46,3 +47,42 @@ elf_convert_fpregset(elfcore_fpregset_t *rd, struct fp
 #error Unsupported architecture
 #endif
 }
+
+static void
+elf_convert_siginfo(struct siginfo32 *sid, siginfo_t *sis)
+{
+
+	bzero(sid, sizeof(*sid));
+	sid->si_signo = sis->si_signo;
+	sid->si_errno = sis->si_errno;
+	sid->si_code = sis->si_code;
+	sid->si_pid = sis->si_pid;
+	sid->si_uid = sis->si_uid;
+	sid->si_status = sis->si_status;
+	sid->si_addr = (uintptr_t)sis->si_addr;
+#if _BYTE_ORDER == _BIG_ENDIAN
+	if (sis->si_value.sival_int == 0)
+		sid->si_value.sival_ptr = (uintptr_t)sis->si_value.sival_ptr;
+	else
+#endif
+		sid->si_value.sival_int = sis->si_value.sival_int;
+	sid->si_timerid = sis->si_timerid;
+	sid->si_overrun = sis->si_overrun;
+}
+
+static void
+elf_convert_lwpinfo(struct ptrace_lwpinfo32 *pld, struct ptrace_lwpinfo *pls)
+{
+
+	pld->pl_lwpid = pls->pl_lwpid;
+	pld->pl_event = pls->pl_event;
+	pld->pl_flags = pls->pl_flags;
+	pld->pl_sigmask = pls->pl_sigmask;
+	pld->pl_siglist = pls->pl_siglist;
+	elf_convert_siginfo(&pld->pl_siginfo, &pls->pl_siginfo);
+	memcpy(pld->pl_tdname, pls->pl_tdname, sizeof(pld->pl_tdname));
+	pld->pl_child_pid = pls->pl_child_pid;
+	pld->pl_syscall_code = pls->pl_syscall_code;
+	pld->pl_syscall_narg = pls->pl_syscall_narg;
+}
+

Modified: head/usr.bin/gcore/elfcore.c
==============================================================================
--- head/usr.bin/gcore/elfcore.c	Thu Jun 29 19:43:27 2017	(r320480)
+++ head/usr.bin/gcore/elfcore.c	Thu Jun 29 21:31:13 2017	(r320481)
@@ -81,15 +81,20 @@ typedef struct fpreg32 elfcore_fpregset_t;
 typedef struct reg32   elfcore_gregset_t;
 typedef struct prpsinfo32 elfcore_prpsinfo_t;
 typedef struct prstatus32 elfcore_prstatus_t;
+typedef struct ptrace_lwpinfo32 elfcore_lwpinfo_t;
 static void elf_convert_gregset(elfcore_gregset_t *rd, struct reg *rs);
 static void elf_convert_fpregset(elfcore_fpregset_t *rd, struct fpreg *rs);
+static void elf_convert_lwpinfo(struct ptrace_lwpinfo32 *pld,
+    struct ptrace_lwpinfo *pls);
 #else
 typedef fpregset_t elfcore_fpregset_t;
 typedef gregset_t  elfcore_gregset_t;
 typedef prpsinfo_t elfcore_prpsinfo_t;
 typedef prstatus_t elfcore_prstatus_t;
+typedef struct ptrace_lwpinfo elfcore_lwpinfo_t;
 #define elf_convert_gregset(d,s)	*d = *s
 #define elf_convert_fpregset(d,s)	*d = *s
+#define	elf_convert_lwpinfo(d,s)	*d = *s
 #endif
 
 typedef void* (*notefunc_t)(void *, size_t *);
@@ -696,15 +701,18 @@ static void *
 elf_note_ptlwpinfo(void *arg, size_t *sizep)
 {
 	lwpid_t tid;
+	elfcore_lwpinfo_t *elf_info;
+	struct ptrace_lwpinfo lwpinfo;
 	void *p;
 
 	tid = *(lwpid_t *)arg;
-	p = calloc(1, sizeof(int) + sizeof(struct ptrace_lwpinfo));
+	p = calloc(1, sizeof(int) + sizeof(elfcore_lwpinfo_t));
 	if (p == NULL)
 		errx(1, "out of memory");
-	*(int *)p = sizeof(struct ptrace_lwpinfo);
-	ptrace(PT_LWPINFO, tid,
-	    (char *)p + sizeof (int), sizeof(struct ptrace_lwpinfo));
+	*(int *)p = sizeof(elfcore_lwpinfo_t);
+	elf_info = (void *)((int *)p + 1);
+	ptrace(PT_LWPINFO, tid, (void *)&lwpinfo, sizeof(lwpinfo));
+	elf_convert_lwpinfo(elf_info, &lwpinfo);
 
 	*sizep = sizeof(int) + sizeof(struct ptrace_lwpinfo);
 	return (p);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201706292131.v5TLVEcF018300>