xref: /freebsd/sys/kern/link_elf.c (revision c678bc4f13a340ad88debe321afd0097db2590cb)
1 /*-
2  * Copyright (c) 1998-2000 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #include "opt_ddb.h"
30 
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/lock.h>
35 #include <sys/malloc.h>
36 #include <sys/proc.h>
37 #include <sys/namei.h>
38 #include <sys/fcntl.h>
39 #include <sys/vnode.h>
40 #include <sys/linker.h>
41 
42 #include <machine/elf.h>
43 
44 #include <vm/vm.h>
45 #include <vm/vm_param.h>
46 #ifdef SPARSE_MAPPING
47 #include <vm/vm_object.h>
48 #include <vm/vm_kern.h>
49 #include <vm/vm_extern.h>
50 #endif
51 #include <vm/pmap.h>
52 #include <vm/vm_map.h>
53 
54 #ifdef __AOUT__
55 #include <nlist.h>
56 #endif
57 #include <link.h>
58 
59 #include "linker_if.h"
60 
61 typedef struct elf_file {
62     struct linker_file	lf;		/* Common fields */
63     int			preloaded;	/* Was file pre-loaded */
64     caddr_t		address;	/* Relocation address */
65 #ifdef SPARSE_MAPPING
66     vm_object_t		object;		/* VM object to hold file pages */
67 #endif
68     Elf_Dyn*		dynamic;	/* Symbol table etc. */
69     Elf_Off		nbuckets;	/* DT_HASH info */
70     Elf_Off		nchains;
71     const Elf_Off*	buckets;
72     const Elf_Off*	chains;
73     caddr_t		hash;
74     caddr_t		strtab;		/* DT_STRTAB */
75     int			strsz;		/* DT_STRSZ */
76     const Elf_Sym*	symtab;		/* DT_SYMTAB */
77     Elf_Addr*		got;		/* DT_PLTGOT */
78     const Elf_Rel*	pltrel;		/* DT_JMPREL */
79     int			pltrelsize;	/* DT_PLTRELSZ */
80     const Elf_Rela*	pltrela;	/* DT_JMPREL */
81     int			pltrelasize;	/* DT_PLTRELSZ */
82     const Elf_Rel*	rel;		/* DT_REL */
83     int			relsize;	/* DT_RELSZ */
84     const Elf_Rela*	rela;		/* DT_RELA */
85     int			relasize;	/* DT_RELASZ */
86     caddr_t		modptr;
87     const Elf_Sym*	ddbsymtab;	/* The symbol table we are using */
88     long		ddbsymcnt;	/* Number of symbols */
89     caddr_t		ddbstrtab;	/* String table */
90     long		ddbstrcnt;	/* number of bytes in string table */
91     caddr_t		symbase;	/* malloc'ed symbold base */
92     caddr_t		strbase;	/* malloc'ed string base */
93 #ifdef DDB
94     struct link_map	gdb;		/* hooks for gdb */
95 #endif
96 } *elf_file_t;
97 
98 static int	link_elf_link_preload(linker_class_t cls,
99 				      const char*, linker_file_t*);
100 static int	link_elf_link_preload_finish(linker_file_t);
101 static int	link_elf_load_file(linker_class_t, const char*, linker_file_t*);
102 static int	link_elf_lookup_symbol(linker_file_t, const char*,
103 				       c_linker_sym_t*);
104 static int	link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t*);
105 static int	link_elf_search_symbol(linker_file_t, caddr_t value,
106 				       c_linker_sym_t* sym, long* diffp);
107 
108 static void	link_elf_unload_file(linker_file_t);
109 static void	link_elf_unload_preload(linker_file_t);
110 
111 static kobj_method_t link_elf_methods[] = {
112     KOBJMETHOD(linker_lookup_symbol,	link_elf_lookup_symbol),
113     KOBJMETHOD(linker_symbol_values,	link_elf_symbol_values),
114     KOBJMETHOD(linker_search_symbol,	link_elf_search_symbol),
115     KOBJMETHOD(linker_unload,		link_elf_unload_file),
116     KOBJMETHOD(linker_load_file,	link_elf_load_file),
117     KOBJMETHOD(linker_link_preload,	link_elf_link_preload),
118     KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
119     { 0, 0 }
120 };
121 
122 static struct linker_class link_elf_class = {
123 #if ELF_TARG_CLASS == ELFCLASS32
124     "elf32",
125 #else
126     "elf64",
127 #endif
128     link_elf_methods, sizeof(struct elf_file)
129 };
130 
131 static int		parse_dynamic(elf_file_t ef);
132 static int		relocate_file(elf_file_t ef);
133 static int		link_elf_preload_parse_symbols(elf_file_t ef);
134 
135 #ifdef DDB
136 static void		r_debug_state(struct r_debug *dummy_one,
137 				      struct link_map *dummy_two);
138 
139 /*
140  * A list of loaded modules for GDB to use for loading symbols.
141  */
142 struct r_debug r_debug;
143 
144 #define GDB_STATE(s)	r_debug.r_state = s; r_debug_state(NULL, NULL);
145 
146 /*
147  * Function for the debugger to set a breakpoint on to gain control.
148  */
149 void
150 r_debug_state(struct r_debug *dummy_one __unused,
151 	      struct link_map *dummy_two __unused)
152 {
153 }
154 
155 #endif
156 
157 /*
158  * The kernel symbol table starts here.
159  */
160 #ifndef __ia64__
161 extern struct _dynamic _DYNAMIC;
162 #endif
163 
164 static void
165 link_elf_init(void* arg)
166 {
167 #ifdef __ELF__
168     Elf_Dyn	*dp;
169     caddr_t	modptr, baseptr, sizeptr;
170     elf_file_t	ef;
171     char	*modname;
172 #endif
173 
174     linker_add_class(&link_elf_class);
175 
176 #ifdef __ELF__
177 #ifndef __ia64__
178     dp = (Elf_Dyn*) &_DYNAMIC;
179 #else
180     dp = 0;
181 #endif
182     if (dp) {
183 	modname = NULL;
184 	modptr = preload_search_by_type("elf kernel");
185 	if (modptr)
186 	    modname = (char *)preload_search_info(modptr, MODINFO_NAME);
187 	if (modname == NULL)
188 	    modname = "kernel";
189 	linker_kernel_file = linker_make_file(modname, &link_elf_class);
190 	if (linker_kernel_file == NULL)
191 	    panic("link_elf_init: Can't create linker structures for kernel");
192 
193 	ef = (elf_file_t) linker_kernel_file;
194 	ef->preloaded = 1;
195 	ef->address = 0;
196 #ifdef SPARSE_MAPPING
197 	ef->object = 0;
198 #endif
199 	ef->dynamic = dp;
200 
201 	parse_dynamic(ef);
202 	linker_kernel_file->address = (caddr_t) KERNBASE;
203 	linker_kernel_file->size = -(intptr_t)linker_kernel_file->address;
204 
205 	if (modptr) {
206 	    ef->modptr = modptr;
207 	    baseptr = preload_search_info(modptr, MODINFO_ADDR);
208 	    if (baseptr)
209 		linker_kernel_file->address = *(caddr_t *)baseptr;
210 	    sizeptr = preload_search_info(modptr, MODINFO_SIZE);
211 	    if (sizeptr)
212 		linker_kernel_file->size = *(size_t *)sizeptr;
213 	}
214 	(void)link_elf_preload_parse_symbols(ef);
215 
216 #ifdef DDB
217 	ef->gdb.l_addr = linker_kernel_file->address;
218 	ef->gdb.l_name = modname;
219 	ef->gdb.l_ld = dp;
220 	ef->gdb.l_prev = 0;
221 	ef->gdb.l_next = 0;
222 
223 	r_debug.r_map = &ef->gdb;
224 	r_debug.r_brk = r_debug_state;
225 	r_debug.r_state = RT_CONSISTENT;
226 
227 	r_debug_state(NULL, NULL);	/* say hello to gdb! */
228 #endif
229 
230     }
231 #endif
232 }
233 
234 SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0);
235 
236 static int
237 link_elf_preload_parse_symbols(elf_file_t ef)
238 {
239     caddr_t	pointer;
240     caddr_t	ssym, esym, base;
241     caddr_t	strtab;
242     int		strcnt;
243     Elf_Sym*	symtab;
244     int		symcnt;
245 
246     if (ef->modptr == NULL)
247 	return 0;
248     pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_SSYM);
249     if (pointer == NULL)
250 	return 0;
251     ssym = *(caddr_t *)pointer;
252     pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_ESYM);
253     if (pointer == NULL)
254 	return 0;
255     esym = *(caddr_t *)pointer;
256 
257     base = ssym;
258 
259     symcnt = *(long *)base;
260     base += sizeof(long);
261     symtab = (Elf_Sym *)base;
262     base += roundup(symcnt, sizeof(long));
263 
264     if (base > esym || base < ssym) {
265 	printf("Symbols are corrupt!\n");
266 	return EINVAL;
267     }
268 
269     strcnt = *(long *)base;
270     base += sizeof(long);
271     strtab = base;
272     base += roundup(strcnt, sizeof(long));
273 
274     if (base > esym || base < ssym) {
275 	printf("Symbols are corrupt!\n");
276 	return EINVAL;
277     }
278 
279     ef->ddbsymtab = symtab;
280     ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
281     ef->ddbstrtab = strtab;
282     ef->ddbstrcnt = strcnt;
283 
284     return 0;
285 }
286 
287 static int
288 parse_dynamic(elf_file_t ef)
289 {
290     Elf_Dyn *dp;
291     int plttype = DT_REL;
292 
293     for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
294 	switch (dp->d_tag) {
295 	case DT_HASH:
296 	{
297 	    /* From src/libexec/rtld-elf/rtld.c */
298 	    const Elf_Off *hashtab = (const Elf_Off *)
299 		(ef->address + dp->d_un.d_ptr);
300 	    ef->nbuckets = hashtab[0];
301 	    ef->nchains = hashtab[1];
302 	    ef->buckets = hashtab + 2;
303 	    ef->chains = ef->buckets + ef->nbuckets;
304 	    break;
305 	}
306 	case DT_STRTAB:
307 	    ef->strtab = (caddr_t) (ef->address + dp->d_un.d_ptr);
308 	    break;
309 	case DT_STRSZ:
310 	    ef->strsz = dp->d_un.d_val;
311 	    break;
312 	case DT_SYMTAB:
313 	    ef->symtab = (Elf_Sym*) (ef->address + dp->d_un.d_ptr);
314 	    break;
315 	case DT_SYMENT:
316 	    if (dp->d_un.d_val != sizeof(Elf_Sym))
317 		return ENOEXEC;
318 	    break;
319 	case DT_PLTGOT:
320 	    ef->got = (Elf_Addr *) (ef->address + dp->d_un.d_ptr);
321 	    break;
322 	case DT_REL:
323 	    ef->rel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr);
324 	    break;
325 	case DT_RELSZ:
326 	    ef->relsize = dp->d_un.d_val;
327 	    break;
328 	case DT_RELENT:
329 	    if (dp->d_un.d_val != sizeof(Elf_Rel))
330 		return ENOEXEC;
331 	    break;
332 	case DT_JMPREL:
333 	    ef->pltrel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr);
334 	    break;
335 	case DT_PLTRELSZ:
336 	    ef->pltrelsize = dp->d_un.d_val;
337 	    break;
338 	case DT_RELA:
339 	    ef->rela = (const Elf_Rela *) (ef->address + dp->d_un.d_ptr);
340 	    break;
341 	case DT_RELASZ:
342 	    ef->relasize = dp->d_un.d_val;
343 	    break;
344 	case DT_RELAENT:
345 	    if (dp->d_un.d_val != sizeof(Elf_Rela))
346 		return ENOEXEC;
347 	    break;
348 	case DT_PLTREL:
349 	    plttype = dp->d_un.d_val;
350 	    if (plttype != DT_REL && plttype != DT_RELA)
351 		return ENOEXEC;
352 	    break;
353 #ifdef DDB
354 	case DT_DEBUG:
355 	    dp->d_un.d_ptr = (Elf_Addr) &r_debug;
356 	    break;
357 #endif
358 	}
359     }
360 
361     if (plttype == DT_RELA) {
362 	ef->pltrela = (const Elf_Rela *) ef->pltrel;
363 	ef->pltrel = NULL;
364 	ef->pltrelasize = ef->pltrelsize;
365 	ef->pltrelsize = 0;
366     }
367 
368     ef->ddbsymtab = ef->symtab;
369     ef->ddbsymcnt = ef->nchains;
370     ef->ddbstrtab = ef->strtab;
371     ef->ddbstrcnt = ef->strsz;
372 
373     return 0;
374 }
375 
376 static void
377 link_elf_error(const char *s)
378 {
379     printf("kldload: %s\n", s);
380 }
381 
382 #ifdef DDB
383 
384 static void
385 link_elf_add_gdb(struct link_map *l)
386 {
387     struct link_map *prev;
388 
389     /*
390      * Scan to the end of the list.
391      */
392     for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next)
393 	;
394 
395     /* Link in the new entry. */
396     l->l_prev = prev;
397     l->l_next = prev->l_next;
398     prev->l_next = l;
399 }
400 
401 static void
402 link_elf_delete_gdb(struct link_map *l)
403 {
404     if (l->l_prev == NULL) {
405 	if ((r_debug.r_map = l->l_next) != NULL)
406 	    l->l_next->l_prev = NULL;
407 	return;
408     }
409 
410     if ((l->l_prev->l_next = l->l_next) != NULL)
411 	l->l_next->l_prev = l->l_prev;
412 }
413 
414 #endif /* DDB */
415 
416 static int
417 link_elf_link_preload(linker_class_t cls,
418 		      const char* filename, linker_file_t *result)
419 {
420     caddr_t		modptr, baseptr, sizeptr, dynptr;
421     char		*type;
422     elf_file_t		ef;
423     linker_file_t	lf;
424     int			error;
425     vm_offset_t		dp;
426 
427     /* Look to see if we have the file preloaded */
428     modptr = preload_search_by_name(filename);
429     if (modptr == NULL)
430 	return ENOENT;
431 
432     type = (char *)preload_search_info(modptr, MODINFO_TYPE);
433     baseptr = preload_search_info(modptr, MODINFO_ADDR);
434     sizeptr = preload_search_info(modptr, MODINFO_SIZE);
435     dynptr = preload_search_info(modptr, MODINFO_METADATA|MODINFOMD_DYNAMIC);
436     if (type == NULL || strcmp(type, "elf module") != 0)
437 	return (EFTYPE);
438     if (baseptr == NULL || sizeptr == NULL || dynptr == NULL)
439 	return (EINVAL);
440 
441     lf = linker_make_file(filename, &link_elf_class);
442     if (lf == NULL) {
443 	return ENOMEM;
444     }
445 
446     ef = (elf_file_t) lf;
447     ef->preloaded = 1;
448     ef->modptr = modptr;
449     ef->address = *(caddr_t *)baseptr;
450 #ifdef SPARSE_MAPPING
451     ef->object = 0;
452 #endif
453     dp = (vm_offset_t)ef->address + *(vm_offset_t *)dynptr;
454     ef->dynamic = (Elf_Dyn *)dp;
455     lf->address = ef->address;
456     lf->size = *(size_t *)sizeptr;
457 
458     error = parse_dynamic(ef);
459     if (error) {
460 	linker_file_unload(lf);
461 	return error;
462     }
463     *result = lf;
464     return (0);
465 }
466 
467 static int
468 link_elf_link_preload_finish(linker_file_t lf)
469 {
470     elf_file_t		ef;
471     int error;
472 
473     ef = (elf_file_t) lf;
474 #if 0	/* this will be more trouble than it's worth for now */
475     for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
476 	if (dp->d_tag != DT_NEEDED)
477 	    continue;
478 	modname = ef->strtab + dp->d_un.d_val;
479 	error = linker_load_module(modname, lf);
480 	if (error)
481 	    goto out;
482     }
483 #endif
484     error = relocate_file(ef);
485     if (error)
486 	return error;
487     (void)link_elf_preload_parse_symbols(ef);
488 
489 #ifdef DDB
490     GDB_STATE(RT_ADD);
491     ef->gdb.l_addr = lf->address;
492     ef->gdb.l_name = lf->filename;
493     ef->gdb.l_ld = ef->dynamic;
494     link_elf_add_gdb(&ef->gdb);
495     GDB_STATE(RT_CONSISTENT);
496 #endif
497 
498     return (0);
499 }
500 
501 static int
502 link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* result)
503 {
504     struct nameidata nd;
505     struct proc* p = curproc;	/* XXX */
506     Elf_Ehdr *hdr;
507     caddr_t firstpage;
508     int nbytes, i;
509     Elf_Phdr *phdr;
510     Elf_Phdr *phlimit;
511     Elf_Phdr *segs[2];
512     int nsegs;
513     Elf_Phdr *phdyn;
514     Elf_Phdr *phphdr;
515     caddr_t mapbase;
516     size_t mapsize;
517     Elf_Off base_offset;
518     Elf_Addr base_vaddr;
519     Elf_Addr base_vlimit;
520     int error = 0;
521     int resid, flags;
522     elf_file_t ef;
523     linker_file_t lf;
524     Elf_Shdr *shdr;
525     int symtabindex;
526     int symstrindex;
527     int symcnt;
528     int strcnt;
529 
530     shdr = NULL;
531     lf = NULL;
532 
533     NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, p);
534     flags = FREAD;
535     error = vn_open(&nd, &flags, 0);
536     if (error)
537 	return error;
538     NDFREE(&nd, NDF_ONLY_PNBUF);
539 
540     /*
541      * Read the elf header from the file.
542      */
543     firstpage = malloc(PAGE_SIZE, M_LINKER, M_WAITOK);
544     if (firstpage == NULL) {
545 	error = ENOMEM;
546 	goto out;
547     }
548     hdr = (Elf_Ehdr *)firstpage;
549     error = vn_rdwr(UIO_READ, nd.ni_vp, firstpage, PAGE_SIZE, 0,
550 		    UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
551     nbytes = PAGE_SIZE - resid;
552     if (error)
553 	goto out;
554 
555     if (!IS_ELF(*hdr)) {
556 	error = ENOEXEC;
557 	goto out;
558     }
559 
560     if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS
561       || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
562 	link_elf_error("Unsupported file layout");
563 	error = ENOEXEC;
564 	goto out;
565     }
566     if (hdr->e_ident[EI_VERSION] != EV_CURRENT
567       || hdr->e_version != EV_CURRENT) {
568 	link_elf_error("Unsupported file version");
569 	error = ENOEXEC;
570 	goto out;
571     }
572     if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
573 	link_elf_error("Unsupported file type");
574 	error = ENOEXEC;
575 	goto out;
576     }
577     if (hdr->e_machine != ELF_TARG_MACH) {
578 	link_elf_error("Unsupported machine");
579 	error = ENOEXEC;
580 	goto out;
581     }
582 
583     /*
584      * We rely on the program header being in the first page.  This is
585      * not strictly required by the ABI specification, but it seems to
586      * always true in practice.  And, it simplifies things considerably.
587      */
588     if (!((hdr->e_phentsize == sizeof(Elf_Phdr)) &&
589 	  (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= PAGE_SIZE) &&
590 	  (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= nbytes)))
591 	link_elf_error("Unreadable program headers");
592 
593     /*
594      * Scan the program header entries, and save key information.
595      *
596      * We rely on there being exactly two load segments, text and data,
597      * in that order.
598      */
599     phdr = (Elf_Phdr *) (firstpage + hdr->e_phoff);
600     phlimit = phdr + hdr->e_phnum;
601     nsegs = 0;
602     phdyn = NULL;
603     phphdr = NULL;
604     while (phdr < phlimit) {
605 	switch (phdr->p_type) {
606 
607 	case PT_LOAD:
608 	    if (nsegs == 2) {
609 		link_elf_error("Too many sections");
610 		error = ENOEXEC;
611 		goto out;
612 	    }
613 	    segs[nsegs] = phdr;
614 	    ++nsegs;
615 	    break;
616 
617 	case PT_PHDR:
618 	    phphdr = phdr;
619 	    break;
620 
621 	case PT_DYNAMIC:
622 	    phdyn = phdr;
623 	    break;
624 
625 	case PT_INTERP:
626 	    link_elf_error("Unsupported file type");
627 	    error = ENOEXEC;
628 	    goto out;
629 	}
630 
631 	++phdr;
632     }
633     if (phdyn == NULL) {
634 	link_elf_error("Object is not dynamically-linked");
635 	error = ENOEXEC;
636 	goto out;
637     }
638 
639     /*
640      * Allocate the entire address space of the object, to stake out our
641      * contiguous region, and to establish the base address for relocation.
642      */
643     base_offset = trunc_page(segs[0]->p_offset);
644     base_vaddr = trunc_page(segs[0]->p_vaddr);
645     base_vlimit = round_page(segs[1]->p_vaddr + segs[1]->p_memsz);
646     mapsize = base_vlimit - base_vaddr;
647 
648     lf = linker_make_file(filename, &link_elf_class);
649     if (!lf) {
650 	error = ENOMEM;
651 	goto out;
652     }
653 
654     ef = (elf_file_t) lf;
655 #ifdef SPARSE_MAPPING
656     mtx_lock(&vm_mtx);
657     ef->object = vm_object_allocate(OBJT_DEFAULT, mapsize >> PAGE_SHIFT);
658     if (ef->object == NULL) {
659     	mtx_unlock(&vm_mtx);
660 	free(ef, M_LINKER);
661 	error = ENOMEM;
662 	goto out;
663     }
664     vm_object_reference(ef->object);
665     ef->address = (caddr_t) vm_map_min(kernel_map);
666     error = vm_map_find(kernel_map, ef->object, 0,
667 			(vm_offset_t *) &ef->address,
668 			mapsize, 1,
669 			VM_PROT_ALL, VM_PROT_ALL, 0);
670     if (error) {
671 	vm_object_deallocate(ef->object);
672     	mtx_unlock(&vm_mtx);
673 	ef->object = 0;
674 	goto out;
675     }
676     mtx_unlock(&vm_mtx);
677 #else
678     ef->address = malloc(mapsize, M_LINKER, M_WAITOK);
679     if (!ef->address) {
680 	error = ENOMEM;
681 	goto out;
682     }
683 #endif
684     mapbase = ef->address;
685 
686     /*
687      * Read the text and data sections and zero the bss.
688      */
689     for (i = 0; i < 2; i++) {
690 	caddr_t segbase = mapbase + segs[i]->p_vaddr - base_vaddr;
691 	error = vn_rdwr(UIO_READ, nd.ni_vp,
692 			segbase, segs[i]->p_filesz, segs[i]->p_offset,
693 			UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
694 	if (error) {
695 	    goto out;
696 	}
697 	bzero(segbase + segs[i]->p_filesz,
698 	      segs[i]->p_memsz - segs[i]->p_filesz);
699 
700 #ifdef SPARSE_MAPPING
701 	/*
702 	 * Wire down the pages
703 	 */
704 	mtx_lock(&vm_mtx);
705 	vm_map_pageable(kernel_map,
706 			(vm_offset_t) segbase,
707 			(vm_offset_t) segbase + segs[i]->p_memsz,
708 			FALSE);
709 	mtx_unlock(&vm_mtx);
710 #endif
711     }
712 
713     ef->dynamic = (Elf_Dyn *) (mapbase + phdyn->p_vaddr - base_vaddr);
714 
715     lf->address = ef->address;
716     lf->size = mapsize;
717 
718     error = parse_dynamic(ef);
719     if (error)
720 	goto out;
721     error = linker_load_dependancies(lf);
722     if (error)
723 	goto out;
724 #if 0	/* this will be more trouble than it's worth for now */
725     for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
726 	if (dp->d_tag != DT_NEEDED)
727 	    continue;
728 	modname = ef->strtab + dp->d_un.d_val;
729 	error = linker_load_module(modname, lf);
730 	if (error)
731 	    goto out;
732     }
733 #endif
734     error = relocate_file(ef);
735     if (error)
736 	goto out;
737 
738     /* Try and load the symbol table if it's present.  (you can strip it!) */
739     nbytes = hdr->e_shnum * hdr->e_shentsize;
740     if (nbytes == 0 || hdr->e_shoff == 0)
741 	goto nosyms;
742     shdr = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO);
743     if (shdr == NULL) {
744 	error = ENOMEM;
745 	goto out;
746     }
747     error = vn_rdwr(UIO_READ, nd.ni_vp,
748 		    (caddr_t)shdr, nbytes, hdr->e_shoff,
749 		    UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
750     if (error)
751 	goto out;
752     symtabindex = -1;
753     symstrindex = -1;
754     for (i = 0; i < hdr->e_shnum; i++) {
755 	if (shdr[i].sh_type == SHT_SYMTAB) {
756 	    symtabindex = i;
757 	    symstrindex = shdr[i].sh_link;
758 	}
759     }
760     if (symtabindex < 0 || symstrindex < 0)
761 	goto nosyms;
762 
763     symcnt = shdr[symtabindex].sh_size;
764     ef->symbase = malloc(symcnt, M_LINKER, M_WAITOK);
765     strcnt = shdr[symstrindex].sh_size;
766     ef->strbase = malloc(strcnt, M_LINKER, M_WAITOK);
767 
768     if (ef->symbase == NULL || ef->strbase == NULL) {
769 	error = ENOMEM;
770 	goto out;
771     }
772     error = vn_rdwr(UIO_READ, nd.ni_vp,
773 		    ef->symbase, symcnt, shdr[symtabindex].sh_offset,
774 		    UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
775     if (error)
776 	goto out;
777     error = vn_rdwr(UIO_READ, nd.ni_vp,
778 		    ef->strbase, strcnt, shdr[symstrindex].sh_offset,
779 		    UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
780     if (error)
781 	goto out;
782 
783     ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
784     ef->ddbsymtab = (const Elf_Sym *)ef->symbase;
785     ef->ddbstrcnt = strcnt;
786     ef->ddbstrtab = ef->strbase;
787 
788 #ifdef DDB
789     GDB_STATE(RT_ADD);
790     ef->gdb.l_addr = lf->address;
791     ef->gdb.l_name = filename;
792     ef->gdb.l_ld = ef->dynamic;
793     link_elf_add_gdb(&ef->gdb);
794     GDB_STATE(RT_CONSISTENT);
795 #endif
796 
797 nosyms:
798 
799     *result = lf;
800 
801 out:
802     if (error && lf)
803 	linker_file_unload(lf);
804     if (shdr)
805 	free(shdr, M_LINKER);
806     if (firstpage)
807 	free(firstpage, M_LINKER);
808     VOP_UNLOCK(nd.ni_vp, 0, p);
809     vn_close(nd.ni_vp, FREAD, p->p_ucred, p);
810 
811     return error;
812 }
813 
814 static void
815 link_elf_unload_file(linker_file_t file)
816 {
817     elf_file_t ef = (elf_file_t) file;
818 
819 #ifdef DDB
820     if (ef->gdb.l_ld) {
821 	GDB_STATE(RT_DELETE);
822 	link_elf_delete_gdb(&ef->gdb);
823 	GDB_STATE(RT_CONSISTENT);
824     }
825 #endif
826 
827     if (ef->preloaded) {
828 	link_elf_unload_preload(file);
829 	return;
830     }
831 #ifdef SPARSE_MAPPING
832     if (ef->object) {
833 	mtx_lock(&vm_mtx);
834 	vm_map_remove(kernel_map, (vm_offset_t) ef->address,
835 		      (vm_offset_t) ef->address
836 		      + (ef->object->size << PAGE_SHIFT));
837 	vm_object_deallocate(ef->object);
838 	mtx_unlock(&vm_mtx);
839     }
840 #else
841     if (ef->address)
842 	free(ef->address, M_LINKER);
843 #endif
844     if (ef->symbase)
845 	free(ef->symbase, M_LINKER);
846     if (ef->strbase)
847 	free(ef->strbase, M_LINKER);
848 }
849 
850 static void
851 link_elf_unload_preload(linker_file_t file)
852 {
853     if (file->filename)
854 	preload_delete_name(file->filename);
855 }
856 
857 static const char *
858 symbol_name(elf_file_t ef, Elf_Word r_info)
859 {
860     const Elf_Sym *ref;
861 
862     if (ELF_R_SYM(r_info)) {
863 	ref = ef->symtab + ELF_R_SYM(r_info);
864 	return ef->strtab + ref->st_name;
865     } else
866 	return NULL;
867 }
868 
869 static int
870 relocate_file(elf_file_t ef)
871 {
872     const Elf_Rel *rellim;
873     const Elf_Rel *rel;
874     const Elf_Rela *relalim;
875     const Elf_Rela *rela;
876     const char *symname;
877 
878     /* Perform relocations without addend if there are any: */
879     rel = ef->rel;
880     if (rel) {
881 	rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
882 	while (rel < rellim) {
883 	    symname = symbol_name(ef, rel->r_info);
884 	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) {
885 		printf("link_elf: symbol %s undefined\n", symname);
886 		return ENOENT;
887 	    }
888 	    rel++;
889 	}
890     }
891 
892     /* Perform relocations with addend if there are any: */
893     rela = ef->rela;
894     if (rela) {
895 	relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
896 	while (rela < relalim) {
897 	    symname = symbol_name(ef, rela->r_info);
898 	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) {
899 		printf("link_elf: symbol %s undefined\n", symname);
900 		return ENOENT;
901 	    }
902 	    rela++;
903 	}
904     }
905 
906     /* Perform PLT relocations without addend if there are any: */
907     rel = ef->pltrel;
908     if (rel) {
909 	rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
910 	while (rel < rellim) {
911 	    symname = symbol_name(ef, rel->r_info);
912 	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) {
913 		printf("link_elf: symbol %s undefined\n", symname);
914 		return ENOENT;
915 	    }
916 	    rel++;
917 	}
918     }
919 
920     /* Perform relocations with addend if there are any: */
921     rela = ef->pltrela;
922     if (rela) {
923 	relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
924 	while (rela < relalim) {
925 	    symname = symbol_name(ef, rela->r_info);
926 	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) {
927 		printf("link_elf: symbol %s undefined\n", symname);
928 		return ENOENT;
929 	    }
930 	    rela++;
931 	}
932     }
933 
934     return 0;
935 }
936 
937 /*
938  * Hash function for symbol table lookup.  Don't even think about changing
939  * this.  It is specified by the System V ABI.
940  */
941 static unsigned long
942 elf_hash(const char *name)
943 {
944     const unsigned char *p = (const unsigned char *) name;
945     unsigned long h = 0;
946     unsigned long g;
947 
948     while (*p != '\0') {
949 	h = (h << 4) + *p++;
950 	if ((g = h & 0xf0000000) != 0)
951 	    h ^= g >> 24;
952 	h &= ~g;
953     }
954     return h;
955 }
956 
957 int
958 link_elf_lookup_symbol(linker_file_t lf, const char* name, c_linker_sym_t* sym)
959 {
960     elf_file_t ef = (elf_file_t) lf;
961     unsigned long symnum;
962     const Elf_Sym* symp;
963     const char *strp;
964     unsigned long hash;
965     int i;
966 
967     /* First, search hashed global symbols */
968     hash = elf_hash(name);
969     symnum = ef->buckets[hash % ef->nbuckets];
970 
971     while (symnum != STN_UNDEF) {
972 	if (symnum >= ef->nchains) {
973 	    printf("link_elf_lookup_symbol: corrupt symbol table\n");
974 	    return ENOENT;
975 	}
976 
977 	symp = ef->symtab + symnum;
978 	if (symp->st_name == 0) {
979 	    printf("link_elf_lookup_symbol: corrupt symbol table\n");
980 	    return ENOENT;
981 	}
982 
983 	strp = ef->strtab + symp->st_name;
984 
985 	if (strcmp(name, strp) == 0) {
986 	    if (symp->st_shndx != SHN_UNDEF ||
987 		(symp->st_value != 0 &&
988 		 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
989 		*sym = (c_linker_sym_t) symp;
990 		return 0;
991 	    } else
992 		return ENOENT;
993 	}
994 
995 	symnum = ef->chains[symnum];
996     }
997 
998     /* If we have not found it, look at the full table (if loaded) */
999     if (ef->symtab == ef->ddbsymtab)
1000 	return ENOENT;
1001 
1002     /* Exhaustive search */
1003     for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1004 	strp = ef->ddbstrtab + symp->st_name;
1005 	if (strcmp(name, strp) == 0) {
1006 	    if (symp->st_shndx != SHN_UNDEF ||
1007 		(symp->st_value != 0 &&
1008 		 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
1009 		*sym = (c_linker_sym_t) symp;
1010 		return 0;
1011 	    } else
1012 		return ENOENT;
1013 	}
1014     }
1015 
1016     return ENOENT;
1017 }
1018 
1019 static int
1020 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t* symval)
1021 {
1022 	elf_file_t ef = (elf_file_t) lf;
1023 	const Elf_Sym* es = (const Elf_Sym*) sym;
1024 
1025 	if (es >= ef->symtab && ((es - ef->symtab) < ef->nchains)) {
1026 	    symval->name = ef->strtab + es->st_name;
1027 	    symval->value = (caddr_t) ef->address + es->st_value;
1028 	    symval->size = es->st_size;
1029 	    return 0;
1030 	}
1031 	if (ef->symtab == ef->ddbsymtab)
1032 	    return ENOENT;
1033 	if (es >= ef->ddbsymtab && ((es - ef->ddbsymtab) < ef->ddbsymcnt)) {
1034 	    symval->name = ef->ddbstrtab + es->st_name;
1035 	    symval->value = (caddr_t) ef->address + es->st_value;
1036 	    symval->size = es->st_size;
1037 	    return 0;
1038 	}
1039 	return ENOENT;
1040 }
1041 
1042 static int
1043 link_elf_search_symbol(linker_file_t lf, caddr_t value,
1044 		       c_linker_sym_t* sym, long* diffp)
1045 {
1046 	elf_file_t ef = (elf_file_t) lf;
1047 	u_long off = (uintptr_t) (void *) value;
1048 	u_long diff = off;
1049 	u_long st_value;
1050 	const Elf_Sym* es;
1051 	const Elf_Sym* best = 0;
1052 	int i;
1053 
1054 	for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) {
1055 		if (es->st_name == 0)
1056 			continue;
1057 		st_value = es->st_value + (uintptr_t) (void *) ef->address;
1058 		if (off >= st_value) {
1059 			if (off - st_value < diff) {
1060 				diff = off - st_value;
1061 				best = es;
1062 				if (diff == 0)
1063 					break;
1064 			} else if (off - st_value == diff) {
1065 				best = es;
1066 			}
1067 		}
1068 	}
1069 	if (best == 0)
1070 		*diffp = off;
1071 	else
1072 		*diffp = diff;
1073 	*sym = (c_linker_sym_t) best;
1074 
1075 	return 0;
1076 }
1077