Source-Changes-HG archive

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

[src/trunk]: src/sys always supply an auxiliary vector for linux ELF processes.



details:   https://anonhg.NetBSD.org/src/rev/af96255ac34b
branches:  trunk
changeset: 757676:af96255ac34b
user:      chs <chs%NetBSD.org@localhost>
date:      Sat Sep 11 20:49:28 2010 +0000

description:
always supply an auxiliary vector for linux ELF processes.
static executables (such as newer versions of /sbin/ldconfig)
require this to work properly.  since static executables
also don't have a PT_PHDR entry, use the same heuristic as
linux does to provide a value for AT_PHDR in this case.

diffstat:

 sys/compat/linux/common/linux_exec_elf32.c     |   5 ++-
 sys/compat/linux32/common/linux32_exec_elf32.c |   7 ++---
 sys/kern/exec_elf.c                            |  32 +++++++++++++++----------
 sys/sys/exec.h                                 |   3 +-
 4 files changed, 27 insertions(+), 20 deletions(-)

diffs (174 lines):

diff -r d65d7216e143 -r af96255ac34b sys/compat/linux/common/linux_exec_elf32.c
--- a/sys/compat/linux/common/linux_exec_elf32.c        Sat Sep 11 16:03:41 2010 +0000
+++ b/sys/compat/linux/common/linux_exec_elf32.c        Sat Sep 11 20:49:28 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_exec_elf32.c,v 1.83 2009/03/15 15:55:51 cegger Exp $     */
+/*     $NetBSD: linux_exec_elf32.c,v 1.84 2010/09/11 20:49:28 chs Exp $        */
 
 /*-
  * Copyright (c) 1995, 1998, 2000, 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.83 2009/03/15 15:55:51 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.84 2010/09/11 20:49:28 chs Exp $");
 
 #ifndef ELFSIZE
 /* XXX should die */
@@ -383,6 +383,7 @@
                if ((error = emul_find_interp(l, epp, itp)))
                        return (error);
        }
+       epp->ep_flags |= EXEC_FORCEAUX;
        DPRINTF(("linux_probe: returning 0\n"));
        return 0;
 }
diff -r d65d7216e143 -r af96255ac34b sys/compat/linux32/common/linux32_exec_elf32.c
--- a/sys/compat/linux32/common/linux32_exec_elf32.c    Sat Sep 11 16:03:41 2010 +0000
+++ b/sys/compat/linux32/common/linux32_exec_elf32.c    Sat Sep 11 20:49:28 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux32_exec_elf32.c,v 1.11 2010/07/07 01:30:35 chs Exp $ */
+/*     $NetBSD: linux32_exec_elf32.c,v 1.12 2010/09/11 20:49:28 chs Exp $ */
 
 /*-                     
  * Copyright (c) 1995, 1998, 2000, 2001,2006 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.11 2010/07/07 01:30:35 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.12 2010/09/11 20:49:28 chs Exp $");
 
 #define        ELFSIZE         32
 
@@ -92,7 +92,7 @@
        DPRINTF(("linux32_probe: returning 0\n"));
 #endif
 
-       epp->ep_flags |= EXEC_32;
+       epp->ep_flags |= EXEC_32 | EXEC_FORCEAUX;
        epp->ep_vm_minaddr = VM_MIN_ADDRESS;
        epp->ep_vm_maxaddr = USRSTACK32;
 
@@ -231,4 +231,3 @@
 
        return 0;
 }
-
diff -r d65d7216e143 -r af96255ac34b sys/kern/exec_elf.c
--- a/sys/kern/exec_elf.c       Sat Sep 11 16:03:41 2010 +0000
+++ b/sys/kern/exec_elf.c       Sat Sep 11 20:49:28 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec_elf.c,v 1.25 2010/09/07 21:32:03 joerg Exp $      */
+/*     $NetBSD: exec_elf.c,v 1.26 2010/09/11 20:49:28 chs 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.25 2010/09/07 21:32:03 joerg Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.26 2010/09/11 20:49:28 chs Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pax.h"
@@ -636,11 +636,12 @@
 {
        Elf_Ehdr *eh = epp->ep_hdr;
        Elf_Phdr *ph, *pp;
-       Elf_Addr phdr = 0, pos = 0, end_text = 0;
+       Elf_Addr phdr = 0, computed_phdr = 0, pos = 0, end_text = 0;
        int error, i, nload;
        char *interp = NULL;
        u_long phsize;
        struct proc *p;
+       struct elf_args *ap = NULL;
        bool is_dyn;
 
        if (epp->ep_hdrvalid < sizeof(Elf_Ehdr))
@@ -749,6 +750,9 @@
                                epp->ep_daddr = addr;
                                epp->ep_dsize = size;
                        }
+                       if (ph[i].p_offset == 0) {
+                               computed_phdr = ph[i].p_vaddr + eh->e_phoff;
+                       }
                        break;
 
                case PT_SHLIB:
@@ -771,6 +775,10 @@
                        break;
                }
        }
+       if (interp || (epp->ep_flags & EXEC_FORCEAUX) != 0) {
+               ap = malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK);
+               ap->arg_interp = (vaddr_t)NULL;
+       }
 
        if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) {
                epp->ep_daddr = end_text;
@@ -782,30 +790,26 @@
         * its interpreter
         */
        if (interp) {
-               struct elf_args *ap;
                int j = epp->ep_vmcmds.evs_used;
                u_long interp_offset;
 
-               ap = (struct elf_args *)malloc(sizeof(struct elf_args),
-                   M_TEMP, M_WAITOK);
                if ((error = elf_load_file(l, epp, interp,
                    &epp->ep_vmcmds, &interp_offset, ap, &pos)) != 0) {
-                       free(ap, M_TEMP);
                        goto bad;
                }
                ap->arg_interp = epp->ep_vmcmds.evs_cmds[j].ev_addr;
                epp->ep_entry = ap->arg_interp + interp_offset;
-               ap->arg_phaddr = phdr;
+               PNBUF_PUT(interp);
+       } else
+               epp->ep_entry = eh->e_entry;
 
+       if (ap) {
+               ap->arg_phaddr = phdr ? phdr : computed_phdr;
                ap->arg_phentsize = eh->e_phentsize;
                ap->arg_phnum = eh->e_phnum;
                ap->arg_entry = eh->e_entry;
-
                epp->ep_emul_arg = ap;
-
-               PNBUF_PUT(interp);
-       } else
-               epp->ep_entry = eh->e_entry;
+       }
 
 #ifdef ELF_MAP_PAGE_ZERO
        /* Dell SVR4 maps page zero, yeuch! */
@@ -818,6 +822,8 @@
 bad:
        if (interp)
                PNBUF_PUT(interp);
+       if (ap)
+               free(ap, M_TEMP);
        kmem_free(ph, phsize);
        kill_vmcmds(&epp->ep_vmcmds);
        return error;
diff -r d65d7216e143 -r af96255ac34b sys/sys/exec.h
--- a/sys/sys/exec.h    Sat Sep 11 16:03:41 2010 +0000
+++ b/sys/sys/exec.h    Sat Sep 11 20:49:28 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec.h,v 1.130 2010/05/02 05:30:20 dholland Exp $      */
+/*     $NetBSD: exec.h,v 1.131 2010/09/11 20:49:28 chs Exp $   */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -209,6 +209,7 @@
 #define        EXEC_SKIPARG    0x0008          /* don't copy user-supplied argv[0] */
 #define        EXEC_DESTR      0x0010          /* destructive ops performed */
 #define        EXEC_32         0x0020          /* 32-bit binary emulation */
+#define        EXEC_FORCEAUX   0x0040          /* always use ELF AUX vector */
 
 struct exec_vmcmd {
        int     (*ev_proc)(struct lwp *, struct exec_vmcmd *);



Home | Main Index | Thread Index | Old Index