FreeBSD kernel kern code
link_elf_obj.c
Go to the documentation of this file.
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("$BSDSUniX$");
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 <net/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 
98  int nprogtab;
99 
101  int nrelatab;
102 
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 void link_elf_reloc_local(linker_file_t);
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 Elf_Addr elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps);
148 
149 static kobj_method_t link_elf_methods[] = {
150  KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
151  KOBJMETHOD(linker_symbol_values, link_elf_symbol_values),
152  KOBJMETHOD(linker_search_symbol, link_elf_search_symbol),
153  KOBJMETHOD(linker_unload, link_elf_unload_file),
155  KOBJMETHOD(linker_link_preload, link_elf_link_preload),
156  KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
157  KOBJMETHOD(linker_lookup_set, link_elf_lookup_set),
158  KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
159  KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval),
160  KOBJMETHOD(linker_ctf_get, link_elf_ctf_get),
161  KOBJMETHOD(linker_symtab_get, link_elf_symtab_get),
162  KOBJMETHOD(linker_strtab_get, link_elf_strtab_get),
163  { 0, 0 }
164 };
165 
166 static struct linker_class link_elf_class = {
167 #if ELF_TARG_CLASS == ELFCLASS32
168  "elf32_obj",
169 #else
170  "elf64_obj",
171 #endif
172  link_elf_methods, sizeof(struct elf_file)
173 };
174 
175 static int relocate_file(elf_file_t ef);
176 
177 static void
178 link_elf_error(const char *filename, const char *s)
179 {
180  if (filename == NULL)
181  printf("kldload: %s\n", s);
182  else
183  printf("kldload: %s: %s\n", filename, s);
184 }
185 
186 static void
187 link_elf_init(void *arg)
188 {
189 
190  linker_add_class(&link_elf_class);
191 }
192 
193 SYSINIT(link_elf_obj, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0);
194 
195 static int
196 link_elf_link_preload(linker_class_t cls, const char *filename,
197  linker_file_t *result)
198 {
199  Elf_Ehdr *hdr;
200  Elf_Shdr *shdr;
201  Elf_Sym *es;
202  void *modptr, *baseptr, *sizeptr;
203  char *type;
204  elf_file_t ef;
205  linker_file_t lf;
206  Elf_Addr off;
207  int error, i, j, pb, ra, rl, shstrindex, symstrindex, symtabindex;
208 
209  /* Look to see if we have the file preloaded */
210  modptr = preload_search_by_name(filename);
211  if (modptr == NULL)
212  return ENOENT;
213 
214  type = (char *)preload_search_info(modptr, MODINFO_TYPE);
215  baseptr = preload_search_info(modptr, MODINFO_ADDR);
216  sizeptr = preload_search_info(modptr, MODINFO_SIZE);
217  hdr = (Elf_Ehdr *)preload_search_info(modptr, MODINFO_METADATA |
218  MODINFOMD_ELFHDR);
219  shdr = (Elf_Shdr *)preload_search_info(modptr, MODINFO_METADATA |
220  MODINFOMD_SHDR);
221  if (type == NULL || (strcmp(type, "elf" __XSTRING(__ELF_WORD_SIZE)
222  " obj module") != 0 &&
223  strcmp(type, "elf obj module") != 0)) {
224  return (EFTYPE);
225  }
226  if (baseptr == NULL || sizeptr == NULL || hdr == NULL ||
227  shdr == NULL)
228  return (EINVAL);
229 
230  lf = linker_make_file(filename, &link_elf_class);
231  if (lf == NULL)
232  return (ENOMEM);
233 
234  ef = (elf_file_t)lf;
235  ef->preloaded = 1;
236  ef->address = *(caddr_t *)baseptr;
237  lf->address = *(caddr_t *)baseptr;
238  lf->size = *(size_t *)sizeptr;
239 
240  if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
241  hdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
242  hdr->e_ident[EI_VERSION] != EV_CURRENT ||
243  hdr->e_version != EV_CURRENT ||
244  hdr->e_type != ET_REL ||
245  hdr->e_machine != ELF_TARG_MACH) {
246  error = EFTYPE;
247  goto out;
248  }
249  ef->e_shdr = shdr;
250 
251  /* Scan the section header for information and table sizing. */
252  symtabindex = -1;
253  symstrindex = -1;
254  for (i = 0; i < hdr->e_shnum; i++) {
255  switch (shdr[i].sh_type) {
256  case SHT_PROGBITS:
257  case SHT_NOBITS:
258 #ifdef __amd64__
259  case SHT_AMD64_UNWIND:
260 #endif
261  ef->nprogtab++;
262  break;
263  case SHT_SYMTAB:
264  symtabindex = i;
265  symstrindex = shdr[i].sh_link;
266  break;
267  case SHT_REL:
268  ef->nreltab++;
269  break;
270  case SHT_RELA:
271  ef->nrelatab++;
272  break;
273  }
274  }
275 
276  shstrindex = hdr->e_shstrndx;
277  if (ef->nprogtab == 0 || symstrindex < 0 ||
278  symstrindex >= hdr->e_shnum ||
279  shdr[symstrindex].sh_type != SHT_STRTAB || shstrindex == 0 ||
280  shstrindex >= hdr->e_shnum ||
281  shdr[shstrindex].sh_type != SHT_STRTAB) {
282  printf("%s: bad/missing section headers\n", filename);
283  error = ENOEXEC;
284  goto out;
285  }
286 
287  /* Allocate space for tracking the load chunks */
288  if (ef->nprogtab != 0)
289  ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab),
290  M_LINKER, M_WAITOK | M_ZERO);
291  if (ef->nreltab != 0)
292  ef->reltab = malloc(ef->nreltab * sizeof(*ef->reltab),
293  M_LINKER, M_WAITOK | M_ZERO);
294  if (ef->nrelatab != 0)
295  ef->relatab = malloc(ef->nrelatab * sizeof(*ef->relatab),
296  M_LINKER, M_WAITOK | M_ZERO);
297  if ((ef->nprogtab != 0 && ef->progtab == NULL) ||
298  (ef->nreltab != 0 && ef->reltab == NULL) ||
299  (ef->nrelatab != 0 && ef->relatab == NULL)) {
300  error = ENOMEM;
301  goto out;
302  }
303 
304  /* XXX, relocate the sh_addr fields saved by the loader. */
305  off = 0;
306  for (i = 0; i < hdr->e_shnum; i++) {
307  if (shdr[i].sh_addr != 0 && (off == 0 || shdr[i].sh_addr < off))
308  off = shdr[i].sh_addr;
309  }
310  for (i = 0; i < hdr->e_shnum; i++) {
311  if (shdr[i].sh_addr != 0)
312  shdr[i].sh_addr = shdr[i].sh_addr - off +
313  (Elf_Addr)ef->address;
314  }
315 
316  ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
317  ef->ddbsymtab = (Elf_Sym *)shdr[symtabindex].sh_addr;
318  ef->ddbstrcnt = shdr[symstrindex].sh_size;
319  ef->ddbstrtab = (char *)shdr[symstrindex].sh_addr;
320  ef->shstrcnt = shdr[shstrindex].sh_size;
321  ef->shstrtab = (char *)shdr[shstrindex].sh_addr;
322 
323  /* Now fill out progtab and the relocation tables. */
324  pb = 0;
325  rl = 0;
326  ra = 0;
327  for (i = 0; i < hdr->e_shnum; i++) {
328  switch (shdr[i].sh_type) {
329  case SHT_PROGBITS:
330  case SHT_NOBITS:
331 #ifdef __amd64__
332  case SHT_AMD64_UNWIND:
333 #endif
334  ef->progtab[pb].addr = (void *)shdr[i].sh_addr;
335  if (shdr[i].sh_type == SHT_PROGBITS)
336  ef->progtab[pb].name = "<<PROGBITS>>";
337 #ifdef __amd64__
338  else if (shdr[i].sh_type == SHT_AMD64_UNWIND)
339  ef->progtab[pb].name = "<<UNWIND>>";
340 #endif
341  else
342  ef->progtab[pb].name = "<<NOBITS>>";
343  ef->progtab[pb].size = shdr[i].sh_size;
344  ef->progtab[pb].sec = i;
345  if (ef->shstrtab && shdr[i].sh_name != 0)
346  ef->progtab[pb].name =
347  ef->shstrtab + shdr[i].sh_name;
348  if (ef->progtab[pb].name != NULL &&
349  !strcmp(ef->progtab[pb].name, DPCPU_SETNAME)) {
350  void *dpcpu;
351 
352  dpcpu = dpcpu_alloc(shdr[i].sh_size);
353  if (dpcpu == NULL) {
354  error = ENOSPC;
355  goto out;
356  }
357  memcpy(dpcpu, ef->progtab[pb].addr,
358  ef->progtab[pb].size);
359  dpcpu_copy(dpcpu, shdr[i].sh_size);
360  ef->progtab[pb].addr = dpcpu;
361 #ifdef VIMAGE
362  } else if (ef->progtab[pb].name != NULL &&
363  !strcmp(ef->progtab[pb].name, VNET_SETNAME)) {
364  void *vnet_data;
365 
366  vnet_data = vnet_data_alloc(shdr[i].sh_size);
367  if (vnet_data == NULL) {
368  error = ENOSPC;
369  goto out;
370  }
371  memcpy(vnet_data, ef->progtab[pb].addr,
372  ef->progtab[pb].size);
373  vnet_data_copy(vnet_data, shdr[i].sh_size);
374  ef->progtab[pb].addr = vnet_data;
375 #endif
376  }
377 
378  /* Update all symbol values with the offset. */
379  for (j = 0; j < ef->ddbsymcnt; j++) {
380  es = &ef->ddbsymtab[j];
381  if (es->st_shndx != i)
382  continue;
383  es->st_value += (Elf_Addr)ef->progtab[pb].addr;
384  }
385  pb++;
386  break;
387  case SHT_REL:
388  ef->reltab[rl].rel = (Elf_Rel *)shdr[i].sh_addr;
389  ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel);
390  ef->reltab[rl].sec = shdr[i].sh_info;
391  rl++;
392  break;
393  case SHT_RELA:
394  ef->relatab[ra].rela = (Elf_Rela *)shdr[i].sh_addr;
395  ef->relatab[ra].nrela =
396  shdr[i].sh_size / sizeof(Elf_Rela);
397  ef->relatab[ra].sec = shdr[i].sh_info;
398  ra++;
399  break;
400  }
401  }
402  if (pb != ef->nprogtab)
403  panic("lost progbits");
404  if (rl != ef->nreltab)
405  panic("lost reltab");
406  if (ra != ef->nrelatab)
407  panic("lost relatab");
408 
409  /* Local intra-module relocations */
411 
412  *result = lf;
413  return (0);
414 
415 out:
416  /* preload not done this way */
417  linker_file_unload(lf, LINKER_UNLOAD_FORCE);
418  return (error);
419 }
420 
421 static int
423 {
424  elf_file_t ef;
425  int error;
426 
427  ef = (elf_file_t)lf;
428  error = relocate_file(ef);
429  if (error)
430  return error;
431 
432  /* Notify MD code that a module is being loaded. */
433  error = elf_cpu_load_file(lf);
434  if (error)
435  return (error);
436 
437  return (0);
438 }
439 
440 static int
441 link_elf_load_file(linker_class_t cls, const char *filename,
442  linker_file_t *result)
443 {
444  struct nameidata nd;
445  struct thread *td = curthread; /* XXX */
446  Elf_Ehdr *hdr;
447  Elf_Shdr *shdr;
448  Elf_Sym *es;
449  int nbytes, i, j;
450  vm_offset_t mapbase;
451  size_t mapsize;
452  int error = 0;
453  ssize_t resid;
454  int flags;
455  elf_file_t ef;
456  linker_file_t lf;
457  int symtabindex;
458  int symstrindex;
459  int shstrindex;
460  int nsym;
461  int pb, rl, ra;
462  int alignmask;
463  int vfslocked;
464 
465  shdr = NULL;
466  lf = NULL;
467  mapsize = 0;
468  hdr = NULL;
469 
470  NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, filename, td);
471  flags = FREAD;
472  error = vn_open(&nd, &flags, 0, NULL);
473  if (error)
474  return error;
475  vfslocked = NDHASGIANT(&nd);
476  NDFREE(&nd, NDF_ONLY_PNBUF);
477  if (nd.ni_vp->v_type != VREG) {
478  error = ENOEXEC;
479  goto out;
480  }
481 #ifdef MAC
482  error = mac_kld_check_load(td->td_ucred, nd.ni_vp);
483  if (error) {
484  goto out;
485  }
486 #endif
487 
488  /* Read the elf header from the file. */
489  hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK);
490  error = vn_rdwr(UIO_READ, nd.ni_vp, (void *)hdr, sizeof(*hdr), 0,
491  UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
492  &resid, td);
493  if (error)
494  goto out;
495  if (resid != 0){
496  error = ENOEXEC;
497  goto out;
498  }
499 
500  if (!IS_ELF(*hdr)) {
501  error = ENOEXEC;
502  goto out;
503  }
504 
505  if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS
506  || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
507  link_elf_error(filename, "Unsupported file layout");
508  error = ENOEXEC;
509  goto out;
510  }
511  if (hdr->e_ident[EI_VERSION] != EV_CURRENT
512  || hdr->e_version != EV_CURRENT) {
513  link_elf_error(filename, "Unsupported file version");
514  error = ENOEXEC;
515  goto out;
516  }
517  if (hdr->e_type != ET_REL) {
518  error = ENOSYS;
519  goto out;
520  }
521  if (hdr->e_machine != ELF_TARG_MACH) {
522  link_elf_error(filename, "Unsupported machine");
523  error = ENOEXEC;
524  goto out;
525  }
526 
527  lf = linker_make_file(filename, &link_elf_class);
528  if (!lf) {
529  error = ENOMEM;
530  goto out;
531  }
532  ef = (elf_file_t) lf;
533  ef->nprogtab = 0;
534  ef->e_shdr = 0;
535  ef->nreltab = 0;
536  ef->nrelatab = 0;
537 
538  /* Allocate and read in the section header */
539  nbytes = hdr->e_shnum * hdr->e_shentsize;
540  if (nbytes == 0 || hdr->e_shoff == 0 ||
541  hdr->e_shentsize != sizeof(Elf_Shdr)) {
542  error = ENOEXEC;
543  goto out;
544  }
545  shdr = malloc(nbytes, M_LINKER, M_WAITOK);
546  ef->e_shdr = shdr;
547  error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes, hdr->e_shoff,
548  UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td);
549  if (error)
550  goto out;
551  if (resid) {
552  error = ENOEXEC;
553  goto out;
554  }
555 
556  /* Scan the section header for information and table sizing. */
557  nsym = 0;
558  symtabindex = -1;
559  symstrindex = -1;
560  for (i = 0; i < hdr->e_shnum; i++) {
561  if (shdr[i].sh_size == 0)
562  continue;
563  switch (shdr[i].sh_type) {
564  case SHT_PROGBITS:
565  case SHT_NOBITS:
566 #ifdef __amd64__
567  case SHT_AMD64_UNWIND:
568 #endif
569  ef->nprogtab++;
570  break;
571  case SHT_SYMTAB:
572  nsym++;
573  symtabindex = i;
574  symstrindex = shdr[i].sh_link;
575  break;
576  case SHT_REL:
577  ef->nreltab++;
578  break;
579  case SHT_RELA:
580  ef->nrelatab++;
581  break;
582  case SHT_STRTAB:
583  break;
584  }
585  }
586  if (ef->nprogtab == 0) {
587  link_elf_error(filename, "file has no contents");
588  error = ENOEXEC;
589  goto out;
590  }
591  if (nsym != 1) {
592  /* Only allow one symbol table for now */
593  link_elf_error(filename, "file has no valid symbol table");
594  error = ENOEXEC;
595  goto out;
596  }
597  if (symstrindex < 0 || symstrindex > hdr->e_shnum ||
598  shdr[symstrindex].sh_type != SHT_STRTAB) {
599  link_elf_error(filename, "file has invalid symbol strings");
600  error = ENOEXEC;
601  goto out;
602  }
603 
604  /* Allocate space for tracking the load chunks */
605  if (ef->nprogtab != 0)
606  ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab),
607  M_LINKER, M_WAITOK | M_ZERO);
608  if (ef->nreltab != 0)
609  ef->reltab = malloc(ef->nreltab * sizeof(*ef->reltab),
610  M_LINKER, M_WAITOK | M_ZERO);
611  if (ef->nrelatab != 0)
612  ef->relatab = malloc(ef->nrelatab * sizeof(*ef->relatab),
613  M_LINKER, M_WAITOK | M_ZERO);
614 
615  if (symtabindex == -1)
616  panic("lost symbol table index");
617  /* Allocate space for and load the symbol table */
618  ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
619  ef->ddbsymtab = malloc(shdr[symtabindex].sh_size, M_LINKER, M_WAITOK);
620  error = vn_rdwr(UIO_READ, nd.ni_vp, (void *)ef->ddbsymtab,
621  shdr[symtabindex].sh_size, shdr[symtabindex].sh_offset,
622  UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
623  &resid, td);
624  if (error)
625  goto out;
626  if (resid != 0){
627  error = EINVAL;
628  goto out;
629  }
630 
631  if (symstrindex == -1)
632  panic("lost symbol string index");
633  /* Allocate space for and load the symbol strings */
634  ef->ddbstrcnt = shdr[symstrindex].sh_size;
635  ef->ddbstrtab = malloc(shdr[symstrindex].sh_size, M_LINKER, M_WAITOK);
636  error = vn_rdwr(UIO_READ, nd.ni_vp, ef->ddbstrtab,
637  shdr[symstrindex].sh_size, shdr[symstrindex].sh_offset,
638  UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
639  &resid, td);
640  if (error)
641  goto out;
642  if (resid != 0){
643  error = EINVAL;
644  goto out;
645  }
646 
647  /* Do we have a string table for the section names? */
648  shstrindex = -1;
649  if (hdr->e_shstrndx != 0 &&
650  shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
651  shstrindex = hdr->e_shstrndx;
652  ef->shstrcnt = shdr[shstrindex].sh_size;
653  ef->shstrtab = malloc(shdr[shstrindex].sh_size, M_LINKER,
654  M_WAITOK);
655  error = vn_rdwr(UIO_READ, nd.ni_vp, ef->shstrtab,
656  shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset,
657  UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
658  &resid, td);
659  if (error)
660  goto out;
661  if (resid != 0){
662  error = EINVAL;
663  goto out;
664  }
665  }
666 
667  /* Size up code/data(progbits) and bss(nobits). */
668  alignmask = 0;
669  for (i = 0; i < hdr->e_shnum; i++) {
670  if (shdr[i].sh_size == 0)
671  continue;
672  switch (shdr[i].sh_type) {
673  case SHT_PROGBITS:
674  case SHT_NOBITS:
675 #ifdef __amd64__
676  case SHT_AMD64_UNWIND:
677 #endif
678  alignmask = shdr[i].sh_addralign - 1;
679  mapsize += alignmask;
680  mapsize &= ~alignmask;
681  mapsize += shdr[i].sh_size;
682  break;
683  }
684  }
685 
686  /*
687  * We know how much space we need for the text/data/bss/etc.
688  * This stuff needs to be in a single chunk so that profiling etc
689  * can get the bounds and gdb can associate offsets with modules
690  */
691  ef->object = vm_object_allocate(OBJT_DEFAULT,
692  round_page(mapsize) >> PAGE_SHIFT);
693  if (ef->object == NULL) {
694  error = ENOMEM;
695  goto out;
696  }
697  ef->address = (caddr_t) vm_map_min(kernel_map);
698 
699  /*
700  * In order to satisfy amd64's architectural requirements on the
701  * location of code and data in the kernel's address space, request a
702  * mapping that is above the kernel.
703  */
704  mapbase = KERNBASE;
705  error = vm_map_find(kernel_map, ef->object, 0, &mapbase,
706  round_page(mapsize), TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE);
707  if (error) {
708  vm_object_deallocate(ef->object);
709  ef->object = 0;
710  goto out;
711  }
712 
713  /* Wire the pages */
714  error = vm_map_wire(kernel_map, mapbase,
715  mapbase + round_page(mapsize),
716  VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES);
717  if (error != KERN_SUCCESS) {
718  error = ENOMEM;
719  goto out;
720  }
721 
722  /* Inform the kld system about the situation */
723  lf->address = ef->address = (caddr_t)mapbase;
724  lf->size = mapsize;
725 
726  /*
727  * Now load code/data(progbits), zero bss(nobits), allocate space for
728  * and load relocs
729  */
730  pb = 0;
731  rl = 0;
732  ra = 0;
733  alignmask = 0;
734  for (i = 0; i < hdr->e_shnum; i++) {
735  if (shdr[i].sh_size == 0)
736  continue;
737  switch (shdr[i].sh_type) {
738  case SHT_PROGBITS:
739  case SHT_NOBITS:
740 #ifdef __amd64__
741  case SHT_AMD64_UNWIND:
742 #endif
743  alignmask = shdr[i].sh_addralign - 1;
744  mapbase += alignmask;
745  mapbase &= ~alignmask;
746  if (ef->shstrtab && shdr[i].sh_name != 0)
747  ef->progtab[pb].name =
748  ef->shstrtab + shdr[i].sh_name;
749  else if (shdr[i].sh_type == SHT_PROGBITS)
750  ef->progtab[pb].name = "<<PROGBITS>>";
751 #ifdef __amd64__
752  else if (shdr[i].sh_type == SHT_AMD64_UNWIND)
753  ef->progtab[pb].name = "<<UNWIND>>";
754 #endif
755  else
756  ef->progtab[pb].name = "<<NOBITS>>";
757  if (ef->progtab[pb].name != NULL &&
758  !strcmp(ef->progtab[pb].name, DPCPU_SETNAME))
759  ef->progtab[pb].addr =
760  dpcpu_alloc(shdr[i].sh_size);
761 #ifdef VIMAGE
762  else if (ef->progtab[pb].name != NULL &&
763  !strcmp(ef->progtab[pb].name, VNET_SETNAME))
764  ef->progtab[pb].addr =
765  vnet_data_alloc(shdr[i].sh_size);
766 #endif
767  else
768  ef->progtab[pb].addr =
769  (void *)(uintptr_t)mapbase;
770  if (ef->progtab[pb].addr == NULL) {
771  error = ENOSPC;
772  goto out;
773  }
774  ef->progtab[pb].size = shdr[i].sh_size;
775  ef->progtab[pb].sec = i;
776  if (shdr[i].sh_type == SHT_PROGBITS
777 #ifdef __amd64__
778  || shdr[i].sh_type == SHT_AMD64_UNWIND
779 #endif
780  ) {
781  error = vn_rdwr(UIO_READ, nd.ni_vp,
782  ef->progtab[pb].addr,
783  shdr[i].sh_size, shdr[i].sh_offset,
784  UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
785  NOCRED, &resid, td);
786  if (error)
787  goto out;
788  if (resid != 0){
789  error = EINVAL;
790  goto out;
791  }
792  /* Initialize the per-cpu or vnet area. */
793  if (ef->progtab[pb].addr != (void *)mapbase &&
794  !strcmp(ef->progtab[pb].name, DPCPU_SETNAME))
795  dpcpu_copy(ef->progtab[pb].addr,
796  shdr[i].sh_size);
797 #ifdef VIMAGE
798  else if (ef->progtab[pb].addr !=
799  (void *)mapbase &&
800  !strcmp(ef->progtab[pb].name, VNET_SETNAME))
801  vnet_data_copy(ef->progtab[pb].addr,
802  shdr[i].sh_size);
803 #endif
804  } else
805  bzero(ef->progtab[pb].addr, shdr[i].sh_size);
806 
807  /* Update all symbol values with the offset. */
808  for (j = 0; j < ef->ddbsymcnt; j++) {
809  es = &ef->ddbsymtab[j];
810  if (es->st_shndx != i)
811  continue;
812  es->st_value += (Elf_Addr)ef->progtab[pb].addr;
813  }
814  mapbase += shdr[i].sh_size;
815  pb++;
816  break;
817  case SHT_REL:
818  ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER,
819  M_WAITOK);
820  ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel);
821  ef->reltab[rl].sec = shdr[i].sh_info;
822  error = vn_rdwr(UIO_READ, nd.ni_vp,
823  (void *)ef->reltab[rl].rel,
824  shdr[i].sh_size, shdr[i].sh_offset,
825  UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
826  &resid, td);
827  if (error)
828  goto out;
829  if (resid != 0){
830  error = EINVAL;
831  goto out;
832  }
833  rl++;
834  break;
835  case SHT_RELA:
836  ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER,
837  M_WAITOK);
838  ef->relatab[ra].nrela =
839  shdr[i].sh_size / sizeof(Elf_Rela);
840  ef->relatab[ra].sec = shdr[i].sh_info;
841  error = vn_rdwr(UIO_READ, nd.ni_vp,
842  (void *)ef->relatab[ra].rela,
843  shdr[i].sh_size, shdr[i].sh_offset,
844  UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
845  &resid, td);
846  if (error)
847  goto out;
848  if (resid != 0){
849  error = EINVAL;
850  goto out;
851  }
852  ra++;
853  break;
854  }
855  }
856  if (pb != ef->nprogtab)
857  panic("lost progbits");
858  if (rl != ef->nreltab)
859  panic("lost reltab");
860  if (ra != ef->nrelatab)
861  panic("lost relatab");
862  if (mapbase != (vm_offset_t)ef->address + mapsize)
863  panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n",
864  (u_long)mapbase, ef->address, (u_long)mapsize,
865  (u_long)(vm_offset_t)ef->address + mapsize);
866 
867  /* Local intra-module relocations */
869 
870  /* Pull in dependencies */
871  VOP_UNLOCK(nd.ni_vp, 0);
872  error = linker_load_dependencies(lf);
873  vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY);
874  if (error)
875  goto out;
876 
877  /* External relocations */
878  error = relocate_file(ef);
879  if (error)
880  goto out;
881 
882  /* Notify MD code that a module is being loaded. */
883  error = elf_cpu_load_file(lf);
884  if (error)
885  goto out;
886 
887  *result = lf;
888 
889 out:
890  VOP_UNLOCK(nd.ni_vp, 0);
891  vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
892  VFS_UNLOCK_GIANT(vfslocked);
893  if (error && lf)
894  linker_file_unload(lf, LINKER_UNLOAD_FORCE);
895  if (hdr)
896  free(hdr, M_LINKER);
897 
898  return error;
899 }
900 
901 static void
902 link_elf_unload_file(linker_file_t file)
903 {
904  elf_file_t ef = (elf_file_t) file;
905  int i;
906 
907  /* Notify MD code that a module is being unloaded. */
908  elf_cpu_unload_file(file);
909 
910  if (ef->progtab) {
911  for (i = 0; i < ef->nprogtab; i++) {
912  if (ef->progtab[i].size == 0)
913  continue;
914  if (ef->progtab[i].name == NULL)
915  continue;
916  if (!strcmp(ef->progtab[i].name, DPCPU_SETNAME))
917  dpcpu_free(ef->progtab[i].addr,
918  ef->progtab[i].size);
919 #ifdef VIMAGE
920  else if (!strcmp(ef->progtab[i].name, VNET_SETNAME))
921  vnet_data_free(ef->progtab[i].addr,
922  ef->progtab[i].size);
923 #endif
924  }
925  }
926  if (ef->preloaded) {
927  if (ef->reltab)
928  free(ef->reltab, M_LINKER);
929  if (ef->relatab)
930  free(ef->relatab, M_LINKER);
931  if (ef->progtab)
932  free(ef->progtab, M_LINKER);
933  if (ef->ctftab)
934  free(ef->ctftab, M_LINKER);
935  if (ef->ctfoff)
936  free(ef->ctfoff, M_LINKER);
937  if (ef->typoff)
938  free(ef->typoff, M_LINKER);
939  if (file->filename != NULL)
940  preload_delete_name(file->filename);
941  /* XXX reclaim module memory? */
942  return;
943  }
944 
945  for (i = 0; i < ef->nreltab; i++)
946  if (ef->reltab[i].rel)
947  free(ef->reltab[i].rel, M_LINKER);
948  for (i = 0; i < ef->nrelatab; i++)
949  if (ef->relatab[i].rela)
950  free(ef->relatab[i].rela, M_LINKER);
951  if (ef->reltab)
952  free(ef->reltab, M_LINKER);
953  if (ef->relatab)
954  free(ef->relatab, M_LINKER);
955  if (ef->progtab)
956  free(ef->progtab, M_LINKER);
957 
958  if (ef->object) {
959  vm_map_remove(kernel_map, (vm_offset_t) ef->address,
960  (vm_offset_t) ef->address +
961  (ef->object->size << PAGE_SHIFT));
962  }
963  if (ef->e_shdr)
964  free(ef->e_shdr, M_LINKER);
965  if (ef->ddbsymtab)
966  free(ef->ddbsymtab, M_LINKER);
967  if (ef->ddbstrtab)
968  free(ef->ddbstrtab, M_LINKER);
969  if (ef->shstrtab)
970  free(ef->shstrtab, M_LINKER);
971  if (ef->ctftab)
972  free(ef->ctftab, M_LINKER);
973  if (ef->ctfoff)
974  free(ef->ctfoff, M_LINKER);
975  if (ef->typoff)
976  free(ef->typoff, M_LINKER);
977 }
978 
979 static const char *
980 symbol_name(elf_file_t ef, Elf_Size r_info)
981 {
982  const Elf_Sym *ref;
983 
984  if (ELF_R_SYM(r_info)) {
985  ref = ef->ddbsymtab + ELF_R_SYM(r_info);
986  return ef->ddbstrtab + ref->st_name;
987  } else
988  return NULL;
989 }
990 
991 static Elf_Addr
992 findbase(elf_file_t ef, int sec)
993 {
994  int i;
995  Elf_Addr base = 0;
996 
997  for (i = 0; i < ef->nprogtab; i++) {
998  if (sec == ef->progtab[i].sec) {
999  base = (Elf_Addr)ef->progtab[i].addr;
1000  break;
1001  }
1002  }
1003  return base;
1004 }
1005 
1006 static int
1008 {
1009  const Elf_Rel *rellim;
1010  const Elf_Rel *rel;
1011  const Elf_Rela *relalim;
1012  const Elf_Rela *rela;
1013  const char *symname;
1014  const Elf_Sym *sym;
1015  int i;
1016  Elf_Size symidx;
1017  Elf_Addr base;
1018 
1019 
1020  /* Perform relocations without addend if there are any: */
1021  for (i = 0; i < ef->nreltab; i++) {
1022  rel = ef->reltab[i].rel;
1023  if (rel == NULL)
1024  panic("lost a reltab!");
1025  rellim = rel + ef->reltab[i].nrel;
1026  base = findbase(ef, ef->reltab[i].sec);
1027  if (base == 0)
1028  panic("lost base for reltab");
1029  for ( ; rel < rellim; rel++) {
1030  symidx = ELF_R_SYM(rel->r_info);
1031  if (symidx >= ef->ddbsymcnt)
1032  continue;
1033  sym = ef->ddbsymtab + symidx;
1034  /* Local relocs are already done */
1035  if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
1036  continue;
1037  if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL,
1038  elf_obj_lookup)) {
1039  symname = symbol_name(ef, rel->r_info);
1040  printf("link_elf_obj: symbol %s undefined\n",
1041  symname);
1042  return ENOENT;
1043  }
1044  }
1045  }
1046 
1047  /* Perform relocations with addend if there are any: */
1048  for (i = 0; i < ef->nrelatab; i++) {
1049  rela = ef->relatab[i].rela;
1050  if (rela == NULL)
1051  panic("lost a relatab!");
1052  relalim = rela + ef->relatab[i].nrela;
1053  base = findbase(ef, ef->relatab[i].sec);
1054  if (base == 0)
1055  panic("lost base for relatab");
1056  for ( ; rela < relalim; rela++) {
1057  symidx = ELF_R_SYM(rela->r_info);
1058  if (symidx >= ef->ddbsymcnt)
1059  continue;
1060  sym = ef->ddbsymtab + symidx;
1061  /* Local relocs are already done */
1062  if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
1063  continue;
1064  if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA,
1065  elf_obj_lookup)) {
1066  symname = symbol_name(ef, rela->r_info);
1067  printf("link_elf_obj: symbol %s undefined\n",
1068  symname);
1069  return ENOENT;
1070  }
1071  }
1072  }
1073 
1074  return 0;
1075 }
1076 
1077 static int
1078 link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
1079 {
1080  elf_file_t ef = (elf_file_t) lf;
1081  const Elf_Sym *symp;
1082  const char *strp;
1083  int i;
1084 
1085  for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1086  strp = ef->ddbstrtab + symp->st_name;
1087  if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) {
1088  *sym = (c_linker_sym_t) symp;
1089  return 0;
1090  }
1091  }
1092  return ENOENT;
1093 }
1094 
1095 static int
1096 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
1097  linker_symval_t *symval)
1098 {
1099  elf_file_t ef = (elf_file_t) lf;
1100  const Elf_Sym *es = (const Elf_Sym*) sym;
1101 
1102  if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
1103  symval->name = ef->ddbstrtab + es->st_name;
1104  symval->value = (caddr_t)es->st_value;
1105  symval->size = es->st_size;
1106  return 0;
1107  }
1108  return ENOENT;
1109 }
1110 
1111 static int
1112 link_elf_search_symbol(linker_file_t lf, caddr_t value,
1113  c_linker_sym_t *sym, long *diffp)
1114 {
1115  elf_file_t ef = (elf_file_t) lf;
1116  u_long off = (uintptr_t) (void *) value;
1117  u_long diff = off;
1118  u_long st_value;
1119  const Elf_Sym *es;
1120  const Elf_Sym *best = 0;
1121  int i;
1122 
1123  for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) {
1124  if (es->st_name == 0)
1125  continue;
1126  st_value = es->st_value;
1127  if (off >= st_value) {
1128  if (off - st_value < diff) {
1129  diff = off - st_value;
1130  best = es;
1131  if (diff == 0)
1132  break;
1133  } else if (off - st_value == diff) {
1134  best = es;
1135  }
1136  }
1137  }
1138  if (best == 0)
1139  *diffp = off;
1140  else
1141  *diffp = diff;
1142  *sym = (c_linker_sym_t) best;
1143 
1144  return 0;
1145 }
1146 
1147 /*
1148  * Look up a linker set on an ELF system.
1149  */
1150 static int
1151 link_elf_lookup_set(linker_file_t lf, const char *name,
1152  void ***startp, void ***stopp, int *countp)
1153 {
1154  elf_file_t ef = (elf_file_t)lf;
1155  void **start, **stop;
1156  int i, count;
1157 
1158  /* Relative to section number */
1159  for (i = 0; i < ef->nprogtab; i++) {
1160  if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) &&
1161  strcmp(ef->progtab[i].name + 4, name) == 0) {
1162  start = (void **)ef->progtab[i].addr;
1163  stop = (void **)((char *)ef->progtab[i].addr +
1164  ef->progtab[i].size);
1165  count = stop - start;
1166  if (startp)
1167  *startp = start;
1168  if (stopp)
1169  *stopp = stop;
1170  if (countp)
1171  *countp = count;
1172  return (0);
1173  }
1174  }
1175  return (ESRCH);
1176 }
1177 
1178 static int
1179 link_elf_each_function_name(linker_file_t file,
1180  int (*callback)(const char *, void *), void *opaque)
1181 {
1182  elf_file_t ef = (elf_file_t)file;
1183  const Elf_Sym *symp;
1184  int i, error;
1185 
1186  /* Exhaustive search */
1187  for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1188  if (symp->st_value != 0 &&
1189  ELF_ST_TYPE(symp->st_info) == STT_FUNC) {
1190  error = callback(ef->ddbstrtab + symp->st_name, opaque);
1191  if (error)
1192  return (error);
1193  }
1194  }
1195  return (0);
1196 }
1197 
1198 static int
1200  linker_function_nameval_callback_t callback, void *opaque)
1201 {
1202  linker_symval_t symval;
1203  elf_file_t ef = (elf_file_t)file;
1204  const Elf_Sym* symp;
1205  int i, error;
1206 
1207  /* Exhaustive search */
1208  for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1209  if (symp->st_value != 0 &&
1210  ELF_ST_TYPE(symp->st_info) == STT_FUNC) {
1211  error = link_elf_symbol_values(file, (c_linker_sym_t) symp, &symval);
1212  if (error)
1213  return (error);
1214  error = callback(file, i, &symval, opaque);
1215  if (error)
1216  return (error);
1217  }
1218  }
1219  return (0);
1220 }
1221 
1222 /*
1223  * Symbol lookup function that can be used when the symbol index is known (ie
1224  * in relocations). It uses the symbol index instead of doing a fully fledged
1225  * hash table based lookup when such is valid. For example for local symbols.
1226  * This is not only more efficient, it's also more correct. It's not always
1227  * the case that the symbol can be found through the hash table.
1228  */
1229 static Elf_Addr
1230 elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps)
1231 {
1232  elf_file_t ef = (elf_file_t)lf;
1233  const Elf_Sym *sym;
1234  const char *symbol;
1235  Elf_Addr ret;
1236 
1237  /* Don't even try to lookup the symbol if the index is bogus. */
1238  if (symidx >= ef->ddbsymcnt)
1239  return (0);
1240 
1241  sym = ef->ddbsymtab + symidx;
1242 
1243  /* Quick answer if there is a definition included. */
1244  if (sym->st_shndx != SHN_UNDEF)
1245  return (sym->st_value);
1246 
1247  /* If we get here, then it is undefined and needs a lookup. */
1248  switch (ELF_ST_BIND(sym->st_info)) {
1249  case STB_LOCAL:
1250  /* Local, but undefined? huh? */
1251  return (0);
1252 
1253  case STB_GLOBAL:
1254  /* Relative to Data or Function name */
1255  symbol = ef->ddbstrtab + sym->st_name;
1256 
1257  /* Force a lookup failure if the symbol name is bogus. */
1258  if (*symbol == 0)
1259  return (0);
1260  ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
1261  return ret;
1262 
1263  case STB_WEAK:
1264  printf("link_elf_obj: Weak symbols not supported\n");
1265  return (0);
1266 
1267  default:
1268  return (0);
1269  }
1270 }
1271 
1272 static void
1274 {
1275  static const char startn[] = "__start_";
1276  static const char stopn[] = "__stop_";
1277  Elf_Sym *sym;
1278  const char *sym_name, *linkset_name;
1279  Elf_Addr startp, stopp;
1280  Elf_Size symidx;
1281  int start, i;
1282 
1283  startp = stopp = 0;
1284  for (symidx = 1 /* zero entry is special */;
1285  symidx < ef->ddbsymcnt; symidx++) {
1286  sym = ef->ddbsymtab + symidx;
1287  if (sym->st_shndx != SHN_UNDEF)
1288  continue;
1289 
1290  sym_name = ef->ddbstrtab + sym->st_name;
1291  if (strncmp(sym_name, startn, sizeof(startn) - 1) == 0) {
1292  start = 1;
1293  linkset_name = sym_name + sizeof(startn) - 1;
1294  }
1295  else if (strncmp(sym_name, stopn, sizeof(stopn) - 1) == 0) {
1296  start = 0;
1297  linkset_name = sym_name + sizeof(stopn) - 1;
1298  }
1299  else
1300  continue;
1301 
1302  for (i = 0; i < ef->nprogtab; i++) {
1303  if (strcmp(ef->progtab[i].name, linkset_name) == 0) {
1304  startp = (Elf_Addr)ef->progtab[i].addr;
1305  stopp = (Elf_Addr)(startp + ef->progtab[i].size);
1306  break;
1307  }
1308  }
1309  if (i == ef->nprogtab)
1310  continue;
1311 
1312  sym->st_value = start ? startp : stopp;
1313  sym->st_shndx = i;
1314  }
1315 }
1316 
1317 static void
1318 link_elf_reloc_local(linker_file_t lf)
1319 {
1320  elf_file_t ef = (elf_file_t)lf;
1321  const Elf_Rel *rellim;
1322  const Elf_Rel *rel;
1323  const Elf_Rela *relalim;
1324  const Elf_Rela *rela;
1325  const Elf_Sym *sym;
1326  Elf_Addr base;
1327  int i;
1328  Elf_Size symidx;
1329 
1331 
1332  /* Perform relocations without addend if there are any: */
1333  for (i = 0; i < ef->nreltab; i++) {
1334  rel = ef->reltab[i].rel;
1335  if (rel == NULL)
1336  panic("lost a reltab!");
1337  rellim = rel + ef->reltab[i].nrel;
1338  base = findbase(ef, ef->reltab[i].sec);
1339  if (base == 0)
1340  panic("lost base for reltab");
1341  for ( ; rel < rellim; rel++) {
1342  symidx = ELF_R_SYM(rel->r_info);
1343  if (symidx >= ef->ddbsymcnt)
1344  continue;
1345  sym = ef->ddbsymtab + symidx;
1346  /* Only do local relocs */
1347  if (ELF_ST_BIND(sym->st_info) != STB_LOCAL)
1348  continue;
1349  elf_reloc_local(lf, base, rel, ELF_RELOC_REL,
1350  elf_obj_lookup);
1351  }
1352  }
1353 
1354  /* Perform relocations with addend if there are any: */
1355  for (i = 0; i < ef->nrelatab; i++) {
1356  rela = ef->relatab[i].rela;
1357  if (rela == NULL)
1358  panic("lost a relatab!");
1359  relalim = rela + ef->relatab[i].nrela;
1360  base = findbase(ef, ef->relatab[i].sec);
1361  if (base == 0)
1362  panic("lost base for relatab");
1363  for ( ; rela < relalim; rela++) {
1364  symidx = ELF_R_SYM(rela->r_info);
1365  if (symidx >= ef->ddbsymcnt)
1366  continue;
1367  sym = ef->ddbsymtab + symidx;
1368  /* Only do local relocs */
1369  if (ELF_ST_BIND(sym->st_info) != STB_LOCAL)
1370  continue;
1371  elf_reloc_local(lf, base, rela, ELF_RELOC_RELA,
1372  elf_obj_lookup);
1373  }
1374  }
1375 }
1376 
1377 static long
1378 link_elf_symtab_get(linker_file_t lf, const Elf_Sym **symtab)
1379 {
1380  elf_file_t ef = (elf_file_t)lf;
1381 
1382  *symtab = ef->ddbsymtab;
1383 
1384  if (*symtab == NULL)
1385  return (0);
1386 
1387  return (ef->ddbsymcnt);
1388 }
1389 
1390 static long
1391 link_elf_strtab_get(linker_file_t lf, caddr_t *strtab)
1392 {
1393  elf_file_t ef = (elf_file_t)lf;
1394 
1395  *strtab = ef->ddbstrtab;
1396 
1397  if (*strtab == NULL)
1398  return (0);
1399 
1400  return (ef->ddbstrcnt);
1401 }
long * diffp
Definition: linker_if.m:53
int linker_ctf_get(linker_file_t file, linker_ctf_t *lc)
Definition: kern_linker.c:725
int preloaded
Definition: link_elf.c:78
caddr_t value
Definition: linker_if.m:51
void NDFREE(struct nameidata *ndp, const u_int flags)
Definition: vfs_lookup.c:1091
void preload_delete_name(const char *name)
Definition: subr_module.c:200
int nrelatab
Definition: link_elf_obj.c:101
void *** start
Definition: linker_if.m:86
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
Definition: kern_malloc.c:454
const char * filename
Definition: linker_if.m:135
int nprogtab
Definition: link_elf_obj.c:98
Elf_Rela * rela
Definition: link_elf_obj.c:83
void dpcpu_copy(void *s, int size)
Definition: subr_pcpu.c:220
static int link_elf_ctf_get(linker_file_t lf, linker_ctf_t *lc)
Definition: kern_ctf.c:59
static int linker_load_file(const char *filename, linker_file_t *result)
Definition: kern_linker.c:388
long ddbstrcnt
Definition: link_elf.c:105
long typlen
Definition: link_elf.c:112
caddr_t ctfoff
Definition: link_elf.c:110
void panic(const char *fmt,...)
Elf_relent * reltab
Definition: link_elf_obj.c:103
long ctfcnt
Definition: link_elf.c:109
const char * name
Definition: kern_fail.c:97
linker_function_name_callback_t callback
Definition: linker_if.m:62
caddr_t address
Definition: link_elf.c:79
c_linker_sym_t * symp
Definition: linker_if.m:40
int * type
Definition: cpufreq_if.m:98
struct linker_file lf
Definition: link_elf.c:77
const Elf_Sym ** symtab
Definition: linker_if.m:113
caddr_t modptr
Definition: link_elf.c:101
Elf_Sym * ddbsymtab
Definition: link_elf_obj.c:106
caddr_t * strtab
Definition: linker_if.m:122
char * name
Definition: link_elf_obj.c:73
void * opaque
Definition: linker_if.m:63
const Elf_Sym * ddbsymtab
Definition: link_elf.c:102
c_linker_sym_t sym
Definition: linker_if.m:45
caddr_t ctftab
Definition: link_elf.c:108
void * addr
Definition: link_elf_obj.c:69
int vn_rdwr(enum uio_rw rw, struct vnode *vp, void *base, int len, off_t offset, enum uio_seg segflg, int ioflg, struct ucred *active_cred, struct ucred *file_cred, ssize_t *aresid, struct thread *td)
Definition: vfs_vnops.c:379
caddr_t typoff
Definition: link_elf.c:111
caddr_t ddbstrtab
Definition: link_elf.c:104
Elf_relaent * relatab
Definition: link_elf_obj.c:100
Elf_Off size
Definition: link_elf_obj.c:70
caddr_t shstrtab
Definition: link_elf_obj.c:111
caddr_t linker_file_lookup_symbol(linker_file_t file, const char *name, int deps)
Definition: kern_linker.c:772
long ddbsymcnt
Definition: link_elf.c:103
caddr_t preload_search_by_name(const char *name)
Definition: subr_module.c:45
void free(void *addr, struct malloc_type *mtp)
Definition: kern_malloc.c:554
int vn_close(struct vnode *vp, int flags, struct ucred *file_cred, struct thread *td)
Definition: vfs_vnops.c:303
int printf(const char *fmt,...)
Definition: subr_prf.c:367
linker_file_t * result
Definition: linker_if.m:136
caddr_t preload_search_info(caddr_t mod, int inf)
Definition: subr_module.c:156
int linker_add_class(linker_class_t lc)
Definition: kern_linker.c:175
int linker_file_unload(linker_file_t file, int flags)
Definition: kern_linker.c:601
linker_file_t linker_make_file(const char *pathname, linker_class_t lc)
Definition: kern_linker.c:572
long shstrcnt
Definition: link_elf_obj.c:112
Elf_Rel * rel
Definition: link_elf_obj.c:77
int linker_load_dependencies(linker_file_t lf)
Definition: kern_linker.c:2038
Elf_progent * progtab
Definition: link_elf_obj.c:97
int vn_open(struct nameidata *ndp, int *flagp, int cmode, struct file *fp)
Definition: vfs_vnops.c:106
void dpcpu_free(void *s, int size)
Definition: subr_pcpu.c:166
void * dpcpu_alloc(int size)
Definition: subr_pcpu.c:135
Elf_Shdr * e_shdr
Definition: link_elf_obj.c:95
void *** stop
Definition: linker_if.m:87
#define __ELF_WORD_SIZE
Definition: imgact_elf32.c:30
vm_object_t object
Definition: link_elf_obj.c:94
int * count
Definition: cpufreq_if.m:63