xref: /freebsd/stand/common/load_elf.c (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
1 /*-
2  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3  * Copyright (c) 1998 Peter Wemm <peter@freebsd.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 #include <sys/param.h>
32 #include <sys/endian.h>
33 #include <sys/exec.h>
34 #include <sys/linker.h>
35 #include <sys/module.h>
36 #include <sys/stdint.h>
37 #include <string.h>
38 #include <machine/elf.h>
39 #include <stand.h>
40 #define FREEBSD_ELF
41 #include <sys/link_elf.h>
42 #include <gfx_fb.h>
43 
44 #include "bootstrap.h"
45 
46 #define COPYOUT(s,d,l)	archsw.arch_copyout((vm_offset_t)(s), d, l)
47 
48 #if defined(__i386__) && __ELF_WORD_SIZE == 64
49 #undef ELF_TARG_CLASS
50 #undef ELF_TARG_MACH
51 #define ELF_TARG_CLASS  ELFCLASS64
52 #define ELF_TARG_MACH   EM_X86_64
53 #endif
54 
55 typedef struct elf_file {
56 	Elf_Phdr	*ph;
57 	Elf_Ehdr	*ehdr;
58 	Elf_Sym		*symtab;
59 	Elf_Hashelt	*hashtab;
60 	Elf_Hashelt	nbuckets;
61 	Elf_Hashelt	nchains;
62 	Elf_Hashelt	*buckets;
63 	Elf_Hashelt	*chains;
64 	Elf_Rel	*rel;
65 	size_t	relsz;
66 	Elf_Rela	*rela;
67 	size_t	relasz;
68 	char	*strtab;
69 	size_t	strsz;
70 	int		fd;
71 	caddr_t	firstpage;
72 	size_t	firstlen;
73 	int		kernel;
74 	uint64_t	off;
75 #ifdef LOADER_VERIEXEC_VECTX
76 	struct vectx	*vctx;
77 #endif
78 } *elf_file_t;
79 
80 #ifdef LOADER_VERIEXEC_VECTX
81 #define VECTX_HANDLE(ef) (ef)->vctx
82 #else
83 #define VECTX_HANDLE(ef) (ef)->fd
84 #endif
85 
86 static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef,
87     uint64_t loadaddr);
88 static int __elfN(lookup_symbol)(elf_file_t ef, const char* name,
89     Elf_Sym *sym, unsigned char type);
90 static int __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef,
91     Elf_Addr p, void *val, size_t len);
92 static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef,
93     Elf_Addr p_start, Elf_Addr p_end);
94 static bool __elfN(parse_vt_drv_set)(struct preloaded_file *mp, elf_file_t ef,
95     Elf_Addr p_start, Elf_Addr p_end);
96 static symaddr_fn __elfN(symaddr);
97 static char	*fake_modname(const char *name);
98 
99 const char	*__elfN(kerneltype) = "elf kernel";
100 const char	*__elfN(moduletype) = "elf module";
101 
102 uint64_t	__elfN(relocation_offset) = 0;
103 
104 extern void elf_wrong_field_size(void);
105 #define CONVERT_FIELD(b, f, e)			\
106 	switch (sizeof((b)->f)) {		\
107 	case 2:					\
108 		(b)->f = e ## 16toh((b)->f);	\
109 		break;				\
110 	case 4:					\
111 		(b)->f = e ## 32toh((b)->f);	\
112 		break;				\
113 	case 8:					\
114 		(b)->f = e ## 64toh((b)->f);	\
115 		break;				\
116 	default:				\
117 		/* Force a link time error. */	\
118 		elf_wrong_field_size();		\
119 		break;				\
120 	}
121 
122 #define CONVERT_SWITCH(h, d, f)			\
123 	switch ((h)->e_ident[EI_DATA]) {	\
124 	case ELFDATA2MSB:			\
125 		f(d, be);			\
126 		break;				\
127 	case ELFDATA2LSB:			\
128 		f(d, le);			\
129 		break;				\
130 	default:				\
131 		return (EINVAL);		\
132 	}
133 
134 
135 static int elf_header_convert(Elf_Ehdr *ehdr)
136 {
137 	/*
138 	 * Fixup ELF header endianness.
139 	 *
140 	 * The Xhdr structure was loaded using block read call to optimize file
141 	 * accesses. It might happen, that the endianness of the system memory
142 	 * is different that endianness of the ELF header.  Swap fields here to
143 	 * guarantee that Xhdr always contain valid data regardless of
144 	 * architecture.
145 	 */
146 #define HEADER_FIELDS(b, e)			\
147 	CONVERT_FIELD(b, e_type, e);		\
148 	CONVERT_FIELD(b, e_machine, e);		\
149 	CONVERT_FIELD(b, e_version, e);		\
150 	CONVERT_FIELD(b, e_entry, e);		\
151 	CONVERT_FIELD(b, e_phoff, e);		\
152 	CONVERT_FIELD(b, e_shoff, e);		\
153 	CONVERT_FIELD(b, e_flags, e);		\
154 	CONVERT_FIELD(b, e_ehsize, e);		\
155 	CONVERT_FIELD(b, e_phentsize, e);	\
156 	CONVERT_FIELD(b, e_phnum, e);		\
157 	CONVERT_FIELD(b, e_shentsize, e);	\
158 	CONVERT_FIELD(b, e_shnum, e);		\
159 	CONVERT_FIELD(b, e_shstrndx, e)
160 
161 	CONVERT_SWITCH(ehdr, ehdr, HEADER_FIELDS);
162 
163 #undef HEADER_FIELDS
164 
165 	return (0);
166 }
167 
168 static int elf_program_header_convert(const Elf_Ehdr *ehdr, Elf_Phdr *phdr)
169 {
170 #define PROGRAM_HEADER_FIELDS(b, e)		\
171 	CONVERT_FIELD(b, p_type, e);		\
172 	CONVERT_FIELD(b, p_flags, e);		\
173 	CONVERT_FIELD(b, p_offset, e);		\
174 	CONVERT_FIELD(b, p_vaddr, e);		\
175 	CONVERT_FIELD(b, p_paddr, e);		\
176 	CONVERT_FIELD(b, p_filesz, e);		\
177 	CONVERT_FIELD(b, p_memsz, e);		\
178 	CONVERT_FIELD(b, p_align, e)
179 
180 	CONVERT_SWITCH(ehdr, phdr, PROGRAM_HEADER_FIELDS);
181 
182 #undef PROGRAM_HEADER_FIELDS
183 
184 	return (0);
185 }
186 
187 static int elf_section_header_convert(const Elf_Ehdr *ehdr, Elf_Shdr *shdr)
188 {
189 #define SECTION_HEADER_FIELDS(b, e)		\
190 	CONVERT_FIELD(b, sh_name, e);		\
191 	CONVERT_FIELD(b, sh_type, e);		\
192 	CONVERT_FIELD(b, sh_link, e);		\
193 	CONVERT_FIELD(b, sh_info, e);		\
194 	CONVERT_FIELD(b, sh_flags, e);		\
195 	CONVERT_FIELD(b, sh_addr, e);		\
196 	CONVERT_FIELD(b, sh_offset, e);		\
197 	CONVERT_FIELD(b, sh_size, e);		\
198 	CONVERT_FIELD(b, sh_addralign, e);	\
199 	CONVERT_FIELD(b, sh_entsize, e)
200 
201 	CONVERT_SWITCH(ehdr, shdr, SECTION_HEADER_FIELDS);
202 
203 #undef SECTION_HEADER_FIELDS
204 
205 	return (0);
206 }
207 #undef CONVERT_SWITCH
208 #undef CONVERT_FIELD
209 
210 static int
211 __elfN(load_elf_header)(char *filename, elf_file_t ef)
212 {
213 	ssize_t			 bytes_read;
214 	Elf_Ehdr		*ehdr;
215 	int			 err;
216 
217 	/*
218 	 * Open the image, read and validate the ELF header
219 	 */
220 	if (filename == NULL)	/* can't handle nameless */
221 		return (EFTYPE);
222 	if ((ef->fd = open(filename, O_RDONLY)) == -1)
223 		return (errno);
224 	ef->firstpage = malloc(PAGE_SIZE);
225 	if (ef->firstpage == NULL) {
226 		close(ef->fd);
227 		return (ENOMEM);
228 	}
229 #ifdef LOADER_VERIEXEC_VECTX
230 	{
231 		int verror;
232 
233 		ef->vctx = vectx_open(ef->fd, filename, 0L, NULL, &verror, __func__);
234 		if (verror) {
235 			printf("Unverified %s: %s\n", filename, ve_error_get());
236 			close(ef->fd);
237 			free(ef->vctx);
238 			return (EAUTH);
239 		}
240 	}
241 #endif
242 	bytes_read = VECTX_READ(VECTX_HANDLE(ef), ef->firstpage, PAGE_SIZE);
243 	ef->firstlen = (size_t)bytes_read;
244 	if (bytes_read < 0 || ef->firstlen <= sizeof(Elf_Ehdr)) {
245 		err = EFTYPE; /* could be EIO, but may be small file */
246 		goto error;
247 	}
248 	ehdr = ef->ehdr = (Elf_Ehdr *)ef->firstpage;
249 
250 	/* Is it ELF? */
251 	if (!IS_ELF(*ehdr)) {
252 		err = EFTYPE;
253 		goto error;
254 	}
255 
256 	if (ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */
257 	    ehdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
258 	    ehdr->e_ident[EI_VERSION] != EV_CURRENT) /* Version ? */ {
259 		err = EFTYPE;
260 		goto error;
261 	}
262 
263 	err = elf_header_convert(ehdr);
264 	if (err)
265 		goto error;
266 
267 	if (ehdr->e_version != EV_CURRENT || ehdr->e_machine != ELF_TARG_MACH) {
268 		/* Machine ? */
269 		err = EFTYPE;
270 		goto error;
271 	}
272 
273 #if defined(LOADER_VERIEXEC) && !defined(LOADER_VERIEXEC_VECTX)
274 	if (verify_file(ef->fd, filename, bytes_read, VE_MUST, __func__) < 0) {
275 		err = EAUTH;
276 		goto error;
277 	}
278 #endif
279 	return (0);
280 
281 error:
282 	if (ef->firstpage != NULL) {
283 		free(ef->firstpage);
284 		ef->firstpage = NULL;
285 	}
286 	if (ef->fd != -1) {
287 #ifdef LOADER_VERIEXEC_VECTX
288 		free(ef->vctx);
289 #endif
290 		close(ef->fd);
291 		ef->fd = -1;
292 	}
293 	return (err);
294 }
295 
296 /*
297  * Attempt to load the file (file) as an ELF module.  It will be stored at
298  * (dest), and a pointer to a module structure describing the loaded object
299  * will be saved in (result).
300  */
301 int
302 __elfN(loadfile)(char *filename, uint64_t dest, struct preloaded_file **result)
303 {
304 	return (__elfN(loadfile_raw)(filename, dest, result, 0));
305 }
306 
307 int
308 __elfN(loadfile_raw)(char *filename, uint64_t dest,
309     struct preloaded_file **result, int multiboot)
310 {
311 	struct preloaded_file	*fp, *kfp;
312 	struct elf_file		ef;
313 	Elf_Ehdr		*ehdr;
314 	int			err;
315 
316 	fp = NULL;
317 	bzero(&ef, sizeof(struct elf_file));
318 	ef.fd = -1;
319 
320 	err = __elfN(load_elf_header)(filename, &ef);
321 	if (err != 0)
322 		return (err);
323 
324 	ehdr = ef.ehdr;
325 
326 	/*
327 	 * Check to see what sort of module we are.
328 	 */
329 	kfp = file_findfile(NULL, __elfN(kerneltype));
330 #ifdef __powerpc__
331 	/*
332 	 * Kernels can be ET_DYN, so just assume the first loaded object is the
333 	 * kernel. This assumption will be checked later.
334 	 */
335 	if (kfp == NULL)
336 		ef.kernel = 1;
337 #endif
338 	if (ef.kernel || ehdr->e_type == ET_EXEC) {
339 		/* Looks like a kernel */
340 		if (kfp != NULL) {
341 			printf("elf" __XSTRING(__ELF_WORD_SIZE)
342 			    "_loadfile: kernel already loaded\n");
343 			err = EPERM;
344 			goto oerr;
345 		}
346 		/*
347 		 * Calculate destination address based on kernel entrypoint.
348 		 *
349 		 * For ARM, the destination address is independent of any values
350 		 * in the elf header (an ARM kernel can be loaded at any 2MB
351 		 * boundary), so we leave dest set to the value calculated by
352 		 * archsw.arch_loadaddr() and passed in to this function.
353 		 */
354 #ifndef __arm__
355 		if (ehdr->e_type == ET_EXEC)
356 			dest = (ehdr->e_entry & ~PAGE_MASK);
357 #endif
358 		if ((ehdr->e_entry & ~PAGE_MASK) == 0) {
359 			printf("elf" __XSTRING(__ELF_WORD_SIZE)
360 			    "_loadfile: not a kernel (maybe static binary?)\n");
361 			err = EPERM;
362 			goto oerr;
363 		}
364 		ef.kernel = 1;
365 
366 	} else if (ehdr->e_type == ET_DYN) {
367 		/* Looks like a kld module */
368 		if (multiboot != 0) {
369 			printf("elf" __XSTRING(__ELF_WORD_SIZE)
370 			    "_loadfile: can't load module as multiboot\n");
371 			err = EPERM;
372 			goto oerr;
373 		}
374 		if (kfp == NULL) {
375 			printf("elf" __XSTRING(__ELF_WORD_SIZE)
376 			    "_loadfile: can't load module before kernel\n");
377 			err = EPERM;
378 			goto oerr;
379 		}
380 		if (strcmp(__elfN(kerneltype), kfp->f_type)) {
381 			printf("elf" __XSTRING(__ELF_WORD_SIZE)
382 			 "_loadfile: can't load module with kernel type '%s'\n",
383 			    kfp->f_type);
384 			err = EPERM;
385 			goto oerr;
386 		}
387 		/* Looks OK, got ahead */
388 		ef.kernel = 0;
389 
390 	} else {
391 		err = EFTYPE;
392 		goto oerr;
393 	}
394 
395 	if (archsw.arch_loadaddr != NULL)
396 		dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest);
397 	else
398 		dest = roundup(dest, PAGE_SIZE);
399 
400 	/*
401 	 * Ok, we think we should handle this.
402 	 */
403 	fp = file_alloc();
404 	if (fp == NULL) {
405 		printf("elf" __XSTRING(__ELF_WORD_SIZE)
406 		    "_loadfile: cannot allocate module info\n");
407 		err = EPERM;
408 		goto out;
409 	}
410 	if (ef.kernel == 1 && multiboot == 0)
411 		setenv("kernelname", filename, 1);
412 	fp->f_name = strdup(filename);
413 	if (multiboot == 0)
414 		fp->f_type = strdup(ef.kernel ?
415 		    __elfN(kerneltype) : __elfN(moduletype));
416 	else
417 		fp->f_type = strdup("elf multiboot kernel");
418 
419 #ifdef ELF_VERBOSE
420 	if (ef.kernel)
421 		printf("%s entry at 0x%jx\n", filename,
422 		    (uintmax_t)ehdr->e_entry);
423 #else
424 	printf("%s ", filename);
425 #endif
426 
427 	fp->f_size = __elfN(loadimage)(fp, &ef, dest);
428 	if (fp->f_size == 0 || fp->f_addr == 0)
429 		goto ioerr;
430 
431 	/* save exec header as metadata */
432 	file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr);
433 
434 	/* Load OK, return module pointer */
435 	*result = (struct preloaded_file *)fp;
436 	err = 0;
437 	goto out;
438 
439 ioerr:
440 	err = EIO;
441 oerr:
442 	file_discard(fp);
443 out:
444 	if (ef.firstpage)
445 		free(ef.firstpage);
446 	if (ef.fd != -1) {
447 #ifdef LOADER_VERIEXEC_VECTX
448 		if (!err && ef.vctx) {
449 			int verror;
450 
451 			verror = vectx_close(ef.vctx, VE_MUST, __func__);
452 			if (verror) {
453 				err = EAUTH;
454 				file_discard(fp);
455 			}
456 		}
457 #endif
458 		close(ef.fd);
459 	}
460 	return (err);
461 }
462 
463 /*
464  * With the file (fd) open on the image, and (ehdr) containing
465  * the Elf header, load the image at (off)
466  */
467 static int
468 __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, uint64_t off)
469 {
470 	int		i;
471 	u_int		j;
472 	Elf_Ehdr	*ehdr;
473 	Elf_Phdr	*phdr, *php;
474 	Elf_Shdr	*shdr;
475 	char		*shstr;
476 	int		ret;
477 	vm_offset_t	firstaddr;
478 	vm_offset_t	lastaddr;
479 	size_t		chunk;
480 	ssize_t		result;
481 	Elf_Addr	ssym, esym;
482 	Elf_Dyn		*dp;
483 	Elf_Addr	adp;
484 	Elf_Addr	ctors;
485 	int		ndp;
486 	int		symstrindex;
487 	int		symtabindex;
488 	Elf_Size	size;
489 	u_int		fpcopy;
490 	Elf_Sym		sym;
491 	Elf_Addr	p_start, p_end;
492 
493 	dp = NULL;
494 	shdr = NULL;
495 	ret = 0;
496 	firstaddr = lastaddr = 0;
497 	ehdr = ef->ehdr;
498 #ifdef __powerpc__
499 	if (ef->kernel) {
500 #else
501 	if (ehdr->e_type == ET_EXEC) {
502 #endif
503 #if defined(__i386__) || defined(__amd64__)
504 #if __ELF_WORD_SIZE == 64
505 		/* x86_64 relocates after locore */
506 		off = - (off & 0xffffffffff000000ull);
507 #else
508 		/* i386 relocates after locore */
509 		off = - (off & 0xff000000u);
510 #endif
511 #elif defined(__powerpc__)
512 		/*
513 		 * On the purely virtual memory machines like e500, the kernel
514 		 * is linked against its final VA range, which is most often
515 		 * not available at the loader stage, but only after kernel
516 		 * initializes and completes its VM settings. In such cases we
517 		 * cannot use p_vaddr field directly to load ELF segments, but
518 		 * put them at some 'load-time' locations.
519 		 */
520 		if (off & 0xf0000000u) {
521 			off = -(off & 0xf0000000u);
522 			/*
523 			 * XXX the physical load address should not be
524 			 * hardcoded. Note that the Book-E kernel assumes that
525 			 * it's loaded at a 16MB boundary for now...
526 			 */
527 			off += 0x01000000;
528 		}
529 		ehdr->e_entry += off;
530 #ifdef ELF_VERBOSE
531 		printf("Converted entry 0x%jx\n", (uintmax_t)ehdr->e_entry);
532 #endif
533 #elif defined(__arm__) && !defined(EFI)
534 		/*
535 		 * The elf headers in arm kernels specify virtual addresses in
536 		 * all header fields, even the ones that should be physical
537 		 * addresses.  We assume the entry point is in the first page,
538 		 * and masking the page offset will leave us with the virtual
539 		 * address the kernel was linked at.  We subtract that from the
540 		 * load offset, making 'off' into the value which, when added
541 		 * to a virtual address in an elf header, translates it to a
542 		 * physical address.  We do the va->pa conversion on the entry
543 		 * point address in the header now, so that later we can launch
544 		 * the kernel by just jumping to that address.
545 		 *
546 		 * When booting from UEFI the copyin and copyout functions
547 		 * handle adjusting the location relative to the first virtual
548 		 * address.  Because of this there is no need to adjust the
549 		 * offset or entry point address as these will both be handled
550 		 * by the efi code.
551 		 */
552 		off -= ehdr->e_entry & ~PAGE_MASK;
553 		ehdr->e_entry += off;
554 #ifdef ELF_VERBOSE
555 		printf("ehdr->e_entry 0x%jx, va<->pa off %llx\n",
556 		    (uintmax_t)ehdr->e_entry, off);
557 #endif
558 #else
559 		off = 0;	/* other archs use direct mapped kernels */
560 #endif
561 	}
562 	ef->off = off;
563 
564 	if (ef->kernel)
565 		__elfN(relocation_offset) = off;
566 
567 	if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > ef->firstlen) {
568 		printf("elf" __XSTRING(__ELF_WORD_SIZE)
569 		    "_loadimage: program header not within first page\n");
570 		goto out;
571 	}
572 	phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff);
573 
574 	for (i = 0; i < ehdr->e_phnum; i++) {
575 		if (elf_program_header_convert(ehdr, phdr))
576 			continue;
577 
578 		/* We want to load PT_LOAD segments only.. */
579 		if (phdr[i].p_type != PT_LOAD)
580 			continue;
581 
582 #ifdef ELF_VERBOSE
583 		printf("Segment: 0x%lx@0x%lx -> 0x%lx-0x%lx",
584 		    (long)phdr[i].p_filesz, (long)phdr[i].p_offset,
585 		    (long)(phdr[i].p_vaddr + off),
586 		    (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz - 1));
587 #else
588 		if ((phdr[i].p_flags & PF_W) == 0) {
589 			printf("text=0x%lx ", (long)phdr[i].p_filesz);
590 		} else {
591 			printf("data=0x%lx", (long)phdr[i].p_filesz);
592 			if (phdr[i].p_filesz < phdr[i].p_memsz)
593 				printf("+0x%lx", (long)(phdr[i].p_memsz -
594 				    phdr[i].p_filesz));
595 			printf(" ");
596 		}
597 #endif
598 		fpcopy = 0;
599 		if (ef->firstlen > phdr[i].p_offset) {
600 			fpcopy = ef->firstlen - phdr[i].p_offset;
601 			archsw.arch_copyin(ef->firstpage + phdr[i].p_offset,
602 			    phdr[i].p_vaddr + off, fpcopy);
603 		}
604 		if (phdr[i].p_filesz > fpcopy) {
605 			if (kern_pread(VECTX_HANDLE(ef),
606 			    phdr[i].p_vaddr + off + fpcopy,
607 			    phdr[i].p_filesz - fpcopy,
608 			    phdr[i].p_offset + fpcopy) != 0) {
609 				printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
610 				    "_loadimage: read failed\n");
611 				goto out;
612 			}
613 		}
614 		/* clear space from oversized segments; eg: bss */
615 		if (phdr[i].p_filesz < phdr[i].p_memsz) {
616 #ifdef ELF_VERBOSE
617 			printf(" (bss: 0x%lx-0x%lx)",
618 			    (long)(phdr[i].p_vaddr + off + phdr[i].p_filesz),
619 			    (long)(phdr[i].p_vaddr + off + phdr[i].p_memsz -1));
620 #endif
621 
622 			kern_bzero(phdr[i].p_vaddr + off + phdr[i].p_filesz,
623 			    phdr[i].p_memsz - phdr[i].p_filesz);
624 		}
625 #ifdef ELF_VERBOSE
626 		printf("\n");
627 #endif
628 
629 		if (archsw.arch_loadseg != NULL)
630 			archsw.arch_loadseg(ehdr, phdr + i, off);
631 
632 		if (firstaddr == 0 || firstaddr > (phdr[i].p_vaddr + off))
633 			firstaddr = phdr[i].p_vaddr + off;
634 		if (lastaddr == 0 || lastaddr <
635 		    (phdr[i].p_vaddr + off + phdr[i].p_memsz))
636 			lastaddr = phdr[i].p_vaddr + off + phdr[i].p_memsz;
637 	}
638 	lastaddr = roundup(lastaddr, sizeof(long));
639 
640 	/*
641 	 * Get the section headers.  We need this for finding the .ctors
642 	 * section as well as for loading any symbols.  Both may be hard
643 	 * to do if reading from a .gz file as it involves seeking.  I
644 	 * think the rule is going to have to be that you must strip a
645 	 * file to remove symbols before gzipping it.
646 	 */
647 	chunk = (size_t)ehdr->e_shnum * (size_t)ehdr->e_shentsize;
648 	if (chunk == 0 || ehdr->e_shoff == 0)
649 		goto nosyms;
650 	shdr = alloc_pread(VECTX_HANDLE(ef), ehdr->e_shoff, chunk);
651 	if (shdr == NULL) {
652 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
653 		    "_loadimage: failed to read section headers");
654 		goto nosyms;
655 	}
656 
657 	for (i = 0; i < ehdr->e_shnum; i++)
658 		elf_section_header_convert(ehdr, &shdr[i]);
659 
660 	file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr);
661 
662 	/*
663 	 * Read the section string table and look for the .ctors section.
664 	 * We need to tell the kernel where it is so that it can call the
665 	 * ctors.
666 	 */
667 	chunk = shdr[ehdr->e_shstrndx].sh_size;
668 	if (chunk) {
669 		shstr = alloc_pread(VECTX_HANDLE(ef),
670 		    shdr[ehdr->e_shstrndx].sh_offset, chunk);
671 		if (shstr) {
672 			for (i = 0; i < ehdr->e_shnum; i++) {
673 				if (strcmp(shstr + shdr[i].sh_name,
674 				    ".ctors") != 0)
675 					continue;
676 				ctors = shdr[i].sh_addr;
677 				file_addmetadata(fp, MODINFOMD_CTORS_ADDR,
678 				    sizeof(ctors), &ctors);
679 				size = shdr[i].sh_size;
680 				file_addmetadata(fp, MODINFOMD_CTORS_SIZE,
681 				    sizeof(size), &size);
682 				break;
683 			}
684 			free(shstr);
685 		}
686 	}
687 
688 	/*
689 	 * Now load any symbols.
690 	 */
691 	symtabindex = -1;
692 	symstrindex = -1;
693 	for (i = 0; i < ehdr->e_shnum; i++) {
694 		if (shdr[i].sh_type != SHT_SYMTAB)
695 			continue;
696 		for (j = 0; j < ehdr->e_phnum; j++) {
697 			if (phdr[j].p_type != PT_LOAD)
698 				continue;
699 			if (shdr[i].sh_offset >= phdr[j].p_offset &&
700 			    (shdr[i].sh_offset + shdr[i].sh_size <=
701 			    phdr[j].p_offset + phdr[j].p_filesz)) {
702 				shdr[i].sh_offset = 0;
703 				shdr[i].sh_size = 0;
704 				break;
705 			}
706 		}
707 		if (shdr[i].sh_offset == 0 || shdr[i].sh_size == 0)
708 			continue;	/* alread loaded in a PT_LOAD above */
709 		/* Save it for loading below */
710 		symtabindex = i;
711 		symstrindex = shdr[i].sh_link;
712 	}
713 	if (symtabindex < 0 || symstrindex < 0)
714 		goto nosyms;
715 
716 	/* Ok, committed to a load. */
717 #ifndef ELF_VERBOSE
718 	printf("syms=[");
719 #endif
720 	ssym = lastaddr;
721 	for (i = symtabindex; i >= 0; i = symstrindex) {
722 #ifdef ELF_VERBOSE
723 		char	*secname;
724 
725 		switch(shdr[i].sh_type) {
726 		case SHT_SYMTAB:		/* Symbol table */
727 			secname = "symtab";
728 			break;
729 		case SHT_STRTAB:		/* String table */
730 			secname = "strtab";
731 			break;
732 		default:
733 			secname = "WHOA!!";
734 			break;
735 		}
736 #endif
737 		size = shdr[i].sh_size;
738 #if defined(__powerpc__)
739   #if __ELF_WORD_SIZE == 64
740 		size = htobe64(size);
741   #else
742 		size = htobe32(size);
743   #endif
744 #endif
745 
746 		archsw.arch_copyin(&size, lastaddr, sizeof(size));
747 		lastaddr += sizeof(size);
748 
749 #ifdef ELF_VERBOSE
750 		printf("\n%s: 0x%jx@0x%jx -> 0x%jx-0x%jx", secname,
751 		    (uintmax_t)shdr[i].sh_size, (uintmax_t)shdr[i].sh_offset,
752 		    (uintmax_t)lastaddr,
753 		    (uintmax_t)(lastaddr + shdr[i].sh_size));
754 #else
755 		if (i == symstrindex)
756 			printf("+");
757 		printf("0x%lx+0x%lx", (long)sizeof(size), (long)size);
758 #endif
759 
760 		if (VECTX_LSEEK(VECTX_HANDLE(ef), (off_t)shdr[i].sh_offset, SEEK_SET) == -1) {
761 			printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
762 			   "_loadimage: could not seek for symbols - skipped!");
763 			lastaddr = ssym;
764 			ssym = 0;
765 			goto nosyms;
766 		}
767 		result = archsw.arch_readin(VECTX_HANDLE(ef), lastaddr, shdr[i].sh_size);
768 		if (result < 0 || (size_t)result != shdr[i].sh_size) {
769 			printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
770 			    "_loadimage: could not read symbols - skipped! "
771 			    "(%ju != %ju)", (uintmax_t)result,
772 			    (uintmax_t)shdr[i].sh_size);
773 			lastaddr = ssym;
774 			ssym = 0;
775 			goto nosyms;
776 		}
777 		/* Reset offsets relative to ssym */
778 		lastaddr += shdr[i].sh_size;
779 		lastaddr = roundup(lastaddr, sizeof(size));
780 		if (i == symtabindex)
781 			symtabindex = -1;
782 		else if (i == symstrindex)
783 			symstrindex = -1;
784 	}
785 	esym = lastaddr;
786 #ifndef ELF_VERBOSE
787 	printf("]");
788 #endif
789 
790 #if defined(__powerpc__)
791   /* On PowerPC we always need to provide BE data to the kernel */
792   #if __ELF_WORD_SIZE == 64
793 	ssym = htobe64((uint64_t)ssym);
794 	esym = htobe64((uint64_t)esym);
795   #else
796 	ssym = htobe32((uint32_t)ssym);
797 	esym = htobe32((uint32_t)esym);
798   #endif
799 #endif
800 
801 	file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
802 	file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym);
803 
804 nosyms:
805 	printf("\n");
806 
807 	ret = lastaddr - firstaddr;
808 	fp->f_addr = firstaddr;
809 
810 	php = NULL;
811 	for (i = 0; i < ehdr->e_phnum; i++) {
812 		if (phdr[i].p_type == PT_DYNAMIC) {
813 			php = phdr + i;
814 			adp = php->p_vaddr;
815 			file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(adp),
816 			    &adp);
817 			break;
818 		}
819 	}
820 
821 	if (php == NULL) /* this is bad, we cannot get to symbols or _DYNAMIC */
822 		goto out;
823 
824 	ndp = php->p_filesz / sizeof(Elf_Dyn);
825 	if (ndp == 0)
826 		goto out;
827 	dp = malloc(php->p_filesz);
828 	if (dp == NULL)
829 		goto out;
830 	archsw.arch_copyout(php->p_vaddr + off, dp, php->p_filesz);
831 
832 	ef->strsz = 0;
833 	for (i = 0; i < ndp; i++) {
834 		if (dp[i].d_tag == 0)
835 			break;
836 		switch (dp[i].d_tag) {
837 		case DT_HASH:
838 			ef->hashtab =
839 			    (Elf_Hashelt*)(uintptr_t)(dp[i].d_un.d_ptr + off);
840 			break;
841 		case DT_STRTAB:
842 			ef->strtab =
843 			    (char *)(uintptr_t)(dp[i].d_un.d_ptr + off);
844 			break;
845 		case DT_STRSZ:
846 			ef->strsz = dp[i].d_un.d_val;
847 			break;
848 		case DT_SYMTAB:
849 			ef->symtab =
850 			    (Elf_Sym *)(uintptr_t)(dp[i].d_un.d_ptr + off);
851 			break;
852 		case DT_REL:
853 			ef->rel =
854 			    (Elf_Rel *)(uintptr_t)(dp[i].d_un.d_ptr + off);
855 			break;
856 		case DT_RELSZ:
857 			ef->relsz = dp[i].d_un.d_val;
858 			break;
859 		case DT_RELA:
860 			ef->rela =
861 			    (Elf_Rela *)(uintptr_t)(dp[i].d_un.d_ptr + off);
862 			break;
863 		case DT_RELASZ:
864 			ef->relasz = dp[i].d_un.d_val;
865 			break;
866 		default:
867 			break;
868 		}
869 	}
870 	if (ef->hashtab == NULL || ef->symtab == NULL ||
871 	    ef->strtab == NULL || ef->strsz == 0)
872 		goto out;
873 	COPYOUT(ef->hashtab, &ef->nbuckets, sizeof(ef->nbuckets));
874 	COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains));
875 	ef->buckets = ef->hashtab + 2;
876 	ef->chains = ef->buckets + ef->nbuckets;
877 
878 	if (!gfx_state.tg_kernel_supported &&
879 	    __elfN(lookup_symbol)(ef, "__start_set_vt_drv_set", &sym,
880 	    STT_NOTYPE) == 0) {
881 		p_start = sym.st_value + ef->off;
882 		if (__elfN(lookup_symbol)(ef, "__stop_set_vt_drv_set", &sym,
883 		    STT_NOTYPE) == 0) {
884 			p_end = sym.st_value + ef->off;
885 			gfx_state.tg_kernel_supported =
886 			    __elfN(parse_vt_drv_set)(fp, ef, p_start, p_end);
887 		}
888 	}
889 
890 	if (__elfN(lookup_symbol)(ef, "__start_set_modmetadata_set", &sym,
891 	    STT_NOTYPE) != 0)
892 		return 0;
893 	p_start = sym.st_value + ef->off;
894 	if (__elfN(lookup_symbol)(ef, "__stop_set_modmetadata_set", &sym,
895 	    STT_NOTYPE) != 0)
896 		return 0;
897 	p_end = sym.st_value + ef->off;
898 
899 	if (__elfN(parse_modmetadata)(fp, ef, p_start, p_end) == 0)
900 		goto out;
901 
902 	if (ef->kernel)		/* kernel must not depend on anything */
903 		goto out;
904 
905 out:
906 	if (dp)
907 		free(dp);
908 	if (shdr)
909 		free(shdr);
910 	return ret;
911 }
912 
913 static char invalid_name[] = "bad";
914 
915 char *
916 fake_modname(const char *name)
917 {
918 	const char *sp, *ep;
919 	char *fp;
920 	size_t len;
921 
922 	sp = strrchr(name, '/');
923 	if (sp)
924 		sp++;
925 	else
926 		sp = name;
927 
928 	ep = strrchr(sp, '.');
929 	if (ep == NULL) {
930 		ep = sp + strlen(sp);
931 	}
932 	if (ep == sp) {
933 		sp = invalid_name;
934 		ep = invalid_name + sizeof(invalid_name) - 1;
935 	}
936 
937 	len = ep - sp;
938 	fp = malloc(len + 1);
939 	if (fp == NULL)
940 		return NULL;
941 	memcpy(fp, sp, len);
942 	fp[len] = '\0';
943 	return fp;
944 }
945 
946 #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64
947 struct mod_metadata64 {
948 	int		md_version;	/* structure version MDTV_* */
949 	int		md_type;	/* type of entry MDT_* */
950 	uint64_t	md_data;	/* specific data */
951 	uint64_t	md_cval;	/* common string label */
952 };
953 #endif
954 #if defined(__amd64__) && __ELF_WORD_SIZE == 32
955 struct mod_metadata32 {
956 	int		md_version;	/* structure version MDTV_* */
957 	int		md_type;	/* type of entry MDT_* */
958 	uint32_t	md_data;	/* specific data */
959 	uint32_t	md_cval;	/* common string label */
960 };
961 #endif
962 
963 int
964 __elfN(load_modmetadata)(struct preloaded_file *fp, uint64_t dest)
965 {
966 	struct elf_file		 ef;
967 	int			 err, i, j;
968 	Elf_Shdr		*sh_meta, *shdr = NULL;
969 	Elf_Shdr		*sh_data[2];
970 	char			*shstrtab = NULL;
971 	size_t			 size;
972 	Elf_Addr		 p_start, p_end;
973 
974 	bzero(&ef, sizeof(struct elf_file));
975 	ef.fd = -1;
976 
977 	err = __elfN(load_elf_header)(fp->f_name, &ef);
978 	if (err != 0)
979 		goto out;
980 
981 	if (ef.kernel == 1 || ef.ehdr->e_type == ET_EXEC) {
982 		ef.kernel = 1;
983 	} else if (ef.ehdr->e_type != ET_DYN) {
984 		err = EFTYPE;
985 		goto out;
986 	}
987 
988 	size = (size_t)ef.ehdr->e_shnum * (size_t)ef.ehdr->e_shentsize;
989 	shdr = alloc_pread(VECTX_HANDLE(&ef), ef.ehdr->e_shoff, size);
990 	if (shdr == NULL) {
991 		err = ENOMEM;
992 		goto out;
993 	}
994 
995 	/* Load shstrtab. */
996 	shstrtab = alloc_pread(VECTX_HANDLE(&ef), shdr[ef.ehdr->e_shstrndx].sh_offset,
997 	    shdr[ef.ehdr->e_shstrndx].sh_size);
998 	if (shstrtab == NULL) {
999 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
1000 		    "load_modmetadata: unable to load shstrtab\n");
1001 		err = EFTYPE;
1002 		goto out;
1003 	}
1004 
1005 	/* Find set_modmetadata_set and data sections. */
1006 	sh_data[0] = sh_data[1] = sh_meta = NULL;
1007 	for (i = 0, j = 0; i < ef.ehdr->e_shnum; i++) {
1008 		if (strcmp(&shstrtab[shdr[i].sh_name],
1009 		    "set_modmetadata_set") == 0) {
1010 			sh_meta = &shdr[i];
1011 		}
1012 		if ((strcmp(&shstrtab[shdr[i].sh_name], ".data") == 0) ||
1013 		    (strcmp(&shstrtab[shdr[i].sh_name], ".rodata") == 0)) {
1014 			sh_data[j++] = &shdr[i];
1015 		}
1016 	}
1017 	if (sh_meta == NULL || sh_data[0] == NULL || sh_data[1] == NULL) {
1018 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
1019     "load_modmetadata: unable to find set_modmetadata_set or data sections\n");
1020 		err = EFTYPE;
1021 		goto out;
1022 	}
1023 
1024 	/* Load set_modmetadata_set into memory */
1025 	err = kern_pread(VECTX_HANDLE(&ef), dest, sh_meta->sh_size, sh_meta->sh_offset);
1026 	if (err != 0) {
1027 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
1028     "load_modmetadata: unable to load set_modmetadata_set: %d\n", err);
1029 		goto out;
1030 	}
1031 	p_start = dest;
1032 	p_end = dest + sh_meta->sh_size;
1033 	dest += sh_meta->sh_size;
1034 
1035 	/* Load data sections into memory. */
1036 	err = kern_pread(VECTX_HANDLE(&ef), dest, sh_data[0]->sh_size,
1037 	    sh_data[0]->sh_offset);
1038 	if (err != 0) {
1039 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
1040 		    "load_modmetadata: unable to load data: %d\n", err);
1041 		goto out;
1042 	}
1043 
1044 	/*
1045 	 * We have to increment the dest, so that the offset is the same into
1046 	 * both the .rodata and .data sections.
1047 	 */
1048 	ef.off = -(sh_data[0]->sh_addr - dest);
1049 	dest +=	(sh_data[1]->sh_addr - sh_data[0]->sh_addr);
1050 
1051 	err = kern_pread(VECTX_HANDLE(&ef), dest, sh_data[1]->sh_size,
1052 	    sh_data[1]->sh_offset);
1053 	if (err != 0) {
1054 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
1055 		    "load_modmetadata: unable to load data: %d\n", err);
1056 		goto out;
1057 	}
1058 
1059 	err = __elfN(parse_modmetadata)(fp, &ef, p_start, p_end);
1060 	if (err != 0) {
1061 		printf("\nelf" __XSTRING(__ELF_WORD_SIZE)
1062 		    "load_modmetadata: unable to parse metadata: %d\n", err);
1063 		goto out;
1064 	}
1065 
1066 out:
1067 	if (shstrtab != NULL)
1068 		free(shstrtab);
1069 	if (shdr != NULL)
1070 		free(shdr);
1071 	if (ef.firstpage != NULL)
1072 		free(ef.firstpage);
1073 	if (ef.fd != -1) {
1074 #ifdef LOADER_VERIEXEC_VECTX
1075 		if (!err && ef.vctx) {
1076 			int verror;
1077 
1078 			verror = vectx_close(ef.vctx, VE_MUST, __func__);
1079 			if (verror) {
1080 				err = EAUTH;
1081 				file_discard(fp);
1082 			}
1083 		}
1084 #endif
1085 		close(ef.fd);
1086 	}
1087 	return (err);
1088 }
1089 
1090 /*
1091  * Walk through vt_drv_set, each vt driver structure starts with
1092  * static 16 chars for driver name. If we have "vbefb", return true.
1093  */
1094 static bool
1095 __elfN(parse_vt_drv_set)(struct preloaded_file *fp, elf_file_t ef,
1096     Elf_Addr p_start, Elf_Addr p_end)
1097 {
1098 	Elf_Addr v, p;
1099 	char vd_name[16];
1100 	int error;
1101 
1102 	p = p_start;
1103 	while (p < p_end) {
1104 		COPYOUT(p, &v, sizeof(v));
1105 
1106 		error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v));
1107 		if (error == EOPNOTSUPP)
1108 			v += ef->off;
1109 		else if (error != 0)
1110 			return (false);
1111 		COPYOUT(v, &vd_name, sizeof(vd_name));
1112 		if (strncmp(vd_name, "vbefb", sizeof(vd_name)) == 0)
1113 			return (true);
1114 		p += sizeof(Elf_Addr);
1115 	}
1116 
1117 	return (false);
1118 }
1119 
1120 int
1121 __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef,
1122     Elf_Addr p_start, Elf_Addr p_end)
1123 {
1124 	struct mod_metadata md;
1125 #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64
1126 	struct mod_metadata64 md64;
1127 #elif defined(__amd64__) && __ELF_WORD_SIZE == 32
1128 	struct mod_metadata32 md32;
1129 #endif
1130 	struct mod_depend *mdepend;
1131 	struct mod_version mver;
1132 	char *s;
1133 	int error, modcnt, minfolen;
1134 	Elf_Addr v, p;
1135 
1136 	modcnt = 0;
1137 	p = p_start;
1138 	while (p < p_end) {
1139 		COPYOUT(p, &v, sizeof(v));
1140 		error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v));
1141 		if (error == EOPNOTSUPP)
1142 			v += ef->off;
1143 		else if (error != 0)
1144 			return (error);
1145 #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64
1146 		COPYOUT(v, &md64, sizeof(md64));
1147 		error = __elfN(reloc_ptr)(fp, ef, v, &md64, sizeof(md64));
1148 		if (error == EOPNOTSUPP) {
1149 			md64.md_cval += ef->off;
1150 			md64.md_data += ef->off;
1151 		} else if (error != 0)
1152 			return (error);
1153 		md.md_version = md64.md_version;
1154 		md.md_type = md64.md_type;
1155 		md.md_cval = (const char *)(uintptr_t)md64.md_cval;
1156 		md.md_data = (void *)(uintptr_t)md64.md_data;
1157 #elif defined(__amd64__) && __ELF_WORD_SIZE == 32
1158 		COPYOUT(v, &md32, sizeof(md32));
1159 		error = __elfN(reloc_ptr)(fp, ef, v, &md32, sizeof(md32));
1160 		if (error == EOPNOTSUPP) {
1161 			md32.md_cval += ef->off;
1162 			md32.md_data += ef->off;
1163 		} else if (error != 0)
1164 			return (error);
1165 		md.md_version = md32.md_version;
1166 		md.md_type = md32.md_type;
1167 		md.md_cval = (const char *)(uintptr_t)md32.md_cval;
1168 		md.md_data = (void *)(uintptr_t)md32.md_data;
1169 #else
1170 		COPYOUT(v, &md, sizeof(md));
1171 		error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md));
1172 		if (error == EOPNOTSUPP) {
1173 			md.md_cval += ef->off;
1174 			md.md_data = (void *)((uintptr_t)md.md_data +
1175 			    (uintptr_t)ef->off);
1176 		} else if (error != 0)
1177 			return (error);
1178 #endif
1179 		p += sizeof(Elf_Addr);
1180 		switch(md.md_type) {
1181 		case MDT_DEPEND:
1182 			if (ef->kernel) /* kernel must not depend on anything */
1183 				break;
1184 			s = strdupout((vm_offset_t)md.md_cval);
1185 			minfolen = sizeof(*mdepend) + strlen(s) + 1;
1186 			mdepend = malloc(minfolen);
1187 			if (mdepend == NULL)
1188 				return ENOMEM;
1189 			COPYOUT((vm_offset_t)md.md_data, mdepend,
1190 			    sizeof(*mdepend));
1191 			strcpy((char*)(mdepend + 1), s);
1192 			free(s);
1193 			file_addmetadata(fp, MODINFOMD_DEPLIST, minfolen,
1194 			    mdepend);
1195 			free(mdepend);
1196 			break;
1197 		case MDT_VERSION:
1198 			s = strdupout((vm_offset_t)md.md_cval);
1199 			COPYOUT((vm_offset_t)md.md_data, &mver, sizeof(mver));
1200 			file_addmodule(fp, s, mver.mv_version, NULL);
1201 			free(s);
1202 			modcnt++;
1203 			break;
1204 		}
1205 	}
1206 	if (modcnt == 0) {
1207 		s = fake_modname(fp->f_name);
1208 		file_addmodule(fp, s, 1, NULL);
1209 		free(s);
1210 	}
1211 	return 0;
1212 }
1213 
1214 static unsigned long
1215 elf_hash(const char *name)
1216 {
1217 	const unsigned char *p = (const unsigned char *) name;
1218 	unsigned long h = 0;
1219 	unsigned long g;
1220 
1221 	while (*p != '\0') {
1222 		h = (h << 4) + *p++;
1223 		if ((g = h & 0xf0000000) != 0)
1224 			h ^= g >> 24;
1225 		h &= ~g;
1226 	}
1227 	return h;
1228 }
1229 
1230 static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE)
1231     "_lookup_symbol: corrupt symbol table\n";
1232 int
1233 __elfN(lookup_symbol)(elf_file_t ef, const char* name, Elf_Sym *symp,
1234     unsigned char type)
1235 {
1236 	Elf_Hashelt symnum;
1237 	Elf_Sym sym;
1238 	char *strp;
1239 	unsigned long hash;
1240 
1241 	hash = elf_hash(name);
1242 	COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof(symnum));
1243 
1244 	while (symnum != STN_UNDEF) {
1245 		if (symnum >= ef->nchains) {
1246 			printf(__elfN(bad_symtable));
1247 			return ENOENT;
1248 		}
1249 
1250 		COPYOUT(ef->symtab + symnum, &sym, sizeof(sym));
1251 		if (sym.st_name == 0) {
1252 			printf(__elfN(bad_symtable));
1253 			return ENOENT;
1254 		}
1255 
1256 		strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name));
1257 		if (strcmp(name, strp) == 0) {
1258 			free(strp);
1259 			if (sym.st_shndx != SHN_UNDEF ||
1260 			    (sym.st_value != 0 &&
1261 			    ELF_ST_TYPE(sym.st_info) == type)) {
1262 				*symp = sym;
1263 				return 0;
1264 			}
1265 			return ENOENT;
1266 		}
1267 		free(strp);
1268 		COPYOUT(&ef->chains[symnum], &symnum, sizeof(symnum));
1269 	}
1270 	return ENOENT;
1271 }
1272 
1273 /*
1274  * Apply any intra-module relocations to the value. p is the load address
1275  * of the value and val/len is the value to be modified. This does NOT modify
1276  * the image in-place, because this is done by kern_linker later on.
1277  *
1278  * Returns EOPNOTSUPP if no relocation method is supplied.
1279  */
1280 static int
1281 __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef,
1282     Elf_Addr p, void *val, size_t len)
1283 {
1284 	size_t n;
1285 	Elf_Rela a;
1286 	Elf_Rel r;
1287 	int error;
1288 
1289 	/*
1290 	 * The kernel is already relocated, but we still want to apply
1291 	 * offset adjustments.
1292 	 */
1293 	if (ef->kernel)
1294 		return (EOPNOTSUPP);
1295 
1296 	for (n = 0; n < ef->relsz / sizeof(r); n++) {
1297 		COPYOUT(ef->rel + n, &r, sizeof(r));
1298 
1299 		error = __elfN(reloc)(ef, __elfN(symaddr), &r, ELF_RELOC_REL,
1300 		    ef->off, p, val, len);
1301 		if (error != 0)
1302 			return (error);
1303 	}
1304 	for (n = 0; n < ef->relasz / sizeof(a); n++) {
1305 		COPYOUT(ef->rela + n, &a, sizeof(a));
1306 
1307 		error = __elfN(reloc)(ef, __elfN(symaddr), &a, ELF_RELOC_RELA,
1308 		    ef->off, p, val, len);
1309 		if (error != 0)
1310 			return (error);
1311 	}
1312 
1313 	return (0);
1314 }
1315 
1316 static Elf_Addr
1317 __elfN(symaddr)(struct elf_file *ef, Elf_Size symidx)
1318 {
1319 
1320 	/* Symbol lookup by index not required here. */
1321 	return (0);
1322 }
1323