1 /* $NetBSD: svr4_32_exec_elf32.c,v 1.19 2007/12/08 18:36:27 dsl Exp $ */
4 * Copyright (c) 1994 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: svr4_32_exec_elf32.c,v 1.19 2007/12/08 18:36:27 dsl Exp $");
35 #define ELFSIZE 32 /* XXX should die */
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
41 #include <sys/malloc.h>
42 #include <sys/namei.h>
43 #include <sys/vnode.h>
44 #include <sys/exec_elf.h>
50 #include <machine/reg.h>
52 #include <compat/svr4_32/svr4_32_types.h>
53 #include <compat/svr4_32/svr4_32_util.h>
54 #include <compat/svr4_32/svr4_32_exec.h>
55 #include <compat/netbsd32/netbsd32_exec.h>
56 #include <compat/svr4/svr4_errno.h>
59 * Since this only works on 64-bit machines trying to execute
60 * 32-bit binaries, it's pretty much limited to sparc64
61 * trying to run solaris binaries. So, to simplify this
62 * I'm making this svr4_32_copyargs() SPARC/Solaris specific
63 * so we can run Solaris 8 dynamic binaries that require
64 * lots of fancy specialized support.
67 int sun_flags
= EF_SPARC_SUN_US1
|EF_SPARC_32PLUS
;
68 int sun_hwcap
= (AV_SPARC_HWMUL_32x32
|AV_SPARC_HWDIV_32x32
|AV_SPARC_HWFSMULD
);
72 svr4_32_copyargs(struct lwp
*l
, struct exec_package
*pack
, struct ps_strings
*arginfo
, char **stackp
, void *argp
)
75 AuxInfo ai
[SVR4_32_AUX_ARGSIZ
], *a
, *platform
=NULL
, *exec
=NULL
;
77 extern char machine_model
[];
80 if ((error
= netbsd32_copyargs(l
, pack
, arginfo
, stackp
, argp
)) != 0)
86 * Push extra arguments on the stack needed by dynamically
89 if ((ap
= (struct elf_args
*)pack
->ep_emul_arg
)) {
90 struct proc
*p
= curproc
; /* XXXXX */
92 a
->a_type
= AT_SUN_PLATFORM
;
93 platform
= a
; /* Patch this later. */
96 if (pack
->ep_ndp
->ni_cnd
.cn_flags
& HASBUF
) {
97 a
->a_type
= AT_SUN_EXECNAME
;
98 exec
= a
; /* Patch this later. */
103 a
->a_v
= ap
->arg_phaddr
;
106 a
->a_type
= AT_PHENT
;
107 a
->a_v
= ap
->arg_phentsize
;
110 a
->a_type
= AT_PHNUM
;
111 a
->a_v
= ap
->arg_phnum
;
114 a
->a_type
= AT_ENTRY
;
115 a
->a_v
= ap
->arg_entry
;
119 a
->a_v
= ap
->arg_interp
;
123 a
->a_type
= AT_FLAGS
;
128 a
->a_type
= AT_PAGESZ
;
133 a
->a_v
= kauth_cred_geteuid(l
->l_cred
);
137 a
->a_v
= kauth_cred_getuid(l
->l_cred
);
141 a
->a_v
= kauth_cred_getegid(l
->l_cred
);
145 a
->a_v
= kauth_cred_getgid(l
->l_cred
);
149 a
->a_type
= AT_SUN_HWCAP
;
154 free((char *)ap
, M_TEMP
);
155 pack
->ep_emul_arg
= NULL
;
162 len
= (a
- ai
) * sizeof(AuxInfo
);
165 char *ptr
= (char *)a
;
166 const char *path
= NULL
;
168 /* Copy out the platform name. */
169 platform
->a_v
= (u_long
)(*stackp
) + len
;
170 /* XXXX extremely inefficient.... */
171 strcpy(ptr
, machine_model
);
172 ptr
+= strlen(machine_model
) + 1;
173 len
+= strlen(machine_model
) + 1;
176 path
= pack
->ep_ndp
->ni_cnd
.cn_pnbuf
;
178 /* Copy out the file we're executing. */
179 exec
->a_v
= (u_long
)(*stackp
) + len
;
181 len
+= strlen(ptr
)+1;
184 /* Round to 32-bits */
187 if ((error
= copyout(ai
, *stackp
, len
)) != 0)
195 svr4_32_copyargs(struct lwp
*l
, struct exec_package
*pack
, struct ps_strings
*arginfo
, char **stackp
, void *argp
)
198 AuxInfo ai
[SVR4_32_AUX_ARGSIZ
], *a
;
202 if ((error
= netbsd32_copyargs(l
, pack
, arginfo
, stackp
, argp
)) != 0)
208 * Push extra arguments on the stack needed by dynamically
211 if ((ap
= (struct elf_args
*)pack
->ep_emul_arg
)) {
214 a
->a_v
= ap
->arg_phaddr
;
217 a
->a_type
= AT_PHENT
;
218 a
->a_v
= ap
->arg_phentsize
;
221 a
->a_type
= AT_PHNUM
;
222 a
->a_v
= ap
->arg_phnum
;
225 a
->a_type
= AT_PAGESZ
;
230 a
->a_v
= ap
->arg_interp
;
233 a
->a_type
= AT_ENTRY
;
234 a
->a_v
= ap
->arg_entry
;
238 a
->a_type
= AT_FLAGS
;
243 free((char *)ap
, M_TEMP
);
244 pack
->ep_emul_arg
= NULL
;
251 len
= (a
- ai
) * sizeof(AuxInfo
);
252 if (copyout(ai
, *stackp
, len
))
261 svr4_32_elf32_probe(struct lwp
*l
, struct exec_package
*epp
, void *eh
, char *itp
, vaddr_t
*pos
)
266 if ((error
= emul_find_interp(l
, epp
, itp
)))
269 epp
->ep_flags
|= EXEC_32
;
270 #ifdef SVR4_32_INTERP_ADDR
271 *pos
= SVR4_32_INTERP_ADDR
;