replace mips:elf_check_itp() and ELFNAME2(netbsd32,probe_noteless) that it's based upon with a common compat_elf_check_interp(). tested on MALTA64 and sparc64.diff -r1.58 -r1.59 src/sys/arch/mips/mips/cpu_exec.c
(mrg)
--- src/sys/arch/mips/mips/cpu_exec.c 2009/12/14 00:46:05 1.58
+++ src/sys/arch/mips/mips/cpu_exec.c 2009/12/14 04:09:38 1.59
@@ -1,470 +1,438 @@ | @@ -1,470 +1,438 @@ | |||
1 | /* $NetBSD: cpu_exec.c,v 1.58 2009/12/14 00:46:05 matt Exp $ */ | 1 | /* $NetBSD: cpu_exec.c,v 1.59 2009/12/14 04:09:38 mrg Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1992, 1993 | 4 | * Copyright (c) 1992, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by Ralph | 7 | * This code is derived from software contributed to Berkeley by Ralph | |
8 | * Campbell. | 8 | * Campbell. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. Neither the name of the University nor the names of its contributors | 18 | * 3. Neither the name of the University nor the names of its contributors | |
19 | * may be used to endorse or promote products derived from this software | 19 | * may be used to endorse or promote products derived from this software | |
20 | * without specific prior written permission. | 20 | * without specific prior written permission. | |
21 | * | 21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | 32 | * SUCH DAMAGE. | |
33 | * | 33 | * | |
34 | * @(#)machdep.c 8.3 (Berkeley) 1/12/94 | 34 | * @(#)machdep.c 8.3 (Berkeley) 1/12/94 | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | #include <sys/cdefs.h> | 37 | #include <sys/cdefs.h> | |
38 | __KERNEL_RCSID(0, "$NetBSD: cpu_exec.c,v 1.58 2009/12/14 00:46:05 matt Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: cpu_exec.c,v 1.59 2009/12/14 04:09:38 mrg Exp $"); | |
39 | 39 | |||
40 | #include "opt_compat_netbsd.h" | 40 | #include "opt_compat_netbsd.h" | |
41 | #include "opt_compat_ultrix.h" | 41 | #include "opt_compat_ultrix.h" | |
42 | #include "opt_execfmt.h" | 42 | #include "opt_execfmt.h" | |
43 | 43 | |||
44 | #include <sys/param.h> | 44 | #include <sys/param.h> | |
45 | #include <sys/systm.h> | 45 | #include <sys/systm.h> | |
46 | #include <sys/proc.h> | 46 | #include <sys/proc.h> | |
47 | #include <sys/malloc.h> | 47 | #include <sys/malloc.h> | |
48 | #include <sys/vnode.h> | 48 | #include <sys/vnode.h> | |
49 | #include <sys/exec.h> | 49 | #include <sys/exec.h> | |
50 | #include <sys/namei.h> | 50 | #include <sys/namei.h> | |
51 | #include <sys/resourcevar.h> | 51 | #include <sys/resourcevar.h> | |
52 | 52 | |||
53 | #include <uvm/uvm_extern.h> | 53 | #include <uvm/uvm_extern.h> | |
54 | 54 | |||
55 | #include <compat/common/compat_util.h> | |||
56 | ||||
55 | #ifdef EXEC_ECOFF | 57 | #ifdef EXEC_ECOFF | |
56 | #include <sys/exec_ecoff.h> | 58 | #include <sys/exec_ecoff.h> | |
57 | #endif | 59 | #endif | |
58 | #include <sys/exec_elf.h> /* mandatory */ | 60 | #include <sys/exec_elf.h> /* mandatory */ | |
59 | #include <machine/reg.h> | 61 | #include <machine/reg.h> | |
60 | #include <mips/regnum.h> /* symbolic register indices */ | 62 | #include <mips/regnum.h> /* symbolic register indices */ | |
61 | 63 | |||
62 | int mips_elf_makecmds(struct lwp *, struct exec_package *); | 64 | int mips_elf_makecmds(struct lwp *, struct exec_package *); | |
63 | 65 | |||
64 | #ifdef EXEC_ECOFF | 66 | #ifdef EXEC_ECOFF | |
65 | void | 67 | void | |
66 | cpu_exec_ecoff_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) | 68 | cpu_exec_ecoff_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) | |
67 | { | 69 | { | |
68 | struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr; | 70 | struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr; | |
69 | struct frame *f = l->l_md.md_regs; | 71 | struct frame *f = l->l_md.md_regs; | |
70 | 72 | |||
71 | f->f_regs[_R_GP] = (register_t)execp->a.gp_value; | 73 | f->f_regs[_R_GP] = (register_t)execp->a.gp_value; | |
72 | } | 74 | } | |
73 | 75 | |||
74 | /* | 76 | /* | |
75 | * cpu_exec_ecoff_probe() | 77 | * cpu_exec_ecoff_probe() | |
76 | * cpu-dependent ECOFF format hook for execve(). | 78 | * cpu-dependent ECOFF format hook for execve(). | |
77 | * | 79 | * | |
78 | * Do any machine-dependent diddling of the exec package when doing ECOFF. | 80 | * Do any machine-dependent diddling of the exec package when doing ECOFF. | |
79 | */ | 81 | */ | |
80 | int | 82 | int | |
81 | cpu_exec_ecoff_probe(struct lwp *l, struct exec_package *epp) | 83 | cpu_exec_ecoff_probe(struct lwp *l, struct exec_package *epp) | |
82 | { | 84 | { | |
83 | 85 | |||
84 | /* NetBSD/mips does not have native ECOFF binaries. */ | 86 | /* NetBSD/mips does not have native ECOFF binaries. */ | |
85 | return ENOEXEC; | 87 | return ENOEXEC; | |
86 | } | 88 | } | |
87 | #endif /* EXEC_ECOFF */ | 89 | #endif /* EXEC_ECOFF */ | |
88 | 90 | |||
89 | /* | 91 | /* | |
90 | * mips_elf_makecmds (l, epp) | 92 | * mips_elf_makecmds (l, epp) | |
91 | * | 93 | * | |
92 | * Test if an executable is a MIPS ELF executable. If it is, | 94 | * Test if an executable is a MIPS ELF executable. If it is, | |
93 | * try to load it. | 95 | * try to load it. | |
94 | */ | 96 | */ | |
95 | 97 | |||
96 | int | 98 | int | |
97 | mips_elf_makecmds (struct lwp *l, struct exec_package *epp) | 99 | mips_elf_makecmds (struct lwp *l, struct exec_package *epp) | |
98 | { | 100 | { | |
99 | Elf32_Ehdr *ex = (Elf32_Ehdr *)epp->ep_hdr; | 101 | Elf32_Ehdr *ex = (Elf32_Ehdr *)epp->ep_hdr; | |
100 | Elf32_Phdr ph; | 102 | Elf32_Phdr ph; | |
101 | int i, error; | 103 | int i, error; | |
102 | size_t resid; | 104 | size_t resid; | |
103 | 105 | |||
104 | /* Make sure we got enough data to check magic numbers... */ | 106 | /* Make sure we got enough data to check magic numbers... */ | |
105 | if (epp->ep_hdrvalid < sizeof (Elf32_Ehdr)) { | 107 | if (epp->ep_hdrvalid < sizeof (Elf32_Ehdr)) { | |
106 | #ifdef DIAGNOSTIC | 108 | #ifdef DIAGNOSTIC | |
107 | if (epp->ep_hdrlen < sizeof (Elf32_Ehdr)) | 109 | if (epp->ep_hdrlen < sizeof (Elf32_Ehdr)) | |
108 | printf ("mips_elf_makecmds: execsw hdrsize too short!\n"); | 110 | printf ("mips_elf_makecmds: execsw hdrsize too short!\n"); | |
109 | #endif | 111 | #endif | |
110 | return ENOEXEC; | 112 | return ENOEXEC; | |
111 | } | 113 | } | |
112 | 114 | |||
113 | /* See if it's got the basic elf magic number leadin... */ | 115 | /* See if it's got the basic elf magic number leadin... */ | |
114 | if (memcmp(ex->e_ident, ELFMAG, SELFMAG) != 0) { | 116 | if (memcmp(ex->e_ident, ELFMAG, SELFMAG) != 0) { | |
115 | return ENOEXEC; | 117 | return ENOEXEC; | |
116 | } | 118 | } | |
117 | 119 | |||
118 | /* XXX: Check other magic numbers here. */ | 120 | /* XXX: Check other magic numbers here. */ | |
119 | if (ex->e_ident[EI_CLASS] != ELFCLASS32) { | 121 | if (ex->e_ident[EI_CLASS] != ELFCLASS32) { | |
120 | return ENOEXEC; | 122 | return ENOEXEC; | |
121 | } | 123 | } | |
122 | 124 | |||
123 | /* See if we got any program header information... */ | 125 | /* See if we got any program header information... */ | |
124 | if (!ex->e_phoff || !ex->e_phnum) { | 126 | if (!ex->e_phoff || !ex->e_phnum) { | |
125 | return ENOEXEC; | 127 | return ENOEXEC; | |
126 | } | 128 | } | |
127 | 129 | |||
128 | error = vn_marktext(epp->ep_vp); | 130 | error = vn_marktext(epp->ep_vp); | |
129 | if (error) | 131 | if (error) | |
130 | return (error); | 132 | return (error); | |
131 | 133 | |||
132 | /* Set the entry point... */ | 134 | /* Set the entry point... */ | |
133 | epp->ep_entry = ex->e_entry; | 135 | epp->ep_entry = ex->e_entry; | |
134 | epp->ep_taddr = 0; | 136 | epp->ep_taddr = 0; | |
135 | epp->ep_tsize = 0; | 137 | epp->ep_tsize = 0; | |
136 | epp->ep_daddr = 0; | 138 | epp->ep_daddr = 0; | |
137 | epp->ep_dsize = 0; | 139 | epp->ep_dsize = 0; | |
138 | 140 | |||
139 | for (i = 0; i < ex->e_phnum; i++) { | 141 | for (i = 0; i < ex->e_phnum; i++) { | |
140 | #ifdef DEBUG | 142 | #ifdef DEBUG | |
141 | /*printf("obsolete elf: mapping %x %x %x\n", resid);*/ | 143 | /*printf("obsolete elf: mapping %x %x %x\n", resid);*/ | |
142 | #endif | 144 | #endif | |
143 | if ((error = vn_rdwr(UIO_READ, epp->ep_vp, (void *)&ph, | 145 | if ((error = vn_rdwr(UIO_READ, epp->ep_vp, (void *)&ph, | |
144 | sizeof ph, ex->e_phoff + i * sizeof ph, | 146 | sizeof ph, ex->e_phoff + i * sizeof ph, | |
145 | UIO_SYSSPACE, IO_NODELOCKED, | 147 | UIO_SYSSPACE, IO_NODELOCKED, | |
146 | l->l_cred, &resid, NULL)) | 148 | l->l_cred, &resid, NULL)) | |
147 | != 0) | 149 | != 0) | |
148 | return error; | 150 | return error; | |
149 | 151 | |||
150 | if (resid != 0) { | 152 | if (resid != 0) { | |
151 | return ENOEXEC; | 153 | return ENOEXEC; | |
152 | } | 154 | } | |
153 | 155 | |||
154 | /* We only care about loadable sections... */ | 156 | /* We only care about loadable sections... */ | |
155 | if (ph.p_type == PT_LOAD) { | 157 | if (ph.p_type == PT_LOAD) { | |
156 | int prot = VM_PROT_READ | VM_PROT_EXECUTE; | 158 | int prot = VM_PROT_READ | VM_PROT_EXECUTE; | |
157 | int residue; | 159 | int residue; | |
158 | unsigned vaddr, offset, length; | 160 | unsigned vaddr, offset, length; | |
159 | 161 | |||
160 | vaddr = ph.p_vaddr; | 162 | vaddr = ph.p_vaddr; | |
161 | offset = ph.p_offset; | 163 | offset = ph.p_offset; | |
162 | length = ph.p_filesz; | 164 | length = ph.p_filesz; | |
163 | residue = ph.p_memsz - ph.p_filesz; | 165 | residue = ph.p_memsz - ph.p_filesz; | |
164 | 166 | |||
165 | if (ph.p_flags & PF_W) { | 167 | if (ph.p_flags & PF_W) { | |
166 | prot |= VM_PROT_WRITE; | 168 | prot |= VM_PROT_WRITE; | |
167 | if (!epp->ep_daddr || vaddr < epp->ep_daddr) | 169 | if (!epp->ep_daddr || vaddr < epp->ep_daddr) | |
168 | epp->ep_daddr = vaddr; | 170 | epp->ep_daddr = vaddr; | |
169 | epp->ep_dsize += ph.p_memsz; | 171 | epp->ep_dsize += ph.p_memsz; | |
170 | /* Read the data from the file... */ | 172 | /* Read the data from the file... */ | |
171 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | 173 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, | |
172 | length, vaddr, | 174 | length, vaddr, | |
173 | epp->ep_vp, offset, prot); | 175 | epp->ep_vp, offset, prot); | |
174 | #ifdef OLD_ELF_DEBUG | 176 | #ifdef OLD_ELF_DEBUG | |
175 | /*XXX*/ printf( | 177 | /*XXX*/ printf( | |
176 | "obsolete elf: NEW_VMCMD len %x va %x off %x prot %x residue %x\n", | 178 | "obsolete elf: NEW_VMCMD len %x va %x off %x prot %x residue %x\n", | |
177 | length, vaddr, offset, prot, residue); | 179 | length, vaddr, offset, prot, residue); | |
178 | #endif /*ELF_DEBUG*/ | 180 | #endif /*ELF_DEBUG*/ | |
179 | 181 | |||
180 | if (residue) { | 182 | if (residue) { | |
181 | vaddr &= ~(PAGE_SIZE - 1); | 183 | vaddr &= ~(PAGE_SIZE - 1); | |
182 | offset &= ~(PAGE_SIZE - 1); | 184 | offset &= ~(PAGE_SIZE - 1); | |
183 | length = roundup (length + ph.p_vaddr | 185 | length = roundup (length + ph.p_vaddr | |
184 | - vaddr, PAGE_SIZE); | 186 | - vaddr, PAGE_SIZE); | |
185 | residue = (ph.p_vaddr + ph.p_memsz) | 187 | residue = (ph.p_vaddr + ph.p_memsz) | |
186 | - (vaddr + length); | 188 | - (vaddr + length); | |
187 | } | 189 | } | |
188 | } else { | 190 | } else { | |
189 | vaddr &= ~(PAGE_SIZE - 1); | 191 | vaddr &= ~(PAGE_SIZE - 1); | |
190 | offset &= ~(PAGE_SIZE - 1); | 192 | offset &= ~(PAGE_SIZE - 1); | |
191 | length = roundup (length + ph.p_vaddr - vaddr, | 193 | length = roundup (length + ph.p_vaddr - vaddr, | |
192 | PAGE_SIZE); | 194 | PAGE_SIZE); | |
193 | residue = (ph.p_vaddr + ph.p_memsz) | 195 | residue = (ph.p_vaddr + ph.p_memsz) | |
194 | - (vaddr + length); | 196 | - (vaddr + length); | |
195 | if (!epp->ep_taddr || vaddr < epp->ep_taddr) | 197 | if (!epp->ep_taddr || vaddr < epp->ep_taddr) | |
196 | epp->ep_taddr = vaddr; | 198 | epp->ep_taddr = vaddr; | |
197 | epp->ep_tsize += ph.p_memsz; | 199 | epp->ep_tsize += ph.p_memsz; | |
198 | /* Map the data from the file... */ | 200 | /* Map the data from the file... */ | |
199 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, | 201 | NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, | |
200 | length, vaddr, | 202 | length, vaddr, | |
201 | epp->ep_vp, offset, prot); | 203 | epp->ep_vp, offset, prot); | |
202 | } | 204 | } | |
203 | /* If part of the segment is just zeros (e.g., bss), | 205 | /* If part of the segment is just zeros (e.g., bss), | |
204 | map that. */ | 206 | map that. */ | |
205 | if (residue > 0) { | 207 | if (residue > 0) { | |
206 | #ifdef OLD_ELF_DEBUG | 208 | #ifdef OLD_ELF_DEBUG | |
207 | /*XXX*/ printf( | 209 | /*XXX*/ printf( | |
208 | "old elf:resid NEW_VMCMD len %x va %x off %x prot %x residue %x\n", | 210 | "old elf:resid NEW_VMCMD len %x va %x off %x prot %x residue %x\n", | |
209 | length, vaddr + length, offset, prot, residue); | 211 | length, vaddr + length, offset, prot, residue); | |
210 | #endif /*ELF_DEBUG*/ | 212 | #endif /*ELF_DEBUG*/ | |
211 | 213 | |||
212 | NEW_VMCMD (&epp->ep_vmcmds, vmcmd_map_zero, | 214 | NEW_VMCMD (&epp->ep_vmcmds, vmcmd_map_zero, | |
213 | residue, vaddr + length, | 215 | residue, vaddr + length, | |
214 | NULLVP, 0, prot); | 216 | NULLVP, 0, prot); | |
215 | } | 217 | } | |
216 | } | 218 | } | |
217 | } | 219 | } | |
218 | 220 | |||
219 | epp->ep_maxsaddr = USRSTACK - MAXSSIZ; | 221 | epp->ep_maxsaddr = USRSTACK - MAXSSIZ; | |
220 | epp->ep_minsaddr = USRSTACK; | 222 | epp->ep_minsaddr = USRSTACK; | |
221 | epp->ep_ssize = l->l_proc->p_rlimit[RLIMIT_STACK].rlim_cur; | 223 | epp->ep_ssize = l->l_proc->p_rlimit[RLIMIT_STACK].rlim_cur; | |
222 | 224 | |||
223 | /* | 225 | /* | |
224 | * set up commands for stack. note that this takes *two*, one to | 226 | * set up commands for stack. note that this takes *two*, one to | |
225 | * map the part of the stack which we can access, and one to map | 227 | * map the part of the stack which we can access, and one to map | |
226 | * the part which we can't. | 228 | * the part which we can't. | |
227 | * | 229 | * | |
228 | * arguably, it could be made into one, but that would require the | 230 | * arguably, it could be made into one, but that would require the | |
229 | * addition of another mapping proc, which is unnecessary | 231 | * addition of another mapping proc, which is unnecessary | |
230 | * | 232 | * | |
231 | * note that in memory, things assumed to be: 0 ....... ep_maxsaddr | 233 | * note that in memory, things assumed to be: 0 ....... ep_maxsaddr | |
232 | * <stack> ep_minsaddr | 234 | * <stack> ep_minsaddr | |
233 | */ | 235 | */ | |
234 | NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, | 236 | NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, | |
235 | ((epp->ep_minsaddr - epp->ep_ssize) - epp->ep_maxsaddr), | 237 | ((epp->ep_minsaddr - epp->ep_ssize) - epp->ep_maxsaddr), | |
236 | epp->ep_maxsaddr, NULLVP, 0, VM_PROT_NONE, VMCMD_STACK); | 238 | epp->ep_maxsaddr, NULLVP, 0, VM_PROT_NONE, VMCMD_STACK); | |
237 | NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, epp->ep_ssize, | 239 | NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, epp->ep_ssize, | |
238 | (epp->ep_minsaddr - epp->ep_ssize), NULLVP, 0, | 240 | (epp->ep_minsaddr - epp->ep_ssize), NULLVP, 0, | |
239 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, VMCMD_STACK); | 241 | VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, VMCMD_STACK); | |
240 | 242 | |||
241 | return 0; | 243 | return 0; | |
242 | } | 244 | } | |
243 | 245 | |||
244 | static int | |||
245 | elf_check_itp(struct exec_package *epp, const char *itp, | |||
246 | const char *itp_suffix) | |||
247 | { | |||
248 | if (itp) { | |||
249 | /* | |||
250 | * If the path is exactly "/usr/libexec/ld.elf_so", first | |||
251 | * try to see if "/usr/libexec/ld.elf_so-<abi>" exists | |||
252 | * and if so, use that instead. | |||
253 | * XXX maybe move this into compat/common | |||
254 | */ | |||
255 | if (strcmp(itp, "/usr/libexec/ld.elf_so") == 0 || | |||
256 | strcmp(itp, "/libexec/ld.elf_so") == 0) { | |||
257 | struct nameidata nd; | |||
258 | char *path; | |||
259 | int error; | |||
260 | ||||
261 | path = PNBUF_GET(); | |||
262 | snprintf(path, MAXPATHLEN, "%s-%s", itp, itp_suffix); | |||
263 | NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path); | |||
264 | error = namei(&nd); | |||
265 | /* | |||
266 | * If that worked, replace interpreter in case we | |||
267 | * actually need to load it | |||
268 | */ | |||
269 | if (error == 0) { | |||
270 | if (epp->ep_interp != NULL) | |||
271 | vrele(epp->ep_interp); | |||
272 | epp->ep_interp = nd.ni_vp; | |||
273 | } | |||
274 | PNBUF_PUT(path); | |||
275 | } | |||
276 | } | |||
277 | return 0; | |||
278 | } | |||
279 | ||||
280 | #if EXEC_ELF32 | 246 | #if EXEC_ELF32 | |
281 | int | 247 | int | |
282 | mips_netbsd_elf32_probe(struct lwp *l, struct exec_package *epp, void *eh0, | 248 | mips_netbsd_elf32_probe(struct lwp *l, struct exec_package *epp, void *eh0, | |
283 | char *itp, vaddr_t *start_p) | 249 | char *itp, vaddr_t *start_p) | |
284 | { | 250 | { | |
285 | struct proc * const p = l->l_proc; | 251 | struct proc * const p = l->l_proc; | |
286 | const Elf32_Ehdr * const eh = eh0; | 252 | const Elf32_Ehdr * const eh = eh0; | |
287 | int old_abi = p->p_md.md_abi; | 253 | int old_abi = p->p_md.md_abi; | |
288 | const char *itp_suffix = NULL; | 254 | const char *itp_suffix = NULL; | |
289 | 255 | |||
290 | /* | 256 | /* | |
291 | * Verify we can support the architecture. | 257 | * Verify we can support the architecture. | |
292 | */ | 258 | */ | |
293 | switch (eh->e_flags & EF_MIPS_ARCH) { | 259 | switch (eh->e_flags & EF_MIPS_ARCH) { | |
294 | case EF_MIPS_ARCH_1: | 260 | case EF_MIPS_ARCH_1: | |
295 | break; | 261 | break; | |
296 | case EF_MIPS_ARCH_2: | 262 | case EF_MIPS_ARCH_2: | |
297 | if (cpu_arch < CPU_ARCH_MIPS2) | 263 | if (cpu_arch < CPU_ARCH_MIPS2) | |
298 | return ENOEXEC; | 264 | return ENOEXEC; | |
299 | break; | 265 | break; | |
300 | case EF_MIPS_ARCH_3: | 266 | case EF_MIPS_ARCH_3: | |
301 | if (cpu_arch < CPU_ARCH_MIPS3) | 267 | if (cpu_arch < CPU_ARCH_MIPS3) | |
302 | return ENOEXEC; | 268 | return ENOEXEC; | |
303 | break; | 269 | break; | |
304 | case EF_MIPS_ARCH_4: | 270 | case EF_MIPS_ARCH_4: | |
305 | if (cpu_arch < CPU_ARCH_MIPS4) | 271 | if (cpu_arch < CPU_ARCH_MIPS4) | |
306 | return ENOEXEC; | 272 | return ENOEXEC; | |
307 | break; | 273 | break; | |
308 | case EF_MIPS_ARCH_5: | 274 | case EF_MIPS_ARCH_5: | |
309 | if (cpu_arch < CPU_ARCH_MIPS5) | 275 | if (cpu_arch < CPU_ARCH_MIPS5) | |
310 | return ENOEXEC; | 276 | return ENOEXEC; | |
311 | break; | 277 | break; | |
312 | case EF_MIPS_ARCH_32: | 278 | case EF_MIPS_ARCH_32: | |
313 | case EF_MIPS_ARCH_64: | 279 | case EF_MIPS_ARCH_64: | |
314 | if (!CPUISMIPSNN) | 280 | if (!CPUISMIPSNN) | |
315 | return ENOEXEC; | 281 | return ENOEXEC; | |
316 | break; | 282 | break; | |
317 | } | 283 | } | |
318 | 284 | |||
319 | switch (eh->e_flags & (EF_MIPS_ABI|EF_MIPS_ABI2)) { | 285 | switch (eh->e_flags & (EF_MIPS_ABI|EF_MIPS_ABI2)) { | |
320 | #if !defined(__mips_o32) | 286 | #if !defined(__mips_o32) | |
321 | case EF_MIPS_ABI2: | 287 | case EF_MIPS_ABI2: | |
322 | itp_suffix = "n32"; | 288 | itp_suffix = "n32"; | |
323 | p->p_md.md_abi = _MIPS_BSD_API_N32; | 289 | p->p_md.md_abi = _MIPS_BSD_API_N32; | |
324 | if (old_abi != p->p_md.md_abi) | 290 | if (old_abi != p->p_md.md_abi) | |
325 | printf("pid %d(%s): ABI set to N32 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); | 291 | printf("pid %d(%s): ABI set to N32 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); | |
326 | break; | 292 | break; | |
327 | #endif | 293 | #endif | |
328 | case EF_MIPS_ABI_O32: | 294 | case EF_MIPS_ABI_O32: | |
329 | itp_suffix = "o32"; | 295 | itp_suffix = "o32"; | |
330 | p->p_md.md_abi = _MIPS_BSD_API_O32; | 296 | p->p_md.md_abi = _MIPS_BSD_API_O32; | |
331 | #ifdef COMPAT_16 | 297 | #ifdef COMPAT_16 | |
332 | *start_p = ELF32_LINK_ADDR; | 298 | *start_p = ELF32_LINK_ADDR; | |
333 | #endif | 299 | #endif | |
334 | if (old_abi != p->p_md.md_abi) | 300 | if (old_abi != p->p_md.md_abi) | |
335 | printf("pid %d(%s): ABI set to O32 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); | 301 | printf("pid %d(%s): ABI set to O32 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); | |
336 | break; | 302 | break; | |
337 | default: | 303 | default: | |
338 | return ENOEXEC; | 304 | return ENOEXEC; | |
339 | } | 305 | } | |
340 | 306 | |||
341 | return elf_check_itp(epp, itp, itp_suffix); | 307 | (void)compat_elf_check_interp(epp, itp, itp_suffix); | |
308 | return 0; | |||
342 | } | 309 | } | |
343 | 310 | |||
344 | void | 311 | void | |
345 | coredump_elf32_setup(struct lwp *l, void *eh0) | 312 | coredump_elf32_setup(struct lwp *l, void *eh0) | |
346 | { | 313 | { | |
347 | struct proc * const p = l->l_proc; | 314 | struct proc * const p = l->l_proc; | |
348 | Elf32_Ehdr * const eh = eh0; | 315 | Elf32_Ehdr * const eh = eh0; | |
349 | 316 | |||
350 | /* | 317 | /* | |
351 | * Mark the type of CPU that the dump happened on. | 318 | * Mark the type of CPU that the dump happened on. | |
352 | */ | 319 | */ | |
353 | if (cpu_arch & CPU_ARCH_MIPS64) { | 320 | if (cpu_arch & CPU_ARCH_MIPS64) { | |
354 | eh->e_flags |= EF_MIPS_ARCH_64; | 321 | eh->e_flags |= EF_MIPS_ARCH_64; | |
355 | } else if (cpu_arch & CPU_ARCH_MIPS32) { | 322 | } else if (cpu_arch & CPU_ARCH_MIPS32) { | |
356 | eh->e_flags |= EF_MIPS_ARCH_32; | 323 | eh->e_flags |= EF_MIPS_ARCH_32; | |
357 | } else if (cpu_arch & CPU_ARCH_MIPS5) { | 324 | } else if (cpu_arch & CPU_ARCH_MIPS5) { | |
358 | eh->e_flags |= EF_MIPS_ARCH_5; | 325 | eh->e_flags |= EF_MIPS_ARCH_5; | |
359 | } else if (cpu_arch & CPU_ARCH_MIPS4) { | 326 | } else if (cpu_arch & CPU_ARCH_MIPS4) { | |
360 | eh->e_flags |= EF_MIPS_ARCH_4; | 327 | eh->e_flags |= EF_MIPS_ARCH_4; | |
361 | } else if (cpu_arch & CPU_ARCH_MIPS3) { | 328 | } else if (cpu_arch & CPU_ARCH_MIPS3) { | |
362 | eh->e_flags |= EF_MIPS_ARCH_3; | 329 | eh->e_flags |= EF_MIPS_ARCH_3; | |
363 | } else if (cpu_arch & CPU_ARCH_MIPS2) { | 330 | } else if (cpu_arch & CPU_ARCH_MIPS2) { | |
364 | eh->e_flags |= EF_MIPS_ARCH_2; | 331 | eh->e_flags |= EF_MIPS_ARCH_2; | |
365 | } else { | 332 | } else { | |
366 | eh->e_flags |= EF_MIPS_ARCH_1; | 333 | eh->e_flags |= EF_MIPS_ARCH_1; | |
367 | } | 334 | } | |
368 | 335 | |||
369 | switch (p->p_md.md_abi) { | 336 | switch (p->p_md.md_abi) { | |
370 | case _MIPS_BSD_API_N32: | 337 | case _MIPS_BSD_API_N32: | |
371 | eh->e_flags |= EF_MIPS_ABI2; | 338 | eh->e_flags |= EF_MIPS_ABI2; | |
372 | break; | 339 | break; | |
373 | case _MIPS_BSD_API_O32: | 340 | case _MIPS_BSD_API_O32: | |
374 | eh->e_flags |=EF_MIPS_ABI_O32; | 341 | eh->e_flags |=EF_MIPS_ABI_O32; | |
375 | break; | 342 | break; | |
376 | } | 343 | } | |
377 | } | 344 | } | |
378 | #endif | 345 | #endif | |
379 | 346 | |||
380 | #if EXEC_ELF64 | 347 | #if EXEC_ELF64 | |
381 | int | 348 | int | |
382 | mips_netbsd_elf64_probe(struct lwp *l, struct exec_package *epp, void *eh0, | 349 | mips_netbsd_elf64_probe(struct lwp *l, struct exec_package *epp, void *eh0, | |
383 | char *itp, vaddr_t *start_p) | 350 | char *itp, vaddr_t *start_p) | |
384 | { | 351 | { | |
385 | struct proc * const p = l->l_proc; | 352 | struct proc * const p = l->l_proc; | |
386 | const Elf64_Ehdr * const eh = eh0; | 353 | const Elf64_Ehdr * const eh = eh0; | |
387 | int old_abi = p->p_md.md_abi; | 354 | int old_abi = p->p_md.md_abi; | |
388 | const char *itp_suffix = NULL; | 355 | const char *itp_suffix = NULL; | |
389 | 356 | |||
390 | switch (eh->e_flags & EF_MIPS_ARCH) { | 357 | switch (eh->e_flags & EF_MIPS_ARCH) { | |
391 | case EF_MIPS_ARCH_1: | 358 | case EF_MIPS_ARCH_1: | |
392 | return ENOEXEC; | 359 | return ENOEXEC; | |
393 | case EF_MIPS_ARCH_2: | 360 | case EF_MIPS_ARCH_2: | |
394 | if (cpu_arch < CPU_ARCH_MIPS2) | 361 | if (cpu_arch < CPU_ARCH_MIPS2) | |
395 | return ENOEXEC; | 362 | return ENOEXEC; | |
396 | break; | 363 | break; | |
397 | case EF_MIPS_ARCH_3: | 364 | case EF_MIPS_ARCH_3: | |
398 | if (cpu_arch < CPU_ARCH_MIPS3) | 365 | if (cpu_arch < CPU_ARCH_MIPS3) | |
399 | return ENOEXEC; | 366 | return ENOEXEC; | |
400 | break; | 367 | break; | |
401 | case EF_MIPS_ARCH_4: | 368 | case EF_MIPS_ARCH_4: | |
402 | if (cpu_arch < CPU_ARCH_MIPS4) | 369 | if (cpu_arch < CPU_ARCH_MIPS4) | |
403 | return ENOEXEC; | 370 | return ENOEXEC; | |
404 | break; | 371 | break; | |
405 | case EF_MIPS_ARCH_5: | 372 | case EF_MIPS_ARCH_5: | |
406 | if (cpu_arch < CPU_ARCH_MIPS5) | 373 | if (cpu_arch < CPU_ARCH_MIPS5) | |
407 | return ENOEXEC; | 374 | return ENOEXEC; | |
408 | break; | 375 | break; | |
409 | case EF_MIPS_ARCH_32: | 376 | case EF_MIPS_ARCH_32: | |
410 | return ENOEXEC; | 377 | return ENOEXEC; | |
411 | case EF_MIPS_ARCH_64: | 378 | case EF_MIPS_ARCH_64: | |
412 | if (!CPUISMIPS64) | 379 | if (!CPUISMIPS64) | |
413 | return ENOEXEC; | 380 | return ENOEXEC; | |
414 | break; | 381 | break; | |
415 | } | 382 | } | |
416 | 383 | |||
417 | switch (eh->e_flags & (EF_MIPS_ABI|EF_MIPS_ABI2)) { | 384 | switch (eh->e_flags & (EF_MIPS_ABI|EF_MIPS_ABI2)) { | |
418 | case 0: | 385 | case 0: | |
419 | itp_suffix = "64"; | 386 | itp_suffix = "64"; | |
420 | p->p_md.md_abi = _MIPS_BSD_API_N64; | 387 | p->p_md.md_abi = _MIPS_BSD_API_N64; | |
421 | if (old_abi != p->p_md.md_abi) | 388 | if (old_abi != p->p_md.md_abi) | |
422 | printf("pid %d(%s): ABI set to N64 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); | 389 | printf("pid %d(%s): ABI set to N64 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); | |
423 | break; | 390 | break; | |
424 | case EF_MIPS_ABI_O64: | 391 | case EF_MIPS_ABI_O64: | |
425 | itp_suffix = "o64"; | 392 | itp_suffix = "o64"; | |
426 | p->p_md.md_abi = _MIPS_BSD_API_O64; | 393 | p->p_md.md_abi = _MIPS_BSD_API_O64; | |
427 | if (old_abi != p->p_md.md_abi) | 394 | if (old_abi != p->p_md.md_abi) | |
428 | printf("pid %d(%s): ABI set to O64 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); | 395 | printf("pid %d(%s): ABI set to O64 (e_flags=%#x)\n", p->p_pid, p->p_comm, eh->e_flags); | |
429 | break; | 396 | break; | |
430 | default: | 397 | default: | |
431 | return ENOEXEC; | 398 | return ENOEXEC; | |
432 | } | 399 | } | |
433 | 400 | |||
434 | return elf_check_itp(epp, itp, itp_suffix); | 401 | (void)compat_elf_check_interp(epp, itp, itp_suffix); | |
402 | return 0; | |||
435 | } | 403 | } | |
436 | 404 | |||
437 | void | 405 | void | |
438 | coredump_elf64_setup(struct lwp *l, void *eh0) | 406 | coredump_elf64_setup(struct lwp *l, void *eh0) | |
439 | { | 407 | { | |
440 | struct proc * const p = l->l_proc; | 408 | struct proc * const p = l->l_proc; | |
441 | Elf64_Ehdr * const eh = eh0; | 409 | Elf64_Ehdr * const eh = eh0; | |
442 | 410 | |||
443 | /* | 411 | /* | |
444 | * Mark the type of CPU that the dump happened on. | 412 | * Mark the type of CPU that the dump happened on. | |
445 | */ | 413 | */ | |
446 | if (cpu_arch & CPU_ARCH_MIPS64) { | 414 | if (cpu_arch & CPU_ARCH_MIPS64) { | |
447 | eh->e_flags |= EF_MIPS_ARCH_64; | 415 | eh->e_flags |= EF_MIPS_ARCH_64; | |
448 | } else if (cpu_arch & CPU_ARCH_MIPS32) { | 416 | } else if (cpu_arch & CPU_ARCH_MIPS32) { | |
449 | eh->e_flags |= EF_MIPS_ARCH_32; | 417 | eh->e_flags |= EF_MIPS_ARCH_32; | |
450 | } else if (cpu_arch & CPU_ARCH_MIPS5) { | 418 | } else if (cpu_arch & CPU_ARCH_MIPS5) { | |
451 | eh->e_flags |= EF_MIPS_ARCH_5; | 419 | eh->e_flags |= EF_MIPS_ARCH_5; | |
452 | } else if (cpu_arch & CPU_ARCH_MIPS4) { | 420 | } else if (cpu_arch & CPU_ARCH_MIPS4) { | |
453 | eh->e_flags |= EF_MIPS_ARCH_4; | 421 | eh->e_flags |= EF_MIPS_ARCH_4; | |
454 | } else if (cpu_arch & CPU_ARCH_MIPS3) { | 422 | } else if (cpu_arch & CPU_ARCH_MIPS3) { | |
455 | eh->e_flags |= EF_MIPS_ARCH_3; | 423 | eh->e_flags |= EF_MIPS_ARCH_3; | |
456 | } else if (cpu_arch & CPU_ARCH_MIPS2) { | 424 | } else if (cpu_arch & CPU_ARCH_MIPS2) { | |
457 | eh->e_flags |= EF_MIPS_ARCH_2; | 425 | eh->e_flags |= EF_MIPS_ARCH_2; | |
458 | } else { | 426 | } else { | |
459 | eh->e_flags |= EF_MIPS_ARCH_1; | 427 | eh->e_flags |= EF_MIPS_ARCH_1; | |
460 | } | 428 | } | |
461 | switch (p->p_md.md_abi) { | 429 | switch (p->p_md.md_abi) { | |
462 | case _MIPS_BSD_API_N64: | 430 | case _MIPS_BSD_API_N64: | |
463 | eh->e_flags |= EF_MIPS_ABI2; | 431 | eh->e_flags |= EF_MIPS_ABI2; | |
464 | break; | 432 | break; | |
465 | case _MIPS_BSD_API_O64: | 433 | case _MIPS_BSD_API_O64: | |
466 | eh->e_flags |= EF_MIPS_ABI_O64; | 434 | eh->e_flags |= EF_MIPS_ABI_O64; | |
467 | break; | 435 | break; | |
468 | } | 436 | } | |
469 | } | 437 | } | |
470 | #endif | 438 | #endif |
--- src/sys/compat/common/compat_util.c 2009/06/29 05:08:15 1.42
+++ src/sys/compat/common/compat_util.c 2009/12/14 04:09:38 1.43
@@ -1,149 +1,223 @@ | @@ -1,149 +1,223 @@ | |||
1 | /* $NetBSD: compat_util.c,v 1.42 2009/06/29 05:08:15 dholland Exp $ */ | 1 | /* $NetBSD: compat_util.c,v 1.43 2009/12/14 04:09:38 mrg Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1994 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1994 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Christos Zoulas and Frank van der Linden. | 8 | * by Christos Zoulas and Frank van der Linden. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | /* | |||
33 | * Copyright (c) 2008, 2009 Matthew R. Green | |||
34 | * All rights reserved. | |||
35 | * | |||
36 | * Redistribution and use in source and binary forms, with or without | |||
37 | * modification, are permitted provided that the following conditions | |||
38 | * are met: | |||
39 | * 1. Redistributions of source code must retain the above copyright | |||
40 | * notice, this list of conditions and the following disclaimer. | |||
41 | * 2. Redistributions in binary form must reproduce the above copyright | |||
42 | * notice, this list of conditions and the following disclaimer in the | |||
43 | * documentation and/or other materials provided with the distribution. | |||
44 | * 3. The name of the author may not be used to endorse or promote products | |||
45 | * derived from this software without specific prior written permission. | |||
46 | * | |||
47 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |||
48 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
49 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |||
50 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
51 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |||
52 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
53 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | |||
54 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
55 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
56 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
57 | * SUCH DAMAGE. | |||
58 | */ | |||
59 | ||||
32 | #include <sys/cdefs.h> | 60 | #include <sys/cdefs.h> | |
33 | __KERNEL_RCSID(0, "$NetBSD: compat_util.c,v 1.42 2009/06/29 05:08:15 dholland Exp $"); | 61 | __KERNEL_RCSID(0, "$NetBSD: compat_util.c,v 1.43 2009/12/14 04:09:38 mrg Exp $"); | |
34 | 62 | |||
35 | #include <sys/param.h> | 63 | #include <sys/param.h> | |
36 | #include <sys/systm.h> | 64 | #include <sys/systm.h> | |
37 | #include <sys/namei.h> | 65 | #include <sys/namei.h> | |
38 | #include <sys/proc.h> | 66 | #include <sys/proc.h> | |
39 | #include <sys/file.h> | 67 | #include <sys/file.h> | |
40 | #include <sys/stat.h> | 68 | #include <sys/stat.h> | |
41 | #include <sys/filedesc.h> | 69 | #include <sys/filedesc.h> | |
42 | #include <sys/exec.h> | 70 | #include <sys/exec.h> | |
43 | #include <sys/ioctl.h> | 71 | #include <sys/ioctl.h> | |
44 | #include <sys/kernel.h> | 72 | #include <sys/kernel.h> | |
45 | #include <sys/malloc.h> | 73 | #include <sys/malloc.h> | |
46 | #include <sys/vnode.h> | 74 | #include <sys/vnode.h> | |
47 | #include <sys/syslog.h> | 75 | #include <sys/syslog.h> | |
48 | #include <sys/mount.h> | 76 | #include <sys/mount.h> | |
49 | 77 | |||
50 | #include <compat/common/compat_util.h> | 78 | #include <compat/common/compat_util.h> | |
51 | 79 | |||
52 | void | 80 | void | |
53 | emul_find_root(struct lwp *l, struct exec_package *epp) | 81 | emul_find_root(struct lwp *l, struct exec_package *epp) | |
54 | { | 82 | { | |
55 | struct vnode *vp; | 83 | struct vnode *vp; | |
56 | const char *emul_path; | 84 | const char *emul_path; | |
57 | 85 | |||
58 | if (epp->ep_emul_root != NULL) | 86 | if (epp->ep_emul_root != NULL) | |
59 | /* We've already found it */ | 87 | /* We've already found it */ | |
60 | return; | 88 | return; | |
61 | 89 | |||
62 | emul_path = epp->ep_esch->es_emul->e_path; | 90 | emul_path = epp->ep_esch->es_emul->e_path; | |
63 | if (emul_path == NULL) | 91 | if (emul_path == NULL) | |
64 | /* Emulation doesn't have a root */ | 92 | /* Emulation doesn't have a root */ | |
65 | return; | 93 | return; | |
66 | 94 | |||
67 | if (namei_simple_kernel(emul_path, NSM_FOLLOW_NOEMULROOT, &vp) != 0) | 95 | if (namei_simple_kernel(emul_path, NSM_FOLLOW_NOEMULROOT, &vp) != 0) | |
68 | /* emulation root doesn't exist */ | 96 | /* emulation root doesn't exist */ | |
69 | return; | 97 | return; | |
70 | 98 | |||
71 | epp->ep_emul_root = vp; | 99 | epp->ep_emul_root = vp; | |
72 | } | 100 | } | |
73 | 101 | |||
74 | /* | 102 | /* | |
75 | * Search the alternate path for dynamic binary interpreter. If not found | 103 | * Search the alternate path for dynamic binary interpreter. If not found | |
76 | * there, check if the interpreter exists in within 'proper' tree. | 104 | * there, check if the interpreter exists in within 'proper' tree. | |
77 | */ | 105 | */ | |
78 | int | 106 | int | |
79 | emul_find_interp(struct lwp *l, struct exec_package *epp, const char *itp) | 107 | emul_find_interp(struct lwp *l, struct exec_package *epp, const char *itp) | |
80 | { | 108 | { | |
81 | int error; | 109 | int error; | |
82 | struct nameidata nd; | 110 | struct nameidata nd; | |
83 | unsigned int flags; | 111 | unsigned int flags; | |
84 | 112 | |||
85 | /* If we haven't found the emulation root already, do so now */ | 113 | /* If we haven't found the emulation root already, do so now */ | |
86 | /* Maybe we should remember failures somehow ? */ | 114 | /* Maybe we should remember failures somehow ? */ | |
87 | if (epp->ep_esch->es_emul->e_path != 0 && epp->ep_emul_root == NULL) | 115 | if (epp->ep_esch->es_emul->e_path != 0 && epp->ep_emul_root == NULL) | |
88 | emul_find_root(l, epp); | 116 | emul_find_root(l, epp); | |
89 | 117 | |||
90 | if (epp->ep_interp != NULL) | 118 | if (epp->ep_interp != NULL) | |
91 | vrele(epp->ep_interp); | 119 | vrele(epp->ep_interp); | |
92 | 120 | |||
93 | /* We need to use the emulation root for the new program, | 121 | /* We need to use the emulation root for the new program, | |
94 | * not the one for the current process. */ | 122 | * not the one for the current process. */ | |
95 | if (epp->ep_emul_root == NULL) | 123 | if (epp->ep_emul_root == NULL) | |
96 | flags = FOLLOW; | 124 | flags = FOLLOW; | |
97 | else { | 125 | else { | |
98 | nd.ni_erootdir = epp->ep_emul_root; | 126 | nd.ni_erootdir = epp->ep_emul_root; | |
99 | /* hack: Pass in the emulation path for ktrace calls */ | 127 | /* hack: Pass in the emulation path for ktrace calls */ | |
100 | nd.ni_next = epp->ep_esch->es_emul->e_path; | 128 | nd.ni_next = epp->ep_esch->es_emul->e_path; | |
101 | flags = FOLLOW | TRYEMULROOT | EMULROOTSET; | 129 | flags = FOLLOW | TRYEMULROOT | EMULROOTSET; | |
102 | } | 130 | } | |
103 | 131 | |||
104 | NDINIT(&nd, LOOKUP, flags, UIO_SYSSPACE, itp); | 132 | NDINIT(&nd, LOOKUP, flags, UIO_SYSSPACE, itp); | |
105 | error = namei(&nd); | 133 | error = namei(&nd); | |
106 | if (error != 0) { | 134 | if (error != 0) { | |
107 | epp->ep_interp = NULL; | 135 | epp->ep_interp = NULL; | |
108 | return error; | 136 | return error; | |
109 | } | 137 | } | |
110 | 138 | |||
111 | /* Save interpreter in case we actually need to load it */ | 139 | /* Save interpreter in case we actually need to load it */ | |
112 | epp->ep_interp = nd.ni_vp; | 140 | epp->ep_interp = nd.ni_vp; | |
113 | 141 | |||
114 | return 0; | 142 | return 0; | |
115 | } | 143 | } | |
116 | 144 | |||
117 | /* | 145 | /* | |
118 | * Translate one set of flags to another, based on the entries in | 146 | * Translate one set of flags to another, based on the entries in | |
119 | * the given table. If 'leftover' is specified, it is filled in | 147 | * the given table. If 'leftover' is specified, it is filled in | |
120 | * with any flags which could not be translated. | 148 | * with any flags which could not be translated. | |
121 | */ | 149 | */ | |
122 | unsigned long | 150 | unsigned long | |
123 | emul_flags_translate(const struct emul_flags_xtab *tab, | 151 | emul_flags_translate(const struct emul_flags_xtab *tab, | |
124 | unsigned long in, unsigned long *leftover) | 152 | unsigned long in, unsigned long *leftover) | |
125 | { | 153 | { | |
126 | unsigned long out; | 154 | unsigned long out; | |
127 | 155 | |||
128 | for (out = 0; tab->omask != 0; tab++) { | 156 | for (out = 0; tab->omask != 0; tab++) { | |
129 | if ((in & tab->omask) == tab->oval) { | 157 | if ((in & tab->omask) == tab->oval) { | |
130 | in &= ~tab->omask; | 158 | in &= ~tab->omask; | |
131 | out |= tab->nval; | 159 | out |= tab->nval; | |
132 | } | 160 | } | |
133 | } | 161 | } | |
134 | if (leftover != NULL) | 162 | if (leftover != NULL) | |
135 | *leftover = in; | 163 | *leftover = in; | |
136 | return (out); | 164 | return (out); | |
137 | } | 165 | } | |
138 | 166 | |||
139 | void | 167 | void | |
140 | compat_offseterr(struct vnode *vp, const char *msg) | 168 | compat_offseterr(struct vnode *vp, const char *msg) | |
141 | { | 169 | { | |
142 | struct mount *mp; | 170 | struct mount *mp; | |
143 | 171 | |||
144 | mp = vp->v_mount; | 172 | mp = vp->v_mount; | |
145 | 173 | |||
146 | log(LOG_ERR, "%s: dir offset too large on fs %s (mounted from %s)\n", | 174 | log(LOG_ERR, "%s: dir offset too large on fs %s (mounted from %s)\n", | |
147 | msg, mp->mnt_stat.f_mntonname, mp->mnt_stat.f_mntfromname); | 175 | msg, mp->mnt_stat.f_mntonname, mp->mnt_stat.f_mntfromname); | |
148 | uprintf("%s: dir offset too large for emulated program\n", msg); | 176 | uprintf("%s: dir offset too large for emulated program\n", msg); | |
149 | } | 177 | } | |
178 | ||||
179 | /* | |||
180 | * Look for native NetBSD compatibility libraries, usually interp-ABI. | |||
181 | * It returns 0 if it changed the interpreter, otherwise it returns | |||
182 | * the error from namei(). Callers should not try any more processing | |||
183 | * if this returns 0, and probably should just ignore the return value. | |||
184 | */ | |||
185 | int | |||
186 | compat_elf_check_interp(struct exec_package *epp, | |||
187 | char *interp, | |||
188 | const char *interp_suffix) | |||
189 | { | |||
190 | int error = 0; | |||
191 | ||||
192 | /* | |||
193 | * Don't look for something else, if someone has already found and | |||
194 | * setup the ep_interp already. | |||
195 | */ | |||
196 | if (interp && epp->ep_interp == NULL) { | |||
197 | /* | |||
198 | * If the path is exactly "/usr/libexec/ld.elf_so", first | |||
199 | * try to see if "/usr/libexec/ld.elf_so-<abi>" exists | |||
200 | * and if so, use that instead. | |||
201 | */ | |||
202 | if (strcmp(interp, "/usr/libexec/ld.elf_so") == 0 || | |||
203 | strcmp(interp, "/libexec/ld.elf_so") == 0) { | |||
204 | struct vnode *vp; | |||
205 | char *path; | |||
206 | ||||
207 | path = PNBUF_GET(); | |||
208 | snprintf(path, MAXPATHLEN, "%s-%s", interp, interp_suffix); | |||
209 | error = namei_simple_kernel(path, | |||
210 | NSM_FOLLOW_NOEMULROOT, &vp); | |||
211 | /* | |||
212 | * If that worked, replace interpreter in case we | |||
213 | * actually need to load it. | |||
214 | */ | |||
215 | if (error == 0) { | |||
216 | epp->ep_interp = vp; | |||
217 | snprintf(interp, MAXPATHLEN, "%s", path); | |||
218 | } | |||
219 | PNBUF_PUT(path); | |||
220 | } | |||
221 | } | |||
222 | return error; | |||
223 | } |
--- src/sys/compat/common/compat_util.h 2008/11/19 18:36:02 1.21
+++ src/sys/compat/common/compat_util.h 2009/12/14 04:09:38 1.22
@@ -1,85 +1,88 @@ | @@ -1,85 +1,88 @@ | |||
1 | /* $NetBSD: compat_util.h,v 1.21 2008/11/19 18:36:02 ad Exp $ */ | 1 | /* $NetBSD: compat_util.h,v 1.22 2009/12/14 04:09:38 mrg Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1994 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1994 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Christos Zoulas. | 8 | * by Christos Zoulas. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | /* | 32 | /* | |
33 | * Copyright (c) 1995 Frank van der Linden | 33 | * Copyright (c) 1995 Frank van der Linden | |
34 | * Copyright (c) 2009 Matthew R. Green | |||
34 | * All rights reserved. | 35 | * All rights reserved. | |
35 | * | 36 | * | |
36 | * Redistribution and use in source and binary forms, with or without | 37 | * Redistribution and use in source and binary forms, with or without | |
37 | * modification, are permitted provided that the following conditions | 38 | * modification, are permitted provided that the following conditions | |
38 | * are met: | 39 | * are met: | |
39 | * 1. Redistributions of source code must retain the above copyright | 40 | * 1. Redistributions of source code must retain the above copyright | |
40 | * notice, this list of conditions and the following disclaimer. | 41 | * notice, this list of conditions and the following disclaimer. | |
41 | * 2. Redistributions in binary form must reproduce the above copyright | 42 | * 2. Redistributions in binary form must reproduce the above copyright | |
42 | * notice, this list of conditions and the following disclaimer in the | 43 | * notice, this list of conditions and the following disclaimer in the | |
43 | * documentation and/or other materials provided with the distribution. | 44 | * documentation and/or other materials provided with the distribution. | |
44 | * 3. The name of the author may not be used to endorse or promote products | 45 | * 3. The name of the author may not be used to endorse or promote products | |
45 | * derived from this software without specific prior written permission | 46 | * derived from this software without specific prior written permission | |
46 | * | 47 | * | |
47 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 48 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
48 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 49 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
49 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 50 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
50 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 51 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
51 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 52 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
52 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 53 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
53 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 54 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
54 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 55 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
55 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 56 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
56 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 57 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
57 | * | 58 | * | |
58 | */ | 59 | */ | |
59 | 60 | |||
60 | #ifndef _COMPAT_UTIL_H_ | 61 | #ifndef _COMPAT_UTIL_H_ | |
61 | #define _COMPAT_UTIL_H_ | 62 | #define _COMPAT_UTIL_H_ | |
62 | 63 | |||
63 | struct emul; | 64 | struct emul; | |
64 | struct proc; | 65 | struct proc; | |
65 | struct exec_package; | 66 | struct exec_package; | |
66 | 67 | |||
67 | struct emul_flags_xtab { | 68 | struct emul_flags_xtab { | |
68 | unsigned long omask; | 69 | unsigned long omask; | |
69 | unsigned long oval; | 70 | unsigned long oval; | |
70 | unsigned long nval; | 71 | unsigned long nval; | |
71 | }; | 72 | }; | |
72 | 73 | |||
73 | void emul_find_root(struct lwp *, struct exec_package *); | 74 | void emul_find_root(struct lwp *, struct exec_package *); | |
74 | 75 | |||
75 | int emul_find_interp(struct lwp *, struct exec_package *, const char *); | 76 | int emul_find_interp(struct lwp *, struct exec_package *, const char *); | |
76 | 77 | |||
77 | unsigned long emul_flags_translate(const struct emul_flags_xtab *tab, | 78 | unsigned long emul_flags_translate(const struct emul_flags_xtab *tab, | |
78 | unsigned long in, unsigned long *leftover); | 79 | unsigned long in, unsigned long *leftover); | |
79 | 80 | |||
80 | void compat_offseterr(struct vnode *, const char *); | 81 | void compat_offseterr(struct vnode *, const char *); | |
81 | 82 | |||
83 | int compat_elf_check_interp(struct exec_package *, char *, const char *); | |||
84 | ||||
82 | void compat_sysctl_init(void); | 85 | void compat_sysctl_init(void); | |
83 | void compat_sysctl_fini(void); | 86 | void compat_sysctl_fini(void); | |
84 | 87 | |||
85 | #endif /* !_COMPAT_UTIL_H_ */ | 88 | #endif /* !_COMPAT_UTIL_H_ */ |
--- src/sys/compat/netbsd32/netbsd32_exec_elf32.c 2009/12/14 00:47:11 1.31
+++ src/sys/compat/netbsd32/netbsd32_exec_elf32.c 2009/12/14 04:09:38 1.32
@@ -1,245 +1,213 @@ | @@ -1,245 +1,213 @@ | |||
1 | /* $NetBSD: netbsd32_exec_elf32.c,v 1.31 2009/12/14 00:47:11 matt Exp $ */ | 1 | /* $NetBSD: netbsd32_exec_elf32.c,v 1.32 2009/12/14 04:09:38 mrg Exp $ */ | |
2 | /* from: NetBSD: exec_aout.c,v 1.15 1996/09/26 23:34:46 cgd Exp */ | 2 | /* from: NetBSD: exec_aout.c,v 1.15 1996/09/26 23:34:46 cgd Exp */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 1998, 2001 Matthew R. Green. | 5 | * Copyright (c) 1998, 2001 Matthew R. Green. | |
6 | * All rights reserved. | 6 | * All rights reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
15 | * documentation and/or other materials provided with the distribution. | 15 | * documentation and/or other materials provided with the distribution. | |
16 | * | 16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | /* | 29 | /* | |
30 | * Copyright (c) 1993, 1994 Christopher G. Demetriou | 30 | * Copyright (c) 1993, 1994 Christopher G. Demetriou | |
31 | * All rights reserved. | 31 | * All rights reserved. | |
32 | * | 32 | * | |
33 | * Redistribution and use in source and binary forms, with or without | 33 | * Redistribution and use in source and binary forms, with or without | |
34 | * modification, are permitted provided that the following conditions | 34 | * modification, are permitted provided that the following conditions | |
35 | * are met: | 35 | * are met: | |
36 | * 1. Redistributions of source code must retain the above copyright | 36 | * 1. Redistributions of source code must retain the above copyright | |
37 | * notice, this list of conditions and the following disclaimer. | 37 | * notice, this list of conditions and the following disclaimer. | |
38 | * 2. Redistributions in binary form must reproduce the above copyright | 38 | * 2. Redistributions in binary form must reproduce the above copyright | |
39 | * notice, this list of conditions and the following disclaimer in the | 39 | * notice, this list of conditions and the following disclaimer in the | |
40 | * documentation and/or other materials provided with the distribution. | 40 | * documentation and/or other materials provided with the distribution. | |
41 | * 3. All advertising materials mentioning features or use of this software | 41 | * 3. All advertising materials mentioning features or use of this software | |
42 | * must display the following acknowledgement: | 42 | * must display the following acknowledgement: | |
43 | * This product includes software developed by Christopher G. Demetriou. | 43 | * This product includes software developed by Christopher G. Demetriou. | |
44 | * 4. The name of the author may not be used to endorse or promote products | 44 | * 4. The name of the author may not be used to endorse or promote products | |
45 | * derived from this software without specific prior written permission | 45 | * derived from this software without specific prior written permission | |
46 | * | 46 | * | |
47 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 47 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
48 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 48 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
49 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 49 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
50 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 50 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
51 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 51 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
52 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 52 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
53 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 53 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
54 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 54 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
55 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 55 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
56 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 56 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
57 | */ | 57 | */ | |
58 | 58 | |||
59 | #include <sys/cdefs.h> | 59 | #include <sys/cdefs.h> | |
60 | __KERNEL_RCSID(0, "$NetBSD: netbsd32_exec_elf32.c,v 1.31 2009/12/14 00:47:11 matt Exp $"); | 60 | __KERNEL_RCSID(0, "$NetBSD: netbsd32_exec_elf32.c,v 1.32 2009/12/14 04:09:38 mrg Exp $"); | |
61 | 61 | |||
62 | #define ELFSIZE 32 | 62 | #define ELFSIZE 32 | |
63 | 63 | |||
64 | #include <sys/param.h> | 64 | #include <sys/param.h> | |
65 | #include <sys/systm.h> | 65 | #include <sys/systm.h> | |
66 | #include <sys/proc.h> | 66 | #include <sys/proc.h> | |
67 | #include <sys/malloc.h> | 67 | #include <sys/malloc.h> | |
68 | #include <sys/vnode.h> | 68 | #include <sys/vnode.h> | |
69 | #include <sys/exec.h> | 69 | #include <sys/exec.h> | |
70 | #include <sys/exec_elf.h> | 70 | #include <sys/exec_elf.h> | |
71 | #include <sys/resourcevar.h> | 71 | #include <sys/resourcevar.h> | |
72 | #include <sys/signal.h> | 72 | #include <sys/signal.h> | |
73 | #include <sys/signalvar.h> | 73 | #include <sys/signalvar.h> | |
74 | #include <sys/kauth.h> | 74 | #include <sys/kauth.h> | |
75 | #include <sys/namei.h> | 75 | #include <sys/namei.h> | |
76 | 76 | |||
77 | #include <compat/common/compat_util.h> | |||
78 | ||||
77 | #include <compat/netbsd32/netbsd32.h> | 79 | #include <compat/netbsd32/netbsd32.h> | |
78 | #include <compat/netbsd32/netbsd32_exec.h> | 80 | #include <compat/netbsd32/netbsd32_exec.h> | |
79 | 81 | |||
80 | #include <machine/netbsd32_machdep.h> | 82 | #include <machine/netbsd32_machdep.h> | |
81 | 83 | |||
82 | int netbsd32_copyinargs(struct exec_package *, struct ps_strings *, | 84 | int netbsd32_copyinargs(struct exec_package *, struct ps_strings *, | |
83 | void *, size_t, const void *, const void *); | 85 | void *, size_t, const void *, const void *); | |
84 | int ELFNAME2(netbsd32,probe_noteless)(struct lwp *, struct exec_package *epp, | 86 | int ELFNAME2(netbsd32,probe_noteless)(struct lwp *, struct exec_package *epp, | |
85 | void *eh, char *itp, vaddr_t *pos); | 87 | void *eh, char *itp, vaddr_t *pos); | |
86 | extern int ELFNAME2(netbsd,signature)(struct lwp *, struct exec_package *, | 88 | extern int ELFNAME2(netbsd,signature)(struct lwp *, struct exec_package *, | |
87 | Elf_Ehdr *); | 89 | Elf_Ehdr *); | |
88 | 90 | |||
89 | int | 91 | int | |
90 | ELFNAME2(netbsd32,probe)(struct lwp *l, struct exec_package *epp, | 92 | ELFNAME2(netbsd32,probe)(struct lwp *l, struct exec_package *epp, | |
91 | void *eh, char *itp, vaddr_t *pos) | 93 | void *eh, char *itp, vaddr_t *pos) | |
92 | { | 94 | { | |
93 | int error; | 95 | int error; | |
94 | 96 | |||
95 | if ((error = ELFNAME2(netbsd,signature)(l, epp, eh)) != 0) | 97 | if ((error = ELFNAME2(netbsd,signature)(l, epp, eh)) != 0) | |
96 | return error; | 98 | return error; | |
97 | 99 | |||
98 | #ifdef ELF_MD_PROBE_FUNC | 100 | #ifdef ELF_MD_PROBE_FUNC | |
99 | if ((error = ELF_MD_PROBE_FUNC(l, epp, eh, itp, pos)) != 0) | 101 | if ((error = ELF_MD_PROBE_FUNC(l, epp, eh, itp, pos)) != 0) | |
100 | return error; | 102 | return error; | |
101 | #elif defined(ELF_INTERP_NON_RELOCATABLE) | 103 | #elif defined(ELF_INTERP_NON_RELOCATABLE) | |
102 | *pos = ELF_LINK_ADDR; | 104 | *pos = ELF_LINK_ADDR; | |
103 | #endif | 105 | #endif | |
104 | 106 | |||
105 | return ELFNAME2(netbsd32,probe_noteless)(l, epp, eh, itp, pos); | 107 | return ELFNAME2(netbsd32,probe_noteless)(l, epp, eh, itp, pos); | |
106 | } | 108 | } | |
107 | 109 | |||
108 | int | 110 | int | |
109 | ELFNAME2(netbsd32,probe_noteless)(struct lwp *l, struct exec_package *epp, | 111 | ELFNAME2(netbsd32,probe_noteless)(struct lwp *l, struct exec_package *epp, | |
110 | void *eh, char *itp, vaddr_t *pos) | 112 | void *eh, char *itp, vaddr_t *pos) | |
111 | { | 113 | { | |
112 | int error; | 114 | if (itp && epp->ep_interp == NULL) { | |
113 | 115 | extern const char machine32[]; | ||
114 | if (itp) { | 116 | (void)compat_elf_check_interp(epp, itp, machine32); | |
115 | /* | |||
116 | * If the path is exactly "/usr/libexec/ld.elf_so", first | |||
117 | * try to see if "/usr/libexec/ld.elf_so-<arch>" exists | |||
118 | * and if so, use that instead. | |||
119 | * XXX maybe move this into compat/common | |||
120 | */ | |||
121 | error = 0; | |||
122 | if (strcmp(itp, "/usr/libexec/ld.elf_so") == 0 || | |||
123 | strcmp(itp, "/libexec/ld.elf_so") == 0) { | |||
124 | extern const char machine32[]; | |||
125 | struct vnode *vp; | |||
126 | char *path; | |||
127 | ||||
128 | if (epp->ep_interp != NULL) | |||
129 | vrele(epp->ep_interp); | |||
130 | ||||
131 | path = PNBUF_GET(); | |||
132 | snprintf(path, MAXPATHLEN, "%s-%s", itp, machine32); | |||
133 | error = namei_simple_kernel(path, | |||
134 | NSM_FOLLOW_NOEMULROOT, &vp); | |||
135 | /* | |||
136 | * If that worked, save interpreter in case we | |||
137 | * actually need to load it | |||
138 | */ | |||
139 | if (error != 0) | |||
140 | epp->ep_interp = NULL; | |||
141 | else | |||
142 | epp->ep_interp = vp; | |||
143 | PNBUF_PUT(path); | |||
144 | } | |||
145 | ||||
146 | /* Translate interpreter name if needed */ | |||
147 | if (error && (error = emul_find_interp(l, epp, itp)) != 0) | |||
148 | return error; | |||
149 | } | 117 | } | |
150 | epp->ep_flags |= EXEC_32; | 118 | epp->ep_flags |= EXEC_32; | |
151 | epp->ep_vm_minaddr = VM_MIN_ADDRESS; | 119 | epp->ep_vm_minaddr = VM_MIN_ADDRESS; | |
152 | epp->ep_vm_maxaddr = USRSTACK32; | 120 | epp->ep_vm_maxaddr = USRSTACK32; | |
153 | #ifdef ELF_INTERP_NON_RELOCATABLE | 121 | #ifdef ELF_INTERP_NON_RELOCATABLE | |
154 | *pos = ELF_LINK_ADDR; | 122 | *pos = ELF_LINK_ADDR; | |
155 | #endif | 123 | #endif | |
156 | return 0; | 124 | return 0; | |
157 | } | 125 | } | |
158 | 126 | |||
159 | /* round up and down to page boundaries. */ | 127 | /* round up and down to page boundaries. */ | |
160 | #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) | 128 | #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) | |
161 | #define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) | 129 | #define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) | |
162 | 130 | |||
163 | /* | 131 | /* | |
164 | * Copy arguments onto the stack in the normal way, but add some | 132 | * Copy arguments onto the stack in the normal way, but add some | |
165 | * extra information in case of dynamic binding. | 133 | * extra information in case of dynamic binding. | |
166 | */ | 134 | */ | |
167 | int | 135 | int | |
168 | netbsd32_elf32_copyargs(struct lwp *l, struct exec_package *pack, | 136 | netbsd32_elf32_copyargs(struct lwp *l, struct exec_package *pack, | |
169 | struct ps_strings *arginfo, char **stackp, void *argp) | 137 | struct ps_strings *arginfo, char **stackp, void *argp) | |
170 | { | 138 | { | |
171 | size_t len; | 139 | size_t len; | |
172 | AuxInfo ai[ELF_AUX_ENTRIES], *a; | 140 | AuxInfo ai[ELF_AUX_ENTRIES], *a; | |
173 | struct elf_args *ap; | 141 | struct elf_args *ap; | |
174 | int error; | 142 | int error; | |
175 | 143 | |||
176 | if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0) | 144 | if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0) | |
177 | return error; | 145 | return error; | |
178 | 146 | |||
179 | a = ai; | 147 | a = ai; | |
180 | 148 | |||
181 | /* | 149 | /* | |
182 | * Push extra arguments on the stack needed by dynamically | 150 | * Push extra arguments on the stack needed by dynamically | |
183 | * linked binaries | 151 | * linked binaries | |
184 | */ | 152 | */ | |
185 | if ((ap = (struct elf_args *)pack->ep_emul_arg)) { | 153 | if ((ap = (struct elf_args *)pack->ep_emul_arg)) { | |
186 | 154 | |||
187 | a->a_type = AT_PHDR; | 155 | a->a_type = AT_PHDR; | |
188 | a->a_v = ap->arg_phaddr; | 156 | a->a_v = ap->arg_phaddr; | |
189 | a++; | 157 | a++; | |
190 | 158 | |||
191 | a->a_type = AT_PHENT; | 159 | a->a_type = AT_PHENT; | |
192 | a->a_v = ap->arg_phentsize; | 160 | a->a_v = ap->arg_phentsize; | |
193 | a++; | 161 | a++; | |
194 | 162 | |||
195 | a->a_type = AT_PHNUM; | 163 | a->a_type = AT_PHNUM; | |
196 | a->a_v = ap->arg_phnum; | 164 | a->a_v = ap->arg_phnum; | |
197 | a++; | 165 | a++; | |
198 | 166 | |||
199 | a->a_type = AT_PAGESZ; | 167 | a->a_type = AT_PAGESZ; | |
200 | a->a_v = PAGE_SIZE; | 168 | a->a_v = PAGE_SIZE; | |
201 | a++; | 169 | a++; | |
202 | 170 | |||
203 | a->a_type = AT_BASE; | 171 | a->a_type = AT_BASE; | |
204 | a->a_v = ap->arg_interp; | 172 | a->a_v = ap->arg_interp; | |
205 | a++; | 173 | a++; | |
206 | 174 | |||
207 | a->a_type = AT_FLAGS; | 175 | a->a_type = AT_FLAGS; | |
208 | a->a_v = 0; | 176 | a->a_v = 0; | |
209 | a++; | 177 | a++; | |
210 | 178 | |||
211 | a->a_type = AT_ENTRY; | 179 | a->a_type = AT_ENTRY; | |
212 | a->a_v = ap->arg_entry; | 180 | a->a_v = ap->arg_entry; | |
213 | a++; | 181 | a++; | |
214 | 182 | |||
215 | a->a_type = AT_EUID; | 183 | a->a_type = AT_EUID; | |
216 | a->a_v = kauth_cred_geteuid(l->l_cred); | 184 | a->a_v = kauth_cred_geteuid(l->l_cred); | |
217 | a++; | 185 | a++; | |
218 | 186 | |||
219 | a->a_type = AT_RUID; | 187 | a->a_type = AT_RUID; | |
220 | a->a_v = kauth_cred_getuid(l->l_cred); | 188 | a->a_v = kauth_cred_getuid(l->l_cred); | |
221 | a++; | 189 | a++; | |
222 | 190 | |||
223 | a->a_type = AT_EGID; | 191 | a->a_type = AT_EGID; | |
224 | a->a_v = kauth_cred_getegid(l->l_cred); | 192 | a->a_v = kauth_cred_getegid(l->l_cred); | |
225 | a++; | 193 | a++; | |
226 | 194 | |||
227 | a->a_type = AT_RGID; | 195 | a->a_type = AT_RGID; | |
228 | a->a_v = kauth_cred_getgid(l->l_cred); | 196 | a->a_v = kauth_cred_getgid(l->l_cred); | |
229 | a++; | 197 | a++; | |
230 | 198 | |||
231 | free((char *)ap, M_TEMP); | 199 | free((char *)ap, M_TEMP); | |
232 | pack->ep_emul_arg = NULL; | 200 | pack->ep_emul_arg = NULL; | |
233 | } | 201 | } | |
234 | 202 | |||
235 | a->a_type = AT_NULL; | 203 | a->a_type = AT_NULL; | |
236 | a->a_v = 0; | 204 | a->a_v = 0; | |
237 | a++; | 205 | a++; | |
238 | 206 | |||
239 | len = (a - ai) * sizeof(AuxInfo); | 207 | len = (a - ai) * sizeof(AuxInfo); | |
240 | if ((error = copyout(ai, *stackp, len)) != 0) | 208 | if ((error = copyout(ai, *stackp, len)) != 0) | |
241 | return error; | 209 | return error; | |
242 | *stackp += len; | 210 | *stackp += len; | |
243 | 211 | |||
244 | return 0; | 212 | return 0; | |
245 | } | 213 | } |