2 * Copyright (c) 1997-2000 Doug Rabson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
29 #ifndef _SYS_LINKER_H_
30 #define _SYS_LINKER_H_
34 #include <machine/elf.h>
38 MALLOC_DECLARE(M_LINKER
);
44 * Object representing a file which has been loaded by the linker.
46 typedef struct linker_file
* linker_file_t
;
47 typedef TAILQ_HEAD(, linker_file
) linker_file_list_t
;
49 typedef caddr_t linker_sym_t
; /* opaque symbol */
50 typedef c_caddr_t c_linker_sym_t
; /* const opaque symbol */
51 typedef int (*linker_function_name_callback_t
)(const char *, void *);
54 * expanded out linker_sym_t
56 typedef struct linker_symval
{
62 typedef int (*linker_function_nameval_callback_t
)(linker_file_t
, int, linker_symval_t
*, void *);
64 struct common_symbol
{
65 STAILQ_ENTRY(common_symbol
) link
;
72 int refs
; /* reference count */
73 int userrefs
; /* kldload(2) count */
75 #define LINKER_FILE_LINKED 0x1 /* file has been fully linked */
76 TAILQ_ENTRY(linker_file
) link
; /* list of all loaded files */
77 char* filename
; /* file which was loaded */
78 char* pathname
; /* file name with full path */
79 int id
; /* unique id */
80 caddr_t address
; /* load address */
81 size_t size
; /* size of file */
82 caddr_t ctors_addr
; /* address of .ctors */
83 size_t ctors_size
; /* size of .ctors */
84 int ndeps
; /* number of dependencies */
85 linker_file_t
* deps
; /* list of dependencies */
86 STAILQ_HEAD(, common_symbol
) common
; /* list of common symbols */
87 TAILQ_HEAD(, module
) modules
; /* modules in this file */
88 TAILQ_ENTRY(linker_file
) loaded
; /* preload dependency support */
89 int loadcnt
; /* load counter value */
92 * Function Boundary Tracing (FBT) or Statically Defined Tracing (SDT)
95 int nenabled
; /* number of enabled probes. */
96 int fbt_nentries
; /* number of fbt entries created. */
100 * Object implementing a class of file (a.out, elf, etc.)
102 typedef struct linker_class
*linker_class_t
;
103 typedef TAILQ_HEAD(, linker_class
) linker_class_list_t
;
105 struct linker_class
{
107 TAILQ_ENTRY(linker_class
) link
; /* list of all file classes */
111 * Function type used when iterating over the list of linker files.
113 typedef int linker_predicate_t(linker_file_t
, void *);
116 * The "file" for the kernel.
118 extern linker_file_t linker_kernel_file
;
121 * Obtain a reference to a module, loading it if required.
123 int linker_reference_module(const char* _modname
, struct mod_depend
*_verinfo
,
124 linker_file_t
* _result
);
127 * Release a reference to a module, unloading it if there are no more
128 * references. Note that one should either provide a module name and
129 * optional version info or a linker file, but not both.
131 int linker_release_module(const char *_modname
, struct mod_depend
*_verinfo
,
132 linker_file_t _file
);
135 * Iterate over all of the currently loaded linker files calling the
136 * predicate function while the function returns 0. Returns the value
137 * returned by the last predicate function.
139 int linker_file_foreach(linker_predicate_t
*_predicate
, void *_context
);
142 * Lookup a symbol in a file. If deps is TRUE, look in dependencies
143 * if not found in file.
145 caddr_t
linker_file_lookup_symbol(linker_file_t _file
, const char* _name
,
149 * Lookup a linker set in a file. Return pointers to the first entry,
150 * last + 1, and count of entries. Use: for (p = start; p < stop; p++) {}
151 * void *start is really: "struct yoursetmember ***start;"
153 int linker_file_lookup_set(linker_file_t _file
, const char *_name
,
154 void *_start
, void *_stop
, int *_count
);
157 * List all functions in a file.
159 int linker_file_function_listall(linker_file_t
,
160 linker_function_nameval_callback_t
, void *);
163 * Functions soley for use by the linker class handlers.
165 int linker_add_class(linker_class_t _cls
);
166 int linker_file_unload(linker_file_t _file
, int flags
);
167 int linker_load_dependencies(linker_file_t _lf
);
168 linker_file_t
linker_make_file(const char* _filename
, linker_class_t _cls
);
171 * DDB Helpers, tuned specifically for ddb/db_kld.c
173 int linker_ddb_lookup(const char *_symstr
, c_linker_sym_t
*_sym
);
174 int linker_ddb_search_symbol(caddr_t _value
, c_linker_sym_t
*_sym
,
176 int linker_ddb_symbol_values(c_linker_sym_t _sym
, linker_symval_t
*_symval
);
177 int linker_ddb_search_symbol_name(caddr_t value
, char *buf
, u_int buflen
,
181 * stack(9) helper for situations where kernel locking is required.
183 int linker_search_symbol_name(caddr_t value
, char *buf
, u_int buflen
,
188 void *linker_hwpmc_list_objects(void);
193 * Module information subtypes
195 #define MODINFO_END 0x0000 /* End of list */
196 #define MODINFO_NAME 0x0001 /* Name of module (string) */
197 #define MODINFO_TYPE 0x0002 /* Type of module (string) */
198 #define MODINFO_ADDR 0x0003 /* Loaded address */
199 #define MODINFO_SIZE 0x0004 /* Size of module */
200 #define MODINFO_EMPTY 0x0005 /* Has been deleted */
201 #define MODINFO_ARGS 0x0006 /* Parameters string */
202 #define MODINFO_METADATA 0x8000 /* Module-specfic */
204 #define MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */
205 #define MODINFOMD_ELFHDR 0x0002 /* ELF header */
206 #define MODINFOMD_SSYM 0x0003 /* start of symbols */
207 #define MODINFOMD_ESYM 0x0004 /* end of symbols */
208 #define MODINFOMD_DYNAMIC 0x0005 /* _DYNAMIC pointer */
209 /* These values are MD on these two platforms */
210 #if !defined(__sparc64__) && !defined(__powerpc__)
211 #define MODINFOMD_ENVP 0x0006 /* envp[] */
212 #define MODINFOMD_HOWTO 0x0007 /* boothowto */
213 #define MODINFOMD_KERNEND 0x0008 /* kernend */
215 #define MODINFOMD_SHDR 0x0009 /* section header table */
216 #define MODINFOMD_CTORS_ADDR 0x000a /* address of .ctors */
217 #define MODINFOMD_CTORS_SIZE 0x000b /* size of .ctors */
218 #define MODINFOMD_FW_HANDLE 0x000c /* Firmware dependent handle */
219 #define MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */
221 #define MODINFOMD_DEPLIST (0x4001 | MODINFOMD_NOCOPY) /* depends on */
224 #define MD_FETCH(mdp, info, type) ({ \
226 __p = (type *)preload_search_info((mdp), MODINFO_METADATA | (info)); \
231 #define LINKER_HINTS_VERSION 1 /* linker.hints file version */
232 #define LINKER_HINTS_MAX (1 << 20) /* Allow at most 1MB for linker.hints */
239 extern vm_offset_t preload_addr_relocate
;
240 extern caddr_t preload_metadata
;
242 extern void * preload_fetch_addr(caddr_t _mod
);
243 extern size_t preload_fetch_size(caddr_t _mod
);
244 extern caddr_t
preload_search_by_name(const char *_name
);
245 extern caddr_t
preload_search_by_type(const char *_type
);
246 extern caddr_t
preload_search_next_name(caddr_t _base
);
247 extern caddr_t
preload_search_info(caddr_t _mod
, int _inf
);
248 extern void preload_delete_name(const char *_name
);
249 extern void preload_bootstrap_relocate(vm_offset_t _offset
);
253 extern int kld_debug
;
254 #define KLD_DEBUG_FILE 1 /* file load/unload */
255 #define KLD_DEBUG_SYM 2 /* symbol lookup */
257 #define KLD_DPF(cat, args) \
259 if (kld_debug & KLD_DEBUG_##cat) printf args; \
264 #define KLD_DPF(cat, args)
268 typedef int elf_lookup_fn(linker_file_t
, Elf_Size
, int, Elf_Addr
*);
270 /* Support functions */
271 int elf_reloc(linker_file_t _lf
, Elf_Addr base
, const void *_rel
, int _type
, elf_lookup_fn _lu
);
272 int elf_reloc_local(linker_file_t _lf
, Elf_Addr base
, const void *_rel
, int _type
, elf_lookup_fn _lu
);
273 Elf_Addr
elf_relocaddr(linker_file_t _lf
, Elf_Addr addr
);
274 const Elf_Sym
*elf_get_sym(linker_file_t _lf
, Elf_Size _symidx
);
275 const char *elf_get_symname(linker_file_t _lf
, Elf_Size _symidx
);
277 typedef struct linker_ctf
{
278 const uint8_t *ctftab
; /* Decompressed CTF data. */
279 int ctfcnt
; /* Number of CTF data bytes. */
280 const Elf_Sym
*symtab
; /* Ptr to the symbol table. */
281 int nsym
; /* Number of symbols. */
282 const char *strtab
; /* Ptr to the string table. */
283 int strcnt
; /* Number of string bytes. */
284 uint32_t **ctfoffp
; /* Ptr to array of obj/fnc offsets. */
285 uint32_t **typoffp
; /* Ptr to array of type offsets. */
286 long *typlenp
; /* Ptr to number of type data entries. */
289 int linker_ctf_get(linker_file_t
, linker_ctf_t
*);
291 int elf_cpu_load_file(linker_file_t
);
292 int elf_cpu_unload_file(linker_file_t
);
294 /* values for type */
295 #define ELF_RELOC_REL 1
296 #define ELF_RELOC_RELA 2
299 * This is version 1 of the KLD file status structure. It is identified
300 * by its _size_ in the version field.
302 struct kld_file_stat_1
{
303 int version
; /* set to sizeof(struct kld_file_stat_1) */
304 char name
[MAXPATHLEN
];
307 caddr_t address
; /* load address */
308 size_t size
; /* size in bytes */
312 struct kld_file_stat
{
313 int version
; /* set to sizeof(struct kld_file_stat) */
314 char name
[MAXPATHLEN
];
317 caddr_t address
; /* load address */
318 size_t size
; /* size in bytes */
319 char pathname
[MAXPATHLEN
];
322 struct kld_sym_lookup
{
323 int version
; /* set to sizeof(struct kld_sym_lookup) */
324 char *symname
; /* Symbol name we are looking up */
328 #define KLDSYM_LOOKUP 1
331 * Flags for kldunloadf() and linker_file_unload()
333 #define LINKER_UNLOAD_NORMAL 0
334 #define LINKER_UNLOAD_FORCE 1
338 #include <sys/cdefs.h>
341 int kldload(const char* _file
);
342 int kldunload(int _fileid
);
343 int kldunloadf(int _fileid
, int flags
);
344 int kldfind(const char* _file
);
345 int kldnext(int _fileid
);
346 int kldstat(int _fileid
, struct kld_file_stat
* _stat
);
347 int kldfirstmod(int _fileid
);
348 int kldsym(int _fileid
, int _cmd
, void *_data
);
353 #endif /* !_SYS_LINKER_H_ */