Subject: kern/25664: exec_sigcode_map() fails with OSF dynamically linked executables after uvm_map_findspace() changes
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mhitch@netbsd.org>
List: netbsd-bugs
Date: 05/21/2004 21:13:45
>Number:         25664
>Category:       kern
>Synopsis:       OSF dynamically linked executables no longer work
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat May 22 03:14:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Michael L. Hitch
>Release:        NetBSD 1.6ZC
>Organization:
	
>Environment:
	
	
System: NetBSD netbsd0 1.6ZC NetBSD 1.6ZC (GENERIC.MP) #23: Fri May 21 11:18:40 MDT 2004 mhitch@:/usr/staff/mhitch/200310030000/src/sys/arch/alpha/compile/GENERIC.MP alpha
Architecture: alpha
Machine: alpha
>Description:
	Since October 2003, OSF dynamically linked executables can no longer
	be run on alphas.  I ran into this several months ago, and after a brief
	look at the time, I couldn't determine what might be the problem.
	Since I needed to run a -current kernel to troubleshoot and fix another
	problem, I decided to take a look at this again.  The immediate symptom
	of the problem was a kernel panic from user-mode, which is documented
	in another PR, kern/25663.

	This PR is to document the problem that lead to the panics (fixing the
	panic to prevent users from crashing the system is separate from this
	problem, since the panics could potentially be caused by other problems)
	and provide a workaround fix.

	I tracked down the point in time when the OSF executables started failing
	to October 3, 2003 by changes in uvm_map_findspace().  I was able to
	to determine that uvm_map_findspace() had a bug prior to that time,
	and the fixing of that bug caused uvm_map() to fail in exec_sigcode_map().

	Previously, exec_sigcode_map() was added to support non-executable
	stacks by mapping the location for the trampoline separately outside
	the stack.  That mapping uses the data address of the program being
	started to locate where the trampoline code is mapped.  In the case
	of an OSF dynamically linked executable, that program is /bin/loader,
	the Tru64 equivalent of ld_elf.so.  Tru64 loads /bin/loader at the
	end of the user virtual memory space, so the hint of where to map
	the trampoline code ended up just after the last address of the
	user virtual memory.  Because of the bug in uvm_map_findspace(),
	it was mapping the trampoline code after the user VM and was able
	to function.  When uvm_map_findspace() was changed, that mapping
	was no longer valid, and exec_sigcode_map() would fail [which would
	cause a panic later because of another bug in sys_execve()].

>How-To-Repeat:
	Fix the problem documented in PR kern/25663 and attempt to run
	an OSF dynamically linked executable and watch it fail.

>Fix:
	I was able to get a workaround for this by checking of the
	hint VA was equal to the max_offset of the vm_map, and
	changing the hint VA to be prior to the text address of
	the program being started.  This totally ignores TOPDOWN, but
	does work on the alpha with the Tru64 /bin/loader.

Index: sys/kern/kern_exec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.185
diff -u -r1.185 kern_exec.c
--- sys/kern/kern_exec.c	26 Mar 2004 17:13:37 -0000	1.185
+++ sys/kern/kern_exec.c	22 May 2004 03:05:58 -0000
@@ -1324,6 +1326,9 @@
 
 	/* Just a hint to uvm_map where to put it. */
 	va = VM_DEFAULT_ADDRESS(p->p_vmspace->vm_daddr, round_page(sz));
+	if (va == (vaddr_t)p->p_vmspace->vm_map.max_offset) {
+		va = (vaddr_t)p->p_vmspace->vm_taddr - round_page(sz);
+	}
 	(*uobj->pgops->pgo_reference)(uobj);
 	error = uvm_map(&p->p_vmspace->vm_map, &va, round_page(sz),
 			uobj, 0, 0,
>Release-Note:
>Audit-Trail:
>Unformatted: