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--