Date: Tue, 2 Jun 2015 13:07:23 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r283909 - stable/10/usr.bin/gcore Message-ID: <201506021307.t52D7Nun006291@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Tue Jun 2 13:07:22 2015 New Revision: 283909 URL: https://svnweb.freebsd.org/changeset/base/283909 Log: MFC 269128: Create 32-bit core files for 32-bit processes on 64-bit machines. The 64-bit machine supported right now is amd64, but it's not too hard to add powerpc64. Added: stable/10/usr.bin/gcore/elf32core.c - copied unchanged from r269128, head/usr.bin/gcore/elf32core.c Modified: stable/10/usr.bin/gcore/Makefile stable/10/usr.bin/gcore/elfcore.c Directory Properties: stable/10/ (props changed) Modified: stable/10/usr.bin/gcore/Makefile ============================================================================== --- stable/10/usr.bin/gcore/Makefile Tue Jun 2 09:42:00 2015 (r283908) +++ stable/10/usr.bin/gcore/Makefile Tue Jun 2 13:07:22 2015 (r283909) @@ -6,6 +6,10 @@ SRCS= elfcore.c gcore.c DPADD= ${LIBSBUF} ${LIBUTIL} LDADD= -lsbuf -lutil +.if ${MACHINE_ARCH} == "amd64" +SRCS+= elf32core.c +.endif + WARNS?= 1 .include <bsd.prog.mk> Copied: stable/10/usr.bin/gcore/elf32core.c (from r269128, head/usr.bin/gcore/elf32core.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/usr.bin/gcore/elf32core.c Tue Jun 2 13:07:22 2015 (r283909, copy of r269128, head/usr.bin/gcore/elf32core.c) @@ -0,0 +1,66 @@ +/* $FreeBSD$ */ +#ifndef __LP64__ +#error "this file must be compiled for LP64." +#endif + +#define __ELF_WORD_SIZE 32 +#define _MACHINE_ELF_WANT_32BIT + +#include <sys/procfs.h> + +struct prpsinfo32 { + int pr_version; + u_int pr_psinfosz; + char pr_fname[PRFNAMESZ+1]; + char pr_psargs[PRARGSZ+1]; +}; + +struct prstatus32 { + int pr_version; + u_int pr_statussz; + u_int pr_gregsetsz; + u_int pr_fpregsetsz; + int pr_osreldate; + int pr_cursig; + pid_t pr_pid; + struct reg32 pr_reg; +}; + +#define ELFCORE_COMPAT_32 1 +#include "elfcore.c" + +static void +elf_convert_gregset(elfcore_gregset_t *rd, struct reg *rs) +{ +#ifdef __amd64__ + rd->r_gs = rs->r_gs; + rd->r_fs = rs->r_fs; + rd->r_es = rs->r_es; + rd->r_ds = rs->r_ds; + rd->r_edi = rs->r_rdi; + rd->r_esi = rs->r_rsi; + rd->r_ebp = rs->r_rbp; + rd->r_ebx = rs->r_rbx; + rd->r_edx = rs->r_rdx; + rd->r_ecx = rs->r_rcx; + rd->r_eax = rs->r_rax; + rd->r_eip = rs->r_rip; + rd->r_cs = rs->r_cs; + rd->r_eflags = rs->r_rflags; + rd->r_esp = rs->r_rsp; + rd->r_ss = rs->r_ss; +#else +#error Unsupported architecture +#endif +} + +static void +elf_convert_fpregset(elfcore_fpregset_t *rd, struct fpreg *rs) +{ +#ifdef __amd64__ + /* XXX this is wrong... */ + memcpy(rd, rs, sizeof(*rd)); +#else +#error Unsupported architecture +#endif +} Modified: stable/10/usr.bin/gcore/elfcore.c ============================================================================== --- stable/10/usr.bin/gcore/elfcore.c Tue Jun 2 09:42:00 2015 (r283908) +++ stable/10/usr.bin/gcore/elfcore.c Tue Jun 2 13:07:22 2015 (r283909) @@ -28,6 +28,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/endian.h> #include <sys/param.h> #include <sys/procfs.h> #include <sys/ptrace.h> @@ -74,6 +75,22 @@ struct sseg_closure { 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 *); @@ -112,13 +129,28 @@ elf_ident(int efd, pid_t pid __unused, c { 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 @@ -198,7 +230,7 @@ elf_coredump(int efd __unused, int fd, p 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; @@ -318,6 +350,7 @@ elf_putnotes(pid_t pid, struct sbuf *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); @@ -328,6 +361,7 @@ elf_putnotes(pid_t pid, struct sbuf *sb, 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) @@ -499,7 +533,7 @@ static void * elf_note_prpsinfo(void *arg, size_t *sizep) { pid_t pid; - prpsinfo_t *psinfo; + elfcore_prpsinfo_t *psinfo; struct kinfo_proc kip; size_t len; int name[4]; @@ -509,7 +543,7 @@ elf_note_prpsinfo(void *arg, size_t *siz 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; @@ -531,19 +565,21 @@ static void * 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)); 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); @@ -553,13 +589,15 @@ static void * 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); @@ -736,5 +774,5 @@ elf_note_procstat_rlimit(void *arg, size 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));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506021307.t52D7Nun006291>