xref: /minix/sys/sys/module.h (revision 0a6a1f1d)
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