linker.h revision 40906
1/*-
2 * Copyright (c) 1997 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 *	$Id: linker.h,v 1.9 1998/10/16 03:55:01 peter Exp $
27 */
28
29#ifndef _SYS_LINKER_H_
30#define _SYS_LINKER_H_
31
32#ifdef KERNEL
33
34#include <machine/elf.h>
35
36#ifdef MALLOC_DECLARE
37MALLOC_DECLARE(M_LINKER);
38#endif
39
40/*
41 * Object representing a file which has been loaded by the linker.
42 */
43typedef struct linker_file* linker_file_t;
44typedef TAILQ_HEAD(, linker_file) linker_file_list_t;
45
46typedef caddr_t linker_sym_t;	/* opaque symbol */
47
48/*
49 * expanded out linker_sym_t
50 */
51typedef struct linker_symval {
52    const char*		name;
53    caddr_t		value;
54    size_t		size;
55} linker_symval_t;
56
57struct linker_file_ops {
58    /*
59     * Lookup a symbol in the file's symbol table.  If the symbol is
60     * not found then return ENOENT, otherwise zero.  If the symbol
61     * found is a common symbol, return with *address set to zero and
62     * *size set to the size of the common space required.  Otherwise
63     * set *address the value of the symbol.
64     */
65    int			(*lookup_symbol)(linker_file_t, const char* name,
66					 linker_sym_t* sym);
67
68    int			(*symbol_values)(linker_file_t, linker_sym_t,
69					 linker_symval_t*);
70
71    int			(*search_symbol)(linker_file_t, caddr_t value,
72					 linker_sym_t* sym, long* diffp);
73
74    /*
75     * Unload a file, releasing dependancies and freeing storage.
76     */
77    void		(*unload)(linker_file_t);
78};
79
80struct common_symbol {
81    STAILQ_ENTRY(common_symbol) link;
82    char*		name;
83    caddr_t		address;
84};
85
86struct linker_file {
87    int			refs;		/* reference count */
88    int			userrefs;	/* kldload(2) count */
89    TAILQ_ENTRY(linker_file) link;	/* list of all loaded files */
90    char*		filename;	/* file which was loaded */
91    int			id;		/* unique id */
92    caddr_t		address;	/* load address */
93    size_t		size;		/* size of file */
94    int			ndeps;		/* number of dependancies */
95    linker_file_t*	deps;		/* list of dependancies */
96    STAILQ_HEAD(, common_symbol) common; /* list of common symbols */
97    TAILQ_HEAD(, module) modules;	/* modules in this file */
98    void*		priv;		/* implementation data */
99
100    struct linker_file_ops* ops;
101};
102
103/*
104 * Object implementing a class of file (a.out, elf, etc.)
105 */
106typedef struct linker_class *linker_class_t;
107typedef TAILQ_HEAD(, linker_class) linker_class_list_t;
108
109struct linker_class_ops {
110    /*
111     * Load a file, returning the new linker_file_t in *result.  If
112     * the class does not recognise the file type, zero should be
113     * returned, without modifying *result.  If the file is
114     * recognised, the file should be loaded, *result set to the new
115     * file and zero returned.  If some other error is detected an
116     * appropriate errno should be returned.
117     */
118    int		(*load_file)(const char* filename, linker_file_t* result);
119};
120
121struct linker_class {
122    TAILQ_ENTRY(linker_class) link;	/* list of all file classes */
123    const char*		desc;		/* description (e.g. "a.out") */
124    void*		priv;		/* implementation data */
125
126    struct linker_class_ops *ops;
127};
128
129/*
130 * The file which is currently loading.  Used to register modules with
131 * the files which contain them.
132 */
133extern linker_file_t	linker_current_file;
134
135/*
136 * The "file" for the kernel.
137 */
138extern linker_file_t	linker_kernel_file;
139
140/*
141 * Add a new file class to the linker.
142 */
143int linker_add_class(const char* desc, void* priv,
144		     struct linker_class_ops* ops);
145
146/*
147 * Load a file, trying each file class until one succeeds.
148 */
149int linker_load_file(const char* filename, linker_file_t* result);
150
151/*
152 * Find a currently loaded file given its filename.
153 */
154linker_file_t linker_find_file_by_name(const char* filename);
155
156/*
157 * Find a currently loaded file given its file id.
158 */
159linker_file_t linker_find_file_by_id(int fileid);
160
161/*
162 * Called from a class handler when a file is laoded.
163 */
164linker_file_t linker_make_file(const char* filename, void* priv,
165			       struct linker_file_ops* ops);
166
167/*
168 * Unload a file, freeing up memory.
169 */
170int linker_file_unload(linker_file_t file);
171
172/*
173 * Add a dependancy to a file.
174 */
175int linker_file_add_dependancy(linker_file_t file, linker_file_t dep);
176
177/*
178 * Lookup a symbol in a file.  If deps is TRUE, look in dependancies
179 * if not found in file.
180 */
181caddr_t linker_file_lookup_symbol(linker_file_t file, const char* name,
182				  int deps);
183
184/*
185 * Search the linker path for the module.  Return the full pathname in
186 * a malloc'ed buffer.
187 */
188char *linker_search_path(const char *filename);
189
190/*
191 * DDB Helpers, tuned specifically for ddb/db_kld.c
192 */
193int linker_ddb_lookup(char *symstr, linker_sym_t *sym);
194int linker_ddb_search_symbol(caddr_t value, linker_sym_t *sym, long *diffp);
195int linker_ddb_symbol_values(linker_sym_t sym, linker_symval_t *symval);
196
197
198#endif	/* KERNEL */
199
200/*
201 * Module information subtypes
202 */
203#define MODINFO_END		0x0000		/* End of list */
204#define MODINFO_NAME		0x0001		/* Name of module (string) */
205#define MODINFO_TYPE		0x0002		/* Type of module (string) */
206#define MODINFO_ADDR		0x0003		/* Loaded address */
207#define MODINFO_SIZE		0x0004		/* Size of module */
208#define MODINFO_EMPTY		0x0005		/* Has been deleted */
209#define MODINFO_METADATA	0x8000		/* Module-specfic */
210
211#define MODINFOMD_AOUTEXEC	0x0001		/* a.out exec header */
212#define MODINFOMD_ELFHDR	0x0002		/* ELF header */
213#define MODINFOMD_SSYM		0x0003		/* start of symbols */
214#define MODINFOMD_ESYM		0x0004		/* end of symbols */
215#define MODINFOMD_DYNAMIC	0x0005		/* _DYNAMIC pointer */
216#define MODINFOMD_NOCOPY	0x8000		/* don't copy this metadata to the kernel */
217
218#define MODINFOMD_DEPLIST	(0x4001 | MODINFOMD_NOCOPY)	/* depends on */
219
220#ifdef KERNEL
221
222/*
223 * Module lookup
224 */
225extern caddr_t		preload_metadata;
226extern caddr_t		preload_search_by_name(const char *name);
227extern caddr_t		preload_search_by_type(const char *type);
228extern caddr_t		preload_search_next_name(caddr_t base);
229extern caddr_t		preload_search_info(caddr_t mod, int inf);
230extern void		preload_delete_name(const char *name);
231extern void		preload_bootstrap_relocate(vm_offset_t offset);
232
233#ifdef KLD_DEBUG
234
235extern int kld_debug;
236#define KLD_DEBUG_FILE	1	/* file load/unload */
237#define KLD_DEBUG_SYM	2	/* symbol lookup */
238
239#define KLD_DPF(cat, args)					\
240	do {							\
241		if (kld_debug & KLD_DEBUG_##cat) printf args;	\
242	} while (0)
243
244#else
245
246#define KLD_DPF(cat, args)
247
248#endif
249
250/* Support functions */
251int	elf_reloc(linker_file_t lf, const void *rel, int type, const char *sym);
252/* values for type */
253#define ELF_RELOC_REL	1
254#define ELF_RELOC_RELA	2
255
256#endif /* KERNEL */
257
258struct kld_file_stat {
259    int		version;	/* set to sizeof(linker_file_stat) */
260    char        name[MAXPATHLEN];
261    int		refs;
262    int		id;
263    caddr_t	address;	/* load address */
264    size_t	size;		/* size in bytes */
265};
266
267#ifndef KERNEL
268
269#include <sys/cdefs.h>
270
271__BEGIN_DECLS
272int	kldload(const char* file);
273int	kldunload(int fileid);
274int	kldfind(const char* file);
275int	kldnext(int fileid);
276int	kldstat(int fileid, struct kld_file_stat* stat);
277int	kldfirstmod(int fileid);
278__END_DECLS
279
280#endif
281
282#endif /* !_SYS_LINKER_H_ */
283