1 | /** |
---|
2 | * syslinux/module.h |
---|
3 | * |
---|
4 | * Dynamic ELF modules definitions and services. |
---|
5 | */ |
---|
6 | |
---|
7 | #ifndef MODULE_H_ |
---|
8 | #define MODULE_H_ |
---|
9 | |
---|
10 | #include <stdio.h> |
---|
11 | #include <elf.h> |
---|
12 | #include <stdint.h> |
---|
13 | #include <setjmp.h> |
---|
14 | #include <stdbool.h> |
---|
15 | #include <linux/list.h> |
---|
16 | |
---|
17 | #if __SIZEOF_POINTER__ == 4 |
---|
18 | #include <i386/module.h> |
---|
19 | #elif __SIZEOF_POINTER__ == 8 |
---|
20 | #include <x86_64/module.h> |
---|
21 | #else |
---|
22 | #error "unsupported architecture" |
---|
23 | #endif |
---|
24 | |
---|
25 | /* |
---|
26 | * The maximum length of the module file name (including path), stored |
---|
27 | * in the struct module descriptor. |
---|
28 | */ |
---|
29 | #define MODULE_NAME_SIZE 256 |
---|
30 | |
---|
31 | /* |
---|
32 | * Some common information about what kind of modules we're dealing with |
---|
33 | */ |
---|
34 | #define EXEC_MODULE 0 |
---|
35 | #define LIB_MODULE 1 |
---|
36 | |
---|
37 | #define MAX_NR_DEPS 64 |
---|
38 | |
---|
39 | /* |
---|
40 | * Initialization and finalization function signatures |
---|
41 | */ |
---|
42 | |
---|
43 | /** |
---|
44 | * module_main_t - pointer to an entry routine |
---|
45 | * |
---|
46 | * The entry routine is present only in executable modules, and represents |
---|
47 | * the entry point for the program. |
---|
48 | */ |
---|
49 | typedef int (*module_main_t)(int, char**); |
---|
50 | |
---|
51 | /** |
---|
52 | * module_ctor_t - pointer to a constructor or destructor routine |
---|
53 | * |
---|
54 | * A module may have multiple routines that need to be executed before |
---|
55 | * or after the main routine. These are the constructors and |
---|
56 | * destructors, respectively. |
---|
57 | */ |
---|
58 | typedef void (*module_ctor_t) (void); |
---|
59 | |
---|
60 | /** |
---|
61 | * struct elf_module - structure encapsulating a module loaded in memory. |
---|
62 | * |
---|
63 | * Each SYSLINUX ELF module must have an associated struct elf_module descriptor |
---|
64 | * that keeps track of memory allocations, symbol information, and various other |
---|
65 | * resources needed by the module itself or by other modules that depend on it. |
---|
66 | * |
---|
67 | * There are two types of modules: |
---|
68 | * - regular modules, which are actual memory images of a loaded & linked shared |
---|
69 | * object (ELF file). Memory is reserved for the struct elf_module structure itself |
---|
70 | * and for the object loadable sections read from the file. |
---|
71 | * - shallow modules, which are not associated with an ELF shared object, but contain |
---|
72 | * metainformation about a memory region already present and containing the |
---|
73 | * actual code and data. One particular usage of shallow modules is to access |
---|
74 | * symbol information from the root COM32 module loaded by the SYSLINUX core. |
---|
75 | * As their name suggests, memory is reserved only for the elf_module structure |
---|
76 | * itself and optionally for a usually small memory region containing metainformation |
---|
77 | * (symbol information). |
---|
78 | * |
---|
79 | * Module descriptors are related to each other through dependency information. A module |
---|
80 | * can depend on symbols from other modules, and in turn it can provide symbols used |
---|
81 | * by other dependant modules. This relationship can be described as a directed |
---|
82 | * acyclic graph (DAG). The graph is stored using double linked lists of |
---|
83 | * predecessors and successors. There is also a global linked list containing all |
---|
84 | * the modules currently loaded. |
---|
85 | */ |
---|
86 | struct atexit; |
---|
87 | struct elf_module { |
---|
88 | char name[MODULE_NAME_SIZE]; // The module name |
---|
89 | |
---|
90 | bool shallow; // Whether the module contains any code |
---|
91 | |
---|
92 | struct list_head required; // Head of the required modules list |
---|
93 | struct list_head dependants; // Head of module dependants list |
---|
94 | struct list_head list; // The list entry in the module list |
---|
95 | |
---|
96 | module_ctor_t *ctors; // module constructors |
---|
97 | module_ctor_t *dtors; // module destructors |
---|
98 | module_main_t main_func; // The main function (for executable modules) |
---|
99 | |
---|
100 | void *module_addr; // The module location in the memory |
---|
101 | Elf_Addr base_addr; // The base address of the module |
---|
102 | Elf_Word module_size; // The module size in memory |
---|
103 | |
---|
104 | Elf_Word *hash_table; // The symbol hash table |
---|
105 | Elf_Word *ghash_table; // The GNU style hash table |
---|
106 | char *str_table; // The string table |
---|
107 | void *sym_table; // The symbol table |
---|
108 | void *got; // The Global Offset Table |
---|
109 | Elf_Dyn *dyn_table; // Dynamic loading information table |
---|
110 | |
---|
111 | Elf_Word strtable_size; // The size of the string table |
---|
112 | Elf_Word syment_size; // The size of a symbol entry |
---|
113 | Elf_Word symtable_size; // The size of the symbol table |
---|
114 | |
---|
115 | |
---|
116 | union { |
---|
117 | // Transient - Data available while the module is loading |
---|
118 | struct { |
---|
119 | FILE *_file; // The file object of the open file |
---|
120 | Elf_Off _cr_offset; // The current offset in the open file |
---|
121 | } l; |
---|
122 | |
---|
123 | // Process execution data |
---|
124 | struct { |
---|
125 | jmp_buf process_exit; // Exit state |
---|
126 | struct atexit *atexit_list; // atexit() chain |
---|
127 | } x; |
---|
128 | } u; |
---|
129 | |
---|
130 | // ELF DT_NEEDED entries for this module |
---|
131 | int nr_needed; |
---|
132 | Elf_Word needed[MAX_NR_DEPS]; |
---|
133 | }; |
---|
134 | |
---|
135 | /** |
---|
136 | * struct module_dep - structure encapsulating a module dependency need |
---|
137 | * |
---|
138 | * This structure represents an item in a double linked list of predecessors or |
---|
139 | * successors. The item contents is a pointer to the corresponding module descriptor. |
---|
140 | */ |
---|
141 | struct module_dep { |
---|
142 | struct list_head list; // The list entry in the dependency list |
---|
143 | |
---|
144 | struct elf_module *module; // The target module descriptor |
---|
145 | }; |
---|
146 | |
---|
147 | |
---|
148 | /** |
---|
149 | * Unload all modules that have been loaded since @name. |
---|
150 | * |
---|
151 | * Returns the struct elf_module * for @name or %NULL if no modules |
---|
152 | * have been loaded since @name. |
---|
153 | */ |
---|
154 | extern struct elf_module *unload_modules_since(const char *name); |
---|
155 | |
---|
156 | extern FILE *findpath(char *name); |
---|
157 | |
---|
158 | |
---|
159 | /** |
---|
160 | * Names of symbols with special meaning (treated as special cases at linking) |
---|
161 | */ |
---|
162 | #define MODULE_ELF_INIT_PTR "__module_init_ptr" // Initialization pointer symbol name |
---|
163 | #define MODULE_ELF_EXIT_PTR "__module_exit_ptr" // Finalization pointer symbol name |
---|
164 | #define MODULE_ELF_MAIN_PTR "__module_main_ptr" // Entry pointer symbol name |
---|
165 | |
---|
166 | /** |
---|
167 | * modules_head - A global linked list containing all the loaded modules. |
---|
168 | */ |
---|
169 | extern struct list_head modules_head; |
---|
170 | |
---|
171 | |
---|
172 | /** |
---|
173 | * for_each_module - iterator loop through the list of loaded modules. |
---|
174 | */ |
---|
175 | #define for_each_module(m) list_for_each_entry(m, &modules_head, list) |
---|
176 | |
---|
177 | /** |
---|
178 | * for_each_module_safe - iterator loop through the list of loaded modules safe against removal. |
---|
179 | */ |
---|
180 | #define for_each_module_safe(m, n) \ |
---|
181 | list_for_each_entry_safe(m, n, &modules_head, list) |
---|
182 | |
---|
183 | /** |
---|
184 | * module_current - return the module at the head of the module list. |
---|
185 | */ |
---|
186 | static inline struct elf_module *module_current(void) |
---|
187 | { |
---|
188 | struct elf_module *head; |
---|
189 | |
---|
190 | head = list_entry((&modules_head)->next, typeof(*head), list); |
---|
191 | return head; |
---|
192 | } |
---|
193 | |
---|
194 | /** |
---|
195 | * modules_init - initialize the module subsystem. |
---|
196 | * |
---|
197 | * This function must be called before any module operation is to be performed. |
---|
198 | */ |
---|
199 | extern int modules_init(void); |
---|
200 | |
---|
201 | |
---|
202 | /** |
---|
203 | * modules_term - releases all resources pertaining to the module subsystem. |
---|
204 | * |
---|
205 | * This function should be called after all module operations. |
---|
206 | */ |
---|
207 | extern void modules_term(void); |
---|
208 | |
---|
209 | |
---|
210 | /** |
---|
211 | * module_alloc - reserves space for a new module descriptor. |
---|
212 | * @name: the file name of the module to be loaded. |
---|
213 | * |
---|
214 | * The function simply allocates a new module descriptor and initializes its fields |
---|
215 | * in order to be used by subsequent loading operations. |
---|
216 | */ |
---|
217 | extern struct elf_module *module_alloc(const char *name); |
---|
218 | |
---|
219 | |
---|
220 | /** |
---|
221 | * module_load - loads a regular ELF module into memory. |
---|
222 | * @module: the module descriptor returned by module_alloc. |
---|
223 | * |
---|
224 | * The function reads the module file, checks whether the file has a |
---|
225 | * valid structure, then loads into memory the code and the data and performs |
---|
226 | * any symbol relocations. A module dependency is created automatically when the |
---|
227 | * relocated symbol is defined in a different module. |
---|
228 | * |
---|
229 | * The function returns 0 if the operation is completed successfully, and |
---|
230 | * a non-zero value if an error occurs. Possible errors include invalid module |
---|
231 | * structure, missing symbol definitions (unsatisfied dependencies) and memory |
---|
232 | * allocation issues. |
---|
233 | */ |
---|
234 | extern int module_load(struct elf_module *module); |
---|
235 | |
---|
236 | |
---|
237 | /** |
---|
238 | * module_unload - unloads the module from the system. |
---|
239 | * @module: the module descriptor structure. |
---|
240 | * |
---|
241 | * The function checks to see whether the module can be safely |
---|
242 | * removed, then it executes any destructors and releases all the |
---|
243 | * associated memory. This function can be applied both for standard |
---|
244 | * modules and for shallow modules. |
---|
245 | * |
---|
246 | * A module can be safely removed from the system when no other modules reference |
---|
247 | * symbols from it. |
---|
248 | */ |
---|
249 | extern int module_unload(struct elf_module *module); |
---|
250 | |
---|
251 | /** |
---|
252 | * _module_unload - unloads the module without running destructors |
---|
253 | * @module: the module descriptor structure. |
---|
254 | * |
---|
255 | * This function is the same as module_unload(), except that the |
---|
256 | * module's destructors are not executed. |
---|
257 | */ |
---|
258 | extern int _module_unload(struct elf_module *module); |
---|
259 | |
---|
260 | /** |
---|
261 | * get_module_type - get type of the module |
---|
262 | * @module: the module descriptor structure. |
---|
263 | * |
---|
264 | * This function returns the type of module we're dealing with |
---|
265 | * either a library module ( LIB_MODULE ), executable module ( EXEC_MODULE ), |
---|
266 | * or an error ( UNKNOWN_MODULE ). The way it checks teh type is by checking to see |
---|
267 | * if the module has its main_func set ( in which case it's an executable ). In case |
---|
268 | * it doesn't it then checks to see if init_func is set ( in which case it's a |
---|
269 | * library module. If this isn't the case either we don't know what it is so bail out |
---|
270 | */ |
---|
271 | extern int get_module_type(struct elf_module *module); |
---|
272 | |
---|
273 | /** |
---|
274 | * module_unloadable - checks whether the given module can be unloaded. |
---|
275 | * @module: the module descriptor structure |
---|
276 | * |
---|
277 | * A module can be unloaded from the system when no other modules depend on it, |
---|
278 | * that is, no symbols are referenced from it. |
---|
279 | */ |
---|
280 | extern int module_unloadable(struct elf_module *module); |
---|
281 | |
---|
282 | /** |
---|
283 | * module_find - searches for a module by its name. |
---|
284 | * @name: the name of the module, as it was specified in module_alloc. |
---|
285 | * |
---|
286 | * The function returns a pointer to the module descriptor, if found, or |
---|
287 | * NULL otherwise. |
---|
288 | */ |
---|
289 | extern struct elf_module *module_find(const char *name); |
---|
290 | |
---|
291 | /** |
---|
292 | * module_find_symbol - searches for a symbol definition in a given module. |
---|
293 | * @name: the name of the symbol to be found. |
---|
294 | * @module: the module descriptor structure. |
---|
295 | * |
---|
296 | * The function searches the module symbol table for a symbol matching exactly |
---|
297 | * the name provided. The operation uses the following search algorithms, in this |
---|
298 | * order: |
---|
299 | * - If a GNU hash table is present in the module, it is used to find the symbol. |
---|
300 | * - If the symbol cannot be found with the first method (either the hash table |
---|
301 | * is not present or the symbol is not found) and if a regular (SysV) hash table |
---|
302 | * is present, a search is performed on the SysV hash table. If the symbol is not |
---|
303 | * found, NULL is returned. |
---|
304 | * - If the second method cannot be applied, a linear search is performed by |
---|
305 | * inspecting every symbol in the symbol table. |
---|
306 | * |
---|
307 | * If the symbol is found, a pointer to its descriptor structure is returned, and |
---|
308 | * NULL otherwise. |
---|
309 | */ |
---|
310 | extern Elf_Sym *module_find_symbol(const char *name, struct elf_module *module); |
---|
311 | |
---|
312 | /** |
---|
313 | * global_find_symbol - searches for a symbol definition in the entire module namespace. |
---|
314 | * @name: the name of the symbol to be found. |
---|
315 | * @module: an optional (may be NULL) pointer to a module descriptor variable that |
---|
316 | * will hold the module where the symbol was found. |
---|
317 | * |
---|
318 | * The function search for the given symbol name in all the modules currently |
---|
319 | * loaded in the system, in the reverse module loading order. That is, the most |
---|
320 | * recently loaded module is searched first, followed by the previous one, until |
---|
321 | * the first loaded module is reached. |
---|
322 | * |
---|
323 | * If no module contains the symbol, NULL is returned, otherwise the return value is |
---|
324 | * a pointer to the symbol descriptor structure. If the module parameter is not NULL, |
---|
325 | * it is filled with the address of the module descriptor where the symbol is defined. |
---|
326 | */ |
---|
327 | extern Elf_Sym *global_find_symbol(const char *name, struct elf_module **module); |
---|
328 | |
---|
329 | /** |
---|
330 | * module_get_absolute - converts an memory address relative to a module base address |
---|
331 | * to its absolute value in RAM. |
---|
332 | * @addr: the relative address to convert. |
---|
333 | * @module: the module whose base address is used for the conversion. |
---|
334 | * |
---|
335 | * The function returns a pointer to the absolute memory address. |
---|
336 | */ |
---|
337 | static inline void *module_get_absolute(Elf_Addr addr, struct elf_module *module) { |
---|
338 | return (void*)(module->base_addr + addr); |
---|
339 | } |
---|
340 | |
---|
341 | /** |
---|
342 | * syslinux_current - get the current module process |
---|
343 | */ |
---|
344 | extern struct elf_module *__syslinux_current; |
---|
345 | static inline const struct elf_module *syslinux_current(void) |
---|
346 | { |
---|
347 | return __syslinux_current; |
---|
348 | } |
---|
349 | |
---|
350 | |
---|
351 | #endif // MODULE_H_ |
---|