Module Name:    src
Committed By:   riz
Date:           Tue Jan 26 01:18:37 UTC 2016

Modified Files:
        src/sys/kern [netbsd-7]: exec_elf.c

Log Message:
Apply patch (requested by martin in ticket #1062):

sys/kern/exec_elf.c                     patch

        Restore binary compatibility on sparc64 for old binaries.
        [martin, ticket #1062]


To generate a diff of this commit:
cvs rdiff -u -r1.69.2.3 -r1.69.2.4 src/sys/kern/exec_elf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/exec_elf.c
diff -u src/sys/kern/exec_elf.c:1.69.2.3 src/sys/kern/exec_elf.c:1.69.2.4
--- src/sys/kern/exec_elf.c:1.69.2.3	Sun Nov  8 00:57:09 2015
+++ src/sys/kern/exec_elf.c	Tue Jan 26 01:18:37 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec_elf.c,v 1.69.2.3 2015/11/08 00:57:09 riz Exp $	*/
+/*	$NetBSD: exec_elf.c,v 1.69.2.4 2016/01/26 01:18:37 riz Exp $	*/
 
 /*-
  * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.69.2.3 2015/11/08 00:57:09 riz Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.69.2.4 2016/01/26 01:18:37 riz Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pax.h"
@@ -77,6 +77,7 @@ __KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v
 #include <sys/kauth.h>
 #include <sys/bitops.h>
 #include <sys/cprng.h>
+#include <sys/atomic.h>
 
 #include <sys/cpu.h>
 #include <machine/reg.h>
@@ -409,20 +410,18 @@ elf_load_interp(struct lwp *l, struct ex
 	u_long phsize;
 	Elf_Addr addr = *last;
 	struct proc *p;
-	bool use_topdown;
+	bool use_topdown, restore_topdown;
 
 	p = l->l_proc;
 
 	KASSERT(p->p_vmspace);
-	if (__predict_true(p->p_vmspace != proc0.p_vmspace)) {
-		use_topdown = p->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN;
-	} else {
+	KASSERT(p->p_vmspace != proc0.p_vmspace);
+	restore_topdown = false;
 #ifdef __USE_TOPDOWN_VM
-		use_topdown = epp->ep_flags & EXEC_TOPDOWN_VM;
+	use_topdown = epp->ep_flags & EXEC_TOPDOWN_VM;
 #else
-		use_topdown = false;
+	use_topdown = false;
 #endif
-	}
 
 	/*
 	 * 1. open file
@@ -537,9 +536,36 @@ elf_load_interp(struct lwp *l, struct ex
 		/*
 		 * Now compute the size and load address.
 		 */
+		if (__predict_false(
+		    /* vmspace is marked as topdown */
+		    (((p->p_vmspace->vm_map.flags & VM_MAP_TOPDOWN) != 0)
+			!=
+		     /* but this differs from the topdown usage we need */
+		     use_topdown))) {
+			/*
+			 * The vmmap might be shared, but this flag is
+			 * considered r/o and we will restore it immediately
+			 * after calculating the load address.
+			 */
+			int flags = p->p_vmspace->vm_map.flags;
+			int n = use_topdown
+				    ? (flags | VM_MAP_TOPDOWN)
+				    : (flags & ~VM_MAP_TOPDOWN);
+
+			restore_topdown = true;
+			atomic_swap_32(&p->p_vmspace->vm_map.flags, n);
+		}
 		addr = (*epp->ep_esch->es_emul->e_vm_default_addr)(p,
 		    epp->ep_daddr,
 		    round_page(limit) - trunc_page(base_ph->p_vaddr));
+		if (__predict_false(restore_topdown)) {
+			int flags = p->p_vmspace->vm_map.flags;
+			int n = !use_topdown
+				    ? (flags | VM_MAP_TOPDOWN)
+				    : (flags & ~VM_MAP_TOPDOWN);
+
+			atomic_swap_32(&p->p_vmspace->vm_map.flags, n);
+		}
 	} else
 		addr = *last; /* may be ELF_LINK_ADDR */
 

Reply via email to