1*f265a4a4Sitojun /* $NetBSD: core_elf32.c,v 1.7 2003/05/16 14:25:02 itojun Exp $ */ 251535d4bSthorpej 351535d4bSthorpej /* 451535d4bSthorpej * Copyright (c) 2001 Wasabi Systems, Inc. 551535d4bSthorpej * All rights reserved. 651535d4bSthorpej * 751535d4bSthorpej * Written by Jason R. Thorpe for Wasabi Systems, Inc. 851535d4bSthorpej * 951535d4bSthorpej * Redistribution and use in source and binary forms, with or without 1051535d4bSthorpej * modification, are permitted provided that the following conditions 1151535d4bSthorpej * are met: 1251535d4bSthorpej * 1. Redistributions of source code must retain the above copyright 1351535d4bSthorpej * notice, this list of conditions and the following disclaimer. 1451535d4bSthorpej * 2. Redistributions in binary form must reproduce the above copyright 1551535d4bSthorpej * notice, this list of conditions and the following disclaimer in the 1651535d4bSthorpej * documentation and/or other materials provided with the distribution. 1751535d4bSthorpej * 3. All advertising materials mentioning features or use of this software 1851535d4bSthorpej * must display the following acknowledgement: 1951535d4bSthorpej * This product includes software developed for the NetBSD Project by 2051535d4bSthorpej * Wasabi Systems, Inc. 2151535d4bSthorpej * 4. The name of Wasabi Systems, Inc. may not be used to endorse 2251535d4bSthorpej * or promote products derived from this software without specific prior 2351535d4bSthorpej * written permission. 2451535d4bSthorpej * 2551535d4bSthorpej * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 2651535d4bSthorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2751535d4bSthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2851535d4bSthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 2951535d4bSthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3051535d4bSthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3151535d4bSthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3251535d4bSthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3351535d4bSthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3451535d4bSthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3551535d4bSthorpej * POSSIBILITY OF SUCH DAMAGE. 3651535d4bSthorpej */ 3751535d4bSthorpej 3851535d4bSthorpej /* 3951535d4bSthorpej * core_elf32.c/core_elf64.c: Support for the Elf32/Elf64 core file format. 4051535d4bSthorpej */ 4151535d4bSthorpej 4251535d4bSthorpej #include <sys/cdefs.h> 43*f265a4a4Sitojun __KERNEL_RCSID(1, "$NetBSD: core_elf32.c,v 1.7 2003/05/16 14:25:02 itojun Exp $"); 4451535d4bSthorpej 4551535d4bSthorpej /* If not included by core_elf64.c, ELFSIZE won't be defined. */ 4651535d4bSthorpej #ifndef ELFSIZE 4751535d4bSthorpej #define ELFSIZE 32 4851535d4bSthorpej #endif 4951535d4bSthorpej 5051535d4bSthorpej #include <sys/param.h> 5151535d4bSthorpej #include <sys/systm.h> 5251535d4bSthorpej #include <sys/proc.h> 5351535d4bSthorpej #include <sys/vnode.h> 5451535d4bSthorpej #include <sys/exec_elf.h> 5551535d4bSthorpej #include <sys/ptrace.h> 5651535d4bSthorpej 5751535d4bSthorpej #include <machine/reg.h> 5851535d4bSthorpej 5906920aefSthorpej #include <uvm/uvm_extern.h> 6006920aefSthorpej 6106920aefSthorpej struct countsegs_state { 6206920aefSthorpej int npsections; 6306920aefSthorpej }; 6406920aefSthorpej 6506920aefSthorpej int ELFNAMEEND(coredump_countsegs)(struct proc *, struct vnode *, 6606920aefSthorpej struct ucred *, struct uvm_coredump_state *); 6706920aefSthorpej 6806920aefSthorpej struct writesegs_state { 6906920aefSthorpej off_t offset; 7006920aefSthorpej off_t secoff; 7106920aefSthorpej }; 7206920aefSthorpej 7306920aefSthorpej int ELFNAMEEND(coredump_writeseghdrs)(struct proc *, struct vnode *, 7406920aefSthorpej struct ucred *, struct uvm_coredump_state *); 7506920aefSthorpej int ELFNAMEEND(coredump_writesegs)(struct proc *, struct vnode *, 7606920aefSthorpej struct ucred *, struct uvm_coredump_state *); 7751535d4bSthorpej 782de77aedSmatt int ELFNAMEEND(coredump_notes)(struct proc *, struct lwp *, struct vnode *, 792de77aedSmatt struct ucred *, size_t *, off_t); 802de77aedSmatt int ELFNAMEEND(coredump_note)(struct proc *, struct lwp *, struct vnode *, 812de77aedSmatt struct ucred *, size_t *, off_t); 8251535d4bSthorpej 8351535d4bSthorpej #define ELFROUNDSIZE 4 /* XXX Should it be sizeof(Elf_Word)? */ 8451535d4bSthorpej #define elfround(x) roundup((x), ELFROUNDSIZE) 8551535d4bSthorpej 8651535d4bSthorpej int 87e0d8d366Sthorpej ELFNAMEEND(coredump)(struct lwp *l, struct vnode *vp, struct ucred *cred) 8851535d4bSthorpej { 89e0d8d366Sthorpej struct proc *p; 9051535d4bSthorpej Elf_Ehdr ehdr; 9151535d4bSthorpej Elf_Phdr phdr; 9206920aefSthorpej struct countsegs_state cs; 9306920aefSthorpej struct writesegs_state ws; 9406920aefSthorpej off_t notestart, secstart; 952de77aedSmatt size_t notesize; 962de77aedSmatt int error; 9751535d4bSthorpej 98e0d8d366Sthorpej p = l->l_proc; 9951535d4bSthorpej /* 10051535d4bSthorpej * We have to make a total of 3 passes across the map: 10151535d4bSthorpej * 10251535d4bSthorpej * 1. Count the number of map entries (the number of 10351535d4bSthorpej * PT_LOAD sections). 10451535d4bSthorpej * 10551535d4bSthorpej * 2. Write the P-section headers. 10651535d4bSthorpej * 10751535d4bSthorpej * 3. Write the P-sections. 10851535d4bSthorpej */ 10951535d4bSthorpej 11051535d4bSthorpej /* Pass 1: count the entries. */ 11106920aefSthorpej cs.npsections = 0; 11206920aefSthorpej error = uvm_coredump_walkmap(p, vp, cred, 11306920aefSthorpej ELFNAMEEND(coredump_countsegs), &cs); 11406920aefSthorpej if (error) 11506920aefSthorpej return (error); 11651535d4bSthorpej 11751535d4bSthorpej /* Get the size of the notes. */ 1182de77aedSmatt error = ELFNAMEEND(coredump_notes)(p, l, vp, cred, ¬esize, 0); 11951535d4bSthorpej if (error) 12051535d4bSthorpej return (error); 12151535d4bSthorpej 12251535d4bSthorpej /* Count the PT_NOTE section. */ 12306920aefSthorpej cs.npsections++; 12451535d4bSthorpej 12551535d4bSthorpej memcpy(ehdr.e_ident, ELFMAG, SELFMAG); 12651535d4bSthorpej #if ELFSIZE == 32 12751535d4bSthorpej ehdr.e_ident[EI_CLASS] = ELFCLASS32; 12851535d4bSthorpej #elif ELFSIZE == 64 12951535d4bSthorpej ehdr.e_ident[EI_CLASS] = ELFCLASS64; 13051535d4bSthorpej #endif 13151535d4bSthorpej ehdr.e_ident[EI_DATA] = ELFDEFNNAME(MACHDEP_ENDIANNESS); 13251535d4bSthorpej ehdr.e_ident[EI_VERSION] = EV_CURRENT; 13351535d4bSthorpej /* XXX Should be the OSABI/ABI version of the executable. */ 13451535d4bSthorpej ehdr.e_ident[EI_OSABI] = ELFOSABI_SYSV; 13506920aefSthorpej ehdr.e_ident[EI_ABIVERSION] = 0; 13651535d4bSthorpej 13751535d4bSthorpej ehdr.e_type = ET_CORE; 13851535d4bSthorpej /* XXX This should be the e_machine of the executable. */ 13951535d4bSthorpej ehdr.e_machine = ELFDEFNNAME(MACHDEP_ID); 14051535d4bSthorpej ehdr.e_version = EV_CURRENT; 14151535d4bSthorpej ehdr.e_entry = 0; 14251535d4bSthorpej ehdr.e_phoff = sizeof(ehdr); 14351535d4bSthorpej ehdr.e_shoff = 0; 14451535d4bSthorpej ehdr.e_flags = 0; 14551535d4bSthorpej ehdr.e_ehsize = sizeof(ehdr); 14651535d4bSthorpej ehdr.e_phentsize = sizeof(Elf_Phdr); 14706920aefSthorpej ehdr.e_phnum = cs.npsections; 14851535d4bSthorpej ehdr.e_shentsize = 0; 14951535d4bSthorpej ehdr.e_shnum = 0; 15051535d4bSthorpej ehdr.e_shstrndx = 0; 15151535d4bSthorpej 15251535d4bSthorpej /* Write out the ELF header. */ 15351535d4bSthorpej error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&ehdr, 15451535d4bSthorpej (int)sizeof(ehdr), (off_t)0, 15551535d4bSthorpej UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p); 15651535d4bSthorpej 15706920aefSthorpej ws.offset = ehdr.e_phoff; 15806920aefSthorpej notestart = ws.offset + (sizeof(phdr) * cs.npsections); 15951535d4bSthorpej secstart = round_page(notestart + notesize); 16051535d4bSthorpej 161524df474Satatat /* Pass 2: now write the P-section headers. */ 16206920aefSthorpej ws.secoff = secstart; 16306920aefSthorpej error = uvm_coredump_walkmap(p, vp, cred, 16406920aefSthorpej ELFNAMEEND(coredump_writeseghdrs), &ws); 16551535d4bSthorpej if (error) 16651535d4bSthorpej return (error); 16751535d4bSthorpej 16851535d4bSthorpej /* Write out the PT_NOTE header. */ 16951535d4bSthorpej phdr.p_type = PT_NOTE; 17051535d4bSthorpej phdr.p_offset = notestart; 17151535d4bSthorpej phdr.p_vaddr = 0; 17251535d4bSthorpej phdr.p_paddr = 0; 17351535d4bSthorpej phdr.p_filesz = notesize; 17451535d4bSthorpej phdr.p_memsz = 0; 17551535d4bSthorpej phdr.p_flags = PF_R; 17651535d4bSthorpej phdr.p_align = ELFROUNDSIZE; 17751535d4bSthorpej 17851535d4bSthorpej error = vn_rdwr(UIO_WRITE, vp, 17951535d4bSthorpej (caddr_t)&phdr, sizeof(phdr), 18006920aefSthorpej ws.offset, UIO_SYSSPACE, 18151535d4bSthorpej IO_NODELOCKED|IO_UNIT, cred, NULL, p); 18251535d4bSthorpej if (error) 18351535d4bSthorpej return (error); 18451535d4bSthorpej 18506920aefSthorpej ws.offset += sizeof(phdr); 18651535d4bSthorpej 18706920aefSthorpej #ifdef DIAGNOSTIC 18806920aefSthorpej if (ws.offset != notestart) 18906920aefSthorpej panic("coredump: offset %lld != notestart %lld", 1900b63bf16Sthorpej (long long) ws.offset, (long long) notestart); 19106920aefSthorpej #endif 19251535d4bSthorpej 19351535d4bSthorpej /* Write out the notes. */ 1942de77aedSmatt error = ELFNAMEEND(coredump_notes)(p, l, vp, cred, ¬esize, ws.offset); 19506920aefSthorpej 19606920aefSthorpej ws.offset += notesize; 19706920aefSthorpej 19806920aefSthorpej #ifdef DIAGNOSTIC 19906920aefSthorpej if (round_page(ws.offset) != secstart) 20006920aefSthorpej panic("coredump: offset %lld != secstart %lld", 2010b63bf16Sthorpej (long long) round_page(ws.offset), (long long) secstart); 20206920aefSthorpej #endif 20306920aefSthorpej 204524df474Satatat /* Pass 3: finally, write the sections themselves. */ 20506920aefSthorpej ws.secoff = secstart; 20606920aefSthorpej error = uvm_coredump_walkmap(p, vp, cred, 20706920aefSthorpej ELFNAMEEND(coredump_writesegs), &ws); 20851535d4bSthorpej if (error) 20951535d4bSthorpej return (error); 21051535d4bSthorpej 21106920aefSthorpej return (error); 21251535d4bSthorpej } 21351535d4bSthorpej 21406920aefSthorpej int 21506920aefSthorpej ELFNAMEEND(coredump_countsegs)(struct proc *p, struct vnode *vp, 21606920aefSthorpej struct ucred *cred, struct uvm_coredump_state *us) 21706920aefSthorpej { 21806920aefSthorpej struct countsegs_state *cs = us->cookie; 21951535d4bSthorpej 22006920aefSthorpej cs->npsections++; 22106920aefSthorpej return (0); 22251535d4bSthorpej } 22351535d4bSthorpej 22406920aefSthorpej int 22506920aefSthorpej ELFNAMEEND(coredump_writeseghdrs)(struct proc *p, struct vnode *vp, 22606920aefSthorpej struct ucred *cred, struct uvm_coredump_state *us) 22706920aefSthorpej { 22806920aefSthorpej struct writesegs_state *ws = us->cookie; 22906920aefSthorpej Elf_Phdr phdr; 23006920aefSthorpej vsize_t size; 23106920aefSthorpej int error; 23206920aefSthorpej 23306920aefSthorpej size = us->end - us->start; 23406920aefSthorpej 23506920aefSthorpej phdr.p_type = PT_LOAD; 23606920aefSthorpej phdr.p_offset = ws->secoff; 23706920aefSthorpej phdr.p_vaddr = us->start; 23806920aefSthorpej phdr.p_paddr = 0; 23906920aefSthorpej phdr.p_filesz = (us->flags & UVM_COREDUMP_NODUMP) ? 0 : size; 24006920aefSthorpej phdr.p_memsz = size; 24106920aefSthorpej phdr.p_flags = 0; 24206920aefSthorpej if (us->prot & VM_PROT_READ) 24306920aefSthorpej phdr.p_flags |= PF_R; 24406920aefSthorpej if (us->prot & VM_PROT_WRITE) 24506920aefSthorpej phdr.p_flags |= PF_W; 24606920aefSthorpej if (us->prot & VM_PROT_EXECUTE) 24706920aefSthorpej phdr.p_flags |= PF_X; 24806920aefSthorpej phdr.p_align = PAGE_SIZE; 24906920aefSthorpej 25051535d4bSthorpej error = vn_rdwr(UIO_WRITE, vp, 25106920aefSthorpej (caddr_t)&phdr, sizeof(phdr), 25206920aefSthorpej ws->offset, UIO_SYSSPACE, 25351535d4bSthorpej IO_NODELOCKED|IO_UNIT, cred, NULL, p); 25451535d4bSthorpej if (error) 25551535d4bSthorpej return (error); 25651535d4bSthorpej 25706920aefSthorpej ws->offset += sizeof(phdr); 25806920aefSthorpej ws->secoff += phdr.p_filesz; 25906920aefSthorpej 26006920aefSthorpej return (0); 26151535d4bSthorpej } 26251535d4bSthorpej 26306920aefSthorpej int 26406920aefSthorpej ELFNAMEEND(coredump_writesegs)(struct proc *p, struct vnode *vp, 26506920aefSthorpej struct ucred *cred, struct uvm_coredump_state *us) 26606920aefSthorpej { 26706920aefSthorpej struct writesegs_state *ws = us->cookie; 26806920aefSthorpej vsize_t size; 26906920aefSthorpej int error; 27006920aefSthorpej 27106920aefSthorpej if (us->flags & UVM_COREDUMP_NODUMP) 27206920aefSthorpej return (0); 27306920aefSthorpej 27406920aefSthorpej size = us->end - us->start; 27506920aefSthorpej 27606920aefSthorpej error = vn_rdwr(UIO_WRITE, vp, 27706920aefSthorpej (caddr_t) us->start, size, 27806920aefSthorpej ws->secoff, UIO_USERSPACE, 27906920aefSthorpej IO_NODELOCKED|IO_UNIT, cred, NULL, p); 28006920aefSthorpej if (error) 28106920aefSthorpej return (error); 28206920aefSthorpej 28306920aefSthorpej ws->secoff += size; 28406920aefSthorpej 28551535d4bSthorpej return (0); 28651535d4bSthorpej } 28751535d4bSthorpej 28851535d4bSthorpej int 2892de77aedSmatt ELFNAMEEND(coredump_notes)(struct proc *p, struct lwp *l, struct vnode *vp, 2902de77aedSmatt struct ucred *cred, size_t *sizep, off_t offset) 29151535d4bSthorpej { 29251535d4bSthorpej struct netbsd_elfcore_procinfo cpi; 29351535d4bSthorpej Elf_Nhdr nhdr; 2942de77aedSmatt size_t size, notesize; 2952de77aedSmatt int error; 2962de77aedSmatt struct lwp *l0; 29751535d4bSthorpej 29851535d4bSthorpej size = 0; 29951535d4bSthorpej 30051535d4bSthorpej /* First, write an elfcore_procinfo. */ 30151535d4bSthorpej notesize = sizeof(nhdr) + elfround(sizeof(ELF_NOTE_NETBSD_CORE_NAME)) + 30251535d4bSthorpej elfround(sizeof(cpi)); 30351535d4bSthorpej if (offset) { 30451535d4bSthorpej cpi.cpi_version = NETBSD_ELFCORE_PROCINFO_VERSION; 30551535d4bSthorpej cpi.cpi_cpisize = sizeof(cpi); 30651535d4bSthorpej cpi.cpi_signo = p->p_sigctx.ps_sig; 30751535d4bSthorpej cpi.cpi_sigcode = p->p_sigctx.ps_code; 30851535d4bSthorpej 30951535d4bSthorpej memcpy(&cpi.cpi_sigpend, &p->p_sigctx.ps_siglist, 31051535d4bSthorpej sizeof(cpi.cpi_sigpend)); 31151535d4bSthorpej memcpy(&cpi.cpi_sigmask, &p->p_sigctx.ps_sigmask, 31251535d4bSthorpej sizeof(cpi.cpi_sigmask)); 31351535d4bSthorpej memcpy(&cpi.cpi_sigignore, &p->p_sigctx.ps_sigignore, 31451535d4bSthorpej sizeof(cpi.cpi_sigignore)); 31551535d4bSthorpej memcpy(&cpi.cpi_sigcatch, &p->p_sigctx.ps_sigcatch, 31651535d4bSthorpej sizeof(cpi.cpi_sigcatch)); 31751535d4bSthorpej 31851535d4bSthorpej cpi.cpi_pid = p->p_pid; 31951535d4bSthorpej cpi.cpi_ppid = p->p_pptr->p_pid; 32051535d4bSthorpej cpi.cpi_pgrp = p->p_pgid; 32151535d4bSthorpej cpi.cpi_sid = p->p_session->s_sid; 32251535d4bSthorpej 32351535d4bSthorpej cpi.cpi_ruid = p->p_cred->p_ruid; 32451535d4bSthorpej cpi.cpi_euid = p->p_ucred->cr_uid; 32551535d4bSthorpej cpi.cpi_svuid = p->p_cred->p_svuid; 32651535d4bSthorpej 32751535d4bSthorpej cpi.cpi_rgid = p->p_cred->p_rgid; 32851535d4bSthorpej cpi.cpi_egid = p->p_ucred->cr_gid; 32951535d4bSthorpej cpi.cpi_svgid = p->p_cred->p_svgid; 33051535d4bSthorpej 331e0d8d366Sthorpej cpi.cpi_nlwps = p->p_nlwps; 332*f265a4a4Sitojun strlcpy(cpi.cpi_name, p->p_comm, sizeof(cpi.cpi_name)); 33351535d4bSthorpej 33451535d4bSthorpej nhdr.n_namesz = sizeof(ELF_NOTE_NETBSD_CORE_NAME); 33551535d4bSthorpej nhdr.n_descsz = sizeof(cpi); 33651535d4bSthorpej nhdr.n_type = ELF_NOTE_NETBSD_CORE_PROCINFO; 33751535d4bSthorpej 33851535d4bSthorpej error = ELFNAMEEND(coredump_writenote)(p, vp, cred, offset, 33951535d4bSthorpej &nhdr, ELF_NOTE_NETBSD_CORE_NAME, &cpi); 34051535d4bSthorpej if (error) 34151535d4bSthorpej return (error); 34251535d4bSthorpej 34351535d4bSthorpej offset += notesize; 34451535d4bSthorpej } 34551535d4bSthorpej 34651535d4bSthorpej size += notesize; 34751535d4bSthorpej 34851535d4bSthorpej /* XXX Add hook for machdep per-proc notes. */ 34951535d4bSthorpej 35051535d4bSthorpej /* 3512de77aedSmatt * Now write the register info for the thread that caused the 3522de77aedSmatt * coredump. 3532de77aedSmatt */ 3542de77aedSmatt error = ELFNAMEEND(coredump_note)(p, l, vp, cred, ¬esize, offset); 3552de77aedSmatt if (error) 3562de77aedSmatt return (error); 3572de77aedSmatt if (offset) 3582de77aedSmatt offset += notesize; 3592de77aedSmatt size += notesize; 3602de77aedSmatt 3612de77aedSmatt /* 36251535d4bSthorpej * Now, for each LWP, write the register info and any other 36351535d4bSthorpej * per-LWP notes. 36451535d4bSthorpej */ 3652de77aedSmatt LIST_FOREACH(l0, &p->p_lwps, l_sibling) { 3662de77aedSmatt if (l0 == l) /* we've taken care of this thread */ 3672de77aedSmatt continue; 3682de77aedSmatt error = ELFNAMEEND(coredump_note)(p, l0, vp, cred, 3692de77aedSmatt ¬esize, offset); 3702de77aedSmatt if (error) 3712de77aedSmatt return (error); 3722de77aedSmatt if (offset) 3732de77aedSmatt offset += notesize; 3742de77aedSmatt size += notesize; 3752de77aedSmatt } 3762de77aedSmatt 3772de77aedSmatt *sizep = size; 3782de77aedSmatt return (0); 3792de77aedSmatt } 3802de77aedSmatt 3812de77aedSmatt int 3822de77aedSmatt ELFNAMEEND(coredump_note)(struct proc *p, struct lwp *l, struct vnode *vp, 3832de77aedSmatt struct ucred *cred, size_t *sizep, off_t offset) 3842de77aedSmatt { 3852de77aedSmatt Elf_Nhdr nhdr; 3862de77aedSmatt int size, notesize, error; 3872de77aedSmatt int namesize; 3882de77aedSmatt char name[64]; 3892de77aedSmatt struct reg intreg; 3902de77aedSmatt #ifdef PT_GETFPREGS 3912de77aedSmatt struct fpreg freg; 3922de77aedSmatt #endif 3932de77aedSmatt 3942de77aedSmatt size = 0; 3952de77aedSmatt 396e0d8d366Sthorpej sprintf(name, "%s@%d", ELF_NOTE_NETBSD_CORE_NAME, l->l_lid); 39751535d4bSthorpej namesize = strlen(name) + 1; 39851535d4bSthorpej 3992de77aedSmatt notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(intreg)); 40051535d4bSthorpej if (offset) { 401e0d8d366Sthorpej PHOLD(l); 402e0d8d366Sthorpej error = process_read_regs(l, &intreg); 403e0d8d366Sthorpej PRELE(l); 40451535d4bSthorpej if (error) 40551535d4bSthorpej return (error); 40651535d4bSthorpej 40751535d4bSthorpej nhdr.n_namesz = namesize; 40851535d4bSthorpej nhdr.n_descsz = sizeof(intreg); 40951535d4bSthorpej nhdr.n_type = PT_GETREGS; 41051535d4bSthorpej 41151535d4bSthorpej error = ELFNAMEEND(coredump_writenote)(p, vp, cred, 41251535d4bSthorpej offset, &nhdr, name, &intreg); 41351535d4bSthorpej if (error) 41451535d4bSthorpej return (error); 41551535d4bSthorpej 41651535d4bSthorpej offset += notesize; 41751535d4bSthorpej } 41851535d4bSthorpej size += notesize; 41951535d4bSthorpej 42051535d4bSthorpej #ifdef PT_GETFPREGS 4212de77aedSmatt notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(freg)); 42251535d4bSthorpej if (offset) { 423e0d8d366Sthorpej PHOLD(l); 424e0d8d366Sthorpej error = process_read_fpregs(l, &freg); 425e0d8d366Sthorpej PRELE(l); 42651535d4bSthorpej if (error) 42751535d4bSthorpej return (error); 42851535d4bSthorpej 42951535d4bSthorpej nhdr.n_namesz = namesize; 43051535d4bSthorpej nhdr.n_descsz = sizeof(freg); 43151535d4bSthorpej nhdr.n_type = PT_GETFPREGS; 43251535d4bSthorpej 43351535d4bSthorpej error = ELFNAMEEND(coredump_writenote)(p, vp, cred, 43451535d4bSthorpej offset, &nhdr, name, &freg); 43551535d4bSthorpej if (error) 43651535d4bSthorpej return (error); 43751535d4bSthorpej 43851535d4bSthorpej offset += notesize; 43951535d4bSthorpej } 44051535d4bSthorpej size += notesize; 44151535d4bSthorpej #endif 44251535d4bSthorpej *sizep = size; 4432de77aedSmatt /* XXX Add hook for machdep per-LWP notes. */ 44451535d4bSthorpej return (0); 44551535d4bSthorpej } 44651535d4bSthorpej 44751535d4bSthorpej int 44851535d4bSthorpej ELFNAMEEND(coredump_writenote)(struct proc *p, struct vnode *vp, 44951535d4bSthorpej struct ucred *cred, off_t offset, Elf_Nhdr *nhdr, const char *name, 45051535d4bSthorpej void *data) 45151535d4bSthorpej { 45251535d4bSthorpej int error; 45351535d4bSthorpej 45451535d4bSthorpej error = vn_rdwr(UIO_WRITE, vp, 45551535d4bSthorpej (caddr_t) nhdr, sizeof(*nhdr), 45651535d4bSthorpej offset, UIO_SYSSPACE, 45751535d4bSthorpej IO_NODELOCKED|IO_UNIT, cred, NULL, p); 45851535d4bSthorpej if (error) 45951535d4bSthorpej return (error); 46051535d4bSthorpej 46151535d4bSthorpej offset += sizeof(*nhdr); 46251535d4bSthorpej 46351535d4bSthorpej error = vn_rdwr(UIO_WRITE, vp, 46451535d4bSthorpej (caddr_t)name, nhdr->n_namesz, 46551535d4bSthorpej offset, UIO_SYSSPACE, 46651535d4bSthorpej IO_NODELOCKED|IO_UNIT, cred, NULL, p); 46751535d4bSthorpej if (error) 46851535d4bSthorpej return (error); 46951535d4bSthorpej 47051535d4bSthorpej offset += elfround(nhdr->n_namesz); 47151535d4bSthorpej 47251535d4bSthorpej error = vn_rdwr(UIO_WRITE, vp, 47351535d4bSthorpej data, nhdr->n_descsz, 47451535d4bSthorpej offset, UIO_SYSSPACE, 47551535d4bSthorpej IO_NODELOCKED|IO_UNIT, cred, NULL, p); 47651535d4bSthorpej 47751535d4bSthorpej return (error); 47851535d4bSthorpej } 479