Module Name: src Committed By: matt Date: Sun Sep 13 23:06:22 UTC 2009
Modified Files: src/sys/arch/mips/mips [matt-nb5-mips64]: cpu_exec.c Log Message: Try to find an exact interp match before defaulting to one supplied: o32: ld.elf_so-32 n32: ld.elf_so-n32 o64: ld.elf_so-o64 n64: ld.elf_so-64 To generate a diff of this commit: cvs rdiff -u -r1.50.54.1.4.8 -r1.50.54.1.4.9 \ src/sys/arch/mips/mips/cpu_exec.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/mips/mips/cpu_exec.c diff -u src/sys/arch/mips/mips/cpu_exec.c:1.50.54.1.4.8 src/sys/arch/mips/mips/cpu_exec.c:1.50.54.1.4.9 --- src/sys/arch/mips/mips/cpu_exec.c:1.50.54.1.4.8 Sat Sep 5 03:03:44 2009 +++ src/sys/arch/mips/mips/cpu_exec.c Sun Sep 13 23:06:22 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu_exec.c,v 1.50.54.1.4.8 2009/09/05 03:03:44 matt Exp $ */ +/* $NetBSD: cpu_exec.c,v 1.50.54.1.4.9 2009/09/13 23:06:22 matt Exp $ */ /* * Copyright (c) 1992, 1993 @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu_exec.c,v 1.50.54.1.4.8 2009/09/05 03:03:44 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu_exec.c,v 1.50.54.1.4.9 2009/09/13 23:06:22 matt Exp $"); #include "opt_compat_netbsd.h" #include "opt_compat_ultrix.h" @@ -47,6 +47,7 @@ #include <sys/malloc.h> #include <sys/vnode.h> #include <sys/exec.h> +#include <sys/namei.h> #include <sys/resourcevar.h> #include <uvm/uvm_extern.h> @@ -309,14 +310,52 @@ return 0; } +static int +elf_check_itp(struct exec_package *epp, const char *itp, + const char *itp_suffix) +{ + int error = 0; + if (itp) { + /* + * If the path is exactly "/usr/libexec/ld.elf_so", first + * try to see if "/usr/libexec/ld.elf_so-<abi>" exists + * and if so, use that instead. + * XXX maybe move this into compat/common + */ + if (strcmp(itp, "/usr/libexec/ld.elf_so") == 0 || + strcmp(itp, "/libexec/ld.elf_so") == 0) { + struct nameidata nd; + char *path; + + path = PNBUF_GET(); + snprintf(path, MAXPATHLEN, "%s-%s", itp, itp_suffix); + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path); + error = namei(&nd); + /* + * If that worked, replace interpreter in case we + * actually need to load it + */ + if (error == 0) { + if (epp->ep_interp != NULL) + vrele(epp->ep_interp); + epp->ep_interp = nd.ni_vp; + } + PNBUF_PUT(path); + error = 0; + } + } + return error; +} + #if EXEC_ELF32 int mips_netbsd_elf32_probe(struct lwp *l, struct exec_package *epp, void *eh0, - char *idt, vaddr_t *start_p) + char *itp, vaddr_t *start_p) { struct proc * const p = l->l_proc; const Elf32_Ehdr * const eh = eh0; int old_abi = p->p_md.md_abi; + const char *itp_suffix = NULL; /* * Verify we can support the architecture. @@ -350,22 +389,26 @@ switch (eh->e_flags & (EF_MIPS_ABI|EF_MIPS_ABI2)) { #if !defined(__mips_o32) case EF_MIPS_ABI2: + itp_suffix = "n32"; p->p_md.md_abi = _MIPS_BSD_API_N32; if (old_abi != p->p_md.md_abi) printf("pid %d(%s): ABI set to N32 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); - return 0; + break; #endif case EF_MIPS_ABI_O32: + itp_suffix = "o32"; p->p_md.md_abi = _MIPS_BSD_API_O32; #ifdef COMPAT_16 *start_p = ELF32_LINK_ADDR; #endif if (old_abi != p->p_md.md_abi) printf("pid %d(%s): ABI set to O32 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); - return 0; + break; default: return ENOEXEC; } + + return elf_check_itp(epp, itp, itp_suffix); } void @@ -407,11 +450,12 @@ #if EXEC_ELF64 int mips_netbsd_elf64_probe(struct lwp *l, struct exec_package *epp, void *eh0, - char *idt, vaddr_t *start_p) + char *itp, vaddr_t *start_p) { struct proc * const p = l->l_proc; const Elf64_Ehdr * const eh = eh0; int old_abi = p->p_md.md_abi; + const char *itp_suffix = NULL; switch (eh->e_flags & EF_MIPS_ARCH) { case EF_MIPS_ARCH_1: @@ -442,18 +486,22 @@ switch (eh->e_flags & (EF_MIPS_ABI|EF_MIPS_ABI2)) { case 0: + itp_suffix = "64"; p->p_md.md_abi = _MIPS_BSD_API_N64; if (old_abi != p->p_md.md_abi) printf("pid %d(%s): ABI set to N64 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); - return 0; + break; case EF_MIPS_ABI_O64: + itp_suffix = "o64"; p->p_md.md_abi = _MIPS_BSD_API_O64; if (old_abi != p->p_md.md_abi) printf("pid %d(%s): ABI set to O64 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); - return 0; + break; default: return ENOEXEC; } + + return elf_check_itp(epp, itp, itp_suffix); } void