1 /* $OpenBSD: exec_elf.c,v 1.117 2015/09/28 20:32:59 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Per Fogelstrom 5 * All rights reserved. 6 * 7 * Copyright (c) 1994 Christos Zoulas 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34 /* 35 * Copyright (c) 2001 Wasabi Systems, Inc. 36 * All rights reserved. 37 * 38 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. All advertising materials mentioning features or use of this software 49 * must display the following acknowledgement: 50 * This product includes software developed for the NetBSD Project by 51 * Wasabi Systems, Inc. 52 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 53 * or promote products derived from this software without specific prior 54 * written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 58 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 59 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 60 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 61 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 62 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 64 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 * POSSIBILITY OF SUCH DAMAGE. 67 */ 68 69 #include <sys/param.h> 70 #include <sys/systm.h> 71 #include <sys/kernel.h> 72 #include <sys/proc.h> 73 #include <sys/malloc.h> 74 #include <sys/pool.h> 75 #include <sys/mount.h> 76 #include <sys/namei.h> 77 #include <sys/vnode.h> 78 #include <sys/core.h> 79 #include <sys/exec.h> 80 #include <sys/exec_elf.h> 81 #include <sys/file.h> 82 #include <sys/ptrace.h> 83 #include <sys/syscall.h> 84 #include <sys/signalvar.h> 85 #include <sys/stat.h> 86 87 #include <sys/mman.h> 88 89 #include <uvm/uvm_extern.h> 90 91 #include <machine/reg.h> 92 #include <machine/exec.h> 93 94 #ifdef COMPAT_LINUX 95 #include <compat/linux/linux_exec.h> 96 #endif 97 98 struct ELFNAME(probe_entry) { 99 int (*func)(struct proc *, struct exec_package *, char *, 100 u_long *); 101 } ELFNAME(probes)[] = { 102 /* XXX - bogus, shouldn't be size independent.. */ 103 #ifdef COMPAT_LINUX 104 { linux_elf_probe }, 105 #endif 106 { NULL } 107 }; 108 109 int ELFNAME(load_file)(struct proc *, char *, struct exec_package *, 110 struct elf_args *, Elf_Addr *); 111 int ELFNAME(check_header)(Elf_Ehdr *); 112 int ELFNAME(read_from)(struct proc *, struct vnode *, u_long, caddr_t, int); 113 void ELFNAME(load_psection)(struct exec_vmcmd_set *, struct vnode *, 114 Elf_Phdr *, Elf_Addr *, Elf_Addr *, int *, int); 115 int ELFNAMEEND(coredump)(struct proc *, void *); 116 117 extern char sigcode[], esigcode[]; 118 #ifdef SYSCALL_DEBUG 119 extern char *syscallnames[]; 120 #endif 121 122 /* round up and down to page boundaries. */ 123 #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) 124 #define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) 125 126 /* 127 * We limit the number of program headers to 32, this should 128 * be a reasonable limit for ELF, the most we have seen so far is 12 129 */ 130 #define ELF_MAX_VALID_PHDR 32 131 132 /* 133 * This is the basic elf emul. elf_probe_funcs may change to other emuls. 134 */ 135 struct emul ELFNAMEEND(emul) = { 136 "native", 137 NULL, 138 sendsig, 139 SYS_syscall, 140 SYS_MAXSYSCALL, 141 sysent, 142 #ifdef SYSCALL_DEBUG 143 syscallnames, 144 #else 145 NULL, 146 #endif 147 (sizeof(AuxInfo) * ELF_AUX_ENTRIES / sizeof(char *)), 148 ELFNAME(copyargs), 149 setregs, 150 ELFNAME2(exec,fixup), 151 ELFNAMEEND(coredump), 152 sigcode, 153 esigcode, 154 EMUL_ENABLED | EMUL_NATIVE, 155 }; 156 157 /* 158 * Copy arguments onto the stack in the normal way, but add some 159 * space for extra information in case of dynamic binding. 160 */ 161 void * 162 ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo, 163 void *stack, void *argp) 164 { 165 stack = copyargs(pack, arginfo, stack, argp); 166 if (!stack) 167 return (NULL); 168 169 /* 170 * Push space for extra arguments on the stack needed by 171 * dynamically linked binaries. 172 */ 173 if (pack->ep_emul_arg != NULL) { 174 pack->ep_emul_argp = stack; 175 stack = (char *)stack + ELF_AUX_ENTRIES * sizeof (AuxInfo); 176 } 177 return (stack); 178 } 179 180 /* 181 * Check header for validity; return 0 for ok, ENOEXEC if error 182 */ 183 int 184 ELFNAME(check_header)(Elf_Ehdr *ehdr) 185 { 186 /* 187 * We need to check magic, class size, endianess, and version before 188 * we look at the rest of the Elf_Ehdr structure. These few elements 189 * are represented in a machine independent fashion. 190 */ 191 if (!IS_ELF(*ehdr) || 192 ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 193 ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || 194 ehdr->e_ident[EI_VERSION] != ELF_TARG_VER) 195 return (ENOEXEC); 196 197 /* Now check the machine dependent header */ 198 if (ehdr->e_machine != ELF_TARG_MACH || 199 ehdr->e_version != ELF_TARG_VER) 200 return (ENOEXEC); 201 202 /* Don't allow an insane amount of sections. */ 203 if (ehdr->e_phnum > ELF_MAX_VALID_PHDR) 204 return (ENOEXEC); 205 206 return (0); 207 } 208 209 /* 210 * Load a psection at the appropriate address 211 */ 212 void 213 ELFNAME(load_psection)(struct exec_vmcmd_set *vcset, struct vnode *vp, 214 Elf_Phdr *ph, Elf_Addr *addr, Elf_Addr *size, int *prot, int flags) 215 { 216 u_long msize, lsize, psize, rm, rf; 217 long diff, offset, bdiff; 218 Elf_Addr base; 219 220 /* 221 * If the user specified an address, then we load there. 222 */ 223 if (*addr != ELFDEFNNAME(NO_ADDR)) { 224 if (ph->p_align > 1) { 225 *addr = ELF_TRUNC(*addr, ph->p_align); 226 diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align); 227 /* page align vaddr */ 228 base = *addr + trunc_page(ph->p_vaddr) 229 - ELF_TRUNC(ph->p_vaddr, ph->p_align); 230 } else { 231 diff = 0; 232 base = *addr + trunc_page(ph->p_vaddr) - ph->p_vaddr; 233 } 234 } else { 235 *addr = ph->p_vaddr; 236 if (ph->p_align > 1) 237 *addr = ELF_TRUNC(*addr, ph->p_align); 238 base = trunc_page(ph->p_vaddr); 239 diff = ph->p_vaddr - *addr; 240 } 241 bdiff = ph->p_vaddr - trunc_page(ph->p_vaddr); 242 243 *prot |= (ph->p_flags & PF_R) ? PROT_READ : 0; 244 *prot |= (ph->p_flags & PF_W) ? PROT_WRITE : 0; 245 *prot |= (ph->p_flags & PF_X) ? PROT_EXEC : 0; 246 247 msize = ph->p_memsz + diff; 248 offset = ph->p_offset - bdiff; 249 lsize = ph->p_filesz + bdiff; 250 psize = round_page(lsize); 251 252 /* 253 * Because the pagedvn pager can't handle zero fill of the last 254 * data page if it's not page aligned we map the last page readvn. 255 */ 256 if (ph->p_flags & PF_W) { 257 psize = trunc_page(lsize); 258 if (psize > 0) 259 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, 260 offset, *prot, flags); 261 if (psize != lsize) { 262 NEW_VMCMD2(vcset, vmcmd_map_readvn, lsize - psize, 263 base + psize, vp, offset + psize, *prot, flags); 264 } 265 } else { 266 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, offset, 267 *prot, flags); 268 } 269 270 /* 271 * Check if we need to extend the size of the segment 272 */ 273 rm = round_page(*addr + ph->p_memsz + diff); 274 rf = round_page(*addr + ph->p_filesz + diff); 275 276 if (rm != rf) { 277 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0, 278 *prot, flags); 279 } 280 *size = msize; 281 } 282 283 /* 284 * Read from vnode into buffer at offset. 285 */ 286 int 287 ELFNAME(read_from)(struct proc *p, struct vnode *vp, u_long off, caddr_t buf, 288 int size) 289 { 290 int error; 291 size_t resid; 292 293 if ((error = vn_rdwr(UIO_READ, vp, buf, size, off, UIO_SYSSPACE, 294 0, p->p_ucred, &resid, p)) != 0) 295 return error; 296 /* 297 * See if we got all of it 298 */ 299 if (resid != 0) 300 return (ENOEXEC); 301 return (0); 302 } 303 304 /* 305 * Load a file (interpreter/library) pointed to by path [stolen from 306 * coff_load_shlib()]. Made slightly generic so it might be used externally. 307 */ 308 int 309 ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp, 310 struct elf_args *ap, Elf_Addr *last) 311 { 312 int error, i; 313 struct nameidata nd; 314 Elf_Ehdr eh; 315 Elf_Phdr *ph = NULL; 316 u_long phsize; 317 Elf_Addr addr; 318 struct vnode *vp; 319 Elf_Phdr *base_ph = NULL; 320 struct interp_ld_sec { 321 Elf_Addr vaddr; 322 u_long memsz; 323 } loadmap[ELF_MAX_VALID_PHDR]; 324 int nload, idx = 0; 325 Elf_Addr pos = *last; 326 int file_align; 327 int loop; 328 size_t randomizequota = ELF_RANDOMIZE_LIMIT; 329 330 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 331 if ((error = namei(&nd)) != 0) { 332 return (error); 333 } 334 vp = nd.ni_vp; 335 if (vp->v_type != VREG) { 336 error = EACCES; 337 goto bad; 338 } 339 if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0) 340 goto bad; 341 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 342 error = EACCES; 343 goto bad; 344 } 345 if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0) 346 goto bad1; 347 if ((error = ELFNAME(read_from)(p, nd.ni_vp, 0, 348 (caddr_t)&eh, sizeof(eh))) != 0) 349 goto bad1; 350 351 if (ELFNAME(check_header)(&eh) || eh.e_type != ET_DYN) { 352 error = ENOEXEC; 353 goto bad1; 354 } 355 356 ph = mallocarray(eh.e_phnum, sizeof(Elf_Phdr), M_TEMP, M_WAITOK); 357 phsize = eh.e_phnum * sizeof(Elf_Phdr); 358 359 if ((error = ELFNAME(read_from)(p, nd.ni_vp, eh.e_phoff, (caddr_t)ph, 360 phsize)) != 0) 361 goto bad1; 362 363 for (i = 0; i < eh.e_phnum; i++) { 364 if (ph[i].p_type == PT_LOAD) { 365 if (ph[i].p_filesz > ph[i].p_memsz) 366 goto bad1; 367 loadmap[idx].vaddr = trunc_page(ph[i].p_vaddr); 368 loadmap[idx].memsz = round_page (ph[i].p_vaddr + 369 ph[i].p_memsz - loadmap[idx].vaddr); 370 file_align = ph[i].p_align; 371 idx++; 372 } 373 } 374 nload = idx; 375 376 /* 377 * If no position to load the interpreter was set by a probe 378 * function, pick the same address that a non-fixed mmap(0, ..) 379 * would (i.e. something safely out of the way). 380 */ 381 if (pos == ELFDEFNNAME(NO_ADDR)) { 382 pos = uvm_map_hint(p->p_vmspace, PROT_EXEC, 383 VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS); 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 free(ph, M_TEMP, phsize); 495 496 *last = addr; 497 vput(nd.ni_vp); 498 return (error); 499 } 500 501 /* 502 * Prepare an Elf binary's exec package 503 * 504 * First, set of the various offsets/lengths in the exec package. 505 * 506 * Then, mark the text image busy (so it can be demand paged) or error out if 507 * this is not possible. Finally, set up vmcmds for the text, data, bss, and 508 * stack segments. 509 */ 510 int 511 ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) 512 { 513 Elf_Ehdr *eh = epp->ep_hdr; 514 Elf_Phdr *ph, *pp, *base_ph = NULL; 515 Elf_Addr phdr = 0, exe_base = 0; 516 int error, i, has_phdr = 0; 517 char *interp = NULL; 518 u_long pos = 0, phsize; 519 size_t randomizequota = ELF_RANDOMIZE_LIMIT; 520 521 if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) 522 return (ENOEXEC); 523 524 if (ELFNAME(check_header)(eh) || 525 (eh->e_type != ET_EXEC && eh->e_type != ET_DYN)) 526 return (ENOEXEC); 527 528 /* 529 * check if vnode is in open for writing, because we want to demand- 530 * page out of it. if it is, don't do it, for various reasons. 531 */ 532 if (epp->ep_vp->v_writecount != 0) { 533 #ifdef DIAGNOSTIC 534 if (epp->ep_vp->v_flag & VTEXT) 535 panic("exec: a VTEXT vnode has writecount != 0"); 536 #endif 537 return (ETXTBSY); 538 } 539 /* 540 * Allocate space to hold all the program headers, and read them 541 * from the file 542 */ 543 ph = mallocarray(eh->e_phnum, sizeof(Elf_Phdr), M_TEMP, M_WAITOK); 544 phsize = eh->e_phnum * sizeof(Elf_Phdr); 545 546 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph, 547 phsize)) != 0) 548 goto bad; 549 550 epp->ep_tsize = ELFDEFNNAME(NO_ADDR); 551 epp->ep_dsize = ELFDEFNNAME(NO_ADDR); 552 553 for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) { 554 if (pp->p_type == PT_INTERP && !interp) { 555 if (pp->p_filesz < 2 || pp->p_filesz > MAXPATHLEN) 556 goto bad; 557 interp = pool_get(&namei_pool, PR_WAITOK); 558 if ((error = ELFNAME(read_from)(p, epp->ep_vp, 559 pp->p_offset, interp, pp->p_filesz)) != 0) { 560 goto bad; 561 } 562 if (interp[pp->p_filesz - 1] != '\0') 563 goto bad; 564 } else if (pp->p_type == PT_LOAD) { 565 if (pp->p_filesz > pp->p_memsz) { 566 error = EINVAL; 567 goto bad; 568 } 569 if (base_ph == NULL) 570 base_ph = pp; 571 } else if (pp->p_type == PT_PHDR) { 572 has_phdr = 1; 573 } 574 } 575 576 if (eh->e_type == ET_DYN) { 577 /* need phdr and load sections for PIE */ 578 if (!has_phdr || base_ph == NULL) { 579 error = EINVAL; 580 goto bad; 581 } 582 /* randomize exe_base for PIE */ 583 exe_base = uvm_map_pie(base_ph->p_align); 584 } 585 586 /* 587 * OK, we want a slightly different twist of the 588 * standard emulation package for "real" elf. 589 */ 590 epp->ep_emul = &ELFNAMEEND(emul); 591 pos = ELFDEFNNAME(NO_ADDR); 592 593 /* 594 * On the same architecture, we may be emulating different systems. 595 * See which one will accept this executable. 596 * 597 * Probe functions would normally see if the interpreter (if any) 598 * exists. Emulation packages may possibly replace the interpreter in 599 * *interp with a changed path (/emul/xxx/<path>), and also 600 * set the ep_emul field in the exec package structure. 601 */ 602 error = ENOEXEC; 603 if (eh->e_ident[EI_OSABI] != ELFOSABI_OPENBSD && 604 ELFNAME(os_pt_note)(p, epp, epp->ep_hdr, "OpenBSD", 8, 4) != 0) { 605 for (i = 0; ELFNAME(probes)[i].func != NULL && error; i++) 606 error = (*ELFNAME(probes)[i].func)(p, epp, interp, &pos); 607 if (error) 608 goto bad; 609 } 610 611 /* 612 * Load all the necessary sections 613 */ 614 for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) { 615 Elf_Addr addr, size = 0; 616 int prot = 0; 617 int flags = 0; 618 619 switch (pp->p_type) { 620 case PT_LOAD: 621 if (exe_base != 0) { 622 if (pp == base_ph) { 623 flags = VMCMD_BASE; 624 addr = exe_base; 625 } else { 626 flags = VMCMD_RELATIVE; 627 addr = pp->p_vaddr - base_ph->p_vaddr; 628 } 629 } else 630 addr = ELFDEFNNAME(NO_ADDR); 631 632 /* 633 * Calculates size of text and data segments 634 * by starting at first and going to end of last. 635 * 'rwx' sections are treated as data. 636 * this is correct for BSS_PLT, but may not be 637 * for DATA_PLT, is fine for TEXT_PLT. 638 */ 639 ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp, 640 pp, &addr, &size, &prot, flags); 641 642 /* 643 * Update exe_base in case alignment was off. 644 * For PIE, addr is relative to exe_base so 645 * adjust it (non PIE exe_base is 0 so no change). 646 */ 647 if (flags == VMCMD_BASE) 648 exe_base = addr; 649 else 650 addr += exe_base; 651 652 /* 653 * Decide whether it's text or data by looking 654 * at the protection of the section 655 */ 656 if (prot & PROT_WRITE) { 657 /* data section */ 658 if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) { 659 epp->ep_daddr = addr; 660 epp->ep_dsize = size; 661 } else { 662 if (addr < epp->ep_daddr) { 663 epp->ep_dsize = 664 epp->ep_dsize + 665 epp->ep_daddr - 666 addr; 667 epp->ep_daddr = addr; 668 } else 669 epp->ep_dsize = addr+size - 670 epp->ep_daddr; 671 } 672 } else if (prot & PROT_EXEC) { 673 /* text section */ 674 if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR)) { 675 epp->ep_taddr = addr; 676 epp->ep_tsize = size; 677 } else { 678 if (addr < epp->ep_taddr) { 679 epp->ep_tsize = 680 epp->ep_tsize + 681 epp->ep_taddr - 682 addr; 683 epp->ep_taddr = addr; 684 } else 685 epp->ep_tsize = addr+size - 686 epp->ep_taddr; 687 } 688 } 689 break; 690 691 case PT_SHLIB: 692 error = ENOEXEC; 693 goto bad; 694 695 case PT_INTERP: 696 /* Already did this one */ 697 case PT_DYNAMIC: 698 case PT_NOTE: 699 break; 700 701 case PT_PHDR: 702 /* Note address of program headers (in text segment) */ 703 phdr = pp->p_vaddr; 704 break; 705 706 case PT_OPENBSD_RANDOMIZE: 707 if (ph[i].p_memsz > randomizequota) { 708 error = ENOMEM; 709 goto bad; 710 } 711 randomizequota -= ph[i].p_memsz; 712 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_randomize, 713 ph[i].p_memsz, ph[i].p_vaddr + exe_base, NULLVP, 0, 0); 714 break; 715 716 default: 717 /* 718 * Not fatal, we don't need to understand everything 719 * :-) 720 */ 721 break; 722 } 723 } 724 725 phdr += exe_base; 726 727 /* 728 * Strangely some linux programs may have all load sections marked 729 * writeable, in this case, textsize is not -1, but rather 0; 730 */ 731 if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR)) 732 epp->ep_tsize = 0; 733 /* 734 * Another possibility is that it has all load sections marked 735 * read-only. Fake a zero-sized data segment right after the 736 * text segment. 737 */ 738 if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) { 739 epp->ep_daddr = round_page(epp->ep_taddr + epp->ep_tsize); 740 epp->ep_dsize = 0; 741 } 742 743 epp->ep_interp = interp; 744 epp->ep_entry = eh->e_entry + exe_base; 745 746 /* 747 * Check if we found a dynamically linked binary and arrange to load 748 * its interpreter when the exec file is released. 749 */ 750 if (interp || eh->e_type == ET_DYN) { 751 struct elf_args *ap; 752 753 ap = malloc(sizeof(*ap), M_TEMP, M_WAITOK); 754 755 ap->arg_phaddr = phdr; 756 ap->arg_phentsize = eh->e_phentsize; 757 ap->arg_phnum = eh->e_phnum; 758 ap->arg_entry = eh->e_entry + exe_base; 759 ap->arg_interp = exe_base; 760 761 epp->ep_emul_arg = ap; 762 epp->ep_emul_argsize = sizeof *ap; 763 epp->ep_interp_pos = pos; 764 } 765 766 free(ph, M_TEMP, phsize); 767 vn_marktext(epp->ep_vp); 768 return (exec_setup_stack(p, epp)); 769 770 bad: 771 if (interp) 772 pool_put(&namei_pool, interp); 773 free(ph, M_TEMP, phsize); 774 kill_vmcmds(&epp->ep_vmcmds); 775 if (error == 0) 776 return (ENOEXEC); 777 return (error); 778 } 779 780 /* 781 * Phase II of load. It is now safe to load the interpreter. Info collected 782 * when loading the program is available for setup of the interpreter. 783 */ 784 int 785 ELFNAME2(exec,fixup)(struct proc *p, struct exec_package *epp) 786 { 787 char *interp; 788 int error = 0; 789 struct elf_args *ap; 790 AuxInfo ai[ELF_AUX_ENTRIES], *a; 791 Elf_Addr pos = epp->ep_interp_pos; 792 793 if (epp->ep_emul_arg == NULL) { 794 return (0); 795 } 796 797 interp = epp->ep_interp; 798 ap = epp->ep_emul_arg; 799 800 if (interp && 801 (error = ELFNAME(load_file)(p, interp, epp, ap, &pos)) != 0) { 802 free(ap, M_TEMP, epp->ep_emul_argsize); 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, epp->ep_emul_argsize); 854 if (interp) 855 pool_put(&namei_pool, interp); 856 return (error); 857 } 858 859 /* 860 * Older ELF binaries use EI_ABIVERSION (formerly EI_BRAND) to brand 861 * executables. Newer ELF binaries use EI_OSABI instead. 862 */ 863 char * 864 ELFNAME(check_brand)(Elf_Ehdr *eh) 865 { 866 if (eh->e_ident[EI_ABIVERSION] == '\0') 867 return (NULL); 868 return (&eh->e_ident[EI_ABIVERSION]); 869 } 870 871 int 872 ELFNAME(os_pt_note)(struct proc *p, struct exec_package *epp, Elf_Ehdr *eh, 873 char *os_name, size_t name_size, size_t desc_size) 874 { 875 Elf_Phdr *hph, *ph; 876 Elf_Note *np = NULL; 877 size_t phsize; 878 int error; 879 880 hph = mallocarray(eh->e_phnum, sizeof(Elf_Phdr), M_TEMP, M_WAITOK); 881 phsize = eh->e_phnum * sizeof(Elf_Phdr); 882 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, 883 (caddr_t)hph, phsize)) != 0) 884 goto out1; 885 886 for (ph = hph; ph < &hph[eh->e_phnum]; ph++) { 887 if (ph->p_type != PT_NOTE || 888 ph->p_filesz > 1024 || 889 ph->p_filesz < sizeof(Elf_Note) + name_size) 890 continue; 891 892 np = malloc(ph->p_filesz, M_TEMP, M_WAITOK); 893 if ((error = ELFNAME(read_from)(p, epp->ep_vp, ph->p_offset, 894 (caddr_t)np, ph->p_filesz)) != 0) 895 goto out2; 896 897 #if 0 898 if (np->type != ELF_NOTE_TYPE_OSVERSION) { 899 free(np, M_TEMP, ph->p_filesz); 900 np = NULL; 901 continue; 902 } 903 #endif 904 905 /* Check the name and description sizes. */ 906 if (np->namesz != name_size || 907 np->descsz != desc_size) 908 goto out3; 909 910 if (memcmp((np + 1), os_name, name_size)) 911 goto out3; 912 913 /* XXX: We could check for the specific emulation here */ 914 /* All checks succeeded. */ 915 error = 0; 916 goto out2; 917 } 918 919 out3: 920 error = ENOEXEC; 921 out2: 922 free(np, M_TEMP, ph->p_filesz); 923 out1: 924 free(hph, M_TEMP, phsize); 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 *psections = NULL; 959 struct countsegs_state cs; 960 struct writesegs_state ws; 961 off_t notestart, secstart, offset; 962 size_t notesize, psectionslen; 963 int error, i; 964 965 /* 966 * We have to make a total of 3 passes across the map: 967 * 968 * 1. Count the number of map entries (the number of 969 * PT_LOAD sections). 970 * 971 * 2. Write the P-section headers. 972 * 973 * 3. Write the P-sections. 974 */ 975 976 /* Pass 1: count the entries. */ 977 cs.npsections = 0; 978 error = uvm_coredump_walkmap(p, NULL, 979 ELFNAMEEND(coredump_countsegs), &cs); 980 if (error) 981 goto out; 982 983 /* Count the PT_NOTE section. */ 984 cs.npsections++; 985 986 /* Get the size of the notes. */ 987 error = ELFNAMEEND(coredump_notes)(p, NULL, ¬esize); 988 if (error) 989 goto out; 990 991 memset(&ehdr, 0, sizeof(ehdr)); 992 memcpy(ehdr.e_ident, ELFMAG, SELFMAG); 993 ehdr.e_ident[EI_CLASS] = ELF_TARG_CLASS; 994 ehdr.e_ident[EI_DATA] = ELF_TARG_DATA; 995 ehdr.e_ident[EI_VERSION] = EV_CURRENT; 996 /* XXX Should be the OSABI/ABI version of the executable. */ 997 ehdr.e_ident[EI_OSABI] = ELFOSABI_SYSV; 998 ehdr.e_ident[EI_ABIVERSION] = 0; 999 ehdr.e_type = ET_CORE; 1000 /* XXX This should be the e_machine of the executable. */ 1001 ehdr.e_machine = ELF_TARG_MACH; 1002 ehdr.e_version = EV_CURRENT; 1003 ehdr.e_entry = 0; 1004 ehdr.e_phoff = sizeof(ehdr); 1005 ehdr.e_shoff = 0; 1006 ehdr.e_flags = 0; 1007 ehdr.e_ehsize = sizeof(ehdr); 1008 ehdr.e_phentsize = sizeof(Elf_Phdr); 1009 ehdr.e_phnum = cs.npsections; 1010 ehdr.e_shentsize = 0; 1011 ehdr.e_shnum = 0; 1012 ehdr.e_shstrndx = 0; 1013 1014 /* Write out the ELF header. */ 1015 error = coredump_write(cookie, UIO_SYSSPACE, &ehdr, sizeof(ehdr)); 1016 if (error) 1017 goto out; 1018 1019 psections = mallocarray(cs.npsections, sizeof(Elf_Phdr), 1020 M_TEMP, M_WAITOK|M_ZERO); 1021 psectionslen = cs.npsections * sizeof(Elf_Phdr); 1022 1023 offset = sizeof(ehdr); 1024 notestart = offset + psectionslen; 1025 secstart = notestart + notesize; 1026 1027 /* Pass 2: now write the P-section headers. */ 1028 ws.secoff = secstart; 1029 ws.psections = psections; 1030 error = uvm_coredump_walkmap(p, cookie, 1031 ELFNAMEEND(coredump_writeseghdrs), &ws); 1032 if (error) 1033 goto out; 1034 1035 /* Write out the PT_NOTE header. */ 1036 ws.psections->p_type = PT_NOTE; 1037 ws.psections->p_offset = notestart; 1038 ws.psections->p_vaddr = 0; 1039 ws.psections->p_paddr = 0; 1040 ws.psections->p_filesz = notesize; 1041 ws.psections->p_memsz = 0; 1042 ws.psections->p_flags = PF_R; 1043 ws.psections->p_align = ELFROUNDSIZE; 1044 1045 error = coredump_write(cookie, UIO_SYSSPACE, psections, psectionslen); 1046 if (error) 1047 goto out; 1048 1049 #ifdef DIAGNOSTIC 1050 offset += psectionslen; 1051 if (offset != notestart) 1052 panic("coredump: offset %lld != notestart %lld", 1053 (long long) offset, (long long) notestart); 1054 #endif 1055 1056 /* Write out the notes. */ 1057 error = ELFNAMEEND(coredump_notes)(p, cookie, ¬esize); 1058 if (error) 1059 goto out; 1060 1061 #ifdef DIAGNOSTIC 1062 offset += notesize; 1063 if (offset != secstart) 1064 panic("coredump: offset %lld != secstart %lld", 1065 (long long) offset, (long long) secstart); 1066 #endif 1067 1068 /* Pass 3: finally, write the sections themselves. */ 1069 for (i = 0; i < cs.npsections - 1; i++) { 1070 if (psections[i].p_filesz == 0) 1071 continue; 1072 1073 #ifdef DIAGNOSTIC 1074 if (offset != psections[i].p_offset) 1075 panic("coredump: offset %lld != p_offset[%d] %lld", 1076 (long long) offset, i, 1077 (long long) psections[i].p_filesz); 1078 #endif 1079 1080 error = coredump_write(cookie, UIO_USERSPACE, 1081 (void *)(vaddr_t)psections[i].p_vaddr, 1082 psections[i].p_filesz); 1083 if (error) 1084 goto out; 1085 1086 coredump_unmap(cookie, (vaddr_t)psections[i].p_vaddr, 1087 (vaddr_t)psections[i].p_vaddr + psections[i].p_filesz); 1088 1089 #ifdef DIAGNOSTIC 1090 offset += psections[i].p_filesz; 1091 #endif 1092 } 1093 1094 out: 1095 free(psections, M_TEMP, psectionslen); 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 & PROT_READ) 1132 phdr.p_flags |= PF_R; 1133 if (us->prot & PROT_WRITE) 1134 phdr.p_flags |= PF_W; 1135 if (us->prot & PROT_EXEC) 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 memset(&cpi, 0, 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 = pr->ps_sigacts->ps_sigignore; 1176 cpi.cpi_sigcatch = pr->ps_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_ucred->cr_ruid; 1187 cpi.cpi_euid = p->p_ucred->cr_uid; 1188 cpi.cpi_svuid = p->p_ucred->cr_svuid; 1189 1190 cpi.cpi_rgid = p->p_ucred->cr_rgid; 1191 cpi.cpi_egid = p->p_ucred->cr_gid; 1192 cpi.cpi_svgid = p->p_ucred->cr_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(pr->ps_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)pr->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 = pr->ps_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, all the other 1280 * threads in the process have been stopped and the list can't 1281 * change. 1282 */ 1283 TAILQ_FOREACH(q, &pr->ps_threads, p_thr_link) { 1284 if (q == p) /* we've taken care of this thread */ 1285 continue; 1286 error = ELFNAMEEND(coredump_note)(q, iocookie, ¬esize); 1287 if (error) 1288 return (error); 1289 size += notesize; 1290 } 1291 1292 *sizep = size; 1293 #endif 1294 return (0); 1295 } 1296 1297 int 1298 ELFNAMEEND(coredump_note)(struct proc *p, void *iocookie, size_t *sizep) 1299 { 1300 #ifndef SMALL_KERNEL 1301 Elf_Note nhdr; 1302 int size, notesize, error; 1303 int namesize; 1304 char name[64+ELFROUNDSIZE]; 1305 struct reg intreg; 1306 #ifdef PT_GETFPREGS 1307 struct fpreg freg; 1308 #endif 1309 1310 size = 0; 1311 1312 snprintf(name, sizeof(name)-ELFROUNDSIZE, "%s@%d", 1313 "OpenBSD", p->p_pid); 1314 namesize = strlen(name) + 1; 1315 memset(name + namesize, 0, elfround(namesize) - namesize); 1316 1317 notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(intreg)); 1318 if (iocookie) { 1319 error = process_read_regs(p, &intreg); 1320 if (error) 1321 return (error); 1322 1323 nhdr.namesz = namesize; 1324 nhdr.descsz = sizeof(intreg); 1325 nhdr.type = NT_OPENBSD_REGS; 1326 1327 error = ELFNAMEEND(coredump_writenote)(p, iocookie, &nhdr, 1328 name, &intreg); 1329 if (error) 1330 return (error); 1331 1332 } 1333 size += notesize; 1334 1335 #ifdef PT_GETFPREGS 1336 notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(freg)); 1337 if (iocookie) { 1338 error = process_read_fpregs(p, &freg); 1339 if (error) 1340 return (error); 1341 1342 nhdr.namesz = namesize; 1343 nhdr.descsz = sizeof(freg); 1344 nhdr.type = NT_OPENBSD_FPREGS; 1345 1346 error = ELFNAMEEND(coredump_writenote)(p, iocookie, &nhdr, 1347 name, &freg); 1348 if (error) 1349 return (error); 1350 } 1351 size += notesize; 1352 #endif 1353 1354 *sizep = size; 1355 /* XXX Add hook for machdep per-LWP notes. */ 1356 #endif 1357 return (0); 1358 } 1359 1360 int 1361 ELFNAMEEND(coredump_writenote)(struct proc *p, void *cookie, Elf_Note *nhdr, 1362 const char *name, void *data) 1363 { 1364 #ifdef SMALL_KERNEL 1365 return EPERM; 1366 #else 1367 int error; 1368 1369 error = coredump_write(cookie, UIO_SYSSPACE, nhdr, sizeof(*nhdr)); 1370 if (error) 1371 return error; 1372 1373 error = coredump_write(cookie, UIO_SYSSPACE, name, 1374 elfround(nhdr->namesz)); 1375 if (error) 1376 return error; 1377 1378 return coredump_write(cookie, UIO_SYSSPACE, data, nhdr->descsz); 1379 #endif 1380 } 1381