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