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 * 26a2c99e3eSDoug Rabson * $Id: linker.h,v 1.3 1998/01/01 08:55:37 bde Exp $ 27cea6c86cSDoug Rabson */ 28cea6c86cSDoug Rabson 29cea6c86cSDoug Rabson #ifndef _SYS_LINKER_H_ 30cea6c86cSDoug Rabson #define _SYS_LINKER_H_ 31cea6c86cSDoug Rabson 32cea6c86cSDoug Rabson #ifdef KERNEL 33cea6c86cSDoug Rabson 34452ed6dcSBruce Evans #ifdef MALLOC_DECLARE 35452ed6dcSBruce Evans MALLOC_DECLARE(M_LINKER); 36452ed6dcSBruce Evans #endif 37cea6c86cSDoug Rabson 38cea6c86cSDoug Rabson /* 39cea6c86cSDoug Rabson * Object representing a file which has been loaded by the linker. 40cea6c86cSDoug Rabson */ 41cea6c86cSDoug Rabson typedef struct linker_file* linker_file_t; 42cea6c86cSDoug Rabson typedef TAILQ_HEAD(, linker_file) linker_file_list_t; 43cea6c86cSDoug Rabson 44a2c99e3eSDoug Rabson typedef caddr_t linker_sym_t; /* opaque symbol */ 45a2c99e3eSDoug Rabson 46a2c99e3eSDoug Rabson /* 47a2c99e3eSDoug Rabson * expanded out linker_sym_t 48a2c99e3eSDoug Rabson */ 49a2c99e3eSDoug Rabson typedef struct linker_symval { 50a2c99e3eSDoug Rabson const char* name; 51a2c99e3eSDoug Rabson caddr_t value; 52a2c99e3eSDoug Rabson size_t size; 53a2c99e3eSDoug Rabson } linker_symval_t; 54a2c99e3eSDoug Rabson 55cea6c86cSDoug Rabson struct linker_file_ops { 56cea6c86cSDoug Rabson /* 57cea6c86cSDoug Rabson * Lookup a symbol in the file's symbol table. If the symbol is 58cea6c86cSDoug Rabson * not found then return ENOENT, otherwise zero. If the symbol 59cea6c86cSDoug Rabson * found is a common symbol, return with *address set to zero and 60cea6c86cSDoug Rabson * *size set to the size of the common space required. Otherwise 61cea6c86cSDoug Rabson * set *address the value of the symbol. 62cea6c86cSDoug Rabson */ 63cea6c86cSDoug Rabson int (*lookup_symbol)(linker_file_t, const char* name, 64a2c99e3eSDoug Rabson linker_sym_t* sym); 65a2c99e3eSDoug Rabson 66a2c99e3eSDoug Rabson void (*symbol_values)(linker_file_t, linker_sym_t, 67a2c99e3eSDoug Rabson linker_symval_t*); 68a2c99e3eSDoug Rabson 69a2c99e3eSDoug Rabson int (*search_symbol)(linker_file_t, caddr_t value, 70a2c99e3eSDoug Rabson linker_sym_t* sym, long* diffp); 71cea6c86cSDoug Rabson 72cea6c86cSDoug Rabson /* 73cea6c86cSDoug Rabson * Unload a file, releasing dependancies and freeing storage. 74cea6c86cSDoug Rabson */ 75cea6c86cSDoug Rabson void (*unload)(linker_file_t); 76cea6c86cSDoug Rabson }; 77cea6c86cSDoug Rabson 78cea6c86cSDoug Rabson struct common_symbol { 79cea6c86cSDoug Rabson STAILQ_ENTRY(common_symbol) link; 80cea6c86cSDoug Rabson char* name; 81cea6c86cSDoug Rabson caddr_t address; 82cea6c86cSDoug Rabson }; 83cea6c86cSDoug Rabson 84cea6c86cSDoug Rabson struct linker_file { 85cea6c86cSDoug Rabson int refs; /* reference count */ 86cea6c86cSDoug Rabson int userrefs; /* modload(2) count */ 87cea6c86cSDoug Rabson TAILQ_ENTRY(linker_file) link; /* list of all loaded files */ 88cea6c86cSDoug Rabson char* filename; /* file which was loaded */ 89cea6c86cSDoug Rabson int id; /* unique id */ 90cea6c86cSDoug Rabson caddr_t address; /* load address */ 91cea6c86cSDoug Rabson size_t size; /* size of file */ 92cea6c86cSDoug Rabson int ndeps; /* number of dependancies */ 93cea6c86cSDoug Rabson linker_file_t* deps; /* list of dependancies */ 94cea6c86cSDoug Rabson STAILQ_HEAD(, common_symbol) common; /* list of common symbols */ 95cea6c86cSDoug Rabson TAILQ_HEAD(, module) modules; /* modules in this file */ 96cea6c86cSDoug Rabson void* priv; /* implementation data */ 97cea6c86cSDoug Rabson 98cea6c86cSDoug Rabson struct linker_file_ops* ops; 99cea6c86cSDoug Rabson }; 100cea6c86cSDoug Rabson 101cea6c86cSDoug Rabson /* 102cea6c86cSDoug Rabson * Object implementing a class of file (a.out, elf, etc.) 103cea6c86cSDoug Rabson */ 104cea6c86cSDoug Rabson typedef struct linker_class *linker_class_t; 105cea6c86cSDoug Rabson typedef TAILQ_HEAD(, linker_class) linker_class_list_t; 106cea6c86cSDoug Rabson 107cea6c86cSDoug Rabson struct linker_class_ops { 108cea6c86cSDoug Rabson /* 109cea6c86cSDoug Rabson * Load a file, returning the new linker_file_t in *result. If 110cea6c86cSDoug Rabson * the class does not recognise the file type, zero should be 111cea6c86cSDoug Rabson * returned, without modifying *result. If the file is 112cea6c86cSDoug Rabson * recognised, the file should be loaded, *result set to the new 113cea6c86cSDoug Rabson * file and zero returned. If some other error is detected an 114cea6c86cSDoug Rabson * appropriate errno should be returned. 115cea6c86cSDoug Rabson */ 116cea6c86cSDoug Rabson int (*load_file)(const char* filename, linker_file_t* result); 117cea6c86cSDoug Rabson }; 118cea6c86cSDoug Rabson 119cea6c86cSDoug Rabson struct linker_class { 120cea6c86cSDoug Rabson TAILQ_ENTRY(linker_class) link; /* list of all file classes */ 121cea6c86cSDoug Rabson const char* desc; /* description (e.g. "a.out") */ 122cea6c86cSDoug Rabson void* priv; /* implementation data */ 123cea6c86cSDoug Rabson 124cea6c86cSDoug Rabson struct linker_class_ops *ops; 125cea6c86cSDoug Rabson }; 126cea6c86cSDoug Rabson 127cea6c86cSDoug Rabson /* 128cea6c86cSDoug Rabson * The file which is currently loading. Used to register modules with 129cea6c86cSDoug Rabson * the files which contain them. 130cea6c86cSDoug Rabson */ 131d73424aaSBruce Evans extern linker_file_t linker_current_file; 132cea6c86cSDoug Rabson 133cea6c86cSDoug Rabson /* 134cea6c86cSDoug Rabson * Add a new file class to the linker. 135cea6c86cSDoug Rabson */ 136cea6c86cSDoug Rabson int linker_add_class(const char* desc, void* priv, 137cea6c86cSDoug Rabson struct linker_class_ops* ops); 138cea6c86cSDoug Rabson 139cea6c86cSDoug Rabson /* 140cea6c86cSDoug Rabson * Load a file, trying each file class until one succeeds. 141cea6c86cSDoug Rabson */ 142cea6c86cSDoug Rabson int linker_load_file(const char* filename, linker_file_t* result); 143cea6c86cSDoug Rabson 144cea6c86cSDoug Rabson /* 145cea6c86cSDoug Rabson * Find a currently loaded file given its filename. 146cea6c86cSDoug Rabson */ 147cea6c86cSDoug Rabson linker_file_t linker_find_file_by_name(const char* filename); 148cea6c86cSDoug Rabson 149cea6c86cSDoug Rabson /* 150cea6c86cSDoug Rabson * Find a currently loaded file given its file id. 151cea6c86cSDoug Rabson */ 152cea6c86cSDoug Rabson linker_file_t linker_find_file_by_id(int fileid); 153cea6c86cSDoug Rabson 154cea6c86cSDoug Rabson /* 155cea6c86cSDoug Rabson * Called from a class handler when a file is laoded. 156cea6c86cSDoug Rabson */ 157cea6c86cSDoug Rabson linker_file_t linker_make_file(const char* filename, void* priv, 158cea6c86cSDoug Rabson struct linker_file_ops* ops); 159cea6c86cSDoug Rabson 160cea6c86cSDoug Rabson /* 161cea6c86cSDoug Rabson * Unload a file, freeing up memory. 162cea6c86cSDoug Rabson */ 163cea6c86cSDoug Rabson int linker_file_unload(linker_file_t file); 164cea6c86cSDoug Rabson 165cea6c86cSDoug Rabson /* 166cea6c86cSDoug Rabson * Add a dependancy to a file. 167cea6c86cSDoug Rabson */ 168cea6c86cSDoug Rabson int linker_file_add_dependancy(linker_file_t file, linker_file_t dep); 169cea6c86cSDoug Rabson 170cea6c86cSDoug Rabson /* 171cea6c86cSDoug Rabson * Lookup a symbol in a file. If deps is TRUE, look in dependancies 172cea6c86cSDoug Rabson * if not found in file. 173cea6c86cSDoug Rabson */ 174cea6c86cSDoug Rabson caddr_t linker_file_lookup_symbol(linker_file_t file, const char* name, 175cea6c86cSDoug Rabson int deps); 176cea6c86cSDoug Rabson 177cea6c86cSDoug Rabson #ifdef KLD_DEBUG 178cea6c86cSDoug Rabson 179cea6c86cSDoug Rabson extern int kld_debug; 180cea6c86cSDoug Rabson #define KLD_DEBUG_FILE 1 /* file load/unload */ 181cea6c86cSDoug Rabson #define KLD_DEBUG_SYM 2 /* symbol lookup */ 182cea6c86cSDoug Rabson 183cea6c86cSDoug Rabson #define KLD_DPF(cat, args) \ 184cea6c86cSDoug Rabson do { \ 185cea6c86cSDoug Rabson if (KLD_debug & KLD_DEBUG_##cat) printf args; \ 186cea6c86cSDoug Rabson } while (0) 187cea6c86cSDoug Rabson 188cea6c86cSDoug Rabson #else 189cea6c86cSDoug Rabson 190cea6c86cSDoug Rabson #define KLD_DPF(cat, args) 191cea6c86cSDoug Rabson 192cea6c86cSDoug Rabson #endif 193cea6c86cSDoug Rabson 194cea6c86cSDoug Rabson #endif /* KERNEL */ 195cea6c86cSDoug Rabson 196cea6c86cSDoug Rabson struct kld_file_stat { 197cea6c86cSDoug Rabson int version; /* set to sizeof(linker_file_stat) */ 198cea6c86cSDoug Rabson char name[MAXPATHLEN]; 199cea6c86cSDoug Rabson int refs; 200cea6c86cSDoug Rabson int id; 201cea6c86cSDoug Rabson caddr_t address; /* load address */ 202cea6c86cSDoug Rabson size_t size; /* size in bytes */ 203cea6c86cSDoug Rabson }; 204cea6c86cSDoug Rabson 205cea6c86cSDoug Rabson #ifndef KERNEL 206cea6c86cSDoug Rabson 207cea6c86cSDoug Rabson #include <sys/cdefs.h> 208cea6c86cSDoug Rabson 209cea6c86cSDoug Rabson __BEGIN_DECLS 210cea6c86cSDoug Rabson int kldload(const char* file); 211cea6c86cSDoug Rabson int kldunload(int fileid); 212cea6c86cSDoug Rabson int kldfind(const char* file); 213cea6c86cSDoug Rabson int kldnext(int fileid); 214cea6c86cSDoug Rabson int kldstat(int fileid, struct kld_file_stat* stat); 215cea6c86cSDoug Rabson int kldfirstmod(int fileid); 216cea6c86cSDoug Rabson __END_DECLS 217cea6c86cSDoug Rabson 218cea6c86cSDoug Rabson #endif 219cea6c86cSDoug Rabson 220452ed6dcSBruce Evans #endif /* !_SYS_LINKER_H_ */ 221