link_elf.c revision 105467
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: head/sys/kern/link_elf.c 105467 2002-10-19 18:43:37Z marcel $
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/mutex.h>
37#include <sys/proc.h>
38#include <sys/namei.h>
39#include <sys/fcntl.h>
40#include <sys/vnode.h>
41#include <sys/linker.h>
42
43#include <machine/elf.h>
44#ifdef GPROF
45#include <machine/profile.h>
46#endif
47
48#include <vm/vm.h>
49#include <vm/vm_param.h>
50#ifdef SPARSE_MAPPING
51#include <vm/vm_object.h>
52#include <vm/vm_kern.h>
53#include <vm/vm_extern.h>
54#endif
55#include <vm/pmap.h>
56#include <vm/vm_map.h>
57
58#include <sys/link_elf.h>
59
60#include "linker_if.h"
61
62typedef struct elf_file {
63    struct linker_file	lf;		/* Common fields */
64    int			preloaded;	/* Was file pre-loaded */
65    caddr_t		address;	/* Relocation address */
66#ifdef SPARSE_MAPPING
67    vm_object_t		object;		/* VM object to hold file pages */
68#endif
69    Elf_Dyn*		dynamic;	/* Symbol table etc. */
70    Elf_Hashelt		nbuckets;	/* DT_HASH info */
71    Elf_Hashelt		nchains;
72    const Elf_Hashelt*	buckets;
73    const Elf_Hashelt*	chains;
74    caddr_t		hash;
75    caddr_t		strtab;		/* DT_STRTAB */
76    int			strsz;		/* DT_STRSZ */
77    const Elf_Sym*	symtab;		/* DT_SYMTAB */
78    Elf_Addr*		got;		/* DT_PLTGOT */
79    const Elf_Rel*	pltrel;		/* DT_JMPREL */
80    int			pltrelsize;	/* DT_PLTRELSZ */
81    const Elf_Rela*	pltrela;	/* DT_JMPREL */
82    int			pltrelasize;	/* DT_PLTRELSZ */
83    const Elf_Rel*	rel;		/* DT_REL */
84    int			relsize;	/* DT_RELSZ */
85    const Elf_Rela*	rela;		/* DT_RELA */
86    int			relasize;	/* DT_RELASZ */
87    caddr_t		modptr;
88    const Elf_Sym*	ddbsymtab;	/* The symbol table we are using */
89    long		ddbsymcnt;	/* Number of symbols */
90    caddr_t		ddbstrtab;	/* String table */
91    long		ddbstrcnt;	/* number of bytes in string table */
92    caddr_t		symbase;	/* malloc'ed symbold base */
93    caddr_t		strbase;	/* malloc'ed string base */
94#ifdef DDB
95    struct link_map	gdb;		/* hooks for gdb */
96#endif
97} *elf_file_t;
98
99static int	link_elf_link_preload(linker_class_t cls,
100				      const char*, linker_file_t*);
101static int	link_elf_link_preload_finish(linker_file_t);
102static int	link_elf_load_file(linker_class_t, const char*, linker_file_t*);
103static int	link_elf_lookup_symbol(linker_file_t, const char*,
104				       c_linker_sym_t*);
105static int	link_elf_symbol_values(linker_file_t, c_linker_sym_t, linker_symval_t*);
106static int	link_elf_search_symbol(linker_file_t, caddr_t value,
107				       c_linker_sym_t* sym, long* diffp);
108
109static void	link_elf_unload_file(linker_file_t);
110static void	link_elf_unload_preload(linker_file_t);
111static int	link_elf_lookup_set(linker_file_t, const char *,
112				    void ***, void ***, int *);
113static int	link_elf_each_function_name(linker_file_t,
114				int (*)(const char *, void *),
115				void *);
116
117static kobj_method_t link_elf_methods[] = {
118    KOBJMETHOD(linker_lookup_symbol,	link_elf_lookup_symbol),
119    KOBJMETHOD(linker_symbol_values,	link_elf_symbol_values),
120    KOBJMETHOD(linker_search_symbol,	link_elf_search_symbol),
121    KOBJMETHOD(linker_unload,		link_elf_unload_file),
122    KOBJMETHOD(linker_load_file,	link_elf_load_file),
123    KOBJMETHOD(linker_link_preload,	link_elf_link_preload),
124    KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish),
125    KOBJMETHOD(linker_lookup_set,	link_elf_lookup_set),
126    KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
127    { 0, 0 }
128};
129
130static struct linker_class link_elf_class = {
131#if ELF_TARG_CLASS == ELFCLASS32
132    "elf32",
133#else
134    "elf64",
135#endif
136    link_elf_methods, sizeof(struct elf_file)
137};
138
139static int		parse_dynamic(elf_file_t ef);
140static int		relocate_file(elf_file_t ef);
141static int		link_elf_preload_parse_symbols(elf_file_t ef);
142
143#ifdef DDB
144static void		r_debug_state(struct r_debug *dummy_one,
145				      struct link_map *dummy_two);
146
147/*
148 * A list of loaded modules for GDB to use for loading symbols.
149 */
150struct r_debug r_debug;
151
152#define GDB_STATE(s)	r_debug.r_state = s; r_debug_state(NULL, NULL);
153
154/*
155 * Function for the debugger to set a breakpoint on to gain control.
156 */
157static void
158r_debug_state(struct r_debug *dummy_one __unused,
159	      struct link_map *dummy_two __unused)
160{
161}
162
163static void
164link_elf_add_gdb(struct link_map *l)
165{
166    struct link_map *prev;
167
168    /*
169     * Scan to the end of the list.
170     */
171    for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next)
172	;
173
174    /* Link in the new entry. */
175    l->l_prev = prev;
176    l->l_next = prev->l_next;
177    prev->l_next = l;
178}
179
180static void
181link_elf_delete_gdb(struct link_map *l)
182{
183    if (l->l_prev == NULL) {
184	if ((r_debug.r_map = l->l_next) != NULL)
185	    l->l_next->l_prev = NULL;
186	return;
187    }
188
189    if ((l->l_prev->l_next = l->l_next) != NULL)
190	l->l_next->l_prev = l->l_prev;
191}
192#endif /* DDB */
193
194#ifdef __ia64__
195Elf_Addr link_elf_get_gp(linker_file_t);
196#endif
197
198/*
199 * The kernel symbol table starts here.
200 */
201extern struct _dynamic _DYNAMIC;
202
203static void
204link_elf_error(const char *s)
205{
206    printf("kldload: %s\n", s);
207}
208
209static void
210link_elf_init(void* arg)
211{
212    Elf_Dyn	*dp;
213    caddr_t	modptr, baseptr, sizeptr;
214    elf_file_t	ef;
215    char	*modname;
216#ifdef DDB
217    char *newfilename;
218#endif
219
220    linker_add_class(&link_elf_class);
221
222    dp = (Elf_Dyn*) &_DYNAMIC;
223    modname = NULL;
224    modptr = preload_search_by_type("elf kernel");
225    if (modptr)
226	modname = (char *)preload_search_info(modptr, MODINFO_NAME);
227    if (modname == NULL)
228	modname = "kernel";
229    linker_kernel_file = linker_make_file(modname, &link_elf_class);
230    if (linker_kernel_file == NULL)
231	panic("link_elf_init: Can't create linker structures for kernel");
232
233    ef = (elf_file_t) linker_kernel_file;
234    ef->preloaded = 1;
235    ef->address = 0;
236#ifdef SPARSE_MAPPING
237    ef->object = 0;
238#endif
239    ef->dynamic = dp;
240
241    if (dp)
242	parse_dynamic(ef);
243    linker_kernel_file->address = (caddr_t) KERNBASE;
244    linker_kernel_file->size = -(intptr_t)linker_kernel_file->address;
245
246    if (modptr) {
247	ef->modptr = modptr;
248	baseptr = preload_search_info(modptr, MODINFO_ADDR);
249	if (baseptr)
250	    linker_kernel_file->address = *(caddr_t *)baseptr;
251	sizeptr = preload_search_info(modptr, MODINFO_SIZE);
252	if (sizeptr)
253	    linker_kernel_file->size = *(size_t *)sizeptr;
254    }
255    (void)link_elf_preload_parse_symbols(ef);
256
257#ifdef DDB
258    ef->gdb.l_addr = linker_kernel_file->address;
259    newfilename = malloc(strlen(modname) + 1, M_LINKER, M_WAITOK);
260    strcpy(newfilename, modname);
261    ef->gdb.l_name = newfilename;
262    ef->gdb.l_ld = dp;
263    ef->gdb.l_prev = 0;
264    ef->gdb.l_next = 0;
265
266    r_debug.r_map = &ef->gdb;
267    r_debug.r_brk = r_debug_state;
268    r_debug.r_state = RT_CONSISTENT;
269
270    r_debug_state(NULL, NULL);	/* say hello to gdb! */
271#endif
272}
273
274SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0);
275
276static int
277link_elf_preload_parse_symbols(elf_file_t ef)
278{
279    caddr_t	pointer;
280    caddr_t	ssym, esym, base;
281    caddr_t	strtab;
282    int		strcnt;
283    Elf_Sym*	symtab;
284    int		symcnt;
285
286    if (ef->modptr == NULL)
287	return 0;
288    pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_SSYM);
289    if (pointer == NULL)
290	return 0;
291    ssym = *(caddr_t *)pointer;
292    pointer = preload_search_info(ef->modptr, MODINFO_METADATA|MODINFOMD_ESYM);
293    if (pointer == NULL)
294	return 0;
295    esym = *(caddr_t *)pointer;
296
297    base = ssym;
298
299    symcnt = *(long *)base;
300    base += sizeof(long);
301    symtab = (Elf_Sym *)base;
302    base += roundup(symcnt, sizeof(long));
303
304    if (base > esym || base < ssym) {
305	printf("Symbols are corrupt!\n");
306	return EINVAL;
307    }
308
309    strcnt = *(long *)base;
310    base += sizeof(long);
311    strtab = base;
312    base += roundup(strcnt, sizeof(long));
313
314    if (base > esym || base < ssym) {
315	printf("Symbols are corrupt!\n");
316	return EINVAL;
317    }
318
319    ef->ddbsymtab = symtab;
320    ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
321    ef->ddbstrtab = strtab;
322    ef->ddbstrcnt = strcnt;
323
324    return 0;
325}
326
327static int
328parse_dynamic(elf_file_t ef)
329{
330    Elf_Dyn *dp;
331    int plttype = DT_REL;
332
333    for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
334	switch (dp->d_tag) {
335	case DT_HASH:
336	{
337	    /* From src/libexec/rtld-elf/rtld.c */
338	    const Elf_Hashelt *hashtab = (const Elf_Hashelt *)
339		(ef->address + dp->d_un.d_ptr);
340	    ef->nbuckets = hashtab[0];
341	    ef->nchains = hashtab[1];
342	    ef->buckets = hashtab + 2;
343	    ef->chains = ef->buckets + ef->nbuckets;
344	    break;
345	}
346	case DT_STRTAB:
347	    ef->strtab = (caddr_t) (ef->address + dp->d_un.d_ptr);
348	    break;
349	case DT_STRSZ:
350	    ef->strsz = dp->d_un.d_val;
351	    break;
352	case DT_SYMTAB:
353	    ef->symtab = (Elf_Sym*) (ef->address + dp->d_un.d_ptr);
354	    break;
355	case DT_SYMENT:
356	    if (dp->d_un.d_val != sizeof(Elf_Sym))
357		return ENOEXEC;
358	    break;
359	case DT_PLTGOT:
360	    ef->got = (Elf_Addr *) (ef->address + dp->d_un.d_ptr);
361	    break;
362	case DT_REL:
363	    ef->rel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr);
364	    break;
365	case DT_RELSZ:
366	    ef->relsize = dp->d_un.d_val;
367	    break;
368	case DT_RELENT:
369	    if (dp->d_un.d_val != sizeof(Elf_Rel))
370		return ENOEXEC;
371	    break;
372	case DT_JMPREL:
373	    ef->pltrel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr);
374	    break;
375	case DT_PLTRELSZ:
376	    ef->pltrelsize = dp->d_un.d_val;
377	    break;
378	case DT_RELA:
379	    ef->rela = (const Elf_Rela *) (ef->address + dp->d_un.d_ptr);
380	    break;
381	case DT_RELASZ:
382	    ef->relasize = dp->d_un.d_val;
383	    break;
384	case DT_RELAENT:
385	    if (dp->d_un.d_val != sizeof(Elf_Rela))
386		return ENOEXEC;
387	    break;
388	case DT_PLTREL:
389	    plttype = dp->d_un.d_val;
390	    if (plttype != DT_REL && plttype != DT_RELA)
391		return ENOEXEC;
392	    break;
393#ifdef DDB
394	case DT_DEBUG:
395	    dp->d_un.d_ptr = (Elf_Addr) &r_debug;
396	    break;
397#endif
398	}
399    }
400
401    if (plttype == DT_RELA) {
402	ef->pltrela = (const Elf_Rela *) ef->pltrel;
403	ef->pltrel = NULL;
404	ef->pltrelasize = ef->pltrelsize;
405	ef->pltrelsize = 0;
406    }
407
408    ef->ddbsymtab = ef->symtab;
409    ef->ddbsymcnt = ef->nchains;
410    ef->ddbstrtab = ef->strtab;
411    ef->ddbstrcnt = ef->strsz;
412
413    return 0;
414}
415
416static int
417link_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
467static int
468link_elf_link_preload_finish(linker_file_t lf)
469{
470    elf_file_t		ef;
471    int error;
472#ifdef DDB
473    char *newfilename;
474#endif
475
476    ef = (elf_file_t) lf;
477#if 0	/* this will be more trouble than it's worth for now */
478    for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
479	if (dp->d_tag != DT_NEEDED)
480	    continue;
481	modname = ef->strtab + dp->d_un.d_val;
482	error = linker_load_module(modname, lf);
483	if (error)
484	    goto out;
485    }
486#endif
487    error = relocate_file(ef);
488    if (error)
489	return error;
490    (void)link_elf_preload_parse_symbols(ef);
491
492#ifdef DDB
493    GDB_STATE(RT_ADD);
494    ef->gdb.l_addr = lf->address;
495    newfilename = malloc(strlen(lf->filename) + 1, M_LINKER, M_WAITOK);
496    strcpy(newfilename, lf->filename);
497    ef->gdb.l_name = newfilename;
498    ef->gdb.l_ld = ef->dynamic;
499    link_elf_add_gdb(&ef->gdb);
500    GDB_STATE(RT_CONSISTENT);
501#endif
502
503    return (0);
504}
505
506static int
507link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* result)
508{
509    struct nameidata nd;
510    struct thread* td = curthread;	/* XXX */
511    Elf_Ehdr *hdr;
512    caddr_t firstpage;
513    int nbytes, i;
514    Elf_Phdr *phdr;
515    Elf_Phdr *phlimit;
516    Elf_Phdr *segs[2];
517    int nsegs;
518    Elf_Phdr *phdyn;
519    Elf_Phdr *phphdr;
520    caddr_t mapbase;
521    size_t mapsize;
522    Elf_Off base_offset;
523    Elf_Addr base_vaddr;
524    Elf_Addr base_vlimit;
525    int error = 0;
526    int resid, flags;
527    elf_file_t ef;
528    linker_file_t lf;
529    Elf_Shdr *shdr;
530    int symtabindex;
531    int symstrindex;
532    int symcnt;
533    int strcnt;
534#ifdef DDB
535    char *newfilename;
536#endif
537
538    GIANT_REQUIRED;
539
540    shdr = NULL;
541    lf = NULL;
542
543    NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
544    flags = FREAD;
545    error = vn_open(&nd, &flags, 0);
546    if (error)
547	return error;
548    NDFREE(&nd, NDF_ONLY_PNBUF);
549
550    /*
551     * Read the elf header from the file.
552     */
553    firstpage = malloc(PAGE_SIZE, M_LINKER, M_WAITOK);
554    if (firstpage == NULL) {
555	error = ENOMEM;
556	goto out;
557    }
558    hdr = (Elf_Ehdr *)firstpage;
559    error = vn_rdwr(UIO_READ, nd.ni_vp, firstpage, PAGE_SIZE, 0,
560		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
561		    &resid, td);
562    nbytes = PAGE_SIZE - resid;
563    if (error)
564	goto out;
565
566    if (!IS_ELF(*hdr)) {
567	error = ENOEXEC;
568	goto out;
569    }
570
571    if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS
572      || hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
573	link_elf_error("Unsupported file layout");
574	error = ENOEXEC;
575	goto out;
576    }
577    if (hdr->e_ident[EI_VERSION] != EV_CURRENT
578      || hdr->e_version != EV_CURRENT) {
579	link_elf_error("Unsupported file version");
580	error = ENOEXEC;
581	goto out;
582    }
583    if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
584	link_elf_error("Unsupported file type");
585	error = ENOEXEC;
586	goto out;
587    }
588    if (hdr->e_machine != ELF_TARG_MACH) {
589	link_elf_error("Unsupported machine");
590	error = ENOEXEC;
591	goto out;
592    }
593
594    /*
595     * We rely on the program header being in the first page.  This is
596     * not strictly required by the ABI specification, but it seems to
597     * always true in practice.  And, it simplifies things considerably.
598     */
599    if (!((hdr->e_phentsize == sizeof(Elf_Phdr)) &&
600	  (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= PAGE_SIZE) &&
601	  (hdr->e_phoff + hdr->e_phnum*sizeof(Elf_Phdr) <= nbytes)))
602	link_elf_error("Unreadable program headers");
603
604    /*
605     * Scan the program header entries, and save key information.
606     *
607     * We rely on there being exactly two load segments, text and data,
608     * in that order.
609     */
610    phdr = (Elf_Phdr *) (firstpage + hdr->e_phoff);
611    phlimit = phdr + hdr->e_phnum;
612    nsegs = 0;
613    phdyn = NULL;
614    phphdr = NULL;
615    while (phdr < phlimit) {
616	switch (phdr->p_type) {
617
618	case PT_LOAD:
619	    if (nsegs == 2) {
620		link_elf_error("Too many sections");
621		error = ENOEXEC;
622		goto out;
623	    }
624	    segs[nsegs] = phdr;
625	    ++nsegs;
626	    break;
627
628	case PT_PHDR:
629	    phphdr = phdr;
630	    break;
631
632	case PT_DYNAMIC:
633	    phdyn = phdr;
634	    break;
635
636	case PT_INTERP:
637	    link_elf_error("Unsupported file type");
638	    error = ENOEXEC;
639	    goto out;
640	}
641
642	++phdr;
643    }
644    if (phdyn == NULL) {
645	link_elf_error("Object is not dynamically-linked");
646	error = ENOEXEC;
647	goto out;
648    }
649
650    /*
651     * Allocate the entire address space of the object, to stake out our
652     * contiguous region, and to establish the base address for relocation.
653     */
654    base_offset = trunc_page(segs[0]->p_offset);
655    base_vaddr = trunc_page(segs[0]->p_vaddr);
656    base_vlimit = round_page(segs[1]->p_vaddr + segs[1]->p_memsz);
657    mapsize = base_vlimit - base_vaddr;
658
659    lf = linker_make_file(filename, &link_elf_class);
660    if (!lf) {
661	error = ENOMEM;
662	goto out;
663    }
664
665    ef = (elf_file_t) lf;
666#ifdef SPARSE_MAPPING
667    ef->object = vm_object_allocate(OBJT_DEFAULT, mapsize >> PAGE_SHIFT);
668    if (ef->object == NULL) {
669	error = ENOMEM;
670	goto out;
671    }
672    vm_object_reference(ef->object);
673    ef->address = (caddr_t) vm_map_min(kernel_map);
674    error = vm_map_find(kernel_map, ef->object, 0,
675			(vm_offset_t *) &ef->address,
676			mapsize, 1,
677			VM_PROT_ALL, VM_PROT_ALL, 0);
678    if (error) {
679	vm_object_deallocate(ef->object);
680	ef->object = 0;
681	goto out;
682    }
683#else
684    ef->address = malloc(mapsize, M_LINKER, M_WAITOK);
685    if (!ef->address) {
686	error = ENOMEM;
687	goto out;
688    }
689#endif
690    mapbase = ef->address;
691
692    /*
693     * Read the text and data sections and zero the bss.
694     */
695    for (i = 0; i < 2; i++) {
696	caddr_t segbase = mapbase + segs[i]->p_vaddr - base_vaddr;
697	error = vn_rdwr(UIO_READ, nd.ni_vp,
698			segbase, segs[i]->p_filesz, segs[i]->p_offset,
699			UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
700			&resid, td);
701	if (error) {
702	    goto out;
703	}
704	bzero(segbase + segs[i]->p_filesz,
705	      segs[i]->p_memsz - segs[i]->p_filesz);
706
707#ifdef SPARSE_MAPPING
708	/*
709	 * Wire down the pages
710	 */
711	vm_map_wire(kernel_map,
712		    (vm_offset_t) segbase,
713		    (vm_offset_t) segbase + segs[i]->p_memsz,
714		    FALSE);
715#endif
716    }
717
718#ifdef GPROF
719    /* Update profiling information with the new text segment. */
720    kmupetext((uintfptr_t)(mapbase + segs[0]->p_vaddr - base_vaddr +
721	segs[0]->p_memsz));
722#endif
723
724    ef->dynamic = (Elf_Dyn *) (mapbase + phdyn->p_vaddr - base_vaddr);
725
726    lf->address = ef->address;
727    lf->size = mapsize;
728
729    error = parse_dynamic(ef);
730    if (error)
731	goto out;
732    error = linker_load_dependencies(lf);
733    if (error)
734	goto out;
735#if 0	/* this will be more trouble than it's worth for now */
736    for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) {
737	if (dp->d_tag != DT_NEEDED)
738	    continue;
739	modname = ef->strtab + dp->d_un.d_val;
740	error = linker_load_module(modname, lf);
741	if (error)
742	    goto out;
743    }
744#endif
745    error = relocate_file(ef);
746    if (error)
747	goto out;
748
749    /* Try and load the symbol table if it's present.  (you can strip it!) */
750    nbytes = hdr->e_shnum * hdr->e_shentsize;
751    if (nbytes == 0 || hdr->e_shoff == 0)
752	goto nosyms;
753    shdr = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO);
754    if (shdr == NULL) {
755	error = ENOMEM;
756	goto out;
757    }
758    error = vn_rdwr(UIO_READ, nd.ni_vp,
759		    (caddr_t)shdr, nbytes, hdr->e_shoff,
760		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
761		    &resid, td);
762    if (error)
763	goto out;
764    symtabindex = -1;
765    symstrindex = -1;
766    for (i = 0; i < hdr->e_shnum; i++) {
767	if (shdr[i].sh_type == SHT_SYMTAB) {
768	    symtabindex = i;
769	    symstrindex = shdr[i].sh_link;
770	}
771    }
772    if (symtabindex < 0 || symstrindex < 0)
773	goto nosyms;
774
775    symcnt = shdr[symtabindex].sh_size;
776    ef->symbase = malloc(symcnt, M_LINKER, M_WAITOK);
777    strcnt = shdr[symstrindex].sh_size;
778    ef->strbase = malloc(strcnt, M_LINKER, M_WAITOK);
779
780    if (ef->symbase == NULL || ef->strbase == NULL) {
781	error = ENOMEM;
782	goto out;
783    }
784    error = vn_rdwr(UIO_READ, nd.ni_vp,
785		    ef->symbase, symcnt, shdr[symtabindex].sh_offset,
786		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
787		    &resid, td);
788    if (error)
789	goto out;
790    error = vn_rdwr(UIO_READ, nd.ni_vp,
791		    ef->strbase, strcnt, shdr[symstrindex].sh_offset,
792		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
793		    &resid, td);
794    if (error)
795	goto out;
796
797    ef->ddbsymcnt = symcnt / sizeof(Elf_Sym);
798    ef->ddbsymtab = (const Elf_Sym *)ef->symbase;
799    ef->ddbstrcnt = strcnt;
800    ef->ddbstrtab = ef->strbase;
801
802#ifdef DDB
803    GDB_STATE(RT_ADD);
804    ef->gdb.l_addr = lf->address;
805    newfilename = malloc(strlen(filename) + 1, M_LINKER, M_WAITOK);
806    strcpy(newfilename, filename);
807    ef->gdb.l_name = (const char *)newfilename;
808    ef->gdb.l_ld = ef->dynamic;
809    link_elf_add_gdb(&ef->gdb);
810    GDB_STATE(RT_CONSISTENT);
811#endif
812
813nosyms:
814
815    *result = lf;
816
817out:
818    if (error && lf)
819	linker_file_unload(lf);
820    if (shdr)
821	free(shdr, M_LINKER);
822    if (firstpage)
823	free(firstpage, M_LINKER);
824    VOP_UNLOCK(nd.ni_vp, 0, td);
825    vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
826
827    return error;
828}
829
830static void
831link_elf_unload_file(linker_file_t file)
832{
833    elf_file_t ef = (elf_file_t) file;
834
835#ifdef DDB
836    if (ef->gdb.l_ld) {
837	GDB_STATE(RT_DELETE);
838	free((void *)(uintptr_t)ef->gdb.l_name, M_LINKER);
839	link_elf_delete_gdb(&ef->gdb);
840	GDB_STATE(RT_CONSISTENT);
841    }
842#endif
843
844    if (ef->preloaded) {
845	link_elf_unload_preload(file);
846	return;
847    }
848#ifdef SPARSE_MAPPING
849    if (ef->object) {
850	vm_map_remove(kernel_map, (vm_offset_t) ef->address,
851		      (vm_offset_t) ef->address
852		      + (ef->object->size << PAGE_SHIFT));
853	vm_object_deallocate(ef->object);
854    }
855#else
856    if (ef->address)
857	free(ef->address, M_LINKER);
858#endif
859    if (ef->symbase)
860	free(ef->symbase, M_LINKER);
861    if (ef->strbase)
862	free(ef->strbase, M_LINKER);
863}
864
865static void
866link_elf_unload_preload(linker_file_t file)
867{
868    if (file->filename)
869	preload_delete_name(file->filename);
870}
871
872static const char *
873symbol_name(elf_file_t ef, Elf_Word r_info)
874{
875    const Elf_Sym *ref;
876
877    if (ELF_R_SYM(r_info)) {
878	ref = ef->symtab + ELF_R_SYM(r_info);
879	return ef->strtab + ref->st_name;
880    } else
881	return NULL;
882}
883
884static int
885relocate_file(elf_file_t ef)
886{
887    const Elf_Rel *rellim;
888    const Elf_Rel *rel;
889    const Elf_Rela *relalim;
890    const Elf_Rela *rela;
891    const char *symname;
892
893    /* Perform relocations without addend if there are any: */
894    rel = ef->rel;
895    if (rel) {
896	rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize);
897	while (rel < rellim) {
898	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
899		symname = symbol_name(ef, rel->r_info);
900		printf("link_elf: symbol %s undefined\n", symname);
901		return ENOENT;
902	    }
903	    rel++;
904	}
905    }
906
907    /* Perform relocations with addend if there are any: */
908    rela = ef->rela;
909    if (rela) {
910	relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize);
911	while (rela < relalim) {
912	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
913		symname = symbol_name(ef, rela->r_info);
914		printf("link_elf: symbol %s undefined\n", symname);
915		return ENOENT;
916	    }
917	    rela++;
918	}
919    }
920
921    /* Perform PLT relocations without addend if there are any: */
922    rel = ef->pltrel;
923    if (rel) {
924	rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize);
925	while (rel < rellim) {
926	    if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) {
927		symname = symbol_name(ef, rel->r_info);
928		printf("link_elf: symbol %s undefined\n", symname);
929		return ENOENT;
930	    }
931	    rel++;
932	}
933    }
934
935    /* Perform relocations with addend if there are any: */
936    rela = ef->pltrela;
937    if (rela) {
938	relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize);
939	while (rela < relalim) {
940	    if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) {
941		symname = symbol_name(ef, rela->r_info);
942		printf("link_elf: symbol %s undefined\n", symname);
943		return ENOENT;
944	    }
945	    rela++;
946	}
947    }
948
949    return 0;
950}
951
952/*
953 * Hash function for symbol table lookup.  Don't even think about changing
954 * this.  It is specified by the System V ABI.
955 */
956static unsigned long
957elf_hash(const char *name)
958{
959    const unsigned char *p = (const unsigned char *) name;
960    unsigned long h = 0;
961    unsigned long g;
962
963    while (*p != '\0') {
964	h = (h << 4) + *p++;
965	if ((g = h & 0xf0000000) != 0)
966	    h ^= g >> 24;
967	h &= ~g;
968    }
969    return h;
970}
971
972static int
973link_elf_lookup_symbol(linker_file_t lf, const char* name, c_linker_sym_t* sym)
974{
975    elf_file_t ef = (elf_file_t) lf;
976    unsigned long symnum;
977    const Elf_Sym* symp;
978    const char *strp;
979    unsigned long hash;
980    int i;
981
982    /* First, search hashed global symbols */
983    hash = elf_hash(name);
984    symnum = ef->buckets[hash % ef->nbuckets];
985
986    while (symnum != STN_UNDEF) {
987	if (symnum >= ef->nchains) {
988	    printf("link_elf_lookup_symbol: corrupt symbol table\n");
989	    return ENOENT;
990	}
991
992	symp = ef->symtab + symnum;
993	if (symp->st_name == 0) {
994	    printf("link_elf_lookup_symbol: corrupt symbol table\n");
995	    return ENOENT;
996	}
997
998	strp = ef->strtab + symp->st_name;
999
1000	if (strcmp(name, strp) == 0) {
1001	    if (symp->st_shndx != SHN_UNDEF ||
1002		(symp->st_value != 0 &&
1003		 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
1004		*sym = (c_linker_sym_t) symp;
1005		return 0;
1006	    } else
1007		return ENOENT;
1008	}
1009
1010	symnum = ef->chains[symnum];
1011    }
1012
1013    /* If we have not found it, look at the full table (if loaded) */
1014    if (ef->symtab == ef->ddbsymtab)
1015	return ENOENT;
1016
1017    /* Exhaustive search */
1018    for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1019	strp = ef->ddbstrtab + symp->st_name;
1020	if (strcmp(name, strp) == 0) {
1021	    if (symp->st_shndx != SHN_UNDEF ||
1022		(symp->st_value != 0 &&
1023		 ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
1024		*sym = (c_linker_sym_t) symp;
1025		return 0;
1026	    } else
1027		return ENOENT;
1028	}
1029    }
1030
1031    return ENOENT;
1032}
1033
1034static int
1035link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t* symval)
1036{
1037	elf_file_t ef = (elf_file_t) lf;
1038	const Elf_Sym* es = (const Elf_Sym*) sym;
1039
1040	if (es >= ef->symtab && es < (ef->symtab + ef->nchains)) {
1041	    symval->name = ef->strtab + es->st_name;
1042	    symval->value = (caddr_t) ef->address + es->st_value;
1043	    symval->size = es->st_size;
1044	    return 0;
1045	}
1046	if (ef->symtab == ef->ddbsymtab)
1047	    return ENOENT;
1048	if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
1049	    symval->name = ef->ddbstrtab + es->st_name;
1050	    symval->value = (caddr_t) ef->address + es->st_value;
1051	    symval->size = es->st_size;
1052	    return 0;
1053	}
1054	return ENOENT;
1055}
1056
1057static int
1058link_elf_search_symbol(linker_file_t lf, caddr_t value,
1059		       c_linker_sym_t* sym, long* diffp)
1060{
1061	elf_file_t ef = (elf_file_t) lf;
1062	u_long off = (uintptr_t) (void *) value;
1063	u_long diff = off;
1064	u_long st_value;
1065	const Elf_Sym* es;
1066	const Elf_Sym* best = 0;
1067	int i;
1068
1069	for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) {
1070		if (es->st_name == 0)
1071			continue;
1072		st_value = es->st_value + (uintptr_t) (void *) ef->address;
1073		if (off >= st_value) {
1074			if (off - st_value < diff) {
1075				diff = off - st_value;
1076				best = es;
1077				if (diff == 0)
1078					break;
1079			} else if (off - st_value == diff) {
1080				best = es;
1081			}
1082		}
1083	}
1084	if (best == 0)
1085		*diffp = off;
1086	else
1087		*diffp = diff;
1088	*sym = (c_linker_sym_t) best;
1089
1090	return 0;
1091}
1092
1093/*
1094 * Look up a linker set on an ELF system.
1095 */
1096static int
1097link_elf_lookup_set(linker_file_t lf, const char *name,
1098		    void ***startp, void ***stopp, int *countp)
1099{
1100	c_linker_sym_t sym;
1101	linker_symval_t symval;
1102	char *setsym;
1103	void **start, **stop;
1104	int len, error = 0, count;
1105
1106	len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */
1107	setsym = malloc(len, M_LINKER, M_WAITOK);
1108	if (setsym == NULL)
1109		return ENOMEM;
1110
1111	/* get address of first entry */
1112	snprintf(setsym, len, "%s%s", "__start_set_", name);
1113	error = link_elf_lookup_symbol(lf, setsym, &sym);
1114	if (error)
1115		goto out;
1116	link_elf_symbol_values(lf, sym, &symval);
1117	if (symval.value == 0) {
1118		error = ESRCH;
1119		goto out;
1120	}
1121	start = (void **)symval.value;
1122
1123	/* get address of last entry */
1124	snprintf(setsym, len, "%s%s", "__stop_set_", name);
1125	error = link_elf_lookup_symbol(lf, setsym, &sym);
1126	if (error)
1127		goto out;
1128	link_elf_symbol_values(lf, sym, &symval);
1129	if (symval.value == 0) {
1130		error = ESRCH;
1131		goto out;
1132	}
1133	stop = (void **)symval.value;
1134
1135	/* and the number of entries */
1136	count = stop - start;
1137
1138	/* and copy out */
1139	if (startp)
1140		*startp = start;
1141	if (stopp)
1142		*stopp = stop;
1143	if (countp)
1144		*countp = count;
1145
1146out:
1147	free(setsym, M_LINKER);
1148	return error;
1149}
1150
1151static int
1152link_elf_each_function_name(linker_file_t file,
1153  int (*callback)(const char *, void *), void *opaque) {
1154    elf_file_t ef = (elf_file_t)file;
1155    const Elf_Sym* symp;
1156    int i, error;
1157
1158    /* Exhaustive search */
1159    for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
1160	if (symp->st_value != 0 &&
1161	    ELF_ST_TYPE(symp->st_info) == STT_FUNC) {
1162		error = callback(ef->ddbstrtab + symp->st_name, opaque);
1163		if (error)
1164		    return (error);
1165	}
1166    }
1167    return (0);
1168}
1169
1170#ifdef __ia64__
1171/*
1172 * Each KLD has its own GP. The GP value for each load module is given by
1173 * DT_PLTGOT on ia64. We need GP to construct function descriptors, but
1174 * don't have direct access to the ELF file structure. The link_elf_get_gp()
1175 * function returns the GP given a pointer to a generic linker file struct.
1176 */
1177Elf_Addr
1178link_elf_get_gp(linker_file_t lf)
1179{
1180	elf_file_t ef = (elf_file_t)lf;
1181	return (Elf_Addr)ef->got;
1182}
1183#endif
1184
1185const Elf_Sym *
1186elf_get_sym(linker_file_t lf, Elf_Word symidx)
1187{
1188	elf_file_t ef = (elf_file_t)lf;
1189
1190	if (symidx >= ef->nchains)
1191		return (NULL);
1192	return (ef->symtab + symidx);
1193}
1194
1195const char *
1196elf_get_symname(linker_file_t lf, Elf_Word symidx)
1197{
1198	elf_file_t ef = (elf_file_t)lf;
1199	const Elf_Sym *sym;
1200
1201	if (symidx >= ef->nchains)
1202		return (NULL);
1203	sym = ef->symtab + symidx;
1204	return (ef->strtab + sym->st_name);
1205}
1206
1207/*
1208 * Symbol lookup function that can be used when the symbol index is known (ie
1209 * in relocations). It uses the symbol index instead of doing a fully fledged
1210 * hash table based lookup when such is valid. For example for local symbols.
1211 * This is not only more efficient, it's also more correct. It's not always
1212 * the case that the symbol can be found through the hash table.
1213 */
1214Elf_Addr
1215elf_lookup(linker_file_t lf, Elf_Word symidx, int deps)
1216{
1217	elf_file_t ef = (elf_file_t)lf;
1218	const Elf_Sym *sym;
1219	const char *symbol;
1220
1221	/* Don't even try to lookup the symbol if the index is bogus. */
1222	if (symidx >= ef->nchains)
1223		return (0);
1224
1225	sym = ef->symtab + symidx;
1226
1227	/*
1228	 * Don't do a full lookup when the symbol is local. It may even
1229	 * fail because it may not be found through the hash table.
1230	 */
1231	if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
1232		/* Force lookup failure when we have an insanity. */
1233		if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0)
1234			return (0);
1235		return ((Elf_Addr)ef->address + sym->st_value);
1236	}
1237
1238	/*
1239	 * XXX we can avoid doing a hash table based lookup for global
1240	 * symbols as well. This however is not always valid, so we'll
1241	 * just do it the hard way for now. Performance tweaks can
1242	 * always be added.
1243	 */
1244
1245	symbol = ef->strtab + sym->st_name;
1246
1247	/* Force a lookup failure if the symbol name is bogus. */
1248	if (*symbol == 0)
1249		return (0);
1250
1251	return ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
1252}
1253