Releasing debian version 5.00+dfsg-1.
[syslinux-debian/hramrach.git] / com32 / lib / sys / module / shallow_module.c
blob8a88e40315c11f38c5c05baba77a2bf7ff45e246
1 /*
2 * shallow_module.c
4 * Created on: Aug 11, 2008
5 * Author: Stefan Bucur <stefanb@zytor.com>
6 */
9 #include <string.h>
10 #include <sys/module.h>
12 #include "common.h"
13 #include "elfutils.h"
16 static int check_header_shallow(Elf32_Ehdr *elf_hdr) {
17 int res;
19 res = check_header_common(elf_hdr);
21 if (res != 0)
22 return res;
24 if (elf_hdr->e_shoff == 0x00000000) {
25 DBG_PRINT("SHT missing\n");
26 return -1;
29 return 0;
32 static int load_shallow_sections(struct elf_module *module, Elf32_Ehdr *elf_hdr) {
33 int i;
34 int res = 0;
35 char *sht = NULL;
36 char *buffer = NULL;
37 Elf32_Shdr *crt_sht;
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;
48 char *sh_strtable;
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);
54 // Get to the SHT
55 image_read(buffer, elf_hdr->e_shoff - buff_offset, module);
57 // Load the SHT
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");
94 goto out;
97 // Copy the data
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);
106 out:
107 // Release the SHT
108 if (sht != NULL)
109 free(sht);
111 // Release the buffer
112 if (buffer != NULL)
113 free(buffer);
115 return res;
119 int module_load_shallow(struct elf_module *module, Elf32_Addr base_addr) {
120 int res;
121 Elf32_Ehdr elf_hdr;
123 // Do not allow duplicate modules
124 if (module_find(module->name) != NULL) {
125 DBG_PRINT("Module already loaded.\n");
126 return -1;
129 res = image_load(module);
131 if (res < 0)
132 return res;
134 module->shallow = 1;
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);
155 return 0;
157 error:
158 image_unload(module);
160 return res;