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 char path
[FILENAME_MAX
];
67 f
= fopen(name
, "rb"); /* for full path */
74 while (*p
&& *p
!= ':' && i
< FILENAME_MAX
- 1) {
81 /* Ensure we have a '/' separator */
82 if (path
[i
] != '/' && i
< FILENAME_MAX
- 1)
86 while (*n
&& i
< FILENAME_MAX
- 1)
90 f
= fopen(path
, "rb");
94 if (p
>= PATH
&& p
< PATH
+ strlen(PATH
))
101 * Image files manipulation routines
104 int image_load(struct elf_module
*module
)
106 module
->u
.l
._file
= findpath(module
->name
);
108 if (module
->u
.l
._file
== NULL
) {
109 DBG_PRINT("Could not open object file '%s'\n", module
->name
);
113 module
->u
.l
._cr_offset
= 0;
118 if (module
->u
.l
._file
!= NULL
) {
119 fclose(module
->u
.l
._file
);
120 module
->u
.l
._file
= NULL
;
127 int image_unload(struct elf_module
*module
) {
128 if (module
->u
.l
._file
!= NULL
) {
129 fclose(module
->u
.l
._file
);
130 module
->u
.l
._file
= NULL
;
133 module
->u
.l
._cr_offset
= 0;
138 int image_read(void *buff
, size_t size
, struct elf_module
*module
) {
139 size_t result
= fread(buff
, size
, 1, module
->u
.l
._file
);
144 module
->u
.l
._cr_offset
+= size
;
148 int image_skip(size_t size
, struct elf_module
*module
) {
149 void *skip_buff
= NULL
;
155 skip_buff
= malloc(size
);
156 result
= fread(skip_buff
, size
, 1, module
->u
.l
._file
);
162 module
->u
.l
._cr_offset
+= size
;
166 int image_seek(Elf32_Off offset
, struct elf_module
*module
) {
167 if (offset
< module
->u
.l
._cr_offset
) // Cannot seek backwards
170 return image_skip(offset
- module
->u
.l
._cr_offset
, module
);
174 // Initialization of the module subsystem
175 int modules_init(void) {
179 // Termination of the module subsystem
180 void modules_term(void) {
184 // Allocates the structure for a new module
185 struct elf_module
*module_alloc(const char *name
) {
186 struct elf_module
*result
= malloc(sizeof(struct elf_module
));
189 dprintf("module: Failed to alloc elf_module\n");
193 memset(result
, 0, sizeof(struct elf_module
));
195 INIT_LIST_HEAD(&result
->list
);
196 INIT_LIST_HEAD(&result
->required
);
197 INIT_LIST_HEAD(&result
->dependants
);
199 strncpy(result
->name
, name
, MODULE_NAME_SIZE
);
204 struct module_dep
*module_dep_alloc(struct elf_module
*module
) {
205 struct module_dep
*result
= malloc(sizeof(struct module_dep
));
207 INIT_LIST_HEAD (&result
->list
);
209 result
->module
= module
;
214 struct elf_module
*module_find(const char *name
) {
215 struct elf_module
*cr_module
;
217 for_each_module(cr_module
) {
218 if (strcmp(cr_module
->name
, name
) == 0)
226 // Performs verifications on ELF header to assure that the open file is a
227 // valid SYSLINUX ELF module.
228 int check_header_common(Elf32_Ehdr
*elf_hdr
) {
229 // Check the header magic
230 if (elf_hdr
->e_ident
[EI_MAG0
] != ELFMAG0
||
231 elf_hdr
->e_ident
[EI_MAG1
] != ELFMAG1
||
232 elf_hdr
->e_ident
[EI_MAG2
] != ELFMAG2
||
233 elf_hdr
->e_ident
[EI_MAG3
] != ELFMAG3
) {
235 DBG_PRINT("The file is not an ELF object\n");
239 if (elf_hdr
->e_ident
[EI_CLASS
] != MODULE_ELF_CLASS
) {
240 DBG_PRINT("Invalid ELF class code\n");
244 if (elf_hdr
->e_ident
[EI_DATA
] != MODULE_ELF_DATA
) {
245 DBG_PRINT("Invalid ELF data encoding\n");
249 if (elf_hdr
->e_ident
[EI_VERSION
] != MODULE_ELF_VERSION
||
250 elf_hdr
->e_version
!= MODULE_ELF_VERSION
) {
251 DBG_PRINT("Invalid ELF file version\n");
255 if (elf_hdr
->e_machine
!= MODULE_ELF_MACHINE
) {
256 DBG_PRINT("Invalid ELF architecture\n");
264 int enforce_dependency(struct elf_module
*req
, struct elf_module
*dep
) {
265 struct module_dep
*crt_dep
;
266 struct module_dep
*new_dep
;
268 list_for_each_entry(crt_dep
, &req
->dependants
, list
) {
269 if (crt_dep
->module
== dep
) {
270 // The dependency is already enforced
275 new_dep
= module_dep_alloc(req
);
276 list_add(&new_dep
->list
, &dep
->required
);
278 new_dep
= module_dep_alloc(dep
);
279 list_add(&new_dep
->list
, &req
->dependants
);
284 int clear_dependency(struct elf_module
*req
, struct elf_module
*dep
) {
285 struct module_dep
*crt_dep
= NULL
;
288 list_for_each_entry(crt_dep
, &req
->dependants
, list
) {
289 if (crt_dep
->module
== dep
) {
296 list_del(&crt_dep
->list
);
302 list_for_each_entry(crt_dep
, &dep
->required
, list
) {
303 if (crt_dep
->module
== req
) {
310 list_del(&crt_dep
->list
);
317 int check_symbols(struct elf_module
*module
)
320 Elf32_Sym
*crt_sym
= NULL
, *ref_sym
= NULL
;
322 struct elf_module
*crt_module
;
327 for (i
= 1; i
< module
->symtable_size
/module
->syment_size
; i
++)
329 crt_sym
= symbol_get_entry(module
, i
);
330 crt_name
= module
->str_table
+ crt_sym
->st_name
;
333 weak_count
= (ELF32_ST_BIND(crt_sym
->st_info
) == STB_WEAK
);
335 for_each_module(crt_module
)
337 ref_sym
= module_find_symbol(crt_name
, crt_module
);
339 // If we found a definition for our symbol...
340 if (ref_sym
!= NULL
&& ref_sym
->st_shndx
!= SHN_UNDEF
)
342 switch (ELF32_ST_BIND(ref_sym
->st_info
))
354 if (crt_sym
->st_shndx
== SHN_UNDEF
)
356 // We have an undefined symbol
358 // We use the weak_count to differentiate
359 // between Syslinux-derivative-specific
360 // functions. For example, unload_pxe() is
361 // only provided by PXELINUX, so we mark it as
362 // __weak and replace it with a reference to
363 // undefined_symbol() on SYSLINUX, EXTLINUX,
364 // and ISOLINUX. See perform_relocations().
365 if (strong_count
== 0 && weak_count
== 0)
367 DBG_PRINT("Symbol %s is undefined\n", crt_name
);
368 printf("Undef symbol FAIL: %s\n",crt_name
);
374 if (strong_count
> 0 && ELF32_ST_BIND(ref_sym
->st_info
) == STB_GLOBAL
)
376 // It's not an error - at relocation, the most recent symbol
377 // will be considered
378 DBG_PRINT("Info: Symbol %s is defined more than once\n", crt_name
);
381 //printf("symbol %s laoded from %d\n",crt_name,crt_sym->st_value);
387 int module_unloadable(struct elf_module
*module
) {
388 if (!list_empty(&module
->dependants
))
395 // Unloads the module from the system and releases all the associated memory
396 int _module_unload(struct elf_module
*module
) {
397 struct module_dep
*crt_dep
, *tmp
;
398 // Make sure nobody needs us
399 if (!module_unloadable(module
)) {
400 DBG_PRINT("Module is required by other modules.\n");
404 // Remove any dependency information
405 list_for_each_entry_safe(crt_dep
, tmp
, &module
->required
, list
) {
406 clear_dependency(crt_dep
->module
, module
);
409 // Remove the module from the module list
410 list_del_init(&module
->list
);
412 // Release the loaded segments or sections
413 if (module
->module_addr
!= NULL
) {
414 elf_free(module
->module_addr
);
416 DBG_PRINT("%s MODULE %s UNLOADED\n", module
->shallow
? "SHALLOW" : "",
419 // Release the module structure
425 int module_unload(struct elf_module
*module
) {
428 for (dtor
= module
->dtors
; dtor
&& *dtor
; dtor
++)
431 return _module_unload(module
);
434 struct elf_module
*unload_modules_since(const char *name
) {
435 struct elf_module
*m
, *mod
, *begin
= NULL
;
437 for_each_module(mod
) {
438 if (!strcmp(mod
->name
, name
)) {
447 for_each_module_safe(mod
, m
) {
458 static Elf32_Sym
*module_find_symbol_sysv(const char *name
, struct elf_module
*module
) {
459 unsigned long h
= elf_hash((const unsigned char*)name
);
460 Elf32_Word
*cr_word
= module
->hash_table
;
462 Elf32_Word nbucket
= *cr_word
++;
463 cr_word
++; // Skip nchain
465 Elf32_Word
*bkt
= cr_word
;
466 Elf32_Word
*chn
= cr_word
+ nbucket
;
468 Elf32_Word crt_index
= bkt
[h
% module
->hash_table
[0]];
472 while (crt_index
!= STN_UNDEF
) {
473 crt_sym
= symbol_get_entry(module
, crt_index
);
475 if (strcmp(name
, module
->str_table
+ crt_sym
->st_name
) == 0)
478 crt_index
= chn
[crt_index
];
484 static Elf32_Sym
*module_find_symbol_gnu(const char *name
, struct elf_module
*module
) {
485 unsigned long h
= elf_gnu_hash((const unsigned char*)name
);
487 // Setup code (TODO: Optimize this by computing only once)
488 Elf32_Word
*cr_word
= module
->ghash_table
;
489 Elf32_Word nbucket
= *cr_word
++;
490 Elf32_Word symbias
= *cr_word
++;
491 Elf32_Word bitmask_nwords
= *cr_word
++;
493 if ((bitmask_nwords
& (bitmask_nwords
- 1)) != 0) {
494 DBG_PRINT("Invalid GNU Hash structure\n");
498 Elf32_Word gnu_shift
= *cr_word
++;
500 Elf32_Addr
*gnu_bitmask
= (Elf32_Addr
*)cr_word
;
501 cr_word
+= MODULE_ELF_CLASS_SIZE
/ 32 * bitmask_nwords
;
503 Elf32_Word
*gnu_buckets
= cr_word
;
506 Elf32_Word
*gnu_chain_zero
= cr_word
- symbias
;
509 Elf32_Word bitmask_word
= gnu_bitmask
[(h
/ MODULE_ELF_CLASS_SIZE
) &
510 (bitmask_nwords
- 1)];
512 unsigned int hashbit1
= h
& (MODULE_ELF_CLASS_SIZE
- 1);
513 unsigned int hashbit2
= (h
>> gnu_shift
) & (MODULE_ELF_CLASS_SIZE
- 1);
515 if ((bitmask_word
>> hashbit1
) & (bitmask_word
>> hashbit2
) & 1) {
521 bucket
= gnu_buckets
[rem
];
524 const Elf32_Word
* hasharr
= &gnu_chain_zero
[bucket
];
527 if (((*hasharr
^ h
) >> 1) == 0) {
528 Elf32_Sym
*crt_sym
= symbol_get_entry(module
, (hasharr
- gnu_chain_zero
));
530 if (strcmp(name
, module
->str_table
+ crt_sym
->st_name
) == 0) {
534 } while ((*hasharr
++ & 1u) == 0);
541 static Elf32_Sym
*module_find_symbol_iterate(const char *name
,struct elf_module
*module
)
547 for (i
= 1; i
< module
->symtable_size
/module
->syment_size
; i
++)
549 crt_sym
= symbol_get_entry(module
, i
);
550 if (strcmp(name
, module
->str_table
+ crt_sym
->st_name
) == 0)
559 Elf32_Sym
*module_find_symbol(const char *name
, struct elf_module
*module
) {
560 Elf32_Sym
*result
= NULL
;
562 if (module
->ghash_table
!= NULL
)
563 result
= module_find_symbol_gnu(name
, module
);
567 if (module
->hash_table
!= NULL
)
569 //printf("Attempting SYSV Symbol search\n");
570 result
= module_find_symbol_sysv(name
, module
);
574 //printf("Attempting Iterative Symbol search\n");
575 result
= module_find_symbol_iterate(name
, module
);
582 Elf32_Sym
*global_find_symbol(const char *name
, struct elf_module
**module
) {
583 struct elf_module
*crt_module
;
584 Elf32_Sym
*crt_sym
= NULL
;
585 Elf32_Sym
*result
= NULL
;
587 for_each_module(crt_module
) {
588 crt_sym
= module_find_symbol(name
, crt_module
);
590 if (crt_sym
!= NULL
&& crt_sym
->st_shndx
!= SHN_UNDEF
) {
591 switch (ELF32_ST_BIND(crt_sym
->st_info
)) {
593 if (module
!= NULL
) {
594 *module
= crt_module
;
598 // Consider only the first weak symbol
599 if (result
== NULL
) {
600 if (module
!= NULL
) {
601 *module
= crt_module
;