1 /* $NetBSD: linux_exec_powerpc.c,v 1.20 2006/07/23 22:06:09 ad Exp $ */
4 * Copyright (c) 2001 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.
33 * From NetBSD's sys/compat/arch/alpha/linux_exec_alpha.c, with some
34 * powerpc add-ons (ifdef LINUX_SHIFT).
36 * This code is to be common to alpha and powerpc. If it works on alpha, it
37 * should be moved to common/linux_exec_elf32.c. Beware that it needs
38 * LINUX_ELF_AUX_ENTRIES in arch/<arch>/linux_exec.h to also be moved to common
40 * Emmanuel Dreyfus <p99dreyf@criens.u-psud.fr>
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: linux_exec_powerpc.c,v 1.20 2006/07/23 22:06:09 ad Exp $");
46 #if defined (__alpha__)
48 #elif defined (__powerpc__)
51 #error Unified linux_elf_{32|64}copyargs not tested for this platform
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/kernel.h>
57 #include <sys/malloc.h>
60 #include <sys/exec_elf.h>
61 #include <sys/resourcevar.h>
62 #include <sys/kauth.h>
64 #include <uvm/uvm_extern.h>
66 #include <compat/linux/common/linux_exec.h>
69 * Alpha and PowerPC specific linux copyargs function.
72 ELFNAME2(linux
,copyargs
)(l
, pack
, arginfo
, stackp
, argp
)
74 struct exec_package
*pack
;
75 struct ps_strings
*arginfo
;
80 AuxInfo ai
[LINUX_ELF_AUX_ENTRIES
], *a
;
86 * Seems that PowerPC Linux binaries expect argc to start on a 16 bytes
87 * aligned address. And we need one more 16 byte shift if it was already
90 *stackp
= (char *)(((unsigned long)*stackp
- 1) & ~LINUX_SHIFT
);
93 if ((error
= copyargs(l
, pack
, arginfo
, stackp
, argp
)) != 0)
98 * From Linux's arch/ppc/kernel/process.c:shove_aux_table(). GNU ld.so
99 * expects the ELF auxiliary table to start on a 16 bytes boundary on
102 *stackp
= (char *)(((unsigned long)(*stackp
) + LINUX_SHIFT
)
106 memset(ai
, 0, sizeof(AuxInfo
) * LINUX_ELF_AUX_ENTRIES
);
111 * Push extra arguments on the stack needed by dynamically
114 if ((ap
= (struct elf_args
*)pack
->ep_emul_arg
)) {
117 * The exec_package doesn't have a proc pointer and it's not
118 * exactly trivial to add one since the credentials are
119 * changing. XXX Linux uses curlwp's credentials.
120 * Why can't we use them too? XXXad we do, what's different?
122 a
->a_type
= LINUX_AT_EGID
;
123 a
->a_v
= kauth_cred_getegid(l
->l_cred
);
126 a
->a_type
= LINUX_AT_GID
;
127 a
->a_v
= kauth_cred_getgid(l
->l_cred
);
130 a
->a_type
= LINUX_AT_EUID
;
131 a
->a_v
= kauth_cred_geteuid(l
->l_cred
);
134 a
->a_type
= LINUX_AT_UID
;
135 a
->a_v
= kauth_cred_getuid(l
->l_cred
);
139 a
->a_type
= AT_ENTRY
;
140 a
->a_v
= ap
->arg_entry
;
143 a
->a_type
= AT_FLAGS
;
148 a
->a_v
= ap
->arg_interp
;
151 a
->a_type
= AT_PHNUM
;
152 a
->a_v
= ap
->arg_phnum
;
155 a
->a_type
= AT_PHENT
;
156 a
->a_v
= ap
->arg_phentsize
;
160 a
->a_v
= ap
->arg_phaddr
;
163 a
->a_type
= LINUX_AT_CLKTCK
;
164 a
->a_v
= LINUX_CLOCKS_PER_SEC
;
167 a
->a_type
= AT_PAGESZ
;
171 a
->a_type
= LINUX_AT_HWCAP
;
172 a
->a_v
= LINUX_ELF_HWCAP
;
175 free((char *)ap
, M_TEMP
);
176 pack
->ep_emul_arg
= NULL
;
183 len
= (a
- ai
) * sizeof(AuxInfo
);
185 if ((error
= copyout(ai
, *stackp
, len
)) != 0)