[Midnightbsd-cvs] src [11261] trunk/usr.bin/gcore: update

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Tue Jul 3 19:51:35 EDT 2018


Revision: 11261
          http://svnweb.midnightbsd.org/src/?rev=11261
Author:   laffer1
Date:     2018-07-03 19:51:34 -0400 (Tue, 03 Jul 2018)
Log Message:
-----------
update

Modified Paths:
--------------
    trunk/usr.bin/gcore/Makefile
    trunk/usr.bin/gcore/elfcore.c

Modified: trunk/usr.bin/gcore/Makefile
===================================================================
--- trunk/usr.bin/gcore/Makefile	2018-07-03 23:50:30 UTC (rev 11260)
+++ trunk/usr.bin/gcore/Makefile	2018-07-03 23:51:34 UTC (rev 11261)
@@ -1,5 +1,6 @@
+# $MidnightBSD$
 #	@(#)Makefile	8.1 (Berkeley) 6/6/93
-# $MidnightBSD$
+# $FreeBSD: stable/10/usr.bin/gcore/Makefile 283909 2015-06-02 13:07:22Z jhb $
 
 PROG=	gcore
 SRCS=	elfcore.c gcore.c
@@ -6,6 +7,10 @@
 DPADD=	${LIBSBUF} ${LIBUTIL}
 LDADD=	-lsbuf -lutil
 
+.if ${MACHINE_ARCH} == "amd64"
+SRCS+=	elf32core.c
+.endif
+
 WARNS?=	1
 
 .include <bsd.prog.mk>

Modified: trunk/usr.bin/gcore/elfcore.c
===================================================================
--- trunk/usr.bin/gcore/elfcore.c	2018-07-03 23:50:30 UTC (rev 11260)
+++ trunk/usr.bin/gcore/elfcore.c	2018-07-03 23:51:34 UTC (rev 11261)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2007 Sandvine Incorporated
  * Copyright (c) 1998 John D. Polstra
@@ -26,8 +27,9 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/gcore/elfcore.c 318192 2017-05-11 17:26:34Z jhb $");
 
+#include <sys/endian.h>
 #include <sys/param.h>
 #include <sys/procfs.h>
 #include <sys/ptrace.h>
@@ -46,6 +48,7 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -73,6 +76,22 @@
 	size_t size;		/* Total size of all writable segments. */
 };
 
+#ifdef ELFCORE_COMPAT_32
+typedef struct fpreg32 elfcore_fpregset_t;
+typedef struct reg32   elfcore_gregset_t;
+typedef struct prpsinfo32 elfcore_prpsinfo_t;
+typedef struct prstatus32 elfcore_prstatus_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);
+#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;
+#define elf_convert_gregset(d,s)	*d = *s
+#define elf_convert_fpregset(d,s)	*d = *s
+#endif
+
 typedef void* (*notefunc_t)(void *, size_t *);
 
 static void cb_put_phdr(vm_map_entry_t, void *);
@@ -84,6 +103,9 @@
 static void *elf_note_prpsinfo(void *, size_t *);
 static void *elf_note_prstatus(void *, size_t *);
 static void *elf_note_thrmisc(void *, size_t *);
+#if defined(__i386__) || defined(__amd64__)
+static void *elf_note_x86_xstate(void *, size_t *);
+#endif
 static void *elf_note_procstat_auxv(void *, size_t *);
 static void *elf_note_procstat_files(void *, size_t *);
 static void *elf_note_procstat_groups(void *, size_t *);
@@ -93,8 +115,8 @@
 static void *elf_note_procstat_rlimit(void *, size_t *);
 static void *elf_note_procstat_umask(void *, size_t *);
 static void *elf_note_procstat_vmmap(void *, size_t *);
-static void elf_puthdr(pid_t, vm_map_entry_t, void *, size_t, size_t, size_t,
-    int);
+static void elf_puthdr(int, pid_t, vm_map_entry_t, void *, size_t, size_t,
+    size_t, int);
 static void elf_putnote(int, notefunc_t, void *, struct sbuf *);
 static void elf_putnotes(pid_t, struct sbuf *, size_t *);
 static void freemap(vm_map_entry_t);
@@ -102,6 +124,7 @@
 static void *procstat_sysctl(void *, int, size_t, size_t *sizep);
 
 static pid_t g_pid;		/* Pid being dumped, global for elf_detach */
+static int g_status;		/* proc status after ptrace attach */
 
 static int
 elf_ident(int efd, pid_t pid __unused, char *binfile __unused)
@@ -108,21 +131,45 @@
 {
 	Elf_Ehdr hdr;
 	int cnt;
+	uint16_t machine;
 
 	cnt = read(efd, &hdr, sizeof(hdr));
 	if (cnt != sizeof(hdr))
 		return (0);
-	if (IS_ELF(hdr))
-		return (1);
-	return (0);
+	if (!IS_ELF(hdr))
+		return (0);
+	switch (hdr.e_ident[EI_DATA]) {
+	case ELFDATA2LSB:
+		machine = le16toh(hdr.e_machine);
+		break;
+	case ELFDATA2MSB:
+		machine = be16toh(hdr.e_machine);
+		break;
+	default:
+		return (0);
+	}
+	if (!ELF_MACHINE_OK(machine))
+		return (0);
+
+	/* Looks good. */
+	return (1);
 }
 
 static void
 elf_detach(void)
 {
+	int sig;
 
-	if (g_pid != 0)
-		ptrace(PT_DETACH, g_pid, (caddr_t)1, 0);
+	if (g_pid != 0) {
+		/*
+		 * Forward any pending signals. SIGSTOP is generated by ptrace
+		 * itself, so ignore it.
+		 */
+		sig = WIFSTOPPED(g_status) ? WSTOPSIG(g_status) : 0;
+		if (sig == SIGSTOP)
+			sig = 0;
+		ptrace(PT_DETACH, g_pid, (caddr_t)1, sig);
+	}
 }
 
 /*
@@ -129,7 +176,7 @@
  * Write an ELF coredump for the given pid to the given fd.
  */
 static void
-elf_coredump(int efd __unused, int fd, pid_t pid)
+elf_coredump(int efd, int fd, pid_t pid)
 {
 	vm_map_entry_t map;
 	struct sseg_closure seginfo;
@@ -148,7 +195,7 @@
 	ptrace(PT_ATTACH, pid, NULL, 0);
 	if (errno)
 		err(1, "PT_ATTACH");
-	if (waitpid(pid, NULL, 0) == -1)
+	if (waitpid(pid, &g_status, 0) == -1)
 		err(1, "waitpid");
 
 	/* Get the program's memory map. */
@@ -179,7 +226,7 @@
 	hdr = sbuf_data(sb);
 	segoff = sbuf_len(sb);
 	/* Fill in the header. */
-	elf_puthdr(pid, map, hdr, hdrsize, notesz, segoff, seginfo.count);
+	elf_puthdr(efd, pid, map, hdr, hdrsize, notesz, segoff, seginfo.count);
 
 	n = write(fd, hdr, segoff);
 	if (n == -1)
@@ -194,7 +241,7 @@
 		uintmax_t nleft = php->p_filesz;
 
 		iorequest.piod_op = PIOD_READ_D;
-		iorequest.piod_offs = (caddr_t)php->p_vaddr;
+		iorequest.piod_offs = (caddr_t)(uintptr_t)php->p_vaddr;
 		while (nleft > 0) {
 			char buf[8*1024];
 			size_t nwant;
@@ -309,8 +356,12 @@
 		elf_putnote(NT_PRSTATUS, elf_note_prstatus, tids + i, sb);
 		elf_putnote(NT_FPREGSET, elf_note_fpregset, tids + i, sb);
 		elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb);
+#if defined(__i386__) || defined(__amd64__)
+		elf_putnote(NT_X86_XSTATE, elf_note_x86_xstate, tids + i, sb);
+#endif
 	}
 
+#ifndef ELFCORE_COMPAT_32
 	elf_putnote(NT_PROCSTAT_PROC, elf_note_procstat_proc, &pid, sb);
 	elf_putnote(NT_PROCSTAT_FILES, elf_note_procstat_files, &pid, sb);
 	elf_putnote(NT_PROCSTAT_VMMAP, elf_note_procstat_vmmap, &pid, sb);
@@ -321,6 +372,7 @@
 	elf_putnote(NT_PROCSTAT_PSSTRINGS, elf_note_procstat_psstrings, &pid,
 	    sb);
 	elf_putnote(NT_PROCSTAT_AUXV, elf_note_procstat_auxv, &pid, sb);
+#endif
 
 	size = sbuf_end_section(sb, old_len, 1, 0);
 	if (size == -1)
@@ -361,13 +413,20 @@
  * Generate the ELF coredump header.
  */
 static void
-elf_puthdr(pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize,
+elf_puthdr(int efd, pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize,
     size_t notesz, size_t segoff, int numsegs)
 {
-	Elf_Ehdr *ehdr;
+	Elf_Ehdr *ehdr, binhdr;
 	Elf_Phdr *phdr;
 	struct phdr_closure phc;
+	ssize_t cnt;
 
+	cnt = read(efd, &binhdr, sizeof(binhdr));
+	if (cnt < 0)
+		err(1, "Failed to re-read ELF header");
+	else if (cnt != sizeof(binhdr))
+		errx(1, "Failed to re-read ELF header");
+
 	ehdr = (Elf_Ehdr *)hdr;
 	phdr = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr));
 
@@ -382,11 +441,11 @@
 	ehdr->e_ident[EI_ABIVERSION] = 0;
 	ehdr->e_ident[EI_PAD] = 0;
 	ehdr->e_type = ET_CORE;
-	ehdr->e_machine = ELF_ARCH;
+	ehdr->e_machine = binhdr.e_machine;
 	ehdr->e_version = EV_CURRENT;
 	ehdr->e_entry = 0;
 	ehdr->e_phoff = sizeof(Elf_Ehdr);
-	ehdr->e_flags = 0;
+	ehdr->e_flags = binhdr.e_flags;
 	ehdr->e_ehsize = sizeof(Elf_Ehdr);
 	ehdr->e_phentsize = sizeof(Elf_Phdr);
 	ehdr->e_phnum = numsegs + 1;
@@ -464,7 +523,8 @@
 		    ((pflags & PFLAGS_FULL) == 0 &&
 		    kve->kve_type != KVME_TYPE_DEFAULT &&
 		    kve->kve_type != KVME_TYPE_VNODE &&
-		    kve->kve_type != KVME_TYPE_SWAP))
+		    kve->kve_type != KVME_TYPE_SWAP &&
+		    kve->kve_type != KVME_TYPE_PHYS))
 			continue;
 
 		ent = calloc(1, sizeof(*ent));
@@ -490,8 +550,9 @@
 static void *
 elf_note_prpsinfo(void *arg, size_t *sizep)
 {
+	char *cp, *end;
 	pid_t pid;
-	prpsinfo_t *psinfo;
+	elfcore_prpsinfo_t *psinfo;
 	struct kinfo_proc kip;
 	size_t len;
 	int name[4];
@@ -501,7 +562,7 @@
 	if (psinfo == NULL)
 		errx(1, "out of memory");
 	psinfo->pr_version = PRPSINFO_VERSION;
-	psinfo->pr_psinfosz = sizeof(prpsinfo_t);
+	psinfo->pr_psinfosz = sizeof(*psinfo);
 
 	name[0] = CTL_KERN;
 	name[1] = KERN_PROC;
@@ -512,8 +573,22 @@
 		err(1, "kern.proc.pid.%u", pid);
 	if (kip.ki_pid != pid)
 		err(1, "kern.proc.pid.%u", pid);
-	strncpy(psinfo->pr_fname, kip.ki_comm, MAXCOMLEN);
-	strncpy(psinfo->pr_psargs, psinfo->pr_fname, PRARGSZ);
+	strlcpy(psinfo->pr_fname, kip.ki_comm, sizeof(psinfo->pr_fname));
+	name[2] = KERN_PROC_ARGS;
+	len = sizeof(psinfo->pr_psargs) - 1;
+	if (sysctl(name, 4, psinfo->pr_psargs, &len, NULL, 0) == 0 && len > 0) {
+		cp = psinfo->pr_psargs;
+		end = cp + len - 1;
+		for (;;) {
+			cp = memchr(cp, '\0', end - cp);
+			if (cp == NULL)
+				break;
+			*cp = ' ';
+		}
+	} else
+		strlcpy(psinfo->pr_psargs, kip.ki_comm,
+		    sizeof(psinfo->pr_psargs));
+	psinfo->pr_pid = pid;
 
 	*sizep = sizeof(*psinfo);
 	return (psinfo);
@@ -523,7 +598,8 @@
 elf_note_prstatus(void *arg, size_t *sizep)
 {
 	lwpid_t tid;
-	prstatus_t *status;
+	elfcore_prstatus_t *status;
+	struct reg greg;
 
 	tid = *(lwpid_t *)arg;
 	status = calloc(1, sizeof(*status));
@@ -530,12 +606,13 @@
 	if (status == NULL)
 		errx(1, "out of memory");
 	status->pr_version = PRSTATUS_VERSION;
-	status->pr_statussz = sizeof(prstatus_t);
-	status->pr_gregsetsz = sizeof(gregset_t);
-	status->pr_fpregsetsz = sizeof(fpregset_t);
+	status->pr_statussz = sizeof(*status);
+	status->pr_gregsetsz = sizeof(elfcore_gregset_t);
+	status->pr_fpregsetsz = sizeof(elfcore_fpregset_t);
 	status->pr_osreldate = __FreeBSD_version;
 	status->pr_pid = tid;
-	ptrace(PT_GETREGS, tid, (void *)&status->pr_reg, 0);
+	ptrace(PT_GETREGS, tid, (void *)&greg, 0);
+	elf_convert_gregset(&status->pr_reg, &greg);
 
 	*sizep = sizeof(*status);
 	return (status);
@@ -545,13 +622,15 @@
 elf_note_fpregset(void *arg, size_t *sizep)
 {
 	lwpid_t tid;
-	prfpregset_t *fpregset;
+	elfcore_fpregset_t *fpregset;
+	fpregset_t fpreg;
 
 	tid = *(lwpid_t *)arg;
 	fpregset = calloc(1, sizeof(*fpregset));
 	if (fpregset == NULL)
 		errx(1, "out of memory");
-	ptrace(PT_GETFPREGS, tid, (void *)fpregset, 0);
+	ptrace(PT_GETFPREGS, tid, (void *)&fpreg, 0);
+	elf_convert_fpregset(fpregset, &fpreg);
 
 	*sizep = sizeof(*fpregset);
 	return (fpregset);
@@ -577,7 +656,35 @@
 	return (thrmisc);
 }
 
+#if defined(__i386__) || defined(__amd64__)
 static void *
+elf_note_x86_xstate(void *arg, size_t *sizep)
+{
+	lwpid_t tid;
+	char *xstate;
+	static bool xsave_checked = false;
+	static struct ptrace_xstate_info info;
+
+	tid = *(lwpid_t *)arg;
+	if (!xsave_checked) {
+		if (ptrace(PT_GETXSTATE_INFO, tid, (void *)&info,
+		    sizeof(info)) != 0)
+			info.xsave_len = 0;
+		xsave_checked = true;
+	}
+	if (info.xsave_len == 0) {
+		*sizep = 0;
+		return (NULL);
+	}
+	xstate = calloc(1, info.xsave_len);
+	ptrace(PT_GETXSTATE, tid, xstate, 0);
+	*(uint64_t *)(xstate + X86_XSTATE_XCR0_OFFSET) = info.xsave_mask;
+	*sizep = info.xsave_len;
+	return (xstate);
+}
+#endif
+
+static void *
 procstat_sysctl(void *arg, int what, size_t structsz, size_t *sizep)
 {
 	size_t len, oldlen;
@@ -700,5 +807,5 @@
 	return (buf);
 }
 
-struct dumpers elfdump = { elf_ident, elf_coredump };
-TEXT_SET(dumpset, elfdump);
+struct dumpers __elfN(dump) = { elf_ident, elf_coredump };
+TEXT_SET(dumpset, __elfN(dump));



More information about the Midnightbsd-cvs mailing list