1 /* $NetBSD: svr4_32_exec_elf32.c,v 1.13 2003/10/31 14:04:36 drochner Exp $ */
2
3 /*-
4 * Copyright (c) 1994 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 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: svr4_32_exec_elf32.c,v 1.13 2003/10/31 14:04:36 drochner Exp $");
41
42 #define ELFSIZE 32 /* XXX should die */
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/proc.h>
48 #include <sys/malloc.h>
49 #include <sys/namei.h>
50 #include <sys/vnode.h>
51 #include <sys/exec_elf.h>
52 #include <sys/exec.h>
53
54 #include <sys/mman.h>
55
56 #include <machine/cpu.h>
57 #include <machine/reg.h>
58
59 #include <compat/svr4_32/svr4_32_types.h>
60 #include <compat/svr4_32/svr4_32_util.h>
61 #include <compat/svr4_32/svr4_32_exec.h>
62 #include <compat/netbsd32/netbsd32_exec.h>
63 #include <compat/svr4/svr4_errno.h>
64
65 /*
66 * Since this only works on 64-bit machines trying to execute
67 * 32-bit binaries, it's pretty much limited to sparc64
68 * trying to run solaris binaries. So, to simplify this
69 * I'm making this svr4_32_copyargs() SPARC/Solaris specific
70 * so we can run Solaris 8 dynamic binaries that require
71 * lots of fancy specialized support.
72 */
73
74 int sun_flags = EF_SPARC_SUN_US1|EF_SPARC_32PLUS;
75 int sun_hwcap = (AV_SPARC_HWMUL_32x32|AV_SPARC_HWDIV_32x32|AV_SPARC_HWFSMULD);
76
77 #if 0
78 int
79 svr4_32_copyargs(p, pack, arginfo, stackp, argp)
80 struct proc *p;
81 struct exec_package *pack;
82 struct ps_strings *arginfo;
83 char **stackp;
84 void *argp;
85 {
86 size_t len;
87 AuxInfo ai[SVR4_32_AUX_ARGSIZ], *a, *platform=NULL, *exec=NULL;
88 struct elf_args *ap;
89 extern char machine_model[];
90 int error;
91
92 if ((error = netbsd32_copyargs(p, pack, arginfo, stackp, argp)) != 0)
93 return error;
94
95 a = ai;
96
97 /*
98 * Push extra arguments on the stack needed by dynamically
99 * linked binaries
100 */
101 if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
102 struct proc *p = curproc; /* XXXXX */
103
104 a->a_type = AT_SUN_PLATFORM;
105 platform = a; /* Patch this later. */
106 a++;
107
108 if (pack->ep_ndp->ni_cnd.cn_flags & HASBUF) {
109 a->a_type = AT_SUN_EXECNAME;
110 exec = a; /* Patch this later. */
111 a++;
112 }
113
114 a->a_type = AT_PHDR;
115 a->a_v = ap->arg_phaddr;
116 a++;
117
118 a->a_type = AT_PHENT;
119 a->a_v = ap->arg_phentsize;
120 a++;
121
122 a->a_type = AT_PHNUM;
123 a->a_v = ap->arg_phnum;
124 a++;
125
126 a->a_type = AT_ENTRY;
127 a->a_v = ap->arg_entry;
128 a++;
129
130 a->a_type = AT_BASE;
131 a->a_v = ap->arg_interp;
132 a++;
133
134 if (sun_flags) {
135 a->a_type = AT_FLAGS;
136 a->a_v = sun_flags;
137 a++;
138 }
139
140 a->a_type = AT_PAGESZ;
141 a->a_v = PAGE_SIZE;
142 a++;
143
144 a->a_type = AT_EUID;
145 a->a_v = p->p_ucred->cr_uid;
146 a++;
147
148 a->a_type = AT_RUID;
149 a->a_v = p->p_cred->p_ruid;
150 a++;
151
152 a->a_type = AT_EGID;
153 a->a_v = p->p_ucred->cr_gid;
154 a++;
155
156 a->a_type = AT_RGID;
157 a->a_v = p->p_cred->p_rgid;
158 a++;
159
160 if (sun_hwcap) {
161 a->a_type = AT_SUN_HWCAP;
162 a->a_v = sun_hwcap;
163 a++;
164 }
165
166 free((char *)ap, M_TEMP);
167 pack->ep_emul_arg = NULL;
168 }
169
170 a->a_type = AT_NULL;
171 a->a_v = 0;
172 a++;
173
174 len = (a - ai) * sizeof(AuxInfo);
175
176 if (platform) {
177 char *ptr = (char *)a;
178 const char *path = NULL;
179
180 /* Copy out the platform name. */
181 platform->a_v = (u_long)(*stackp) + len;
182 /* XXXX extremely inefficient.... */
183 strcpy(ptr, machine_model);
184 ptr += strlen(machine_model) + 1;
185 len += strlen(machine_model) + 1;
186
187 if (exec) {
188 path = pack->ep_ndp->ni_cnd.cn_pnbuf;
189
190 /* Copy out the file we're executing. */
191 exec->a_v = (u_long)(*stackp) + len;
192 strcpy(ptr, path);
193 len += strlen(ptr)+1;
194 }
195
196 /* Round to 32-bits */
197 len = (len+7)&~0x7L;
198 }
199 if ((error = copyout(ai, *stackp, len)) != 0)
200 return error;
201 *stackp += len;
202
203 return error;
204 }
205 #else
206 int
207 svr4_32_copyargs(p, pack, arginfo, stackp, argp)
208 struct proc *p;
209 struct exec_package *pack;
210 struct ps_strings *arginfo;
211 char **stackp;
212 void *argp;
213 {
214 size_t len;
215 AuxInfo ai[SVR4_32_AUX_ARGSIZ], *a;
216 struct elf_args *ap;
217 int error;
218
219 if ((error = netbsd32_copyargs(p, pack, arginfo, stackp, argp)) != 0)
220 return error;
221
222 a = ai;
223
224 /*
225 * Push extra arguments on the stack needed by dynamically
226 * linked binaries
227 */
228 if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
229
230 a->a_type = AT_PHDR;
231 a->a_v = ap->arg_phaddr;
232 a++;
233
234 a->a_type = AT_PHENT;
235 a->a_v = ap->arg_phentsize;
236 a++;
237
238 a->a_type = AT_PHNUM;
239 a->a_v = ap->arg_phnum;
240 a++;
241
242 a->a_type = AT_PAGESZ;
243 a->a_v = PAGE_SIZE;
244 a++;
245
246 a->a_type = AT_BASE;
247 a->a_v = ap->arg_interp;
248 a++;
249
250 a->a_type = AT_ENTRY;
251 a->a_v = ap->arg_entry;
252 a++;
253
254 if (sun_flags) {
255 a->a_type = AT_FLAGS;
256 a->a_v = sun_flags;
257 a++;
258 }
259
260 free((char *)ap, M_TEMP);
261 pack->ep_emul_arg = NULL;
262 }
263
264 a->a_type = AT_NULL;
265 a->a_v = 0;
266 a++;
267
268 len = (a - ai) * sizeof(AuxInfo);
269 if (copyout(ai, *stackp, len))
270 return error;
271 *stackp += len;
272
273 return 0;
274 }
275 #endif
276
277 int
278 svr4_32_elf32_probe(p, epp, eh, itp, pos)
279 struct proc *p;
280 struct exec_package *epp;
281 void *eh;
282 char *itp;
283 vaddr_t *pos;
284 {
285 int error;
286
287 if (itp) {
288 if ((error = emul_find_interp(p, epp->ep_esch->es_emul->e_path, itp)))
289 return error;
290 }
291 epp->ep_flags |= EXEC_32;
292 #ifdef SVR4_32_INTERP_ADDR
293 *pos = SVR4_32_INTERP_ADDR;
294 #endif
295 return 0;
296 }
Cache object: 959e30303082f924191a4092c7981bca
|