4 * Created on: Aug 11, 2008
5 * Author: Stefan Bucur <stefanb@zytor.com>
10 #include <sys/module.h>
16 static int check_header_shallow(Elf32_Ehdr
*elf_hdr
) {
19 res
= check_header_common(elf_hdr
);
24 if (elf_hdr
->e_shoff
== 0x00000000) {
25 DBG_PRINT("SHT missing\n");
32 static int load_shallow_sections(struct elf_module
*module
, Elf32_Ehdr
*elf_hdr
) {
38 Elf32_Off buff_offset
;
40 Elf32_Off min_offset
= 0xFFFFFFFF;
41 Elf32_Off max_offset
= 0x00000000;
42 Elf32_Word max_align
= 0x1;
44 Elf32_Off sym_offset
= 0xFFFFFFFF;
45 Elf32_Off str_offset
= 0xFFFFFFFF;
50 // We buffer the data up to the SHT
51 buff_offset
= module
->u
.l
._cr_offset
;
53 buffer
= malloc(elf_hdr
->e_shoff
- buff_offset
);
55 image_read(buffer
, elf_hdr
->e_shoff
- buff_offset
, module
);
58 sht
= malloc(elf_hdr
->e_shnum
* elf_hdr
->e_shentsize
);
59 image_read(sht
, elf_hdr
->e_shnum
* elf_hdr
->e_shentsize
, module
);
61 // Get the string table of the section names
62 crt_sht
= (Elf32_Shdr
*)(sht
+ elf_hdr
->e_shstrndx
* elf_hdr
->e_shentsize
);
63 sh_strtable
= (char*)(buffer
+ (crt_sht
->sh_offset
- buff_offset
));
65 for (i
= 0; i
< elf_hdr
->e_shnum
; i
++) {
66 crt_sht
= (Elf32_Shdr
*)(sht
+ i
*elf_hdr
->e_shentsize
);
68 if (strcmp(".symtab", sh_strtable
+ crt_sht
->sh_name
) == 0) {
69 // We found the symbol table
70 min_offset
= MIN(min_offset
, crt_sht
->sh_offset
);
71 max_offset
= MAX(max_offset
, crt_sht
->sh_offset
+ crt_sht
->sh_size
);
72 max_align
= MAX(max_align
, crt_sht
->sh_addralign
);
74 sym_offset
= crt_sht
->sh_offset
;
76 module
->syment_size
= crt_sht
->sh_entsize
;
77 module
->symtable_size
= crt_sht
->sh_size
/ crt_sht
->sh_entsize
;
79 if (strcmp(".strtab", sh_strtable
+ crt_sht
->sh_name
) == 0) {
80 // We found the string table
81 min_offset
= MIN(min_offset
, crt_sht
->sh_offset
);
82 max_offset
= MAX(max_offset
, crt_sht
->sh_offset
+ crt_sht
->sh_size
);
83 max_align
= MAX(max_align
, crt_sht
->sh_addralign
);
85 str_offset
= crt_sht
->sh_offset
;
87 module
->strtable_size
= crt_sht
->sh_size
;
91 if (elf_malloc(&module
->module_addr
, max_align
,
92 max_offset
- min_offset
) != 0) {
93 DBG_PRINT("Could not allocate sections\n");
98 image_seek(min_offset
, module
);
99 image_read(module
->module_addr
, max_offset
- min_offset
, module
);
101 // Setup module information
102 module
->module_size
= max_offset
- min_offset
;
103 module
->str_table
= (char *)module
->module_addr
+ (str_offset
- min_offset
);
104 module
->sym_table
= (char *)module
->module_addr
+ (sym_offset
- min_offset
);
111 // Release the buffer
119 int module_load_shallow(struct elf_module
*module
, Elf32_Addr base_addr
) {
123 // Do not allow duplicate modules
124 if (module_find(module
->name
) != NULL
) {
125 DBG_PRINT("Module already loaded.\n");
129 res
= image_load(module
);
136 CHECKED(res
, image_read(&elf_hdr
, sizeof(Elf32_Ehdr
), module
), error
);
138 // Checking the header signature and members
139 CHECKED(res
, check_header_shallow(&elf_hdr
), error
);
141 CHECKED(res
, load_shallow_sections(module
, &elf_hdr
), error
);
142 module
->base_addr
= base_addr
;
144 // Check the symbols for duplicates / missing definitions
145 CHECKED(res
, check_symbols(module
), error
);
147 // Add the module at the beginning of the module list
148 list_add(&module
->list
, &modules_head
);
150 // The file image is no longer needed
151 image_unload(module
);
153 DBG_PRINT("SHALLOW MODULE %s LOADED SUCCESSFULLY\n", module
->name
);
158 image_unload(module
);