Subject: Flexible process address space limits
To: None <tech-kern@netbsd.org>
From: None <eeh@netbsd.org>
List: tech-kern
Date: 02/12/2001 18:38:09
In order to solve the issues with executing 32-bit binaries on   
64-bit machines, I'm planning to make the following changes:     

1) Add fields to the exec_package structure to specify the       
process' address space limits.  These are set by the selected    
emulation.       

2) Pass these limits to uvmspace_exec() to limit the vm_map      
size.    

3) Use current limits rather than maximum values when laying     
out address space sections during exec.  This mainly affects
the stack segment.       

4) Handle resizing process segments inside dosetrlimit().        

The following patch solves the first two issues: 

Index: sys/param.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/param.h,v
retrieving revision 1.121
diff -u -r1.121 param.h
--- sys/param.h	2001/02/05 10:42:46	1.121
+++ sys/param.h	2001/02/12 18:29:18
@@ -63,9 +63,11 @@
  *	And:
  *	     NetBSD-1.2.1 = 102000100
  *
+ *
+ * Don't forget to change conf/osrelease.sh too.
  */
 
-#define __NetBSD_Version__  105180000	/* NetBSD 1.5R */
+#define __NetBSD_Version__  105190000	/* NetBSD 1.5S */
 
 /*
  * Historical NetBSD #define
Index: sys/exec.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/exec.h,v
retrieving revision 1.77
diff -u -r1.77 exec.h
--- sys/exec.h	2001/01/22 06:42:31	1.77
+++ sys/exec.h	2001/02/12 18:29:18
@@ -154,6 +154,8 @@
 	u_long	ep_minsaddr;		/* proc's min stack addr ("bottom") */
 	u_long	ep_ssize;		/* size of process's stack */
 	u_long	ep_entry;		/* process's entry point */
+	vaddr_t	ep_vm_minaddr;		/* bottom of process address space */
+	vaddr_t	ep_vm_maxaddr;		/* top of process address space */
 	u_int	ep_flags;		/* flags; see below. */
 	char	**ep_fa;		/* a fake args vector for scripts */
 	int	ep_fd;			/* a file descriptor we're holding */
Index: conf/osrelease.sh
===================================================================
RCS file: /cvsroot/syssrc/sys/conf/osrelease.sh,v
retrieving revision 1.64
diff -u -r1.64 osrelease.sh
--- conf/osrelease.sh	2001/01/27 07:35:24	1.64
+++ conf/osrelease.sh	2001/02/12 18:29:18
@@ -39,7 +39,7 @@
 
 # Release number to use
 # Also check __NetBSD_Version__ in sys/sys/param.h if you change this!
-release=1.5R
+release=1.5S
 
 case $1 in
 -s)
Index: kern/kern_exec.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_exec.c,v
retrieving revision 1.135
diff -u -r1.135 kern_exec.c
--- kern/kern_exec.c	2001/02/06 17:01:53	1.135
+++ kern/kern_exec.c	2001/02/12 18:29:19
@@ -230,6 +230,14 @@
 	epp->ep_hdrvalid = epp->ep_hdrlen - resid;
 
 	/*
+	 * Set up default address space limits.  Can be overridden
+	 * by individual exec packages.
+	 * 
+	 * XXX probably shoul be all done in the exec pakages.
+	 */
+	epp->ep_vm_minaddr = VM_MIN_ADDRESS;
+	epp->ep_vm_maxaddr = VM_MAXUSER_ADDRESS;
+	/*
 	 * set up the vmcmds for creation of the process
 	 * address space
 	 */
@@ -453,7 +461,7 @@
 	 * for remapping.  Note that this might replace the current
 	 * vmspace with another!
 	 */
-	uvmspace_exec(p, VM_MIN_ADDRESS, (vaddr_t)pack.ep_minsaddr);
+	uvmspace_exec(p, pack.ep_vm_minaddr, pack.ep_vm_maxaddr);
 
 	/* Now map address space */
 	vm = p->p_vmspace;
@@ -533,7 +541,8 @@
 	/* copy out the process's ps_strings structure */
 	if (copyout(&arginfo, (char *)p->p_psstr, sizeof(arginfo))) {
 #ifdef DEBUG
-		printf("execve: ps_strings copyout failed\n");
+		printf("execve: ps_strings copyout %p->%p size %ld failed\n",
+		       &arginfo, (char *)p->p_psstr, (long)sizeof(arginfo));
 #endif
 		goto exec_abort;
 	}
Index: compat/netbsd32/netbsd32_exec_aout.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/netbsd32/netbsd32_exec_aout.c,v
retrieving revision 1.4
diff -u -r1.4 netbsd32_exec_aout.c
--- compat/netbsd32/netbsd32_exec_aout.c	2001/02/03 12:45:44	1.4
+++ compat/netbsd32/netbsd32_exec_aout.c	2001/02/12 18:29:19
@@ -137,6 +137,8 @@
 	epp->ep_daddr = epp->ep_taddr + execp->a_text;
 	epp->ep_dsize = execp->a_data + execp->a_bss;
 	epp->ep_entry = execp->a_entry;
+	epp->ep_vm_minaddr = VM_MIN_ADDRESS;
+	epp->ep_vm_maxaddr = VM_MAXUSER_ADDRESS32;
 
 	/*
 	 * check if vnode is in open for writing, because we want to
@@ -188,6 +190,8 @@
 	epp->ep_daddr = roundup(epp->ep_taddr + execp->a_text, __LDPGSZ);
 	epp->ep_dsize = execp->a_data + execp->a_bss;
 	epp->ep_entry = execp->a_entry;
+	epp->ep_vm_minaddr = VM_MIN_ADDRESS;
+	epp->ep_vm_maxaddr = VM_MAXUSER_ADDRESS32;
 
 	/* set up command for text segment */
 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->a_text,
@@ -227,6 +231,8 @@
 	epp->ep_daddr = epp->ep_taddr + execp->a_text;
 	epp->ep_dsize = execp->a_data + execp->a_bss;
 	epp->ep_entry = execp->a_entry;
+	epp->ep_vm_minaddr = VM_MIN_ADDRESS;
+	epp->ep_vm_maxaddr = VM_MAXUSER_ADDRESS32;
 
 	/* set up command for text and data segments */
 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
Index: compat/netbsd32/netbsd32_exec_elf32.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/netbsd32/netbsd32_exec_elf32.c,v
retrieving revision 1.3
diff -u -r1.3 netbsd32_exec_elf32.c
--- compat/netbsd32/netbsd32_exec_elf32.c	2001/02/11 00:00:29	1.3
+++ compat/netbsd32/netbsd32_exec_elf32.c	2001/02/12 18:29:19
@@ -82,6 +82,8 @@
 		free((void *)bp, M_TEMP);
 	}
 	epp->ep_flags |= EXEC_32;
+	epp->ep_vm_minaddr = VM_MIN_ADDRESS;
+	epp->ep_vm_maxaddr = USRSTACK32;
 	*pos = ELFDEFNNAME(NO_ADDR);
 	return 0;
 }

Eduardo