1*209be910Scube /* $NetBSD: core_elf32.c,v 1.23 2006/03/12 20:25:26 cube 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*209be910Scube __KERNEL_RCSID(1, "$NetBSD: core_elf32.c,v 1.23 2006/03/12 20:25:26 cube 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> 54e1245a3cSmatt #include <sys/exec.h> 5551535d4bSthorpej #include <sys/exec_elf.h> 5651535d4bSthorpej #include <sys/ptrace.h> 5725a0e29aSmatt #include <sys/malloc.h> 5851535d4bSthorpej 5951535d4bSthorpej #include <machine/reg.h> 6051535d4bSthorpej 6106920aefSthorpej #include <uvm/uvm_extern.h> 6206920aefSthorpej 6306920aefSthorpej struct countsegs_state { 6406920aefSthorpej int npsections; 6506920aefSthorpej }; 6606920aefSthorpej 6759466612Sthorpej static int ELFNAMEEND(coredump_countsegs)(struct proc *, void *, 68e1245a3cSmatt struct uvm_coredump_state *); 6906920aefSthorpej 7006920aefSthorpej struct writesegs_state { 7125a0e29aSmatt Elf_Phdr *psections; 7206920aefSthorpej off_t secoff; 7306920aefSthorpej }; 7406920aefSthorpej 7559466612Sthorpej static int ELFNAMEEND(coredump_writeseghdrs)(struct proc *, void *, 76e1245a3cSmatt struct uvm_coredump_state *); 7751535d4bSthorpej 7859466612Sthorpej static int ELFNAMEEND(coredump_notes)(struct proc *, struct lwp *, void *, 79e1245a3cSmatt size_t *); 8059466612Sthorpej static int ELFNAMEEND(coredump_note)(struct proc *, struct lwp *, void *, 81e1245a3cSmatt size_t *); 8251535d4bSthorpej 8351535d4bSthorpej #define ELFROUNDSIZE 4 /* XXX Should it be sizeof(Elf_Word)? */ 8451535d4bSthorpej #define elfround(x) roundup((x), ELFROUNDSIZE) 8551535d4bSthorpej 86*209be910Scube #define elf_process_read_regs CONCAT(process_read_regs, ELFSIZE) 87*209be910Scube #define elf_process_read_fpregs CONCAT(process_read_fpregs, ELFSIZE) 88*209be910Scube #define elf_reg CONCAT(process_reg, ELFSIZE) 89*209be910Scube #define elf_fpreg CONCAT(process_fpreg, ELFSIZE) 90*209be910Scube 9151535d4bSthorpej int 92e1245a3cSmatt ELFNAMEEND(coredump)(struct lwp *l, void *cookie) 9351535d4bSthorpej { 94e0d8d366Sthorpej struct proc *p; 9551535d4bSthorpej Elf_Ehdr ehdr; 9625a0e29aSmatt Elf_Phdr phdr, *psections; 9706920aefSthorpej struct countsegs_state cs; 9806920aefSthorpej struct writesegs_state ws; 9925a0e29aSmatt off_t notestart, secstart, offset; 1002de77aedSmatt size_t notesize; 10125a0e29aSmatt int error, i; 10251535d4bSthorpej 10325a0e29aSmatt psections = NULL; 104e0d8d366Sthorpej p = l->l_proc; 10551535d4bSthorpej /* 10651535d4bSthorpej * We have to make a total of 3 passes across the map: 10751535d4bSthorpej * 10851535d4bSthorpej * 1. Count the number of map entries (the number of 10951535d4bSthorpej * PT_LOAD sections). 11051535d4bSthorpej * 11151535d4bSthorpej * 2. Write the P-section headers. 11251535d4bSthorpej * 11351535d4bSthorpej * 3. Write the P-sections. 11451535d4bSthorpej */ 11551535d4bSthorpej 11651535d4bSthorpej /* Pass 1: count the entries. */ 11706920aefSthorpej cs.npsections = 0; 118e1245a3cSmatt error = uvm_coredump_walkmap(p, NULL, 11906920aefSthorpej ELFNAMEEND(coredump_countsegs), &cs); 12006920aefSthorpej if (error) 12125a0e29aSmatt goto out; 12225a0e29aSmatt 12325a0e29aSmatt /* Count the PT_NOTE section. */ 12425a0e29aSmatt cs.npsections++; 12551535d4bSthorpej 12651535d4bSthorpej /* Get the size of the notes. */ 127e1245a3cSmatt error = ELFNAMEEND(coredump_notes)(p, l, NULL, ¬esize); 12851535d4bSthorpej if (error) 12925a0e29aSmatt goto out; 13051535d4bSthorpej 131e1245a3cSmatt memset(&ehdr.e_ident[EI_PAD], 0, sizeof(ehdr.e_ident) - EI_PAD); 13251535d4bSthorpej memcpy(ehdr.e_ident, ELFMAG, SELFMAG); 13351535d4bSthorpej #if ELFSIZE == 32 13451535d4bSthorpej ehdr.e_ident[EI_CLASS] = ELFCLASS32; 13551535d4bSthorpej #elif ELFSIZE == 64 13651535d4bSthorpej ehdr.e_ident[EI_CLASS] = ELFCLASS64; 13751535d4bSthorpej #endif 13851535d4bSthorpej ehdr.e_ident[EI_DATA] = ELFDEFNNAME(MACHDEP_ENDIANNESS); 13951535d4bSthorpej ehdr.e_ident[EI_VERSION] = EV_CURRENT; 14051535d4bSthorpej /* XXX Should be the OSABI/ABI version of the executable. */ 14151535d4bSthorpej ehdr.e_ident[EI_OSABI] = ELFOSABI_SYSV; 14206920aefSthorpej ehdr.e_ident[EI_ABIVERSION] = 0; 14351535d4bSthorpej 14451535d4bSthorpej ehdr.e_type = ET_CORE; 14551535d4bSthorpej /* XXX This should be the e_machine of the executable. */ 14651535d4bSthorpej ehdr.e_machine = ELFDEFNNAME(MACHDEP_ID); 14751535d4bSthorpej ehdr.e_version = EV_CURRENT; 14851535d4bSthorpej ehdr.e_entry = 0; 14951535d4bSthorpej ehdr.e_phoff = sizeof(ehdr); 15051535d4bSthorpej ehdr.e_shoff = 0; 15151535d4bSthorpej ehdr.e_flags = 0; 15251535d4bSthorpej ehdr.e_ehsize = sizeof(ehdr); 15351535d4bSthorpej ehdr.e_phentsize = sizeof(Elf_Phdr); 15406920aefSthorpej ehdr.e_phnum = cs.npsections; 15551535d4bSthorpej ehdr.e_shentsize = 0; 15651535d4bSthorpej ehdr.e_shnum = 0; 15751535d4bSthorpej ehdr.e_shstrndx = 0; 15851535d4bSthorpej 15925a0e29aSmatt /* Write out the ELF header. */ 160e1245a3cSmatt error = coredump_write(cookie, UIO_SYSSPACE, &ehdr, sizeof(ehdr)); 16125a0e29aSmatt if (error) 16225a0e29aSmatt goto out; 16325a0e29aSmatt 164e1245a3cSmatt offset = sizeof(ehdr); 16525a0e29aSmatt 16625a0e29aSmatt notestart = offset + sizeof(phdr) * cs.npsections; 16725a0e29aSmatt secstart = notestart + notesize; 16825a0e29aSmatt 16925a0e29aSmatt psections = malloc(cs.npsections * sizeof(Elf_Phdr), 17025a0e29aSmatt M_TEMP, M_WAITOK|M_ZERO); 17151535d4bSthorpej 172524df474Satatat /* Pass 2: now write the P-section headers. */ 17306920aefSthorpej ws.secoff = secstart; 17425a0e29aSmatt ws.psections = psections; 175e1245a3cSmatt error = uvm_coredump_walkmap(p, cookie, 17606920aefSthorpej ELFNAMEEND(coredump_writeseghdrs), &ws); 17751535d4bSthorpej if (error) 17825a0e29aSmatt goto out; 17951535d4bSthorpej 18051535d4bSthorpej /* Write out the PT_NOTE header. */ 18125a0e29aSmatt ws.psections->p_type = PT_NOTE; 18225a0e29aSmatt ws.psections->p_offset = notestart; 18325a0e29aSmatt ws.psections->p_vaddr = 0; 18425a0e29aSmatt ws.psections->p_paddr = 0; 18525a0e29aSmatt ws.psections->p_filesz = notesize; 18625a0e29aSmatt ws.psections->p_memsz = 0; 18725a0e29aSmatt ws.psections->p_flags = PF_R; 18825a0e29aSmatt ws.psections->p_align = ELFROUNDSIZE; 18951535d4bSthorpej 190e1245a3cSmatt error = coredump_write(cookie, UIO_SYSSPACE, psections, 191e1245a3cSmatt cs.npsections * sizeof(Elf_Phdr)); 19251535d4bSthorpej if (error) 19325a0e29aSmatt goto out; 19451535d4bSthorpej 19506920aefSthorpej #ifdef DIAGNOSTIC 196e1245a3cSmatt offset += cs.npsections * sizeof(Elf_Phdr); 19725a0e29aSmatt if (offset != notestart) 19806920aefSthorpej panic("coredump: offset %lld != notestart %lld", 19925a0e29aSmatt (long long) offset, (long long) notestart); 20006920aefSthorpej #endif 20151535d4bSthorpej 20251535d4bSthorpej /* Write out the notes. */ 203e1245a3cSmatt error = ELFNAMEEND(coredump_notes)(p, l, cookie, ¬esize); 20425a0e29aSmatt if (error) 20525a0e29aSmatt goto out; 20606920aefSthorpej 20706920aefSthorpej #ifdef DIAGNOSTIC 20825a0e29aSmatt offset += notesize; 20925a0e29aSmatt if (offset != secstart) 21006920aefSthorpej panic("coredump: offset %lld != secstart %lld", 21125a0e29aSmatt (long long) offset, (long long) secstart); 21206920aefSthorpej #endif 21306920aefSthorpej 214524df474Satatat /* Pass 3: finally, write the sections themselves. */ 21525a0e29aSmatt for (i = 0; i < cs.npsections - 1; i++) { 21625a0e29aSmatt if (psections[i].p_filesz == 0) 21725a0e29aSmatt continue; 21851535d4bSthorpej 21925a0e29aSmatt #ifdef DIAGNOSTIC 22025a0e29aSmatt if (offset != psections[i].p_offset) 22125a0e29aSmatt panic("coredump: offset %lld != p_offset[%d] %lld", 22225a0e29aSmatt (long long) offset, i, 22325a0e29aSmatt (long long) psections[i].p_filesz); 22425a0e29aSmatt #endif 22525a0e29aSmatt 226e1245a3cSmatt error = coredump_write(cookie, UIO_USERSPACE, 227e1245a3cSmatt (void *)(vaddr_t)psections[i].p_vaddr, 228e1245a3cSmatt psections[i].p_filesz); 22925a0e29aSmatt if (error) 23025a0e29aSmatt goto out; 23125a0e29aSmatt 23225a0e29aSmatt #ifdef DIAGNOSTIC 23325a0e29aSmatt offset += psections[i].p_filesz; 23425a0e29aSmatt #endif 23525a0e29aSmatt } 23625a0e29aSmatt 23725a0e29aSmatt out: 23825a0e29aSmatt if (psections) 23925a0e29aSmatt free(psections, M_TEMP); 24006920aefSthorpej return (error); 24151535d4bSthorpej } 24251535d4bSthorpej 24359466612Sthorpej static int 244e1245a3cSmatt ELFNAMEEND(coredump_countsegs)(struct proc *p, void *iocookie, 245e1245a3cSmatt struct uvm_coredump_state *us) 24606920aefSthorpej { 24706920aefSthorpej struct countsegs_state *cs = us->cookie; 24851535d4bSthorpej 24906920aefSthorpej cs->npsections++; 25006920aefSthorpej return (0); 25151535d4bSthorpej } 25251535d4bSthorpej 25359466612Sthorpej static int 254e1245a3cSmatt ELFNAMEEND(coredump_writeseghdrs)(struct proc *p, void *iocookie, 255e1245a3cSmatt struct uvm_coredump_state *us) 25606920aefSthorpej { 25706920aefSthorpej struct writesegs_state *ws = us->cookie; 25806920aefSthorpej Elf_Phdr phdr; 25925a0e29aSmatt vsize_t size, realsize; 26025a0e29aSmatt vaddr_t end; 26106920aefSthorpej int error; 26206920aefSthorpej 26306920aefSthorpej size = us->end - us->start; 26425a0e29aSmatt realsize = us->realend - us->start; 26525a0e29aSmatt end = us->realend; 26625a0e29aSmatt 26725a0e29aSmatt while (realsize > 0) { 26825a0e29aSmatt long buf[1024 / sizeof(long)]; 26925a0e29aSmatt size_t slen = realsize > sizeof(buf) ? sizeof(buf) : realsize; 27025a0e29aSmatt const long *ep; 27125a0e29aSmatt int i; 27225a0e29aSmatt 27325a0e29aSmatt end -= slen; 274de124326Schristos if ((error = copyin_proc(p, (void *)end, buf, slen)) != 0) 275de124326Schristos return error; 27625a0e29aSmatt 27725a0e29aSmatt ep = (const long *) &buf[slen / sizeof(buf[0])]; 27825a0e29aSmatt for (i = 0, ep--; buf <= ep; ep--, i++) { 27925a0e29aSmatt if (*ep) 28025a0e29aSmatt break; 28125a0e29aSmatt } 28225a0e29aSmatt realsize -= i * sizeof(buf[0]); 28325a0e29aSmatt if (i * sizeof(buf[0]) < slen) 28425a0e29aSmatt break; 28525a0e29aSmatt } 28606920aefSthorpej 28706920aefSthorpej phdr.p_type = PT_LOAD; 28806920aefSthorpej phdr.p_offset = ws->secoff; 28906920aefSthorpej phdr.p_vaddr = us->start; 29006920aefSthorpej phdr.p_paddr = 0; 29125a0e29aSmatt phdr.p_filesz = realsize; 29206920aefSthorpej phdr.p_memsz = size; 29306920aefSthorpej phdr.p_flags = 0; 29406920aefSthorpej if (us->prot & VM_PROT_READ) 29506920aefSthorpej phdr.p_flags |= PF_R; 29606920aefSthorpej if (us->prot & VM_PROT_WRITE) 29706920aefSthorpej phdr.p_flags |= PF_W; 29806920aefSthorpej if (us->prot & VM_PROT_EXECUTE) 29906920aefSthorpej phdr.p_flags |= PF_X; 30006920aefSthorpej phdr.p_align = PAGE_SIZE; 30106920aefSthorpej 30206920aefSthorpej ws->secoff += phdr.p_filesz; 30325a0e29aSmatt *ws->psections++ = phdr; 30406920aefSthorpej 30551535d4bSthorpej return (0); 30651535d4bSthorpej } 30751535d4bSthorpej 30859466612Sthorpej static int 309e1245a3cSmatt ELFNAMEEND(coredump_notes)(struct proc *p, struct lwp *l, 310e1245a3cSmatt void *iocookie, size_t *sizep) 31151535d4bSthorpej { 31251535d4bSthorpej struct netbsd_elfcore_procinfo cpi; 31351535d4bSthorpej Elf_Nhdr nhdr; 3142de77aedSmatt size_t size, notesize; 3152de77aedSmatt int error; 3162de77aedSmatt struct lwp *l0; 31751535d4bSthorpej 31851535d4bSthorpej size = 0; 31951535d4bSthorpej 32051535d4bSthorpej /* First, write an elfcore_procinfo. */ 32151535d4bSthorpej notesize = sizeof(nhdr) + elfround(sizeof(ELF_NOTE_NETBSD_CORE_NAME)) + 32251535d4bSthorpej elfround(sizeof(cpi)); 323e1245a3cSmatt if (iocookie) { 32451535d4bSthorpej cpi.cpi_version = NETBSD_ELFCORE_PROCINFO_VERSION; 32551535d4bSthorpej cpi.cpi_cpisize = sizeof(cpi); 3269970fc6aSchristos cpi.cpi_signo = p->p_sigctx.ps_signo; 3279970fc6aSchristos cpi.cpi_sigcode = p->p_sigctx.ps_code; 3288e02eedcSnathanw cpi.cpi_siglwp = p->p_sigctx.ps_lwp; 32951535d4bSthorpej 33051535d4bSthorpej memcpy(&cpi.cpi_sigpend, &p->p_sigctx.ps_siglist, 33151535d4bSthorpej sizeof(cpi.cpi_sigpend)); 33251535d4bSthorpej memcpy(&cpi.cpi_sigmask, &p->p_sigctx.ps_sigmask, 33351535d4bSthorpej sizeof(cpi.cpi_sigmask)); 33451535d4bSthorpej memcpy(&cpi.cpi_sigignore, &p->p_sigctx.ps_sigignore, 33551535d4bSthorpej sizeof(cpi.cpi_sigignore)); 33651535d4bSthorpej memcpy(&cpi.cpi_sigcatch, &p->p_sigctx.ps_sigcatch, 33751535d4bSthorpej sizeof(cpi.cpi_sigcatch)); 33851535d4bSthorpej 33951535d4bSthorpej cpi.cpi_pid = p->p_pid; 34051535d4bSthorpej cpi.cpi_ppid = p->p_pptr->p_pid; 34151535d4bSthorpej cpi.cpi_pgrp = p->p_pgid; 34251535d4bSthorpej cpi.cpi_sid = p->p_session->s_sid; 34351535d4bSthorpej 34451535d4bSthorpej cpi.cpi_ruid = p->p_cred->p_ruid; 34551535d4bSthorpej cpi.cpi_euid = p->p_ucred->cr_uid; 34651535d4bSthorpej cpi.cpi_svuid = p->p_cred->p_svuid; 34751535d4bSthorpej 34851535d4bSthorpej cpi.cpi_rgid = p->p_cred->p_rgid; 34951535d4bSthorpej cpi.cpi_egid = p->p_ucred->cr_gid; 35051535d4bSthorpej cpi.cpi_svgid = p->p_cred->p_svgid; 35151535d4bSthorpej 352e0d8d366Sthorpej cpi.cpi_nlwps = p->p_nlwps; 353f265a4a4Sitojun strlcpy(cpi.cpi_name, p->p_comm, sizeof(cpi.cpi_name)); 35451535d4bSthorpej 35551535d4bSthorpej nhdr.n_namesz = sizeof(ELF_NOTE_NETBSD_CORE_NAME); 35651535d4bSthorpej nhdr.n_descsz = sizeof(cpi); 35751535d4bSthorpej nhdr.n_type = ELF_NOTE_NETBSD_CORE_PROCINFO; 35851535d4bSthorpej 359e1245a3cSmatt error = ELFNAMEEND(coredump_writenote)(p, iocookie, &nhdr, 360e1245a3cSmatt ELF_NOTE_NETBSD_CORE_NAME "\0\0\0", &cpi); 36151535d4bSthorpej if (error) 36251535d4bSthorpej return (error); 36351535d4bSthorpej } 36451535d4bSthorpej 36551535d4bSthorpej size += notesize; 36651535d4bSthorpej 36751535d4bSthorpej /* XXX Add hook for machdep per-proc notes. */ 36851535d4bSthorpej 36951535d4bSthorpej /* 3702de77aedSmatt * Now write the register info for the thread that caused the 3712de77aedSmatt * coredump. 3722de77aedSmatt */ 373e1245a3cSmatt error = ELFNAMEEND(coredump_note)(p, l, iocookie, ¬esize); 3742de77aedSmatt if (error) 3752de77aedSmatt return (error); 3762de77aedSmatt size += notesize; 3772de77aedSmatt 3782de77aedSmatt /* 37951535d4bSthorpej * Now, for each LWP, write the register info and any other 38051535d4bSthorpej * per-LWP notes. 38151535d4bSthorpej */ 3822de77aedSmatt LIST_FOREACH(l0, &p->p_lwps, l_sibling) { 3832de77aedSmatt if (l0 == l) /* we've taken care of this thread */ 3842de77aedSmatt continue; 385e1245a3cSmatt error = ELFNAMEEND(coredump_note)(p, l0, iocookie, ¬esize); 3862de77aedSmatt if (error) 3872de77aedSmatt return (error); 3882de77aedSmatt size += notesize; 3892de77aedSmatt } 3902de77aedSmatt 3912de77aedSmatt *sizep = size; 3922de77aedSmatt return (0); 3932de77aedSmatt } 3942de77aedSmatt 39559466612Sthorpej static int 396e1245a3cSmatt ELFNAMEEND(coredump_note)(struct proc *p, struct lwp *l, void *iocookie, 397e1245a3cSmatt size_t *sizep) 3982de77aedSmatt { 3992de77aedSmatt Elf_Nhdr nhdr; 4002de77aedSmatt int size, notesize, error; 4012de77aedSmatt int namesize; 402e1245a3cSmatt char name[64+ELFROUNDSIZE]; 403*209be910Scube elf_reg intreg; 4042de77aedSmatt #ifdef PT_GETFPREGS 405*209be910Scube elf_fpreg freg; 4062de77aedSmatt #endif 4072de77aedSmatt 4082de77aedSmatt size = 0; 4092de77aedSmatt 410e1245a3cSmatt snprintf(name, sizeof(name)-ELFROUNDSIZE, "%s@%d", 411e1245a3cSmatt ELF_NOTE_NETBSD_CORE_NAME, l->l_lid); 41251535d4bSthorpej namesize = strlen(name) + 1; 413e1245a3cSmatt memset(name + namesize, 0, elfround(namesize) - namesize); 41451535d4bSthorpej 4152de77aedSmatt notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(intreg)); 416e1245a3cSmatt if (iocookie) { 417e0d8d366Sthorpej PHOLD(l); 418*209be910Scube error = elf_process_read_regs(l, &intreg); 419e0d8d366Sthorpej PRELE(l); 42051535d4bSthorpej if (error) 42151535d4bSthorpej return (error); 42251535d4bSthorpej 42351535d4bSthorpej nhdr.n_namesz = namesize; 42451535d4bSthorpej nhdr.n_descsz = sizeof(intreg); 42551535d4bSthorpej nhdr.n_type = PT_GETREGS; 42651535d4bSthorpej 427e1245a3cSmatt error = ELFNAMEEND(coredump_writenote)(p, iocookie, &nhdr, 428e1245a3cSmatt name, &intreg); 42951535d4bSthorpej if (error) 43051535d4bSthorpej return (error); 43151535d4bSthorpej 43251535d4bSthorpej } 43351535d4bSthorpej size += notesize; 43451535d4bSthorpej 43551535d4bSthorpej #ifdef PT_GETFPREGS 4362de77aedSmatt notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(freg)); 437e1245a3cSmatt if (iocookie) { 438e0d8d366Sthorpej PHOLD(l); 439*209be910Scube error = elf_process_read_fpregs(l, &freg); 440e0d8d366Sthorpej PRELE(l); 44151535d4bSthorpej if (error) 44251535d4bSthorpej return (error); 44351535d4bSthorpej 44451535d4bSthorpej nhdr.n_namesz = namesize; 44551535d4bSthorpej nhdr.n_descsz = sizeof(freg); 44651535d4bSthorpej nhdr.n_type = PT_GETFPREGS; 44751535d4bSthorpej 448e1245a3cSmatt error = ELFNAMEEND(coredump_writenote)(p, iocookie, &nhdr, 449e1245a3cSmatt name, &freg); 45051535d4bSthorpej if (error) 45151535d4bSthorpej return (error); 45251535d4bSthorpej } 45351535d4bSthorpej size += notesize; 45451535d4bSthorpej #endif 45551535d4bSthorpej *sizep = size; 4562de77aedSmatt /* XXX Add hook for machdep per-LWP notes. */ 45751535d4bSthorpej return (0); 45851535d4bSthorpej } 45951535d4bSthorpej 46051535d4bSthorpej int 461e1245a3cSmatt ELFNAMEEND(coredump_writenote)(struct proc *p, void *cookie, Elf_Nhdr *nhdr, 462e1245a3cSmatt const char *name, void *data) 46351535d4bSthorpej { 46451535d4bSthorpej int error; 46551535d4bSthorpej 466e1245a3cSmatt error = coredump_write(cookie, UIO_SYSSPACE, nhdr, sizeof(*nhdr)); 46751535d4bSthorpej if (error) 468e1245a3cSmatt return error; 46951535d4bSthorpej 470e1245a3cSmatt error = coredump_write(cookie, UIO_SYSSPACE, name, 471e1245a3cSmatt elfround(nhdr->n_namesz)); 47251535d4bSthorpej if (error) 473e1245a3cSmatt return error; 47451535d4bSthorpej 475e1245a3cSmatt return coredump_write(cookie, UIO_SYSSPACE, data, nhdr->n_descsz); 47651535d4bSthorpej } 477