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