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