1 /* $NetBSD: module.h,v 1.38 2015/06/22 16:35:13 matt Exp $ */ 2 3 /*- 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef _SYS_MODULE_H_ 30 #define _SYS_MODULE_H_ 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/cdefs.h> 35 #include <sys/queue.h> 36 #include <sys/uio.h> 37 38 #define MAXMODNAME 32 39 #define MAXMODDEPS 10 40 41 /* Module classes, provided only for system boot and cosmetic purposes. */ 42 typedef enum modclass { 43 MODULE_CLASS_ANY, 44 MODULE_CLASS_MISC, 45 MODULE_CLASS_VFS, 46 MODULE_CLASS_DRIVER, 47 MODULE_CLASS_EXEC, 48 MODULE_CLASS_SECMODEL 49 } modclass_t; 50 51 /* Module sources: where did it come from? */ 52 typedef enum modsrc { 53 MODULE_SOURCE_KERNEL, 54 MODULE_SOURCE_BOOT, 55 MODULE_SOURCE_FILESYS 56 } modsrc_t; 57 58 /* Commands passed to module control routine. */ 59 typedef enum modcmd { 60 MODULE_CMD_INIT, /* mandatory */ 61 MODULE_CMD_FINI, /* mandatory */ 62 MODULE_CMD_STAT, /* optional */ 63 MODULE_CMD_AUTOUNLOAD, /* optional */ 64 } modcmd_t; 65 66 #ifdef _KERNEL 67 68 #include <sys/mutex.h> 69 70 #include <prop/proplib.h> 71 72 /* Module header structure. */ 73 typedef struct modinfo { 74 u_int mi_version; 75 modclass_t mi_class; 76 int (*mi_modcmd)(modcmd_t, void *); 77 const char *mi_name; 78 const char *mi_required; 79 } const modinfo_t; 80 81 /* Per module information, maintained by kern_module.c */ 82 typedef struct module { 83 u_int mod_refcnt; 84 const modinfo_t *mod_info; 85 struct kobj *mod_kobj; 86 TAILQ_ENTRY(module) mod_chain; 87 struct module *mod_required[MAXMODDEPS]; 88 u_int mod_nrequired; 89 modsrc_t mod_source; 90 time_t mod_autotime; 91 void *mod_ctf; 92 u_int mod_fbtentries; /* DTrace FBT entry count */ 93 int mod_flags; 94 #define MODFLG_MUST_FORCE 0x01 95 #define MODFLG_AUTO_LOADED 0x02 96 97 } module_t; 98 99 /* 100 * Per-module linkage. Loadable modules have a `link_set_modules' section 101 * containing only one entry, pointing to the module's modinfo_t record. 102 * For the kernel, `link_set_modules' can contain multiple entries and 103 * records all modules built into the kernel at link time. 104 * 105 * Alternatively, in some environments rump kernels use 106 * __attribute__((constructor)) due to link sets being 107 * difficult (impossible?) to implement (e.g. GNU gold, OS X, etc.) 108 */ 109 110 #ifdef RUMP_USE_CTOR 111 struct modinfo_chain { 112 const struct modinfo *mc_info; 113 LIST_ENTRY(modinfo_chain) mc_entries; 114 }; 115 LIST_HEAD(modinfo_boot_chain, modinfo_chain); 116 #define _MODULE_REGISTER(name) \ 117 static void __CONCAT(modctor_,name)(void) __attribute__((__constructor__));\ 118 static void __CONCAT(modctor_,name)(void) \ 119 { \ 120 static struct modinfo_chain mc = { \ 121 .mc_info = &__CONCAT(name,_modinfo), \ 122 }; \ 123 extern struct modinfo_boot_chain modinfo_boot_chain; \ 124 LIST_INSERT_HEAD(&modinfo_boot_chain, &mc, mc_entries); \ 125 } 126 127 #else /* RUMP_USE_CTOR */ 128 129 #define _MODULE_REGISTER(name) __link_set_add_rodata(modules, __CONCAT(name,_modinfo)); 130 131 #endif /* RUMP_USE_CTOR */ 132 133 #define MODULE(class, name, required) \ 134 static int __CONCAT(name,_modcmd)(modcmd_t, void *); \ 135 static const modinfo_t __CONCAT(name,_modinfo) = { \ 136 .mi_version = __NetBSD_Version__, \ 137 .mi_class = (class), \ 138 .mi_modcmd = __CONCAT(name,_modcmd), \ 139 .mi_name = __STRING(name), \ 140 .mi_required = (required) \ 141 }; \ 142 _MODULE_REGISTER(name) 143 144 TAILQ_HEAD(modlist, module); 145 146 extern struct vm_map *module_map; 147 extern u_int module_count; 148 extern u_int module_builtinlist; 149 extern struct modlist module_list; 150 extern struct modlist module_builtins; 151 extern u_int module_gen; 152 153 void module_init(void); 154 void module_start_unload_thread(void); 155 void module_builtin_require_force(void); 156 void module_init_md(void); 157 void module_init_class(modclass_t); 158 int module_prime(const char *, void *, size_t); 159 160 bool module_compatible(int, int); 161 int module_load(const char *, int, prop_dictionary_t, modclass_t); 162 int module_builtin_add(modinfo_t * const *, size_t, bool); 163 int module_builtin_remove(modinfo_t *, bool); 164 int module_autoload(const char *, modclass_t); 165 int module_unload(const char *); 166 int module_hold(const char *); 167 void module_rele(const char *); 168 int module_find_section(const char *, void **, size_t *); 169 void module_thread_kick(void); 170 void module_load_vfs_init(void); 171 172 void module_whatis(uintptr_t, void (*)(const char *, ...) 173 __printflike(1, 2)); 174 void module_print_list(void (*)(const char *, ...) __printflike(1, 2)); 175 176 #ifdef _MODULE_INTERNAL 177 extern 178 int (*module_load_vfs_vec)(const char *, int, bool, module_t *, 179 prop_dictionary_t *); 180 int module_load_vfs(const char *, int, bool, module_t *, 181 prop_dictionary_t *); 182 void module_error(const char *, ...) __printflike(1, 2); 183 void module_print(const char *, ...) __printflike(1, 2); 184 #endif /* _MODULE_INTERNAL */ 185 186 #define MODULE_BASE_SIZE 64 187 extern char module_base[MODULE_BASE_SIZE]; 188 extern const char *module_machine; 189 190 #else /* _KERNEL */ 191 192 #include <stdint.h> 193 194 #endif /* _KERNEL */ 195 196 typedef struct modctl_load { 197 const char *ml_filename; 198 199 #define MODCTL_NO_PROP 0x2 200 #define MODCTL_LOAD_FORCE 0x1 201 int ml_flags; 202 203 const char *ml_props; 204 size_t ml_propslen; 205 } modctl_load_t; 206 207 typedef enum modctl { 208 MODCTL_LOAD, /* modctl_load_t *ml */ 209 MODCTL_UNLOAD, /* char *name */ 210 MODCTL_STAT, /* struct iovec *buffer */ 211 MODCTL_EXISTS /* enum: 0: load, 1: autoload */ 212 } modctl_t; 213 214 /* 215 * This structure intentionally has the same layout for 32 and 64 216 * bit builds. 217 */ 218 typedef struct modstat { 219 char ms_name[MAXMODNAME]; 220 char ms_required[MAXMODNAME * MAXMODDEPS]; 221 uint64_t ms_addr; 222 modsrc_t ms_source; 223 modclass_t ms_class; 224 u_int ms_size; 225 u_int ms_refcnt; 226 u_int ms_reserved[4]; 227 } modstat_t; 228 229 int modctl(int, void *); 230 231 #ifdef _KERNEL 232 /* attention: pointers passed are userland pointers!, 233 see modctl_load_t */ 234 int handle_modctl_load(const char *, int, const char *, size_t); 235 #endif 236 237 #endif /* !_SYS_MODULE_H_ */ 238