Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/sys/kern Pullup 1.53 [matt]:



details:   https://anonhg.NetBSD.org/src/rev/72aec5b160f9
branches:  netbsd-1-5
changeset: 490123:72aec5b160f9
user:      tv <tv%NetBSD.org@localhost>
date:      Fri Nov 03 20:00:38 2000 +0000

description:
Pullup 1.53 [matt]:
modify load_file to load at relative vma's as specified in the phdr's.

diffstat:

 sys/kern/exec_elf32.c |  48 +++++++++++++++++++++++++++++++-----------------
 1 files changed, 31 insertions(+), 17 deletions(-)

diffs (127 lines):

diff -r cb02deec93ec -r 72aec5b160f9 sys/kern/exec_elf32.c
--- a/sys/kern/exec_elf32.c     Fri Nov 03 19:59:41 2000 +0000
+++ b/sys/kern/exec_elf32.c     Fri Nov 03 20:00:38 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec_elf32.c,v 1.49.2.1 2000/07/13 01:09:23 thorpej Exp $      */
+/*     $NetBSD: exec_elf32.c,v 1.49.2.2 2000/11/03 20:00:38 tv Exp $   */
 
 /*-
  * Copyright (c) 1994 The NetBSD Foundation, Inc.
@@ -122,7 +122,7 @@
 int    ELFNAME(load_file) __P((struct proc *, struct exec_package *, char *,
            struct exec_vmcmd_set *, u_long *, struct elf_args *, Elf_Addr *));
 void   ELFNAME(load_psection) __P((struct exec_vmcmd_set *, struct vnode *,
-           Elf_Phdr *, Elf_Addr *, u_long *, int *));
+           const Elf_Phdr *, Elf_Addr *, u_long *, int *, int));
 
 int ELFNAME2(netbsd,signature) __P((struct proc *, struct exec_package *,
     Elf_Ehdr *));
@@ -284,13 +284,14 @@
  * Load a psection at the appropriate address
  */
 void
-ELFNAME(load_psection)(vcset, vp, ph, addr, size, prot)
+ELFNAME(load_psection)(vcset, vp, ph, addr, size, prot, flags)
        struct exec_vmcmd_set *vcset;
        struct vnode *vp;
-       Elf_Phdr *ph;
+       const Elf_Phdr *ph;
        Elf_Addr *addr;
        u_long *size;
        int *prot;
+       int flags;
 {
        u_long uaddr, msize, psize, rm, rf;
        long diff, offset;
@@ -300,7 +301,7 @@
         */
        if (*addr != ELFDEFNNAME(NO_ADDR)) {
                if (ph->p_align > 1) {
-                       *addr = ELF_ROUND(*addr, ph->p_align);
+                       *addr = ELF_TRUNC(*addr, ph->p_align);
                        uaddr = ELF_TRUNC(ph->p_vaddr, ph->p_align);
                } else
                        uaddr = ph->p_vaddr;
@@ -328,14 +329,16 @@
                 * readvn.
                 */
                psize = trunc_page(*size);
-               NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp,
-                   offset, *prot);
-               if(psize != *size)
-                       NEW_VMCMD(vcset, vmcmd_map_readvn, *size - psize,
-                           *addr + psize, vp, offset + psize, *prot);
-       } else
-               NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp,
-                   offset, *prot);
+       }
+       if (psize > 0) {
+               NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, *addr, vp,
+                   offset, *prot, flags);
+       }
+       if (psize < *size) {
+               NEW_VMCMD2(vcset, vmcmd_map_readvn, *size - psize,
+                   *addr + psize, vp, offset + psize, *prot, 
+                   psize > 0 ? flags & VMCMD_RELATIVE : flags);
+       }
 
        /*
         * Check if we need to extend the size of the segment
@@ -344,8 +347,8 @@
        rf = round_page(*addr + *size);
 
        if (rm != rf) {
-               NEW_VMCMD(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP,
-                   0, *prot);
+               NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP,
+                   0, *prot, flags & VMCMD_RELATIVE);
                *size = msize;
        }
 }
@@ -400,6 +403,7 @@
        struct vattr attr;
        Elf_Ehdr eh;
        Elf_Phdr *ph = NULL;
+       Elf_Phdr *base_ph = NULL;
        u_long phsize;
        char *bp = NULL;
        Elf_Addr addr = *last;
@@ -467,11 +471,19 @@
        for (i = 0; i < eh.e_phnum; i++) {
                u_long size = 0;
                int prot = 0;
+               int flags;
 
                switch (ph[i].p_type) {
                case PT_LOAD:
+                       if (base_ph == NULL) {
+                               addr = *last;
+                               flags = VMCMD_BASE;
+                       } else {
+                               addr = ph[i].p_vaddr - base_ph->p_vaddr;
+                               flags = VMCMD_RELATIVE;
+                       }
                        ELFNAME(load_psection)(vcset, vp, &ph[i], &addr,
-                           &size, &prot);
+                           &size, &prot, flags);
                        /* If entry is within this section it must be text */
                        if (eh.e_entry >= ph[i].p_vaddr &&
                            eh.e_entry < (ph[i].p_vaddr + size)) {
@@ -482,6 +494,8 @@
 #endif
                                ap->arg_interp = addr;
                        }
+                       if (base_ph == NULL)
+                               base_ph = &ph[i];
                        addr += size;
                        break;
 
@@ -640,7 +654,7 @@
                        if (nload++ == 2)
                                goto bad;
                        ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp,
-                           &ph[i], &addr, &size, &prot);
+                           &ph[i], &addr, &size, &prot, 0);
 
                        /*
                         * Decide whether it's text or data by looking



Home | Main Index | Thread Index | Old Index