1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
/*
* shallow_module.c
*
* Created on: Aug 11, 2008
* Author: Stefan Bucur <stefanb@zytor.com>
*/
#include "common.h"
#include <sys/module.h>
#include <sys/elfutils.h>
static int check_header_shallow(Elf32_Ehdr *elf_hdr) {
int res;
res = check_header_common(elf_hdr);
if (res != 0)
return res;
if (elf_hdr->e_shoff == 0x00000000) {
DBG_PRINT("SHT missing\n");
return -1;
}
return 0;
}
static int load_shallow_sections(struct elf_module *module, Elf32_Ehdr *elf_hdr) {
int i;
int res = 0;
void *sht = NULL;
void *buffer = NULL;
Elf32_Shdr *crt_sht;
Elf32_Off buff_offset;
Elf32_Off min_offset = 0xFFFFFFFF;
Elf32_Off max_offset = 0x00000000;
Elf32_Word max_align = 0x1;
Elf32_Off sym_offset = 0xFFFFFFFF;
Elf32_Off str_offset = 0xFFFFFFFF;
char *sh_strtable;
// We buffer the data up to the SHT
buff_offset = module->_cr_offset;
buffer = malloc(elf_hdr->e_shoff - buff_offset);
// Get to the SHT
image_read(buffer, elf_hdr->e_shoff - buff_offset, module);
// Load the SHT
sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
// Get the string table of the section names
crt_sht = (Elf32_Shdr*)(sht + elf_hdr->e_shstrndx * elf_hdr->e_shentsize);
sh_strtable = (char*)(buffer + (crt_sht->sh_offset - buff_offset));
for (i = 0; i < elf_hdr->e_shnum; i++) {
crt_sht = (Elf32_Shdr*)(sht + i*elf_hdr->e_shentsize);
if (strcmp(".symtab", sh_strtable + crt_sht->sh_name) == 0) {
// We found the symbol table
min_offset = MIN(min_offset, crt_sht->sh_offset);
max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
max_align = MAX(max_align, crt_sht->sh_addralign);
sym_offset = crt_sht->sh_offset;
module->syment_size = crt_sht->sh_entsize;
module->symtable_size = crt_sht->sh_size / crt_sht->sh_entsize;
}
if (strcmp(".strtab", sh_strtable + crt_sht->sh_name) == 0) {
// We found the string table
min_offset = MIN(min_offset, crt_sht->sh_offset);
max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
max_align = MAX(max_align, crt_sht->sh_addralign);
str_offset = crt_sht->sh_offset;
module->strtable_size = crt_sht->sh_size;
}
}
if (elf_malloc(&module->module_addr, max_align,
max_offset - min_offset) != 0) {
DBG_PRINT("Could not allocate sections\n");
goto out;
}
// Copy the data
image_seek(min_offset, module);
image_read(module->module_addr, max_offset - min_offset, module);
// Setup module information
module->module_size = max_offset - min_offset;
module->str_table = (char*)(module->module_addr + (str_offset - min_offset));
module->sym_table = module->module_addr + (sym_offset - min_offset);
out:
// Release the SHT
if (sht != NULL)
free(sht);
// Release the buffer
if (buffer != NULL)
free(buffer);
return res;
}
int module_load_shallow(struct elf_module *module) {
int res;
Elf32_Ehdr elf_hdr;
// Do not allow duplicate modules
if (module_find(module->name) != NULL) {
DBG_PRINT("Module already loaded.\n");
return -1;
}
res = image_load(module);
if (res < 0)
return res;
module->shallow = 1;
CHECKED(res, image_read(&elf_hdr, sizeof(Elf32_Ehdr), module), error);
// Checking the header signature and members
CHECKED(res, check_header_shallow(&elf_hdr), error);
CHECKED(res, load_shallow_sections(module, &elf_hdr), error);
// Check the symbols for duplicates / missing definitions
CHECKED(res, check_symbols(module), error);
// Add the module at the beginning of the module list
list_add(&module->list, &modules);
// The file image is no longer needed
image_unload(module);
DBG_PRINT("SHALLOW MODULE %s LOADED SUCCESSFULLY\n", module->name);
return 0;
error:
image_unload(module);
return res;
}
|