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