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/irix/irix_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: irix_exec_elf32.c,v 1.15 2008/04/28 20:23:41 martin Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Emmanuel Dreyfus.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: irix_exec_elf32.c,v 1.15 2008/04/28 20:23:41 martin Exp $");
   34 
   35 #ifndef ELFSIZE
   36 #define ELFSIZE         32      /* XXX should die */
   37 #endif
   38 
   39 #include <sys/param.h>
   40 #include <sys/types.h>
   41 #include <sys/systm.h>
   42 #include <sys/null.h>
   43 #include <sys/malloc.h>
   44 #include <sys/syslimits.h>
   45 #include <sys/exec.h>
   46 #include <sys/exec_elf.h>
   47 #include <sys/errno.h>
   48 #include <sys/namei.h>  /* Used for irix_load_addr */
   49 #include <sys/vnode.h>  /* Used for irix_load_addr */
   50 
   51 #include <machine/vmparam.h>
   52 
   53 #include <uvm/uvm_extern.h>
   54 
   55 #include <compat/common/compat_util.h>
   56 
   57 #include <compat/irix/irix_exec.h>
   58 
   59 /*
   60  * IRIX o32 ABI probe function
   61  */
   62 int
   63 ELFNAME2(irix,probe_o32)(l, epp, eh, itp, pos)
   64         struct lwp *l;
   65         struct exec_package *epp;
   66         void *eh;
   67         char *itp;
   68         vaddr_t *pos;
   69 {
   70         int error = 0;
   71 
   72 #ifdef DEBUG_IRIX
   73         printf("irix_probe_o32()\n");
   74 #endif
   75         if ((((Elf_Ehdr *)epp->ep_hdr)->e_flags & IRIX_EF_IRIX_ABI_MASK) !=
   76             IRIX_EF_IRIX_ABIO32)
   77                 return error;
   78 
   79         if (itp) {
   80                 /* o32 binaries use /lib/libc.so.1 */
   81                 if (strncmp(itp, "/lib/libc.so", 12) &&
   82                     strncmp(itp, "/usr/lib/libc.so", 16))
   83                         return ENOEXEC;
   84                 if ((error = emul_find_interp(l, epp, itp)))
   85                         return error;
   86                 *pos = ELF_LINK_ADDR;
   87         }
   88 #ifdef DEBUG_IRIX
   89         printf("irix_probe_o32: returning 0\n");
   90         printf("epp->ep_vm_minaddr = 0x%lx\n", epp->ep_vm_minaddr);
   91 #endif
   92         epp->ep_vm_minaddr = epp->ep_vm_minaddr & ~0xfUL;
   93         return 0;
   94 }
   95 
   96 /*
   97  * IRIX n32 ABI probe function
   98  */
   99 int
  100 ELFNAME2(irix,probe_n32)(l, epp, eh, itp, pos)
  101         struct lwp *l;
  102         struct exec_package *epp;
  103         void *eh;
  104         char *itp;
  105         vaddr_t *pos;
  106 {
  107         int error = 0;
  108 
  109 #ifdef DEBUG_IRIX
  110         printf("irix_probe_n32()\n");
  111 #endif
  112         if ((((Elf_Ehdr *)epp->ep_hdr)->e_flags & IRIX_EF_IRIX_ABI_MASK) !=
  113             IRIX_EF_IRIX_ABIN32)
  114                 return error;
  115 
  116         if (itp) {
  117                 /* n32 binaries use /lib32/libc.so.1 */
  118                 if (strncmp(itp, "/lib32/libc.so", 14) &&
  119                     strncmp(itp, "/usr/lib32/libc.so", 18))
  120                         return ENOEXEC;
  121                 if ((error = emul_find_interp(l, epp, itp)))
  122                         return error;
  123         }
  124 #ifdef DEBUG_IRIX
  125         printf("irix_probe_n32: returning 0\n");
  126         printf("epp->ep_vm_minaddr = 0x%lx\n", epp->ep_vm_minaddr);
  127 #endif
  128         epp->ep_vm_minaddr = epp->ep_vm_minaddr & ~0xfUL;
  129         return 0;
  130 }
  131 
  132 int
  133 ELFNAME2(irix,copyargs)(l, pack, arginfo, stackp, argp)
  134         struct lwp *l;
  135         struct exec_package *pack;
  136         struct ps_strings *arginfo;
  137         char **stackp;
  138         void *argp;
  139 {
  140         char **cpp, *dp, *sp;
  141         size_t len;
  142         void *nullp;
  143         long argc, envc;
  144         AuxInfo ai[IRIX_ELF_AUX_ENTRIES], *a;
  145         struct elf_args *ap;
  146         int error;
  147 
  148         /*
  149          * IRIX seems to expect argc and **argv to be aligned on a
  150          * 16 bytes boundary. It seems there is no other way of
  151          * getting **argv aligned than duplicating and customizing
  152          * the code that sets up the stack in copyargs():
  153          */
  154 #ifdef DEBUG_IRIX
  155         printf("irix_elf32_copyargs(): *stackp = %p\n", *stackp);
  156 #endif
  157         /*
  158          * This is borrowed from sys/kern/kern_exec.c:copyargs()
  159          */
  160         cpp = (char **)*stackp;
  161         nullp = NULL;
  162         argc = arginfo->ps_nargvstr;
  163         envc = arginfo->ps_nenvstr;
  164         if ((error = copyout(&argc, cpp++, sizeof(argc))) != 0)
  165                 return error;
  166 
  167         dp = (char *) (cpp + argc + envc + 2 + pack->ep_esch->es_arglen);
  168 
  169         /* Align **argv on a 16 bytes boundary */
  170         dp = (char *)(((unsigned long)dp + 0xf) & ~0xfUL);
  171 
  172         sp = argp;
  173 
  174         arginfo->ps_argvstr = cpp; /* remember location of argv for later */
  175 
  176         for (; --argc >= 0; sp += len, dp += len) {
  177 #ifdef DEBUG_IRIX
  178         printf("irix_elf32_copyargs(): argc = %d, cpp = %p, dp = %p\n", (int)argc, cpp, dp);
  179 #endif
  180                 if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
  181                     (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
  182                         return error;
  183         }
  184 
  185         if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
  186                 return error;
  187 
  188         arginfo->ps_envstr = cpp; /* remember location of envp for later */
  189 
  190         for (; --envc >= 0; sp += len, dp += len)
  191                 if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
  192                     (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
  193                         return error;
  194 
  195         if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
  196                 return error;
  197 
  198         *stackp = (char *)cpp;
  199 
  200         /*
  201          * This is borrowed from sys/kern/exec_elf32.c:elf32_copyargs
  202          */
  203         a = ai;
  204 
  205         /*
  206          * Push extra arguments on the stack needed by dynamically
  207          * linked binaries
  208          */
  209         if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
  210 
  211                 a->a_type = AT_PHDR;
  212                 a->a_v = ap->arg_phaddr;
  213                 a++;
  214 
  215                 a->a_type = AT_PHENT;
  216                 a->a_v = ap->arg_phentsize;
  217                 a++;
  218 
  219                 a->a_type = AT_PHNUM;
  220                 a->a_v = ap->arg_phnum;
  221                 a++;
  222 
  223                 a->a_type = AT_ENTRY;
  224                 a->a_v = ap->arg_entry;
  225                 a++;
  226 
  227                 a->a_type = AT_BASE;
  228                 a->a_v = ap->arg_interp;
  229                 a++;
  230 
  231                 a->a_type = AT_PAGESZ;
  232                 a->a_v = PAGE_SIZE;
  233                 a++;
  234 
  235                 free((char *)ap, M_TEMP);
  236                 pack->ep_emul_arg = NULL;
  237         }
  238 
  239         a->a_type = AT_NULL;
  240         a->a_v = 0;
  241         a++;
  242 
  243         len = (a - ai) * sizeof(AuxInfo);
  244         if ((error = copyout(ai, *stackp, len)) != 0)
  245                 return error;
  246 /*      *stackp += len; */
  247 #ifdef DEBUG_IRIX
  248         printf("*stackp = %p\n", *stackp);
  249 #endif
  250         return 0;
  251 }

Cache object: cc888a5bad7a575701bbf16b4373ed5b


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