[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