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