Subject: Re: more on non-executable mappings
To: None <tech-kern@netbsd.org>
From: Chuck Silvers <chuq@chuq.com>
List: tech-kern
Date: 11/28/2003 12:03:20
--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

... and here's the patch that I forgot to attach.

-Chuck

--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="diff.elf"

Index: kern/exec_elf32.c
===================================================================
RCS file: /cvsroot/src/sys/kern/exec_elf32.c,v
retrieving revision 1.95
diff -u -p -r1.95 exec_elf32.c
--- kern/exec_elf32.c	31 Oct 2003 14:00:52 -0000	1.95
+++ kern/exec_elf32.c	28 Nov 2003 19:07:43 -0000
@@ -537,7 +537,7 @@ ELFNAME2(exec,makecmds)(struct proc *p, 
 	Elf_Ehdr *eh = epp->ep_hdr;
 	Elf_Phdr *ph, *pp;
 	Elf_Addr phdr = 0, pos = 0;
-	int error, i, nload;
+	int error, i;
 	char *interp = NULL;
 	u_long phsize;
 
@@ -611,7 +611,7 @@ ELFNAME2(exec,makecmds)(struct proc *p, 
 	/*
 	 * Load all the necessary sections
 	 */
-	for (i = nload = 0; i < eh->e_phnum; i++) {
+	for (i = 0; i < eh->e_phnum; i++) {
 		Elf_Addr  addr = ELFDEFNNAME(NO_ADDR);
 		u_long size = 0;
 		int prot = 0;
@@ -620,30 +620,51 @@ ELFNAME2(exec,makecmds)(struct proc *p, 
 
 		switch (ph[i].p_type) {
 		case PT_LOAD:
+
 			/*
-			 * XXX
-			 * Can handle only 2 sections: text and data
+			 * Calcuates size of text and data segments
+			 * by starting at first and going to end of last.
+			 * 'rwx' sections are treated as data.
+			 * This is correct for BSS_PLT, but may not be
+			 * for DATA_PLT, is fine for TEXT_PLT.
 			 */
-			if (nload++ == 2)
-				goto bad;
 			ELFNAME(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.
+			 * at the protection of the section.
 			 */
-			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)) {
+			if (prot & VM_PROT_WRITE) {
+				/* data section */
+				if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) {
 					epp->ep_daddr = addr;
 					epp->ep_dsize = size;
+				} else {
+					if (addr < epp->ep_daddr) {
+						epp->ep_dsize =
+						    epp->ep_dsize +
+						    epp->ep_daddr - addr;
+						epp->ep_daddr = addr;
+					} else
+						epp->ep_dsize = addr + size -
+						    epp->ep_daddr;
+				}
+			} else if (prot & VM_PROT_EXECUTE) {
+				/* text section */
+				if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR)) {
+					epp->ep_taddr = addr;
+					epp->ep_tsize = size;
+				} else {
+					if (addr < epp->ep_taddr) {
+						epp->ep_tsize =
+						    epp->ep_tsize +
+						    epp->ep_taddr - addr;
+						epp->ep_taddr = addr;
+					} else
+						epp->ep_tsize = addr + size -
+						    epp->ep_taddr;
 				}
-			} else {
-				epp->ep_daddr = addr;
-				epp->ep_dsize = size;
 			}
 			break;
 

--X1bOJ3K7DJ5YkBrT--