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