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