Module Name:    src
Committed By:   joerg
Date:           Fri Aug 20 14:59:53 UTC 2010

Modified Files:
        src/sys/kern: exec_elf.c

Log Message:
Allow ELF objects with more than two PT_LOAD sections. Go creates such
binaries by default with separate sections for executable, writeable
data and constants. Use the same heuristic as FreeBSD to match up the
text and data segment assumptions.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 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.23 src/sys/kern/exec_elf.c:1.24
--- src/sys/kern/exec_elf.c:1.23	Thu Jun 24 13:03:11 2010
+++ src/sys/kern/exec_elf.c	Fri Aug 20 14:59:53 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec_elf.c,v 1.23 2010/06/24 13:03:11 hannken Exp $	*/
+/*	$NetBSD: exec_elf.c,v 1.24 2010/08/20 14:59:53 joerg 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.23 2010/06/24 13:03:11 hannken Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.24 2010/08/20 14:59:53 joerg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pax.h"
@@ -730,28 +730,22 @@
 
 		switch (ph[i].p_type) {
 		case PT_LOAD:
-			/*
-			 * XXX
-			 * Can handle only 2 sections: text and data
-			 */
-			if (nload++ == 2) {
-				error = ENOEXEC;
-				goto bad;
-			}
 			elf_load_psection(&epp->ep_vmcmds, epp->ep_vp,
 			    &ph[i], &addr, &size, &prot, VMCMD_FIXED);
 
 			/*
-			 * Decide whether it's text or data by looking
-			 * at the entry point.
+			 * Consider this as text segment, if it is executable.
+			 * If there is more than one text segment, pick the
+			 * largest.
+			 *
+			 * If it is not executable, use the last section
+			 * as data segment to make break() happy.
 			 */
-			if (eh->e_entry >= addr &&
-			    eh->e_entry < (addr + size)) {
-				epp->ep_taddr = addr;
-				epp->ep_tsize = size;
-				if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) {
-					epp->ep_daddr = addr;
-					epp->ep_dsize = size;
+			if (ph[i].p_flags & PF_X) {
+				if (epp->ep_taddr == ELFDEFNNAME(NO_ADDR) ||
+				    size > epp->ep_tsize) {
+					epp->ep_taddr = addr;
+					epp->ep_tsize = size;
 				}
 			} else {
 				epp->ep_daddr = addr;
@@ -780,6 +774,11 @@
 		}
 	}
 
+	if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) {
+		epp->ep_daddr = epp->ep_taddr;
+		epp->ep_dsize = epp->ep_tsize;
+	}
+
 	/*
 	 * Check if we found a dynamically linked binary and arrange to load
 	 * its interpreter

Reply via email to