1 /* $OpenBSD: exec_elf.c,v 1.70 2009/06/06 21:25:19 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Per Fogelstrom 5 * All rights reserved. 6 * 7 * Copyright (c) 1994 Christos Zoulas 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34 /* 35 * Copyright (c) 2001 Wasabi Systems, Inc. 36 * All rights reserved. 37 * 38 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. All advertising materials mentioning features or use of this software 49 * must display the following acknowledgement: 50 * This product includes software developed for the NetBSD Project by 51 * Wasabi Systems, Inc. 52 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 53 * or promote products derived from this software without specific prior 54 * written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 58 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 59 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 60 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 61 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 62 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 64 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 * POSSIBILITY OF SUCH DAMAGE. 67 */ 68 69 #include <sys/param.h> 70 #include <sys/systm.h> 71 #include <sys/kernel.h> 72 #include <sys/proc.h> 73 #include <sys/malloc.h> 74 #include <sys/pool.h> 75 #include <sys/mount.h> 76 #include <sys/namei.h> 77 #include <sys/vnode.h> 78 #include <sys/core.h> 79 #include <sys/exec.h> 80 #include <sys/exec_elf.h> 81 #include <sys/exec_olf.h> 82 #include <sys/file.h> 83 #include <sys/ptrace.h> 84 #include <sys/syscall.h> 85 #include <sys/signalvar.h> 86 #include <sys/stat.h> 87 88 #include <sys/mman.h> 89 #include <uvm/uvm_extern.h> 90 91 #include <machine/cpu.h> 92 #include <machine/reg.h> 93 #include <machine/exec.h> 94 95 #ifdef COMPAT_LINUX 96 #include <compat/linux/linux_exec.h> 97 #endif 98 99 #ifdef COMPAT_SVR4 100 #include <compat/svr4/svr4_exec.h> 101 #endif 102 103 #ifdef COMPAT_FREEBSD 104 #include <compat/freebsd/freebsd_exec.h> 105 #endif 106 107 struct ELFNAME(probe_entry) { 108 int (*func)(struct proc *, struct exec_package *, char *, 109 u_long *, u_int8_t *); 110 } ELFNAME(probes)[] = { 111 /* XXX - bogus, shouldn't be size independent.. */ 112 #ifdef COMPAT_FREEBSD 113 { freebsd_elf_probe }, 114 #endif 115 #ifdef COMPAT_LINUX 116 { linux_elf_probe }, 117 #endif 118 #ifdef COMPAT_SVR4 119 { svr4_elf_probe }, 120 #endif 121 { NULL } 122 }; 123 124 int ELFNAME(load_file)(struct proc *, char *, struct exec_package *, 125 struct elf_args *, Elf_Addr *); 126 int ELFNAME(check_header)(Elf_Ehdr *); 127 int ELFNAME(read_from)(struct proc *, struct vnode *, u_long, caddr_t, int); 128 void ELFNAME(load_psection)(struct exec_vmcmd_set *, struct vnode *, 129 Elf_Phdr *, Elf_Addr *, Elf_Addr *, int *, int); 130 int ELFNAMEEND(coredump)(struct proc *, void *); 131 132 extern char sigcode[], esigcode[]; 133 #ifdef SYSCALL_DEBUG 134 extern char *syscallnames[]; 135 #endif 136 137 /* round up and down to page boundaries. */ 138 #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) 139 #define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) 140 141 /* 142 * We limit the number of program headers to 32, this should 143 * be a reasonable limit for ELF, the most we have seen so far is 12 144 */ 145 #define ELF_MAX_VALID_PHDR 32 146 147 /* 148 * This is the basic elf emul. elf_probe_funcs may change to other emuls. 149 */ 150 struct emul ELFNAMEEND(emul) = { 151 "native", 152 NULL, 153 sendsig, 154 SYS_syscall, 155 SYS_MAXSYSCALL, 156 sysent, 157 #ifdef SYSCALL_DEBUG 158 syscallnames, 159 #else 160 NULL, 161 #endif 162 sizeof (AuxInfo) * ELF_AUX_ENTRIES, 163 ELFNAME(copyargs), 164 setregs, 165 ELFNAME2(exec,fixup), 166 ELFNAMEEND(coredump), 167 sigcode, 168 esigcode, 169 EMUL_ENABLED | EMUL_NATIVE, 170 }; 171 172 /* 173 * Copy arguments onto the stack in the normal way, but add some 174 * space for extra information in case of dynamic binding. 175 */ 176 void * 177 ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo, 178 void *stack, void *argp) 179 { 180 stack = copyargs(pack, arginfo, stack, argp); 181 if (!stack) 182 return (NULL); 183 184 /* 185 * Push space for extra arguments on the stack needed by 186 * dynamically linked binaries. 187 */ 188 if (pack->ep_interp != NULL) { 189 pack->ep_emul_argp = stack; 190 stack = (char *)stack + ELF_AUX_ENTRIES * sizeof (AuxInfo); 191 } 192 return (stack); 193 } 194 195 /* 196 * Check header for validity; return 0 for ok, ENOEXEC if error 197 */ 198 int 199 ELFNAME(check_header)(Elf_Ehdr *ehdr) 200 { 201 /* 202 * We need to check magic, class size, endianess, and version before 203 * we look at the rest of the Elf_Ehdr structure. These few elements 204 * are represented in a machine independant fashion. 205 */ 206 if (!IS_ELF(*ehdr) || 207 ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 208 ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || 209 ehdr->e_ident[EI_VERSION] != ELF_TARG_VER) 210 return (ENOEXEC); 211 212 /* Now check the machine dependant header */ 213 if (ehdr->e_machine != ELF_TARG_MACH || 214 ehdr->e_version != ELF_TARG_VER) 215 return (ENOEXEC); 216 217 /* Don't allow an insane amount of sections. */ 218 if (ehdr->e_phnum > ELF_MAX_VALID_PHDR) 219 return (ENOEXEC); 220 221 return (0); 222 } 223 224 /* 225 * Load a psection at the appropriate address 226 */ 227 void 228 ELFNAME(load_psection)(struct exec_vmcmd_set *vcset, struct vnode *vp, 229 Elf_Phdr *ph, Elf_Addr *addr, Elf_Addr *size, int *prot, int flags) 230 { 231 u_long uaddr, msize, lsize, psize, rm, rf; 232 long diff, offset, bdiff; 233 Elf_Addr base; 234 235 /* 236 * If the user specified an address, then we load there. 237 */ 238 if (*addr != ELFDEFNNAME(NO_ADDR)) { 239 if (ph->p_align > 1) { 240 *addr = ELF_TRUNC(*addr, ph->p_align); 241 diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align); 242 /* page align vaddr */ 243 base = *addr + trunc_page(ph->p_vaddr) 244 - ELF_TRUNC(ph->p_vaddr, ph->p_align); 245 246 bdiff = ph->p_vaddr - trunc_page(ph->p_vaddr); 247 248 } else 249 diff = 0; 250 } else { 251 *addr = uaddr = ph->p_vaddr; 252 if (ph->p_align > 1) 253 *addr = ELF_TRUNC(uaddr, ph->p_align); 254 base = trunc_page(uaddr); 255 bdiff = uaddr - base; 256 diff = uaddr - *addr; 257 } 258 259 *prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0; 260 *prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0; 261 *prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0; 262 263 msize = ph->p_memsz + diff; 264 offset = ph->p_offset - bdiff; 265 lsize = ph->p_filesz + bdiff; 266 psize = round_page(lsize); 267 268 /* 269 * Because the pagedvn pager can't handle zero fill of the last 270 * data page if it's not page aligned we map the last page readvn. 271 */ 272 if (ph->p_flags & PF_W) { 273 psize = trunc_page(lsize); 274 if (psize > 0) 275 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, 276 offset, *prot, flags); 277 if (psize != lsize) { 278 NEW_VMCMD2(vcset, vmcmd_map_readvn, lsize - psize, 279 base + psize, vp, offset + psize, *prot, flags); 280 } 281 } else { 282 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, offset, 283 *prot, flags); 284 } 285 286 /* 287 * Check if we need to extend the size of the segment 288 */ 289 rm = round_page(*addr + ph->p_memsz + diff); 290 rf = round_page(*addr + ph->p_filesz + diff); 291 292 if (rm != rf) { 293 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0, 294 *prot, flags); 295 } 296 *size = msize; 297 } 298 299 /* 300 * Read from vnode into buffer at offset. 301 */ 302 int 303 ELFNAME(read_from)(struct proc *p, struct vnode *vp, u_long off, caddr_t buf, 304 int size) 305 { 306 int error; 307 size_t resid; 308 309 if ((error = vn_rdwr(UIO_READ, vp, buf, size, off, UIO_SYSSPACE, 310 0, p->p_ucred, &resid, p)) != 0) 311 return error; 312 /* 313 * See if we got all of it 314 */ 315 if (resid != 0) 316 return (ENOEXEC); 317 return (0); 318 } 319 320 /* 321 * Load a file (interpreter/library) pointed to by path [stolen from 322 * coff_load_shlib()]. Made slightly generic so it might be used externally. 323 */ 324 int 325 ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp, 326 struct elf_args *ap, Elf_Addr *last) 327 { 328 int error, i; 329 struct nameidata nd; 330 Elf_Ehdr eh; 331 Elf_Phdr *ph = NULL; 332 u_long phsize; 333 Elf_Addr addr; 334 struct vnode *vp; 335 Elf_Phdr *base_ph = NULL; 336 struct interp_ld_sec { 337 Elf_Addr vaddr; 338 u_long memsz; 339 } loadmap[ELF_MAX_VALID_PHDR]; 340 int nload, idx = 0; 341 Elf_Addr pos = *last; 342 int file_align; 343 344 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 345 if ((error = namei(&nd)) != 0) { 346 return (error); 347 } 348 vp = nd.ni_vp; 349 if (vp->v_type != VREG) { 350 error = EACCES; 351 goto bad; 352 } 353 if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0) 354 goto bad; 355 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 356 error = EACCES; 357 goto bad; 358 } 359 if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0) 360 goto bad1; 361 if ((error = ELFNAME(read_from)(p, nd.ni_vp, 0, 362 (caddr_t)&eh, sizeof(eh))) != 0) 363 goto bad1; 364 365 if (ELFNAME(check_header)(&eh) || eh.e_type != ET_DYN) { 366 error = ENOEXEC; 367 goto bad1; 368 } 369 370 phsize = eh.e_phnum * sizeof(Elf_Phdr); 371 ph = malloc(phsize, M_TEMP, M_WAITOK); 372 373 if ((error = ELFNAME(read_from)(p, nd.ni_vp, eh.e_phoff, (caddr_t)ph, 374 phsize)) != 0) 375 goto bad1; 376 377 for (i = 0; i < eh.e_phnum; i++) { 378 if (ph[i].p_type == PT_LOAD) { 379 loadmap[idx].vaddr = trunc_page(ph[i].p_vaddr); 380 loadmap[idx].memsz = round_page (ph[i].p_vaddr + 381 ph[i].p_memsz - loadmap[idx].vaddr); 382 file_align = ph[i].p_align; 383 idx++; 384 } 385 } 386 nload = idx; 387 388 /* 389 * If no position to load the interpreter was set by a probe 390 * function, pick the same address that a non-fixed mmap(0, ..) 391 * would (i.e. something safely out of the way). 392 */ 393 if (pos == ELFDEFNNAME(NO_ADDR)) { 394 pos = uvm_map_hint(p, VM_PROT_EXECUTE); 395 } 396 397 pos = ELF_ROUND(pos, file_align); 398 *last = epp->ep_interp_pos = pos; 399 for (i = 0; i < nload;/**/) { 400 vaddr_t addr; 401 struct uvm_object *uobj; 402 off_t uoff; 403 size_t size; 404 405 #ifdef this_needs_fixing 406 if (i == 0) { 407 uobj = &vp->v_uvm.u_obj; 408 /* need to fix uoff */ 409 } else { 410 #endif 411 uobj = NULL; 412 uoff = 0; 413 #ifdef this_needs_fixing 414 } 415 #endif 416 417 addr = trunc_page(pos + loadmap[i].vaddr); 418 size = round_page(addr + loadmap[i].memsz) - addr; 419 420 /* CRAP - map_findspace does not avoid daddr+MAXDSIZ */ 421 if ((addr + size > (vaddr_t)p->p_vmspace->vm_daddr) && 422 (addr < (vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ)) 423 addr = round_page((vaddr_t)p->p_vmspace->vm_daddr + 424 MAXDSIZ); 425 426 vm_map_lock(&p->p_vmspace->vm_map); 427 if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size, 428 &addr, uobj, uoff, 0, UVM_FLAG_FIXED) == NULL) { 429 if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size, 430 &addr, uobj, uoff, 0, 0) == NULL) { 431 error = ENOMEM; /* XXX */ 432 vm_map_unlock(&p->p_vmspace->vm_map); 433 goto bad1; 434 } 435 } 436 vm_map_unlock(&p->p_vmspace->vm_map); 437 if (addr != pos + loadmap[i].vaddr) { 438 /* base changed. */ 439 pos = addr - trunc_page(loadmap[i].vaddr); 440 pos = ELF_ROUND(pos,file_align); 441 epp->ep_interp_pos = *last = pos; 442 i = 0; 443 continue; 444 } 445 446 i++; 447 } 448 449 /* 450 * Load all the necessary sections 451 */ 452 for (i = 0; i < eh.e_phnum; i++) { 453 Elf_Addr size = 0; 454 int prot = 0; 455 int flags; 456 457 switch (ph[i].p_type) { 458 case PT_LOAD: 459 if (base_ph == NULL) { 460 flags = VMCMD_BASE; 461 addr = *last; 462 base_ph = &ph[i]; 463 } else { 464 flags = VMCMD_RELATIVE; 465 addr = ph[i].p_vaddr - base_ph->p_vaddr; 466 } 467 ELFNAME(load_psection)(&epp->ep_vmcmds, nd.ni_vp, 468 &ph[i], &addr, &size, &prot, flags); 469 /* If entry is within this section it must be text */ 470 if (eh.e_entry >= ph[i].p_vaddr && 471 eh.e_entry < (ph[i].p_vaddr + size)) { 472 epp->ep_entry = addr + eh.e_entry - 473 ELF_TRUNC(ph[i].p_vaddr,ph[i].p_align); 474 ap->arg_interp = addr; 475 } 476 addr += size; 477 break; 478 479 case PT_DYNAMIC: 480 case PT_PHDR: 481 case PT_NOTE: 482 break; 483 484 default: 485 break; 486 } 487 } 488 489 vn_marktext(nd.ni_vp); 490 491 bad1: 492 VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p); 493 bad: 494 if (ph != NULL) 495 free(ph, M_TEMP); 496 497 *last = addr; 498 vput(nd.ni_vp); 499 return (error); 500 } 501 502 /* 503 * Prepare an Elf binary's exec package 504 * 505 * First, set of the various offsets/lengths in the exec package. 506 * 507 * Then, mark the text image busy (so it can be demand paged) or error out if 508 * this is not possible. Finally, set up vmcmds for the text, data, bss, and 509 * stack segments. 510 */ 511 int 512 ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) 513 { 514 Elf_Ehdr *eh = epp->ep_hdr; 515 Elf_Phdr *ph, *pp, *base_ph = NULL; 516 Elf_Addr phdr = 0, exe_base = 0; 517 int error, i; 518 char *interp = NULL; 519 u_long pos = 0, phsize; 520 u_int8_t os = OOS_NULL; 521 522 if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) 523 return (ENOEXEC); 524 525 if (ELFNAME(check_header)(eh) || 526 (eh->e_type != ET_EXEC && eh->e_type != ET_DYN)) 527 return (ENOEXEC); 528 529 /* 530 * check if vnode is in open for writing, because we want to demand- 531 * page out of it. if it is, don't do it, for various reasons. 532 */ 533 if (epp->ep_vp->v_writecount != 0) { 534 #ifdef DIAGNOSTIC 535 if (epp->ep_vp->v_flag & VTEXT) 536 panic("exec: a VTEXT vnode has writecount != 0"); 537 #endif 538 return (ETXTBSY); 539 } 540 /* 541 * Allocate space to hold all the program headers, and read them 542 * from the file 543 */ 544 phsize = eh->e_phnum * sizeof(Elf_Phdr); 545 ph = malloc(phsize, M_TEMP, M_WAITOK); 546 547 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph, 548 phsize)) != 0) 549 goto bad; 550 551 epp->ep_tsize = ELFDEFNNAME(NO_ADDR); 552 epp->ep_dsize = ELFDEFNNAME(NO_ADDR); 553 554 for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) { 555 if (pp->p_type == PT_INTERP && !interp) { 556 if (pp->p_filesz >= MAXPATHLEN) 557 goto bad; 558 interp = pool_get(&namei_pool, PR_WAITOK); 559 if ((error = ELFNAME(read_from)(p, epp->ep_vp, 560 pp->p_offset, interp, pp->p_filesz)) != 0) { 561 goto bad; 562 } 563 } else if (pp->p_type == PT_LOAD) { 564 if (base_ph == NULL) 565 base_ph = pp; 566 } 567 } 568 569 if (eh->e_type == ET_DYN) { 570 /* need an interpreter and load sections for PIE */ 571 if (interp == NULL || base_ph == NULL) 572 goto bad; 573 /* randomize exe_base for PIE */ 574 exe_base = uvm_map_pie(base_ph->p_align); 575 } 576 577 /* 578 * OK, we want a slightly different twist of the 579 * standard emulation package for "real" elf. 580 */ 581 epp->ep_emul = &ELFNAMEEND(emul); 582 pos = ELFDEFNNAME(NO_ADDR); 583 584 /* 585 * On the same architecture, we may be emulating different systems. 586 * See which one will accept this executable. 587 * 588 * Probe functions would normally see if the interpreter (if any) 589 * exists. Emulation packages may possibly replace the interpreter in 590 * *interp with a changed path (/emul/xxx/<path>), and also 591 * set the ep_emul field in the exec package structure. 592 */ 593 error = ENOEXEC; 594 p->p_os = OOS_OPENBSD; 595 #ifdef NATIVE_EXEC_ELF 596 if (ELFNAME(os_pt_note)(p, epp, epp->ep_hdr, "OpenBSD", 8, 4) == 0) { 597 goto native; 598 } 599 #endif 600 for (i = 0; ELFNAME(probes)[i].func != NULL && error; i++) { 601 error = (*ELFNAME(probes)[i].func)(p, epp, interp, &pos, &os); 602 } 603 if (!error) 604 p->p_os = os; 605 #ifndef NATIVE_EXEC_ELF 606 else 607 goto bad; 608 #else 609 native: 610 #endif /* NATIVE_EXEC_ELF */ 611 612 /* 613 * Load all the necessary sections 614 */ 615 for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) { 616 Elf_Addr addr, size = 0; 617 int prot = 0; 618 int flags = 0; 619 620 switch (pp->p_type) { 621 case PT_LOAD: 622 if (exe_base != 0) { 623 if (pp == base_ph) { 624 flags = VMCMD_BASE; 625 addr = exe_base; 626 } else { 627 flags = VMCMD_RELATIVE; 628 addr = pp->p_vaddr - base_ph->p_vaddr; 629 } 630 } else 631 addr = ELFDEFNNAME(NO_ADDR); 632 633 /* 634 * Calculates size of text and data segments 635 * by starting at first and going to end of last. 636 * 'rwx' sections are treated as data. 637 * this is correct for BSS_PLT, but may not be 638 * for DATA_PLT, is fine for TEXT_PLT. 639 */ 640 ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp, 641 pp, &addr, &size, &prot, flags); 642 643 /* 644 * Update exe_base in case allignment was off. 645 * For PIE, addr is relative to exe_base so 646 * adjust it (non PIE exe_base is 0 so no change). 647 */ 648 if (flags == VMCMD_BASE) 649 exe_base = addr; 650 else 651 addr += exe_base; 652 653 /* 654 * Decide whether it's text or data by looking 655 * at the protection of the section 656 */ 657 if (prot & VM_PROT_WRITE) { 658 /* data section */ 659 if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) { 660 epp->ep_daddr = addr; 661 epp->ep_dsize = size; 662 } else { 663 if (addr < epp->ep_daddr) { 664 epp->ep_dsize = 665 epp->ep_dsize + 666 epp->ep_daddr - 667 addr; 668 epp->ep_daddr = addr; 669 } else 670 epp->ep_dsize = addr+size - 671 epp->ep_daddr; 672 } 673 } else if (prot & VM_PROT_EXECUTE) { 674 /* text section */ 675 if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR)) { 676 epp->ep_taddr = addr; 677 epp->ep_tsize = size; 678 } else { 679 if (addr < epp->ep_taddr) { 680 epp->ep_tsize = 681 epp->ep_tsize + 682 epp->ep_taddr - 683 addr; 684 epp->ep_taddr = addr; 685 } else 686 epp->ep_tsize = addr+size - 687 epp->ep_taddr; 688 } 689 } 690 break; 691 692 case PT_SHLIB: 693 error = ENOEXEC; 694 goto bad; 695 696 case PT_INTERP: 697 /* Already did this one */ 698 case PT_DYNAMIC: 699 case PT_NOTE: 700 break; 701 702 case PT_PHDR: 703 /* Note address of program headers (in text segment) */ 704 phdr = pp->p_vaddr; 705 break; 706 707 default: 708 /* 709 * Not fatal, we don't need to understand everything 710 * :-) 711 */ 712 break; 713 } 714 } 715 716 phdr += exe_base; 717 718 /* 719 * Strangely some linux programs may have all load sections marked 720 * writeable, in this case, textsize is not -1, but rather 0; 721 */ 722 if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR)) 723 epp->ep_tsize = 0; 724 /* 725 * Another possibility is that it has all load sections marked 726 * read-only. Fake a zero-sized data segment right after the 727 * text segment. 728 */ 729 if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) { 730 epp->ep_daddr = round_page(epp->ep_taddr + epp->ep_tsize); 731 epp->ep_dsize = 0; 732 } 733 734 epp->ep_interp = interp; 735 epp->ep_entry = eh->e_entry + exe_base; 736 737 /* 738 * Check if we found a dynamically linked binary and arrange to load 739 * its interpreter when the exec file is released. 740 */ 741 if (interp) { 742 struct elf_args *ap; 743 744 ap = malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK); 745 746 ap->arg_phaddr = phdr; 747 ap->arg_phentsize = eh->e_phentsize; 748 ap->arg_phnum = eh->e_phnum; 749 ap->arg_entry = eh->e_entry + exe_base; 750 ap->arg_os = os; 751 752 epp->ep_emul_arg = ap; 753 epp->ep_interp_pos = pos; 754 } 755 756 #if defined(COMPAT_SVR4) && defined(i386) && 0 /* nothing sets OOS_DELL... */ 757 #ifndef ELF_MAP_PAGE_ZERO 758 /* Dell SVR4 maps page zero, yeuch! */ 759 if (p->p_os == OOS_DELL) 760 #endif 761 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0, 762 epp->ep_vp, 0, VM_PROT_READ); 763 #endif 764 765 free(ph, M_TEMP); 766 vn_marktext(epp->ep_vp); 767 return (exec_setup_stack(p, epp)); 768 769 bad: 770 if (interp) 771 pool_put(&namei_pool, interp); 772 free(ph, M_TEMP); 773 kill_vmcmds(&epp->ep_vmcmds); 774 return (ENOEXEC); 775 } 776 777 /* 778 * Phase II of load. It is now safe to load the interpreter. Info collected 779 * when loading the program is available for setup of the interpreter. 780 */ 781 int 782 ELFNAME2(exec,fixup)(struct proc *p, struct exec_package *epp) 783 { 784 char *interp; 785 int error; 786 struct elf_args *ap; 787 AuxInfo ai[ELF_AUX_ENTRIES], *a; 788 Elf_Addr pos = epp->ep_interp_pos; 789 790 if (epp->ep_interp == NULL) { 791 return (0); 792 } 793 794 interp = epp->ep_interp; 795 ap = epp->ep_emul_arg; 796 797 if ((error = ELFNAME(load_file)(p, interp, epp, ap, &pos)) != 0) { 798 free(ap, M_TEMP); 799 pool_put(&namei_pool, interp); 800 kill_vmcmds(&epp->ep_vmcmds); 801 return (error); 802 } 803 /* 804 * We have to do this ourselves... 805 */ 806 error = exec_process_vmcmds(p, epp); 807 808 /* 809 * Push extra arguments on the stack needed by dynamically 810 * linked binaries 811 */ 812 if (error == 0) { 813 a = ai; 814 815 a->au_id = AUX_phdr; 816 a->au_v = ap->arg_phaddr; 817 a++; 818 819 a->au_id = AUX_phent; 820 a->au_v = ap->arg_phentsize; 821 a++; 822 823 a->au_id = AUX_phnum; 824 a->au_v = ap->arg_phnum; 825 a++; 826 827 a->au_id = AUX_pagesz; 828 a->au_v = PAGE_SIZE; 829 a++; 830 831 a->au_id = AUX_base; 832 a->au_v = ap->arg_interp; 833 a++; 834 835 a->au_id = AUX_flags; 836 a->au_v = 0; 837 a++; 838 839 a->au_id = AUX_entry; 840 a->au_v = ap->arg_entry; 841 a++; 842 843 a->au_id = AUX_null; 844 a->au_v = 0; 845 a++; 846 847 error = copyout(ai, epp->ep_emul_argp, sizeof ai); 848 } 849 free(ap, M_TEMP); 850 pool_put(&namei_pool, interp); 851 return (error); 852 } 853 854 /* 855 * Older ELF binaries use EI_ABIVERSION (formerly EI_BRAND) to brand 856 * executables. Newer ELF binaries use EI_OSABI instead. 857 */ 858 char * 859 ELFNAME(check_brand)(Elf_Ehdr *eh) 860 { 861 if (eh->e_ident[EI_ABIVERSION] == '\0') 862 return (NULL); 863 return (&eh->e_ident[EI_ABIVERSION]); 864 } 865 866 int 867 ELFNAME(os_pt_note)(struct proc *p, struct exec_package *epp, Elf_Ehdr *eh, 868 char *os_name, size_t name_size, size_t desc_size) 869 { 870 Elf_Phdr *hph, *ph; 871 Elf_Note *np = NULL; 872 size_t phsize; 873 int error; 874 875 phsize = eh->e_phnum * sizeof(Elf_Phdr); 876 hph = malloc(phsize, M_TEMP, M_WAITOK); 877 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, 878 (caddr_t)hph, phsize)) != 0) 879 goto out1; 880 881 for (ph = hph; ph < &hph[eh->e_phnum]; ph++) { 882 if (ph->p_type != PT_NOTE || 883 ph->p_filesz > 1024 || 884 ph->p_filesz < sizeof(Elf_Note) + name_size) 885 continue; 886 887 np = malloc(ph->p_filesz, M_TEMP, M_WAITOK); 888 if ((error = ELFNAME(read_from)(p, epp->ep_vp, ph->p_offset, 889 (caddr_t)np, ph->p_filesz)) != 0) 890 goto out2; 891 892 #if 0 893 if (np->type != ELF_NOTE_TYPE_OSVERSION) { 894 free(np, M_TEMP); 895 np = NULL; 896 continue; 897 } 898 #endif 899 900 /* Check the name and description sizes. */ 901 if (np->namesz != name_size || 902 np->descsz != desc_size) 903 goto out3; 904 905 if (bcmp((np + 1), os_name, name_size)) 906 goto out3; 907 908 /* XXX: We could check for the specific emulation here */ 909 /* All checks succeeded. */ 910 error = 0; 911 goto out2; 912 } 913 914 out3: 915 error = ENOEXEC; 916 out2: 917 if (np) 918 free(np, M_TEMP); 919 out1: 920 free(hph, M_TEMP); 921 return error; 922 } 923 924 struct countsegs_state { 925 int npsections; 926 }; 927 928 int ELFNAMEEND(coredump_countsegs)(struct proc *, void *, 929 struct uvm_coredump_state *); 930 931 struct writesegs_state { 932 Elf_Phdr *psections; 933 off_t secoff; 934 }; 935 936 int ELFNAMEEND(coredump_writeseghdrs)(struct proc *, void *, 937 struct uvm_coredump_state *); 938 939 int ELFNAMEEND(coredump_notes)(struct proc *, void *, size_t *); 940 int ELFNAMEEND(coredump_note)(struct proc *, void *, size_t *); 941 int ELFNAMEEND(coredump_writenote)(struct proc *, void *, Elf_Note *, 942 const char *, void *); 943 944 #define ELFROUNDSIZE 4 /* XXX Should it be sizeof(Elf_Word)? */ 945 #define elfround(x) roundup((x), ELFROUNDSIZE) 946 947 int 948 ELFNAMEEND(coredump)(struct proc *p, void *cookie) 949 { 950 #ifdef SMALL_KERNEL 951 return EPERM; 952 #else 953 Elf_Ehdr ehdr; 954 Elf_Phdr phdr, *psections; 955 struct countsegs_state cs; 956 struct writesegs_state ws; 957 off_t notestart, secstart, offset; 958 size_t notesize; 959 int error, i; 960 961 psections = NULL; 962 /* 963 * We have to make a total of 3 passes across the map: 964 * 965 * 1. Count the number of map entries (the number of 966 * PT_LOAD sections). 967 * 968 * 2. Write the P-section headers. 969 * 970 * 3. Write the P-sections. 971 */ 972 973 /* Pass 1: count the entries. */ 974 cs.npsections = 0; 975 error = uvm_coredump_walkmap(p, NULL, 976 ELFNAMEEND(coredump_countsegs), &cs); 977 if (error) 978 goto out; 979 980 /* Count the PT_NOTE section. */ 981 cs.npsections++; 982 983 /* Get the size of the notes. */ 984 error = ELFNAMEEND(coredump_notes)(p, NULL, ¬esize); 985 if (error) 986 goto out; 987 988 memset(&ehdr, 0, sizeof(ehdr)); 989 memcpy(ehdr.e_ident, ELFMAG, SELFMAG); 990 ehdr.e_ident[EI_CLASS] = ELF_TARG_CLASS; 991 ehdr.e_ident[EI_DATA] = ELF_TARG_DATA; 992 ehdr.e_ident[EI_VERSION] = EV_CURRENT; 993 /* XXX Should be the OSABI/ABI version of the executable. */ 994 ehdr.e_ident[EI_OSABI] = ELFOSABI_SYSV; 995 ehdr.e_ident[EI_ABIVERSION] = 0; 996 ehdr.e_type = ET_CORE; 997 /* XXX This should be the e_machine of the executable. */ 998 ehdr.e_machine = ELF_TARG_MACH; 999 ehdr.e_version = EV_CURRENT; 1000 ehdr.e_entry = 0; 1001 ehdr.e_phoff = sizeof(ehdr); 1002 ehdr.e_shoff = 0; 1003 ehdr.e_flags = 0; 1004 ehdr.e_ehsize = sizeof(ehdr); 1005 ehdr.e_phentsize = sizeof(Elf_Phdr); 1006 ehdr.e_phnum = cs.npsections; 1007 ehdr.e_shentsize = 0; 1008 ehdr.e_shnum = 0; 1009 ehdr.e_shstrndx = 0; 1010 1011 /* Write out the ELF header. */ 1012 error = coredump_write(cookie, UIO_SYSSPACE, &ehdr, sizeof(ehdr)); 1013 if (error) 1014 goto out; 1015 1016 offset = sizeof(ehdr); 1017 1018 notestart = offset + sizeof(phdr) * cs.npsections; 1019 secstart = notestart + notesize; 1020 1021 psections = malloc(cs.npsections * sizeof(Elf_Phdr), 1022 M_TEMP, M_WAITOK|M_ZERO); 1023 1024 /* Pass 2: now write the P-section headers. */ 1025 ws.secoff = secstart; 1026 ws.psections = psections; 1027 error = uvm_coredump_walkmap(p, cookie, 1028 ELFNAMEEND(coredump_writeseghdrs), &ws); 1029 if (error) 1030 goto out; 1031 1032 /* Write out the PT_NOTE header. */ 1033 ws.psections->p_type = PT_NOTE; 1034 ws.psections->p_offset = notestart; 1035 ws.psections->p_vaddr = 0; 1036 ws.psections->p_paddr = 0; 1037 ws.psections->p_filesz = notesize; 1038 ws.psections->p_memsz = 0; 1039 ws.psections->p_flags = PF_R; 1040 ws.psections->p_align = ELFROUNDSIZE; 1041 1042 error = coredump_write(cookie, UIO_SYSSPACE, psections, 1043 cs.npsections * sizeof(Elf_Phdr)); 1044 if (error) 1045 goto out; 1046 1047 #ifdef DIAGNOSTIC 1048 offset += cs.npsections * sizeof(Elf_Phdr); 1049 if (offset != notestart) 1050 panic("coredump: offset %lld != notestart %lld", 1051 (long long) offset, (long long) notestart); 1052 #endif 1053 1054 /* Write out the notes. */ 1055 error = ELFNAMEEND(coredump_notes)(p, cookie, ¬esize); 1056 if (error) 1057 goto out; 1058 1059 #ifdef DIAGNOSTIC 1060 offset += notesize; 1061 if (offset != secstart) 1062 panic("coredump: offset %lld != secstart %lld", 1063 (long long) offset, (long long) secstart); 1064 #endif 1065 1066 /* Pass 3: finally, write the sections themselves. */ 1067 for (i = 0; i < cs.npsections - 1; i++) { 1068 if (psections[i].p_filesz == 0) 1069 continue; 1070 1071 #ifdef DIAGNOSTIC 1072 if (offset != psections[i].p_offset) 1073 panic("coredump: offset %lld != p_offset[%d] %lld", 1074 (long long) offset, i, 1075 (long long) psections[i].p_filesz); 1076 #endif 1077 1078 error = coredump_write(cookie, UIO_USERSPACE, 1079 (void *)(vaddr_t)psections[i].p_vaddr, 1080 psections[i].p_filesz); 1081 if (error) 1082 goto out; 1083 1084 #ifdef DIAGNOSTIC 1085 offset += psections[i].p_filesz; 1086 #endif 1087 } 1088 1089 out: 1090 return (error); 1091 #endif 1092 } 1093 1094 int 1095 ELFNAMEEND(coredump_countsegs)(struct proc *p, void *iocookie, 1096 struct uvm_coredump_state *us) 1097 { 1098 #ifndef SMALL_KERNEL 1099 struct countsegs_state *cs = us->cookie; 1100 1101 cs->npsections++; 1102 #endif 1103 return (0); 1104 } 1105 1106 int 1107 ELFNAMEEND(coredump_writeseghdrs)(struct proc *p, void *iocookie, 1108 struct uvm_coredump_state *us) 1109 { 1110 #ifndef SMALL_KERNEL 1111 struct writesegs_state *ws = us->cookie; 1112 Elf_Phdr phdr; 1113 vsize_t size, realsize; 1114 1115 size = us->end - us->start; 1116 realsize = us->realend - us->start; 1117 1118 phdr.p_type = PT_LOAD; 1119 phdr.p_offset = ws->secoff; 1120 phdr.p_vaddr = us->start; 1121 phdr.p_paddr = 0; 1122 phdr.p_filesz = realsize; 1123 phdr.p_memsz = size; 1124 phdr.p_flags = 0; 1125 if (us->prot & VM_PROT_READ) 1126 phdr.p_flags |= PF_R; 1127 if (us->prot & VM_PROT_WRITE) 1128 phdr.p_flags |= PF_W; 1129 if (us->prot & VM_PROT_EXECUTE) 1130 phdr.p_flags |= PF_X; 1131 phdr.p_align = PAGE_SIZE; 1132 1133 ws->secoff += phdr.p_filesz; 1134 *ws->psections++ = phdr; 1135 #endif 1136 1137 return (0); 1138 } 1139 1140 int 1141 ELFNAMEEND(coredump_notes)(struct proc *p, void *iocookie, size_t *sizep) 1142 { 1143 #ifndef SMALL_KERNEL 1144 struct ps_strings pss; 1145 struct iovec iov; 1146 struct uio uio; 1147 struct elfcore_procinfo cpi; 1148 Elf_Note nhdr; 1149 #ifdef RTHREADS 1150 struct proc *q; 1151 #endif 1152 size_t size, notesize; 1153 int error; 1154 1155 size = 0; 1156 1157 /* First, write an elfcore_procinfo. */ 1158 notesize = sizeof(nhdr) + elfround(sizeof("OpenBSD")) + 1159 elfround(sizeof(cpi)); 1160 if (iocookie) { 1161 bzero(&cpi, sizeof(cpi)); 1162 1163 cpi.cpi_version = ELFCORE_PROCINFO_VERSION; 1164 cpi.cpi_cpisize = sizeof(cpi); 1165 cpi.cpi_signo = p->p_sigacts->ps_sig; 1166 cpi.cpi_sigcode = p->p_sigacts->ps_code; 1167 1168 cpi.cpi_sigpend = p->p_siglist; 1169 cpi.cpi_sigmask = p->p_sigmask; 1170 cpi.cpi_sigignore = p->p_sigignore; 1171 cpi.cpi_sigcatch = p->p_sigcatch; 1172 1173 cpi.cpi_pid = p->p_pid; 1174 cpi.cpi_ppid = p->p_pptr->p_pid; 1175 cpi.cpi_pgrp = p->p_pgid; 1176 if (p->p_session->s_leader) 1177 cpi.cpi_sid = p->p_session->s_leader->p_pid; 1178 else 1179 cpi.cpi_sid = 0; 1180 1181 cpi.cpi_ruid = p->p_cred->p_ruid; 1182 cpi.cpi_euid = p->p_ucred->cr_uid; 1183 cpi.cpi_svuid = p->p_cred->p_svuid; 1184 1185 cpi.cpi_rgid = p->p_cred->p_rgid; 1186 cpi.cpi_egid = p->p_ucred->cr_gid; 1187 cpi.cpi_svgid = p->p_cred->p_svgid; 1188 1189 (void)strlcpy(cpi.cpi_name, p->p_comm, sizeof(cpi.cpi_name)); 1190 1191 nhdr.namesz = sizeof("OpenBSD"); 1192 nhdr.descsz = sizeof(cpi); 1193 nhdr.type = NT_OPENBSD_PROCINFO; 1194 1195 error = ELFNAMEEND(coredump_writenote)(p, iocookie, &nhdr, 1196 "OpenBSD", &cpi); 1197 if (error) 1198 return (error); 1199 } 1200 size += notesize; 1201 1202 /* Second, write an NT_OPENBSD_AUXV note. */ 1203 notesize = sizeof(nhdr) + elfround(sizeof("OpenBSD")) + 1204 elfround(p->p_emul->e_arglen * sizeof(char *)); 1205 if (iocookie) { 1206 iov.iov_base = &pss; 1207 iov.iov_len = sizeof(pss); 1208 uio.uio_iov = &iov; 1209 uio.uio_iovcnt = 1; 1210 uio.uio_offset = (off_t)PS_STRINGS; 1211 uio.uio_resid = sizeof(pss); 1212 uio.uio_segflg = UIO_SYSSPACE; 1213 uio.uio_rw = UIO_READ; 1214 uio.uio_procp = NULL; 1215 1216 error = uvm_io(&p->p_vmspace->vm_map, &uio, 0); 1217 if (error) 1218 return (error); 1219 1220 if (pss.ps_envstr == NULL) 1221 return (EIO); 1222 1223 nhdr.namesz = sizeof("OpenBSD"); 1224 nhdr.descsz = p->p_emul->e_arglen * sizeof(char *); 1225 nhdr.type = NT_OPENBSD_AUXV; 1226 1227 error = coredump_write(iocookie, UIO_SYSSPACE, 1228 &nhdr, sizeof(nhdr)); 1229 if (error) 1230 return (error); 1231 1232 error = coredump_write(iocookie, UIO_SYSSPACE, 1233 "OpenBSD", elfround(nhdr.namesz)); 1234 if (error) 1235 return (error); 1236 1237 error = coredump_write(iocookie, UIO_USERSPACE, 1238 pss.ps_envstr + pss.ps_nenvstr + 1, nhdr.descsz); 1239 if (error) 1240 return (error); 1241 } 1242 size += notesize; 1243 1244 #ifdef PT_WCOOKIE 1245 notesize = sizeof(nhdr) + elfround(sizeof("OpenBSD")) + 1246 elfround(sizeof(register_t)); 1247 if (iocookie) { 1248 register_t wcookie; 1249 1250 nhdr.namesz = sizeof("OpenBSD"); 1251 nhdr.descsz = sizeof(register_t); 1252 nhdr.type = NT_OPENBSD_WCOOKIE; 1253 1254 wcookie = process_get_wcookie(p); 1255 error = ELFNAMEEND(coredump_writenote)(p, iocookie, &nhdr, 1256 "OpenBSD", &wcookie); 1257 if (error) 1258 return (error); 1259 } 1260 size += notesize; 1261 #endif 1262 1263 /* 1264 * Now write the register info for the thread that caused the 1265 * coredump. 1266 */ 1267 error = ELFNAMEEND(coredump_note)(p, iocookie, ¬esize); 1268 if (error) 1269 return (error); 1270 size += notesize; 1271 1272 #ifdef RTHREADS 1273 /* 1274 * Now, for each thread, write the register info and any other 1275 * per-thread notes. Since we're dumping core, we don't bother 1276 * locking. 1277 */ 1278 TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) { 1279 if (q == p) /* we've taken care of this thread */ 1280 continue; 1281 error = ELFNAMEEND(coredump_note)(q, iocookie, ¬esize); 1282 if (error) 1283 return (error); 1284 size += notesize; 1285 } 1286 #endif 1287 1288 *sizep = size; 1289 #endif 1290 return (0); 1291 } 1292 1293 int 1294 ELFNAMEEND(coredump_note)(struct proc *p, void *iocookie, size_t *sizep) 1295 { 1296 #ifndef SMALL_KERNEL 1297 Elf_Note nhdr; 1298 int size, notesize, error; 1299 int namesize; 1300 char name[64+ELFROUNDSIZE]; 1301 struct reg intreg; 1302 #ifdef PT_GETFPREGS 1303 struct fpreg freg; 1304 #endif 1305 1306 size = 0; 1307 1308 snprintf(name, sizeof(name)-ELFROUNDSIZE, "%s@%d", 1309 "OpenBSD", p->p_pid); 1310 namesize = strlen(name) + 1; 1311 memset(name + namesize, 0, elfround(namesize) - namesize); 1312 1313 notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(intreg)); 1314 if (iocookie) { 1315 error = process_read_regs(p, &intreg); 1316 if (error) 1317 return (error); 1318 1319 nhdr.namesz = namesize; 1320 nhdr.descsz = sizeof(intreg); 1321 nhdr.type = NT_OPENBSD_REGS; 1322 1323 error = ELFNAMEEND(coredump_writenote)(p, iocookie, &nhdr, 1324 name, &intreg); 1325 if (error) 1326 return (error); 1327 1328 } 1329 size += notesize; 1330 1331 #ifdef PT_GETFPREGS 1332 notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(freg)); 1333 if (iocookie) { 1334 error = process_read_fpregs(p, &freg); 1335 if (error) 1336 return (error); 1337 1338 nhdr.namesz = namesize; 1339 nhdr.descsz = sizeof(freg); 1340 nhdr.type = NT_OPENBSD_FPREGS; 1341 1342 error = ELFNAMEEND(coredump_writenote)(p, iocookie, &nhdr, 1343 name, &freg); 1344 if (error) 1345 return (error); 1346 } 1347 size += notesize; 1348 #endif 1349 1350 *sizep = size; 1351 /* XXX Add hook for machdep per-LWP notes. */ 1352 #endif 1353 return (0); 1354 } 1355 1356 int 1357 ELFNAMEEND(coredump_writenote)(struct proc *p, void *cookie, Elf_Note *nhdr, 1358 const char *name, void *data) 1359 { 1360 #ifdef SMALL_KERNEL 1361 return EPERM; 1362 #else 1363 int error; 1364 1365 error = coredump_write(cookie, UIO_SYSSPACE, nhdr, sizeof(*nhdr)); 1366 if (error) 1367 return error; 1368 1369 error = coredump_write(cookie, UIO_SYSSPACE, name, 1370 elfround(nhdr->namesz)); 1371 if (error) 1372 return error; 1373 1374 return coredump_write(cookie, UIO_SYSSPACE, data, nhdr->descsz); 1375 #endif 1376 } 1377