Subject: Kernel support for ELF-format core files
To: None <tech-kern@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-kern
Date: 12/07/2001 17:16:40
--tThc/1wpZn/ma/RB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
The attached patch implements support for dumping ELF-format core files.
ELF format core dumps basically are comprised of several PT_LOAD sections
(one for each chunk of the process's address space represented in the
core file) and a PT_NOTE section that contains other various bits of
information.
I had to invent a format for the notes in our ELF-format files, mostly
because the existing practice in Solaris and Linux wasn't flexible
enough to do what I wanted to do.
The goals of these changes are the following:
* Support for processes with multiple LWPs. This is
something that has to be supported for the nathanw_sa
branch (and the associated pthreads library).
* Support for arbitrary extended register sets. This includes
SSE/SSE2 on the x86, and AltiVec on the PowerPC.
The notes in the PT_NOTE section have the following names:
* "NetBSD-CORE" for each note that applies to the entire
process (e.g. a procinfo note).
* "NetBSD-CORE@nn" (where nn is the lwpid of the LWP) for
notes that apply only to the specified LWP (e.g. register
contents). Since the kernel on the trunk doesn't yet support
LWPs, these currently just look like "NetBSD-CORE@0".
The notes in the PT_NOTE section have the following types and contents:
* ELF_NOTE_NETBSD_CORE_PROCINFO (value 1). The definition of
this structure is in the patch (obviously). The structure
uses fixed-size types and is versioned for future expandability.
* Machine-dependent note types. These have the value of
the ptrace(2) request that would fetch the data that the
note contains, e.g. PT_GETREGS or PT_GETFPREGS. I chose
these values because once they're selected for ptrace(2),
they're set in stone (for ABI compatibility), and they
happen to describe exactly what the note contains.
I have also updated BFD (bfd/elf.c) and GDB (gdb/i386nbsd-nat.c) to
support the new core file format. Additional target support in GDB
will be trivial, since it's just a matter of adding a little bit
of glue code. I will post my changes to the toolchain to tech-toolchain
separately.
--
-- Jason R. Thorpe <thorpej@wasabisystems.com>
--tThc/1wpZn/ma/RB
Content-Type: text/plain; charset=us-ascii
Content-Description: elfcore.diff
Content-Disposition: attachment; filename="elfcore.diff"
Index: arch/alpha/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/alpha/include/elf_machdep.h,v
retrieving revision 1.9
diff -c -r1.9 elf_machdep.h
*** arch/alpha/include/elf_machdep.h 2001/11/01 12:54:35 1.9
--- arch/alpha/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 22,27 ****
--- 22,29 ----
case EM_ALPHA_EXP: \
break;
+ #define ELF64_MACHDEP_ID EM_ALPHA_EXP /* XXX */
+
#define ARCH_ELFSIZE 64 /* MD native binary size */
/*
Index: arch/arm/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/arm/include/elf_machdep.h,v
retrieving revision 1.2
diff -c -r1.2 elf_machdep.h
*** arch/arm/include/elf_machdep.h 2001/01/18 23:50:50 1.2
--- arch/arm/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 22,27 ****
--- 22,29 ----
case EM_ARM: \
break;
+ #define ELF32_MACHDEP_ID EM_ARM
+
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* Processor specific relocation types */
Index: arch/i386/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/include/elf_machdep.h,v
retrieving revision 1.8
diff -c -r1.8 elf_machdep.h
*** arch/i386/include/elf_machdep.h 2000/04/02 15:35:49 1.8
--- arch/i386/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 10,15 ****
--- 10,17 ----
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
+ #define ELF32_MACHDEP_ID EM_386
+
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* i386 relocations */
Index: arch/m68k/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/m68k/include/elf_machdep.h,v
retrieving revision 1.5
diff -c -r1.5 elf_machdep.h
*** arch/m68k/include/elf_machdep.h 2000/04/02 15:35:49 1.5
--- arch/m68k/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 9,14 ****
--- 9,16 ----
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
+ #define ELF32_MACHDEP_ID EM_68K
+
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* m68k relocation types */
Index: arch/mips/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/include/elf_machdep.h,v
retrieving revision 1.7
diff -c -r1.7 elf_machdep.h
*** arch/mips/include/elf_machdep.h 2000/04/02 15:35:50 1.7
--- arch/mips/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 8,13 ****
--- 8,16 ----
/* no 64-bit ELF machine types supported */
+ #define ELF32_MACHDEP_ID EM_MIPS
+ #define ELF64_MACHDEP_ID EM_MIPS
+
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* mips relocs. */
Index: arch/powerpc/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/powerpc/include/elf_machdep.h,v
retrieving revision 1.4
diff -c -r1.4 elf_machdep.h
*** arch/powerpc/include/elf_machdep.h 2000/04/02 15:35:50 1.4
--- arch/powerpc/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 9,14 ****
--- 9,16 ----
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
+ #define ELF32_MACHDEP_ID EM_PPC
+
#define ARCH_ELFSIZE 32 /* MD native binary size */
#include <machine/reloc.h> /* XXX */
Index: arch/sh3/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sh3/include/elf_machdep.h,v
retrieving revision 1.4
diff -c -r1.4 elf_machdep.h
*** arch/sh3/include/elf_machdep.h 2001/03/29 03:23:33 1.4
--- arch/sh3/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 17,20 ****
--- 17,22 ----
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
+ #define ELF32_MACHDEP_ID EM_SH
+
#define ARCH_ELFSIZE 32 /* MD native binary size */
Index: arch/sparc/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc/include/elf_machdep.h,v
retrieving revision 1.5
diff -c -r1.5 elf_machdep.h
*** arch/sparc/include/elf_machdep.h 2000/04/02 15:35:50 1.5
--- arch/sparc/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 12,17 ****
--- 12,19 ----
case EM_SPARCV9: \
/* no 64-bit ELF machine types supported */
+ #define ELF32_MACHDEP_ID EM_SPARC /* XXX right? */
+
#define ARCH_ELFSIZE 32 /* MD native binary size */
#define R_SPARC_NONE 0
Index: arch/sparc64/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sparc64/include/elf_machdep.h,v
retrieving revision 1.7
diff -c -r1.7 elf_machdep.h
*** arch/sparc64/include/elf_machdep.h 2001/02/11 00:18:49 1.7
--- arch/sparc64/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 12,17 ****
--- 12,20 ----
case EM_SPARCV9: \
break;
+ #define ELF32_MACHDEP_ID EM_SPARC32PLUS /* XXX right? */
+ #define ELF64_MACHDEP_ID EM_SPARCV9 /* XXX right? */
+
#ifdef __arch64__
#define ARCH_ELFSIZE 64 /* MD native binary size */
#else
Index: arch/sun2/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/sun2/include/elf_machdep.h,v
retrieving revision 1.2
diff -c -r1.2 elf_machdep.h
*** arch/sun2/include/elf_machdep.h 2001/06/27 19:20:22 1.2
--- arch/sun2/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 10,13 ****
--- 10,16 ----
case EM_68000: \
break;
+ #undef ELF32_MACHDEP_ID
+ #define ELF32_MACHDEP_ID EM_68000
+
#endif
Index: arch/vax/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/vax/include/elf_machdep.h,v
retrieving revision 1.4
diff -c -r1.4 elf_machdep.h
*** arch/vax/include/elf_machdep.h 2000/07/13 03:18:22 1.4
--- arch/vax/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 9,14 ****
--- 9,16 ----
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
+ #define ELF32_MACHDEP_ID EM_VAX
+
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* VAX relocations */
Index: arch/x86_64/include/elf_machdep.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/x86_64/include/elf_machdep.h,v
retrieving revision 1.2
diff -c -r1.2 elf_machdep.h
*** arch/x86_64/include/elf_machdep.h 2001/06/20 01:20:33 1.2
--- arch/x86_64/include/elf_machdep.h 2001/12/08 00:49:03
***************
*** 10,15 ****
--- 10,18 ----
case EM_X86_64: \
break;
+ #define ELF32_MACHDEP_ID EM_386
+ #define ELF64_MACHDEP_ID EM_X86_64
+
#define ARCH_ELFSIZE 64 /* MD native binary size */
/* x86-64 relocations */
Index: kern/core_elf32.c
===================================================================
RCS file: core_elf32.c
diff -N core_elf32.c
*** /dev/null Fri Dec 7 03:15:07 2001
--- core_elf32.c Sat Dec 8 02:49:04 2001
***************
*** 0 ****
--- 1,424 ----
+ /* $NetBSD$ */
+
+ /*
+ * Copyright (c) 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /*
+ * core_elf32.c/core_elf64.c: Support for the Elf32/Elf64 core file format.
+ */
+
+ #include <sys/cdefs.h>
+ __KERNEL_RCSID(1, "$NetBSD$");
+
+ /* If not included by core_elf64.c, ELFSIZE won't be defined. */
+ #ifndef ELFSIZE
+ #define ELFSIZE 32
+ #endif
+
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/proc.h>
+ #include <sys/vnode.h>
+ #include <sys/exec_elf.h>
+ #include <sys/ptrace.h>
+
+ #include <machine/reg.h>
+
+ #include <uvm/uvm.h>
+
+ int ELFNAMEEND(coredump_notes)(struct proc *, struct vnode *,
+ struct ucred *, int *, off_t);
+
+ #define ELFROUNDSIZE 4 /* XXX Should it be sizeof(Elf_Word)? */
+ #define elfround(x) roundup((x), ELFROUNDSIZE)
+
+ int
+ ELFNAMEEND(coredump)(struct proc *p, struct vnode *vp, struct ucred *cred)
+ {
+ Elf_Ehdr ehdr;
+ Elf_Phdr phdr;
+ struct vmspace *vm = p->p_vmspace;
+ struct vm_map *map = &vm->vm_map;
+ struct vm_map_entry *entry;
+ vaddr_t start, end, maxstack;
+ vsize_t size;
+ off_t offset, secoff, notestart, secstart;
+ int npsections, notesize, error;
+
+ maxstack = trunc_page(USRSTACK - ctob(vm->vm_ssize));
+
+ /*
+ * We have to make a total of 3 passes across the map:
+ *
+ * 1. Count the number of map entries (the number of
+ * PT_LOAD sections).
+ *
+ * 2. Write the P-section headers.
+ *
+ * 3. Write the P-sections.
+ */
+
+ /* Pass 1: count the entries. */
+ npsections = 0;
+ for (entry = map->header.next; entry != &map->header;
+ entry = entry->next) {
+ /* Should never happen for a user process. */
+ if (UVM_ET_ISSUBMAP(entry))
+ panic("coredump_elf: user process with submap?");
+
+ if (entry->start >= VM_MAXUSER_ADDRESS)
+ continue;
+
+ if (entry->start >= (vaddr_t)vm->vm_maxsaddr &&
+ entry->end <= maxstack)
+ continue;
+
+ npsections++;
+ }
+
+ /* Get the size of the notes. */
+ error = ELFNAMEEND(coredump_notes)(p, vp, cred, ¬esize, 0);
+ if (error)
+ return (error);
+
+ /* Count the PT_NOTE section. */
+ npsections++;
+
+ memcpy(ehdr.e_ident, ELFMAG, SELFMAG);
+ #if ELFSIZE == 32
+ ehdr.e_ident[EI_CLASS] = ELFCLASS32;
+ #elif ELFSIZE == 64
+ ehdr.e_ident[EI_CLASS] = ELFCLASS64;
+ #endif
+ ehdr.e_ident[EI_DATA] = ELFDEFNNAME(MACHDEP_ENDIANNESS);
+ ehdr.e_ident[EI_VERSION] = EV_CURRENT;
+
+ ehdr.e_type = ET_CORE;
+ /* XXX This should be the e_machine of the executable. */
+ ehdr.e_machine = ELFDEFNNAME(MACHDEP_ID);
+ ehdr.e_version = EV_CURRENT;
+ ehdr.e_entry = 0;
+ ehdr.e_phoff = sizeof(ehdr);
+ ehdr.e_shoff = 0;
+ ehdr.e_flags = 0;
+ ehdr.e_ehsize = sizeof(ehdr);
+ ehdr.e_phentsize = sizeof(Elf_Phdr);
+ ehdr.e_phnum = npsections;
+ ehdr.e_shentsize = 0;
+ ehdr.e_shnum = 0;
+ ehdr.e_shstrndx = 0;
+
+ /* Write out the ELF header. */
+ error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&ehdr,
+ (int)sizeof(ehdr), (off_t)0,
+ UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p);
+
+ offset = ehdr.e_phoff;
+ notestart = offset + (sizeof(phdr) * npsections);
+ secstart = round_page(notestart + notesize);
+
+ /*
+ * Now write the P-section headers.
+ */
+ secoff = secstart;
+ for (entry = map->header.next; entry != &map->header;
+ entry = entry->next) {
+ start = entry->start;
+ end = entry->end;
+
+ if (start >= VM_MAXUSER_ADDRESS)
+ continue;
+
+ if (end > VM_MAXUSER_ADDRESS)
+ end = VM_MAXUSER_ADDRESS;
+
+ if (start >= (vaddr_t)vm->vm_maxsaddr) {
+ if (end <= maxstack)
+ continue;
+ if (start < maxstack)
+ start = maxstack;
+ }
+
+ size = end - start;
+
+ phdr.p_type = PT_LOAD;
+ phdr.p_offset = secoff;
+ phdr.p_vaddr = start;
+ phdr.p_paddr = 0;
+ phdr.p_filesz = (entry->protection & VM_PROT_WRITE) ? size : 0;
+ phdr.p_memsz = size;
+ phdr.p_flags = 0;
+ if (entry->protection & VM_PROT_READ)
+ phdr.p_flags |= PF_R;
+ if (entry->protection & VM_PROT_WRITE)
+ phdr.p_flags |= PF_W;
+ if (entry->protection & VM_PROT_EXECUTE)
+ phdr.p_flags |= PF_X;
+ phdr.p_align = PAGE_SIZE;
+
+ error = vn_rdwr(UIO_WRITE, vp,
+ (caddr_t)&phdr, sizeof(phdr),
+ offset, UIO_SYSSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, NULL, p);
+ if (error)
+ return (error);
+
+ offset += sizeof(phdr);
+ secoff += phdr.p_filesz;
+ }
+
+ /* Write out the PT_NOTE header. */
+ phdr.p_type = PT_NOTE;
+ phdr.p_offset = notestart;
+ phdr.p_vaddr = 0;
+ phdr.p_paddr = 0;
+ phdr.p_filesz = notesize;
+ phdr.p_memsz = 0;
+ phdr.p_flags = PF_R;
+ phdr.p_align = ELFROUNDSIZE;
+
+ error = vn_rdwr(UIO_WRITE, vp,
+ (caddr_t)&phdr, sizeof(phdr),
+ offset, UIO_SYSSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, NULL, p);
+ if (error)
+ return (error);
+
+ offset += sizeof(phdr);
+
+ KASSERT(offset == notestart);
+
+ /* Write out the notes. */
+ error = ELFNAMEEND(coredump_notes)(p, vp, cred, ¬esize, offset);
+ if (error)
+ return (error);
+
+ offset += notesize;
+
+ /* ...and write out the sections. */
+ secoff = secstart;
+ for (entry = map->header.next; entry != &map->header;
+ entry = entry->next) {
+ start = entry->start;
+ end = entry->end;
+
+ if (start >= VM_MAXUSER_ADDRESS)
+ continue;
+
+ if (end > VM_MAXUSER_ADDRESS)
+ end = VM_MAXUSER_ADDRESS;
+
+ if (start >= (vaddr_t)vm->vm_maxsaddr) {
+ if (end <= maxstack)
+ continue;
+ if (start < maxstack)
+ start = maxstack;
+ }
+
+ size = end - start;
+
+ if ((entry->protection & VM_PROT_WRITE) == 0) {
+ /* Not actually written out. */
+ continue;
+ }
+
+ error = vn_rdwr(UIO_WRITE, vp,
+ (caddr_t)start, size,
+ secoff, UIO_USERSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, NULL, p);
+ if (error)
+ return (error);
+
+ secoff += size;
+ }
+
+ return (0);
+ }
+
+ int
+ ELFNAMEEND(coredump_notes)(struct proc *p, struct vnode *vp,
+ struct ucred *cred, int *sizep, off_t offset)
+ {
+ struct netbsd_elfcore_procinfo cpi;
+ Elf_Nhdr nhdr;
+ int size, notesize, error;
+ char name[64];
+ int namesize;
+ struct reg intreg;
+ #ifdef PT_GETFPREGS
+ struct fpreg freg;
+ #endif
+
+ size = 0;
+
+ /* First, write an elfcore_procinfo. */
+ notesize = sizeof(nhdr) + elfround(sizeof(ELF_NOTE_NETBSD_CORE_NAME)) +
+ elfround(sizeof(cpi));
+ if (offset) {
+ cpi.cpi_version = NETBSD_ELFCORE_PROCINFO_VERSION;
+ cpi.cpi_cpisize = sizeof(cpi);
+ cpi.cpi_signo = p->p_sigctx.ps_sig;
+ cpi.cpi_sigcode = p->p_sigctx.ps_code;
+
+ memcpy(&cpi.cpi_sigpend, &p->p_sigctx.ps_siglist,
+ sizeof(cpi.cpi_sigpend));
+ memcpy(&cpi.cpi_sigmask, &p->p_sigctx.ps_sigmask,
+ sizeof(cpi.cpi_sigmask));
+ memcpy(&cpi.cpi_sigignore, &p->p_sigctx.ps_sigignore,
+ sizeof(cpi.cpi_sigignore));
+ memcpy(&cpi.cpi_sigcatch, &p->p_sigctx.ps_sigcatch,
+ sizeof(cpi.cpi_sigcatch));
+
+ cpi.cpi_pid = p->p_pid;
+ cpi.cpi_ppid = p->p_pptr->p_pid;
+ cpi.cpi_pgrp = p->p_pgid;
+ cpi.cpi_sid = p->p_session->s_sid;
+
+ cpi.cpi_ruid = p->p_cred->p_ruid;
+ cpi.cpi_euid = p->p_ucred->cr_uid;
+ cpi.cpi_svuid = p->p_cred->p_svuid;
+
+ cpi.cpi_rgid = p->p_cred->p_rgid;
+ cpi.cpi_egid = p->p_ucred->cr_gid;
+ cpi.cpi_svgid = p->p_cred->p_svgid;
+
+ cpi.cpi_nlwps = 1; /* XXX for now */
+ strcpy(cpi.cpi_name, p->p_comm);
+
+ nhdr.n_namesz = sizeof(ELF_NOTE_NETBSD_CORE_NAME);
+ nhdr.n_descsz = sizeof(cpi);
+ nhdr.n_type = ELF_NOTE_NETBSD_CORE_PROCINFO;
+
+ error = ELFNAMEEND(coredump_writenote)(p, vp, cred, offset,
+ &nhdr, ELF_NOTE_NETBSD_CORE_NAME, &cpi);
+ if (error)
+ return (error);
+
+ offset += notesize;
+ }
+
+ size += notesize;
+
+ /* XXX Add hook for machdep per-proc notes. */
+
+ /*
+ * Now, for each LWP, write the register info and any other
+ * per-LWP notes.
+ */
+ do {
+ /* XXX Only one LWP for now. */
+ sprintf(name, "%s@%d", ELF_NOTE_NETBSD_CORE_NAME, 0);
+ namesize = strlen(name) + 1;
+
+ notesize = sizeof(nhdr) + elfround(namesize) +
+ elfround(sizeof(intreg));
+ if (offset) {
+ error = process_read_regs(p, &intreg);
+ if (error)
+ return (error);
+
+ nhdr.n_namesz = namesize;
+ nhdr.n_descsz = sizeof(intreg);
+ nhdr.n_type = PT_GETREGS;
+
+ error = ELFNAMEEND(coredump_writenote)(p, vp, cred,
+ offset, &nhdr, name, &intreg);
+ if (error)
+ return (error);
+
+ offset += notesize;
+ }
+ size += notesize;
+
+ #ifdef PT_GETFPREGS
+ notesize = sizeof(nhdr) + elfround(namesize) +
+ elfround(sizeof(freg));
+ if (offset) {
+ error = process_read_fpregs(p, &freg);
+ if (error)
+ return (error);
+
+ nhdr.n_namesz = namesize;
+ nhdr.n_descsz = sizeof(freg);
+ nhdr.n_type = PT_GETFPREGS;
+
+ error = ELFNAMEEND(coredump_writenote)(p, vp, cred,
+ offset, &nhdr, name, &freg);
+ if (error)
+ return (error);
+
+ offset += notesize;
+ }
+ size += notesize;
+ #endif
+ /* XXX Add hook for machdep per-LWP notes. */
+ } while (/*CONSTCOND*/0);
+
+ *sizep = size;
+ return (0);
+ }
+
+ int
+ ELFNAMEEND(coredump_writenote)(struct proc *p, struct vnode *vp,
+ struct ucred *cred, off_t offset, Elf_Nhdr *nhdr, const char *name,
+ void *data)
+ {
+ int error;
+
+ error = vn_rdwr(UIO_WRITE, vp,
+ (caddr_t) nhdr, sizeof(*nhdr),
+ offset, UIO_SYSSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, NULL, p);
+ if (error)
+ return (error);
+
+ offset += sizeof(*nhdr);
+
+ error = vn_rdwr(UIO_WRITE, vp,
+ (caddr_t)name, nhdr->n_namesz,
+ offset, UIO_SYSSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, NULL, p);
+ if (error)
+ return (error);
+
+ offset += elfround(nhdr->n_namesz);
+
+ error = vn_rdwr(UIO_WRITE, vp,
+ data, nhdr->n_descsz,
+ offset, UIO_SYSSPACE,
+ IO_NODELOCKED|IO_UNIT, cred, NULL, p);
+
+ return (error);
+ }
Index: kern/core_elf64.c
===================================================================
RCS file: core_elf64.c
diff -N core_elf64.c
*** /dev/null Fri Dec 7 03:15:07 2001
--- core_elf64.c Sat Dec 8 02:49:04 2001
***************
*** 0 ****
--- 1,43 ----
+ /* $NetBSD$ */
+
+ /*
+ * Copyright (c) 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ #include <sys/cdefs.h>
+ __KERNEL_RCSID(0, "$NetBSD$");
+
+ #define ELFSIZE 64
+
+ #include "core_elf32.c"
Index: sys/exec_elf.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/exec_elf.h,v
retrieving revision 1.58
diff -c -r1.58 exec_elf.h
*** sys/exec_elf.h 2001/10/31 18:05:35 1.58
--- sys/exec_elf.h 2001/12/08 00:49:05
***************
*** 650,655 ****
--- 650,709 ----
/* NetBSD-specific note name */
#define ELF_NOTE_NETBSD_NAME "NetBSD\0\0"
+ /*
+ * NetBSD-specific core file information.
+ *
+ * NetBSD ELF core files use notes to provide information about
+ * the process's state. The note name is "NetBSD-CORE" for
+ * information that is global to the process, and "NetBSD-CORE@nn",
+ * where "nn" is the lwpid of the LWP that the information belongs
+ * to (such as register state).
+ *
+ * We use the following note identifiers:
+ *
+ * ELF_NOTE_NETBSD_CORE_PROCINFO
+ * Note is a "netbsd_elfcore_procinfo" structure.
+ *
+ * We also use ptrace(2) request numbers (the ones that exist in
+ * machine-dependent space) to identify register info notes. The
+ * info in such notes is in the same format that ptrace(2) would
+ * export that information.
+ *
+ * Please try to keep the members of this structure nicely aligned,
+ * and if you add elements, add them to the end and bump the version.
+ */
+
+ #define ELF_NOTE_NETBSD_CORE_NAME "NetBSD-CORE"
+
+ #define ELF_NOTE_NETBSD_CORE_PROCINFO 1
+
+ #define NETBSD_ELFCORE_PROCINFO_VERSION 1
+
+ struct netbsd_elfcore_procinfo {
+ /* Version 1 fields start here. */
+ uint32_t cpi_version; /* netbsd_elfcore_procinfo version */
+ uint32_t cpi_cpisize; /* sizeof(netbsd_elfcore_procinfo) */
+ uint32_t cpi_signo; /* killing signal */
+ uint32_t cpi_sigcode; /* signal code */
+ uint32_t cpi_sigpend[4]; /* pending signals */
+ uint32_t cpi_sigmask[4]; /* blocked signals */
+ uint32_t cpi_sigignore[4];/* blocked signals */
+ uint32_t cpi_sigcatch[4];/* blocked signals */
+ int32_t cpi_pid; /* process ID */
+ int32_t cpi_ppid; /* parent process ID */
+ int32_t cpi_pgrp; /* process group ID */
+ int32_t cpi_sid; /* session ID */
+ uint32_t cpi_ruid; /* real user ID */
+ uint32_t cpi_euid; /* effective user ID */
+ uint32_t cpi_svuid; /* saved user ID */
+ uint32_t cpi_rgid; /* real group ID */
+ uint32_t cpi_egid; /* effective group ID */
+ uint32_t cpi_svgid; /* saved group ID */
+ uint32_t cpi_nlwps; /* number of LWPs */
+ int8_t cpi_name[32]; /* copy of p->p_comm */
+ /* Add version 2 fields below here. */
+ };
+
#if defined(ELFSIZE)
#define CONCAT(x,y) __CONCAT(x,y)
#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
***************
*** 736,741 ****
--- 790,799 ----
int exec_elf32_makecmds __P((struct proc *, struct exec_package *));
int elf32_copyargs __P((struct exec_package *, struct ps_strings *,
char **, void *));
+
+ int coredump_elf32 __P((struct proc *, struct vnode *, struct ucred *));
+ int coredump_writenote_elf32 __P((struct proc *, struct vnode *,
+ struct ucred *, off_t, Elf32_Nhdr *, const char *, void *));
#endif
#ifdef EXEC_ELF64
***************
*** 744,749 ****
--- 802,811 ----
caddr_t, int));
int elf64_copyargs __P((struct exec_package *, struct ps_strings *,
char **, void *));
+
+ int coredump_elf64 __P((struct proc *, struct vnode *, struct ucred *));
+ int coredump_writenote_elf64 __P((struct proc *, struct vnode *,
+ struct ucred *, off_t, Elf64_Nhdr *, const char *, void *));
#endif
/* common */
--tThc/1wpZn/ma/RB--