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