Module Name:    src
Committed By:   chs
Date:           Sat Sep 11 20:49:28 UTC 2010

Modified Files:
        src/sys/compat/linux/common: linux_exec_elf32.c
        src/sys/compat/linux32/common: linux32_exec_elf32.c
        src/sys/kern: exec_elf.c
        src/sys/sys: exec.h

Log Message:
always supply an auxiliary vector for linux ELF processes.
static executables (such as newer versions of /sbin/ldconfig)
require this to work properly.  since static executables
also don't have a PT_PHDR entry, use the same heuristic as
linux does to provide a value for AT_PHDR in this case.


To generate a diff of this commit:
cvs rdiff -u -r1.83 -r1.84 src/sys/compat/linux/common/linux_exec_elf32.c
cvs rdiff -u -r1.11 -r1.12 src/sys/compat/linux32/common/linux32_exec_elf32.c
cvs rdiff -u -r1.25 -r1.26 src/sys/kern/exec_elf.c
cvs rdiff -u -r1.130 -r1.131 src/sys/sys/exec.h

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

Modified files:

Index: src/sys/compat/linux/common/linux_exec_elf32.c
diff -u src/sys/compat/linux/common/linux_exec_elf32.c:1.83 src/sys/compat/linux/common/linux_exec_elf32.c:1.84
--- src/sys/compat/linux/common/linux_exec_elf32.c:1.83	Sun Mar 15 15:55:51 2009
+++ src/sys/compat/linux/common/linux_exec_elf32.c	Sat Sep 11 20:49:28 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_exec_elf32.c,v 1.83 2009/03/15 15:55:51 cegger Exp $	*/
+/*	$NetBSD: linux_exec_elf32.c,v 1.84 2010/09/11 20:49:28 chs Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998, 2000, 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.83 2009/03/15 15:55:51 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.84 2010/09/11 20:49:28 chs Exp $");
 
 #ifndef ELFSIZE
 /* XXX should die */
@@ -383,6 +383,7 @@
 		if ((error = emul_find_interp(l, epp, itp)))
 			return (error);
 	}
+	epp->ep_flags |= EXEC_FORCEAUX;
 	DPRINTF(("linux_probe: returning 0\n"));
 	return 0;
 }

Index: src/sys/compat/linux32/common/linux32_exec_elf32.c
diff -u src/sys/compat/linux32/common/linux32_exec_elf32.c:1.11 src/sys/compat/linux32/common/linux32_exec_elf32.c:1.12
--- src/sys/compat/linux32/common/linux32_exec_elf32.c:1.11	Wed Jul  7 01:30:35 2010
+++ src/sys/compat/linux32/common/linux32_exec_elf32.c	Sat Sep 11 20:49:28 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_exec_elf32.c,v 1.11 2010/07/07 01:30:35 chs Exp $ */
+/*	$NetBSD: linux32_exec_elf32.c,v 1.12 2010/09/11 20:49:28 chs Exp $ */
 
 /*-                     
  * Copyright (c) 1995, 1998, 2000, 2001,2006 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.11 2010/07/07 01:30:35 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.12 2010/09/11 20:49:28 chs Exp $");
 
 #define	ELFSIZE		32
 
@@ -92,7 +92,7 @@
 	DPRINTF(("linux32_probe: returning 0\n"));
 #endif
 
-	epp->ep_flags |= EXEC_32;
+	epp->ep_flags |= EXEC_32 | EXEC_FORCEAUX;
 	epp->ep_vm_minaddr = VM_MIN_ADDRESS;
 	epp->ep_vm_maxaddr = USRSTACK32;
 
@@ -231,4 +231,3 @@
 
 	return 0;
 }
-

Index: src/sys/kern/exec_elf.c
diff -u src/sys/kern/exec_elf.c:1.25 src/sys/kern/exec_elf.c:1.26
--- src/sys/kern/exec_elf.c:1.25	Tue Sep  7 21:32:03 2010
+++ src/sys/kern/exec_elf.c	Sat Sep 11 20:49:28 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec_elf.c,v 1.25 2010/09/07 21:32:03 joerg Exp $	*/
+/*	$NetBSD: exec_elf.c,v 1.26 2010/09/11 20:49:28 chs 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.25 2010/09/07 21:32:03 joerg Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.26 2010/09/11 20:49:28 chs Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pax.h"
@@ -636,11 +636,12 @@
 {
 	Elf_Ehdr *eh = epp->ep_hdr;
 	Elf_Phdr *ph, *pp;
-	Elf_Addr phdr = 0, pos = 0, end_text = 0;
+	Elf_Addr phdr = 0, computed_phdr = 0, pos = 0, end_text = 0;
 	int error, i, nload;
 	char *interp = NULL;
 	u_long phsize;
 	struct proc *p;
+	struct elf_args *ap = NULL;
 	bool is_dyn;
 
 	if (epp->ep_hdrvalid < sizeof(Elf_Ehdr))
@@ -749,6 +750,9 @@
 				epp->ep_daddr = addr;
 				epp->ep_dsize = size;
 			}
+			if (ph[i].p_offset == 0) {
+				computed_phdr = ph[i].p_vaddr + eh->e_phoff;
+			}
 			break;
 
 		case PT_SHLIB:
@@ -771,6 +775,10 @@
 			break;
 		}
 	}
+	if (interp || (epp->ep_flags & EXEC_FORCEAUX) != 0) {
+		ap = malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK);
+		ap->arg_interp = (vaddr_t)NULL;
+	}
 
 	if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) {
 		epp->ep_daddr = end_text;
@@ -782,30 +790,26 @@
 	 * its interpreter
 	 */
 	if (interp) {
-		struct elf_args *ap;
 		int j = epp->ep_vmcmds.evs_used;
 		u_long interp_offset;
 
-		ap = (struct elf_args *)malloc(sizeof(struct elf_args),
-		    M_TEMP, M_WAITOK);
 		if ((error = elf_load_file(l, epp, interp,
 		    &epp->ep_vmcmds, &interp_offset, ap, &pos)) != 0) {
-			free(ap, M_TEMP);
 			goto bad;
 		}
 		ap->arg_interp = epp->ep_vmcmds.evs_cmds[j].ev_addr;
 		epp->ep_entry = ap->arg_interp + interp_offset;
-		ap->arg_phaddr = phdr;
+		PNBUF_PUT(interp);
+	} else
+		epp->ep_entry = eh->e_entry;
 
+	if (ap) {
+		ap->arg_phaddr = phdr ? phdr : computed_phdr;
 		ap->arg_phentsize = eh->e_phentsize;
 		ap->arg_phnum = eh->e_phnum;
 		ap->arg_entry = eh->e_entry;
-
 		epp->ep_emul_arg = ap;
-
-		PNBUF_PUT(interp);
-	} else
-		epp->ep_entry = eh->e_entry;
+	}
 
 #ifdef ELF_MAP_PAGE_ZERO
 	/* Dell SVR4 maps page zero, yeuch! */
@@ -818,6 +822,8 @@
 bad:
 	if (interp)
 		PNBUF_PUT(interp);
+	if (ap)
+		free(ap, M_TEMP);
 	kmem_free(ph, phsize);
 	kill_vmcmds(&epp->ep_vmcmds);
 	return error;

Index: src/sys/sys/exec.h
diff -u src/sys/sys/exec.h:1.130 src/sys/sys/exec.h:1.131
--- src/sys/sys/exec.h:1.130	Sun May  2 05:30:20 2010
+++ src/sys/sys/exec.h	Sat Sep 11 20:49:28 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec.h,v 1.130 2010/05/02 05:30:20 dholland Exp $	*/
+/*	$NetBSD: exec.h,v 1.131 2010/09/11 20:49:28 chs Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -209,6 +209,7 @@
 #define	EXEC_SKIPARG	0x0008		/* don't copy user-supplied argv[0] */
 #define	EXEC_DESTR	0x0010		/* destructive ops performed */
 #define	EXEC_32		0x0020		/* 32-bit binary emulation */
+#define	EXEC_FORCEAUX	0x0040		/* always use ELF AUX vector */
 
 struct exec_vmcmd {
 	int	(*ev_proc)(struct lwp *, struct exec_vmcmd *);

Reply via email to