xref: /netbsd-src/sys/compat/linux/arch/i386/linux_exec_machdep.c (revision 23c8222edbfb0f0932d88a8351d3a0cf817dfb9e)
1 /*	$NetBSD: linux_exec_machdep.c,v 1.1 2004/11/13 06:01:34 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2004 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: linux_exec_machdep.c,v 1.1 2004/11/13 06:01:34 christos Exp $");
41 
42 #if defined(_KERNEL_OPT)
43 #include "opt_vm86.h"
44 #include "opt_user_ldt.h"
45 #endif
46 
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/resource.h>
50 #include <sys/proc.h>
51 #include <sys/conf.h>
52 #include <sys/exec.h>
53 #include <sys/exec_elf.h>
54 #include <sys/vnode.h>
55 #include <sys/lwp.h>
56 
57 #include <machine/cpu.h>
58 #include <machine/vmparam.h>
59 
60 #include <uvm/uvm.h>
61 
62 #include <compat/linux/common/linux_types.h>
63 #include <compat/linux/common/linux_signal.h>
64 #include <compat/linux/common/linux_util.h>
65 #include <compat/linux/common/linux_ioctl.h>
66 #include <compat/linux/common/linux_hdio.h>
67 #include <compat/linux/common/linux_exec.h>
68 #include <compat/linux/common/linux_machdep.h>
69 #include <compat/linux/common/linux_errno.h>
70 
71 int
72 linux_exec_setup_stack(struct proc *p, struct exec_package *epp)
73 {
74 	u_long max_stack_size;
75 	u_long access_linear_min, access_size;
76 	u_long noaccess_linear_min, noaccess_size;
77 
78 #ifndef	USRSTACK32
79 #define USRSTACK32	(0x00000000ffffffffL&~PGOFSET)
80 #endif
81 
82 	if (epp->ep_flags & EXEC_32) {
83 		epp->ep_minsaddr = USRSTACK32;
84 		max_stack_size = MAXSSIZ;
85 	} else {
86 		epp->ep_minsaddr = USRSTACK;
87 		max_stack_size = MAXSSIZ;
88 	}
89 
90 	if (epp->ep_minsaddr > LINUX_USRSTACK)
91 		epp->ep_minsaddr = LINUX_USRSTACK;
92 #ifdef DEBUG_LINUX
93 	else {
94 		/*
95 		 * Someone needs to make KERNBASE and TEXTADDR
96 		 * java versions < 1.4.2 need the stack to be
97 		 * at 0xC0000000
98 		 */
99 		uprintf("Cannot setup stack to 0xC0000000, "
100 		    "java will not work properly\n");
101 	}
102 #endif
103 	epp->ep_maxsaddr = (u_long)STACK_GROW(epp->ep_minsaddr,
104 		max_stack_size);
105 	epp->ep_ssize = p->p_rlimit[RLIMIT_STACK].rlim_cur;
106 
107 	/*
108 	 * set up commands for stack.  note that this takes *two*, one to
109 	 * map the part of the stack which we can access, and one to map
110 	 * the part which we can't.
111 	 *
112 	 * arguably, it could be made into one, but that would require the
113 	 * addition of another mapping proc, which is unnecessary
114 	 */
115 	access_size = epp->ep_ssize;
116 	access_linear_min = (u_long)STACK_ALLOC(epp->ep_minsaddr, access_size);
117 	noaccess_size = max_stack_size - access_size;
118 	noaccess_linear_min = (u_long)STACK_ALLOC(STACK_GROW(epp->ep_minsaddr,
119 	    access_size), noaccess_size);
120 	if (noaccess_size > 0) {
121 		NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, noaccess_size,
122 		    noaccess_linear_min, NULLVP, 0, VM_PROT_NONE);
123 	}
124 	KASSERT(access_size > 0);
125 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, access_size,
126 	    access_linear_min, NULLVP, 0, VM_PROT_READ | VM_PROT_WRITE);
127 
128 	return 0;
129 }
130