4 * Created on: Aug 11, 2008
5 * Author: Stefan Bucur <stefanb@zytor.com>
13 #include <linux/list.h>
14 #include <sys/module.h>
20 * The one and only list of loaded modules
22 LIST_HEAD(modules_head
);
24 // User-space debugging routines
26 void print_elf_ehdr(Elf32_Ehdr
*ehdr
) {
29 fprintf(stderr
, "Identification:\t");
30 for (i
=0; i
< EI_NIDENT
; i
++) {
31 printf("%d ", ehdr
->e_ident
[i
]);
33 fprintf(stderr
, "\n");
34 fprintf(stderr
, "Type:\t\t%u\n", ehdr
->e_type
);
35 fprintf(stderr
, "Machine:\t%u\n", ehdr
->e_machine
);
36 fprintf(stderr
, "Version:\t%u\n", ehdr
->e_version
);
37 fprintf(stderr
, "Entry:\t\t0x%08x\n", ehdr
->e_entry
);
38 fprintf(stderr
, "PHT Offset:\t0x%08x\n", ehdr
->e_phoff
);
39 fprintf(stderr
, "SHT Offset:\t0x%08x\n", ehdr
->e_shoff
);
40 //fprintf(stderr, "Flags:\t\t%u\n", ehdr->e_flags);
41 //fprintf(stderr, "Header size:\t%u (Structure size: %u)\n", ehdr->e_ehsize,sizeof(Elf32_Ehdr));
42 fprintf(stderr
, "phnum: %d shnum: %d\n", ehdr
->e_phnum
,
46 void print_elf_symbols(struct elf_module
*module
) {
50 for (i
= 1; i
< module
->symtable_size
/module
->syment_size
; i
++)
52 crt_sym
= (Elf32_Sym
*)(module
->sym_table
+ i
*module
->syment_size
);
54 fprintf(stderr
,"%s %d\n", module
->str_table
+ crt_sym
->st_name
, crt_sym
->st_value
);
60 FILE *findpath(char *name
)
62 struct path_entry
*entry
;
63 char path
[FILENAME_MAX
];
66 f
= fopen(name
, "rb"); /* for full path */
70 list_for_each_entry(entry
, &PATH
, list
) {
73 /* Ensure we have a '/' separator */
74 if (entry
->str
[strlen(entry
->str
) - 1] != '/')
77 snprintf(path
, sizeof(path
), "%s%s%s",
78 entry
->str
, slash
? "/" : "", name
);
80 f
= fopen(path
, "rb");
89 * Image files manipulation routines
92 int image_load(struct elf_module
*module
)
94 module
->u
.l
._file
= findpath(module
->name
);
96 if (module
->u
.l
._file
== NULL
) {
97 DBG_PRINT("Could not open object file '%s'\n", module
->name
);
101 module
->u
.l
._cr_offset
= 0;
106 if (module
->u
.l
._file
!= NULL
) {
107 fclose(module
->u
.l
._file
);
108 module
->u
.l
._file
= NULL
;
115 int image_unload(struct elf_module
*module
) {
116 if (module
->u
.l
._file
!= NULL
) {
117 fclose(module
->u
.l
._file
);
118 module
->u
.l
._file
= NULL
;
121 module
->u
.l
._cr_offset
= 0;
126 int image_read(void *buff
, size_t size
, struct elf_module
*module
) {
127 size_t result
= fread(buff
, size
, 1, module
->u
.l
._file
);
132 module
->u
.l
._cr_offset
+= size
;
136 int image_skip(size_t size
, struct elf_module
*module
) {
137 void *skip_buff
= NULL
;
143 skip_buff
= malloc(size
);
144 result
= fread(skip_buff
, size
, 1, module
->u
.l
._file
);
150 module
->u
.l
._cr_offset
+= size
;
154 int image_seek(Elf32_Off offset
, struct elf_module
*module
) {
155 if (offset
< module
->u
.l
._cr_offset
) // Cannot seek backwards
158 return image_skip(offset
- module
->u
.l
._cr_offset
, module
);
162 // Initialization of the module subsystem
163 int modules_init(void) {
167 // Termination of the module subsystem
168 void modules_term(void) {
172 // Allocates the structure for a new module
173 struct elf_module
*module_alloc(const char *name
) {
174 struct elf_module
*result
= malloc(sizeof(struct elf_module
));
177 dprintf("module: Failed to alloc elf_module\n");
181 memset(result
, 0, sizeof(struct elf_module
));
183 INIT_LIST_HEAD(&result
->list
);
184 INIT_LIST_HEAD(&result
->required
);
185 INIT_LIST_HEAD(&result
->dependants
);
187 strncpy(result
->name
, name
, MODULE_NAME_SIZE
);
192 struct module_dep
*module_dep_alloc(struct elf_module
*module
) {
193 struct module_dep
*result
= malloc(sizeof(struct module_dep
));
195 INIT_LIST_HEAD (&result
->list
);
197 result
->module
= module
;
202 struct elf_module
*module_find(const char *name
) {
203 struct elf_module
*cr_module
;
205 for_each_module(cr_module
) {
206 if (strcmp(cr_module
->name
, name
) == 0)
214 // Performs verifications on ELF header to assure that the open file is a
215 // valid SYSLINUX ELF module.
216 int check_header_common(Elf32_Ehdr
*elf_hdr
) {
217 // Check the header magic
218 if (elf_hdr
->e_ident
[EI_MAG0
] != ELFMAG0
||
219 elf_hdr
->e_ident
[EI_MAG1
] != ELFMAG1
||
220 elf_hdr
->e_ident
[EI_MAG2
] != ELFMAG2
||
221 elf_hdr
->e_ident
[EI_MAG3
] != ELFMAG3
) {
223 DBG_PRINT("The file is not an ELF object\n");
227 if (elf_hdr
->e_ident
[EI_CLASS
] != MODULE_ELF_CLASS
) {
228 DBG_PRINT("Invalid ELF class code\n");
232 if (elf_hdr
->e_ident
[EI_DATA
] != MODULE_ELF_DATA
) {
233 DBG_PRINT("Invalid ELF data encoding\n");
237 if (elf_hdr
->e_ident
[EI_VERSION
] != MODULE_ELF_VERSION
||
238 elf_hdr
->e_version
!= MODULE_ELF_VERSION
) {
239 DBG_PRINT("Invalid ELF file version\n");
243 if (elf_hdr
->e_machine
!= MODULE_ELF_MACHINE
) {
244 DBG_PRINT("Invalid ELF architecture\n");
252 int enforce_dependency(struct elf_module
*req
, struct elf_module
*dep
) {
253 struct module_dep
*crt_dep
;
254 struct module_dep
*new_dep
;
256 list_for_each_entry(crt_dep
, &req
->dependants
, list
) {
257 if (crt_dep
->module
== dep
) {
258 // The dependency is already enforced
263 new_dep
= module_dep_alloc(req
);
264 list_add(&new_dep
->list
, &dep
->required
);
266 new_dep
= module_dep_alloc(dep
);
267 list_add(&new_dep
->list
, &req
->dependants
);
272 int clear_dependency(struct elf_module
*req
, struct elf_module
*dep
) {
273 struct module_dep
*crt_dep
= NULL
;
276 list_for_each_entry(crt_dep
, &req
->dependants
, list
) {
277 if (crt_dep
->module
== dep
) {
284 list_del(&crt_dep
->list
);
290 list_for_each_entry(crt_dep
, &dep
->required
, list
) {
291 if (crt_dep
->module
== req
) {
298 list_del(&crt_dep
->list
);
305 int check_symbols(struct elf_module
*module
)
308 Elf32_Sym
*crt_sym
= NULL
, *ref_sym
= NULL
;
310 struct elf_module
*crt_module
;
315 for (i
= 1; i
< module
->symtable_size
/module
->syment_size
; i
++)
317 crt_sym
= symbol_get_entry(module
, i
);
318 crt_name
= module
->str_table
+ crt_sym
->st_name
;
321 weak_count
= (ELF32_ST_BIND(crt_sym
->st_info
) == STB_WEAK
);
323 for_each_module(crt_module
)
325 ref_sym
= module_find_symbol(crt_name
, crt_module
);
327 // If we found a definition for our symbol...
328 if (ref_sym
!= NULL
&& ref_sym
->st_shndx
!= SHN_UNDEF
)
330 switch (ELF32_ST_BIND(ref_sym
->st_info
))
342 if (crt_sym
->st_shndx
== SHN_UNDEF
)
344 // We have an undefined symbol
346 // We use the weak_count to differentiate
347 // between Syslinux-derivative-specific
348 // functions. For example, unload_pxe() is
349 // only provided by PXELINUX, so we mark it as
350 // __weak and replace it with a reference to
351 // undefined_symbol() on SYSLINUX, EXTLINUX,
352 // and ISOLINUX. See perform_relocations().
353 if (strong_count
== 0 && weak_count
== 0)
355 DBG_PRINT("Symbol %s is undefined\n", crt_name
);
356 printf("Undef symbol FAIL: %s\n",crt_name
);
362 if (strong_count
> 0 && ELF32_ST_BIND(ref_sym
->st_info
) == STB_GLOBAL
)
364 // It's not an error - at relocation, the most recent symbol
365 // will be considered
366 DBG_PRINT("Info: Symbol %s is defined more than once\n", crt_name
);
369 //printf("symbol %s laoded from %d\n",crt_name,crt_sym->st_value);
375 int module_unloadable(struct elf_module
*module
) {
376 if (!list_empty(&module
->dependants
))
383 // Unloads the module from the system and releases all the associated memory
384 int _module_unload(struct elf_module
*module
) {
385 struct module_dep
*crt_dep
, *tmp
;
386 // Make sure nobody needs us
387 if (!module_unloadable(module
)) {
388 DBG_PRINT("Module is required by other modules.\n");
392 // Remove any dependency information
393 list_for_each_entry_safe(crt_dep
, tmp
, &module
->required
, list
) {
394 clear_dependency(crt_dep
->module
, module
);
397 // Remove the module from the module list
398 list_del_init(&module
->list
);
400 // Release the loaded segments or sections
401 if (module
->module_addr
!= NULL
) {
402 elf_free(module
->module_addr
);
404 DBG_PRINT("%s MODULE %s UNLOADED\n", module
->shallow
? "SHALLOW" : "",
407 // Release the module structure
413 int module_unload(struct elf_module
*module
) {
416 for (dtor
= module
->dtors
; dtor
&& *dtor
; dtor
++)
419 return _module_unload(module
);
422 struct elf_module
*unload_modules_since(const char *name
) {
423 struct elf_module
*m
, *mod
, *begin
= NULL
;
425 for_each_module(mod
) {
426 if (!strcmp(mod
->name
, name
)) {
435 for_each_module_safe(mod
, m
) {
446 static Elf32_Sym
*module_find_symbol_sysv(const char *name
, struct elf_module
*module
) {
447 unsigned long h
= elf_hash((const unsigned char*)name
);
448 Elf32_Word
*cr_word
= module
->hash_table
;
450 Elf32_Word nbucket
= *cr_word
++;
451 cr_word
++; // Skip nchain
453 Elf32_Word
*bkt
= cr_word
;
454 Elf32_Word
*chn
= cr_word
+ nbucket
;
456 Elf32_Word crt_index
= bkt
[h
% module
->hash_table
[0]];
460 while (crt_index
!= STN_UNDEF
) {
461 crt_sym
= symbol_get_entry(module
, crt_index
);
463 if (strcmp(name
, module
->str_table
+ crt_sym
->st_name
) == 0)
466 crt_index
= chn
[crt_index
];
472 static Elf32_Sym
*module_find_symbol_gnu(const char *name
, struct elf_module
*module
) {
473 unsigned long h
= elf_gnu_hash((const unsigned char*)name
);
475 // Setup code (TODO: Optimize this by computing only once)
476 Elf32_Word
*cr_word
= module
->ghash_table
;
477 Elf32_Word nbucket
= *cr_word
++;
478 Elf32_Word symbias
= *cr_word
++;
479 Elf32_Word bitmask_nwords
= *cr_word
++;
481 if ((bitmask_nwords
& (bitmask_nwords
- 1)) != 0) {
482 DBG_PRINT("Invalid GNU Hash structure\n");
486 Elf32_Word gnu_shift
= *cr_word
++;
488 Elf32_Addr
*gnu_bitmask
= (Elf32_Addr
*)cr_word
;
489 cr_word
+= MODULE_ELF_CLASS_SIZE
/ 32 * bitmask_nwords
;
491 Elf32_Word
*gnu_buckets
= cr_word
;
494 Elf32_Word
*gnu_chain_zero
= cr_word
- symbias
;
497 Elf32_Word bitmask_word
= gnu_bitmask
[(h
/ MODULE_ELF_CLASS_SIZE
) &
498 (bitmask_nwords
- 1)];
500 unsigned int hashbit1
= h
& (MODULE_ELF_CLASS_SIZE
- 1);
501 unsigned int hashbit2
= (h
>> gnu_shift
) & (MODULE_ELF_CLASS_SIZE
- 1);
503 if ((bitmask_word
>> hashbit1
) & (bitmask_word
>> hashbit2
) & 1) {
509 bucket
= gnu_buckets
[rem
];
512 const Elf32_Word
* hasharr
= &gnu_chain_zero
[bucket
];
515 if (((*hasharr
^ h
) >> 1) == 0) {
516 Elf32_Sym
*crt_sym
= symbol_get_entry(module
, (hasharr
- gnu_chain_zero
));
518 if (strcmp(name
, module
->str_table
+ crt_sym
->st_name
) == 0) {
522 } while ((*hasharr
++ & 1u) == 0);
529 static Elf32_Sym
*module_find_symbol_iterate(const char *name
,struct elf_module
*module
)
535 for (i
= 1; i
< module
->symtable_size
/module
->syment_size
; i
++)
537 crt_sym
= symbol_get_entry(module
, i
);
538 if (strcmp(name
, module
->str_table
+ crt_sym
->st_name
) == 0)
547 Elf32_Sym
*module_find_symbol(const char *name
, struct elf_module
*module
) {
548 Elf32_Sym
*result
= NULL
;
550 if (module
->ghash_table
!= NULL
)
551 result
= module_find_symbol_gnu(name
, module
);
555 if (module
->hash_table
!= NULL
)
557 //printf("Attempting SYSV Symbol search\n");
558 result
= module_find_symbol_sysv(name
, module
);
562 //printf("Attempting Iterative Symbol search\n");
563 result
= module_find_symbol_iterate(name
, module
);
570 Elf32_Sym
*global_find_symbol(const char *name
, struct elf_module
**module
) {
571 struct elf_module
*crt_module
;
572 Elf32_Sym
*crt_sym
= NULL
;
573 Elf32_Sym
*result
= NULL
;
575 for_each_module(crt_module
) {
576 crt_sym
= module_find_symbol(name
, crt_module
);
578 if (crt_sym
!= NULL
&& crt_sym
->st_shndx
!= SHN_UNDEF
) {
579 switch (ELF32_ST_BIND(crt_sym
->st_info
)) {
581 if (module
!= NULL
) {
582 *module
= crt_module
;
586 // Consider only the first weak symbol
587 if (result
== NULL
) {
588 if (module
!= NULL
) {
589 *module
= crt_module
;