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: