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 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD: releng/8.2/sys/kern/imgact_elf.c 206336 2010-04-07 02:24:41Z nwhitehorn $");
   33 
   34 #include "opt_compat.h"
   35 
   36 #include <sys/param.h>
   37 #include <sys/exec.h>
   38 #include <sys/fcntl.h>
   39 #include <sys/imgact.h>
   40 #include <sys/imgact_elf.h>
   41 #include <sys/kernel.h>
   42 #include <sys/lock.h>
   43 #include <sys/malloc.h>
   44 #include <sys/mount.h>
   45 #include <sys/mutex.h>
   46 #include <sys/mman.h>
   47 #include <sys/namei.h>
   48 #include <sys/pioctl.h>
   49 #include <sys/proc.h>
   50 #include <sys/procfs.h>
   51 #include <sys/resourcevar.h>
   52 #include <sys/sf_buf.h>
   53 #include <sys/systm.h>
   54 #include <sys/signalvar.h>
   55 #include <sys/stat.h>
   56 #include <sys/sx.h>
   57 #include <sys/syscall.h>
   58 #include <sys/sysctl.h>
   59 #include <sys/sysent.h>
   60 #include <sys/vnode.h>
   61 
   62 #include <vm/vm.h>
   63 #include <vm/vm_kern.h>
   64 #include <vm/vm_param.h>
   65 #include <vm/pmap.h>
   66 #include <vm/vm_map.h>
   67 #include <vm/vm_object.h>
   68 #include <vm/vm_extern.h>
   69 
   70 #include <machine/elf.h>
   71 #include <machine/md_var.h>
   72 
   73 #define OLD_EI_BRAND    8
   74 
   75 static int __elfN(check_header)(const Elf_Ehdr *hdr);
   76 static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp,
   77     const char *interp, int32_t *osrel);
   78 static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
   79     u_long *entry, size_t pagesize);
   80 static int __elfN(load_section)(struct vmspace *vmspace, vm_object_t object,
   81     vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz,
   82     vm_prot_t prot, size_t pagesize);
   83 static int __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp);
   84 static boolean_t __elfN(freebsd_trans_osrel)(const Elf_Note *note,
   85     int32_t *osrel);
   86 static boolean_t kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel);
   87 static boolean_t __elfN(check_note)(struct image_params *imgp,
   88     Elf_Brandnote *checknote, int32_t *osrel);
   89 
   90 SYSCTL_NODE(_kern, OID_AUTO, __CONCAT(elf, __ELF_WORD_SIZE), CTLFLAG_RW, 0,
   91     "");
   92 
   93 int __elfN(fallback_brand) = -1;
   94 SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO,
   95     fallback_brand, CTLFLAG_RW, &__elfN(fallback_brand), 0,
   96     __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) " brand of last resort");
   97 TUNABLE_INT("kern.elf" __XSTRING(__ELF_WORD_SIZE) ".fallback_brand",
   98     &__elfN(fallback_brand));
   99 
  100 static int elf_legacy_coredump = 0;
  101 SYSCTL_INT(_debug, OID_AUTO, __elfN(legacy_coredump), CTLFLAG_RW, 
  102     &elf_legacy_coredump, 0, "");
  103 
  104 static Elf_Brandinfo *elf_brand_list[MAX_BRANDS];
  105 
  106 #define trunc_page_ps(va, ps)   ((va) & ~(ps - 1))
  107 #define round_page_ps(va, ps)   (((va) + (ps - 1)) & ~(ps - 1))
  108 #define aligned(a, t)   (trunc_page_ps((u_long)(a), sizeof(t)) == (u_long)(a))
  109 
  110 static const char FREEBSD_ABI_VENDOR[] = "FreeBSD";
  111 
  112 Elf_Brandnote __elfN(freebsd_brandnote) = {
  113         .hdr.n_namesz   = sizeof(FREEBSD_ABI_VENDOR),
  114         .hdr.n_descsz   = sizeof(int32_t),
  115         .hdr.n_type     = 1,
  116         .vendor         = FREEBSD_ABI_VENDOR,
  117         .flags          = BN_TRANSLATE_OSREL,
  118         .trans_osrel    = __elfN(freebsd_trans_osrel)
  119 };
  120 
  121 static boolean_t
  122 __elfN(freebsd_trans_osrel)(const Elf_Note *note, int32_t *osrel)
  123 {
  124         uintptr_t p;
  125 
  126         p = (uintptr_t)(note + 1);
  127         p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
  128         *osrel = *(const int32_t *)(p);
  129 
  130         return (TRUE);
  131 }
  132 
  133 static const char GNU_ABI_VENDOR[] = "GNU";
  134 static int GNU_KFREEBSD_ABI_DESC = 3;
  135 
  136 Elf_Brandnote __elfN(kfreebsd_brandnote) = {
  137         .hdr.n_namesz   = sizeof(GNU_ABI_VENDOR),
  138         .hdr.n_descsz   = 16,   /* XXX at least 16 */
  139         .hdr.n_type     = 1,
  140         .vendor         = GNU_ABI_VENDOR,
  141         .flags          = BN_TRANSLATE_OSREL,
  142         .trans_osrel    = kfreebsd_trans_osrel
  143 };
  144 
  145 static boolean_t
  146 kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel)
  147 {
  148         const Elf32_Word *desc;
  149         uintptr_t p;
  150 
  151         p = (uintptr_t)(note + 1);
  152         p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
  153 
  154         desc = (const Elf32_Word *)p;
  155         if (desc[0] != GNU_KFREEBSD_ABI_DESC)
  156                 return (FALSE);
  157 
  158         /*
  159          * Debian GNU/kFreeBSD embed the earliest compatible kernel version
  160          * (__FreeBSD_version: <major><two digit minor>Rxx) in the LSB way.
  161          */
  162         *osrel = desc[1] * 100000 + desc[2] * 1000 + desc[3];
  163 
  164         return (TRUE);
  165 }
  166 
  167 int
  168 __elfN(insert_brand_entry)(Elf_Brandinfo *entry)
  169 {
  170         int i;
  171 
  172         for (i = 0; i < MAX_BRANDS; i++) {
  173                 if (elf_brand_list[i] == NULL) {
  174                         elf_brand_list[i] = entry;
  175                         break;
  176                 }
  177         }
  178         if (i == MAX_BRANDS) {
  179                 printf("WARNING: %s: could not insert brandinfo entry: %p\n",
  180                         __func__, entry);
  181                 return (-1);
  182         }
  183         return (0);
  184 }
  185 
  186 int
  187 __elfN(remove_brand_entry)(Elf_Brandinfo *entry)
  188 {
  189         int i;
  190 
  191         for (i = 0; i < MAX_BRANDS; i++) {
  192                 if (elf_brand_list[i] == entry) {
  193                         elf_brand_list[i] = NULL;
  194                         break;
  195                 }
  196         }
  197         if (i == MAX_BRANDS)
  198                 return (-1);
  199         return (0);
  200 }
  201 
  202 int
  203 __elfN(brand_inuse)(Elf_Brandinfo *entry)
  204 {
  205         struct proc *p;
  206         int rval = FALSE;
  207 
  208         sx_slock(&allproc_lock);
  209         FOREACH_PROC_IN_SYSTEM(p) {
  210                 if (p->p_sysent == entry->sysvec) {
  211                         rval = TRUE;
  212                         break;
  213                 }
  214         }
  215         sx_sunlock(&allproc_lock);
  216 
  217         return (rval);
  218 }
  219 
  220 static Elf_Brandinfo *
  221 __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
  222     int32_t *osrel)
  223 {
  224         const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
  225         Elf_Brandinfo *bi;
  226         boolean_t ret;
  227         int i;
  228 
  229         /*
  230          * We support four types of branding -- (1) the ELF EI_OSABI field
  231          * that SCO added to the ELF spec, (2) FreeBSD 3.x's traditional string
  232          * branding w/in the ELF header, (3) path of the `interp_path'
  233          * field, and (4) the ".note.ABI-tag" ELF section.
  234          */
  235 
  236         /* Look for an ".note.ABI-tag" ELF section */
  237         for (i = 0; i < MAX_BRANDS; i++) {
  238                 bi = elf_brand_list[i];
  239                 if (bi == NULL)
  240                         continue;
  241                 if (hdr->e_machine == bi->machine && (bi->flags &
  242                     (BI_BRAND_NOTE|BI_BRAND_NOTE_MANDATORY)) != 0) {
  243                         ret = __elfN(check_note)(imgp, bi->brand_note, osrel);
  244                         if (ret)
  245                                 return (bi);
  246                 }
  247         }
  248 
  249         /* If the executable has a brand, search for it in the brand list. */
  250         for (i = 0; i < MAX_BRANDS; i++) {
  251                 bi = elf_brand_list[i];
  252                 if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY)
  253                         continue;
  254                 if (hdr->e_machine == bi->machine &&
  255                     (hdr->e_ident[EI_OSABI] == bi->brand ||
  256                     strncmp((const char *)&hdr->e_ident[OLD_EI_BRAND],
  257                     bi->compat_3_brand, strlen(bi->compat_3_brand)) == 0))
  258                         return (bi);
  259         }
  260 
  261         /* Lacking a known brand, search for a recognized interpreter. */
  262         if (interp != NULL) {
  263                 for (i = 0; i < MAX_BRANDS; i++) {
  264                         bi = elf_brand_list[i];
  265                         if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY)
  266                                 continue;
  267                         if (hdr->e_machine == bi->machine &&
  268                             strcmp(interp, bi->interp_path) == 0)
  269                                 return (bi);
  270                 }
  271         }
  272 
  273         /* Lacking a recognized interpreter, try the default brand */
  274         for (i = 0; i < MAX_BRANDS; i++) {
  275                 bi = elf_brand_list[i];
  276                 if (bi == NULL || bi->flags & BI_BRAND_NOTE_MANDATORY)
  277                         continue;
  278                 if (hdr->e_machine == bi->machine &&
  279                     __elfN(fallback_brand) == bi->brand)
  280                         return (bi);
  281         }
  282         return (NULL);
  283 }
  284 
  285 static int
  286 __elfN(check_header)(const Elf_Ehdr *hdr)
  287 {
  288         Elf_Brandinfo *bi;
  289         int i;
  290 
  291         if (!IS_ELF(*hdr) ||
  292             hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
  293             hdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
  294             hdr->e_ident[EI_VERSION] != EV_CURRENT ||
  295             hdr->e_phentsize != sizeof(Elf_Phdr) ||
  296             hdr->e_version != ELF_TARG_VER)
  297                 return (ENOEXEC);
  298 
  299         /*
  300          * Make sure we have at least one brand for this machine.
  301          */
  302 
  303         for (i = 0; i < MAX_BRANDS; i++) {
  304                 bi = elf_brand_list[i];
  305                 if (bi != NULL && bi->machine == hdr->e_machine)
  306                         break;
  307         }
  308         if (i == MAX_BRANDS)
  309                 return (ENOEXEC);
  310 
  311         return (0);
  312 }
  313 
  314 static int
  315 __elfN(map_partial)(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
  316     vm_offset_t start, vm_offset_t end, vm_prot_t prot)
  317 {
  318         struct sf_buf *sf;
  319         int error;
  320         vm_offset_t off;
  321 
  322         /*
  323          * Create the page if it doesn't exist yet. Ignore errors.
  324          */
  325         vm_map_lock(map);
  326         vm_map_insert(map, NULL, 0, trunc_page(start), round_page(end),
  327             VM_PROT_ALL, VM_PROT_ALL, 0);
  328         vm_map_unlock(map);
  329 
  330         /*
  331          * Find the page from the underlying object.
  332          */
  333         if (object) {
  334                 sf = vm_imgact_map_page(object, offset);
  335                 if (sf == NULL)
  336                         return (KERN_FAILURE);
  337                 off = offset - trunc_page(offset);
  338                 error = copyout((caddr_t)sf_buf_kva(sf) + off, (caddr_t)start,
  339                     end - start);
  340                 vm_imgact_unmap_page(sf);
  341                 if (error) {
  342                         return (KERN_FAILURE);
  343                 }
  344         }
  345 
  346         return (KERN_SUCCESS);
  347 }
  348 
  349 static int
  350 __elfN(map_insert)(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
  351     vm_offset_t start, vm_offset_t end, vm_prot_t prot, int cow)
  352 {
  353         struct sf_buf *sf;
  354         vm_offset_t off;
  355         vm_size_t sz;
  356         int error, rv;
  357 
  358         if (start != trunc_page(start)) {
  359                 rv = __elfN(map_partial)(map, object, offset, start,
  360                     round_page(start), prot);
  361                 if (rv)
  362                         return (rv);
  363                 offset += round_page(start) - start;
  364                 start = round_page(start);
  365         }
  366         if (end != round_page(end)) {
  367                 rv = __elfN(map_partial)(map, object, offset +
  368                     trunc_page(end) - start, trunc_page(end), end, prot);
  369                 if (rv)
  370                         return (rv);
  371                 end = trunc_page(end);
  372         }
  373         if (end > start) {
  374                 if (offset & PAGE_MASK) {
  375                         /*
  376                          * The mapping is not page aligned. This means we have
  377                          * to copy the data. Sigh.
  378                          */
  379                         rv = vm_map_find(map, NULL, 0, &start, end - start,
  380                             FALSE, prot | VM_PROT_WRITE, VM_PROT_ALL, 0);
  381                         if (rv)
  382                                 return (rv);
  383                         if (object == NULL)
  384                                 return (KERN_SUCCESS);
  385                         for (; start < end; start += sz) {
  386                                 sf = vm_imgact_map_page(object, offset);
  387                                 if (sf == NULL)
  388                                         return (KERN_FAILURE);
  389                                 off = offset - trunc_page(offset);
  390                                 sz = end - start;
  391                                 if (sz > PAGE_SIZE - off)
  392                                         sz = PAGE_SIZE - off;
  393                                 error = copyout((caddr_t)sf_buf_kva(sf) + off,
  394                                     (caddr_t)start, sz);
  395                                 vm_imgact_unmap_page(sf);
  396                                 if (error) {
  397                                         return (KERN_FAILURE);
  398                                 }
  399                                 offset += sz;
  400                         }
  401                         rv = KERN_SUCCESS;
  402                 } else {
  403                         vm_object_reference(object);
  404                         vm_map_lock(map);
  405                         rv = vm_map_insert(map, object, offset, start, end,
  406                             prot, VM_PROT_ALL, cow);
  407                         vm_map_unlock(map);
  408                         if (rv != KERN_SUCCESS)
  409                                 vm_object_deallocate(object);
  410                 }
  411                 return (rv);
  412         } else {
  413                 return (KERN_SUCCESS);
  414         }
  415 }
  416 
  417 static int
  418 __elfN(load_section)(struct vmspace *vmspace,
  419         vm_object_t object, vm_offset_t offset,
  420         caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot,
  421         size_t pagesize)
  422 {
  423         struct sf_buf *sf;
  424         size_t map_len;
  425         vm_offset_t map_addr;
  426         int error, rv, cow;
  427         size_t copy_len;
  428         vm_offset_t file_addr;
  429 
  430         /*
  431          * It's necessary to fail if the filsz + offset taken from the
  432          * header is greater than the actual file pager object's size.
  433          * If we were to allow this, then the vm_map_find() below would
  434          * walk right off the end of the file object and into the ether.
  435          *
  436          * While I'm here, might as well check for something else that
  437          * is invalid: filsz cannot be greater than memsz.
  438          */
  439         if ((off_t)filsz + offset > object->un_pager.vnp.vnp_size ||
  440             filsz > memsz) {
  441                 uprintf("elf_load_section: truncated ELF file\n");
  442                 return (ENOEXEC);
  443         }
  444 
  445         map_addr = trunc_page_ps((vm_offset_t)vmaddr, pagesize);
  446         file_addr = trunc_page_ps(offset, pagesize);
  447 
  448         /*
  449          * We have two choices.  We can either clear the data in the last page
  450          * of an oversized mapping, or we can start the anon mapping a page
  451          * early and copy the initialized data into that first page.  We
  452          * choose the second..
  453          */
  454         if (memsz > filsz)
  455                 map_len = trunc_page_ps(offset + filsz, pagesize) - file_addr;
  456         else
  457                 map_len = round_page_ps(offset + filsz, pagesize) - file_addr;
  458 
  459         if (map_len != 0) {
  460                 /* cow flags: don't dump readonly sections in core */
  461                 cow = MAP_COPY_ON_WRITE | MAP_PREFAULT |
  462                     (prot & VM_PROT_WRITE ? 0 : MAP_DISABLE_COREDUMP);
  463 
  464                 rv = __elfN(map_insert)(&vmspace->vm_map,
  465                                       object,
  466                                       file_addr,        /* file offset */
  467                                       map_addr,         /* virtual start */
  468                                       map_addr + map_len,/* virtual end */
  469                                       prot,
  470                                       cow);
  471                 if (rv != KERN_SUCCESS)
  472                         return (EINVAL);
  473 
  474                 /* we can stop now if we've covered it all */
  475                 if (memsz == filsz) {
  476                         return (0);
  477                 }
  478         }
  479 
  480 
  481         /*
  482          * We have to get the remaining bit of the file into the first part
  483          * of the oversized map segment.  This is normally because the .data
  484          * segment in the file is extended to provide bss.  It's a neat idea
  485          * to try and save a page, but it's a pain in the behind to implement.
  486          */
  487         copy_len = (offset + filsz) - trunc_page_ps(offset + filsz, pagesize);
  488         map_addr = trunc_page_ps((vm_offset_t)vmaddr + filsz, pagesize);
  489         map_len = round_page_ps((vm_offset_t)vmaddr + memsz, pagesize) -
  490             map_addr;
  491 
  492         /* This had damn well better be true! */
  493         if (map_len != 0) {
  494                 rv = __elfN(map_insert)(&vmspace->vm_map, NULL, 0, map_addr,
  495                     map_addr + map_len, VM_PROT_ALL, 0);
  496                 if (rv != KERN_SUCCESS) {
  497                         return (EINVAL);
  498                 }
  499         }
  500 
  501         if (copy_len != 0) {
  502                 vm_offset_t off;
  503 
  504                 sf = vm_imgact_map_page(object, offset + filsz);
  505                 if (sf == NULL)
  506                         return (EIO);
  507 
  508                 /* send the page fragment to user space */
  509                 off = trunc_page_ps(offset + filsz, pagesize) -
  510                     trunc_page(offset + filsz);
  511                 error = copyout((caddr_t)sf_buf_kva(sf) + off,
  512                     (caddr_t)map_addr, copy_len);
  513                 vm_imgact_unmap_page(sf);
  514                 if (error) {
  515                         return (error);
  516                 }
  517         }
  518 
  519         /*
  520          * set it to the specified protection.
  521          * XXX had better undo the damage from pasting over the cracks here!
  522          */
  523         vm_map_protect(&vmspace->vm_map, trunc_page(map_addr),
  524             round_page(map_addr + map_len),  prot, FALSE);
  525 
  526         return (0);
  527 }
  528 
  529 /*
  530  * Load the file "file" into memory.  It may be either a shared object
  531  * or an executable.
  532  *
  533  * The "addr" reference parameter is in/out.  On entry, it specifies
  534  * the address where a shared object should be loaded.  If the file is
  535  * an executable, this value is ignored.  On exit, "addr" specifies
  536  * where the file was actually loaded.
  537  *
  538  * The "entry" reference parameter is out only.  On exit, it specifies
  539  * the entry point for the loaded file.
  540  */
  541 static int
  542 __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
  543         u_long *entry, size_t pagesize)
  544 {
  545         struct {
  546                 struct nameidata nd;
  547                 struct vattr attr;
  548                 struct image_params image_params;
  549         } *tempdata;
  550         const Elf_Ehdr *hdr = NULL;
  551         const Elf_Phdr *phdr = NULL;
  552         struct nameidata *nd;
  553         struct vmspace *vmspace = p->p_vmspace;
  554         struct vattr *attr;
  555         struct image_params *imgp;
  556         vm_prot_t prot;
  557         u_long rbase;
  558         u_long base_addr = 0;
  559         int vfslocked, error, i, numsegs;
  560 
  561         tempdata = malloc(sizeof(*tempdata), M_TEMP, M_WAITOK);
  562         nd = &tempdata->nd;
  563         attr = &tempdata->attr;
  564         imgp = &tempdata->image_params;
  565 
  566         /*
  567          * Initialize part of the common data
  568          */
  569         imgp->proc = p;
  570         imgp->attr = attr;
  571         imgp->firstpage = NULL;
  572         imgp->image_header = NULL;
  573         imgp->object = NULL;
  574         imgp->execlabel = NULL;
  575 
  576         NDINIT(nd, LOOKUP, MPSAFE|LOCKLEAF|FOLLOW, UIO_SYSSPACE, file,
  577             curthread);
  578         vfslocked = 0;
  579         if ((error = namei(nd)) != 0) {
  580                 nd->ni_vp = NULL;
  581                 goto fail;
  582         }
  583         vfslocked = NDHASGIANT(nd);
  584         NDFREE(nd, NDF_ONLY_PNBUF);
  585         imgp->vp = nd->ni_vp;
  586 
  587         /*
  588          * Check permissions, modes, uid, etc on the file, and "open" it.
  589          */
  590         error = exec_check_permissions(imgp);
  591         if (error)
  592                 goto fail;
  593 
  594         error = exec_map_first_page(imgp);
  595         if (error)
  596                 goto fail;
  597 
  598         /*
  599          * Also make certain that the interpreter stays the same, so set
  600          * its VV_TEXT flag, too.
  601          */
  602         nd->ni_vp->v_vflag |= VV_TEXT;
  603 
  604         imgp->object = nd->ni_vp->v_object;
  605 
  606         hdr = (const Elf_Ehdr *)imgp->image_header;
  607         if ((error = __elfN(check_header)(hdr)) != 0)
  608                 goto fail;
  609         if (hdr->e_type == ET_DYN)
  610                 rbase = *addr;
  611         else if (hdr->e_type == ET_EXEC)
  612                 rbase = 0;
  613         else {
  614                 error = ENOEXEC;
  615                 goto fail;
  616         }
  617 
  618         /* Only support headers that fit within first page for now      */
  619         /*    (multiplication of two Elf_Half fields will not overflow) */
  620         if ((hdr->e_phoff > PAGE_SIZE) ||
  621             (hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE - hdr->e_phoff) {
  622                 error = ENOEXEC;
  623                 goto fail;
  624         }
  625 
  626         phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
  627         if (!aligned(phdr, Elf_Addr)) {
  628                 error = ENOEXEC;
  629                 goto fail;
  630         }
  631 
  632         for (i = 0, numsegs = 0; i < hdr->e_phnum; i++) {
  633                 if (phdr[i].p_type == PT_LOAD && phdr[i].p_memsz != 0) {
  634                         /* Loadable segment */
  635                         prot = 0;
  636                         if (phdr[i].p_flags & PF_X)
  637                                 prot |= VM_PROT_EXECUTE;
  638                         if (phdr[i].p_flags & PF_W)
  639                                 prot |= VM_PROT_WRITE;
  640                         if (phdr[i].p_flags & PF_R)
  641                                 prot |= VM_PROT_READ;
  642 
  643                         if ((error = __elfN(load_section)(vmspace,
  644                             imgp->object, phdr[i].p_offset,
  645                             (caddr_t)(uintptr_t)phdr[i].p_vaddr + rbase,
  646                             phdr[i].p_memsz, phdr[i].p_filesz, prot,
  647                             pagesize)) != 0)
  648                                 goto fail;
  649                         /*
  650                          * Establish the base address if this is the
  651                          * first segment.
  652                          */
  653                         if (numsegs == 0)
  654                                 base_addr = trunc_page(phdr[i].p_vaddr +
  655                                     rbase);
  656                         numsegs++;
  657                 }
  658         }
  659         *addr = base_addr;
  660         *entry = (unsigned long)hdr->e_entry + rbase;
  661 
  662 fail:
  663         if (imgp->firstpage)
  664                 exec_unmap_first_page(imgp);
  665 
  666         if (nd->ni_vp)
  667                 vput(nd->ni_vp);
  668 
  669         VFS_UNLOCK_GIANT(vfslocked);
  670         free(tempdata, M_TEMP);
  671 
  672         return (error);
  673 }
  674 
  675 static int
  676 __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
  677 {
  678         const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
  679         const Elf_Phdr *phdr;
  680         Elf_Auxargs *elf_auxargs;
  681         struct vmspace *vmspace;
  682         vm_prot_t prot;
  683         u_long text_size = 0, data_size = 0, total_size = 0;
  684         u_long text_addr = 0, data_addr = 0;
  685         u_long seg_size, seg_addr;
  686         u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0;
  687         int32_t osrel = 0;
  688         int error = 0, i, n;
  689         const char *interp = NULL, *newinterp = NULL;
  690         Elf_Brandinfo *brand_info;
  691         char *path;
  692         struct sysentvec *sv;
  693 
  694         /*
  695          * Do we have a valid ELF header ?
  696          *
  697          * Only allow ET_EXEC & ET_DYN here, reject ET_DYN later
  698          * if particular brand doesn't support it.
  699          */
  700         if (__elfN(check_header)(hdr) != 0 ||
  701             (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN))
  702                 return (-1);
  703 
  704         /*
  705          * From here on down, we return an errno, not -1, as we've
  706          * detected an ELF file.
  707          */
  708 
  709         if ((hdr->e_phoff > PAGE_SIZE) ||
  710             (hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE) {
  711                 /* Only support headers in first page for now */
  712                 return (ENOEXEC);
  713         }
  714         phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
  715         if (!aligned(phdr, Elf_Addr))
  716                 return (ENOEXEC);
  717         n = 0;
  718         baddr = 0;
  719         for (i = 0; i < hdr->e_phnum; i++) {
  720                 if (phdr[i].p_type == PT_LOAD) {
  721                         if (n == 0)
  722                                 baddr = phdr[i].p_vaddr;
  723                         n++;
  724                         continue;
  725                 }
  726                 if (phdr[i].p_type == PT_INTERP) {
  727                         /* Path to interpreter */
  728                         if (phdr[i].p_filesz > MAXPATHLEN ||
  729                             phdr[i].p_offset + phdr[i].p_filesz > PAGE_SIZE)
  730                                 return (ENOEXEC);
  731                         interp = imgp->image_header + phdr[i].p_offset;
  732                         continue;
  733                 }
  734         }
  735 
  736         brand_info = __elfN(get_brandinfo)(imgp, interp, &osrel);
  737         if (brand_info == NULL) {
  738                 uprintf("ELF binary type \"%u\" not known.\n",
  739                     hdr->e_ident[EI_OSABI]);
  740                 return (ENOEXEC);
  741         }
  742         if (hdr->e_type == ET_DYN) {
  743                 if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0)
  744                         return (ENOEXEC);
  745                 /*
  746                  * Honour the base load address from the dso if it is
  747                  * non-zero for some reason.
  748                  */
  749                 if (baddr == 0)
  750                         et_dyn_addr = ET_DYN_LOAD_ADDR;
  751                 else
  752                         et_dyn_addr = 0;
  753         } else
  754                 et_dyn_addr = 0;
  755         sv = brand_info->sysvec;
  756         if (interp != NULL && brand_info->interp_newpath != NULL)
  757                 newinterp = brand_info->interp_newpath;
  758 
  759         /*
  760          * Avoid a possible deadlock if the current address space is destroyed
  761          * and that address space maps the locked vnode.  In the common case,
  762          * the locked vnode's v_usecount is decremented but remains greater
  763          * than zero.  Consequently, the vnode lock is not needed by vrele().
  764          * However, in cases where the vnode lock is external, such as nullfs,
  765          * v_usecount may become zero.
  766          */
  767         VOP_UNLOCK(imgp->vp, 0);
  768 
  769         error = exec_new_vmspace(imgp, sv);
  770         imgp->proc->p_sysent = sv;
  771 
  772         vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
  773         if (error)
  774                 return (error);
  775 
  776         vmspace = imgp->proc->p_vmspace;
  777 
  778         for (i = 0; i < hdr->e_phnum; i++) {
  779                 switch (phdr[i].p_type) {
  780                 case PT_LOAD:   /* Loadable segment */
  781                         if (phdr[i].p_memsz == 0)
  782                                 break;
  783                         prot = 0;
  784                         if (phdr[i].p_flags & PF_X)
  785                                 prot |= VM_PROT_EXECUTE;
  786                         if (phdr[i].p_flags & PF_W)
  787                                 prot |= VM_PROT_WRITE;
  788                         if (phdr[i].p_flags & PF_R)
  789                                 prot |= VM_PROT_READ;
  790 
  791 #if defined(__ia64__) && __ELF_WORD_SIZE == 32 && defined(IA32_ME_HARDER)
  792                         /*
  793                          * Some x86 binaries assume read == executable,
  794                          * notably the M3 runtime and therefore cvsup
  795                          */
  796                         if (prot & VM_PROT_READ)
  797                                 prot |= VM_PROT_EXECUTE;
  798 #endif
  799 
  800                         if ((error = __elfN(load_section)(vmspace,
  801                             imgp->object, phdr[i].p_offset,
  802                             (caddr_t)(uintptr_t)phdr[i].p_vaddr + et_dyn_addr,
  803                             phdr[i].p_memsz, phdr[i].p_filesz, prot,
  804                             sv->sv_pagesize)) != 0)
  805                                 return (error);
  806 
  807                         /*
  808                          * If this segment contains the program headers,
  809                          * remember their virtual address for the AT_PHDR
  810                          * aux entry. Static binaries don't usually include
  811                          * a PT_PHDR entry.
  812                          */
  813                         if (phdr[i].p_offset == 0 &&
  814                             hdr->e_phoff + hdr->e_phnum * hdr->e_phentsize
  815                                 <= phdr[i].p_filesz)
  816                                 proghdr = phdr[i].p_vaddr + hdr->e_phoff +
  817                                     et_dyn_addr;
  818 
  819                         seg_addr = trunc_page(phdr[i].p_vaddr + et_dyn_addr);
  820                         seg_size = round_page(phdr[i].p_memsz +
  821                             phdr[i].p_vaddr + et_dyn_addr - seg_addr);
  822 
  823                         /*
  824                          * Is this .text or .data?  We can't use
  825                          * VM_PROT_WRITE or VM_PROT_EXEC, it breaks the
  826                          * alpha terribly and possibly does other bad
  827                          * things so we stick to the old way of figuring
  828                          * it out:  If the segment contains the program
  829                          * entry point, it's a text segment, otherwise it
  830                          * is a data segment.
  831                          *
  832                          * Note that obreak() assumes that data_addr + 
  833                          * data_size == end of data load area, and the ELF
  834                          * file format expects segments to be sorted by
  835                          * address.  If multiple data segments exist, the
  836                          * last one will be used.
  837                          */
  838                         if (hdr->e_entry >= phdr[i].p_vaddr &&
  839                             hdr->e_entry < (phdr[i].p_vaddr +
  840                             phdr[i].p_memsz)) {
  841                                 text_size = seg_size;
  842                                 text_addr = seg_addr;
  843                                 entry = (u_long)hdr->e_entry + et_dyn_addr;
  844                         } else {
  845                                 data_size = seg_size;
  846                                 data_addr = seg_addr;
  847                         }
  848                         total_size += seg_size;
  849                         break;
  850                 case PT_PHDR:   /* Program header table info */
  851                         proghdr = phdr[i].p_vaddr + et_dyn_addr;
  852                         break;
  853                 default:
  854                         break;
  855                 }
  856         }
  857         
  858         if (data_addr == 0 && data_size == 0) {
  859                 data_addr = text_addr;
  860                 data_size = text_size;
  861         }
  862 
  863         /*
  864          * Check limits.  It should be safe to check the
  865          * limits after loading the segments since we do
  866          * not actually fault in all the segments pages.
  867          */
  868         PROC_LOCK(imgp->proc);
  869         if (data_size > lim_cur(imgp->proc, RLIMIT_DATA) ||
  870             text_size > maxtsiz ||
  871             total_size > lim_cur(imgp->proc, RLIMIT_VMEM)) {
  872                 PROC_UNLOCK(imgp->proc);
  873                 return (ENOMEM);
  874         }
  875 
  876         vmspace->vm_tsize = text_size >> PAGE_SHIFT;
  877         vmspace->vm_taddr = (caddr_t)(uintptr_t)text_addr;
  878         vmspace->vm_dsize = data_size >> PAGE_SHIFT;
  879         vmspace->vm_daddr = (caddr_t)(uintptr_t)data_addr;
  880 
  881         /*
  882          * We load the dynamic linker where a userland call
  883          * to mmap(0, ...) would put it.  The rationale behind this
  884          * calculation is that it leaves room for the heap to grow to
  885          * its maximum allowed size.
  886          */
  887         addr = round_page((vm_offset_t)imgp->proc->p_vmspace->vm_daddr +
  888             lim_max(imgp->proc, RLIMIT_DATA));
  889         PROC_UNLOCK(imgp->proc);
  890 
  891         imgp->entry_addr = entry;
  892 
  893         if (interp != NULL) {
  894                 int have_interp = FALSE;
  895                 VOP_UNLOCK(imgp->vp, 0);
  896                 if (brand_info->emul_path != NULL &&
  897                     brand_info->emul_path[0] != '\0') {
  898                         path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
  899                         snprintf(path, MAXPATHLEN, "%s%s",
  900                             brand_info->emul_path, interp);
  901                         error = __elfN(load_file)(imgp->proc, path, &addr,
  902                             &imgp->entry_addr, sv->sv_pagesize);
  903                         free(path, M_TEMP);
  904                         if (error == 0)
  905                                 have_interp = TRUE;
  906                 }
  907                 if (!have_interp && newinterp != NULL) {
  908                         error = __elfN(load_file)(imgp->proc, newinterp, &addr,
  909                             &imgp->entry_addr, sv->sv_pagesize);
  910                         if (error == 0)
  911                                 have_interp = TRUE;
  912                 }
  913                 if (!have_interp) {
  914                         error = __elfN(load_file)(imgp->proc, interp, &addr,
  915                             &imgp->entry_addr, sv->sv_pagesize);
  916                 }
  917                 vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
  918                 if (error != 0) {
  919                         uprintf("ELF interpreter %s not found\n", interp);
  920                         return (error);
  921                 }
  922         } else
  923                 addr = et_dyn_addr;
  924 
  925         /*
  926          * Construct auxargs table (used by the fixup routine)
  927          */
  928         elf_auxargs = malloc(sizeof(Elf_Auxargs), M_TEMP, M_WAITOK);
  929         elf_auxargs->execfd = -1;
  930         elf_auxargs->phdr = proghdr;
  931         elf_auxargs->phent = hdr->e_phentsize;
  932         elf_auxargs->phnum = hdr->e_phnum;
  933         elf_auxargs->pagesz = PAGE_SIZE;
  934         elf_auxargs->base = addr;
  935         elf_auxargs->flags = 0;
  936         elf_auxargs->entry = entry;
  937 
  938         imgp->auxargs = elf_auxargs;
  939         imgp->interpreted = 0;
  940         imgp->proc->p_osrel = osrel;
  941 
  942         return (error);
  943 }
  944 
  945 #define suword __CONCAT(suword, __ELF_WORD_SIZE)
  946 
  947 int
  948 __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp)
  949 {
  950         Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs;
  951         Elf_Addr *base;
  952         Elf_Addr *pos;
  953 
  954         base = (Elf_Addr *)*stack_base;
  955         pos = base + (imgp->args->argc + imgp->args->envc + 2);
  956 
  957         if (args->execfd != -1)
  958                 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
  959         AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
  960         AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
  961         AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
  962         AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
  963         AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
  964         AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
  965         AUXARGS_ENTRY(pos, AT_BASE, args->base);
  966         if (imgp->execpathp != 0)
  967                 AUXARGS_ENTRY(pos, AT_EXECPATH, imgp->execpathp);
  968         AUXARGS_ENTRY(pos, AT_NULL, 0);
  969 
  970         free(imgp->auxargs, M_TEMP);
  971         imgp->auxargs = NULL;
  972 
  973         base--;
  974         suword(base, (long)imgp->args->argc);
  975         *stack_base = (register_t *)base;
  976         return (0);
  977 }
  978 
  979 /*
  980  * Code for generating ELF core dumps.
  981  */
  982 
  983 typedef void (*segment_callback)(vm_map_entry_t, void *);
  984 
  985 /* Closure for cb_put_phdr(). */
  986 struct phdr_closure {
  987         Elf_Phdr *phdr;         /* Program header to fill in */
  988         Elf_Off offset;         /* Offset of segment in core file */
  989 };
  990 
  991 /* Closure for cb_size_segment(). */
  992 struct sseg_closure {
  993         int count;              /* Count of writable segments. */
  994         size_t size;            /* Total size of all writable segments. */
  995 };
  996 
  997 static void cb_put_phdr(vm_map_entry_t, void *);
  998 static void cb_size_segment(vm_map_entry_t, void *);
  999 static void each_writable_segment(struct thread *, segment_callback, void *);
 1000 static int __elfN(corehdr)(struct thread *, struct vnode *, struct ucred *,
 1001     int, void *, size_t);
 1002 static void __elfN(puthdr)(struct thread *, void *, size_t *, int);
 1003 static void __elfN(putnote)(void *, size_t *, const char *, int,
 1004     const void *, size_t);
 1005 
 1006 int
 1007 __elfN(coredump)(td, vp, limit)
 1008         struct thread *td;
 1009         struct vnode *vp;
 1010         off_t limit;
 1011 {
 1012         struct ucred *cred = td->td_ucred;
 1013         int error = 0;
 1014         struct sseg_closure seginfo;
 1015         void *hdr;
 1016         size_t hdrsize;
 1017 
 1018         /* Size the program segments. */
 1019         seginfo.count = 0;
 1020         seginfo.size = 0;
 1021         each_writable_segment(td, cb_size_segment, &seginfo);
 1022 
 1023         /*
 1024          * Calculate the size of the core file header area by making
 1025          * a dry run of generating it.  Nothing is written, but the
 1026          * size is calculated.
 1027          */
 1028         hdrsize = 0;
 1029         __elfN(puthdr)(td, (void *)NULL, &hdrsize, seginfo.count);
 1030 
 1031         if (hdrsize + seginfo.size >= limit)
 1032                 return (EFAULT);
 1033 
 1034         /*
 1035          * Allocate memory for building the header, fill it up,
 1036          * and write it out.
 1037          */
 1038         hdr = malloc(hdrsize, M_TEMP, M_WAITOK);
 1039         if (hdr == NULL) {
 1040                 return (EINVAL);
 1041         }
 1042         error = __elfN(corehdr)(td, vp, cred, seginfo.count, hdr, hdrsize);
 1043 
 1044         /* Write the contents of all of the writable segments. */
 1045         if (error == 0) {
 1046                 Elf_Phdr *php;
 1047                 off_t offset;
 1048                 int i;
 1049 
 1050                 php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1;
 1051                 offset = hdrsize;
 1052                 for (i = 0; i < seginfo.count; i++) {
 1053                         error = vn_rdwr_inchunks(UIO_WRITE, vp,
 1054                             (caddr_t)(uintptr_t)php->p_vaddr,
 1055                             php->p_filesz, offset, UIO_USERSPACE,
 1056                             IO_UNIT | IO_DIRECT, cred, NOCRED, NULL,
 1057                             curthread);
 1058                         if (error != 0)
 1059                                 break;
 1060                         offset += php->p_filesz;
 1061                         php++;
 1062                 }
 1063         }
 1064         free(hdr, M_TEMP);
 1065 
 1066         return (error);
 1067 }
 1068 
 1069 /*
 1070  * A callback for each_writable_segment() to write out the segment's
 1071  * program header entry.
 1072  */
 1073 static void
 1074 cb_put_phdr(entry, closure)
 1075         vm_map_entry_t entry;
 1076         void *closure;
 1077 {
 1078         struct phdr_closure *phc = (struct phdr_closure *)closure;
 1079         Elf_Phdr *phdr = phc->phdr;
 1080 
 1081         phc->offset = round_page(phc->offset);
 1082 
 1083         phdr->p_type = PT_LOAD;
 1084         phdr->p_offset = phc->offset;
 1085         phdr->p_vaddr = entry->start;
 1086         phdr->p_paddr = 0;
 1087         phdr->p_filesz = phdr->p_memsz = entry->end - entry->start;
 1088         phdr->p_align = PAGE_SIZE;
 1089         phdr->p_flags = 0;
 1090         if (entry->protection & VM_PROT_READ)
 1091                 phdr->p_flags |= PF_R;
 1092         if (entry->protection & VM_PROT_WRITE)
 1093                 phdr->p_flags |= PF_W;
 1094         if (entry->protection & VM_PROT_EXECUTE)
 1095                 phdr->p_flags |= PF_X;
 1096 
 1097         phc->offset += phdr->p_filesz;
 1098         phc->phdr++;
 1099 }
 1100 
 1101 /*
 1102  * A callback for each_writable_segment() to gather information about
 1103  * the number of segments and their total size.
 1104  */
 1105 static void
 1106 cb_size_segment(entry, closure)
 1107         vm_map_entry_t entry;
 1108         void *closure;
 1109 {
 1110         struct sseg_closure *ssc = (struct sseg_closure *)closure;
 1111 
 1112         ssc->count++;
 1113         ssc->size += entry->end - entry->start;
 1114 }
 1115 
 1116 /*
 1117  * For each writable segment in the process's memory map, call the given
 1118  * function with a pointer to the map entry and some arbitrary
 1119  * caller-supplied data.
 1120  */
 1121 static void
 1122 each_writable_segment(td, func, closure)
 1123         struct thread *td;
 1124         segment_callback func;
 1125         void *closure;
 1126 {
 1127         struct proc *p = td->td_proc;
 1128         vm_map_t map = &p->p_vmspace->vm_map;
 1129         vm_map_entry_t entry;
 1130         vm_object_t backing_object, object;
 1131         boolean_t ignore_entry;
 1132 
 1133         vm_map_lock_read(map);
 1134         for (entry = map->header.next; entry != &map->header;
 1135             entry = entry->next) {
 1136                 /*
 1137                  * Don't dump inaccessible mappings, deal with legacy
 1138                  * coredump mode.
 1139                  *
 1140                  * Note that read-only segments related to the elf binary
 1141                  * are marked MAP_ENTRY_NOCOREDUMP now so we no longer
 1142                  * need to arbitrarily ignore such segments.
 1143                  */
 1144                 if (elf_legacy_coredump) {
 1145                         if ((entry->protection & VM_PROT_RW) != VM_PROT_RW)
 1146                                 continue;
 1147                 } else {
 1148                         if ((entry->protection & VM_PROT_ALL) == 0)
 1149                                 continue;
 1150                 }
 1151 
 1152                 /*
 1153                  * Dont include memory segment in the coredump if
 1154                  * MAP_NOCORE is set in mmap(2) or MADV_NOCORE in
 1155                  * madvise(2).  Do not dump submaps (i.e. parts of the
 1156                  * kernel map).
 1157                  */
 1158                 if (entry->eflags & (MAP_ENTRY_NOCOREDUMP|MAP_ENTRY_IS_SUB_MAP))
 1159                         continue;
 1160 
 1161                 if ((object = entry->object.vm_object) == NULL)
 1162                         continue;
 1163 
 1164                 /* Ignore memory-mapped devices and such things. */
 1165                 VM_OBJECT_LOCK(object);
 1166                 while ((backing_object = object->backing_object) != NULL) {
 1167                         VM_OBJECT_LOCK(backing_object);
 1168                         VM_OBJECT_UNLOCK(object);
 1169                         object = backing_object;
 1170                 }
 1171                 ignore_entry = object->type != OBJT_DEFAULT &&
 1172                     object->type != OBJT_SWAP && object->type != OBJT_VNODE;
 1173                 VM_OBJECT_UNLOCK(object);
 1174                 if (ignore_entry)
 1175                         continue;
 1176 
 1177                 (*func)(entry, closure);
 1178         }
 1179         vm_map_unlock_read(map);
 1180 }
 1181 
 1182 /*
 1183  * Write the core file header to the file, including padding up to
 1184  * the page boundary.
 1185  */
 1186 static int
 1187 __elfN(corehdr)(td, vp, cred, numsegs, hdr, hdrsize)
 1188         struct thread *td;
 1189         struct vnode *vp;
 1190         struct ucred *cred;
 1191         int numsegs;
 1192         size_t hdrsize;
 1193         void *hdr;
 1194 {
 1195         size_t off;
 1196 
 1197         /* Fill in the header. */
 1198         bzero(hdr, hdrsize);
 1199         off = 0;
 1200         __elfN(puthdr)(td, hdr, &off, numsegs);
 1201 
 1202         /* Write it to the core file. */
 1203         return (vn_rdwr_inchunks(UIO_WRITE, vp, hdr, hdrsize, (off_t)0,
 1204             UIO_SYSSPACE, IO_UNIT | IO_DIRECT, cred, NOCRED, NULL,
 1205             td));
 1206 }
 1207 
 1208 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
 1209 #include <compat/freebsd32/freebsd32.h>
 1210 
 1211 typedef struct prstatus32 elf_prstatus_t;
 1212 typedef struct prpsinfo32 elf_prpsinfo_t;
 1213 typedef struct fpreg32 elf_prfpregset_t;
 1214 typedef struct fpreg32 elf_fpregset_t;
 1215 typedef struct reg32 elf_gregset_t;
 1216 #else
 1217 typedef prstatus_t elf_prstatus_t;
 1218 typedef prpsinfo_t elf_prpsinfo_t;
 1219 typedef prfpregset_t elf_prfpregset_t;
 1220 typedef prfpregset_t elf_fpregset_t;
 1221 typedef gregset_t elf_gregset_t;
 1222 #endif
 1223 
 1224 static void
 1225 __elfN(puthdr)(struct thread *td, void *dst, size_t *off, int numsegs)
 1226 {
 1227         struct {
 1228                 elf_prstatus_t status;
 1229                 elf_prfpregset_t fpregset;
 1230                 elf_prpsinfo_t psinfo;
 1231         } *tempdata;
 1232         elf_prstatus_t *status;
 1233         elf_prfpregset_t *fpregset;
 1234         elf_prpsinfo_t *psinfo;
 1235         struct proc *p;
 1236         struct thread *thr;
 1237         size_t ehoff, noteoff, notesz, phoff;
 1238 
 1239         p = td->td_proc;
 1240 
 1241         ehoff = *off;
 1242         *off += sizeof(Elf_Ehdr);
 1243 
 1244         phoff = *off;
 1245         *off += (numsegs + 1) * sizeof(Elf_Phdr);
 1246 
 1247         noteoff = *off;
 1248         /*
 1249          * Don't allocate space for the notes if we're just calculating
 1250          * the size of the header. We also don't collect the data.
 1251          */
 1252         if (dst != NULL) {
 1253                 tempdata = malloc(sizeof(*tempdata), M_TEMP, M_ZERO|M_WAITOK);
 1254                 status = &tempdata->status;
 1255                 fpregset = &tempdata->fpregset;
 1256                 psinfo = &tempdata->psinfo;
 1257         } else {
 1258                 tempdata = NULL;
 1259                 status = NULL;
 1260                 fpregset = NULL;
 1261                 psinfo = NULL;
 1262         }
 1263 
 1264         if (dst != NULL) {
 1265                 psinfo->pr_version = PRPSINFO_VERSION;
 1266                 psinfo->pr_psinfosz = sizeof(elf_prpsinfo_t);
 1267                 strlcpy(psinfo->pr_fname, p->p_comm, sizeof(psinfo->pr_fname));
 1268                 /*
 1269                  * XXX - We don't fill in the command line arguments properly
 1270                  * yet.
 1271                  */
 1272                 strlcpy(psinfo->pr_psargs, p->p_comm,
 1273                     sizeof(psinfo->pr_psargs));
 1274         }
 1275         __elfN(putnote)(dst, off, "FreeBSD", NT_PRPSINFO, psinfo,
 1276             sizeof *psinfo);
 1277 
 1278         /*
 1279          * To have the debugger select the right thread (LWP) as the initial
 1280          * thread, we dump the state of the thread passed to us in td first.
 1281          * This is the thread that causes the core dump and thus likely to
 1282          * be the right thread one wants to have selected in the debugger.
 1283          */
 1284         thr = td;
 1285         while (thr != NULL) {
 1286                 if (dst != NULL) {
 1287                         status->pr_version = PRSTATUS_VERSION;
 1288                         status->pr_statussz = sizeof(elf_prstatus_t);
 1289                         status->pr_gregsetsz = sizeof(elf_gregset_t);
 1290                         status->pr_fpregsetsz = sizeof(elf_fpregset_t);
 1291                         status->pr_osreldate = osreldate;
 1292                         status->pr_cursig = p->p_sig;
 1293                         status->pr_pid = thr->td_tid;
 1294 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
 1295                         fill_regs32(thr, &status->pr_reg);
 1296                         fill_fpregs32(thr, fpregset);
 1297 #else
 1298                         fill_regs(thr, &status->pr_reg);
 1299                         fill_fpregs(thr, fpregset);
 1300 #endif
 1301                 }
 1302                 __elfN(putnote)(dst, off, "FreeBSD", NT_PRSTATUS, status,
 1303                     sizeof *status);
 1304                 __elfN(putnote)(dst, off, "FreeBSD", NT_FPREGSET, fpregset,
 1305                     sizeof *fpregset);
 1306                 /*
 1307                  * Allow for MD specific notes, as well as any MD
 1308                  * specific preparations for writing MI notes.
 1309                  */
 1310                 __elfN(dump_thread)(thr, dst, off);
 1311 
 1312                 thr = (thr == td) ? TAILQ_FIRST(&p->p_threads) :
 1313                     TAILQ_NEXT(thr, td_plist);
 1314                 if (thr == td)
 1315                         thr = TAILQ_NEXT(thr, td_plist);
 1316         }
 1317 
 1318         notesz = *off - noteoff;
 1319 
 1320         if (dst != NULL)
 1321                 free(tempdata, M_TEMP);
 1322 
 1323         /* Align up to a page boundary for the program segments. */
 1324         *off = round_page(*off);
 1325 
 1326         if (dst != NULL) {
 1327                 Elf_Ehdr *ehdr;
 1328                 Elf_Phdr *phdr;
 1329                 struct phdr_closure phc;
 1330 
 1331                 /*
 1332                  * Fill in the ELF header.
 1333                  */
 1334                 ehdr = (Elf_Ehdr *)((char *)dst + ehoff);
 1335                 ehdr->e_ident[EI_MAG0] = ELFMAG0;
 1336                 ehdr->e_ident[EI_MAG1] = ELFMAG1;
 1337                 ehdr->e_ident[EI_MAG2] = ELFMAG2;
 1338                 ehdr->e_ident[EI_MAG3] = ELFMAG3;
 1339                 ehdr->e_ident[EI_CLASS] = ELF_CLASS;
 1340                 ehdr->e_ident[EI_DATA] = ELF_DATA;
 1341                 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
 1342                 ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
 1343                 ehdr->e_ident[EI_ABIVERSION] = 0;
 1344                 ehdr->e_ident[EI_PAD] = 0;
 1345                 ehdr->e_type = ET_CORE;
 1346 #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
 1347                 ehdr->e_machine = ELF_ARCH32;
 1348 #else
 1349                 ehdr->e_machine = ELF_ARCH;
 1350 #endif
 1351                 ehdr->e_version = EV_CURRENT;
 1352                 ehdr->e_entry = 0;
 1353                 ehdr->e_phoff = phoff;
 1354                 ehdr->e_flags = 0;
 1355                 ehdr->e_ehsize = sizeof(Elf_Ehdr);
 1356                 ehdr->e_phentsize = sizeof(Elf_Phdr);
 1357                 ehdr->e_phnum = numsegs + 1;
 1358                 ehdr->e_shentsize = sizeof(Elf_Shdr);
 1359                 ehdr->e_shnum = 0;
 1360                 ehdr->e_shstrndx = SHN_UNDEF;
 1361 
 1362                 /*
 1363                  * Fill in the program header entries.
 1364                  */
 1365                 phdr = (Elf_Phdr *)((char *)dst + phoff);
 1366 
 1367                 /* The note segement. */
 1368                 phdr->p_type = PT_NOTE;
 1369                 phdr->p_offset = noteoff;
 1370                 phdr->p_vaddr = 0;
 1371                 phdr->p_paddr = 0;
 1372                 phdr->p_filesz = notesz;
 1373                 phdr->p_memsz = 0;
 1374                 phdr->p_flags = 0;
 1375                 phdr->p_align = 0;
 1376                 phdr++;
 1377 
 1378                 /* All the writable segments from the program. */
 1379                 phc.phdr = phdr;
 1380                 phc.offset = *off;
 1381                 each_writable_segment(td, cb_put_phdr, &phc);
 1382         }
 1383 }
 1384 
 1385 static void
 1386 __elfN(putnote)(void *dst, size_t *off, const char *name, int type,
 1387     const void *desc, size_t descsz)
 1388 {
 1389         Elf_Note note;
 1390 
 1391         note.n_namesz = strlen(name) + 1;
 1392         note.n_descsz = descsz;
 1393         note.n_type = type;
 1394         if (dst != NULL)
 1395                 bcopy(&note, (char *)dst + *off, sizeof note);
 1396         *off += sizeof note;
 1397         if (dst != NULL)
 1398                 bcopy(name, (char *)dst + *off, note.n_namesz);
 1399         *off += roundup2(note.n_namesz, sizeof(Elf_Size));
 1400         if (dst != NULL)
 1401                 bcopy(desc, (char *)dst + *off, note.n_descsz);
 1402         *off += roundup2(note.n_descsz, sizeof(Elf_Size));
 1403 }
 1404 
 1405 /*
 1406  * Try to find the appropriate ABI-note section for checknote,
 1407  * fetch the osreldate for binary from the ELF OSABI-note. Only the
 1408  * first page of the image is searched, the same as for headers.
 1409  */
 1410 static boolean_t
 1411 __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *checknote,
 1412     int32_t *osrel)
 1413 {
 1414         const Elf_Note *note, *note0, *note_end;
 1415         const Elf_Phdr *phdr, *pnote;
 1416         const Elf_Ehdr *hdr;
 1417         const char *note_name;
 1418         int i;
 1419 
 1420         pnote = NULL;
 1421         hdr = (const Elf_Ehdr *)imgp->image_header;
 1422         phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
 1423 
 1424         for (i = 0; i < hdr->e_phnum; i++) {
 1425                 if (phdr[i].p_type == PT_NOTE) {
 1426                         pnote = &phdr[i];
 1427                         break;
 1428                 }
 1429         }
 1430 
 1431         if (pnote == NULL || pnote->p_offset >= PAGE_SIZE ||
 1432             pnote->p_offset + pnote->p_filesz >= PAGE_SIZE)
 1433                 return (FALSE);
 1434 
 1435         note = note0 = (const Elf_Note *)(imgp->image_header + pnote->p_offset);
 1436         note_end = (const Elf_Note *)(imgp->image_header +
 1437             pnote->p_offset + pnote->p_filesz);
 1438         for (i = 0; i < 100 && note >= note0 && note < note_end; i++) {
 1439                 if (!aligned(note, Elf32_Addr))
 1440                         return (FALSE);
 1441                 if (note->n_namesz != checknote->hdr.n_namesz ||
 1442                     note->n_descsz != checknote->hdr.n_descsz ||
 1443                     note->n_type != checknote->hdr.n_type)
 1444                         goto nextnote;
 1445                 note_name = (const char *)(note + 1);
 1446                 if (strncmp(checknote->vendor, note_name,
 1447                     checknote->hdr.n_namesz) != 0)
 1448                         goto nextnote;
 1449 
 1450                 /*
 1451                  * Fetch the osreldate for binary
 1452                  * from the ELF OSABI-note if necessary.
 1453                  */
 1454                 if ((checknote->flags & BN_TRANSLATE_OSREL) != 0 &&
 1455                     checknote->trans_osrel != NULL)
 1456                         return (checknote->trans_osrel(note, osrel));
 1457                 return (TRUE);
 1458 
 1459 nextnote:
 1460                 note = (const Elf_Note *)((const char *)(note + 1) +
 1461                     roundup2(note->n_namesz, sizeof(Elf32_Addr)) +
 1462                     roundup2(note->n_descsz, sizeof(Elf32_Addr)));
 1463         }
 1464 
 1465         return (FALSE);
 1466 }
 1467 
 1468 /*
 1469  * Tell kern_execve.c about it, with a little help from the linker.
 1470  */
 1471 static struct execsw __elfN(execsw) = {
 1472         __CONCAT(exec_, __elfN(imgact)),
 1473         __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
 1474 };
 1475 EXEC_SET(__CONCAT(elf, __ELF_WORD_SIZE), __elfN(execsw));

Cache object: 9bab0e56a8c188843c74db8e8312889b


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