xref: /netbsd-src/sys/compat/linux/arch/powerpc/linux_exec_powerpc.c (revision 41aa5859b647891f23013f613e0858c4b789a7bf)
1*41aa5859Sriastradh /* $NetBSD: linux_exec_powerpc.c,v 1.25 2021/09/07 11:43:04 riastradh Exp $ */
254724278Smanu 
354724278Smanu /*-
454724278Smanu  * Copyright (c) 2001 The NetBSD Foundation, Inc.
554724278Smanu  * All rights reserved.
654724278Smanu  *
754724278Smanu  * This code is derived from software contributed to The NetBSD Foundation
854724278Smanu  * by Emmanuel Dreyfus.
954724278Smanu  *
1054724278Smanu  * Redistribution and use in source and binary forms, with or without
1154724278Smanu  * modification, are permitted provided that the following conditions
1254724278Smanu  * are met:
1354724278Smanu  * 1. Redistributions of source code must retain the above copyright
1454724278Smanu  *    notice, this list of conditions and the following disclaimer.
1554724278Smanu  * 2. Redistributions in binary form must reproduce the above copyright
1654724278Smanu  *    notice, this list of conditions and the following disclaimer in the
1754724278Smanu  *    documentation and/or other materials provided with the distribution.
1854724278Smanu  *
1954724278Smanu  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2054724278Smanu  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2154724278Smanu  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2254724278Smanu  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2354724278Smanu  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2454724278Smanu  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2554724278Smanu  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654724278Smanu  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2754724278Smanu  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2854724278Smanu  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2954724278Smanu  * POSSIBILITY OF SUCH DAMAGE.
3054724278Smanu  */
3154724278Smanu 
3254724278Smanu /*
3354724278Smanu  * From NetBSD's sys/compat/arch/alpha/linux_exec_alpha.c, with some
34f8fa568eSchs  * powerpc add-ons (ifdef LINUX_SHIFT).
3554724278Smanu  *
3654724278Smanu  * This code is to be common to alpha and powerpc. If it works on alpha, it
3754724278Smanu  * should be moved to common/linux_exec_elf32.c. Beware that it needs
3854724278Smanu  * LINUX_ELF_AUX_ENTRIES in arch/<arch>/linux_exec.h to also be moved to common
3954724278Smanu  *
4054724278Smanu  * Emmanuel Dreyfus <p99dreyf@criens.u-psud.fr>
4154724278Smanu  */
42dab6ef8bSlukem 
43dab6ef8bSlukem #include <sys/cdefs.h>
44*41aa5859Sriastradh __KERNEL_RCSID(0, "$NetBSD: linux_exec_powerpc.c,v 1.25 2021/09/07 11:43:04 riastradh Exp $");
45dab6ef8bSlukem 
4654724278Smanu #define ELFSIZE 32
4754724278Smanu 
4854724278Smanu #include <sys/param.h>
4954724278Smanu #include <sys/systm.h>
5054724278Smanu #include <sys/kernel.h>
5154724278Smanu #include <sys/proc.h>
5254724278Smanu #include <sys/exec.h>
5354724278Smanu #include <sys/exec_elf.h>
540d510f3eSmanu #include <sys/resourcevar.h>
551e7ca673Syamt #include <sys/kauth.h>
5654724278Smanu 
57d46b766dSthorpej #include <uvm/uvm_extern.h>
58d46b766dSthorpej 
5954724278Smanu #include <compat/linux/common/linux_exec.h>
6054724278Smanu 
6154724278Smanu /*
6254724278Smanu  * Alpha and PowerPC specific linux copyargs function.
6354724278Smanu  */
64934898bcSchristos int
ELFNAME2(linux,copyargs)65bbf374d1Srjs ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack,
66bbf374d1Srjs 			 struct ps_strings *arginfo, char **stackp,
67bbf374d1Srjs 			 void *argp)
6854724278Smanu {
6954724278Smanu 	size_t len;
703e8efcddSjdolecek 	AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a;
7154724278Smanu 	struct elf_args *ap;
72934898bcSchristos 	int error;
7354724278Smanu 
7454724278Smanu #ifdef LINUX_SHIFT
7554724278Smanu 	/*
7654724278Smanu 	 * Seems that PowerPC Linux binaries expect argc to start on a 16 bytes
7754724278Smanu 	 * aligned address. And we need one more 16 byte shift if it was already
7854724278Smanu 	 * 16 bytes aligned,
7954724278Smanu 	 */
80699b0099Schristos 	*stackp = (char *)(((unsigned long)*stackp - 1) & ~LINUX_SHIFT);
8154724278Smanu #endif
8254724278Smanu 
8395e1ffb1Schristos 	if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
84934898bcSchristos 		return error;
8554724278Smanu 
8654724278Smanu #ifdef LINUX_SHIFT
8754724278Smanu 	/*
8854724278Smanu 	 * From Linux's arch/ppc/kernel/process.c:shove_aux_table(). GNU ld.so
89ff4eeac9Schristos 	 * expects the ELF auxiliary table to start on a 16 bytes boundary on
90ff4eeac9Schristos 	 * the PowerPC.
9154724278Smanu 	 */
92934898bcSchristos 	*stackp = (char *)(((unsigned long)(*stackp) + LINUX_SHIFT)
93934898bcSchristos 	    & ~LINUX_SHIFT);
9454724278Smanu #endif
9554724278Smanu 
96*41aa5859Sriastradh 	memset(ai, 0, sizeof(ai));
9754724278Smanu 
9854724278Smanu 	a = ai;
9954724278Smanu 
10054724278Smanu 	/*
10154724278Smanu 	 * Push extra arguments on the stack needed by dynamically
10254724278Smanu 	 * linked binaries.
10354724278Smanu 	 */
10454724278Smanu 	if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
10554724278Smanu #if 1
10654724278Smanu 		/*
10754724278Smanu 		 * The exec_package doesn't have a proc pointer and it's not
108ff4eeac9Schristos 		 * exactly trivial to add one since the credentials are
10946141a31Sthorpej 		 * changing. XXX Linux uses curlwp's credentials.
110f474dcebSad 		 * Why can't we use them too? XXXad we do, what's different?
11154724278Smanu 		 */
11254724278Smanu 		a->a_type = LINUX_AT_EGID;
113f474dcebSad 		a->a_v = kauth_cred_getegid(l->l_cred);
11454724278Smanu 		a++;
11554724278Smanu 
11654724278Smanu 		a->a_type = LINUX_AT_GID;
117f474dcebSad 		a->a_v = kauth_cred_getgid(l->l_cred);
11854724278Smanu 		a++;
11954724278Smanu 
12054724278Smanu 		a->a_type = LINUX_AT_EUID;
121f474dcebSad 		a->a_v = kauth_cred_geteuid(l->l_cred);
12254724278Smanu 		a++;
12354724278Smanu 
12454724278Smanu 		a->a_type = LINUX_AT_UID;
125f474dcebSad 		a->a_v = kauth_cred_getuid(l->l_cred);
12654724278Smanu 		a++;
12754724278Smanu #endif
12854724278Smanu 
12954724278Smanu 		a->a_type = AT_ENTRY;
13054724278Smanu 		a->a_v = ap->arg_entry;
13154724278Smanu 		a++;
13254724278Smanu 
13354724278Smanu 		a->a_type = AT_FLAGS;
13454724278Smanu 		a->a_v = 0;
13554724278Smanu 		a++;
13654724278Smanu 
13754724278Smanu 		a->a_type = AT_BASE;
13854724278Smanu 		a->a_v = ap->arg_interp;
13954724278Smanu 		a++;
14054724278Smanu 
14154724278Smanu 		a->a_type = AT_PHNUM;
14254724278Smanu 		a->a_v = ap->arg_phnum;
14354724278Smanu 		a++;
14454724278Smanu 
14554724278Smanu 		a->a_type = AT_PHENT;
14654724278Smanu 		a->a_v = ap->arg_phentsize;
14754724278Smanu 		a++;
14854724278Smanu 
14954724278Smanu 		a->a_type = AT_PHDR;
15054724278Smanu 		a->a_v = ap->arg_phaddr;
15154724278Smanu 		a++;
15254724278Smanu 
15354724278Smanu 		a->a_type = LINUX_AT_CLKTCK;
15454724278Smanu 		a->a_v = LINUX_CLOCKS_PER_SEC;
15554724278Smanu 		a++;
15654724278Smanu 
15754724278Smanu 		a->a_type = AT_PAGESZ;
158d46b766dSthorpej 		a->a_v = PAGE_SIZE;
15954724278Smanu 		a++;
16054724278Smanu 
16154724278Smanu 		a->a_type = LINUX_AT_HWCAP;
16254724278Smanu 		a->a_v = LINUX_ELF_HWCAP;
16354724278Smanu 		a++;
16454724278Smanu 
1652210079eSmatt 		exec_free_emul_arg(pack);
16654724278Smanu 	}
16754724278Smanu 
16854724278Smanu 	a->a_type = AT_NULL;
16954724278Smanu 	a->a_v = 0;
17054724278Smanu 	a++;
17154724278Smanu 
1723e8efcddSjdolecek 	len = (a - ai) * sizeof(AuxInfo);
17354724278Smanu 
174934898bcSchristos 	if ((error = copyout(ai, *stackp, len)) != 0)
175934898bcSchristos 		return error;
176934898bcSchristos 	*stackp += len;
1776b1a1526Smanu 	return 0;
1786b1a1526Smanu }
179