Home | History | Annotate | Line # | Download | only in sys
      1 /*	$NetBSD: module.h,v 1.48 2021/10/24 06:52:26 skrll 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/uio.h>
     36 
     37 #define	MAXMODNAME	32
     38 #define	MAXMODDEPS	10
     39 
     40 /* Module classes, provided only for system boot and module validation. */
     41 typedef enum modclass {
     42 	MODULE_CLASS_ANY,
     43 	MODULE_CLASS_MISC,
     44 	MODULE_CLASS_VFS,
     45 	MODULE_CLASS_DRIVER,
     46 	MODULE_CLASS_EXEC,
     47 	MODULE_CLASS_SECMODEL,
     48 	MODULE_CLASS_BUFQ,
     49 	MODULE_CLASS_MAX
     50 } modclass_t;
     51 
     52 /* Module sources: where did it come from? */
     53 typedef enum modsrc {
     54 	MODULE_SOURCE_KERNEL,
     55 	MODULE_SOURCE_BOOT,
     56 	MODULE_SOURCE_FILESYS
     57 } modsrc_t;
     58 
     59 /* Commands passed to module control routine. */
     60 typedef enum modcmd {
     61 	MODULE_CMD_INIT,		/* mandatory */
     62 	MODULE_CMD_FINI,		/* mandatory */
     63 	MODULE_CMD_STAT,		/* optional */
     64 	MODULE_CMD_AUTOUNLOAD,		/* optional */
     65 } modcmd_t;
     66 
     67 #ifdef _KERNEL
     68 
     69 #include <sys/kernel.h>
     70 #include <sys/mutex.h>
     71 #include <sys/queue.h>
     72 #include <sys/specificdata.h>
     73 
     74 #include <prop/proplib.h>
     75 
     76 /* Module header structure. */
     77 typedef struct modinfo {
     78 	u_int			mi_version;
     79 	modclass_t		mi_class;
     80 	int			(*mi_modcmd)(modcmd_t, void *);
     81 	const char		*mi_name;
     82 	const char		*mi_required;
     83 } const modinfo_t;
     84 
     85 /* Per module information, maintained by kern_module.c */
     86 
     87 struct sysctllog;
     88 
     89 typedef struct module {
     90 	u_int			mod_refcnt;
     91 	int			mod_flags;
     92 #define MODFLG_MUST_FORCE	0x01
     93 #define MODFLG_AUTO_LOADED	0x02
     94 	const modinfo_t		*mod_info;
     95 	struct kobj		*mod_kobj;
     96 	TAILQ_ENTRY(module)	mod_chain;
     97 	struct module		*(*mod_required)[MAXMODDEPS];
     98 	u_int			mod_nrequired;
     99 	u_int			mod_arequired;
    100 	modsrc_t		mod_source;
    101 	time_t			mod_autotime;
    102 	specificdata_reference	mod_sdref;
    103 	struct sysctllog	*mod_sysctllog;
    104 } module_t;
    105 
    106 /*
    107  * Per-module linkage.  Loadable modules have a `link_set_modules' section
    108  * containing only one entry, pointing to the module's modinfo_t record.
    109  * For the kernel, `link_set_modules' can contain multiple entries and
    110  * records all modules built into the kernel at link time.
    111  *
    112  * Alternatively, in some environments rump kernels use
    113  * __attribute__((constructor)) due to link sets being
    114  * difficult (impossible?) to implement (e.g. GNU gold, OS X, etc.)
    115  * If we're cold (read: rump_init() has not been called), we lob the
    116  * module onto the list to be handled when rump_init() runs.
    117  * nb. it's not possible to use in-kernel locking mechanisms here since
    118  * the code runs before rump_init().  We solve the problem by decreeing
    119  * that thou shalt not call dlopen()/dlclose() for rump kernel components
    120  * from multiple threads before calling rump_init().
    121  */
    122 
    123 #ifdef RUMP_USE_CTOR
    124 struct modinfo_chain {
    125 	const struct modinfo	*mc_info;
    126 	LIST_ENTRY(modinfo_chain) mc_entries;
    127 };
    128 LIST_HEAD(modinfo_boot_chain, modinfo_chain);
    129 #define _MODULE_REGISTER(name)						\
    130 static struct modinfo_chain __CONCAT(mc,name) = {			\
    131 	.mc_info = &__CONCAT(name,_modinfo),				\
    132 };									\
    133 static void __CONCAT(modctor_,name)(void) __attribute__((__constructor__));\
    134 static void __CONCAT(modctor_,name)(void)				\
    135 {									\
    136 	extern struct modinfo_boot_chain modinfo_boot_chain;		\
    137 	if (cold) {							\
    138 		struct modinfo_chain *mc = &__CONCAT(mc,name);		\
    139 		LIST_INSERT_HEAD(&modinfo_boot_chain, mc, mc_entries);	\
    140 	}								\
    141 }									\
    142 									\
    143 static void __CONCAT(moddtor_,name)(void) __attribute__((__destructor__));\
    144 static void __CONCAT(moddtor_,name)(void)				\
    145 {									\
    146 	struct modinfo_chain *mc = &__CONCAT(mc,name);			\
    147 	if (cold) {							\
    148 		LIST_REMOVE(mc, mc_entries);				\
    149 	}								\
    150 }
    151 
    152 #else /* RUMP_USE_CTOR */
    153 
    154 #define _MODULE_REGISTER(name) __link_set_add_rodata(modules, __CONCAT(name,_modinfo));
    155 
    156 #endif /* RUMP_USE_CTOR */
    157 
    158 #define	MODULE(class, name, required)				\
    159 static int __CONCAT(name,_modcmd)(modcmd_t, void *);		\
    160 static const modinfo_t __CONCAT(name,_modinfo) = {		\
    161 	.mi_version = __NetBSD_Version__,			\
    162 	.mi_class = (class),					\
    163 	.mi_modcmd = __CONCAT(name,_modcmd),			\
    164 	.mi_name = __STRING(name),				\
    165 	.mi_required = (required)				\
    166 }; 								\
    167 _MODULE_REGISTER(name)
    168 
    169 TAILQ_HEAD(modlist, module);
    170 
    171 extern struct vm_map	*module_map;
    172 extern u_int		module_count;
    173 extern u_int		module_builtinlist;
    174 extern struct modlist	module_list;
    175 extern struct modlist	module_builtins;
    176 extern u_int		module_gen;
    177 
    178 void	module_init(void);
    179 void	module_start_unload_thread(void);
    180 void	module_builtin_require_force(void);
    181 void	module_init_md(void);
    182 void	module_init_class(modclass_t);
    183 int	module_prime(const char *, void *, size_t);
    184 
    185 module_t *module_kernel(void);
    186 const char *module_name(struct module *);
    187 modsrc_t module_source(struct module *);
    188 bool	module_compatible(int, int);
    189 int	module_load(const char *, int, prop_dictionary_t, modclass_t);
    190 int	module_builtin_add(modinfo_t * const *, size_t, bool);
    191 int	module_builtin_remove(modinfo_t *, bool);
    192 int	module_autoload(const char *, modclass_t);
    193 int	module_unload(const char *);
    194 void	module_hold(module_t *);
    195 void	module_rele(module_t *);
    196 int	module_find_section(const char *, void **, size_t *);
    197 void	module_thread_kick(void);
    198 void	module_load_vfs_init(void);
    199 
    200 specificdata_key_t module_specific_key_create(specificdata_key_t *, specificdata_dtor_t);
    201 void	module_specific_key_delete(specificdata_key_t);
    202 void	*module_getspecific(module_t *, specificdata_key_t);
    203 void	module_setspecific(module_t *, specificdata_key_t, void *);
    204 void	*module_register_callbacks(void (*)(struct module *),
    205 				  void (*)(struct module *));
    206 void	module_unregister_callbacks(void *);
    207 
    208 void	module_whatis(uintptr_t, void (*)(const char *, ...)
    209     __printflike(1, 2));
    210 void	module_print_list(void (*)(const char *, ...) __printflike(1, 2));
    211 
    212 #ifdef _MODULE_INTERNAL
    213 extern
    214 int	(*module_load_vfs_vec)(const char *, int, bool, module_t *,
    215 			       prop_dictionary_t *);
    216 int	module_load_vfs(const char *, int, bool, module_t *,
    217 			prop_dictionary_t *);
    218 void	module_error(const char *, ...) __printflike(1, 2);
    219 void	module_print(const char *, ...) __printflike(1, 2);
    220 #endif /* _MODULE_INTERNAL */
    221 
    222 #define MODULE_BASE_SIZE 64
    223 extern char	module_base[MODULE_BASE_SIZE];
    224 extern const char	*module_machine;
    225 
    226 struct netbsd32_modctl_args;
    227 extern int compat32_80_modctl_compat_stub(struct lwp *,
    228     const struct netbsd32_modctl_args *, register_t *);
    229 
    230 #else	/* _KERNEL */
    231 
    232 #include <stdint.h>
    233 
    234 #endif	/* _KERNEL */
    235 
    236 typedef struct modctl_load {
    237 	const char *ml_filename;
    238 
    239 #define MODCTL_NO_PROP		0x2
    240 #define MODCTL_LOAD_FORCE	0x1
    241 	int ml_flags;
    242 
    243 	const char *ml_props;
    244 	size_t ml_propslen;
    245 } modctl_load_t;
    246 
    247 enum modctl {
    248 	MODCTL_LOAD,		/* modctl_load_t *ml */
    249 	MODCTL_UNLOAD,		/* char *name */
    250 	MODCTL_OSTAT,		/* struct iovec *buffer */
    251 	MODCTL_EXISTS,		/* enum: 0: load, 1: autoload */
    252 	MODCTL_STAT		/* struct iovec *buffer */
    253 };
    254 
    255 /*
    256  * This structure is used with the newer version of MODCTL_STAT, which
    257  * exports strings of arbitrary length for the list of required modules.
    258  */
    259 typedef struct modstat {
    260 	char		ms_name[MAXMODNAME];
    261 	uint64_t	ms_addr;
    262 	modsrc_t	ms_source;
    263 	modclass_t	ms_class;
    264 	u_int		ms_size;
    265 	u_int		ms_refcnt;
    266 	u_int		ms_flags;
    267 	u_int		ms_reqoffset;	/* offset to module's required list
    268 					   from beginning of iovec buffer! */
    269 } modstat_t;
    270 
    271 int	modctl(int, void *);
    272 
    273 #ifdef _KERNEL
    274 /* attention: pointers passed are userland pointers!,
    275    see modctl_load_t */
    276 int	handle_modctl_load(const char *, int, const char *, size_t);
    277 #endif
    278 
    279 #endif	/* !_SYS_MODULE_H_ */
    280