[e16e8f2] | 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_ |
---|