1cea6c86cSDoug Rabson /*- 2cea6c86cSDoug Rabson * Copyright (c) 1997 Doug Rabson 3cea6c86cSDoug Rabson * All rights reserved. 4cea6c86cSDoug Rabson * 5cea6c86cSDoug Rabson * Redistribution and use in source and binary forms, with or without 6cea6c86cSDoug Rabson * modification, are permitted provided that the following conditions 7cea6c86cSDoug Rabson * are met: 8cea6c86cSDoug Rabson * 1. Redistributions of source code must retain the above copyright 9cea6c86cSDoug Rabson * notice, this list of conditions and the following disclaimer. 10cea6c86cSDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 11cea6c86cSDoug Rabson * notice, this list of conditions and the following disclaimer in the 12cea6c86cSDoug Rabson * documentation and/or other materials provided with the distribution. 13cea6c86cSDoug Rabson * 14cea6c86cSDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15cea6c86cSDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16cea6c86cSDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17cea6c86cSDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18cea6c86cSDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19cea6c86cSDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20cea6c86cSDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21cea6c86cSDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22cea6c86cSDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23cea6c86cSDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24cea6c86cSDoug Rabson * SUCH DAMAGE. 25cea6c86cSDoug Rabson * 26cea6c86cSDoug Rabson * $Id$ 27cea6c86cSDoug Rabson */ 28cea6c86cSDoug Rabson 29cea6c86cSDoug Rabson #ifndef _SYS_LINKER_H_ 30cea6c86cSDoug Rabson #define _SYS_LINKER_H_ 31cea6c86cSDoug Rabson 32cea6c86cSDoug Rabson #ifdef KERNEL 33cea6c86cSDoug Rabson 34cea6c86cSDoug Rabson #define M_LINKER M_TEMP /* XXX */ 35cea6c86cSDoug Rabson 36cea6c86cSDoug Rabson /* 37cea6c86cSDoug Rabson * Object representing a file which has been loaded by the linker. 38cea6c86cSDoug Rabson */ 39cea6c86cSDoug Rabson typedef struct linker_file* linker_file_t; 40cea6c86cSDoug Rabson typedef TAILQ_HEAD(, linker_file) linker_file_list_t; 41cea6c86cSDoug Rabson 42cea6c86cSDoug Rabson struct linker_file_ops { 43cea6c86cSDoug Rabson /* 44cea6c86cSDoug Rabson * Lookup a symbol in the file's symbol table. If the symbol is 45cea6c86cSDoug Rabson * not found then return ENOENT, otherwise zero. If the symbol 46cea6c86cSDoug Rabson * found is a common symbol, return with *address set to zero and 47cea6c86cSDoug Rabson * *size set to the size of the common space required. Otherwise 48cea6c86cSDoug Rabson * set *address the value of the symbol. 49cea6c86cSDoug Rabson */ 50cea6c86cSDoug Rabson int (*lookup_symbol)(linker_file_t, const char* name, 51cea6c86cSDoug Rabson caddr_t* address, size_t* size); 52cea6c86cSDoug Rabson 53cea6c86cSDoug Rabson /* 54cea6c86cSDoug Rabson * Unload a file, releasing dependancies and freeing storage. 55cea6c86cSDoug Rabson */ 56cea6c86cSDoug Rabson void (*unload)(linker_file_t); 57cea6c86cSDoug Rabson }; 58cea6c86cSDoug Rabson 59cea6c86cSDoug Rabson struct common_symbol { 60cea6c86cSDoug Rabson STAILQ_ENTRY(common_symbol) link; 61cea6c86cSDoug Rabson char* name; 62cea6c86cSDoug Rabson caddr_t address; 63cea6c86cSDoug Rabson }; 64cea6c86cSDoug Rabson 65cea6c86cSDoug Rabson struct linker_file { 66cea6c86cSDoug Rabson int refs; /* reference count */ 67cea6c86cSDoug Rabson int userrefs; /* modload(2) count */ 68cea6c86cSDoug Rabson TAILQ_ENTRY(linker_file) link; /* list of all loaded files */ 69cea6c86cSDoug Rabson char* filename; /* file which was loaded */ 70cea6c86cSDoug Rabson int id; /* unique id */ 71cea6c86cSDoug Rabson caddr_t address; /* load address */ 72cea6c86cSDoug Rabson size_t size; /* size of file */ 73cea6c86cSDoug Rabson int ndeps; /* number of dependancies */ 74cea6c86cSDoug Rabson linker_file_t* deps; /* list of dependancies */ 75cea6c86cSDoug Rabson STAILQ_HEAD(, common_symbol) common; /* list of common symbols */ 76cea6c86cSDoug Rabson TAILQ_HEAD(, module) modules; /* modules in this file */ 77cea6c86cSDoug Rabson void* priv; /* implementation data */ 78cea6c86cSDoug Rabson 79cea6c86cSDoug Rabson struct linker_file_ops* ops; 80cea6c86cSDoug Rabson }; 81cea6c86cSDoug Rabson 82cea6c86cSDoug Rabson /* 83cea6c86cSDoug Rabson * Object implementing a class of file (a.out, elf, etc.) 84cea6c86cSDoug Rabson */ 85cea6c86cSDoug Rabson typedef struct linker_class *linker_class_t; 86cea6c86cSDoug Rabson typedef TAILQ_HEAD(, linker_class) linker_class_list_t; 87cea6c86cSDoug Rabson 88cea6c86cSDoug Rabson struct linker_class_ops { 89cea6c86cSDoug Rabson /* 90cea6c86cSDoug Rabson * Load a file, returning the new linker_file_t in *result. If 91cea6c86cSDoug Rabson * the class does not recognise the file type, zero should be 92cea6c86cSDoug Rabson * returned, without modifying *result. If the file is 93cea6c86cSDoug Rabson * recognised, the file should be loaded, *result set to the new 94cea6c86cSDoug Rabson * file and zero returned. If some other error is detected an 95cea6c86cSDoug Rabson * appropriate errno should be returned. 96cea6c86cSDoug Rabson */ 97cea6c86cSDoug Rabson int (*load_file)(const char* filename, linker_file_t* result); 98cea6c86cSDoug Rabson }; 99cea6c86cSDoug Rabson 100cea6c86cSDoug Rabson struct linker_class { 101cea6c86cSDoug Rabson TAILQ_ENTRY(linker_class) link; /* list of all file classes */ 102cea6c86cSDoug Rabson const char* desc; /* description (e.g. "a.out") */ 103cea6c86cSDoug Rabson void* priv; /* implementation data */ 104cea6c86cSDoug Rabson 105cea6c86cSDoug Rabson struct linker_class_ops *ops; 106cea6c86cSDoug Rabson }; 107cea6c86cSDoug Rabson 108cea6c86cSDoug Rabson /* 109cea6c86cSDoug Rabson * The file representing the currently running kernel. This contains 110cea6c86cSDoug Rabson * the global symbol table. 111cea6c86cSDoug Rabson */ 112cea6c86cSDoug Rabson linker_file_t linker_kernel_file; 113cea6c86cSDoug Rabson 114cea6c86cSDoug Rabson /* 115cea6c86cSDoug Rabson * The file which is currently loading. Used to register modules with 116cea6c86cSDoug Rabson * the files which contain them. 117cea6c86cSDoug Rabson */ 118cea6c86cSDoug Rabson linker_file_t linker_current_file; 119cea6c86cSDoug Rabson 120cea6c86cSDoug Rabson /* 121cea6c86cSDoug Rabson * Add a new file class to the linker. 122cea6c86cSDoug Rabson */ 123cea6c86cSDoug Rabson int linker_add_class(const char* desc, void* priv, 124cea6c86cSDoug Rabson struct linker_class_ops* ops); 125cea6c86cSDoug Rabson 126cea6c86cSDoug Rabson /* 127cea6c86cSDoug Rabson * Load a file, trying each file class until one succeeds. 128cea6c86cSDoug Rabson */ 129cea6c86cSDoug Rabson int linker_load_file(const char* filename, linker_file_t* result); 130cea6c86cSDoug Rabson 131cea6c86cSDoug Rabson /* 132cea6c86cSDoug Rabson * Find a currently loaded file given its filename. 133cea6c86cSDoug Rabson */ 134cea6c86cSDoug Rabson linker_file_t linker_find_file_by_name(const char* filename); 135cea6c86cSDoug Rabson 136cea6c86cSDoug Rabson /* 137cea6c86cSDoug Rabson * Find a currently loaded file given its file id. 138cea6c86cSDoug Rabson */ 139cea6c86cSDoug Rabson linker_file_t linker_find_file_by_id(int fileid); 140cea6c86cSDoug Rabson 141cea6c86cSDoug Rabson /* 142cea6c86cSDoug Rabson * Called from a class handler when a file is laoded. 143cea6c86cSDoug Rabson */ 144cea6c86cSDoug Rabson linker_file_t linker_make_file(const char* filename, void* priv, 145cea6c86cSDoug Rabson struct linker_file_ops* ops); 146cea6c86cSDoug Rabson 147cea6c86cSDoug Rabson /* 148cea6c86cSDoug Rabson * Unload a file, freeing up memory. 149cea6c86cSDoug Rabson */ 150cea6c86cSDoug Rabson int linker_file_unload(linker_file_t file); 151cea6c86cSDoug Rabson 152cea6c86cSDoug Rabson /* 153cea6c86cSDoug Rabson * Add a dependancy to a file. 154cea6c86cSDoug Rabson */ 155cea6c86cSDoug Rabson int linker_file_add_dependancy(linker_file_t file, linker_file_t dep); 156cea6c86cSDoug Rabson 157cea6c86cSDoug Rabson /* 158cea6c86cSDoug Rabson * Lookup a symbol in a file. If deps is TRUE, look in dependancies 159cea6c86cSDoug Rabson * if not found in file. 160cea6c86cSDoug Rabson */ 161cea6c86cSDoug Rabson caddr_t linker_file_lookup_symbol(linker_file_t file, const char* name, 162cea6c86cSDoug Rabson int deps); 163cea6c86cSDoug Rabson 164cea6c86cSDoug Rabson #ifdef KLD_DEBUG 165cea6c86cSDoug Rabson 166cea6c86cSDoug Rabson extern int kld_debug; 167cea6c86cSDoug Rabson #define KLD_DEBUG_FILE 1 /* file load/unload */ 168cea6c86cSDoug Rabson #define KLD_DEBUG_SYM 2 /* symbol lookup */ 169cea6c86cSDoug Rabson 170cea6c86cSDoug Rabson #define KLD_DPF(cat, args) \ 171cea6c86cSDoug Rabson do { \ 172cea6c86cSDoug Rabson if (KLD_debug & KLD_DEBUG_##cat) printf args; \ 173cea6c86cSDoug Rabson } while (0) 174cea6c86cSDoug Rabson 175cea6c86cSDoug Rabson #else 176cea6c86cSDoug Rabson 177cea6c86cSDoug Rabson #define KLD_DPF(cat, args) 178cea6c86cSDoug Rabson 179cea6c86cSDoug Rabson #endif 180cea6c86cSDoug Rabson 181cea6c86cSDoug Rabson #endif /* KERNEL */ 182cea6c86cSDoug Rabson 183cea6c86cSDoug Rabson struct kld_file_stat { 184cea6c86cSDoug Rabson int version; /* set to sizeof(linker_file_stat) */ 185cea6c86cSDoug Rabson char name[MAXPATHLEN]; 186cea6c86cSDoug Rabson int refs; 187cea6c86cSDoug Rabson int id; 188cea6c86cSDoug Rabson caddr_t address; /* load address */ 189cea6c86cSDoug Rabson size_t size; /* size in bytes */ 190cea6c86cSDoug Rabson }; 191cea6c86cSDoug Rabson 192cea6c86cSDoug Rabson #ifndef KERNEL 193cea6c86cSDoug Rabson 194cea6c86cSDoug Rabson #include <sys/cdefs.h> 195cea6c86cSDoug Rabson 196cea6c86cSDoug Rabson __BEGIN_DECLS 197cea6c86cSDoug Rabson int kldload(const char* file); 198cea6c86cSDoug Rabson int kldunload(int fileid); 199cea6c86cSDoug Rabson int kldfind(const char* file); 200cea6c86cSDoug Rabson int kldnext(int fileid); 201cea6c86cSDoug Rabson int kldstat(int fileid, struct kld_file_stat* stat); 202cea6c86cSDoug Rabson int kldfirstmod(int fileid); 203cea6c86cSDoug Rabson __END_DECLS 204cea6c86cSDoug Rabson 205cea6c86cSDoug Rabson #endif 206cea6c86cSDoug Rabson 207cea6c86cSDoug Rabson #endif /* !_SYS_KLD_H_ */ 208