The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/linux32/common/linux32_exec_elf32.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: linux32_exec_elf32.c,v 1.8 2008/04/28 20:23:44 martin Exp $ */
    2 
    3 /*-                     
    4  * Copyright (c) 1995, 1998, 2000, 2001,2006 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *              
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and
    9  * Emmanuel Dreyfus.
   10  *      
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *      
   20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30  * POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: linux32_exec_elf32.c,v 1.8 2008/04/28 20:23:44 martin Exp $");
   35 
   36 #define ELFSIZE         32
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/proc.h>
   41 #include <sys/malloc.h>
   42 #include <sys/vnode.h>
   43 #include <sys/exec.h>
   44 #include <sys/exec_elf.h>
   45 #include <sys/kauth.h>
   46 #include <sys/kernel.h>
   47 #include <sys/resourcevar.h>
   48 #include <sys/signal.h>
   49 #include <sys/signalvar.h>
   50 
   51 #include <compat/linux/common/linux_exec.h>
   52 #include <compat/netbsd32/netbsd32.h>
   53 #include <compat/netbsd32/netbsd32_exec.h>
   54 #include <compat/linux32/common/linux32_exec.h>
   55 
   56 #include <machine/frame.h>
   57 
   58 #ifdef DEBUG_LINUX
   59 #define DPRINTF(a)      uprintf a
   60 #else
   61 #define DPRINTF(a)
   62 #endif
   63 
   64 int linux32_copyinargs(struct exec_package *, struct ps_strings *,
   65                         void *, size_t, const void *, const void *);
   66 
   67 int
   68 ELFNAME2(linux32,probe)(l, epp, eh, itp, pos)
   69         struct lwp *l;
   70         struct exec_package *epp;
   71         void *eh;
   72         char *itp;
   73         vaddr_t *pos;
   74 {
   75         int error;
   76 
   77         if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) &&
   78 #ifdef LINUX32_GCC_SIGNATURE
   79             ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) &&
   80 #endif
   81 #ifdef LINUX32_ATEXIT_SIGNATURE
   82             ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) &&
   83 #endif
   84 #ifdef LINUX32_DEBUGLINK_SIGNATURE
   85             ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) &&
   86 #endif
   87             1)
   88                         return error;
   89 
   90         if (itp) {
   91                 if ((error = emul_find_interp(l, epp, itp)))
   92                         return (error);
   93         }
   94 #if 0
   95         DPRINTF(("linux32_probe: returning 0\n"));
   96 #endif
   97 
   98         epp->ep_flags |= EXEC_32;
   99         epp->ep_vm_minaddr = VM_MIN_ADDRESS;
  100         epp->ep_vm_maxaddr = USRSTACK32;
  101 
  102         return 0;
  103 }
  104 
  105 /* round up and down to page boundaries. */
  106 #define ELF_ROUND(a, b)         (((a) + (b) - 1) & ~((b) - 1))
  107 #define ELF_TRUNC(a, b)         ((a) & ~((b) - 1))
  108 
  109 /*
  110  * Copy arguments onto the stack in the normal way, but add some
  111  * extra information in case of dynamic binding.
  112  */
  113 int
  114 linux32_elf32_copyargs(struct lwp *l, struct exec_package *pack,
  115     struct ps_strings *arginfo, char **stackp, void *argp)
  116 {
  117         struct linux32_extra_stack_data *esdp, esd;
  118         struct elf_args *ap;
  119         struct vattr *vap;
  120         Elf_Ehdr *eh;
  121         Elf_Phdr *ph;
  122         Elf_Addr phdr = 0;
  123         u_long phsize;
  124         int error;
  125         int i;
  126 
  127         if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0)
  128                 return error;
  129 
  130         /*
  131          * Push extra arguments on the stack needed by dynamically
  132          * linked binaries and static binaries as well.
  133          */
  134         memset(&esd, 0, sizeof(esd));
  135         esdp = (struct linux32_extra_stack_data *)(*stackp);
  136         ap = (struct elf_args *)pack->ep_emul_arg;
  137         vap = pack->ep_vap;
  138         eh = (Elf_Ehdr *)pack->ep_hdr;
  139 
  140         /*
  141          * We forgot this, so we ned to reload it now. XXX keep track of it?
  142          */
  143         if (ap == NULL) {
  144                 phsize = eh->e_phnum * sizeof(Elf_Phdr);
  145                 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
  146                 error = exec_read_from(l, pack->ep_vp, eh->e_phoff, ph, phsize);
  147                 if (error != 0) {
  148                         for (i = 0; i < eh->e_phnum; i++) {
  149                                 if (ph[i].p_type == PT_PHDR) {
  150                                         phdr = ph[i].p_vaddr;
  151                                         break;
  152                                 }
  153                         }
  154                 }
  155                 free(ph, M_TEMP);
  156         }
  157 
  158 
  159         /*
  160          * The exec_package doesn't have a proc pointer and it's not
  161          * exactly trivial to add one since the credentials are
  162          * changing. XXX Linux uses curlwp's credentials.
  163          * Why can't we use them too? XXXad we do now; what's different
  164          * about Linux's LWP creds?
  165          */
  166 
  167         i = 0;
  168         esd.ai[i].a_type = LINUX_AT_SYSINFO;
  169         esd.ai[i++].a_v = NETBSD32PTR32I(&esdp->kernel_vsyscall[0]);
  170 
  171         esd.ai[i].a_type = LINUX_AT_SYSINFO_EHDR;
  172         esd.ai[i++].a_v = NETBSD32PTR32I(&esdp->elfhdr);
  173 
  174         esd.ai[i].a_type = LINUX_AT_HWCAP;
  175         esd.ai[i++].a_v = LINUX32_CPUCAP;
  176 
  177         esd.ai[i].a_type = AT_PAGESZ;
  178         esd.ai[i++].a_v = PAGE_SIZE;
  179 
  180         esd.ai[i].a_type = LINUX_AT_CLKTCK;
  181         esd.ai[i++].a_v = hz;
  182 
  183         esd.ai[i].a_type = AT_PHDR;
  184         esd.ai[i++].a_v = (ap ? ap->arg_phaddr: phdr);
  185 
  186         esd.ai[i].a_type = AT_PHENT;
  187         esd.ai[i++].a_v = (ap ? ap->arg_phentsize : eh->e_phentsize);
  188 
  189         esd.ai[i].a_type = AT_PHNUM;
  190         esd.ai[i++].a_v = (ap ? ap->arg_phnum : eh->e_phnum);
  191 
  192         esd.ai[i].a_type = AT_BASE;
  193         esd.ai[i++].a_v = (ap ? ap->arg_interp : 0);
  194 
  195         esd.ai[i].a_type = AT_FLAGS;
  196         esd.ai[i++].a_v = 0;
  197 
  198         esd.ai[i].a_type = AT_ENTRY;
  199         esd.ai[i++].a_v = (ap ? ap->arg_entry : eh->e_entry);
  200 
  201         esd.ai[i].a_type = LINUX_AT_EGID;
  202         esd.ai[i++].a_v = ((vap->va_mode & S_ISGID) ?
  203             vap->va_gid : kauth_cred_getegid(l->l_cred));
  204 
  205         esd.ai[i].a_type = LINUX_AT_GID;
  206         esd.ai[i++].a_v = kauth_cred_getgid(l->l_cred);
  207 
  208         esd.ai[i].a_type = LINUX_AT_EUID;
  209         esd.ai[i++].a_v = ((vap->va_mode & S_ISUID) ?
  210             vap->va_uid : kauth_cred_geteuid(l->l_cred));
  211 
  212         esd.ai[i].a_type = LINUX_AT_UID;
  213         esd.ai[i++].a_v = kauth_cred_getuid(l->l_cred);
  214 
  215         esd.ai[i].a_type = LINUX_AT_SECURE;
  216         esd.ai[i++].a_v = 0;
  217 
  218         esd.ai[i].a_type = LINUX_AT_PLATFORM;
  219         esd.ai[i++].a_v = NETBSD32PTR32I(&esdp->hw_platform[0]);
  220 
  221         esd.ai[i].a_type = AT_NULL;
  222         esd.ai[i++].a_v = 0;
  223 
  224 #ifdef DEBUG_LINUX
  225         if (i != LINUX32_ELF_AUX_ENTRIES) {
  226                 printf("linux32_elf32_copyargs: %d Aux entries\n", i);
  227                 return EINVAL;
  228         }
  229 #endif
  230                 
  231         memcpy(esd.kernel_vsyscall, linux32_kernel_vsyscall, 
  232             sizeof(linux32_kernel_vsyscall));
  233 
  234         memcpy(&esd.elfhdr, eh, sizeof(*eh));
  235 
  236         strcpy(esd.hw_platform, LINUX32_PLATFORM); 
  237 
  238         if (ap) {
  239                 free((char *)ap, M_TEMP);
  240                 pack->ep_emul_arg = NULL;
  241         }
  242         
  243         /*
  244          * Copy out the ELF auxiliary table and hw platform name
  245          */
  246         if ((error = copyout(&esd, esdp, sizeof(esd))) != 0)
  247                 return error;
  248         *stackp += sizeof(esd);
  249         return 0;
  250 }
  251 

Cache object: 972e5bd7716d0f38768ca316305e0642


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.