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