summaryrefslogtreecommitdiffstats
path: root/sys/kern/exec_elf.c
diff options
context:
space:
mode:
authordrahn <drahn@openbsd.org>2002-11-22 22:10:21 +0000
committerdrahn <drahn@openbsd.org>2002-11-22 22:10:21 +0000
commit4b46e292ce90fdf5f64b4b33ebc7e27d42913eb1 (patch)
treec298acfe7fa32d18967450f71ed0992846b655c9 /sys/kern/exec_elf.c
parentadd /usr/share/pf (diff)
downloadwireguard-openbsd-4b46e292ce90fdf5f64b4b33ebc7e27d42913eb1.tar.xz
wireguard-openbsd-4b46e292ce90fdf5f64b4b33ebc7e27d42913eb1.zip
Allow more than two load sections on ELF executables, this limit
should not be required, and may be violated soon. With two fixes art pointed out. ok art@
Diffstat (limited to 'sys/kern/exec_elf.c')
-rw-r--r--sys/kern/exec_elf.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c
index d86ef335654..ae570d00a62 100644
--- a/sys/kern/exec_elf.c
+++ b/sys/kern/exec_elf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec_elf.c,v 1.42 2002/10/06 22:39:25 art Exp $ */
+/* $OpenBSD: exec_elf.c,v 1.43 2002/11/22 22:10:21 drahn Exp $ */
/*
* Copyright (c) 1996 Per Fogelstrom
@@ -444,7 +444,7 @@ ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp)
Elf_Ehdr *eh = epp->ep_hdr;
Elf_Phdr *ph, *pp;
Elf_Addr phdr = 0;
- int error, i, nload;
+ int error, i;
char interp[MAXPATHLEN];
u_long pos = 0, phsize;
u_int8_t os = OOS_NULL;
@@ -537,7 +537,7 @@ native:
/*
* 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), size = 0;
int prot = 0;
@@ -546,28 +546,50 @@ native:
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, 0);
/*
* 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;