First commit
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / ELFManager.cpp
1 //
2 // ELFManager.cpp: ELF format manager
3 //
4 // by Jean-Paul Mari
5 //
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 //
8 // WHO WHEN WHAT
9 // --- ---------- ------------------------------------------------------------
10 // JPM 12/01/2016 Created this file
11 // JPM 12/01/2016 ELF format support
12 // JPM 13/07/2017 ELF DWARF format support
13 //
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include "libelf\libelf.h"
18 #include "libelf\gelf.h"
19 #include "libdwarf.h"
20 #include "log.h"
21 #include "ELFManager.h"
22 #include "DwarfManager.h"
23
24
25 typedef struct {
26 const char *SectionName;
27 size_t SectionType;
28 }ELFSectionType;
29
30 typedef struct {
31 size_t Type;
32 size_t Size;
33 union {
34 Elf_Data *PtrDataTab;
35 void *PtrTab;
36 };
37 }ELFTab;
38
39
40 // Section type list
41 ELFSectionType ELFTabSectionType[] = {
42 { "", ELF_NULL_TYPE },
43 { ".text", ELF_text_TYPE },
44 { ".rodata", ELF_rodata_TYPE },
45 { ".data", ELF_data_TYPE },
46 { ".bss", ELF_bss_TYPE },
47 { ".heap", ELF_heap_TYPE },
48 { ".debug_aranges", ELF_debug_aranges_TYPE },
49 { ".debug_info", ELF_debug_info_TYPE },
50 { ".debug_abbrev", ELF_debug_abbrev_TYPE },
51 { ".debug_line", ELF_debug_line_TYPE },
52 { ".debug_frame", ELF_debug_frame_TYPE },
53 { ".debug_str", ELF_debug_str_TYPE },
54 { ".debug_loc", ELF_debug_loc_TYPE },
55 { ".debug_ranges", ELF_debug_ranges_TYPE },
56 { ".comment", ELF_comment_TYPE },
57 { ".shstrtab", ELF_shstrtab_TYPE },
58 { ".symtab", ELF_symtab_TYPE },
59 { ".strtab", ELF_strtab_TYPE }
60 };
61
62
63 // ELF management
64 Elf *ElfMem;
65 void *PtrExec; // ELF executable
66
67 // ELF Dwarf management
68 bool ElfDwarf;
69
70 // TAB structure
71 size_t NbELFtabStruct;
72 ELFTab **ELFtab;
73
74
75 char *ELFManager_GetSymbolnameFromSymbolindex(size_t Index);
76
77
78 // ELF section type detection
79 size_t ELFManager_GetSectionType(char *SectionName)
80 {
81 for (int i = 0; i < ELF_END_TYPE; i++)
82 {
83 if (!strcmp(ELFTabSectionType[i].SectionName, SectionName))
84 {
85 return (ELFTabSectionType[i].SectionType);
86 }
87 }
88
89 return ELF_NO_TYPE;
90 }
91
92
93 // ELF manager executable copy
94 void *ELFManager_ExeCopy(void *src, size_t size)
95 {
96 if ((PtrExec = malloc(size)) != NULL)
97 {
98 memcpy(PtrExec, src, size);
99 }
100
101 return PtrExec;
102 }
103
104
105 Elf *ELFManager_MemOpen(char *PtrELFExe, size_t Size)
106 {
107 return(ElfMem = elf_memory(PtrELFExe, Size));
108 }
109
110
111 int ELFManager_MemEnd(void)
112 {
113 int err = 0;
114
115 if (ElfMem)
116 {
117 err = elf_end(ElfMem);
118 ElfMem = NULL;
119 }
120
121 return (err);
122 }
123
124
125 // ELF manager Initialisation
126 void ELFManager_Init(void)
127 {
128 PtrExec = NULL;
129 NbELFtabStruct = 0;
130 ELFtab = NULL;
131 ElfMem = NULL;
132 ElfDwarf = false;
133 }
134
135
136 // ELF manager Dwarf Initialisation
137 bool ELFManager_DwarfInit(Elf *PtrElfMem)
138 {
139 return (ElfDwarf = (DWARFManager_ElfInit(PtrElfMem) == DW_DLV_OK) ? true : false);
140 }
141
142
143 // ELF manager Reset
144 void ELFManager_Reset(void)
145 {
146 if (ElfDwarf)
147 {
148 DWARFManager_Reset();
149 ElfDwarf = false;
150 }
151
152 if (PtrExec != NULL)
153 {
154 free(PtrExec);
155 PtrExec = NULL;
156 }
157
158 if (ELFtab != NULL)
159 {
160 while (NbELFtabStruct)
161 {
162 free(ELFtab[--NbELFtabStruct]);
163 }
164
165 free(ELFtab);
166 ELFtab = NULL;
167 }
168
169 ELFManager_MemEnd();
170 }
171
172
173 // ELF manager Closing
174 void ELFManager_Close(void)
175 {
176 ELFManager_Reset();
177 }
178
179
180 // Save the ELF tab in memory
181 bool ELFManager_AddTab(void *Ptr, size_t type)
182 {
183 if (!NbELFtabStruct)
184 {
185 if ((ELFtab = (ELFTab **)calloc(1, sizeof(ELFTab *))) == NULL)
186 {
187 return false;
188 }
189 }
190 else
191 {
192 if ((ELFtab = (ELFTab **)realloc(ELFtab, sizeof(ELFTab *)*(NbELFtabStruct+1))) == NULL)
193 {
194 return false;
195 }
196 }
197
198 if ((ELFtab[NbELFtabStruct] = (ELFTab *)calloc(1, sizeof(ELFTab))) == NULL)
199 {
200 return false;
201 }
202 else
203 {
204 ELFtab[NbELFtabStruct]->Type = type;
205 ELFtab[NbELFtabStruct]->PtrTab = Ptr;
206 NbELFtabStruct++;
207 return true;
208 }
209 }
210
211
212 // Get Address from his Symbol Name
213 // Return 0 if Symbol name is not found
214 size_t ELFManager_GetAdrFromSymbolName(char *SymbolName)
215 {
216 size_t Adr = 0;
217 GElf_Sym *PtrST, ST;
218
219 if (ELFtab != NULL)
220 {
221 for (size_t i = 0; i < NbELFtabStruct; i++)
222 {
223 if ((ELFtab[i]->Type == ELF_symtab_TYPE) && ((ELFtab[i]->PtrDataTab) != NULL))
224 {
225 int j = 0;
226
227 while ((PtrST = gelf_getsym(ELFtab[i]->PtrDataTab, j++, &ST)) != NULL)
228 {
229 if (!strcmp(ELFManager_GetSymbolnameFromSymbolindex(PtrST->st_name), SymbolName))
230 {
231 Adr = PtrST->st_value;
232 }
233 }
234 }
235 }
236 }
237
238 return Adr;
239 }
240
241
242 // Get Symbol name from his address
243 // Return NULL if Symbol name is not found
244 char *ELFManager_GetSymbolnameFromAdr(size_t Adr)
245 {
246 char *SymbolName = NULL;
247 GElf_Sym *PtrST, ST;
248
249 if (ELFtab != NULL)
250 {
251 for (size_t i = 0; i < NbELFtabStruct; i++)
252 {
253 if ((ELFtab[i]->Type == ELF_symtab_TYPE) && ((ELFtab[i]->PtrDataTab) != NULL))
254 {
255 int j = 0;
256
257 while ((PtrST = gelf_getsym(ELFtab[i]->PtrDataTab, j++, &ST)) != NULL)
258 {
259 if (PtrST->st_value == Adr)
260 {
261 WriteLog("ELF: .symtab: DATA: st_info=%0x, st_name=%0x, st_other=%0x, st_shndx=%0x, st_size=%0x, st_value=%0x\n", PtrST->st_info, PtrST->st_name, PtrST->st_other, PtrST->st_shndx, PtrST->st_size, PtrST->st_value);
262 SymbolName = ELFManager_GetSymbolnameFromSymbolindex(PtrST->st_name);
263 }
264 }
265 }
266 }
267 }
268
269 return SymbolName;
270 }
271
272
273 // Get Symbol name from his Symbol index
274 char *ELFManager_GetSymbolnameFromSymbolindex(size_t Index)
275 {
276 if (ELFtab != NULL)
277 {
278 for (size_t i = 0; i < NbELFtabStruct; i++)
279 {
280 if ((ELFtab[i]->Type == ELF_strtab_TYPE) && ((ELFtab[i]->PtrDataTab) != NULL))
281 {
282 return ((char *)(ELFtab[i]->PtrDataTab->d_buf) + Index);
283 }
284 }
285 }
286
287 return NULL;
288 }