xref: /freebsd/sys/kern/link_elf_obj.c (revision 3a51f88a2721f4cf7aded2a63f20925f8d700a7c)
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     ef->object = vm_object_allocate(OBJT_DEFAULT, mapsize >> PAGE_SHIFT);
657     if (ef->object == NULL) {
658 	free(ef, M_LINKER);
659 	error = ENOMEM;
660 	goto out;
661     }
662     vm_object_reference(ef->object);
663     ef->address = (caddr_t) vm_map_min(kernel_map);
664     error = vm_map_find(kernel_map, ef->object, 0,
665 			(vm_offset_t *) &ef->address,
666 			mapsize, 1,
667 			VM_PROT_ALL, VM_PROT_ALL, 0);
668     if (error) {
669 	vm_object_deallocate(ef->object);
670 	ef->object = 0;
671 	goto out;
672     }
673 #else
674     ef->address = malloc(mapsize, M_LINKER, M_WAITOK);
675     if (!ef->address) {
676 	error = ENOMEM;
677 	goto out;
678     }
679 #endif
680     mapbase = ef->address;
681 
682     /*
683      * Read the text and data sections and zero the bss.
684      */
685     for (i = 0; i < 2; i++) {
686 	caddr_t segbase = mapbase + segs[i]->p_vaddr - base_vaddr;
687 	error = vn_rdwr(UIO_READ, nd.ni_vp,
688 			segbase, segs[i]->p_filesz, segs[i]->p_offset,
689 			UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
690 	if (error) {
691 	    goto out;
692 	}
693 	bzero(segbase + segs[i]->p_filesz,
694 	      segs[i]->p_memsz - segs[i]->p_filesz);
695 
696 #ifdef SPARSE_MAPPING
697 	/*
698 	 * Wire down the pages
699 	 */
700 	vm_map_pageable(kernel_map,
701 			(vm_offset_t) segbase,
702 			(vm_offset_t) segbase + segs[i]->p_memsz,
703 			FALSE);
704 #endif
705     }
706 
707     ef->dynamic = (Elf_Dyn *) (mapbase + phdyn->p_vaddr - base_vaddr);
708 
709     lf->address = ef->address;
710     lf->size = mapsize;
711 
712     error = parse_dynamic(ef);
713     if (error)
714 	goto out;
715     error = linker_load_dependancies(lf);
716     if (error)
717 	goto out;
718 #if 0	/* this will be more trouble than it's worth for now */
719     for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
720 	if (dp->d_tag != DT_NEEDED)
721 	    continue;
722 	modname = ef->strtab + dp->d_un.d_val;
723 	error = linker_load_module(modname, lf);
724 	if (error)
725 	    goto out;
726     }
727 #endif
728     error = relocate_file(ef);
729     if (error)
730 	goto out;
731 
732     /* Try and load the symbol table if it's present.  (you can strip it!) */
733     nbytes = hdr->e_shnum * hdr->e_shentsize;
734     if (nbytes == 0 || hdr->e_shoff == 0)
735 	goto nosyms;
736     shdr = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO);
737     if (shdr == NULL) {
738 	error = ENOMEM;
739 	goto out;
740     }
741     error = vn_rdwr(UIO_READ, nd.ni_vp,
742 		    (caddr_t)shdr, nbytes, hdr->e_shoff,
743 		    UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
744     if (error)
745 	goto out;
746     symtabindex = -1;
747     symstrindex = -1;
748     for (i = 0; i < hdr->e_shnum; i++) {
749 	if (shdr[i].sh_type == SHT_SYMTAB) {
750 	    symtabindex = i;
751 	    symstrindex = shdr[i].sh_link;
752 	}
753     }
754     if (symtabindex < 0 || symstrindex < 0)
755 	goto nosyms;
756 
757     symcnt = shdr[symtabindex].sh_size;
758     ef->symbase = malloc(symcnt, M_LINKER, M_WAITOK);
759     strcnt = shdr[symstrindex].sh_size;
760     ef->strbase = malloc(strcnt, M_LINKER, M_WAITOK);
761 
762     if (ef->symbase == NULL || ef->strbase == NULL) {
763 	error = ENOMEM;
764 	goto out;
765     }
766     error = vn_rdwr(UIO_READ, nd.ni_vp,
767 		    ef->symbase, symcnt, shdr[symtabindex].sh_offset,
768 		    UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
769     if (error)
770 	goto out;
771     error = vn_rdwr(UIO_READ, nd.ni_vp,
772 		    ef->strbase, strcnt, shdr[symstrindex].sh_offset,
773 		    UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
774     if (error)
775 	goto out;
776 
777     ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
778     ef->ddbsymtab = (const Elf_Sym *)ef->symbase;
779     ef->ddbstrcnt = strcnt;
780     ef->ddbstrtab = ef->strbase;
781 
782 #ifdef DDB
783     GDB_STATE(RT_ADD);
784     ef->gdb.l_addr = lf->address;
785     ef->gdb.l_name = filename;
786     ef->gdb.l_ld = ef->dynamic;
787     link_elf_add_gdb(&ef->gdb);
788     GDB_STATE(RT_CONSISTENT);
789 #endif
790 
791 nosyms:
792 
793     *result = lf;
794 
795 out:
796     if (error && lf)
797 	linker_file_unload(lf);
798     if (shdr)
799 	free(shdr, M_LINKER);
800     if (firstpage)
801 	free(firstpage, M_LINKER);
802     VOP_UNLOCK(nd.ni_vp, 0, p);
803     vn_close(nd.ni_vp, FREAD, p->p_ucred, p);
804 
805     return error;
806 }
807 
808 static void
809 link_elf_unload_file(linker_file_t file)
810 {
811     elf_file_t ef = (elf_file_t) file;
812 
813 #ifdef DDB
814     if (ef->gdb.l_ld) {
815 	GDB_STATE(RT_DELETE);
816 	link_elf_delete_gdb(&ef->gdb);
817 	GDB_STATE(RT_CONSISTENT);
818     }
819 #endif
820 
821     if (ef->preloaded) {
822 	link_elf_unload_preload(file);
823 	return;
824     }
825 #ifdef SPARSE_MAPPING
826     if (ef->object) {
827 	vm_map_remove(kernel_map, (vm_offset_t) ef->address,
828 		      (vm_offset_t) ef->address
829 		      + (ef->object->size << PAGE_SHIFT));
830 	vm_object_deallocate(ef->object);
831     }
832 #else
833     if (ef->address)
834 	free(ef->address, M_LINKER);
835 #endif
836     if (ef->symbase)
837 	free(ef->symbase, M_LINKER);
838     if (ef->strbase)
839 	free(ef->strbase, M_LINKER);
840 }
841 
842 static void
843 link_elf_unload_preload(linker_file_t file)
844 {
845     if (file->filename)
846 	preload_delete_name(file->filename);
847 }
848 
849 static const char *
850 symbol_name(elf_file_t ef, Elf_Word r_info)
851 {
852     const Elf_Sym *ref;
853 
854     if (ELF_R_SYM(r_info)) {
855 	ref = ef->symtab + ELF_R_SYM(r_info);
856 	return ef->strtab + ref->st_name;
857     } else
858 	return NULL;
859 }
860 
861 static int
862 relocate_file(elf_file_t ef)
863 {
864     const Elf_Rel *rellim;
865     const Elf_Rel *rel;
866     const Elf_Rela *relalim;
867     const Elf_Rela *rela;
868     const char *symname;
869 
870     /* Perform relocations without addend if there are any: */
871     rel = ef->rel;
872     if (rel) {
873 	rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
874 	while (rel < rellim) {
875 	    symname = symbol_name(ef, rel->r_info);
876 	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) {
877 		printf("link_elf: symbol %s undefined\n", symname);
878 		return ENOENT;
879 	    }
880 	    rel++;
881 	}
882     }
883 
884     /* Perform relocations with addend if there are any: */
885     rela = ef->rela;
886     if (rela) {
887 	relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
888 	while (rela < relalim) {
889 	    symname = symbol_name(ef, rela->r_info);
890 	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) {
891 		printf("link_elf: symbol %s undefined\n", symname);
892 		return ENOENT;
893 	    }
894 	    rela++;
895 	}
896     }
897 
898     /* Perform PLT relocations without addend if there are any: */
899     rel = ef->pltrel;
900     if (rel) {
901 	rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
902 	while (rel < rellim) {
903 	    symname = symbol_name(ef, rel->r_info);
904 	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL, symname)) {
905 		printf("link_elf: symbol %s undefined\n", symname);
906 		return ENOENT;
907 	    }
908 	    rel++;
909 	}
910     }
911 
912     /* Perform relocations with addend if there are any: */
913     rela = ef->pltrela;
914     if (rela) {
915 	relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
916 	while (rela < relalim) {
917 	    symname = symbol_name(ef, rela->r_info);
918 	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA, symname)) {
919 		printf("link_elf: symbol %s undefined\n", symname);
920 		return ENOENT;
921 	    }
922 	    rela++;
923 	}
924     }
925 
926     return 0;
927 }
928 
929 /*
930  * Hash function for symbol table lookup.  Don't even think about changing
931  * this.  It is specified by the System V ABI.
932  */
933 static unsigned long
934 elf_hash(const char *name)
935 {
936     const unsigned char *p = (const unsigned char *) name;
937     unsigned long h = 0;
938     unsigned long g;
939 
940     while (*p != '\0') {
941 	h = (h << 4) + *p++;
942 	if ((g = h & 0xf0000000) != 0)
943 	    h ^= g >> 24;
944 	h &= ~g;
945     }
946     return h;
947 }
948 
949 int
950 link_elf_lookup_symbol(linker_file_t lf, const char* name, c_linker_sym_t* sym)
951 {
952     elf_file_t ef = (elf_file_t) lf;
953     unsigned long symnum;
954     const Elf_Sym* symp;
955     const char *strp;
956     unsigned long hash;
957     int i;
958 
959     /* First, search hashed global symbols */
960     hash = elf_hash(name);
961     symnum = ef->buckets[hash % ef->nbuckets];
962 
963     while (symnum != STN_UNDEF) {
964 	if (symnum >= ef->nchains) {
965 	    printf("link_elf_lookup_symbol: corrupt symbol table\n");
966 	    return ENOENT;
967 	}
968 
969 	symp = ef->symtab + symnum;
970 	if (symp->st_name == 0) {
971 	    printf("link_elf_lookup_symbol: corrupt symbol table\n");
972 	    return ENOENT;
973 	}
974 
975 	strp = ef->strtab + symp->st_name;
976 
977 	if (strcmp(name, strp) == 0) {
978 	    if (symp->st_shndx != SHN_UNDEF ||
979 		(symp->st_value != 0 &&
980 		 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
981 		*sym = (c_linker_sym_t) symp;
982 		return 0;
983 	    } else
984 		return ENOENT;
985 	}
986 
987 	symnum = ef->chains[symnum];
988     }
989 
990     /* If we have not found it, look at the full table (if loaded) */
991     if (ef->symtab == ef->ddbsymtab)
992 	return ENOENT;
993 
994     /* Exhaustive search */
995     for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
996 	strp = ef->ddbstrtab + symp->st_name;
997 	if (strcmp(name, strp) == 0) {
998 	    if (symp->st_shndx != SHN_UNDEF ||
999 		(symp->st_value != 0 &&
1000 		 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
1001 		*sym = (c_linker_sym_t) symp;
1002 		return 0;
1003 	    } else
1004 		return ENOENT;
1005 	}
1006     }
1007 
1008     return ENOENT;
1009 }
1010 
1011 static int
1012 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t* symval)
1013 {
1014 	elf_file_t ef = (elf_file_t) lf;
1015 	const Elf_Sym* es = (const Elf_Sym*) sym;
1016 
1017 	if (es >= ef->symtab && ((es - ef->symtab) < ef->nchains)) {
1018 	    symval->name = ef->strtab + es->st_name;
1019 	    symval->value = (caddr_t) ef->address + es->st_value;
1020 	    symval->size = es->st_size;
1021 	    return 0;
1022 	}
1023 	if (ef->symtab == ef->ddbsymtab)
1024 	    return ENOENT;
1025 	if (es >= ef->ddbsymtab && ((es - ef->ddbsymtab) < ef->ddbsymcnt)) {
1026 	    symval->name = ef->ddbstrtab + es->st_name;
1027 	    symval->value = (caddr_t) ef->address + es->st_value;
1028 	    symval->size = es->st_size;
1029 	    return 0;
1030 	}
1031 	return ENOENT;
1032 }
1033 
1034 static int
1035 link_elf_search_symbol(linker_file_t lf, caddr_t value,
1036 		       c_linker_sym_t* sym, long* diffp)
1037 {
1038 	elf_file_t ef = (elf_file_t) lf;
1039 	u_long off = (uintptr_t) (void *) value;
1040 	u_long diff = off;
1041 	u_long st_value;
1042 	const Elf_Sym* es;
1043 	const Elf_Sym* best = 0;
1044 	int i;
1045 
1046 	for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) {
1047 		if (es->st_name == 0)
1048 			continue;
1049 		st_value = es->st_value + (uintptr_t) (void *) ef->address;
1050 		if (off >= st_value) {
1051 			if (off - st_value < diff) {
1052 				diff = off - st_value;
1053 				best = es;
1054 				if (diff == 0)
1055 					break;
1056 			} else if (off - st_value == diff) {
1057 				best = es;
1058 			}
1059 		}
1060 	}
1061 	if (best == 0)
1062 		*diffp = off;
1063 	else
1064 		*diffp = diff;
1065 	*sym = (c_linker_sym_t) best;
1066 
1067 	return 0;
1068 }
1069