exec_elf32.c revision 1.64
1/* $NetBSD: exec_elf32.c,v 1.64 2001/07/14 02:08:29 christos Exp $ */ 2 3/*- 4 * Copyright (c) 1994, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christos Zoulas. 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. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39/* 40 * Copyright (c) 1996 Christopher G. Demetriou 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. The name of the author may not be used to endorse or promote products 52 * derived from this software without specific prior written permission 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 59 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 63 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 64 */ 65 66/* If not included by exec_elf64.c, ELFSIZE won't be defined. */ 67#ifndef ELFSIZE 68#define ELFSIZE 32 69#endif 70 71#include <sys/param.h> 72#include <sys/proc.h> 73#include <sys/malloc.h> 74#include <sys/namei.h> 75#include <sys/vnode.h> 76#include <sys/exec.h> 77#include <sys/exec_elf.h> 78#include <sys/syscall.h> 79#include <sys/signalvar.h> 80#include <sys/mount.h> 81#include <sys/stat.h> 82 83#include <machine/cpu.h> 84#include <machine/reg.h> 85 86extern const struct emul emul_netbsd; 87 88int ELFNAME(check_header)(Elf_Ehdr *, int); 89int ELFNAME(load_file)(struct proc *, struct exec_package *, char *, 90 struct exec_vmcmd_set *, u_long *, struct elf_args *, Elf_Addr *); 91void ELFNAME(load_psection)(struct exec_vmcmd_set *, struct vnode *, 92 const Elf_Phdr *, Elf_Addr *, u_long *, int *, int); 93 94int ELFNAME2(netbsd,signature)(struct proc *, struct exec_package *, 95 Elf_Ehdr *); 96int ELFNAME2(netbsd,probe)(struct proc *, struct exec_package *, 97 void *, char *, vaddr_t *); 98 99/* round up and down to page boundaries. */ 100#define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) 101#define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) 102 103/* 104 * Copy arguments onto the stack in the normal way, but add some 105 * extra information in case of dynamic binding. 106 */ 107void * 108ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo, 109 void *stack, void *argp) 110{ 111 size_t len; 112 AuxInfo ai[ELF_AUX_ENTRIES], *a; 113 struct elf_args *ap; 114 115 stack = copyargs(pack, arginfo, stack, argp); 116 if (!stack) 117 return NULL; 118 119 a = ai; 120 121 /* 122 * Push extra arguments on the stack needed by dynamically 123 * linked binaries 124 */ 125 if ((ap = (struct elf_args *)pack->ep_emul_arg)) { 126 127 a->a_type = AT_PHDR; 128 a->a_v = ap->arg_phaddr; 129 a++; 130 131 a->a_type = AT_PHENT; 132 a->a_v = ap->arg_phentsize; 133 a++; 134 135 a->a_type = AT_PHNUM; 136 a->a_v = ap->arg_phnum; 137 a++; 138 139 a->a_type = AT_PAGESZ; 140 a->a_v = PAGE_SIZE; 141 a++; 142 143 a->a_type = AT_BASE; 144 a->a_v = ap->arg_interp; 145 a++; 146 147 a->a_type = AT_FLAGS; 148 a->a_v = 0; 149 a++; 150 151 a->a_type = AT_ENTRY; 152 a->a_v = ap->arg_entry; 153 a++; 154 155 free((char *)ap, M_TEMP); 156 pack->ep_emul_arg = NULL; 157 } 158 159 a->a_type = AT_NULL; 160 a->a_v = 0; 161 a++; 162 163 len = (a - ai) * sizeof(AuxInfo); 164 if (copyout(ai, stack, len)) 165 return NULL; 166 stack = (caddr_t)stack + len; 167 168 return stack; 169} 170 171/* 172 * elf_check_header(): 173 * 174 * Check header for validity; return 0 of ok ENOEXEC if error 175 */ 176int 177ELFNAME(check_header)(Elf_Ehdr *eh, int type) 178{ 179 180 if (memcmp(eh->e_ident, ELFMAG, SELFMAG) != 0 || 181 eh->e_ident[EI_CLASS] != ELFCLASS) 182 return (ENOEXEC); 183 184 switch (eh->e_machine) { 185 186 ELFDEFNNAME(MACHDEP_ID_CASES) 187 188 default: 189 return (ENOEXEC); 190 } 191 192 if (eh->e_type != type) 193 return (ENOEXEC); 194 195 if (eh->e_shnum > 512 || 196 eh->e_phnum > 128) 197 return (ENOEXEC); 198 199 return (0); 200} 201 202/* 203 * elf_load_psection(): 204 * 205 * Load a psection at the appropriate address 206 */ 207void 208ELFNAME(load_psection)(struct exec_vmcmd_set *vcset, struct vnode *vp, 209 const Elf_Phdr *ph, Elf_Addr *addr, u_long *size, int *prot, int flags) 210{ 211 u_long uaddr, msize, psize, rm, rf; 212 long diff, offset; 213 214 /* 215 * If the user specified an address, then we load there. 216 */ 217 if (*addr != ELFDEFNNAME(NO_ADDR)) { 218 if (ph->p_align > 1) { 219 *addr = ELF_TRUNC(*addr, ph->p_align); 220 uaddr = ELF_TRUNC(ph->p_vaddr, ph->p_align); 221 } else 222 uaddr = ph->p_vaddr; 223 diff = ph->p_vaddr - uaddr; 224 } else { 225 *addr = uaddr = ph->p_vaddr; 226 if (ph->p_align > 1) 227 *addr = ELF_TRUNC(uaddr, ph->p_align); 228 diff = uaddr - *addr; 229 } 230 231 *prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0; 232 *prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0; 233 *prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0; 234 235 offset = ph->p_offset - diff; 236 *size = ph->p_filesz + diff; 237 msize = ph->p_memsz + diff; 238 psize = round_page(*size); 239 240 if ((ph->p_flags & PF_W) != 0) { 241 /* 242 * Because the pagedvn pager can't handle zero fill of the last 243 * data page if it's not page aligned we map the last page 244 * readvn. 245 */ 246 psize = trunc_page(*size); 247 } 248 if (psize > 0) { 249 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, *addr, vp, 250 offset, *prot, flags); 251 } 252 if (psize < *size) { 253 NEW_VMCMD2(vcset, vmcmd_map_readvn, *size - psize, 254 *addr + psize, vp, offset + psize, *prot, 255 psize > 0 ? flags & VMCMD_RELATIVE : flags); 256 } 257 258 /* 259 * Check if we need to extend the size of the segment 260 */ 261 rm = round_page(*addr + msize); 262 rf = round_page(*addr + *size); 263 264 if (rm != rf) { 265 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 266 0, *prot, flags & VMCMD_RELATIVE); 267 *size = msize; 268 } 269} 270 271/* 272 * elf_load_file(): 273 * 274 * Load a file (interpreter/library) pointed to by path 275 * [stolen from coff_load_shlib()]. Made slightly generic 276 * so it might be used externally. 277 */ 278int 279ELFNAME(load_file)(struct proc *p, struct exec_package *epp, char *path, 280 struct exec_vmcmd_set *vcset, u_long *entry, struct elf_args *ap, 281 Elf_Addr *last) 282{ 283 int error, i; 284 struct nameidata nd; 285 struct vnode *vp; 286 struct vattr attr; 287 Elf_Ehdr eh; 288 Elf_Phdr *ph = NULL; 289 Elf_Phdr *base_ph = NULL; 290 u_long phsize; 291 char *bp = NULL; 292 Elf_Addr addr = *last; 293 294 bp = path; 295 /* 296 * 1. open file 297 * 2. read filehdr 298 * 3. map text, data, and bss out of it using VM_* 299 */ 300 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 301 if ((error = namei(&nd)) != 0) 302 return error; 303 vp = nd.ni_vp; 304 305 /* 306 * Similarly, if it's not marked as executable, or it's not a regular 307 * file, we don't allow it to be used. 308 */ 309 if (vp->v_type != VREG) { 310 error = EACCES; 311 goto badunlock; 312 } 313 if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) != 0) 314 goto badunlock; 315 316 /* get attributes */ 317 if ((error = VOP_GETATTR(vp, &attr, p->p_ucred, p)) != 0) 318 goto badunlock; 319 320 /* 321 * Check mount point. Though we're not trying to exec this binary, 322 * we will be executing code from it, so if the mount point 323 * disallows execution or set-id-ness, we punt or kill the set-id. 324 */ 325 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 326 error = EACCES; 327 goto badunlock; 328 } 329 if (vp->v_mount->mnt_flag & MNT_NOSUID) 330 epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID); 331 332#ifdef notyet /* XXX cgd 960926 */ 333 XXX cgd 960926: (maybe) VOP_OPEN it (and VOP_CLOSE in copyargs?) 334#endif 335 VOP_UNLOCK(vp, 0); 336 337 if ((error = exec_read_from(p, vp, 0, &eh, sizeof(eh))) != 0) 338 goto bad; 339 340 if ((error = ELFNAME(check_header)(&eh, ET_DYN)) != 0) 341 goto bad; 342 343 phsize = eh.e_phnum * sizeof(Elf_Phdr); 344 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 345 346 if ((error = exec_read_from(p, vp, eh.e_phoff, ph, phsize)) != 0) 347 goto bad; 348 349 /* 350 * Load all the necessary sections 351 */ 352 for (i = 0; i < eh.e_phnum; i++) { 353 u_long size = 0; 354 int prot = 0; 355 int flags; 356 357 switch (ph[i].p_type) { 358 case PT_LOAD: 359 if (base_ph == NULL) { 360 addr = *last; 361 flags = VMCMD_BASE; 362 } else { 363 addr = ph[i].p_vaddr - base_ph->p_vaddr; 364 flags = VMCMD_RELATIVE; 365 } 366 ELFNAME(load_psection)(vcset, vp, &ph[i], &addr, 367 &size, &prot, flags); 368 /* If entry is within this section it must be text */ 369 if (eh.e_entry >= ph[i].p_vaddr && 370 eh.e_entry < (ph[i].p_vaddr + size)) { 371 /* XXX */ 372 *entry = addr + eh.e_entry; 373#ifdef mips 374 *entry -= ph[i].p_vaddr; 375#endif 376 ap->arg_interp = addr; 377 } 378 if (base_ph == NULL) 379 base_ph = &ph[i]; 380 addr += size; 381 break; 382 383 case PT_DYNAMIC: 384 case PT_PHDR: 385 case PT_NOTE: 386 break; 387 388 default: 389 break; 390 } 391 } 392 393 free((char *)ph, M_TEMP); 394 *last = addr; 395 vrele(vp); 396 return 0; 397 398badunlock: 399 VOP_UNLOCK(vp, 0); 400 401bad: 402 if (ph != NULL) 403 free((char *)ph, M_TEMP); 404#ifdef notyet /* XXX cgd 960926 */ 405 (maybe) VOP_CLOSE it 406#endif 407 vrele(vp); 408 return error; 409} 410 411/* 412 * exec_elf_makecmds(): Prepare an Elf binary's exec package 413 * 414 * First, set of the various offsets/lengths in the exec package. 415 * 416 * Then, mark the text image busy (so it can be demand paged) or error 417 * out if this is not possible. Finally, set up vmcmds for the 418 * text, data, bss, and stack segments. 419 */ 420int 421ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) 422{ 423 Elf_Ehdr *eh = epp->ep_hdr; 424 Elf_Phdr *ph, *pp; 425 Elf_Addr phdr = 0, pos = 0; 426 int error, i, nload; 427 char *interp = NULL; 428 u_long phsize; 429 430 if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) 431 return ENOEXEC; 432 433 /* 434 * XXX allow for executing shared objects. It seems silly 435 * but other ELF-based systems allow it as well. 436 */ 437 if (ELFNAME(check_header)(eh, ET_EXEC) != 0 && 438 ELFNAME(check_header)(eh, ET_DYN) != 0) 439 return ENOEXEC; 440 441 /* 442 * check if vnode is in open for writing, because we want to 443 * demand-page out of it. if it is, don't do it, for various 444 * reasons 445 */ 446 if (epp->ep_vp->v_writecount != 0) { 447#ifdef DIAGNOSTIC 448 if (epp->ep_vp->v_flag & VTEXT) 449 panic("exec: a VTEXT vnode has writecount != 0\n"); 450#endif 451 return ETXTBSY; 452 } 453 /* 454 * Allocate space to hold all the program headers, and read them 455 * from the file 456 */ 457 phsize = eh->e_phnum * sizeof(Elf_Phdr); 458 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 459 460 if ((error = exec_read_from(p, epp->ep_vp, eh->e_phoff, ph, phsize)) != 461 0) 462 goto bad; 463 464 epp->ep_taddr = epp->ep_tsize = ELFDEFNNAME(NO_ADDR); 465 epp->ep_daddr = epp->ep_dsize = ELFDEFNNAME(NO_ADDR); 466 467 MALLOC(interp, char *, MAXPATHLEN, M_TEMP, M_WAITOK); 468 interp[0] = '\0'; 469 470 for (i = 0; i < eh->e_phnum; i++) { 471 pp = &ph[i]; 472 if (pp->p_type == PT_INTERP) { 473 if (pp->p_filesz >= MAXPATHLEN) 474 goto bad; 475 if ((error = exec_read_from(p, epp->ep_vp, 476 pp->p_offset, interp, pp->p_filesz)) != 0) 477 goto bad; 478 break; 479 } 480 } 481 482 /* 483 * On the same architecture, we may be emulating different systems. 484 * See which one will accept this executable. This currently only 485 * applies to SVR4, and IBCS2 on the i386 and Linux on the i386 486 * and the Alpha. 487 * 488 * Probe functions would normally see if the interpreter (if any) 489 * exists. Emulation packages may possibly replace the interpreter in 490 * interp[] with a changed path (/emul/xxx/<path>). 491 */ 492 if (!epp->ep_esch->u.elf_probe_func) { 493 pos = ELFDEFNNAME(NO_ADDR); 494 } else { 495 vaddr_t startp = 0; 496 497 error = (*epp->ep_esch->u.elf_probe_func)(p, epp, eh, interp, 498 &startp); 499 pos = (Elf_Addr)startp; 500 if (error) 501 goto bad; 502 } 503 504 /* 505 * Load all the necessary sections 506 */ 507 for (i = nload = 0; i < eh->e_phnum; i++) { 508 Elf_Addr addr = ELFDEFNNAME(NO_ADDR); 509 u_long size = 0; 510 int prot = 0; 511 512 pp = &ph[i]; 513 514 switch (ph[i].p_type) { 515 case PT_LOAD: 516 /* 517 * XXX 518 * Can handle only 2 sections: text and data 519 */ 520 if (nload++ == 2) 521 goto bad; 522 ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp, 523 &ph[i], &addr, &size, &prot, 0); 524 525 /* 526 * Decide whether it's text or data by looking 527 * at the entry point. 528 */ 529 if (eh->e_entry >= addr && 530 eh->e_entry < (addr + size)) { 531 epp->ep_taddr = addr; 532 epp->ep_tsize = size; 533 if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) { 534 epp->ep_daddr = addr; 535 epp->ep_dsize = size; 536 } 537 } else { 538 epp->ep_daddr = addr; 539 epp->ep_dsize = size; 540 } 541 break; 542 543 case PT_SHLIB: 544 /* SCO has these sections. */ 545 case PT_INTERP: 546 /* Already did this one. */ 547 case PT_DYNAMIC: 548 case PT_NOTE: 549 break; 550 551 case PT_PHDR: 552 /* Note address of program headers (in text segment) */ 553 phdr = pp->p_vaddr; 554 break; 555 556 default: 557 /* 558 * Not fatal; we don't need to understand everything. 559 */ 560 break; 561 } 562 } 563 564 /* this breaks on, e.g., OpenBSD-compatible mips shared binaries. */ 565#ifndef ELF_INTERP_NON_RELOCATABLE 566 /* 567 * If no position to load the interpreter was set by a probe 568 * function, pick the same address that a non-fixed mmap(0, ..) 569 * would (i.e. something safely out of the way). 570 */ 571 if (pos == ELFDEFNNAME(NO_ADDR)) 572 pos = round_page(epp->ep_daddr + MAXDSIZ); 573#endif /* !ELF_INTERP_NON_RELOCATABLE */ 574 575 /* 576 * Check if we found a dynamically linked binary and arrange to load 577 * it's interpreter 578 */ 579 if (interp[0]) { 580 struct elf_args *ap; 581 582 MALLOC(ap, struct elf_args *, sizeof(struct elf_args), 583 M_TEMP, M_WAITOK); 584 if ((error = ELFNAME(load_file)(p, epp, interp, 585 &epp->ep_vmcmds, &epp->ep_entry, ap, &pos)) != 0) { 586 FREE((char *)ap, M_TEMP); 587 goto bad; 588 } 589 pos += phsize; 590 ap->arg_phaddr = phdr; 591 592 ap->arg_phentsize = eh->e_phentsize; 593 ap->arg_phnum = eh->e_phnum; 594 ap->arg_entry = eh->e_entry; 595 596 epp->ep_emul_arg = ap; 597 } else 598 epp->ep_entry = eh->e_entry; 599 600#ifdef ELF_MAP_PAGE_ZERO 601 /* Dell SVR4 maps page zero, yeuch! */ 602 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0, 603 epp->ep_vp, 0, VM_PROT_READ); 604#endif 605 FREE(interp, M_TEMP); 606 free((char *)ph, M_TEMP); 607 vn_marktext(epp->ep_vp); 608 return exec_elf_setup_stack(p, epp); 609 610bad: 611 if (interp) 612 FREE(interp, M_TEMP); 613 free((char *)ph, M_TEMP); 614 kill_vmcmds(&epp->ep_vmcmds); 615 return ENOEXEC; 616} 617 618int 619ELFNAME2(netbsd,signature)(struct proc *p, struct exec_package *epp, 620 Elf_Ehdr *eh) 621{ 622 size_t i; 623 Elf_Phdr *ph; 624 size_t phsize; 625 int error; 626 627 phsize = eh->e_phnum * sizeof(Elf_Phdr); 628 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 629 error = exec_read_from(p, epp->ep_vp, eh->e_phoff, ph, phsize); 630 if (error) 631 goto out; 632 633 for (i = 0; i < eh->e_phnum; i++) { 634 Elf_Phdr *ephp = &ph[i]; 635 Elf_Nhdr *np; 636 637 if (ephp->p_type != PT_NOTE || 638 ephp->p_filesz > 1024 || 639 ephp->p_filesz < sizeof(Elf_Nhdr) + ELF_NOTE_NETBSD_NAMESZ) 640 continue; 641 642 np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK); 643 error = exec_read_from(p, epp->ep_vp, ephp->p_offset, np, 644 ephp->p_filesz); 645 if (error) 646 goto next; 647 648 if (np->n_type != ELF_NOTE_TYPE_NETBSD_TAG || 649 np->n_namesz != ELF_NOTE_NETBSD_NAMESZ || 650 np->n_descsz != ELF_NOTE_NETBSD_DESCSZ || 651 memcmp((caddr_t)(np + 1), ELF_NOTE_NETBSD_NAME, 652 ELF_NOTE_NETBSD_NAMESZ)) 653 goto next; 654 655 error = 0; 656 free(np, M_TEMP); 657 goto out; 658 659 next: 660 free(np, M_TEMP); 661 continue; 662 } 663 664 error = ENOEXEC; 665out: 666 free(ph, M_TEMP); 667 return (error); 668} 669 670int 671ELFNAME2(netbsd,probe)(struct proc *p, struct exec_package *epp, 672 void *eh, char *itp, vaddr_t *pos) 673{ 674 int error; 675 676 if ((error = ELFNAME2(netbsd,signature)(p, epp, eh)) != 0) 677 return error; 678 *pos = ELFDEFNNAME(NO_ADDR); 679 return 0; 680} 681