4 * Created on: Aug 11, 2008
5 * Author: Stefan Bucur <stefanb@zytor.com>
16 #include <linux/list.h>
17 #include <sys/module.h>
23 static int check_header(Elf_Ehdr
*elf_hdr
) {
26 res
= check_header_common(elf_hdr
);
31 if (elf_hdr
->e_type
!= MODULE_ELF_TYPE
) {
32 DBG_PRINT("The ELF file must be a shared object\n");
36 if (elf_hdr
->e_phoff
== 0x00000000) {
37 DBG_PRINT("PHT missing\n");
46 * The implementation assumes that the loadable segments are present
47 * in the PHT sorted by their offsets, so that only forward seeks would
50 extern int load_segments(struct elf_module
*module
, Elf_Ehdr
*elf_hdr
);
52 static int prepare_dynlinking(struct elf_module
*module
) {
53 Elf_Dyn
*dyn_entry
= module
->dyn_table
;
55 while (dyn_entry
->d_tag
!= DT_NULL
) {
56 switch (dyn_entry
->d_tag
) {
59 * It's unlikely there'll be more than
60 * MAX_NR_DEPS DT_NEEDED entries but if there
61 * are then inform the user that we ran out of
64 if (module
->nr_needed
< MAX_NR_DEPS
)
65 module
->needed
[module
->nr_needed
++] = dyn_entry
->d_un
.d_ptr
;
67 printf("Too many dependencies!\n");
73 (Elf_Word
*)module_get_absolute(dyn_entry
->d_un
.d_ptr
, module
);
77 (Elf_Word
*)module_get_absolute(dyn_entry
->d_un
.d_ptr
, module
);
81 (char*)module_get_absolute(dyn_entry
->d_un
.d_ptr
, module
);
85 module_get_absolute(dyn_entry
->d_un
.d_ptr
, module
);
88 module
->strtable_size
= dyn_entry
->d_un
.d_val
;
91 module
->syment_size
= dyn_entry
->d_un
.d_val
;
93 case DT_PLTGOT
: // The first entry in the GOT
94 module
->got
= module_get_absolute(dyn_entry
->d_un
.d_ptr
, module
);
104 void undefined_symbol(void)
106 printf("Error: An undefined symbol was referenced\n");
110 extern int perform_relocation(struct elf_module
*module
, Elf_Rel
*rel
);
111 extern int resolve_symbols(struct elf_module
*module
);
113 static int extract_operations(struct elf_module
*module
) {
114 Elf_Sym
*ctors_start
, *ctors_end
;
115 Elf_Sym
*dtors_start
, *dtors_end
;
116 module_ctor_t
*ctors
= NULL
;
117 module_ctor_t
*dtors
= NULL
;
119 ctors_start
= module_find_symbol("__ctors_start", module
);
120 ctors_end
= module_find_symbol("__ctors_end", module
);
122 if (ctors_start
&& ctors_end
) {
123 module_ctor_t
*start
, *end
;
127 start
= module_get_absolute(ctors_start
->st_value
, module
);
128 end
= module_get_absolute(ctors_end
->st_value
, module
);
130 nr_ctors
= end
- start
;
132 size
= nr_ctors
* sizeof(module_ctor_t
);
133 size
+= sizeof(module_ctor_t
); /* NULL entry */
135 ctors
= malloc(size
);
137 printf("Unable to alloc memory for ctors\n");
141 memset(ctors
, 0, size
);
142 for (i
= 0; i
< nr_ctors
; i
++)
145 module
->ctors
= ctors
;
148 dtors_start
= module_find_symbol("__dtors_start", module
);
149 dtors_end
= module_find_symbol("__dtors_end", module
);
151 if (dtors_start
&& dtors_end
) {
152 module_ctor_t
*start
, *end
;
156 start
= module_get_absolute(dtors_start
->st_value
, module
);
157 end
= module_get_absolute(dtors_end
->st_value
, module
);
159 nr_dtors
= end
- start
;
161 size
= nr_dtors
* sizeof(module_ctor_t
);
162 size
+= sizeof(module_ctor_t
); /* NULL entry */
164 dtors
= malloc(size
);
166 printf("Unable to alloc memory for dtors\n");
171 memset(dtors
, 0, size
);
172 for (i
= 0; i
< nr_dtors
; i
++)
175 module
->dtors
= dtors
;
181 // Loads the module into the system
182 int module_load(struct elf_module
*module
) {
187 struct elf_module
*head
= NULL
;
189 // Do not allow duplicate modules
190 if (module_find(module
->name
) != NULL
) {
191 DBG_PRINT("Module %s is already loaded.\n", module
->name
);
195 // Get a mapping/copy of the ELF file in memory
196 res
= image_load(module
);
202 // The module is a fully featured dynamic library
205 CHECKED(res
, image_read(&elf_hdr
, sizeof(Elf_Ehdr
), module
), error
);
206 //printf("check... 1\n");
208 //print_elf_ehdr(&elf_hdr);
210 // Checking the header signature and members
211 CHECKED(res
, check_header(&elf_hdr
), error
);
212 //printf("check... 2\n");
214 // Load the segments in the memory
215 CHECKED(res
, load_segments(module
, &elf_hdr
), error
);
216 //printf("bleah... 3\n");
217 // Obtain dynamic linking information
218 CHECKED(res
, prepare_dynlinking(module
), error
);
219 //printf("check... 4\n");
221 head
= module_current();
223 /* Find modules we need to load as dependencies */
224 if (module
->str_table
) {
228 * Note that we have to load the dependencies in
231 for (i
= module
->nr_needed
- 1; i
>= 0; i
--) {
233 char *argv
[2] = { NULL
, NULL
};
235 dep
= module
->str_table
+ module
->needed
[i
];
237 /* strip everything but the last component */
241 if (strchr(dep
, '/')) {
242 p
= strrchr(dep
, '/');
248 res
= spawn_load(p
, 1, argv
);
250 printf("Failed to load %s\n", p
);
256 // Check the symbols for duplicates / missing definitions
257 CHECKED(res
, check_symbols(module
), error
);
258 //printf("check... 5\n");
260 main_sym
= module_find_symbol("main", module
);
263 module_get_absolute(main_sym
->st_value
, module
);
265 //printf("check... 6\n");
267 // Add the module at the beginning of the module list
268 list_add(&module
->list
, &modules_head
);
270 // Perform the relocations
271 resolve_symbols(module
);
273 // Obtain constructors and destructors
274 CHECKED(res
, extract_operations(module
), error
);
276 //dprintf("module->symtable_size = %d\n", module->symtable_size);
278 //print_elf_symbols(module);
280 // The file image is no longer needed
281 image_unload(module
);
284 DBG_PRINT("MODULE %s LOADED SUCCESSFULLY (main@%p, init@%p, exit@%p)\n",
286 (module->main_func == NULL) ? NULL : *(module->main_func),
287 (module->init_func == NULL) ? NULL : *(module->init_func),
288 (module->exit_func == NULL) ? NULL : *(module->exit_func));
291 for (ctor
= module
->ctors
; ctor
&& *ctor
; ctor
++)
298 unload_modules_since(head
->name
);
300 // Remove the module from the module list (if applicable)
301 list_del_init(&module
->list
);
303 if (module
->module_addr
!= NULL
) {
304 elf_free(module
->module_addr
);
305 module
->module_addr
= NULL
;
308 image_unload(module
);
310 // Clear the execution part of the module buffer
311 memset(&module
->u
, 0, sizeof module
->u
);