exec_elf32.c revision 1.67
1/* $NetBSD: exec_elf32.c,v 1.67 2001/07/29 21:24:23 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 */ 107int 108ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo, 109 char **stackp, void *argp) 110{ 111 size_t len; 112 AuxInfo ai[ELF_AUX_ENTRIES], *a; 113 struct elf_args *ap; 114 int error; 115 116 if ((error = copyargs(pack, arginfo, stackp, argp)) != 0) 117 return error; 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 ((error = copyout(ai, *stackp, len)) != 0) 165 return error; 166 *stackp += len; 167 168 return 0; 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 239 if (ph->p_align >= PAGE_SIZE) { 240 if ((ph->p_flags & PF_W) != 0) { 241 /* 242 * Because the pagedvn pager can't handle zero fill 243 * of the last data page if it's not page aligned we 244 * map the last page readvn. 245 */ 246 psize = trunc_page(*size); 247 } else { 248 psize = round_page(*size); 249 } 250 } else { 251 psize = *size; 252 } 253 254 if (psize > 0) { 255 NEW_VMCMD2(vcset, ph->p_align < PAGE_SIZE ? 256 vmcmd_map_readvn : vmcmd_map_pagedvn, psize, *addr, vp, 257 offset, *prot, flags); 258 } 259 if (psize < *size) { 260 NEW_VMCMD2(vcset, vmcmd_map_readvn, *size - psize, 261 *addr + psize, vp, offset + psize, *prot, 262 psize > 0 ? flags & VMCMD_RELATIVE : flags); 263 } 264 265 /* 266 * Check if we need to extend the size of the segment 267 */ 268 rm = round_page(*addr + msize); 269 rf = round_page(*addr + *size); 270 271 if (rm != rf) { 272 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 273 0, *prot, flags & VMCMD_RELATIVE); 274 *size = msize; 275 } 276} 277 278/* 279 * elf_load_file(): 280 * 281 * Load a file (interpreter/library) pointed to by path 282 * [stolen from coff_load_shlib()]. Made slightly generic 283 * so it might be used externally. 284 */ 285int 286ELFNAME(load_file)(struct proc *p, struct exec_package *epp, char *path, 287 struct exec_vmcmd_set *vcset, u_long *entry, struct elf_args *ap, 288 Elf_Addr *last) 289{ 290 int error, i; 291 struct nameidata nd; 292 struct vnode *vp; 293 struct vattr attr; 294 Elf_Ehdr eh; 295 Elf_Phdr *ph = NULL; 296 Elf_Phdr *base_ph = NULL; 297 u_long phsize; 298 char *bp = NULL; 299 Elf_Addr addr = *last; 300 301 bp = path; 302 /* 303 * 1. open file 304 * 2. read filehdr 305 * 3. map text, data, and bss out of it using VM_* 306 */ 307 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 308 if ((error = namei(&nd)) != 0) 309 return error; 310 vp = nd.ni_vp; 311 312 /* 313 * Similarly, if it's not marked as executable, or it's not a regular 314 * file, we don't allow it to be used. 315 */ 316 if (vp->v_type != VREG) { 317 error = EACCES; 318 goto badunlock; 319 } 320 if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) != 0) 321 goto badunlock; 322 323 /* get attributes */ 324 if ((error = VOP_GETATTR(vp, &attr, p->p_ucred, p)) != 0) 325 goto badunlock; 326 327 /* 328 * Check mount point. Though we're not trying to exec this binary, 329 * we will be executing code from it, so if the mount point 330 * disallows execution or set-id-ness, we punt or kill the set-id. 331 */ 332 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 333 error = EACCES; 334 goto badunlock; 335 } 336 if (vp->v_mount->mnt_flag & MNT_NOSUID) 337 epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID); 338 339#ifdef notyet /* XXX cgd 960926 */ 340 XXX cgd 960926: (maybe) VOP_OPEN it (and VOP_CLOSE in copyargs?) 341#endif 342 VOP_UNLOCK(vp, 0); 343 344 if ((error = exec_read_from(p, vp, 0, &eh, sizeof(eh))) != 0) 345 goto bad; 346 347 if ((error = ELFNAME(check_header)(&eh, ET_DYN)) != 0) 348 goto bad; 349 350 phsize = eh.e_phnum * sizeof(Elf_Phdr); 351 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 352 353 if ((error = exec_read_from(p, vp, eh.e_phoff, ph, phsize)) != 0) 354 goto bad; 355 356 /* 357 * Load all the necessary sections 358 */ 359 for (i = 0; i < eh.e_phnum; i++) { 360 u_long size = 0; 361 int prot = 0; 362 int flags; 363 364 switch (ph[i].p_type) { 365 case PT_LOAD: 366 if (base_ph == NULL) { 367 addr = *last; 368 flags = VMCMD_BASE; 369 } else { 370 addr = ph[i].p_vaddr - base_ph->p_vaddr; 371 flags = VMCMD_RELATIVE; 372 } 373 ELFNAME(load_psection)(vcset, vp, &ph[i], &addr, 374 &size, &prot, flags); 375 /* If entry is within this section it must be text */ 376 if (eh.e_entry >= ph[i].p_vaddr && 377 eh.e_entry < (ph[i].p_vaddr + size)) { 378 /* XXX */ 379 *entry = addr + eh.e_entry; 380#ifdef mips 381 *entry -= ph[i].p_vaddr; 382#endif 383 ap->arg_interp = addr; 384 } 385 if (base_ph == NULL) 386 base_ph = &ph[i]; 387 addr += size; 388 break; 389 390 case PT_DYNAMIC: 391 case PT_PHDR: 392 case PT_NOTE: 393 break; 394 395 default: 396 break; 397 } 398 } 399 400 free((char *)ph, M_TEMP); 401 *last = addr; 402 vrele(vp); 403 return 0; 404 405badunlock: 406 VOP_UNLOCK(vp, 0); 407 408bad: 409 if (ph != NULL) 410 free((char *)ph, M_TEMP); 411#ifdef notyet /* XXX cgd 960926 */ 412 (maybe) VOP_CLOSE it 413#endif 414 vrele(vp); 415 return error; 416} 417 418/* 419 * exec_elf_makecmds(): Prepare an Elf binary's exec package 420 * 421 * First, set of the various offsets/lengths in the exec package. 422 * 423 * Then, mark the text image busy (so it can be demand paged) or error 424 * out if this is not possible. Finally, set up vmcmds for the 425 * text, data, bss, and stack segments. 426 */ 427int 428ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) 429{ 430 Elf_Ehdr *eh = epp->ep_hdr; 431 Elf_Phdr *ph, *pp; 432 Elf_Addr phdr = 0, pos = 0; 433 int error, i, nload; 434 char *interp = NULL; 435 u_long phsize; 436 437 if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) 438 return ENOEXEC; 439 440 /* 441 * XXX allow for executing shared objects. It seems silly 442 * but other ELF-based systems allow it as well. 443 */ 444 if (ELFNAME(check_header)(eh, ET_EXEC) != 0 && 445 ELFNAME(check_header)(eh, ET_DYN) != 0) 446 return ENOEXEC; 447 448 /* 449 * check if vnode is in open for writing, because we want to 450 * demand-page out of it. if it is, don't do it, for various 451 * reasons 452 */ 453 if (epp->ep_vp->v_writecount != 0) { 454#ifdef DIAGNOSTIC 455 if (epp->ep_vp->v_flag & VTEXT) 456 panic("exec: a VTEXT vnode has writecount != 0\n"); 457#endif 458 return ETXTBSY; 459 } 460 /* 461 * Allocate space to hold all the program headers, and read them 462 * from the file 463 */ 464 phsize = eh->e_phnum * sizeof(Elf_Phdr); 465 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 466 467 if ((error = exec_read_from(p, epp->ep_vp, eh->e_phoff, ph, phsize)) != 468 0) 469 goto bad; 470 471 epp->ep_taddr = epp->ep_tsize = ELFDEFNNAME(NO_ADDR); 472 epp->ep_daddr = epp->ep_dsize = ELFDEFNNAME(NO_ADDR); 473 474 MALLOC(interp, char *, MAXPATHLEN, M_TEMP, M_WAITOK); 475 interp[0] = '\0'; 476 477 for (i = 0; i < eh->e_phnum; i++) { 478 pp = &ph[i]; 479 if (pp->p_type == PT_INTERP) { 480 if (pp->p_filesz >= MAXPATHLEN) 481 goto bad; 482 if ((error = exec_read_from(p, epp->ep_vp, 483 pp->p_offset, interp, pp->p_filesz)) != 0) 484 goto bad; 485 break; 486 } 487 } 488 489 /* 490 * On the same architecture, we may be emulating different systems. 491 * See which one will accept this executable. This currently only 492 * applies to SVR4, and IBCS2 on the i386 and Linux on the i386 493 * and the Alpha. 494 * 495 * Probe functions would normally see if the interpreter (if any) 496 * exists. Emulation packages may possibly replace the interpreter in 497 * interp[] with a changed path (/emul/xxx/<path>). 498 */ 499 if (!epp->ep_esch->u.elf_probe_func) { 500 pos = ELFDEFNNAME(NO_ADDR); 501 } else { 502 vaddr_t startp = 0; 503 504 error = (*epp->ep_esch->u.elf_probe_func)(p, epp, eh, interp, 505 &startp); 506 pos = (Elf_Addr)startp; 507 if (error) 508 goto bad; 509 } 510 511 /* 512 * Load all the necessary sections 513 */ 514 for (i = nload = 0; i < eh->e_phnum; i++) { 515 Elf_Addr addr = ELFDEFNNAME(NO_ADDR); 516 u_long size = 0; 517 int prot = 0; 518 519 pp = &ph[i]; 520 521 switch (ph[i].p_type) { 522 case PT_LOAD: 523 /* 524 * XXX 525 * Can handle only 2 sections: text and data 526 */ 527 if (nload++ == 2) 528 goto bad; 529 ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp, 530 &ph[i], &addr, &size, &prot, 0); 531 532 /* 533 * Decide whether it's text or data by looking 534 * at the entry point. 535 */ 536 if (eh->e_entry >= addr && 537 eh->e_entry < (addr + size)) { 538 epp->ep_taddr = addr; 539 epp->ep_tsize = size; 540 if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) { 541 epp->ep_daddr = addr; 542 epp->ep_dsize = size; 543 } 544 } else { 545 epp->ep_daddr = addr; 546 epp->ep_dsize = size; 547 } 548 break; 549 550 case PT_SHLIB: 551 /* SCO has these sections. */ 552 case PT_INTERP: 553 /* Already did this one. */ 554 case PT_DYNAMIC: 555 case PT_NOTE: 556 break; 557 558 case PT_PHDR: 559 /* Note address of program headers (in text segment) */ 560 phdr = pp->p_vaddr; 561 break; 562 563 default: 564 /* 565 * Not fatal; we don't need to understand everything. 566 */ 567 break; 568 } 569 } 570 571 /* this breaks on, e.g., OpenBSD-compatible mips shared binaries. */ 572#ifndef ELF_INTERP_NON_RELOCATABLE 573 /* 574 * If no position to load the interpreter was set by a probe 575 * function, pick the same address that a non-fixed mmap(0, ..) 576 * would (i.e. something safely out of the way). 577 */ 578 if (pos == ELFDEFNNAME(NO_ADDR)) 579 pos = round_page(epp->ep_daddr + MAXDSIZ); 580#endif /* !ELF_INTERP_NON_RELOCATABLE */ 581 582 /* 583 * Check if we found a dynamically linked binary and arrange to load 584 * it's interpreter 585 */ 586 if (interp[0]) { 587 struct elf_args *ap; 588 589 MALLOC(ap, struct elf_args *, sizeof(struct elf_args), 590 M_TEMP, M_WAITOK); 591 if ((error = ELFNAME(load_file)(p, epp, interp, 592 &epp->ep_vmcmds, &epp->ep_entry, ap, &pos)) != 0) { 593 FREE((char *)ap, M_TEMP); 594 goto bad; 595 } 596 pos += phsize; 597 ap->arg_phaddr = phdr; 598 599 ap->arg_phentsize = eh->e_phentsize; 600 ap->arg_phnum = eh->e_phnum; 601 ap->arg_entry = eh->e_entry; 602 603 epp->ep_emul_arg = ap; 604 } else 605 epp->ep_entry = eh->e_entry; 606 607#ifdef ELF_MAP_PAGE_ZERO 608 /* Dell SVR4 maps page zero, yeuch! */ 609 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0, 610 epp->ep_vp, 0, VM_PROT_READ); 611#endif 612 FREE(interp, M_TEMP); 613 free((char *)ph, M_TEMP); 614 vn_marktext(epp->ep_vp); 615 return exec_elf_setup_stack(p, epp); 616 617bad: 618 if (interp) 619 FREE(interp, M_TEMP); 620 free((char *)ph, M_TEMP); 621 kill_vmcmds(&epp->ep_vmcmds); 622 return ENOEXEC; 623} 624 625int 626ELFNAME2(netbsd,signature)(struct proc *p, struct exec_package *epp, 627 Elf_Ehdr *eh) 628{ 629 size_t i; 630 Elf_Phdr *ph; 631 size_t phsize; 632 int error; 633 634 phsize = eh->e_phnum * sizeof(Elf_Phdr); 635 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 636 error = exec_read_from(p, epp->ep_vp, eh->e_phoff, ph, phsize); 637 if (error) 638 goto out; 639 640 for (i = 0; i < eh->e_phnum; i++) { 641 Elf_Phdr *ephp = &ph[i]; 642 Elf_Nhdr *np; 643 644 if (ephp->p_type != PT_NOTE || 645 ephp->p_filesz > 1024 || 646 ephp->p_filesz < sizeof(Elf_Nhdr) + ELF_NOTE_NETBSD_NAMESZ) 647 continue; 648 649 np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK); 650 error = exec_read_from(p, epp->ep_vp, ephp->p_offset, np, 651 ephp->p_filesz); 652 if (error) 653 goto next; 654 655 if (np->n_type != ELF_NOTE_TYPE_NETBSD_TAG || 656 np->n_namesz != ELF_NOTE_NETBSD_NAMESZ || 657 np->n_descsz != ELF_NOTE_NETBSD_DESCSZ || 658 memcmp((caddr_t)(np + 1), ELF_NOTE_NETBSD_NAME, 659 ELF_NOTE_NETBSD_NAMESZ)) 660 goto next; 661 662 error = 0; 663 free(np, M_TEMP); 664 goto out; 665 666 next: 667 free(np, M_TEMP); 668 continue; 669 } 670 671 error = ENOEXEC; 672out: 673 free(ph, M_TEMP); 674 return (error); 675} 676 677int 678ELFNAME2(netbsd,probe)(struct proc *p, struct exec_package *epp, 679 void *eh, char *itp, vaddr_t *pos) 680{ 681 int error; 682 683 if ((error = ELFNAME2(netbsd,signature)(p, epp, eh)) != 0) 684 return error; 685 *pos = ELFDEFNNAME(NO_ADDR); 686 return 0; 687} 688