]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/link_elf_obj.c
Fix missing pfctl(8) tunable.
[FreeBSD/FreeBSD.git] / sys / kern / link_elf_obj.c
1 /*-
2  * Copyright (c) 1998-2000 Doug Rabson
3  * Copyright (c) 2004 Peter Wemm
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include "opt_ddb.h"
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/lock.h>
37 #include <sys/malloc.h>
38 #include <sys/mutex.h>
39 #include <sys/mount.h>
40 #include <sys/proc.h>
41 #include <sys/namei.h>
42 #include <sys/fcntl.h>
43 #include <sys/vnode.h>
44 #include <sys/linker.h>
45
46 #include <machine/elf.h>
47
48 #include <net/vnet.h>
49
50 #include <security/mac/mac_framework.h>
51
52 #include <vm/vm.h>
53 #include <vm/vm_param.h>
54 #include <vm/vm_object.h>
55 #include <vm/vm_kern.h>
56 #include <vm/vm_extern.h>
57 #include <vm/pmap.h>
58 #include <vm/vm_map.h>
59
60 #include <sys/link_elf.h>
61
62 #ifdef DDB_CTF
63 #include <sys/zlib.h>
64 #endif
65
66 #include "linker_if.h"
67
68 typedef struct {
69         void            *addr;
70         Elf_Off         size;
71         int             flags;
72         int             sec;    /* Original section */
73         char            *name;
74 } Elf_progent;
75
76 typedef struct {
77         Elf_Rel         *rel;
78         int             nrel;
79         int             sec;
80 } Elf_relent;
81
82 typedef struct {
83         Elf_Rela        *rela;
84         int             nrela;
85         int             sec;
86 } Elf_relaent;
87
88
89 typedef struct elf_file {
90         struct linker_file lf;          /* Common fields */
91
92         int             preloaded;
93         caddr_t         address;        /* Relocation address */
94         vm_object_t     object;         /* VM object to hold file pages */
95         Elf_Shdr        *e_shdr;
96
97         Elf_progent     *progtab;
98         int             nprogtab;
99
100         Elf_relaent     *relatab;
101         int             nrelatab;
102
103         Elf_relent      *reltab;
104         int             nreltab;
105
106         Elf_Sym         *ddbsymtab;     /* The symbol table we are using */
107         long            ddbsymcnt;      /* Number of symbols */
108         caddr_t         ddbstrtab;      /* String table */
109         long            ddbstrcnt;      /* number of bytes in string table */
110
111         caddr_t         shstrtab;       /* Section name string table */
112         long            shstrcnt;       /* number of bytes in string table */
113
114         caddr_t         ctftab;         /* CTF table */
115         long            ctfcnt;         /* number of bytes in CTF table */
116         caddr_t         ctfoff;         /* CTF offset table */
117         caddr_t         typoff;         /* Type offset table */
118         long            typlen;         /* Number of type entries. */
119
120 } *elf_file_t;
121
122 #include <kern/kern_ctf.c>
123
124 static int      link_elf_link_preload(linker_class_t cls,
125                     const char *, linker_file_t *);
126 static int      link_elf_link_preload_finish(linker_file_t);
127 static int      link_elf_load_file(linker_class_t, const char *, linker_file_t *);
128 static int      link_elf_lookup_symbol(linker_file_t, const char *,
129                     c_linker_sym_t *);
130 static int      link_elf_symbol_values(linker_file_t, c_linker_sym_t,
131                     linker_symval_t *);
132 static int      link_elf_search_symbol(linker_file_t, caddr_t value,
133                     c_linker_sym_t *sym, long *diffp);
134
135 static void     link_elf_unload_file(linker_file_t);
136 static int      link_elf_lookup_set(linker_file_t, const char *,
137                     void ***, void ***, int *);
138 static int      link_elf_each_function_name(linker_file_t,
139                     int (*)(const char *, void *), void *);
140 static int      link_elf_each_function_nameval(linker_file_t,
141                                 linker_function_nameval_callback_t,
142                                 void *);
143 static int      link_elf_reloc_local(linker_file_t, bool);
144 static long     link_elf_symtab_get(linker_file_t, const Elf_Sym **);
145 static long     link_elf_strtab_get(linker_file_t, caddr_t *);
146
147 static int      elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps,
148                     Elf_Addr *);
149
150 static kobj_method_t link_elf_methods[] = {
151         KOBJMETHOD(linker_lookup_symbol,        link_elf_lookup_symbol),
152         KOBJMETHOD(linker_symbol_values,        link_elf_symbol_values),
153         KOBJMETHOD(linker_search_symbol,        link_elf_search_symbol),
154         KOBJMETHOD(linker_unload,               link_elf_unload_file),
155         KOBJMETHOD(linker_load_file,            link_elf_load_file),
156         KOBJMETHOD(linker_link_preload,         link_elf_link_preload),
157         KOBJMETHOD(linker_link_preload_finish,  link_elf_link_preload_finish),
158         KOBJMETHOD(linker_lookup_set,           link_elf_lookup_set),
159         KOBJMETHOD(linker_each_function_name,   link_elf_each_function_name),
160         KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval),
161         KOBJMETHOD(linker_ctf_get,              link_elf_ctf_get),
162         KOBJMETHOD(linker_symtab_get,           link_elf_symtab_get),
163         KOBJMETHOD(linker_strtab_get,           link_elf_strtab_get),
164         { 0, 0 }
165 };
166
167 static struct linker_class link_elf_class = {
168 #if ELF_TARG_CLASS == ELFCLASS32
169         "elf32_obj",
170 #else
171         "elf64_obj",
172 #endif
173         link_elf_methods, sizeof(struct elf_file)
174 };
175
176 static int      relocate_file(elf_file_t ef);
177 static void     elf_obj_cleanup_globals_cache(elf_file_t);
178
179 static void
180 link_elf_error(const char *filename, const char *s)
181 {
182         if (filename == NULL)
183                 printf("kldload: %s\n", s);
184         else
185                 printf("kldload: %s: %s\n", filename, s);
186 }
187
188 static void
189 link_elf_init(void *arg)
190 {
191
192         linker_add_class(&link_elf_class);
193 }
194
195 SYSINIT(link_elf_obj, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0);
196
197 static int
198 link_elf_link_preload(linker_class_t cls, const char *filename,
199     linker_file_t *result)
200 {
201         Elf_Ehdr *hdr;
202         Elf_Shdr *shdr;
203         Elf_Sym *es;
204         void *modptr, *baseptr, *sizeptr;
205         char *type;
206         elf_file_t ef;
207         linker_file_t lf;
208         Elf_Addr off;
209         int error, i, j, pb, ra, rl, shstrindex, symstrindex, symtabindex;
210
211         /* Look to see if we have the file preloaded */
212         modptr = preload_search_by_name(filename);
213         if (modptr == NULL)
214                 return ENOENT;
215
216         type = (char *)preload_search_info(modptr, MODINFO_TYPE);
217         baseptr = preload_search_info(modptr, MODINFO_ADDR);
218         sizeptr = preload_search_info(modptr, MODINFO_SIZE);
219         hdr = (Elf_Ehdr *)preload_search_info(modptr, MODINFO_METADATA |
220             MODINFOMD_ELFHDR);
221         shdr = (Elf_Shdr *)preload_search_info(modptr, MODINFO_METADATA |
222             MODINFOMD_SHDR);
223         if (type == NULL || (strcmp(type, "elf" __XSTRING(__ELF_WORD_SIZE)
224             " obj module") != 0 &&
225             strcmp(type, "elf obj module") != 0)) {
226                 return (EFTYPE);
227         }
228         if (baseptr == NULL || sizeptr == NULL || hdr == NULL ||
229             shdr == NULL)
230                 return (EINVAL);
231
232         lf = linker_make_file(filename, &link_elf_class);
233         if (lf == NULL)
234                 return (ENOMEM);
235
236         ef = (elf_file_t)lf;
237         ef->preloaded = 1;
238         ef->address = *(caddr_t *)baseptr;
239         lf->address = *(caddr_t *)baseptr;
240         lf->size = *(size_t *)sizeptr;
241
242         if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
243             hdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
244             hdr->e_ident[EI_VERSION] != EV_CURRENT ||
245             hdr->e_version != EV_CURRENT ||
246             hdr->e_type != ET_REL ||
247             hdr->e_machine != ELF_TARG_MACH) {
248                 error = EFTYPE;
249                 goto out;
250         }
251         ef->e_shdr = shdr;
252
253         /* Scan the section header for information and table sizing. */
254         symtabindex = -1;
255         symstrindex = -1;
256         for (i = 0; i < hdr->e_shnum; i++) {
257                 switch (shdr[i].sh_type) {
258                 case SHT_PROGBITS:
259                 case SHT_NOBITS:
260 #ifdef __amd64__
261                 case SHT_X86_64_UNWIND:
262 #endif
263                         /* Ignore sections not loaded by the loader. */
264                         if (shdr[i].sh_addr == 0)
265                                 break;
266                         ef->nprogtab++;
267                         break;
268                 case SHT_SYMTAB:
269                         symtabindex = i;
270                         symstrindex = shdr[i].sh_link;
271                         break;
272                 case SHT_REL:
273                         /*
274                          * Ignore relocation tables for sections not
275                          * loaded by the loader.
276                          */
277                         if (shdr[shdr[i].sh_info].sh_addr == 0)
278                                 break;
279                         ef->nreltab++;
280                         break;
281                 case SHT_RELA:
282                         if (shdr[shdr[i].sh_info].sh_addr == 0)
283                                 break;
284                         ef->nrelatab++;
285                         break;
286                 }
287         }
288
289         shstrindex = hdr->e_shstrndx;
290         if (ef->nprogtab == 0 || symstrindex < 0 ||
291             symstrindex >= hdr->e_shnum ||
292             shdr[symstrindex].sh_type != SHT_STRTAB || shstrindex == 0 ||
293             shstrindex >= hdr->e_shnum ||
294             shdr[shstrindex].sh_type != SHT_STRTAB) {
295                 printf("%s: bad/missing section headers\n", filename);
296                 error = ENOEXEC;
297                 goto out;
298         }
299
300         /* Allocate space for tracking the load chunks */
301         if (ef->nprogtab != 0)
302                 ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab),
303                     M_LINKER, M_WAITOK | M_ZERO);
304         if (ef->nreltab != 0)
305                 ef->reltab = malloc(ef->nreltab * sizeof(*ef->reltab),
306                     M_LINKER, M_WAITOK | M_ZERO);
307         if (ef->nrelatab != 0)
308                 ef->relatab = malloc(ef->nrelatab * sizeof(*ef->relatab),
309                     M_LINKER, M_WAITOK | M_ZERO);
310         if ((ef->nprogtab != 0 && ef->progtab == NULL) ||
311             (ef->nreltab != 0 && ef->reltab == NULL) ||
312             (ef->nrelatab != 0 && ef->relatab == NULL)) {
313                 error = ENOMEM;
314                 goto out;
315         }
316
317         /* XXX, relocate the sh_addr fields saved by the loader. */
318         off = 0;
319         for (i = 0; i < hdr->e_shnum; i++) {
320                 if (shdr[i].sh_addr != 0 && (off == 0 || shdr[i].sh_addr < off))
321                         off = shdr[i].sh_addr;
322         }
323         for (i = 0; i < hdr->e_shnum; i++) {
324                 if (shdr[i].sh_addr != 0)
325                         shdr[i].sh_addr = shdr[i].sh_addr - off +
326                             (Elf_Addr)ef->address;
327         }
328
329         ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
330         ef->ddbsymtab = (Elf_Sym *)shdr[symtabindex].sh_addr;
331         ef->ddbstrcnt = shdr[symstrindex].sh_size;
332         ef->ddbstrtab = (char *)shdr[symstrindex].sh_addr;
333         ef->shstrcnt = shdr[shstrindex].sh_size;
334         ef->shstrtab = (char *)shdr[shstrindex].sh_addr;
335
336         /* Now fill out progtab and the relocation tables. */
337         pb = 0;
338         rl = 0;
339         ra = 0;
340         for (i = 0; i < hdr->e_shnum; i++) {
341                 switch (shdr[i].sh_type) {
342                 case SHT_PROGBITS:
343                 case SHT_NOBITS:
344 #ifdef __amd64__
345                 case SHT_X86_64_UNWIND:
346 #endif
347                         if (shdr[i].sh_addr == 0)
348                                 break;
349                         ef->progtab[pb].addr = (void *)shdr[i].sh_addr;
350                         if (shdr[i].sh_type == SHT_PROGBITS)
351                                 ef->progtab[pb].name = "<<PROGBITS>>";
352 #ifdef __amd64__
353                         else if (shdr[i].sh_type == SHT_X86_64_UNWIND)
354                                 ef->progtab[pb].name = "<<UNWIND>>";
355 #endif
356                         else
357                                 ef->progtab[pb].name = "<<NOBITS>>";
358                         ef->progtab[pb].size = shdr[i].sh_size;
359                         ef->progtab[pb].sec = i;
360                         if (ef->shstrtab && shdr[i].sh_name != 0)
361                                 ef->progtab[pb].name =
362                                     ef->shstrtab + shdr[i].sh_name;
363                         if (ef->progtab[pb].name != NULL && 
364                             !strcmp(ef->progtab[pb].name, DPCPU_SETNAME)) {
365                                 void *dpcpu;
366
367                                 dpcpu = dpcpu_alloc(shdr[i].sh_size);
368                                 if (dpcpu == NULL) {
369                                         printf("%s: pcpu module space is out "
370                                             "of space; cannot allocate %#jx "
371                                             "for %s\n", __func__,
372                                             (uintmax_t)shdr[i].sh_size,
373                                             filename);
374                                         error = ENOSPC;
375                                         goto out;
376                                 }
377                                 memcpy(dpcpu, ef->progtab[pb].addr,
378                                     ef->progtab[pb].size);
379                                 dpcpu_copy(dpcpu, shdr[i].sh_size);
380                                 ef->progtab[pb].addr = dpcpu;
381 #ifdef VIMAGE
382                         } else if (ef->progtab[pb].name != NULL &&
383                             !strcmp(ef->progtab[pb].name, VNET_SETNAME)) {
384                                 void *vnet_data;
385
386                                 vnet_data = vnet_data_alloc(shdr[i].sh_size);
387                                 if (vnet_data == NULL) {
388                                         printf("%s: vnet module space is out "
389                                             "of space; cannot allocate %#jx "
390                                             "for %s\n", __func__,
391                                             (uintmax_t)shdr[i].sh_size,
392                                             filename);
393                                         error = ENOSPC;
394                                         goto out;
395                                 }
396                                 memcpy(vnet_data, ef->progtab[pb].addr,
397                                     ef->progtab[pb].size);
398                                 vnet_data_copy(vnet_data, shdr[i].sh_size);
399                                 ef->progtab[pb].addr = vnet_data;
400 #endif
401                         } else if (ef->progtab[pb].name != NULL &&
402                             !strcmp(ef->progtab[pb].name, ".ctors")) {
403                                 lf->ctors_addr = ef->progtab[pb].addr;
404                                 lf->ctors_size = shdr[i].sh_size;
405                         }
406
407                         /* Update all symbol values with the offset. */
408                         for (j = 0; j < ef->ddbsymcnt; j++) {
409                                 es = &ef->ddbsymtab[j];
410                                 if (es->st_shndx != i)
411                                         continue;
412                                 es->st_value += (Elf_Addr)ef->progtab[pb].addr;
413                         }
414                         pb++;
415                         break;
416                 case SHT_REL:
417                         if (shdr[shdr[i].sh_info].sh_addr == 0)
418                                 break;
419                         ef->reltab[rl].rel = (Elf_Rel *)shdr[i].sh_addr;
420                         ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel);
421                         ef->reltab[rl].sec = shdr[i].sh_info;
422                         rl++;
423                         break;
424                 case SHT_RELA:
425                         if (shdr[shdr[i].sh_info].sh_addr == 0)
426                                 break;
427                         ef->relatab[ra].rela = (Elf_Rela *)shdr[i].sh_addr;
428                         ef->relatab[ra].nrela =
429                             shdr[i].sh_size / sizeof(Elf_Rela);
430                         ef->relatab[ra].sec = shdr[i].sh_info;
431                         ra++;
432                         break;
433                 }
434         }
435         if (pb != ef->nprogtab) {
436                 printf("%s: lost progbits\n", filename);
437                 error = ENOEXEC;
438                 goto out;
439         }
440         if (rl != ef->nreltab) {
441                 printf("%s: lost reltab\n", filename);
442                 error = ENOEXEC;
443                 goto out;
444         }
445         if (ra != ef->nrelatab) {
446                 printf("%s: lost relatab\n", filename);
447                 error = ENOEXEC;
448                 goto out;
449         }
450
451         /* Local intra-module relocations */
452         error = link_elf_reloc_local(lf, false);
453         if (error != 0)
454                 goto out;
455         *result = lf;
456         return (0);
457
458 out:
459         /* preload not done this way */
460         linker_file_unload(lf, LINKER_UNLOAD_FORCE);
461         return (error);
462 }
463
464 static void
465 link_elf_invoke_ctors(caddr_t addr, size_t size)
466 {
467         void (**ctor)(void);
468         size_t i, cnt;
469
470         if (addr == NULL || size == 0)
471                 return;
472         cnt = size / sizeof(*ctor);
473         ctor = (void *)addr;
474         for (i = 0; i < cnt; i++) {
475                 if (ctor[i] != NULL)
476                         (*ctor[i])();
477         }
478 }
479
480 static int
481 link_elf_link_preload_finish(linker_file_t lf)
482 {
483         elf_file_t ef;
484         int error;
485
486         ef = (elf_file_t)lf;
487         error = relocate_file(ef);
488         if (error)
489                 return (error);
490
491         /* Notify MD code that a module is being loaded. */
492         error = elf_cpu_load_file(lf);
493         if (error)
494                 return (error);
495
496 #if defined(__i386__) || defined(__amd64__)
497         /* Now ifuncs. */
498         error = link_elf_reloc_local(lf, true);
499         if (error != 0)
500                 return (error);
501 #endif
502
503         /* Invoke .ctors */
504         link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size);
505         return (0);
506 }
507
508 static int
509 link_elf_load_file(linker_class_t cls, const char *filename,
510     linker_file_t *result)
511 {
512         struct nameidata nd;
513         struct thread *td = curthread;  /* XXX */
514         Elf_Ehdr *hdr;
515         Elf_Shdr *shdr;
516         Elf_Sym *es;
517         int nbytes, i, j;
518         vm_offset_t mapbase;
519         size_t mapsize;
520         int error = 0;
521         ssize_t resid;
522         int flags;
523         elf_file_t ef;
524         linker_file_t lf;
525         int symtabindex;
526         int symstrindex;
527         int shstrindex;
528         int nsym;
529         int pb, rl, ra;
530         int alignmask;
531
532         shdr = NULL;
533         lf = NULL;
534         mapsize = 0;
535         hdr = NULL;
536
537         NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
538         flags = FREAD;
539         error = vn_open(&nd, &flags, 0, NULL);
540         if (error)
541                 return error;
542         NDFREE(&nd, NDF_ONLY_PNBUF);
543         if (nd.ni_vp->v_type != VREG) {
544                 error = ENOEXEC;
545                 goto out;
546         }
547 #ifdef MAC
548         error = mac_kld_check_load(td->td_ucred, nd.ni_vp);
549         if (error) {
550                 goto out;
551         }
552 #endif
553
554         /* Read the elf header from the file. */
555         hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK);
556         error = vn_rdwr(UIO_READ, nd.ni_vp, (void *)hdr, sizeof(*hdr), 0,
557             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
558             &resid, td);
559         if (error)
560                 goto out;
561         if (resid != 0){
562                 error = ENOEXEC;
563                 goto out;
564         }
565
566         if (!IS_ELF(*hdr)) {
567                 error = ENOEXEC;
568                 goto out;
569         }
570
571         if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS
572             || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
573                 link_elf_error(filename, "Unsupported file layout");
574                 error = ENOEXEC;
575                 goto out;
576         }
577         if (hdr->e_ident[EI_VERSION] != EV_CURRENT
578             || hdr->e_version != EV_CURRENT) {
579                 link_elf_error(filename, "Unsupported file version");
580                 error = ENOEXEC;
581                 goto out;
582         }
583         if (hdr->e_type != ET_REL) {
584                 error = ENOSYS;
585                 goto out;
586         }
587         if (hdr->e_machine != ELF_TARG_MACH) {
588                 link_elf_error(filename, "Unsupported machine");
589                 error = ENOEXEC;
590                 goto out;
591         }
592
593         lf = linker_make_file(filename, &link_elf_class);
594         if (!lf) {
595                 error = ENOMEM;
596                 goto out;
597         }
598         ef = (elf_file_t) lf;
599         ef->nprogtab = 0;
600         ef->e_shdr = 0;
601         ef->nreltab = 0;
602         ef->nrelatab = 0;
603
604         /* Allocate and read in the section header */
605         nbytes = hdr->e_shnum * hdr->e_shentsize;
606         if (nbytes == 0 || hdr->e_shoff == 0 ||
607             hdr->e_shentsize != sizeof(Elf_Shdr)) {
608                 error = ENOEXEC;
609                 goto out;
610         }
611         shdr = malloc(nbytes, M_LINKER, M_WAITOK);
612         ef->e_shdr = shdr;
613         error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes, hdr->e_shoff,
614             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td);
615         if (error)
616                 goto out;
617         if (resid) {
618                 error = ENOEXEC;
619                 goto out;
620         }
621
622         /* Scan the section header for information and table sizing. */
623         nsym = 0;
624         symtabindex = -1;
625         symstrindex = -1;
626         for (i = 0; i < hdr->e_shnum; i++) {
627                 if (shdr[i].sh_size == 0)
628                         continue;
629                 switch (shdr[i].sh_type) {
630                 case SHT_PROGBITS:
631                 case SHT_NOBITS:
632 #ifdef __amd64__
633                 case SHT_X86_64_UNWIND:
634 #endif
635                         if ((shdr[i].sh_flags & SHF_ALLOC) == 0)
636                                 break;
637                         ef->nprogtab++;
638                         break;
639                 case SHT_SYMTAB:
640                         nsym++;
641                         symtabindex = i;
642                         symstrindex = shdr[i].sh_link;
643                         break;
644                 case SHT_REL:
645                         /*
646                          * Ignore relocation tables for unallocated
647                          * sections.
648                          */
649                         if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0)
650                                 break;
651                         ef->nreltab++;
652                         break;
653                 case SHT_RELA:
654                         if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0)
655                                 break;
656                         ef->nrelatab++;
657                         break;
658                 case SHT_STRTAB:
659                         break;
660                 }
661         }
662         if (ef->nprogtab == 0) {
663                 link_elf_error(filename, "file has no contents");
664                 error = ENOEXEC;
665                 goto out;
666         }
667         if (nsym != 1) {
668                 /* Only allow one symbol table for now */
669                 link_elf_error(filename, "file has no valid symbol table");
670                 error = ENOEXEC;
671                 goto out;
672         }
673         if (symstrindex < 0 || symstrindex > hdr->e_shnum ||
674             shdr[symstrindex].sh_type != SHT_STRTAB) {
675                 link_elf_error(filename, "file has invalid symbol strings");
676                 error = ENOEXEC;
677                 goto out;
678         }
679
680         /* Allocate space for tracking the load chunks */
681         if (ef->nprogtab != 0)
682                 ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab),
683                     M_LINKER, M_WAITOK | M_ZERO);
684         if (ef->nreltab != 0)
685                 ef->reltab = malloc(ef->nreltab * sizeof(*ef->reltab),
686                     M_LINKER, M_WAITOK | M_ZERO);
687         if (ef->nrelatab != 0)
688                 ef->relatab = malloc(ef->nrelatab * sizeof(*ef->relatab),
689                     M_LINKER, M_WAITOK | M_ZERO);
690
691         if (symtabindex == -1) {
692                 link_elf_error(filename, "lost symbol table index");
693                 error = ENOEXEC;
694                 goto out;
695         }
696         /* Allocate space for and load the symbol table */
697         ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
698         ef->ddbsymtab = malloc(shdr[symtabindex].sh_size, M_LINKER, M_WAITOK);
699         error = vn_rdwr(UIO_READ, nd.ni_vp, (void *)ef->ddbsymtab,
700             shdr[symtabindex].sh_size, shdr[symtabindex].sh_offset,
701             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
702             &resid, td);
703         if (error)
704                 goto out;
705         if (resid != 0){
706                 error = EINVAL;
707                 goto out;
708         }
709
710         if (symstrindex == -1) {
711                 link_elf_error(filename, "lost symbol string index");
712                 error = ENOEXEC;
713                 goto out;
714         }
715         /* Allocate space for and load the symbol strings */
716         ef->ddbstrcnt = shdr[symstrindex].sh_size;
717         ef->ddbstrtab = malloc(shdr[symstrindex].sh_size, M_LINKER, M_WAITOK);
718         error = vn_rdwr(UIO_READ, nd.ni_vp, ef->ddbstrtab,
719             shdr[symstrindex].sh_size, shdr[symstrindex].sh_offset,
720             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
721             &resid, td);
722         if (error)
723                 goto out;
724         if (resid != 0){
725                 error = EINVAL;
726                 goto out;
727         }
728
729         /* Do we have a string table for the section names?  */
730         shstrindex = -1;
731         if (hdr->e_shstrndx != 0 &&
732             shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
733                 shstrindex = hdr->e_shstrndx;
734                 ef->shstrcnt = shdr[shstrindex].sh_size;
735                 ef->shstrtab = malloc(shdr[shstrindex].sh_size, M_LINKER,
736                     M_WAITOK);
737                 error = vn_rdwr(UIO_READ, nd.ni_vp, ef->shstrtab,
738                     shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset,
739                     UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
740                     &resid, td);
741                 if (error)
742                         goto out;
743                 if (resid != 0){
744                         error = EINVAL;
745                         goto out;
746                 }
747         }
748
749         /* Size up code/data(progbits) and bss(nobits). */
750         alignmask = 0;
751         for (i = 0; i < hdr->e_shnum; i++) {
752                 if (shdr[i].sh_size == 0)
753                         continue;
754                 switch (shdr[i].sh_type) {
755                 case SHT_PROGBITS:
756                 case SHT_NOBITS:
757 #ifdef __amd64__
758                 case SHT_X86_64_UNWIND:
759 #endif
760                         if ((shdr[i].sh_flags & SHF_ALLOC) == 0)
761                                 break;
762                         alignmask = shdr[i].sh_addralign - 1;
763                         mapsize += alignmask;
764                         mapsize &= ~alignmask;
765                         mapsize += shdr[i].sh_size;
766                         break;
767                 }
768         }
769
770         /*
771          * We know how much space we need for the text/data/bss/etc.
772          * This stuff needs to be in a single chunk so that profiling etc
773          * can get the bounds and gdb can associate offsets with modules
774          */
775         ef->object = vm_object_allocate(OBJT_DEFAULT,
776             round_page(mapsize) >> PAGE_SHIFT);
777         if (ef->object == NULL) {
778                 error = ENOMEM;
779                 goto out;
780         }
781         ef->address = (caddr_t) vm_map_min(kernel_map);
782
783         /*
784          * In order to satisfy amd64's architectural requirements on the
785          * location of code and data in the kernel's address space, request a
786          * mapping that is above the kernel.  
787          */
788 #ifdef __amd64__
789         mapbase = KERNBASE;
790 #else
791         mapbase = VM_MIN_KERNEL_ADDRESS;
792 #endif
793         error = vm_map_find(kernel_map, ef->object, 0, &mapbase,
794             round_page(mapsize), 0, VMFS_OPTIMAL_SPACE, VM_PROT_ALL,
795             VM_PROT_ALL, 0);
796         if (error) {
797                 vm_object_deallocate(ef->object);
798                 ef->object = 0;
799                 goto out;
800         }
801
802         /* Wire the pages */
803         error = vm_map_wire(kernel_map, mapbase,
804             mapbase + round_page(mapsize),
805             VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES);
806         if (error != KERN_SUCCESS) {
807                 error = ENOMEM;
808                 goto out;
809         }
810
811         /* Inform the kld system about the situation */
812         lf->address = ef->address = (caddr_t)mapbase;
813         lf->size = mapsize;
814
815         /*
816          * Now load code/data(progbits), zero bss(nobits), allocate space for
817          * and load relocs
818          */
819         pb = 0;
820         rl = 0;
821         ra = 0;
822         alignmask = 0;
823         for (i = 0; i < hdr->e_shnum; i++) {
824                 if (shdr[i].sh_size == 0)
825                         continue;
826                 switch (shdr[i].sh_type) {
827                 case SHT_PROGBITS:
828                 case SHT_NOBITS:
829 #ifdef __amd64__
830                 case SHT_X86_64_UNWIND:
831 #endif
832                         if ((shdr[i].sh_flags & SHF_ALLOC) == 0)
833                                 break;
834                         alignmask = shdr[i].sh_addralign - 1;
835                         mapbase += alignmask;
836                         mapbase &= ~alignmask;
837                         if (ef->shstrtab != NULL && shdr[i].sh_name != 0) {
838                                 ef->progtab[pb].name =
839                                     ef->shstrtab + shdr[i].sh_name;
840                                 if (!strcmp(ef->progtab[pb].name, ".ctors")) {
841                                         lf->ctors_addr = (caddr_t)mapbase;
842                                         lf->ctors_size = shdr[i].sh_size;
843                                 }
844                         } else if (shdr[i].sh_type == SHT_PROGBITS)
845                                 ef->progtab[pb].name = "<<PROGBITS>>";
846 #ifdef __amd64__
847                         else if (shdr[i].sh_type == SHT_X86_64_UNWIND)
848                                 ef->progtab[pb].name = "<<UNWIND>>";
849 #endif
850                         else
851                                 ef->progtab[pb].name = "<<NOBITS>>";
852                         if (ef->progtab[pb].name != NULL && 
853                             !strcmp(ef->progtab[pb].name, DPCPU_SETNAME)) {
854                                 ef->progtab[pb].addr =
855                                     dpcpu_alloc(shdr[i].sh_size);
856                                 if (ef->progtab[pb].addr == NULL) {
857                                         printf("%s: pcpu module space is out "
858                                             "of space; cannot allocate %#jx "
859                                             "for %s\n", __func__,
860                                             (uintmax_t)shdr[i].sh_size,
861                                             filename);
862                                 }
863                         }
864 #ifdef VIMAGE
865                         else if (ef->progtab[pb].name != NULL &&
866                             !strcmp(ef->progtab[pb].name, VNET_SETNAME)) {
867                                 ef->progtab[pb].addr =
868                                     vnet_data_alloc(shdr[i].sh_size);
869                                 if (ef->progtab[pb].addr == NULL) {
870                                         printf("%s: vnet module space is out "
871                                             "of space; cannot allocate %#jx "
872                                             "for %s\n", __func__,
873                                             (uintmax_t)shdr[i].sh_size,
874                                             filename);
875                                 }
876                         }
877 #endif
878                         else
879                                 ef->progtab[pb].addr =
880                                     (void *)(uintptr_t)mapbase;
881                         if (ef->progtab[pb].addr == NULL) {
882                                 error = ENOSPC;
883                                 goto out;
884                         }
885                         ef->progtab[pb].size = shdr[i].sh_size;
886                         ef->progtab[pb].sec = i;
887                         if (shdr[i].sh_type == SHT_PROGBITS
888 #ifdef __amd64__
889                             || shdr[i].sh_type == SHT_X86_64_UNWIND
890 #endif
891                             ) {
892                                 error = vn_rdwr(UIO_READ, nd.ni_vp,
893                                     ef->progtab[pb].addr,
894                                     shdr[i].sh_size, shdr[i].sh_offset,
895                                     UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
896                                     NOCRED, &resid, td);
897                                 if (error)
898                                         goto out;
899                                 if (resid != 0){
900                                         error = EINVAL;
901                                         goto out;
902                                 }
903                                 /* Initialize the per-cpu or vnet area. */
904                                 if (ef->progtab[pb].addr != (void *)mapbase &&
905                                     !strcmp(ef->progtab[pb].name, DPCPU_SETNAME))
906                                         dpcpu_copy(ef->progtab[pb].addr,
907                                             shdr[i].sh_size);
908 #ifdef VIMAGE
909                                 else if (ef->progtab[pb].addr !=
910                                     (void *)mapbase &&
911                                     !strcmp(ef->progtab[pb].name, VNET_SETNAME))
912                                         vnet_data_copy(ef->progtab[pb].addr,
913                                             shdr[i].sh_size);
914 #endif
915                         } else
916                                 bzero(ef->progtab[pb].addr, shdr[i].sh_size);
917
918                         /* Update all symbol values with the offset. */
919                         for (j = 0; j < ef->ddbsymcnt; j++) {
920                                 es = &ef->ddbsymtab[j];
921                                 if (es->st_shndx != i)
922                                         continue;
923                                 es->st_value += (Elf_Addr)ef->progtab[pb].addr;
924                         }
925                         mapbase += shdr[i].sh_size;
926                         pb++;
927                         break;
928                 case SHT_REL:
929                         if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0)
930                                 break;
931                         ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER,
932                             M_WAITOK);
933                         ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel);
934                         ef->reltab[rl].sec = shdr[i].sh_info;
935                         error = vn_rdwr(UIO_READ, nd.ni_vp,
936                             (void *)ef->reltab[rl].rel,
937                             shdr[i].sh_size, shdr[i].sh_offset,
938                             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
939                             &resid, td);
940                         if (error)
941                                 goto out;
942                         if (resid != 0){
943                                 error = EINVAL;
944                                 goto out;
945                         }
946                         rl++;
947                         break;
948                 case SHT_RELA:
949                         if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0)
950                                 break;
951                         ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER,
952                             M_WAITOK);
953                         ef->relatab[ra].nrela =
954                             shdr[i].sh_size / sizeof(Elf_Rela);
955                         ef->relatab[ra].sec = shdr[i].sh_info;
956                         error = vn_rdwr(UIO_READ, nd.ni_vp,
957                             (void *)ef->relatab[ra].rela,
958                             shdr[i].sh_size, shdr[i].sh_offset,
959                             UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
960                             &resid, td);
961                         if (error)
962                                 goto out;
963                         if (resid != 0){
964                                 error = EINVAL;
965                                 goto out;
966                         }
967                         ra++;
968                         break;
969                 }
970         }
971         if (pb != ef->nprogtab) {
972                 link_elf_error(filename, "lost progbits");
973                 error = ENOEXEC;
974                 goto out;
975         }
976         if (rl != ef->nreltab) {
977                 link_elf_error(filename, "lost reltab");
978                 error = ENOEXEC;
979                 goto out;
980         }
981         if (ra != ef->nrelatab) {
982                 link_elf_error(filename, "lost relatab");
983                 error = ENOEXEC;
984                 goto out;
985         }
986         if (mapbase != (vm_offset_t)ef->address + mapsize) {
987                 printf(
988                     "%s: mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n",
989                     filename != NULL ? filename : "<none>",
990                     (u_long)mapbase, ef->address, (u_long)mapsize,
991                     (u_long)(vm_offset_t)ef->address + mapsize);
992                 error = ENOMEM;
993                 goto out;
994         }
995
996         /* Local intra-module relocations */
997         error = link_elf_reloc_local(lf, false);
998         if (error != 0)
999                 goto out;
1000
1001         /* Pull in dependencies */
1002         VOP_UNLOCK(nd.ni_vp, 0);
1003         error = linker_load_dependencies(lf);
1004         vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY);
1005         if (error)
1006                 goto out;
1007
1008         /* External relocations */
1009         error = relocate_file(ef);
1010         if (error)
1011                 goto out;
1012
1013         /* Notify MD code that a module is being loaded. */
1014         error = elf_cpu_load_file(lf);
1015         if (error)
1016                 goto out;
1017
1018 #if defined(__i386__) || defined(__amd64__)
1019         /* Now ifuncs. */
1020         error = link_elf_reloc_local(lf, true);
1021         if (error != 0)
1022                 goto out;
1023 #endif
1024
1025         /* Invoke .ctors */
1026         link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size);
1027
1028         *result = lf;
1029
1030 out:
1031         VOP_UNLOCK(nd.ni_vp, 0);
1032         vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
1033         if (error && lf)
1034                 linker_file_unload(lf, LINKER_UNLOAD_FORCE);
1035         free(hdr, M_LINKER);
1036
1037         return error;
1038 }
1039
1040 static void
1041 link_elf_unload_file(linker_file_t file)
1042 {
1043         elf_file_t ef = (elf_file_t) file;
1044         int i;
1045
1046         /* Notify MD code that a module is being unloaded. */
1047         elf_cpu_unload_file(file);
1048
1049         if (ef->progtab) {
1050                 for (i = 0; i < ef->nprogtab; i++) {
1051                         if (ef->progtab[i].size == 0)
1052                                 continue;
1053                         if (ef->progtab[i].name == NULL)
1054                                 continue;
1055                         if (!strcmp(ef->progtab[i].name, DPCPU_SETNAME))
1056                                 dpcpu_free(ef->progtab[i].addr,
1057                                     ef->progtab[i].size);
1058 #ifdef VIMAGE
1059                         else if (!strcmp(ef->progtab[i].name, VNET_SETNAME))
1060                                 vnet_data_free(ef->progtab[i].addr,
1061                                     ef->progtab[i].size);
1062 #endif
1063                 }
1064         }
1065         if (ef->preloaded) {
1066                 free(ef->reltab, M_LINKER);
1067                 free(ef->relatab, M_LINKER);
1068                 free(ef->progtab, M_LINKER);
1069                 free(ef->ctftab, M_LINKER);
1070                 free(ef->ctfoff, M_LINKER);
1071                 free(ef->typoff, M_LINKER);
1072                 if (file->pathname != NULL)
1073                         preload_delete_name(file->pathname);
1074                 return;
1075         }
1076
1077         for (i = 0; i < ef->nreltab; i++)
1078                 free(ef->reltab[i].rel, M_LINKER);
1079         for (i = 0; i < ef->nrelatab; i++)
1080                 free(ef->relatab[i].rela, M_LINKER);
1081         free(ef->reltab, M_LINKER);
1082         free(ef->relatab, M_LINKER);
1083         free(ef->progtab, M_LINKER);
1084
1085         if (ef->object) {
1086                 vm_map_remove(kernel_map, (vm_offset_t) ef->address,
1087                     (vm_offset_t) ef->address +
1088                     (ef->object->size << PAGE_SHIFT));
1089         }
1090         free(ef->e_shdr, M_LINKER);
1091         free(ef->ddbsymtab, M_LINKER);
1092         free(ef->ddbstrtab, M_LINKER);
1093         free(ef->shstrtab, M_LINKER);
1094         free(ef->ctftab, M_LINKER);
1095         free(ef->ctfoff, M_LINKER);
1096         free(ef->typoff, M_LINKER);
1097 }
1098
1099 static const char *
1100 symbol_name(elf_file_t ef, Elf_Size r_info)
1101 {
1102         const Elf_Sym *ref;
1103
1104         if (ELF_R_SYM(r_info)) {
1105                 ref = ef->ddbsymtab + ELF_R_SYM(r_info);
1106                 return ef->ddbstrtab + ref->st_name;
1107         } else
1108                 return NULL;
1109 }
1110
1111 static Elf_Addr
1112 findbase(elf_file_t ef, int sec)
1113 {
1114         int i;
1115         Elf_Addr base = 0;
1116
1117         for (i = 0; i < ef->nprogtab; i++) {
1118                 if (sec == ef->progtab[i].sec) {
1119                         base = (Elf_Addr)ef->progtab[i].addr;
1120                         break;
1121                 }
1122         }
1123         return base;
1124 }
1125
1126 static int
1127 relocate_file(elf_file_t ef)
1128 {
1129         const Elf_Rel *rellim;
1130         const Elf_Rel *rel;
1131         const Elf_Rela *relalim;
1132         const Elf_Rela *rela;
1133         const char *symname;
1134         const Elf_Sym *sym;
1135         int i;
1136         Elf_Size symidx;
1137         Elf_Addr base;
1138
1139
1140         /* Perform relocations without addend if there are any: */
1141         for (i = 0; i < ef->nreltab; i++) {
1142                 rel = ef->reltab[i].rel;
1143                 if (rel == NULL) {
1144                         link_elf_error(ef->lf.filename, "lost a reltab!");
1145                         return (ENOEXEC);
1146                 }
1147                 rellim = rel + ef->reltab[i].nrel;
1148                 base = findbase(ef, ef->reltab[i].sec);
1149                 if (base == 0) {
1150                         link_elf_error(ef->lf.filename, "lost base for reltab");
1151                         return (ENOEXEC);
1152                 }
1153                 for ( ; rel < rellim; rel++) {
1154                         symidx = ELF_R_SYM(rel->r_info);
1155                         if (symidx >= ef->ddbsymcnt)
1156                                 continue;
1157                         sym = ef->ddbsymtab + symidx;
1158                         /* Local relocs are already done */
1159                         if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
1160                                 continue;
1161                         if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL,
1162                             elf_obj_lookup)) {
1163                                 symname = symbol_name(ef, rel->r_info);
1164                                 printf("link_elf_obj: symbol %s undefined\n",
1165                                     symname);
1166                                 return (ENOENT);
1167                         }
1168                 }
1169         }
1170
1171         /* Perform relocations with addend if there are any: */
1172         for (i = 0; i < ef->nrelatab; i++) {
1173                 rela = ef->relatab[i].rela;
1174                 if (rela == NULL) {
1175                         link_elf_error(ef->lf.filename, "lost a relatab!");
1176                         return (ENOEXEC);
1177                 }
1178                 relalim = rela + ef->relatab[i].nrela;
1179                 base = findbase(ef, ef->relatab[i].sec);
1180                 if (base == 0) {
1181                         link_elf_error(ef->lf.filename,
1182                             "lost base for relatab");
1183                         return (ENOEXEC);
1184                 }
1185                 for ( ; rela < relalim; rela++) {
1186                         symidx = ELF_R_SYM(rela->r_info);
1187                         if (symidx >= ef->ddbsymcnt)
1188                                 continue;
1189                         sym = ef->ddbsymtab + symidx;
1190                         /* Local relocs are already done */
1191                         if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
1192                                 continue;
1193                         if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA,
1194                             elf_obj_lookup)) {
1195                                 symname = symbol_name(ef, rela->r_info);
1196                                 printf("link_elf_obj: symbol %s undefined\n",
1197                                     symname);
1198                                 return (ENOENT);
1199                         }
1200                 }
1201         }
1202
1203         /*
1204          * Only clean SHN_FBSD_CACHED for successful return.  If we
1205          * modified symbol table for the object but found an
1206          * unresolved symbol, there is no reason to roll back.
1207          */
1208         elf_obj_cleanup_globals_cache(ef);
1209
1210         return (0);
1211 }
1212
1213 static int
1214 link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
1215 {
1216         elf_file_t ef = (elf_file_t) lf;
1217         const Elf_Sym *symp;
1218         const char *strp;
1219         int i;
1220
1221         for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1222                 strp = ef->ddbstrtab + symp->st_name;
1223                 if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) {
1224                         *sym = (c_linker_sym_t) symp;
1225                         return 0;
1226                 }
1227         }
1228         return ENOENT;
1229 }
1230
1231 static int
1232 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
1233     linker_symval_t *symval)
1234 {
1235         elf_file_t ef;
1236         const Elf_Sym *es;
1237         caddr_t val;
1238
1239         ef = (elf_file_t) lf;
1240         es = (const Elf_Sym*) sym;
1241         val = (caddr_t)es->st_value;
1242         if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
1243                 symval->name = ef->ddbstrtab + es->st_name;
1244                 val = (caddr_t)es->st_value;
1245                 if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC)
1246                         val = ((caddr_t (*)(void))val)();
1247                 symval->value = val;
1248                 symval->size = es->st_size;
1249                 return 0;
1250         }
1251         return ENOENT;
1252 }
1253
1254 static int
1255 link_elf_search_symbol(linker_file_t lf, caddr_t value,
1256     c_linker_sym_t *sym, long *diffp)
1257 {
1258         elf_file_t ef = (elf_file_t) lf;
1259         u_long off = (uintptr_t) (void *) value;
1260         u_long diff = off;
1261         u_long st_value;
1262         const Elf_Sym *es;
1263         const Elf_Sym *best = NULL;
1264         int i;
1265
1266         for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) {
1267                 if (es->st_name == 0)
1268                         continue;
1269                 st_value = es->st_value;
1270                 if (off >= st_value) {
1271                         if (off - st_value < diff) {
1272                                 diff = off - st_value;
1273                                 best = es;
1274                                 if (diff == 0)
1275                                         break;
1276                         } else if (off - st_value == diff) {
1277                                 best = es;
1278                         }
1279                 }
1280         }
1281         if (best == NULL)
1282                 *diffp = off;
1283         else
1284                 *diffp = diff;
1285         *sym = (c_linker_sym_t) best;
1286
1287         return 0;
1288 }
1289
1290 /*
1291  * Look up a linker set on an ELF system.
1292  */
1293 static int
1294 link_elf_lookup_set(linker_file_t lf, const char *name,
1295     void ***startp, void ***stopp, int *countp)
1296 {
1297         elf_file_t ef = (elf_file_t)lf;
1298         void **start, **stop;
1299         int i, count;
1300
1301         /* Relative to section number */
1302         for (i = 0; i < ef->nprogtab; i++) {
1303                 if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) &&
1304                     strcmp(ef->progtab[i].name + 4, name) == 0) {
1305                         start  = (void **)ef->progtab[i].addr;
1306                         stop = (void **)((char *)ef->progtab[i].addr +
1307                             ef->progtab[i].size);
1308                         count = stop - start;
1309                         if (startp)
1310                                 *startp = start;
1311                         if (stopp)
1312                                 *stopp = stop;
1313                         if (countp)
1314                                 *countp = count;
1315                         return (0);
1316                 }
1317         }
1318         return (ESRCH);
1319 }
1320
1321 static int
1322 link_elf_each_function_name(linker_file_t file,
1323     int (*callback)(const char *, void *), void *opaque)
1324 {
1325         elf_file_t ef = (elf_file_t)file;
1326         const Elf_Sym *symp;
1327         int i, error;
1328         
1329         /* Exhaustive search */
1330         for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1331                 if (symp->st_value != 0 &&
1332                     (ELF_ST_TYPE(symp->st_info) == STT_FUNC ||
1333                     ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC)) {
1334                         error = callback(ef->ddbstrtab + symp->st_name, opaque);
1335                         if (error)
1336                                 return (error);
1337                 }
1338         }
1339         return (0);
1340 }
1341
1342 static int
1343 link_elf_each_function_nameval(linker_file_t file,
1344     linker_function_nameval_callback_t callback, void *opaque)
1345 {
1346         linker_symval_t symval;
1347         elf_file_t ef = (elf_file_t)file;
1348         const Elf_Sym* symp;
1349         int i, error;
1350
1351         /* Exhaustive search */
1352         for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1353                 if (symp->st_value != 0 &&
1354                     (ELF_ST_TYPE(symp->st_info) == STT_FUNC ||
1355                     ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC)) {
1356                         error = link_elf_symbol_values(file,
1357                             (c_linker_sym_t)symp, &symval);
1358                         if (error)
1359                                 return (error);
1360                         error = callback(file, i, &symval, opaque);
1361                         if (error)
1362                                 return (error);
1363                 }
1364         }
1365         return (0);
1366 }
1367
1368 static void
1369 elf_obj_cleanup_globals_cache(elf_file_t ef)
1370 {
1371         Elf_Sym *sym;
1372         Elf_Size i;
1373
1374         for (i = 0; i < ef->ddbsymcnt; i++) {
1375                 sym = ef->ddbsymtab + i;
1376                 if (sym->st_shndx == SHN_FBSD_CACHED) {
1377                         sym->st_shndx = SHN_UNDEF;
1378                         sym->st_value = 0;
1379                 }
1380         }
1381 }
1382
1383 /*
1384  * Symbol lookup function that can be used when the symbol index is known (ie
1385  * in relocations). It uses the symbol index instead of doing a fully fledged
1386  * hash table based lookup when such is valid. For example for local symbols.
1387  * This is not only more efficient, it's also more correct. It's not always
1388  * the case that the symbol can be found through the hash table.
1389  */
1390 static int
1391 elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res)
1392 {
1393         elf_file_t ef = (elf_file_t)lf;
1394         Elf_Sym *sym;
1395         const char *symbol;
1396         Elf_Addr res1;
1397
1398         /* Don't even try to lookup the symbol if the index is bogus. */
1399         if (symidx >= ef->ddbsymcnt) {
1400                 *res = 0;
1401                 return (EINVAL);
1402         }
1403
1404         sym = ef->ddbsymtab + symidx;
1405
1406         /* Quick answer if there is a definition included. */
1407         if (sym->st_shndx != SHN_UNDEF) {
1408                 res1 = (Elf_Addr)sym->st_value;
1409                 if (ELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC)
1410                         res1 = ((Elf_Addr (*)(void))res1)();
1411                 *res = res1;
1412                 return (0);
1413         }
1414
1415         /* If we get here, then it is undefined and needs a lookup. */
1416         switch (ELF_ST_BIND(sym->st_info)) {
1417         case STB_LOCAL:
1418                 /* Local, but undefined? huh? */
1419                 *res = 0;
1420                 return (EINVAL);
1421
1422         case STB_GLOBAL:
1423         case STB_WEAK:
1424                 /* Relative to Data or Function name */
1425                 symbol = ef->ddbstrtab + sym->st_name;
1426
1427                 /* Force a lookup failure if the symbol name is bogus. */
1428                 if (*symbol == 0) {
1429                         *res = 0;
1430                         return (EINVAL);
1431                 }
1432                 res1 = (Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps);
1433
1434                 /*
1435                  * Cache global lookups during module relocation. The failure
1436                  * case is particularly expensive for callers, who must scan
1437                  * through the entire globals table doing strcmp(). Cache to
1438                  * avoid doing such work repeatedly.
1439                  *
1440                  * After relocation is complete, undefined globals will be
1441                  * restored to SHN_UNDEF in elf_obj_cleanup_globals_cache(),
1442                  * above.
1443                  */
1444                 if (res1 != 0) {
1445                         sym->st_shndx = SHN_FBSD_CACHED;
1446                         sym->st_value = res1;
1447                         *res = res1;
1448                         return (0);
1449                 } else if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
1450                         sym->st_value = 0;
1451                         *res = 0;
1452                         return (0);
1453                 }
1454                 return (EINVAL);
1455
1456         default:
1457                 return (EINVAL);
1458         }
1459 }
1460
1461 static void
1462 link_elf_fix_link_set(elf_file_t ef)
1463 {
1464         static const char startn[] = "__start_";
1465         static const char stopn[] = "__stop_";
1466         Elf_Sym *sym;
1467         const char *sym_name, *linkset_name;
1468         Elf_Addr startp, stopp;
1469         Elf_Size symidx;
1470         int start, i;
1471
1472         startp = stopp = 0;
1473         for (symidx = 1 /* zero entry is special */;
1474                 symidx < ef->ddbsymcnt; symidx++) {
1475                 sym = ef->ddbsymtab + symidx;
1476                 if (sym->st_shndx != SHN_UNDEF)
1477                         continue;
1478
1479                 sym_name = ef->ddbstrtab + sym->st_name;
1480                 if (strncmp(sym_name, startn, sizeof(startn) - 1) == 0) {
1481                         start = 1;
1482                         linkset_name = sym_name + sizeof(startn) - 1;
1483                 }
1484                 else if (strncmp(sym_name, stopn, sizeof(stopn) - 1) == 0) {
1485                         start = 0;
1486                         linkset_name = sym_name + sizeof(stopn) - 1;
1487                 }
1488                 else
1489                         continue;
1490
1491                 for (i = 0; i < ef->nprogtab; i++) {
1492                         if (strcmp(ef->progtab[i].name, linkset_name) == 0) {
1493                                 startp = (Elf_Addr)ef->progtab[i].addr;
1494                                 stopp = (Elf_Addr)(startp + ef->progtab[i].size);
1495                                 break;
1496                         }
1497                 }
1498                 if (i == ef->nprogtab)
1499                         continue;
1500
1501                 sym->st_value = start ? startp : stopp;
1502                 sym->st_shndx = i;
1503         }
1504 }
1505
1506 static int
1507 link_elf_reloc_local(linker_file_t lf, bool ifuncs)
1508 {
1509         elf_file_t ef = (elf_file_t)lf;
1510         const Elf_Rel *rellim;
1511         const Elf_Rel *rel;
1512         const Elf_Rela *relalim;
1513         const Elf_Rela *rela;
1514         const Elf_Sym *sym;
1515         Elf_Addr base;
1516         int i;
1517         Elf_Size symidx;
1518
1519         link_elf_fix_link_set(ef);
1520
1521         /* Perform relocations without addend if there are any: */
1522         for (i = 0; i < ef->nreltab; i++) {
1523                 rel = ef->reltab[i].rel;
1524                 if (rel == NULL) {
1525                         link_elf_error(ef->lf.filename, "lost a reltab");
1526                         return (ENOEXEC);
1527                 }
1528                 rellim = rel + ef->reltab[i].nrel;
1529                 base = findbase(ef, ef->reltab[i].sec);
1530                 if (base == 0) {
1531                         link_elf_error(ef->lf.filename, "lost base for reltab");
1532                         return (ENOEXEC);
1533                 }
1534                 for ( ; rel < rellim; rel++) {
1535                         symidx = ELF_R_SYM(rel->r_info);
1536                         if (symidx >= ef->ddbsymcnt)
1537                                 continue;
1538                         sym = ef->ddbsymtab + symidx;
1539                         /* Only do local relocs */
1540                         if (ELF_ST_BIND(sym->st_info) != STB_LOCAL)
1541                                 continue;
1542                         if ((ELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC ||
1543                             elf_is_ifunc_reloc(rel->r_info)) == ifuncs)
1544                                 elf_reloc_local(lf, base, rel, ELF_RELOC_REL,
1545                                     elf_obj_lookup);
1546                 }
1547         }
1548
1549         /* Perform relocations with addend if there are any: */
1550         for (i = 0; i < ef->nrelatab; i++) {
1551                 rela = ef->relatab[i].rela;
1552                 if (rela == NULL) {
1553                         link_elf_error(ef->lf.filename, "lost a relatab!");
1554                         return (ENOEXEC);
1555                 }
1556                 relalim = rela + ef->relatab[i].nrela;
1557                 base = findbase(ef, ef->relatab[i].sec);
1558                 if (base == 0) {
1559                         link_elf_error(ef->lf.filename, "lost base for reltab");
1560                         return (ENOEXEC);
1561                 }
1562                 for ( ; rela < relalim; rela++) {
1563                         symidx = ELF_R_SYM(rela->r_info);
1564                         if (symidx >= ef->ddbsymcnt)
1565                                 continue;
1566                         sym = ef->ddbsymtab + symidx;
1567                         /* Only do local relocs */
1568                         if (ELF_ST_BIND(sym->st_info) != STB_LOCAL)
1569                                 continue;
1570                         if ((ELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC ||
1571                             elf_is_ifunc_reloc(rela->r_info)) == ifuncs)
1572                                 elf_reloc_local(lf, base, rela, ELF_RELOC_RELA,
1573                                     elf_obj_lookup);
1574                 }
1575         }
1576         return (0);
1577 }
1578
1579 static long
1580 link_elf_symtab_get(linker_file_t lf, const Elf_Sym **symtab)
1581 {
1582     elf_file_t ef = (elf_file_t)lf;
1583     
1584     *symtab = ef->ddbsymtab;
1585     
1586     if (*symtab == NULL)
1587         return (0);
1588
1589     return (ef->ddbsymcnt);
1590 }
1591     
1592 static long
1593 link_elf_strtab_get(linker_file_t lf, caddr_t *strtab)
1594 {
1595     elf_file_t ef = (elf_file_t)lf;
1596
1597     *strtab = ef->ddbstrtab;
1598
1599     if (*strtab == NULL)
1600         return (0);
1601
1602     return (ef->ddbstrcnt);
1603 }