diff options
author | Feng Tang <feng.tang@intel.com> | 2010-08-12 20:42:00 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-08-12 20:43:14 -0700 |
commit | 0fb20934d2145e43f08650dbbf6613f24f2df8c6 (patch) | |
tree | 98018a3a38d693937fe19e6f5d2f7f1dfddcdc38 /com32/include/sys | |
parent | 0ee50473e37cbc22ef1b2f9897bce48c41be8f5e (diff) | |
parent | 64076d080c03973acbbb12e9b80b017920b1c259 (diff) | |
download | syslinux-0fb20934d2145e43f08650dbbf6613f24f2df8c6.tar.gz |
elflink: merge with master branch
ELF modules basically work
Conflicts:
com32/Makefile
com32/lib/Makefile
com32/lua/etc/luavs.bat
core/fs/getcwd.c
core/include/fs.h
core/pmapi.c
libinstaller/syslxmod.c
Signed-off-by: Feng Tang <feng.tang@intel.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'com32/include/sys')
-rw-r--r-- | com32/include/sys/elfcommon.h | 231 | ||||
-rw-r--r-- | com32/include/sys/exec.h | 134 | ||||
-rw-r--r-- | com32/include/sys/module.h | 377 |
3 files changed, 715 insertions, 27 deletions
diff --git a/com32/include/sys/elfcommon.h b/com32/include/sys/elfcommon.h index 2489e3c0..8d6ddb05 100644 --- a/com32/include/sys/elfcommon.h +++ b/com32/include/sys/elfcommon.h @@ -59,32 +59,108 @@ #define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */ /* Dynamic type values */ -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_PLTRELSZ 2 -#define DT_PLTGOT 3 -#define DT_HASH 4 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_RELA 7 -#define DT_RELASZ 8 -#define DT_RELAENT 9 -#define DT_STRSZ 10 -#define DT_SYMENT 11 -#define DT_INIT 12 -#define DT_FINI 13 -#define DT_SONAME 14 -#define DT_RPATH 15 -#define DT_SYMBOLIC 16 -#define DT_REL 17 -#define DT_RELSZ 18 -#define DT_RELENT 19 -#define DT_PLTREL 20 -#define DT_DEBUG 21 -#define DT_TEXTREL 22 -#define DT_JMPREL 23 -#define DT_LOPROC 0x70000000 -#define DT_HIPROC 0x7fffffff +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path (deprecated) */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used */ +#define DT_LOOS 0x6000000d /* Start of OS-specific */ +#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ + +#define DT_VALRNGLO 0x6ffffd00 +#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ +#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ +#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ +#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting + the following DT_* entry. */ +#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +#define DT_VALRNGHI 0x6ffffdff +#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ +#define DT_VALNUM 12 + +/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + + If any adjustment is made to the ELF object after it has been + built these entries will need to be adjusted. */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ +#define DT_TLSDESC_PLT 0x6ffffef6 +#define DT_TLSDESC_GOT 0x6ffffef7 +#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ +#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ +#define DT_CONFIG 0x6ffffefa /* Configuration information. */ +#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ +#define DT_AUDIT 0x6ffffefc /* Object auditing. */ +#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ +#define DT_MOVETAB 0x6ffffefe /* Move table. */ +#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ +#define DT_ADDRNUM 11 + +/* The versioning entry types. The next are defined as part of the + GNU extension. */ +#define DT_VERSYM 0x6ffffff0 + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa + +/* These were chosen by Sun. */ +#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_VERSIONTAGNUM 16 + +/* Sun added these machine-independent extensions in the "processor-specific" + range. Be compatible. */ +#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 /* Auxilliary table entries */ #define AT_NULL 0 /* end of vector */ @@ -147,6 +223,52 @@ #define SHN_COMMON 0xfff2 #define SHN_HIRESERVE 0xffff +/* Symbol table definitions */ + +/* How to extract and insert information held in the st_info field. */ + +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) + +/* Legal values for ST_BIND subfield of st_info (symbol binding). */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types. */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_COMMON 5 /* Symbol is a common data object */ +#define STT_TLS 6 /* Symbol is thread-local data object*/ +#define STT_NUM 7 /* Number of defined types. */ +#define STT_LOOS 10 /* Start of OS-specific */ +#define STT_HIOS 12 /* End of OS-specific */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ + + +/* Symbol table indices are found in the hash buckets and chain table + of a symbol hash table section. This special index value indicates + the end of a chain, meaning no further symbols are found in that bucket. */ + +#define STN_UNDEF 0 /* End of a chain. */ + /* Lenght of magic at the start of a file */ #define EI_NIDENT 16 @@ -184,4 +306,59 @@ #define ELFOSABI_NONE 0 #define ELFOSABI_LINUX 3 -#endif /* _SYS_ELFCOMMON_H */ +/* Intel 80386 specific definitions. */ + +/* i386 relocs. */ + +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ +#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS + block offset */ +#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block + offset */ +#define R_386_TLS_LE 17 /* Offset relative to static TLS + block */ +#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of + general dynamic thread local data */ +#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of + local dynamic thread local data + in LE code */ +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic + thread local data */ +#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ +#define R_386_TLS_GD_CALL 26 /* Relocation for call to + __tls_get_addr() */ +#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ +#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic + thread local data in LE code */ +#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ +#define R_386_TLS_LDM_CALL 30 /* Relocation for call to + __tls_get_addr() in LDM code */ +#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ +#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ +#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS + block offset */ +#define R_386_TLS_LE_32 34 /* Negated offset relative to static + TLS block */ +#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ +#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ +#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +/* Keep this the last entry. */ +#define R_386_NUM 38 + +#endif /* _SYS_ELFCOMMON_H */ diff --git a/com32/include/sys/exec.h b/com32/include/sys/exec.h new file mode 100644 index 00000000..31b62beb --- /dev/null +++ b/com32/include/sys/exec.h @@ -0,0 +1,134 @@ +/* + * exec.h + * + * Created on: Aug 14, 2008 + * Author: Stefan Bucur <stefanb@zytor.com> + */ + +#ifndef EXEC_H_ +#define EXEC_H_ + +#include <sys/module.h> +#include <stdlib.h> + +/** + * EXEC_ROOT_NAME - The name of the ELF module associated with the COM32 module. + * + * This is a shallow ELF module, that contains only the symbol table for + * the code and data sections of the loaded COM32 root module. + */ +#define EXEC_ROOT_NAME "_root_.c32" + +/** + * MODULES_DEP - The name of the standard module dependency file + * + * This is the file which contains information about the module dependency + * graph ( what other modules it depends on ). The file format is identical + * to the standard linux modules.dep file... for more information check out the + * man page ). + */ +#define MODULES_DEP "modules.dep" + +/** + * spawn_load - Load a library module or executes an executable one + * @name the name of the library/executable to use, including the extension + * (e.g. 'sort.c32') + * @argv: a NULL-terminated vector of string arguments, starting with + * the program name. + * + * This procedure in essence loads takes the name of a module and checks to see what + * kind of module it is ( executable or library ), after which is performs the + * appropriate action, either spawning or simply loading the module into memory. + */ +extern int spawn_load(const char *name,const char **argv); + +extern int module_load_dependencies(const char*name,const char*dep_file); + +/** + * exec_init - Initialize the dynamic execution environment. + * + * Among others, it initializes the module subsystem and loads the root + * module into memory. You should note the difference between the module + * management API, and the execution API: + * - the module system is a static one - it only manages the data structures + * and their relationship. It does not describe the way modules are executed, + * when and how they are loaded/unloaded, etc. It acts as a service layer for + * the execution API. + * - the execution environment is the dynamic part of the SYSLINUX dynamic + * module API - it implements the behavior of the modules: it + * triggers the execution of initialization and termination functions for + * libraries, executes the modules marked as executable, handles dynamic + * memory cleanup, etc. In other words, at this layer the code and data + * loaded by the lower module layer gets to be executed by the CPU, + * thus becoming part of the SYSLINUX environment. + */ +extern int exec_init(void); + + +/** + * load_library - Loads a dynamic library into the environment. + * @name: the name of the library to load, including the extension + * (e.g. 'sort.c32') + * + * A dynamic library is an ELF module that may contain initialization and + * termination routines, but not a main routine. At the same time, any memory + * allocations using malloc() and its derivatives are made on behalf of the + * currently executing program or the COM32 root module. If the library + * is unloaded, no memory cleanup is performed. + */ +extern int load_library(const char *name); + +/** + * unload_library - unloads a library from the environment. + * @name: the name of the library to unload, including the extension + * (e.g. 'sort.c32') + * + * Note that no memory allocated by the library code is cleaned up, as the + * allocations belong to the innermost calling program in the call stack. + */ +extern int unload_library(const char *name); + +/** + * spawnv - Executes a program in the current environment. + * @name: the name of the program to spawn, including the extension + * (e.g. 'hello.c32') + * @argv: a NULL-terminated vector of string arguments, starting with + * the program name. + * + * A program is an ELF module that contains a main routine. A program is + * loaded into memory, executed, then unloaded, thus remaining in memory only + * while the main() function is executing. A program also defines a + * memory allocation context, and a simple garbage collection mechanism + * it thus provided. This is done by internally associating with the program + * module each pointer returned by malloc(). After the program finishes + * its execution, all the unallocated memory pertaining to the program + * is automatically cleaned up. + * + * Note that this association takes place both for the allocations happening + * directly in the program, or indirectly through a library function. Libraries + * do not create allocation contexts, thus each allocation they made belong + * to the innermost calling program. + */ +extern int spawnv(const char *name, const char **argv); + +/** + * spawnl - Executes a program in the current environment. + * @name: the name of the program to spawn, including the extension + * (e.g. 'hello.c32') + * @arg: the first argument (argv[0]) to be passed to the main function + * of the program + * @...: optional subsequent arguments that are passed o the main function + * of the program + * + * This is another version of the spawn routine. Please see 'spawnv' for + * a full presentation. + */ +extern int spawnl(const char *name, const char *arg, ...); + +/** + * exec_term - Releases the resources of the execution environment. + */ +extern void exec_term(void); + + +#endif /* EXEC_H_ */ diff --git a/com32/include/sys/module.h b/com32/include/sys/module.h new file mode 100644 index 00000000..0c7c71f4 --- /dev/null +++ b/com32/include/sys/module.h @@ -0,0 +1,377 @@ +/** + * syslinux/module.h + * + * Dynamic ELF modules definitions and services. + */ + + +#ifndef MODULE_H_ +#define MODULE_H_ + +#include <stdio.h> +#include <elf.h> +#include <stdint.h> +#include <setjmp.h> +#include <stdbool.h> +#include <linux/list.h> + +/* + * The maximum length of the module file name (including path), stored + * in the struct module descriptor. + */ +#define MODULE_NAME_SIZE 256 + +/* + * Some common information about what kind of modules we're dealing with + */ +#define UNKNOWN_MODULE -1 +#define EXEC_MODULE 0 +#define LIB_MODULE 1 + +/* + * Initialization and finalization function signatures + */ + + +/** + * module_init_t - pointer to a initialization routine + * + * The initialization routine is called after all module constructors were invoked. + * It takes no parameters and returns 0 if the module was initialized successfully, + * or a non-zero value if errors have occurred. + */ +typedef int (*module_init_t)(void); + +/** + * module_exit_t - pointer to a finalization routine + * + * The finalization routine is called before the module destructors are to be invoked. + * It simply executes some cleanup code, without error reporting. + */ +typedef void (*module_exit_t)(void); + +/** + * module_main_t - pointer to an entry routine + * + * The entry routine is present only in executable modules, and represents + * the entry point for the program. + */ +typedef int (*module_main_t)(int, char**); + + +/** + * struct elf_module - structure encapsulating a module loaded in memory. + * + * Each SYSLINUX ELF module must have an associated struct elf_module descriptor + * that keeps track of memory allocations, symbol information, and various other + * resources needed by the module itself or by other modules that depend on it. + * + * There are two types of modules: + * - regular modules, which are actual memory images of a loaded & linked shared + * object (ELF file). Memory is reserved for the struct elf_module structure itself + * and for the object loadable sections read from the file. + * - shallow modules, which are not associated with an ELF shared object, but contain + * metainformation about a memory region already present and containing the + * actual code and data. One particular usage of shallow modules is to access + * symbol information from the root COM32 module loaded by the SYSLINUX core. + * As their name suggests, memory is reserved only for the elf_module structure + * itself and optionally for a usually small memory region containing metainformation + * (symbol information). + * + * Module descriptors are related to each other through dependency information. A module + * can depend on symbols from other modules, and in turn it can provide symbols used + * by other dependant modules. This relationship can be described as a directed + * acyclic graph (DAG). The graph is stored using double linked lists of + * predecessors and successors. There is also a global linked list containing all + * the modules currently loaded. + */ +struct atexit; +struct elf_module { + char name[MODULE_NAME_SIZE]; // The module name + + bool shallow; // Whether the module contains any code + + struct list_head required; // Head of the required modules list + struct list_head dependants; // Head of module dependants list + struct list_head list; // The list entry in the module list + + module_init_t *init_func; // The initialization entry point + module_exit_t *exit_func; // The module finalization code + module_main_t *main_func; // The main function (for executable modules) + + + void *module_addr; // The module location in the memory + Elf32_Addr base_addr; // The base address of the module + Elf32_Word module_size; // The module size in memory + + Elf32_Word *hash_table; // The symbol hash table + Elf32_Word *ghash_table; // The GNU style hash table + char *str_table; // The string table + void *sym_table; // The symbol table + void *got; // The Global Offset Table + Elf32_Dyn *dyn_table; // Dynamic loading information table + + Elf32_Word strtable_size; // The size of the string table + Elf32_Word syment_size; // The size of a symbol entry + Elf32_Word symtable_size; // The size of the symbol table + + + union { + // Transient - Data available while the module is loading + struct { + FILE *_file; // The file object of the open file + Elf32_Off _cr_offset; // The current offset in the open file + } l; + + // Process execution data + struct { + jmp_buf process_exit; // Exit state + struct atexit *atexit_list; // atexit() chain + } x; + } u; + +}; + +static inline void dump_elf_module(struct elf_module *module) +{ + /* + mp("module name = %s", module->name); + printf("base_addr = 0x%p, module_size = %d\n", module->base_addr, module->module_size); + printf("hash tlb = 0x%p, ghash tbl = 0x%p\n", module->hash_table, module->ghash_table); + printf("str tbl = 0x%p, size = %d\n", module->str_table, module->strtable_size); + printf("sym tbl = 0x%p, entry = %d, size = %d\n", module->sym_table, module->syment_size, module->symtable_size); + printf("init: %p", module->init_func); + printf("main: %p", module->main_func); + printf("exit: %p", module->exit_func); + printf("", module->base_addr); + printf("", module->base_addr); + printf("", module->base_addr); + */ +} + +/** + * struct module_dep - structure encapsulating a module dependency need + * + * This structure represents an item in a double linked list of predecessors or + * successors. The item contents is a pointer to the corresponding module descriptor. + */ +struct module_dep { + struct list_head list; // The list entry in the dependency list + + struct elf_module *module; // The target module descriptor +}; + + + +#ifdef DYNAMIC_MODULE + +/* + * This portion is included by dynamic (ELF) module source files. + */ + +#define MODULE_INIT(fn) static module_init_t __module_init \ + __used __attribute__((section(".ctors_modinit"))) = fn + +#define MODULE_EXIT(fn) static module_exit_t __module_exit \ + __used __attribute__((section(".dtors_modexit"))) = fn + +#define MODULE_MAIN(fn) static module_main_t __module_main \ + __used __attribute__((section(".ctors_modmain"))) = fn + +#else + +/* + * This portion is included by the core COM32 module. + */ + +/* + * Accepted values for various ELF header parameters found in an ELF dynamic + * object. + */ +#define MODULE_ELF_CLASS ELFCLASS32 // 32-bit modules +#define MODULE_ELF_CLASS_SIZE 32 // Size of a word value +#define MODULE_ELF_DATA ELFDATA2LSB // Word endianess +#define MODULE_ELF_VERSION EV_CURRENT // Object version +#define MODULE_ELF_TYPE ET_DYN // Executable type (shared object - .so) +#define MODULE_ELF_MACHINE EM_386 // Target architecture + +/** + * Names of symbols with special meaning (treated as special cases at linking) + */ +#define MODULE_ELF_INIT_PTR "__module_init_ptr" // Initialization pointer symbol name +#define MODULE_ELF_EXIT_PTR "__module_exit_ptr" // Finalization pointer symbol name +#define MODULE_ELF_MAIN_PTR "__module_main_ptr" // Entry pointer symbol name + +/** + * modules_head - A global linked list containing all the loaded modules. + */ +extern struct list_head modules_head; + + +/** + * for_each_module - iterator loop through the list of loaded modules. + */ +#define for_each_module(m) list_for_each_entry(m, &modules_head, list) + +/** + * modules_init - initialize the module subsystem. + * + * This function must be called before any module operation is to be performed. + */ +extern int modules_init(void); + + +/** + * modules_term - releases all resources pertaining to the module subsystem. + * + * This function should be called after all module operations. + */ +extern void modules_term(void); + + +/** + * module_alloc - reserves space for a new module descriptor. + * @name: the file name of the module to be loaded. + * + * The function simply allocates a new module descriptor and initializes its fields + * in order to be used by subsequent loading operations. + */ +extern struct elf_module *module_alloc(const char *name); + + +/** + * module_load - loads a regular ELF module into memory. + * @module: the module descriptor returned by module_alloc. + * + * The function reads the module file, checks whether the file has a + * valid structure, then loads into memory the code and the data and performs + * any symbol relocations. A module dependency is created automatically when the + * relocated symbol is defined in a different module. + * + * The function returns 0 if the operation is completed successfully, and + * a non-zero value if an error occurs. Possible errors include invalid module + * structure, missing symbol definitions (unsatisfied dependencies) and memory + * allocation issues. + */ +extern int module_load(struct elf_module *module); + + +/** + * module_load_shallow - loads a shallow ELF module into memory. + * @module: the module descriptor returned by module_alloc. + * + * The function reads the module file, checks whether the file has a valid + * structure, then loads into memory the module metadata. The metadata currently + * contains a symbol table that describes code & data allocated by other means. + * Its current use is to describe the root COM32 module to the rest of the + * module subsystem. + */ +extern int module_load_shallow(struct elf_module *module, Elf32_Addr base_addr); + +/** + * module_unload - unloads the module from the system. + * @module: the module descriptor structure. + * + * The function checks to see whether the module can be safely removed, then + * it releases all the associated memory. This function can be applied both + * for standard modules and for shallow modules. + * + * A module can be safely removed from the system when no other modules reference + * symbols from it. + */ +extern int module_unload(struct elf_module *module); + +/** + * module_unload - unloads the module from the system. + * @module: the module descriptor structure. + * + * This function returns the type of module we're dealing with + * either a library module ( LIB_MODULE ), executable module ( EXEC_MODULE ), + * or an error ( UNKNOWN_MODULE ). The way it checks teh type is by checking to see + * if the module has its main_func set ( in which case it's an executable ). In case + * it doesn't it then checks to see if init_func is set ( in which case it's a + * library module. If this isn't the case either we don't know what it is so bail out + */ +extern int get_module_type(struct elf_module *module); + +/** + * module_unloadable - checks whether the given module can be unloaded. + * @module: the module descriptor structure + * + * A module can be unloaded from the system when no other modules depend on it, + * that is, no symbols are referenced from it. + */ +extern int module_unloadable(struct elf_module *module); + +/** + * module_find - searches for a module by its name. + * @name: the name of the module, as it was specified in module_alloc. + * + * The function returns a pointer to the module descriptor, if found, or + * NULL otherwise. + */ +extern struct elf_module *module_find(const char *name); + +/** + * module_find_symbol - searches for a symbol definition in a given module. + * @name: the name of the symbol to be found. + * @module: the module descriptor structure. + * + * The function searches the module symbol table for a symbol matching exactly + * the name provided. The operation uses the following search algorithms, in this + * order: + * - If a GNU hash table is present in the module, it is used to find the symbol. + * - If the symbol cannot be found with the first method (either the hash table + * is not present or the symbol is not found) and if a regular (SysV) hash table + * is present, a search is performed on the SysV hash table. If the symbol is not + * found, NULL is returned. + * - If the second method cannot be applied, a linear search is performed by + * inspecting every symbol in the symbol table. + * + * If the symbol is found, a pointer to its descriptor structure is returned, and + * NULL otherwise. + */ +extern Elf32_Sym *module_find_symbol(const char *name, struct elf_module *module); + +/** + * global_find_symbol - searches for a symbol definition in the entire module namespace. + * @name: the name of the symbol to be found. + * @module: an optional (may be NULL) pointer to a module descriptor variable that + * will hold the module where the symbol was found. + * + * The function search for the given symbol name in all the modules currently + * loaded in the system, in the reverse module loading order. That is, the most + * recently loaded module is searched first, followed by the previous one, until + * the first loaded module is reached. + * + * If no module contains the symbol, NULL is returned, otherwise the return value is + * a pointer to the symbol descriptor structure. If the module parameter is not NULL, + * it is filled with the address of the module descriptor where the symbol is defined. + */ +extern Elf32_Sym *global_find_symbol(const char *name, struct elf_module **module); + +/** + * module_get_absolute - converts an memory address relative to a module base address + * to its absolute value in RAM. + * @addr: the relative address to convert. + * @module: the module whose base address is used for the conversion. + * + * The function returns a pointer to the absolute memory address. + */ +static inline void *module_get_absolute(Elf32_Addr addr, struct elf_module *module) { + return (void*)(module->base_addr + addr); +} + +/** + * syslinux_current - get the current module process + */ +extern struct elf_module *__syslinux_current; +static inline const struct elf_module *syslinux_current(void) +{ + return __syslinux_current; +} + + +#endif // DYNAMIC_MODULE + +#endif // MODULE_H_ |