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/kern/imgact_elf.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 /*-
    2  * Copyright (c) 2000 David O'Brien
    3  * Copyright (c) 1995-1996 Søren Schmidt
    4  * Copyright (c) 1996 Peter Wemm
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer
   12  *    in this position and unchanged.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   29  *
   30  * $FreeBSD: src/sys/kern/imgact_elf.c,v 1.73.2.13 2002/12/28 19:49:41 dillon Exp $
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/exec.h>
   35 #include <sys/fcntl.h>
   36 #include <sys/file.h>
   37 #include <sys/imgact.h>
   38 #include <sys/imgact_elf.h>
   39 #include <sys/kernel.h>
   40 #include <sys/malloc.h>
   41 #include <sys/mman.h>
   42 #include <sys/systm.h>
   43 #include <sys/proc.h>
   44 #include <sys/nlookup.h>
   45 #include <sys/pioctl.h>
   46 #include <sys/procfs.h>
   47 #include <sys/resourcevar.h>
   48 #include <sys/signalvar.h>
   49 #include <sys/stat.h>
   50 #include <sys/syscall.h>
   51 #include <sys/sysctl.h>
   52 #include <sys/sysent.h>
   53 #include <sys/vnode.h>
   54 #include <sys/eventhandler.h>
   55 
   56 #include <cpu/lwbuf.h>
   57 
   58 #include <vm/vm.h>
   59 #include <vm/vm_kern.h>
   60 #include <vm/vm_param.h>
   61 #include <vm/pmap.h>
   62 #include <sys/lock.h>
   63 #include <vm/vm_map.h>
   64 #include <vm/vm_object.h>
   65 #include <vm/vm_extern.h>
   66 
   67 #include <machine/elf.h>
   68 #include <machine/md_var.h>
   69 #include <sys/mount.h>
   70 #include <sys/ckpt.h>
   71 
   72 #define OLD_EI_BRAND    8
   73 #define truncps(va,ps)  ((va) & ~(ps - 1))
   74 #define aligned(a,t)    (truncps((u_long)(a), sizeof(t)) == (u_long)(a))
   75 
   76 static int __elfN(check_header)(const Elf_Ehdr *hdr);
   77 static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp,
   78     const char *interp, int32_t *osrel);
   79 static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
   80     u_long *entry);
   81 static int __elfN(load_section)(struct proc *p,
   82     struct vmspace *vmspace, struct vnode *vp,
   83     vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz,
   84     vm_prot_t prot);
   85 static int __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp);
   86 static boolean_t __elfN(bsd_trans_osrel)(const Elf_Note *note,
   87     int32_t *osrel);
   88 static boolean_t __elfN(check_note)(struct image_params *imgp,
   89     Elf_Brandnote *checknote, int32_t *osrel);
   90 static vm_prot_t __elfN(trans_prot)(Elf_Word);
   91 static Elf_Word __elfN(untrans_prot)(vm_prot_t);
   92 static boolean_t check_PT_NOTE(struct image_params *imgp,
   93     Elf_Brandnote *checknote, int32_t *osrel, const Elf_Phdr * pnote);
   94 static boolean_t extract_interpreter(struct image_params *imgp,
   95     const Elf_Phdr *pinterpreter, char *data);
   96 
   97 static int elf_legacy_coredump = 0;
   98 static int __elfN(fallback_brand) = -1;
   99 #if defined(__x86_64__)
  100 SYSCTL_NODE(_kern, OID_AUTO, elf64, CTLFLAG_RW, 0, "");
  101 SYSCTL_INT(_debug, OID_AUTO, elf64_legacy_coredump, CTLFLAG_RW,
  102     &elf_legacy_coredump, 0, "legacy coredump mode");
  103 SYSCTL_INT(_kern_elf64, OID_AUTO, fallback_brand, CTLFLAG_RW,
  104     &elf64_fallback_brand, 0, "ELF64 brand of last resort");
  105 TUNABLE_INT("kern.elf64.fallback_brand", &elf64_fallback_brand);
  106 #else /* i386 assumed */
  107 SYSCTL_NODE(_kern, OID_AUTO, elf32, CTLFLAG_RW, 0, "");
  108 SYSCTL_INT(_debug, OID_AUTO, elf32_legacy_coredump, CTLFLAG_RW,
  109     &elf_legacy_coredump, 0, "legacy coredump mode");
  110 SYSCTL_INT(_kern_elf32, OID_AUTO, fallback_brand, CTLFLAG_RW,
  111     &elf32_fallback_brand, 0, "ELF32 brand of last resort");
  112 TUNABLE_INT("kern.elf32.fallback_brand", &elf32_fallback_brand);
  113 #endif
  114 
  115 static Elf_Brandinfo *elf_brand_list[MAX_BRANDS];
  116 
  117 static const char DRAGONFLY_ABI_VENDOR[] = "DragonFly";
  118 static const char FREEBSD_ABI_VENDOR[]   = "FreeBSD";
  119 
  120 Elf_Brandnote __elfN(dragonfly_brandnote) = {
  121         .hdr.n_namesz   = sizeof(DRAGONFLY_ABI_VENDOR),
  122         .hdr.n_descsz   = sizeof(int32_t),
  123         .hdr.n_type     = 1,
  124         .vendor         = DRAGONFLY_ABI_VENDOR,
  125         .flags          = BN_TRANSLATE_OSREL,
  126         .trans_osrel    = __elfN(bsd_trans_osrel),
  127 };
  128 
  129 Elf_Brandnote __elfN(freebsd_brandnote) = {
  130         .hdr.n_namesz   = sizeof(FREEBSD_ABI_VENDOR),
  131         .hdr.n_descsz   = sizeof(int32_t),
  132         .hdr.n_type     = 1,
  133         .vendor         = FREEBSD_ABI_VENDOR,
  134         .flags          = BN_TRANSLATE_OSREL,
  135         .trans_osrel    = __elfN(bsd_trans_osrel),
  136 };
  137 
  138 int
  139 __elfN(insert_brand_entry)(Elf_Brandinfo *entry)
  140 {
  141         int i;
  142 
  143         for (i = 0; i < MAX_BRANDS; i++) {
  144                 if (elf_brand_list[i] == NULL) {
  145                         elf_brand_list[i] = entry;
  146                         break;
  147                 }
  148         }
  149         if (i == MAX_BRANDS) {
  150                 uprintf("WARNING: %s: could not insert brandinfo entry: %p\n",
  151                         __func__, entry);
  152                 return (-1);
  153         }
  154         return (0);
  155 }
  156 
  157 int
  158 __elfN(remove_brand_entry)(Elf_Brandinfo *entry)
  159 {
  160         int i;
  161 
  162         for (i = 0; i < MAX_BRANDS; i++) {
  163                 if (elf_brand_list[i] == entry) {
  164                         elf_brand_list[i] = NULL;
  165                         break;
  166                 }
  167         }
  168         if (i == MAX_BRANDS)
  169                 return (-1);
  170         return (0);
  171 }
  172 
  173 /*
  174  * Check if an elf brand is being used anywhere in the system.
  175  *
  176  * Used by the linux emulation module unloader.  This isn't safe from
  177  * races.
  178  */
  179 struct elf_brand_inuse_info {
  180         int rval;
  181         Elf_Brandinfo *entry;
  182 };
  183 
  184 static int elf_brand_inuse_callback(struct proc *p, void *data);
  185 
  186 int
  187 __elfN(brand_inuse)(Elf_Brandinfo *entry)
  188 {
  189         struct elf_brand_inuse_info info;
  190 
  191         info.rval = FALSE;
  192         info.entry = entry;
  193         allproc_scan(elf_brand_inuse_callback, &info);
  194         return (info.rval);
  195 }
  196 
  197 static
  198 int
  199 elf_brand_inuse_callback(struct proc *p, void *data)
  200 {
  201         struct elf_brand_inuse_info *info = data;
  202 
  203         if (p->p_sysent == info->entry->sysvec) {
  204                 info->rval = TRUE;
  205                 return (-1);
  206         }
  207         return (0);
  208 }
  209 
  210 static int
  211 __elfN(check_header)(const Elf_Ehdr *hdr)
  212 {
  213         Elf_Brandinfo *bi;
  214         int i;
  215 
  216         if (!IS_ELF(*hdr) ||
  217             hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
  218             hdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
  219             hdr->e_ident[EI_VERSION] != EV_CURRENT ||
  220             hdr->e_phentsize != sizeof(Elf_Phdr) ||
  221             hdr->e_ehsize != sizeof(Elf_Ehdr) ||
  222             hdr->e_version != ELF_TARG_VER)
  223                 return (ENOEXEC);
  224 
  225         /*
  226          * Make sure we have at least one brand for this machine.
  227          */
  228 
  229         for (i = 0; i < MAX_BRANDS; i++) {
  230                 bi = elf_brand_list[i];
  231                 if (bi != NULL && bi->machine == hdr->e_machine)
  232                         break;
  233         }
  234         if (i == MAX_BRANDS)
  235                 return (ENOEXEC);
  236 
  237         return (0);
  238 }
  239 
  240 static int
  241 __elfN(load_section)(struct proc *p, struct vmspace *vmspace, struct vnode *vp,
  242                  vm_offset_t offset, caddr_t vmaddr, size_t memsz,
  243                  size_t filsz, vm_prot_t prot)
  244 {
  245         size_t map_len;
  246         vm_offset_t map_addr;
  247         int error, rv, cow;
  248         int count;
  249         int shared;
  250         size_t copy_len;
  251         vm_object_t object;
  252         vm_offset_t file_addr;
  253 
  254         object = vp->v_object;
  255         error = 0;
  256 
  257         /*
  258          * In most cases we will be able to use a shared lock on the
  259          * object we are inserting into the map.  The lock will be
  260          * upgraded in situations where new VM pages must be allocated.
  261          */
  262         vm_object_hold_shared(object);
  263         shared = 1;
  264 
  265         /*
  266          * It's necessary to fail if the filsz + offset taken from the
  267          * header is greater than the actual file pager object's size.
  268          * If we were to allow this, then the vm_map_find() below would
  269          * walk right off the end of the file object and into the ether.
  270          *
  271          * While I'm here, might as well check for something else that
  272          * is invalid: filsz cannot be greater than memsz.
  273          */
  274         if ((off_t)filsz + offset > vp->v_filesize || filsz > memsz) {
  275                 uprintf("elf_load_section: truncated ELF file\n");
  276                 vm_object_drop(object);
  277                 return (ENOEXEC);
  278         }
  279 
  280         map_addr = trunc_page((vm_offset_t)vmaddr);
  281         file_addr = trunc_page(offset);
  282 
  283         /*
  284          * We have two choices.  We can either clear the data in the last page
  285          * of an oversized mapping, or we can start the anon mapping a page
  286          * early and copy the initialized data into that first page.  We
  287          * choose the second..
  288          */
  289         if (memsz > filsz)
  290                 map_len = trunc_page(offset+filsz) - file_addr;
  291         else
  292                 map_len = round_page(offset+filsz) - file_addr;
  293 
  294         if (map_len != 0) {
  295                 vm_object_reference_locked(object);
  296 
  297                 /* cow flags: don't dump readonly sections in core */
  298                 cow = MAP_COPY_ON_WRITE | MAP_PREFAULT;
  299                 if ((prot & VM_PROT_WRITE) == 0)
  300                         cow |= MAP_DISABLE_COREDUMP;
  301                 if (shared == 0)
  302                         cow |= MAP_PREFAULT_RELOCK;
  303 
  304                 count = vm_map_entry_reserve(MAP_RESERVE_COUNT);
  305                 vm_map_lock(&vmspace->vm_map);
  306                 rv = vm_map_insert(&vmspace->vm_map, &count,
  307                                       object,
  308                                       file_addr,        /* file offset */
  309                                       map_addr,         /* virtual start */
  310                                       map_addr + map_len,/* virtual end */
  311                                       VM_MAPTYPE_NORMAL,
  312                                       prot, VM_PROT_ALL,
  313                                       cow);
  314                 vm_map_unlock(&vmspace->vm_map);
  315                 vm_map_entry_release(count);
  316 
  317                 /*
  318                  * NOTE: Object must have a hold ref when calling
  319                  * vm_object_deallocate().
  320                  */
  321                 if (rv != KERN_SUCCESS) {
  322                         vm_object_drop(object);
  323                         vm_object_deallocate(object);
  324                         return (EINVAL);
  325                 }
  326 
  327                 /* we can stop now if we've covered it all */
  328                 if (memsz == filsz) {
  329                         vm_object_drop(object);
  330                         return (0);
  331                 }
  332         }
  333 
  334         /*
  335          * We have to get the remaining bit of the file into the first part
  336          * of the oversized map segment.  This is normally because the .data
  337          * segment in the file is extended to provide bss.  It's a neat idea
  338          * to try and save a page, but it's a pain in the behind to implement.
  339          */
  340         copy_len = (offset + filsz) - trunc_page(offset + filsz);
  341         map_addr = trunc_page((vm_offset_t)vmaddr + filsz);
  342         map_len = round_page((vm_offset_t)vmaddr + memsz) - map_addr;
  343 
  344         /* This had damn well better be true! */
  345         if (map_len != 0) {
  346                 count = vm_map_entry_reserve(MAP_RESERVE_COUNT);
  347                 vm_map_lock(&vmspace->vm_map);
  348                 rv = vm_map_insert(&vmspace->vm_map, &count,
  349                                         NULL, 0,
  350                                         map_addr, map_addr + map_len,
  351                                         VM_MAPTYPE_NORMAL,
  352                                         VM_PROT_ALL, VM_PROT_ALL,
  353                                         0);
  354                 vm_map_unlock(&vmspace->vm_map);
  355                 vm_map_entry_release(count);
  356                 if (rv != KERN_SUCCESS) {
  357                         vm_object_drop(object);
  358                         return (EINVAL);
  359                 }
  360         }
  361 
  362         if (copy_len != 0) {
  363                 struct lwbuf *lwb;
  364                 struct lwbuf lwb_cache;
  365                 vm_page_t m;
  366 
  367                 m = vm_fault_object_page(object, trunc_page(offset + filsz),
  368                                          VM_PROT_READ, 0, &shared, &error);
  369                 vm_object_drop(object);
  370                 if (m) {
  371                         lwb = lwbuf_alloc(m, &lwb_cache);
  372                         error = copyout((caddr_t)lwbuf_kva(lwb),
  373                                         (caddr_t)map_addr, copy_len);
  374                         lwbuf_free(lwb);
  375                         vm_page_unhold(m);
  376                 }
  377         } else {
  378                 vm_object_drop(object);
  379         }
  380 
  381         /*
  382          * set it to the specified protection
  383          */
  384         if (error == 0) {
  385                 vm_map_protect(&vmspace->vm_map,
  386                                map_addr, map_addr + map_len,
  387                                prot, FALSE);
  388         }
  389         return (error);
  390 }
  391 
  392 /*
  393  * Load the file "file" into memory.  It may be either a shared object
  394  * or an executable.
  395  *
  396  * The "addr" reference parameter is in/out.  On entry, it specifies
  397  * the address where a shared object should be loaded.  If the file is
  398  * an executable, this value is ignored.  On exit, "addr" specifies
  399  * where the file was actually loaded.
  400  *
  401  * The "entry" reference parameter is out only.  On exit, it specifies
  402  * the entry point for the loaded file.
  403  */
  404 static int
  405 __elfN(load_file)(struct proc *p, const char *file, u_long *addr, u_long *entry)
  406 {
  407         struct {
  408                 struct nlookupdata nd;
  409                 struct vattr attr;
  410                 struct image_params image_params;
  411         } *tempdata;
  412         const Elf_Ehdr *hdr = NULL;
  413         const Elf_Phdr *phdr = NULL;
  414         struct nlookupdata *nd;
  415         struct vmspace *vmspace = p->p_vmspace;
  416         struct vattr *attr;
  417         struct image_params *imgp;
  418         struct mount *topmnt;
  419         vm_prot_t prot;
  420         u_long rbase;
  421         u_long base_addr = 0;
  422         int error, i, numsegs;
  423 
  424         tempdata = kmalloc(sizeof(*tempdata), M_TEMP, M_WAITOK);
  425         nd = &tempdata->nd;
  426         attr = &tempdata->attr;
  427         imgp = &tempdata->image_params;
  428 
  429         /*
  430          * Initialize part of the common data
  431          */
  432         imgp->proc = p;
  433         imgp->attr = attr;
  434         imgp->firstpage = NULL;
  435         imgp->image_header = NULL;
  436         imgp->vp = NULL;
  437 
  438         error = nlookup_init(nd, file, UIO_SYSSPACE, NLC_FOLLOW);
  439         if (error == 0)
  440                 error = nlookup(nd);
  441         if (error == 0)
  442                 error = cache_vget(&nd->nl_nch, nd->nl_cred,
  443                                    LK_SHARED, &imgp->vp);
  444         topmnt = nd->nl_nch.mount;
  445         nlookup_done(nd);
  446         if (error)
  447                 goto fail;
  448 
  449         /*
  450          * Check permissions, modes, uid, etc on the file, and "open" it.
  451          */
  452         error = exec_check_permissions(imgp, topmnt);
  453         if (error) {
  454                 vn_unlock(imgp->vp);
  455                 goto fail;
  456         }
  457 
  458         error = exec_map_first_page(imgp);
  459         /*
  460          * Also make certain that the interpreter stays the same, so set
  461          * its VTEXT flag, too.
  462          */
  463         if (error == 0)
  464                 vsetflags(imgp->vp, VTEXT);
  465         vn_unlock(imgp->vp);
  466         if (error)
  467                 goto fail;
  468 
  469         hdr = (const Elf_Ehdr *)imgp->image_header;
  470         if ((error = __elfN(check_header)(hdr)) != 0)
  471                 goto fail;
  472         if (hdr->e_type == ET_DYN)
  473                 rbase = *addr;
  474         else if (hdr->e_type == ET_EXEC)
  475                 rbase = 0;
  476         else {
  477                 error = ENOEXEC;
  478                 goto fail;
  479         }
  480 
  481         /* Only support headers that fit within first page for now      */
  482         /*    (multiplication of two Elf_Half fields will not overflow) */
  483         if ((hdr->e_phoff > PAGE_SIZE) ||
  484             (hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE - hdr->e_phoff) {
  485                 error = ENOEXEC;
  486                 goto fail;
  487         }
  488 
  489         phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
  490         if (!aligned(phdr, Elf_Addr)) {
  491                 error = ENOEXEC;
  492                 goto fail;
  493         }
  494 
  495         for (i = 0, numsegs = 0; i < hdr->e_phnum; i++) {
  496                 if (phdr[i].p_type == PT_LOAD && phdr[i].p_memsz != 0) {
  497                         /* Loadable segment */
  498                         prot = __elfN(trans_prot)(phdr[i].p_flags);
  499                         error = __elfN(load_section)(
  500                                     p, vmspace, imgp->vp,
  501                                     phdr[i].p_offset,
  502                                     (caddr_t)phdr[i].p_vaddr +
  503                                     rbase,
  504                                     phdr[i].p_memsz,
  505                                     phdr[i].p_filesz, prot);
  506                         if (error != 0)
  507                                 goto fail;
  508                         /*
  509                          * Establish the base address if this is the
  510                          * first segment.
  511                          */
  512                         if (numsegs == 0)
  513                                 base_addr = trunc_page(phdr[i].p_vaddr + rbase);
  514                         numsegs++;
  515                 }
  516         }
  517         *addr = base_addr;
  518         *entry = (unsigned long)hdr->e_entry + rbase;
  519 
  520 fail:
  521         if (imgp->firstpage)
  522                 exec_unmap_first_page(imgp);
  523         if (imgp->vp) {
  524                 vrele(imgp->vp);
  525                 imgp->vp = NULL;
  526         }
  527         kfree(tempdata, M_TEMP);
  528 
  529         return (error);
  530 }
  531 
  532 static Elf_Brandinfo *
  533 __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
  534     int32_t *osrel)
  535 {
  536         const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
  537         Elf_Brandinfo *bi;
  538         boolean_t ret;
  539         int i;
  540 
  541         /* We support four types of branding -- (1) the ELF EI_OSABI field
  542          * that SCO added to the ELF spec, (2) FreeBSD 3.x's traditional string
  543          * branding within the ELF header, (3) path of the `interp_path' field,
  544          * and (4) the ".note.ABI-tag" ELF section.
  545          */
  546 
  547         /* Look for an ".note.ABI-tag" ELF section */
  548         for (i = 0; i < MAX_BRANDS; i++) {
  549                 bi = elf_brand_list[i];
  550 
  551                 if (bi == NULL)
  552                         continue;
  553                 if (hdr->e_machine == bi->machine && (bi->flags &
  554                     (BI_BRAND_NOTE|BI_BRAND_NOTE_MANDATORY)) != 0) {
  555                         ret = __elfN(check_note)(imgp, bi->brand_note, osrel);
  556                         if (ret)
  557                                 return (bi);
  558                 }
  559         }
  560 
  561         /* If the executable has a brand, search for it in the brand list. */
  562         for (i = 0;  i < MAX_BRANDS;  i++) {
  563                 bi = elf_brand_list[i];
  564 
  565                 if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY)
  566                         continue;
  567                 if (hdr->e_machine == bi->machine &&
  568                     (hdr->e_ident[EI_OSABI] == bi->brand ||
  569                     strncmp((const char *)&hdr->e_ident[OLD_EI_BRAND],
  570                     bi->compat_3_brand, strlen(bi->compat_3_brand)) == 0))
  571                         return (bi);
  572         }
  573 
  574         /* Lacking a known brand, search for a recognized interpreter. */
  575         if (interp != NULL) {
  576                 for (i = 0;  i < MAX_BRANDS;  i++) {
  577                         bi = elf_brand_list[i];
  578 
  579                         if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY)
  580                                 continue;
  581                         if (hdr->e_machine == bi->machine &&
  582                             strcmp(interp, bi->interp_path) == 0)
  583                                 return (bi);
  584                 }
  585         }
  586 
  587         /* Lacking a recognized interpreter, try the default brand */
  588         for (i = 0; i < MAX_BRANDS; i++) {
  589                 bi = elf_brand_list[i];
  590 
  591                 if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY)
  592                         continue;
  593                 if (hdr->e_machine == bi->machine &&
  594                     __elfN(fallback_brand) == bi->brand)
  595                         return (bi);
  596         }
  597         return (NULL);
  598 }
  599 
  600 static int
  601 __CONCAT(exec_,__elfN(imgact))(struct image_params *imgp)
  602 {
  603         const Elf_Ehdr *hdr = (const Elf_Ehdr *) imgp->image_header;
  604         const Elf_Phdr *phdr;
  605         Elf_Auxargs *elf_auxargs;
  606         struct vmspace *vmspace;
  607         vm_prot_t prot;
  608         u_long text_size = 0, data_size = 0, total_size = 0;
  609         u_long text_addr = 0, data_addr = 0;
  610         u_long seg_size, seg_addr;
  611         u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0;
  612         int32_t osrel = 0;
  613         int error = 0, i, n;
  614         boolean_t failure;
  615         char *interp = NULL;
  616         const char *newinterp = NULL;
  617         Elf_Brandinfo *brand_info;
  618         char *path;
  619 
  620         /*
  621          * Do we have a valid ELF header ?
  622          *
  623          * Only allow ET_EXEC & ET_DYN here, reject ET_DYN later if a particular
  624          * brand doesn't support it.  Both DragonFly platforms do by default.
  625          */
  626         if (__elfN(check_header)(hdr) != 0 ||
  627             (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN))
  628                 return (-1);
  629 
  630         /*
  631          * From here on down, we return an errno, not -1, as we've
  632          * detected an ELF file.
  633          */
  634 
  635         if ((hdr->e_phoff > PAGE_SIZE) ||
  636             (hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE) {
  637                 /* Only support headers in first page for now */
  638                 return (ENOEXEC);
  639         }
  640         phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
  641         if (!aligned(phdr, Elf_Addr))
  642                 return (ENOEXEC);
  643         n = 0;
  644         baddr = 0;
  645         for (i = 0; i < hdr->e_phnum; i++) {
  646                 if (phdr[i].p_type == PT_LOAD) {
  647                         if (n == 0)
  648                                 baddr = phdr[i].p_vaddr;
  649                         n++;
  650                         continue;
  651                 }
  652                 if (phdr[i].p_type == PT_INTERP) {
  653                         /*
  654                          * If interp is already defined there are more than
  655                          * one PT_INTERP program headers present.  Take only
  656                          * the first one and ignore the rest.
  657                          */
  658                         if (interp != NULL)
  659                                 continue;
  660 
  661                         if (phdr[i].p_filesz == 0 ||
  662                             phdr[i].p_filesz > PAGE_SIZE ||
  663                             phdr[i].p_filesz > MAXPATHLEN)
  664                                 return (ENOEXEC);
  665 
  666                         interp = kmalloc(phdr[i].p_filesz, M_TEMP, M_WAITOK);
  667                         failure = extract_interpreter(imgp, &phdr[i], interp);
  668                         if (failure) {
  669                                 kfree(interp, M_TEMP);
  670                                 return (ENOEXEC);
  671                         }
  672                         continue;
  673                 }
  674         }
  675         
  676         brand_info = __elfN(get_brandinfo)(imgp, interp, &osrel);
  677         if (brand_info == NULL) {
  678                 uprintf("ELF binary type \"%u\" not known.\n",
  679                     hdr->e_ident[EI_OSABI]);
  680                 if (interp != NULL)
  681                         kfree(interp, M_TEMP);
  682                 return (ENOEXEC);
  683         }
  684         if (hdr->e_type == ET_DYN) {
  685                 if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) {
  686                         if (interp != NULL)
  687                                 kfree(interp, M_TEMP);
  688                         return (ENOEXEC);
  689                 }
  690                 /*
  691                  * Honour the base load address from the dso if it is
  692                  * non-zero for some reason.
  693                  */
  694                 if (baddr == 0)
  695                         et_dyn_addr = ET_DYN_LOAD_ADDR;
  696                 else
  697                         et_dyn_addr = 0;
  698         } else
  699                 et_dyn_addr = 0;
  700 
  701         if (interp != NULL && brand_info->interp_newpath != NULL)
  702                 newinterp = brand_info->interp_newpath;
  703 
  704         exec_new_vmspace(imgp, NULL);
  705 
  706         /*
  707          * Yeah, I'm paranoid.  There is every reason in the world to get
  708          * VTEXT now since from here on out, there are places we can have
  709          * a context switch.  Better safe than sorry; I really don't want
  710          * the file to change while it's being loaded.
  711          */
  712         vsetflags(imgp->vp, VTEXT);
  713 
  714         vmspace = imgp->proc->p_vmspace;
  715 
  716         for (i = 0; i < hdr->e_phnum; i++) {
  717                 switch (phdr[i].p_type) {
  718                 case PT_LOAD:   /* Loadable segment */
  719                         if (phdr[i].p_memsz == 0)
  720                                 break;
  721                         prot = __elfN(trans_prot)(phdr[i].p_flags);
  722 
  723                         if ((error = __elfN(load_section)(
  724                                         imgp->proc,
  725                                         vmspace,
  726                                         imgp->vp,
  727                                         phdr[i].p_offset,
  728                                         (caddr_t)phdr[i].p_vaddr + et_dyn_addr,
  729                                         phdr[i].p_memsz,
  730                                         phdr[i].p_filesz,
  731                                         prot)) != 0) {
  732                                 if (interp != NULL)
  733                                         kfree (interp, M_TEMP);
  734                                 return (error);
  735                         }
  736 
  737                         /*
  738                          * If this segment contains the program headers,
  739                          * remember their virtual address for the AT_PHDR
  740                          * aux entry. Static binaries don't usually include
  741                          * a PT_PHDR entry.
  742                          */
  743                         if (phdr[i].p_offset == 0 &&
  744                             hdr->e_phoff + hdr->e_phnum * hdr->e_phentsize
  745                                 <= phdr[i].p_filesz)
  746                                 proghdr = phdr[i].p_vaddr + hdr->e_phoff +
  747                                     et_dyn_addr;
  748 
  749                         seg_addr = trunc_page(phdr[i].p_vaddr + et_dyn_addr);
  750                         seg_size = round_page(phdr[i].p_memsz +
  751                             phdr[i].p_vaddr + et_dyn_addr - seg_addr);
  752 
  753                         /*
  754                          * Is this .text or .data?  We can't use
  755                          * VM_PROT_WRITE or VM_PROT_EXEC, it breaks the
  756                          * alpha terribly and possibly does other bad
  757                          * things so we stick to the old way of figuring
  758                          * it out:  If the segment contains the program
  759                          * entry point, it's a text segment, otherwise it
  760                          * is a data segment.
  761                          *
  762                          * Note that obreak() assumes that data_addr + 
  763                          * data_size == end of data load area, and the ELF
  764                          * file format expects segments to be sorted by
  765                          * address.  If multiple data segments exist, the
  766                          * last one will be used.
  767                          */
  768                         if (hdr->e_entry >= phdr[i].p_vaddr &&
  769                             hdr->e_entry < (phdr[i].p_vaddr +
  770                             phdr[i].p_memsz)) {
  771                                 text_size = seg_size;
  772                                 text_addr = seg_addr;
  773                                 entry = (u_long)hdr->e_entry + et_dyn_addr;
  774                         } else {
  775                                 data_size = seg_size;
  776                                 data_addr = seg_addr;
  777                         }
  778                         total_size += seg_size;
  779 
  780                         /*
  781                          * Check limits.  It should be safe to check the
  782                          * limits after loading the segment since we do
  783                          * not actually fault in all the segment's pages.
  784                          */
  785                         if (data_size >
  786                             imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur ||
  787                             text_size > maxtsiz ||
  788                             total_size >
  789                             imgp->proc->p_rlimit[RLIMIT_VMEM].rlim_cur) {
  790                                 if (interp != NULL)
  791                                         kfree(interp, M_TEMP);
  792                                 error = ENOMEM;
  793                                 return (error);
  794                         }
  795                         break;
  796                 case PT_PHDR:   /* Program header table info */
  797                         proghdr = phdr[i].p_vaddr + et_dyn_addr;
  798                         break;
  799                 default:
  800                         break;
  801                 }
  802         }
  803 
  804         vmspace->vm_tsize = text_size >> PAGE_SHIFT;
  805         vmspace->vm_taddr = (caddr_t)(uintptr_t)text_addr;
  806         vmspace->vm_dsize = data_size >> PAGE_SHIFT;
  807         vmspace->vm_daddr = (caddr_t)(uintptr_t)data_addr;
  808 
  809         addr = ELF_RTLD_ADDR(vmspace);
  810 
  811         imgp->entry_addr = entry;
  812 
  813         imgp->proc->p_sysent = brand_info->sysvec;
  814         EVENTHANDLER_INVOKE(process_exec, imgp);
  815 
  816         if (interp != NULL) {
  817                 int have_interp = FALSE;
  818                 if (brand_info->emul_path != NULL &&
  819                     brand_info->emul_path[0] != '\0') {
  820                         path = kmalloc(MAXPATHLEN, M_TEMP, M_WAITOK);
  821                         ksnprintf(path, MAXPATHLEN, "%s%s",
  822                             brand_info->emul_path, interp);
  823                         error = __elfN(load_file)(imgp->proc, path, &addr,
  824                             &imgp->entry_addr);
  825                         kfree(path, M_TEMP);
  826                         if (error == 0)
  827                                 have_interp = TRUE;
  828                 }
  829                 if (!have_interp && newinterp != NULL) {
  830                         error = __elfN(load_file)(imgp->proc, newinterp,
  831                             &addr, &imgp->entry_addr);
  832                         if (error == 0)
  833                                 have_interp = TRUE;
  834                 }
  835                 if (!have_interp) {
  836                         error = __elfN(load_file)(imgp->proc, interp, &addr,
  837                             &imgp->entry_addr);
  838                 }
  839                 if (error != 0) {
  840                         uprintf("ELF interpreter %s not found\n", interp);
  841                         kfree(interp, M_TEMP);
  842                         return (error);
  843                 }
  844                 kfree(interp, M_TEMP);
  845         } else
  846                 addr = et_dyn_addr;
  847 
  848         /*
  849          * Construct auxargs table (used by the fixup routine)
  850          */
  851         elf_auxargs = kmalloc(sizeof(Elf_Auxargs), M_TEMP, M_WAITOK);
  852         elf_auxargs->execfd = -1;
  853         elf_auxargs->phdr = proghdr;
  854         elf_auxargs->phent = hdr->e_phentsize;
  855         elf_auxargs->phnum = hdr->e_phnum;
  856         elf_auxargs->pagesz = PAGE_SIZE;
  857         elf_auxargs->base = addr;
  858         elf_auxargs->flags = 0;
  859         elf_auxargs->entry = entry;
  860 
  861         imgp->auxargs = elf_auxargs;
  862         imgp->interpreted = 0;
  863         imgp->proc->p_osrel = osrel;
  864 
  865         return (error);
  866 }
  867 
  868 int
  869 __elfN(dragonfly_fixup)(register_t **stack_base, struct image_params *imgp)
  870 {
  871         Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs;
  872         Elf_Addr *base;
  873         Elf_Addr *pos;
  874 
  875         base = (Elf_Addr *)*stack_base;
  876         pos = base + (imgp->args->argc + imgp->args->envc + 2);
  877 
  878         if (args->execfd != -1)
  879                 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
  880         AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
  881         AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
  882         AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
  883         AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
  884         AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
  885         AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
  886         AUXARGS_ENTRY(pos, AT_BASE, args->base);
  887         if (imgp->execpathp != 0)
  888                 AUXARGS_ENTRY(pos, AT_EXECPATH, imgp->execpathp);
  889         AUXARGS_ENTRY(pos, AT_OSRELDATE, osreldate);
  890         AUXARGS_ENTRY(pos, AT_NULL, 0);
  891 
  892         kfree(imgp->auxargs, M_TEMP);
  893         imgp->auxargs = NULL;
  894 
  895         base--;
  896         suword(base, (long)imgp->args->argc);
  897         *stack_base = (register_t *)base;
  898         return (0);
  899 }
  900 
  901 /*
  902  * Code for generating ELF core dumps.
  903  */
  904 
  905 typedef int (*segment_callback)(vm_map_entry_t, void *);
  906 
  907 /* Closure for cb_put_phdr(). */
  908 struct phdr_closure {
  909         Elf_Phdr *phdr;         /* Program header to fill in (incremented) */
  910         Elf_Phdr *phdr_max;     /* Pointer bound for error check */
  911         Elf_Off offset;         /* Offset of segment in core file */
  912 };
  913 
  914 /* Closure for cb_size_segment(). */
  915 struct sseg_closure {
  916         int count;              /* Count of writable segments. */
  917         size_t vsize;           /* Total size of all writable segments. */
  918 };
  919 
  920 /* Closure for cb_put_fp(). */
  921 struct fp_closure {
  922         struct vn_hdr *vnh;
  923         struct vn_hdr *vnh_max;
  924         int count;
  925         struct stat *sb;
  926 };
  927 
  928 typedef struct elf_buf {
  929         char    *buf;
  930         size_t  off;
  931         size_t  off_max;
  932 } *elf_buf_t;
  933 
  934 static void *target_reserve(elf_buf_t target, size_t bytes, int *error);
  935 
  936 static int cb_put_phdr (vm_map_entry_t, void *);
  937 static int cb_size_segment (vm_map_entry_t, void *);
  938 static int cb_fpcount_segment(vm_map_entry_t, void *);
  939 static int cb_put_fp(vm_map_entry_t, void *);
  940 
  941 
  942 static int each_segment (struct proc *, segment_callback, void *, int);
  943 static int __elfN(corehdr)(struct lwp *, int, struct file *, struct ucred *,
  944                         int, elf_buf_t);
  945 enum putmode { WRITE, DRYRUN };
  946 static int __elfN(puthdr)(struct lwp *, elf_buf_t, int sig, enum putmode,
  947                         int, struct file *);
  948 static int elf_putallnotes(struct lwp *, elf_buf_t, int, enum putmode);
  949 static int __elfN(putnote)(elf_buf_t, const char *, int, const void *, size_t);
  950 
  951 static int elf_putsigs(struct lwp *, elf_buf_t);
  952 static int elf_puttextvp(struct proc *, elf_buf_t);
  953 static int elf_putfiles(struct proc *, elf_buf_t, struct file *);
  954 
  955 int
  956 __elfN(coredump)(struct lwp *lp, int sig, struct vnode *vp, off_t limit)
  957 {
  958         struct file *fp; 
  959         int error;
  960 
  961         if ((error = falloc(NULL, &fp, NULL)) != 0)
  962                 return (error);
  963         fsetcred(fp, lp->lwp_proc->p_ucred);
  964 
  965         /*
  966          * XXX fixme.
  967          */
  968         fp->f_type = DTYPE_VNODE;
  969         fp->f_flag = O_CREAT|O_WRONLY|O_NOFOLLOW;
  970         fp->f_ops = &vnode_fileops;
  971         fp->f_data = vp;
  972         
  973         error = generic_elf_coredump(lp, sig, fp, limit);
  974 
  975         fp->f_type = 0;
  976         fp->f_flag = 0;
  977         fp->f_ops = &badfileops;
  978         fp->f_data = NULL;
  979         fdrop(fp);
  980         return (error);
  981 }
  982 
  983 int
  984 generic_elf_coredump(struct lwp *lp, int sig, struct file *fp, off_t limit)
  985 {
  986         struct proc *p = lp->lwp_proc;
  987         struct ucred *cred = p->p_ucred;
  988         int error = 0;
  989         struct sseg_closure seginfo;
  990         struct elf_buf target;
  991 
  992         if (!fp)
  993                 kprintf("can't dump core - null fp\n");
  994 
  995         /*
  996          * Size the program segments
  997          */
  998         seginfo.count = 0;
  999         seginfo.vsize = 0;
 1000         each_segment(p, cb_size_segment, &seginfo, 1);
 1001 
 1002         /*
 1003          * Calculate the size of the core file header area by making
 1004          * a dry run of generating it.  Nothing is written, but the
 1005          * size is calculated.
 1006          */
 1007         bzero(&target, sizeof(target));
 1008         __elfN(puthdr)(lp, &target, sig, DRYRUN, seginfo.count, fp);
 1009 
 1010         if (target.off + seginfo.vsize >= limit)
 1011                 return (EFAULT);
 1012 
 1013         /*
 1014          * Allocate memory for building the header, fill it up,
 1015          * and write it out.
 1016          */
 1017         target.off_max = target.off;
 1018         target.off = 0;
 1019         target.buf = kmalloc(target.off_max, M_TEMP, M_WAITOK|M_ZERO);
 1020 
 1021         error = __elfN(corehdr)(lp, sig, fp, cred, seginfo.count, &target);
 1022 
 1023         /* Write the contents of all of the writable segments. */
 1024         if (error == 0) {
 1025                 Elf_Phdr *php;
 1026                 int i;
 1027                 ssize_t nbytes;
 1028 
 1029                 php = (Elf_Phdr *)(target.buf + sizeof(Elf_Ehdr)) + 1;
 1030                 for (i = 0; i < seginfo.count; i++) {
 1031                         error = fp_write(fp, (caddr_t)php->p_vaddr,
 1032                                         php->p_filesz, &nbytes, UIO_USERSPACE);
 1033                         if (error != 0)
 1034                                 break;
 1035                         php++;
 1036                 }
 1037         }
 1038         kfree(target.buf, M_TEMP);
 1039         
 1040         return (error);
 1041 }
 1042 
 1043 /*
 1044  * A callback for each_segment() to write out the segment's
 1045  * program header entry.
 1046  */
 1047 static int
 1048 cb_put_phdr(vm_map_entry_t entry, void *closure)
 1049 {
 1050         struct phdr_closure *phc = closure;
 1051         Elf_Phdr *phdr = phc->phdr;
 1052 
 1053         if (phc->phdr == phc->phdr_max)
 1054                 return (EINVAL);
 1055 
 1056         phc->offset = round_page(phc->offset);
 1057 
 1058         phdr->p_type = PT_LOAD;
 1059         phdr->p_offset = phc->offset;
 1060         phdr->p_vaddr = entry->start;
 1061         phdr->p_paddr = 0;
 1062         phdr->p_filesz = phdr->p_memsz = entry->end - entry->start;
 1063         phdr->p_align = PAGE_SIZE;
 1064         phdr->p_flags = __elfN(untrans_prot)(entry->protection);
 1065 
 1066         phc->offset += phdr->p_filesz;
 1067         ++phc->phdr;
 1068         return (0);
 1069 }
 1070 
 1071 /*
 1072  * A callback for each_writable_segment() to gather information about
 1073  * the number of segments and their total size.
 1074  */
 1075 static int
 1076 cb_size_segment(vm_map_entry_t entry, void *closure)
 1077 {
 1078         struct sseg_closure *ssc = closure;
 1079 
 1080         ++ssc->count;
 1081         ssc->vsize += entry->end - entry->start;
 1082         return (0);
 1083 }
 1084 
 1085 /*
 1086  * A callback for each_segment() to gather information about
 1087  * the number of text segments.
 1088  */
 1089 static int
 1090 cb_fpcount_segment(vm_map_entry_t entry, void *closure)
 1091 {
 1092         int *count = closure;
 1093         struct vnode *vp;
 1094 
 1095         if (entry->object.vm_object->type == OBJT_VNODE) {
 1096                 vp = (struct vnode *)entry->object.vm_object->handle;
 1097                 if ((vp->v_flag & VCKPT) && curproc->p_textvp == vp)
 1098                         return (0);
 1099                 ++*count;
 1100         }
 1101         return (0);
 1102 }
 1103 
 1104 static int
 1105 cb_put_fp(vm_map_entry_t entry, void *closure) 
 1106 {
 1107         struct fp_closure *fpc = closure;
 1108         struct vn_hdr *vnh = fpc->vnh;
 1109         Elf_Phdr *phdr = &vnh->vnh_phdr;
 1110         struct vnode *vp;
 1111         int error;
 1112 
 1113         /*
 1114          * If an entry represents a vnode then write out a file handle.
 1115          *
 1116          * If we are checkpointing a checkpoint-restored program we do
 1117          * NOT record the filehandle for the old checkpoint vnode (which
 1118          * is mapped all over the place).  Instead we rely on the fact
 1119          * that a checkpoint-restored program does not mmap() the checkpt
 1120          * vnode NOCORE, so its contents will be written out to the
 1121          * new checkpoint file.  This is necessary because the 'old'
 1122          * checkpoint file is typically destroyed when a new one is created
 1123          * and thus cannot be used to restore the new checkpoint.
 1124          *
 1125          * Theoretically we could create a chain of checkpoint files and
 1126          * operate the checkpointing operation kinda like an incremental
 1127          * checkpoint, but a checkpoint restore would then likely wind up
 1128          * referencing many prior checkpoint files and that is a bit over
 1129          * the top for the purpose of the checkpoint API.
 1130          */
 1131         if (entry->object.vm_object->type == OBJT_VNODE) {
 1132                 vp = (struct vnode *)entry->object.vm_object->handle;
 1133                 if ((vp->v_flag & VCKPT) && curproc->p_textvp == vp)
 1134                         return (0);
 1135                 if (vnh == fpc->vnh_max)
 1136                         return (EINVAL);
 1137 
 1138                 if (vp->v_mount)
 1139                         vnh->vnh_fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
 1140                 error = VFS_VPTOFH(vp, &vnh->vnh_fh.fh_fid);
 1141                 if (error) {
 1142                         char *freepath, *fullpath;
 1143 
 1144                         if (vn_fullpath(curproc, vp, &fullpath, &freepath, 0)) {
 1145                                 kprintf("Warning: coredump, error %d: cannot store file handle for vnode %p\n", error, vp);
 1146                         } else {
 1147                                 kprintf("Warning: coredump, error %d: cannot store file handle for %s\n", error, fullpath);
 1148                                 kfree(freepath, M_TEMP);
 1149                         }
 1150                         error = 0;
 1151                 }
 1152 
 1153                 phdr->p_type = PT_LOAD;
 1154                 phdr->p_offset = 0;        /* not written to core */
 1155                 phdr->p_vaddr = entry->start;
 1156                 phdr->p_paddr = 0;
 1157                 phdr->p_filesz = phdr->p_memsz = entry->end - entry->start;
 1158                 phdr->p_align = PAGE_SIZE;
 1159                 phdr->p_flags = 0;
 1160                 if (entry->protection & VM_PROT_READ)
 1161                         phdr->p_flags |= PF_R;
 1162                 if (entry->protection & VM_PROT_WRITE)
 1163                         phdr->p_flags |= PF_W;
 1164                 if (entry->protection & VM_PROT_EXECUTE)
 1165                         phdr->p_flags |= PF_X;
 1166                 ++fpc->vnh;
 1167                 ++fpc->count;
 1168         }
 1169         return (0);
 1170 }
 1171 
 1172 /*
 1173  * For each writable segment in the process's memory map, call the given
 1174  * function with a pointer to the map entry and some arbitrary
 1175  * caller-supplied data.
 1176  */
 1177 static int
 1178 each_segment(struct proc *p, segment_callback func, void *closure, int writable)
 1179 {
 1180         int error = 0;
 1181         vm_map_t map = &p->p_vmspace->vm_map;
 1182         vm_map_entry_t entry;
 1183 
 1184         for (entry = map->header.next; error == 0 && entry != &map->header;
 1185             entry = entry->next) {
 1186                 vm_object_t obj;
 1187                 vm_object_t lobj;
 1188                 vm_object_t tobj;
 1189 
 1190                 /*
 1191                  * Don't dump inaccessible mappings, deal with legacy
 1192                  * coredump mode.
 1193                  *
 1194                  * Note that read-only segments related to the elf binary
 1195                  * are marked MAP_ENTRY_NOCOREDUMP now so we no longer
 1196                  * need to arbitrarily ignore such segments.
 1197                  */
 1198                 if (elf_legacy_coredump) {
 1199                         if (writable && (entry->protection & VM_PROT_RW) != VM_PROT_RW)
 1200                                 continue;
 1201                 } else {
 1202                         if (writable && (entry->protection & VM_PROT_ALL) == 0)
 1203                                 continue;
 1204                 }
 1205 
 1206                 /*
 1207                  * Dont include memory segment in the coredump if
 1208                  * MAP_NOCORE is set in mmap(2) or MADV_NOCORE in
 1209                  * madvise(2).
 1210                  *
 1211                  * Currently we only dump normal VM object maps.  We do
 1212                  * not dump submaps or virtual page tables.
 1213                  */
 1214                 if (writable && (entry->eflags & MAP_ENTRY_NOCOREDUMP))
 1215                         continue;
 1216                 if (entry->maptype != VM_MAPTYPE_NORMAL)
 1217                         continue;
 1218                 if ((obj = entry->object.vm_object) == NULL)
 1219                         continue;
 1220 
 1221                 /*
 1222                  * Find the bottom-most object, leaving the base object
 1223                  * and the bottom-most object held (but only one hold
 1224                  * if they happen to be the same).
 1225                  */
 1226                 vm_object_hold_shared(obj);
 1227 
 1228                 lobj = obj;
 1229                 while (lobj && (tobj = lobj->backing_object) != NULL) {
 1230                         KKASSERT(tobj != obj);
 1231                         vm_object_hold_shared(tobj);
 1232                         if (tobj == lobj->backing_object) {
 1233                                 if (lobj != obj) {
 1234                                         vm_object_lock_swap();
 1235                                         vm_object_drop(lobj);
 1236                                 }
 1237                                 lobj = tobj;
 1238                         } else {
 1239                                 vm_object_drop(tobj);
 1240                         }
 1241                 }
 1242 
 1243                 /*
 1244                  * The callback only applies to default, swap, or vnode
 1245                  * objects.  Other types of objects such as memory-mapped
 1246                  * devices are ignored.
 1247                  */
 1248                 if (lobj->type == OBJT_DEFAULT || lobj->type == OBJT_SWAP ||
 1249                     lobj->type == OBJT_VNODE) {
 1250                         error = (*func)(entry, closure);
 1251                 }
 1252                 if (lobj != obj)
 1253                         vm_object_drop(lobj);
 1254                 vm_object_drop(obj);
 1255         }
 1256         return (error);
 1257 }
 1258 
 1259 static
 1260 void *
 1261 target_reserve(elf_buf_t target, size_t bytes, int *error)
 1262 {
 1263     void *res = NULL;
 1264 
 1265     if (target->buf) {
 1266             if (target->off + bytes > target->off_max)
 1267                     *error = EINVAL;
 1268             else
 1269                     res = target->buf + target->off;
 1270     }
 1271     target->off += bytes;
 1272     return (res);
 1273 }
 1274 
 1275 /*
 1276  * Write the core file header to the file, including padding up to
 1277  * the page boundary.
 1278  */
 1279 static int
 1280 __elfN(corehdr)(struct lwp *lp, int sig, struct file *fp, struct ucred *cred,
 1281             int numsegs, elf_buf_t target)
 1282 {
 1283         int error;
 1284         ssize_t nbytes;
 1285 
 1286         /*
 1287          * Fill in the header.  The fp is passed so we can detect and flag
 1288          * a checkpoint file pointer within the core file itself, because
 1289          * it may not be restored from the same file handle.
 1290          */
 1291         error = __elfN(puthdr)(lp, target, sig, WRITE, numsegs, fp);
 1292 
 1293         /* Write it to the core file. */
 1294         if (error == 0) {
 1295                 error = fp_write(fp, target->buf, target->off, &nbytes,
 1296                                  UIO_SYSSPACE);
 1297         }
 1298         return (error);
 1299 }
 1300 
 1301 static int
 1302 __elfN(puthdr)(struct lwp *lp, elf_buf_t target, int sig, enum putmode mode,
 1303     int numsegs, struct file *fp)
 1304 {
 1305         struct proc *p = lp->lwp_proc;
 1306         int error = 0;
 1307         size_t phoff;
 1308         size_t noteoff;
 1309         size_t notesz;
 1310         Elf_Ehdr *ehdr;
 1311         Elf_Phdr *phdr;
 1312 
 1313         ehdr = target_reserve(target, sizeof(Elf_Ehdr), &error);
 1314 
 1315         phoff = target->off;
 1316         phdr = target_reserve(target, (numsegs + 1) * sizeof(Elf_Phdr), &error);
 1317 
 1318         noteoff = target->off;
 1319         if (error == 0)
 1320                 elf_putallnotes(lp, target, sig, mode);
 1321         notesz = target->off - noteoff;
 1322 
 1323         /*
 1324          * put extra cruft for dumping process state here 
 1325          *  - we really want it be before all the program 
 1326          *    mappings
 1327          *  - we just need to update the offset accordingly
 1328          *    and GDB will be none the wiser.
 1329          */
 1330         if (error == 0)
 1331                 error = elf_puttextvp(p, target);
 1332         if (error == 0)
 1333                 error = elf_putsigs(lp, target);
 1334         if (error == 0)
 1335                 error = elf_putfiles(p, target, fp);
 1336 
 1337         /*
 1338          * Align up to a page boundary for the program segments.  The
 1339          * actual data will be written to the outptu file, not to elf_buf_t,
 1340          * so we do not have to do any further bounds checking.
 1341          */
 1342         target->off = round_page(target->off);
 1343         if (error == 0 && ehdr != NULL) {
 1344                 /*
 1345                  * Fill in the ELF header.
 1346                  */
 1347                 ehdr->e_ident[EI_MAG0] = ELFMAG0;
 1348                 ehdr->e_ident[EI_MAG1] = ELFMAG1;
 1349                 ehdr->e_ident[EI_MAG2] = ELFMAG2;
 1350                 ehdr->e_ident[EI_MAG3] = ELFMAG3;
 1351                 ehdr->e_ident[EI_CLASS] = ELF_CLASS;
 1352                 ehdr->e_ident[EI_DATA] = ELF_DATA;
 1353                 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
 1354                 ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
 1355                 ehdr->e_ident[EI_ABIVERSION] = 0;
 1356                 ehdr->e_ident[EI_PAD] = 0;
 1357                 ehdr->e_type = ET_CORE;
 1358                 ehdr->e_machine = ELF_ARCH;
 1359                 ehdr->e_version = EV_CURRENT;
 1360                 ehdr->e_entry = 0;
 1361                 ehdr->e_phoff = phoff;
 1362                 ehdr->e_flags = 0;
 1363                 ehdr->e_ehsize = sizeof(Elf_Ehdr);
 1364                 ehdr->e_phentsize = sizeof(Elf_Phdr);
 1365                 ehdr->e_phnum = numsegs + 1;
 1366                 ehdr->e_shentsize = sizeof(Elf_Shdr);
 1367                 ehdr->e_shnum = 0;
 1368                 ehdr->e_shstrndx = SHN_UNDEF;
 1369         }
 1370         if (error == 0 && phdr != NULL) {
 1371                 /*
 1372                  * Fill in the program header entries.
 1373                  */
 1374                 struct phdr_closure phc;
 1375 
 1376                 /* The note segement. */
 1377                 phdr->p_type = PT_NOTE;
 1378                 phdr->p_offset = noteoff;
 1379                 phdr->p_vaddr = 0;
 1380                 phdr->p_paddr = 0;
 1381                 phdr->p_filesz = notesz;
 1382                 phdr->p_memsz = 0;
 1383                 phdr->p_flags = 0;
 1384                 phdr->p_align = 0;
 1385                 ++phdr;
 1386 
 1387                 /* All the writable segments from the program. */
 1388                 phc.phdr = phdr;
 1389                 phc.phdr_max = phdr + numsegs;
 1390                 phc.offset = target->off;
 1391                 each_segment(p, cb_put_phdr, &phc, 1);
 1392         }
 1393         return (error);
 1394 }
 1395 
 1396 /*
 1397  * Append core dump notes to target ELF buffer or simply update target size
 1398  * if dryrun selected.
 1399  */
 1400 static int
 1401 elf_putallnotes(struct lwp *corelp, elf_buf_t target, int sig,
 1402     enum putmode mode)
 1403 {
 1404         struct proc *p = corelp->lwp_proc;
 1405         int error;
 1406         struct {
 1407                 prstatus_t status;
 1408                 prfpregset_t fpregs;
 1409                 prpsinfo_t psinfo;
 1410         } *tmpdata;
 1411         prstatus_t *status;
 1412         prfpregset_t *fpregs;
 1413         prpsinfo_t *psinfo;
 1414         struct lwp *lp;
 1415 
 1416         /*
 1417          * Allocate temporary storage for notes on heap to avoid stack overflow.
 1418          */
 1419         if (mode != DRYRUN) {
 1420                 tmpdata = kmalloc(sizeof(*tmpdata), M_TEMP, M_ZERO | M_WAITOK);
 1421                 status = &tmpdata->status;
 1422                 fpregs = &tmpdata->fpregs;
 1423                 psinfo = &tmpdata->psinfo;
 1424         } else {
 1425                 tmpdata = NULL;
 1426                 status = NULL;
 1427                 fpregs = NULL;
 1428                 psinfo = NULL;
 1429         }
 1430 
 1431         /*
 1432          * Append LWP-agnostic note.
 1433          */
 1434         if (mode != DRYRUN) {
 1435                 psinfo->pr_version = PRPSINFO_VERSION;
 1436                 psinfo->pr_psinfosz = sizeof(prpsinfo_t);
 1437                 strlcpy(psinfo->pr_fname, p->p_comm,
 1438                         sizeof(psinfo->pr_fname));
 1439                 /*
 1440                  * XXX - We don't fill in the command line arguments
 1441                  * properly yet.
 1442                  */
 1443                 strlcpy(psinfo->pr_psargs, p->p_comm,
 1444                         sizeof(psinfo->pr_psargs));
 1445         }
 1446         error =
 1447             __elfN(putnote)(target, "CORE", NT_PRPSINFO, psinfo, sizeof *psinfo);
 1448         if (error)
 1449                 goto exit;
 1450 
 1451         /*
 1452          * Append first note for LWP that triggered core so that it is
 1453          * the selected one when the debugger starts.
 1454          */
 1455         if (mode != DRYRUN) {
 1456                 status->pr_version = PRSTATUS_VERSION;
 1457                 status->pr_statussz = sizeof(prstatus_t);
 1458                 status->pr_gregsetsz = sizeof(gregset_t);
 1459                 status->pr_fpregsetsz = sizeof(fpregset_t);
 1460                 status->pr_osreldate = osreldate;
 1461                 status->pr_cursig = sig;
 1462                 /*
 1463                  * XXX GDB needs unique pr_pid for each LWP and does not
 1464                  * not support pr_pid==0 but lwp_tid can be 0, so hack unique
 1465                  * value.
 1466                  */
 1467                 status->pr_pid = corelp->lwp_tid;
 1468                 fill_regs(corelp, &status->pr_reg);
 1469                 fill_fpregs(corelp, fpregs);
 1470         }
 1471         error =
 1472             __elfN(putnote)(target, "CORE", NT_PRSTATUS, status, sizeof *status);
 1473         if (error)
 1474                 goto exit;
 1475         error =
 1476             __elfN(putnote)(target, "CORE", NT_FPREGSET, fpregs, sizeof *fpregs);
 1477         if (error)
 1478                 goto exit;
 1479 
 1480         /*
 1481          * Then append notes for other LWPs.
 1482          */
 1483         FOREACH_LWP_IN_PROC(lp, p) {
 1484                 if (lp == corelp)
 1485                         continue;
 1486                 /* skip lwps being created */
 1487                 if (lp->lwp_thread == NULL)
 1488                         continue;
 1489                 if (mode != DRYRUN) {
 1490                         status->pr_pid = lp->lwp_tid;
 1491                         fill_regs(lp, &status->pr_reg);
 1492                         fill_fpregs(lp, fpregs);
 1493                 }
 1494                 error = __elfN(putnote)(target, "CORE", NT_PRSTATUS,
 1495                                         status, sizeof *status);
 1496                 if (error)
 1497                         goto exit;
 1498                 error = __elfN(putnote)(target, "CORE", NT_FPREGSET,
 1499                                         fpregs, sizeof *fpregs);
 1500                 if (error)
 1501                         goto exit;
 1502         }
 1503 
 1504 exit:
 1505         if (tmpdata != NULL)
 1506                 kfree(tmpdata, M_TEMP);
 1507         return (error);
 1508 }
 1509 
 1510 /*
 1511  * Generate a note sub-structure.
 1512  *
 1513  * NOTE: 4-byte alignment.
 1514  */
 1515 static int
 1516 __elfN(putnote)(elf_buf_t target, const char *name, int type,
 1517             const void *desc, size_t descsz)
 1518 {
 1519         int error = 0;
 1520         char *dst;
 1521         Elf_Note note;
 1522 
 1523         note.n_namesz = strlen(name) + 1;
 1524         note.n_descsz = descsz;
 1525         note.n_type = type;
 1526         dst = target_reserve(target, sizeof(note), &error);
 1527         if (dst != NULL)
 1528                 bcopy(&note, dst, sizeof note);
 1529         dst = target_reserve(target, note.n_namesz, &error);
 1530         if (dst != NULL)
 1531                 bcopy(name, dst, note.n_namesz);
 1532         target->off = roundup2(target->off, sizeof(Elf_Word));
 1533         dst = target_reserve(target, note.n_descsz, &error);
 1534         if (dst != NULL)
 1535                 bcopy(desc, dst, note.n_descsz);
 1536         target->off = roundup2(target->off, sizeof(Elf_Word));
 1537         return (error);
 1538 }
 1539 
 1540 
 1541 static int
 1542 elf_putsigs(struct lwp *lp, elf_buf_t target)
 1543 {
 1544         /* XXX lwp handle more than one lwp */
 1545         struct proc *p = lp->lwp_proc;
 1546         int error = 0;
 1547         struct ckpt_siginfo *csi;
 1548 
 1549         csi = target_reserve(target, sizeof(struct ckpt_siginfo), &error);
 1550         if (csi) {
 1551                 csi->csi_ckptpisz = sizeof(struct ckpt_siginfo);
 1552                 bcopy(p->p_sigacts, &csi->csi_sigacts, sizeof(*p->p_sigacts));
 1553                 bcopy(&p->p_realtimer, &csi->csi_itimerval, sizeof(struct itimerval));
 1554                 bcopy(&lp->lwp_sigmask, &csi->csi_sigmask,
 1555                         sizeof(sigset_t));
 1556                 csi->csi_sigparent = p->p_sigparent;
 1557         }
 1558         return (error);
 1559 }
 1560 
 1561 static int
 1562 elf_putfiles(struct proc *p, elf_buf_t target, struct file *ckfp)
 1563 {
 1564         int error = 0;
 1565         int i;
 1566         struct ckpt_filehdr *cfh = NULL;
 1567         struct ckpt_fileinfo *cfi;
 1568         struct file *fp;        
 1569         struct vnode *vp;
 1570         /*
 1571          * the duplicated loop is gross, but it was the only way
 1572          * to eliminate uninitialized variable warnings 
 1573          */
 1574         cfh = target_reserve(target, sizeof(struct ckpt_filehdr), &error);
 1575         if (cfh) {
 1576                 cfh->cfh_nfiles = 0;            
 1577         }
 1578 
 1579         /*
 1580          * ignore STDIN/STDERR/STDOUT.
 1581          */
 1582         for (i = 3; error == 0 && i < p->p_fd->fd_nfiles; i++) {
 1583                 fp = holdfp(p->p_fd, i, -1);
 1584                 if (fp == NULL)
 1585                         continue;
 1586                 /* 
 1587                  * XXX Only checkpoint vnodes for now.
 1588                  */
 1589                 if (fp->f_type != DTYPE_VNODE) {
 1590                         fdrop(fp);
 1591                         continue;
 1592                 }
 1593                 cfi = target_reserve(target, sizeof(struct ckpt_fileinfo),
 1594                                         &error);
 1595                 if (cfi == NULL) {
 1596                         fdrop(fp);
 1597                         continue;
 1598                 }
 1599                 cfi->cfi_index = -1;
 1600                 cfi->cfi_type = fp->f_type;
 1601                 cfi->cfi_flags = fp->f_flag;
 1602                 cfi->cfi_offset = fp->f_offset;
 1603                 cfi->cfi_ckflags = 0;
 1604 
 1605                 if (fp == ckfp)
 1606                         cfi->cfi_ckflags |= CKFIF_ISCKPTFD;
 1607                 /* f_count and f_msgcount should not be saved/restored */
 1608                 /* XXX save cred info */
 1609 
 1610                 switch(fp->f_type) {
 1611                 case DTYPE_VNODE:
 1612                         vp = (struct vnode *)fp->f_data;
 1613                         /*
 1614                          * it looks like a bug in ptrace is marking 
 1615                          * a non-vnode as a vnode - until we find the 
 1616                          * root cause this will at least prevent
 1617                          * further panics from truss
 1618                          */
 1619                         if (vp == NULL || vp->v_mount == NULL)
 1620                                 break;
 1621                         cfh->cfh_nfiles++;
 1622                         cfi->cfi_index = i;
 1623                         cfi->cfi_fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
 1624                         error = VFS_VPTOFH(vp, &cfi->cfi_fh.fh_fid);
 1625                         break;
 1626                 default:
 1627                         break;
 1628                 }
 1629                 fdrop(fp);
 1630         }
 1631         return (error);
 1632 }
 1633 
 1634 static int
 1635 elf_puttextvp(struct proc *p, elf_buf_t target)
 1636 {
 1637         int error = 0;
 1638         int *vn_count;
 1639         struct fp_closure fpc;
 1640         struct ckpt_vminfo *vminfo;
 1641 
 1642         vminfo = target_reserve(target, sizeof(struct ckpt_vminfo), &error);
 1643         if (vminfo != NULL) {
 1644                 vminfo->cvm_dsize = p->p_vmspace->vm_dsize;
 1645                 vminfo->cvm_tsize = p->p_vmspace->vm_tsize;
 1646                 vminfo->cvm_daddr = p->p_vmspace->vm_daddr;
 1647                 vminfo->cvm_taddr = p->p_vmspace->vm_taddr;
 1648         }
 1649 
 1650         fpc.count = 0;
 1651         vn_count = target_reserve(target, sizeof(int), &error);
 1652         if (target->buf != NULL) {
 1653                 fpc.vnh = (struct vn_hdr *)(target->buf + target->off);
 1654                 fpc.vnh_max = fpc.vnh + 
 1655                         (target->off_max - target->off) / sizeof(struct vn_hdr);
 1656                 error = each_segment(p, cb_put_fp, &fpc, 0);
 1657                 if (vn_count)
 1658                         *vn_count = fpc.count;
 1659         } else {
 1660                 error = each_segment(p, cb_fpcount_segment, &fpc.count, 0);
 1661         }
 1662         target->off += fpc.count * sizeof(struct vn_hdr);
 1663         return (error);
 1664 }
 1665 
 1666 /*
 1667  * Try to find the appropriate ABI-note section for checknote,
 1668  * The entire image is searched if necessary, not only the first page.
 1669  */
 1670 static boolean_t
 1671 __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *checknote,
 1672     int32_t *osrel)
 1673 {
 1674         boolean_t valid_note_found;
 1675         const Elf_Phdr *phdr, *pnote;
 1676         const Elf_Ehdr *hdr;
 1677         int i;
 1678 
 1679         valid_note_found = FALSE;
 1680         hdr = (const Elf_Ehdr *)imgp->image_header;
 1681         phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
 1682 
 1683         for (i = 0; i < hdr->e_phnum; i++) {
 1684                 if (phdr[i].p_type == PT_NOTE) {
 1685                         pnote = &phdr[i];
 1686                         valid_note_found = check_PT_NOTE (imgp, checknote,
 1687                                 osrel, pnote);
 1688                         if (valid_note_found)
 1689                                 break;
 1690                 }
 1691         }
 1692         return valid_note_found;
 1693 }
 1694 
 1695 /*
 1696  * Be careful not to create new overflow conditions when checking
 1697  * for overflow.
 1698  */
 1699 static boolean_t
 1700 note_overflow(const Elf_Note *note, size_t maxsize)
 1701 {
 1702         if (sizeof(*note) > maxsize)
 1703                 return TRUE;
 1704         if (note->n_namesz > maxsize - sizeof(*note))
 1705                 return TRUE;
 1706         return FALSE;
 1707 }
 1708 
 1709 static boolean_t
 1710 hdr_overflow(__ElfN(Off) off_beg, __ElfN(Size) size)
 1711 {
 1712         __ElfN(Off) off_end;
 1713 
 1714         off_end = off_beg + size;
 1715         if (off_end < off_beg)
 1716                 return TRUE;
 1717         return FALSE;
 1718 }
 1719 
 1720 static boolean_t
 1721 check_PT_NOTE(struct image_params *imgp, Elf_Brandnote *checknote,
 1722               int32_t *osrel, const Elf_Phdr * pnote)
 1723 {
 1724         boolean_t limited_to_first_page;
 1725         boolean_t found = FALSE;
 1726         const Elf_Note *note, *note0, *note_end;
 1727         const char *note_name;
 1728         __ElfN(Off) noteloc, firstloc;
 1729         __ElfN(Size) notesz, firstlen, endbyte;
 1730         struct lwbuf *lwb;
 1731         struct lwbuf lwb_cache;
 1732         const char *page;
 1733         char *data = NULL;
 1734         int n;
 1735 
 1736         if (hdr_overflow(pnote->p_offset, pnote->p_filesz))
 1737                 return (FALSE);
 1738         notesz = pnote->p_filesz;
 1739         noteloc = pnote->p_offset;
 1740         endbyte = noteloc + notesz;
 1741         limited_to_first_page = noteloc < PAGE_SIZE && endbyte < PAGE_SIZE;
 1742 
 1743         if (limited_to_first_page) {
 1744                 note = (const Elf_Note *)(imgp->image_header + noteloc);
 1745                 note_end = (const Elf_Note *)(imgp->image_header + endbyte);
 1746                 note0 = note;
 1747         } else {
 1748                 firstloc = noteloc & PAGE_MASK;
 1749                 firstlen = PAGE_SIZE - firstloc;
 1750                 if (notesz < sizeof(Elf_Note) || notesz > PAGE_SIZE)
 1751                         return (FALSE);
 1752 
 1753                 lwb = &lwb_cache;
 1754                 if (exec_map_page(imgp, noteloc >> PAGE_SHIFT, &lwb, &page))
 1755                         return (FALSE);
 1756                 if (firstlen < notesz) {         /* crosses page boundary */
 1757                         data = kmalloc(notesz, M_TEMP, M_WAITOK);
 1758                         bcopy(page + firstloc, data, firstlen);
 1759 
 1760                         exec_unmap_page(lwb);
 1761                         lwb = &lwb_cache;
 1762                         if (exec_map_page(imgp, (noteloc >> PAGE_SHIFT) + 1,
 1763                                 &lwb, &page)) {
 1764                                 kfree(data, M_TEMP);
 1765                                 return (FALSE);
 1766                         }
 1767                         bcopy(page, data + firstlen, notesz - firstlen);
 1768                         note = note0 = (const Elf_Note *)(data);
 1769                         note_end = (const Elf_Note *)(data + notesz);
 1770                 } else {
 1771                         note = note0 = (const Elf_Note *)(page + firstloc);
 1772                         note_end = (const Elf_Note *)(page + firstloc +
 1773                                 firstlen);
 1774                 }
 1775         }
 1776 
 1777         for (n = 0; n < 100 && note >= note0 && note < note_end; n++) {
 1778                 if (!aligned(note, Elf32_Addr))
 1779                         break;
 1780                 if (note_overflow(note, (const char *)note_end -
 1781                                         (const char *)note)) {
 1782                         break;
 1783                 }
 1784                 note_name = (const char *)(note + 1);
 1785 
 1786                 if (note->n_namesz == checknote->hdr.n_namesz
 1787                     && note->n_descsz == checknote->hdr.n_descsz
 1788                     && note->n_type == checknote->hdr.n_type
 1789                     && (strncmp(checknote->vendor, note_name,
 1790                         checknote->hdr.n_namesz) == 0)) {
 1791                         /* Fetch osreldata from ABI.note-tag */
 1792                         if ((checknote->flags & BN_TRANSLATE_OSREL) != 0 &&
 1793                             checknote->trans_osrel != NULL)
 1794                                 checknote->trans_osrel(note, osrel);
 1795                         found = TRUE;
 1796                         break;
 1797                 }
 1798                 note = (const Elf_Note *)((const char *)(note + 1) +
 1799                     roundup2(note->n_namesz, sizeof(Elf32_Addr)) +
 1800                     roundup2(note->n_descsz, sizeof(Elf32_Addr)));
 1801         }
 1802 
 1803         if (!limited_to_first_page) {
 1804                 if (data != NULL)
 1805                         kfree(data, M_TEMP);
 1806                 exec_unmap_page(lwb);
 1807         }
 1808         return (found);
 1809 }
 1810 
 1811 /*
 1812  * The interpreter program header may be located beyond the first page, so
 1813  * regardless of its location, a copy of the interpreter path is created so
 1814  * that it may be safely referenced by the calling function in all case.  The
 1815  * memory is allocated by calling function, and the copying is done here.
 1816  */
 1817 static boolean_t
 1818 extract_interpreter(struct image_params *imgp, const Elf_Phdr *pinterpreter,
 1819                     char *data)
 1820 {
 1821         boolean_t limited_to_first_page;
 1822         const boolean_t result_success = FALSE;
 1823         const boolean_t result_failure = TRUE;
 1824         __ElfN(Off) pathloc, firstloc;
 1825         __ElfN(Size) pathsz, firstlen, endbyte;
 1826         struct lwbuf *lwb;
 1827         struct lwbuf lwb_cache;
 1828         const char *page;
 1829 
 1830         if (hdr_overflow(pinterpreter->p_offset, pinterpreter->p_filesz))
 1831                 return (result_failure);
 1832         pathsz  = pinterpreter->p_filesz;
 1833         pathloc = pinterpreter->p_offset;
 1834         endbyte = pathloc + pathsz;
 1835 
 1836         limited_to_first_page = pathloc < PAGE_SIZE && endbyte < PAGE_SIZE;
 1837         if (limited_to_first_page) {
 1838                 bcopy(imgp->image_header + pathloc, data, pathsz);
 1839                 return (result_success);
 1840         }
 1841 
 1842         firstloc = pathloc & PAGE_MASK;
 1843         firstlen = PAGE_SIZE - firstloc;
 1844 
 1845         lwb = &lwb_cache;
 1846         if (exec_map_page(imgp, pathloc >> PAGE_SHIFT, &lwb, &page))
 1847                 return (result_failure);
 1848 
 1849         if (firstlen < pathsz) {         /* crosses page boundary */
 1850                 bcopy(page + firstloc, data, firstlen);
 1851 
 1852                 exec_unmap_page(lwb);
 1853                 lwb = &lwb_cache;
 1854                 if (exec_map_page(imgp, (pathloc >> PAGE_SHIFT) + 1, &lwb,
 1855                         &page))
 1856                         return (result_failure);
 1857                 bcopy(page, data + firstlen, pathsz - firstlen);
 1858         } else
 1859                 bcopy(page + firstloc, data, pathsz);
 1860 
 1861         exec_unmap_page(lwb);
 1862         return (result_success);
 1863 }
 1864 
 1865 static boolean_t
 1866 __elfN(bsd_trans_osrel)(const Elf_Note *note, int32_t *osrel)
 1867 {
 1868         uintptr_t p;
 1869 
 1870         p = (uintptr_t)(note + 1);
 1871         p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
 1872         *osrel = *(const int32_t *)(p);
 1873 
 1874         return (TRUE);
 1875 }
 1876 
 1877 /*
 1878  * Tell kern_execve.c about it, with a little help from the linker.
 1879  */
 1880 #if defined(__x86_64__)
 1881 static struct execsw elf_execsw = {exec_elf64_imgact, "ELF64"};
 1882 EXEC_SET_ORDERED(elf64, elf_execsw, SI_ORDER_FIRST);
 1883 #else /* i386 assumed */
 1884 static struct execsw elf_execsw = {exec_elf32_imgact, "ELF32"};
 1885 EXEC_SET_ORDERED(elf32, elf_execsw, SI_ORDER_FIRST);
 1886 #endif
 1887 
 1888 static vm_prot_t
 1889 __elfN(trans_prot)(Elf_Word flags)
 1890 {
 1891         vm_prot_t prot;
 1892 
 1893         prot = 0;
 1894         if (flags & PF_X)
 1895                 prot |= VM_PROT_EXECUTE;
 1896         if (flags & PF_W)
 1897                 prot |= VM_PROT_WRITE;
 1898         if (flags & PF_R)
 1899                 prot |= VM_PROT_READ;
 1900         return (prot);
 1901 }
 1902 
 1903 static Elf_Word
 1904 __elfN(untrans_prot)(vm_prot_t prot)
 1905 {
 1906         Elf_Word flags;
 1907 
 1908         flags = 0;
 1909         if (prot & VM_PROT_EXECUTE)
 1910                 flags |= PF_X;
 1911         if (prot & VM_PROT_READ)
 1912                 flags |= PF_R;
 1913         if (prot & VM_PROT_WRITE)
 1914                 flags |= PF_W;
 1915         return (flags);
 1916 }

Cache object: bbc0677d8cf4ea43d435329daa52cf94


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