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);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to