362465383f2be60ce193a2aac8ee000ea556139e
[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 Jan./2016 Created this file and added ELF format support
11 // JPM 07/13/2017 ELF DWARF format support improvement
12 // JPM 10/20/2018 Added function name support from ELF structure
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 //#define LOG_SUPPORT // Support log
26
27
28 typedef struct {
29 const char *SectionName;
30 size_t SectionType;
31 }ELFSectionType;
32
33 typedef struct {
34 size_t Type;
35 size_t Size;
36 union {
37 Elf_Data *PtrDataTab;
38 void *PtrTab;
39 };
40 }ELFTab;
41
42
43 // Section type list
44 ELFSectionType ELFTabSectionType[] = {
45 { "", ELF_NULL_TYPE },
46 { ".text", ELF_text_TYPE },
47 { ".rodata", ELF_rodata_TYPE },
48 { ".data", ELF_data_TYPE },
49 { ".bss", ELF_bss_TYPE },
50 { ".heap", ELF_heap_TYPE },
51 { ".debug_aranges", ELF_debug_aranges_TYPE },
52 { ".debug_info", ELF_debug_info_TYPE },
53 { ".debug_abbrev", ELF_debug_abbrev_TYPE },
54 { ".debug_line", ELF_debug_line_TYPE },
55 { ".debug_frame", ELF_debug_frame_TYPE },
56 { ".debug_str", ELF_debug_str_TYPE },
57 { ".debug_loc", ELF_debug_loc_TYPE },
58 { ".debug_ranges", ELF_debug_ranges_TYPE },
59 { ".comment", ELF_comment_TYPE },
60 { ".shstrtab", ELF_shstrtab_TYPE },
61 { ".symtab", ELF_symtab_TYPE },
62 { ".strtab", ELF_strtab_TYPE }
63 };
64
65
66 // ELF management
67 Elf *ElfMem;
68 void *PtrExec; // ELF executable
69
70 // ELF Dwarf management
71 bool ElfDwarf;
72
73 // TAB structure
74 size_t NbELFtabStruct;
75 ELFTab **ELFtab;
76
77
78 char *ELFManager_GetSymbolnameFromSymbolindex(size_t Index);
79
80
81 // ELF section type detection
82 size_t ELFManager_GetSectionType(char *SectionName)
83 {
84 size_t i;
85
86 for (i = 0; i < ELF_END_TYPE; i++)
87 {
88 if (!strcmp(ELFTabSectionType[i].SectionName, SectionName))
89 {
90 return (ELFTabSectionType[i].SectionType);
91 }
92 }
93
94 return (size_t)ELF_NO_TYPE;
95 }
96
97
98 // ELF manager executable copy
99 void *ELFManager_ExeCopy(void *src, size_t size)
100 {
101 if ((PtrExec = malloc(size)) != NULL)
102 {
103 memcpy(PtrExec, src, size);
104 }
105
106 return PtrExec;
107 }
108
109
110 Elf *ELFManager_MemOpen(char *PtrELFExe, size_t Size)
111 {
112 return(ElfMem = elf_memory(PtrELFExe, Size));
113 }
114
115
116 int ELFManager_MemEnd(void)
117 {
118 int err = 0;
119
120 if (ElfMem)
121 {
122 err = elf_end(ElfMem);
123 ElfMem = NULL;
124 }
125
126 return (err);
127 }
128
129
130 // ELF manager Initialisation
131 void ELFManager_Init(void)
132 {
133 PtrExec = NULL;
134 NbELFtabStruct = 0;
135 ELFtab = NULL;
136 ElfMem = NULL;
137 ElfDwarf = false;
138 }
139
140
141 // ELF manager Dwarf Initialisation
142 bool ELFManager_DwarfInit(Elf *PtrElfMem)
143 {
144 return (ElfDwarf = (DWARFManager_ElfInit(PtrElfMem) == DW_DLV_OK) ? true : false);
145 }
146
147
148 // ELF manager Reset
149 void ELFManager_Reset(void)
150 {
151 if (ElfDwarf)
152 {
153 DWARFManager_Reset();
154 ElfDwarf = false;
155 }
156
157 if (PtrExec != NULL)
158 {
159 free(PtrExec);
160 PtrExec = NULL;
161 }
162
163 if (ELFtab != NULL)
164 {
165 while (NbELFtabStruct)
166 {
167 free(ELFtab[--NbELFtabStruct]);
168 }
169
170 free(ELFtab);
171 ELFtab = NULL;
172 }
173
174 ELFManager_MemEnd();
175 }
176
177
178 // ELF manager Closing
179 void ELFManager_Close(void)
180 {
181 ELFManager_Reset();
182 }
183
184
185 // Save the ELF tab in memory
186 bool ELFManager_AddTab(void *Ptr, size_t type)
187 {
188 if (!NbELFtabStruct)
189 {
190 if ((ELFtab = (ELFTab **)calloc(1, sizeof(ELFTab *))) == NULL)
191 {
192 return false;
193 }
194 }
195 else
196 {
197 if ((ELFtab = (ELFTab **)realloc(ELFtab, sizeof(ELFTab *)*(NbELFtabStruct+1))) == NULL)
198 {
199 return false;
200 }
201 }
202
203 if ((ELFtab[NbELFtabStruct] = (ELFTab *)calloc(1, sizeof(ELFTab))) == NULL)
204 {
205 return false;
206 }
207 else
208 {
209 ELFtab[NbELFtabStruct]->Type = type;
210 ELFtab[NbELFtabStruct]->PtrTab = Ptr;
211 NbELFtabStruct++;
212 return true;
213 }
214 }
215
216
217 // Get Address from his Symbol Name
218 // Return 0 if Symbol name is not found
219 size_t ELFManager_GetAdrFromSymbolName(char *SymbolName)
220 {
221 size_t Adr = 0;
222 GElf_Sym *PtrST, ST;
223
224 if (ELFtab && SymbolName)
225 {
226 for (size_t i = 0; i < NbELFtabStruct; i++)
227 {
228 if ((ELFtab[i]->Type == ELF_symtab_TYPE) && ((ELFtab[i]->PtrDataTab) != NULL))
229 {
230 int j = 0;
231
232 while ((PtrST = gelf_getsym(ELFtab[i]->PtrDataTab, j++, &ST)) != NULL)
233 {
234 if (!strcmp(ELFManager_GetSymbolnameFromSymbolindex(PtrST->st_name), SymbolName))
235 {
236 Adr = PtrST->st_value;
237 }
238 }
239 }
240 }
241 }
242
243 return Adr;
244 }
245
246
247 // Get function name from his address
248 // Return NULL if function name is not found
249 char *ELFManager_GetFunctionName(size_t Adr)
250 {
251 char *SymbolName = NULL;
252 GElf_Sym *PtrST, ST;
253
254 if (ELFtab != NULL)
255 {
256 for (size_t i = 0; i < NbELFtabStruct; i++)
257 {
258 if ((ELFtab[i]->Type == ELF_symtab_TYPE) && ((ELFtab[i]->PtrDataTab) != NULL))
259 {
260 int j = 0;
261
262 while ((PtrST = gelf_getsym(ELFtab[i]->PtrDataTab, j++, &ST)) != NULL)
263 {
264 if (PtrST->st_value == Adr)
265 {
266 if (ELF32_ST_TYPE(PtrST->st_info) == STT_FUNC)
267 {
268 SymbolName = ELFManager_GetSymbolnameFromSymbolindex(PtrST->st_name);
269 }
270 }
271 }
272 }
273 }
274 }
275
276 return SymbolName;
277 }
278
279
280 // Get Symbol name from his address
281 // Return NULL if Symbol name is not found
282 char *ELFManager_GetSymbolnameFromAdr(size_t Adr)
283 {
284 char *SymbolName = NULL;
285 GElf_Sym *PtrST, ST;
286
287 if (ELFtab != NULL)
288 {
289 for (size_t i = 0; i < NbELFtabStruct; i++)
290 {
291 if ((ELFtab[i]->Type == ELF_symtab_TYPE) && ((ELFtab[i]->PtrDataTab) != NULL))
292 {
293 int j = 0;
294
295 while ((PtrST = gelf_getsym(ELFtab[i]->PtrDataTab, j++, &ST)) != NULL)
296 {
297 if (PtrST->st_value == Adr)
298 {
299 #ifdef LOG_SUPPORT
300 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);
301 #endif
302 SymbolName = ELFManager_GetSymbolnameFromSymbolindex(PtrST->st_name);
303 }
304 }
305 }
306 }
307 }
308
309 return SymbolName;
310 }
311
312
313 // Get Symbol name from his Symbol index
314 char *ELFManager_GetSymbolnameFromSymbolindex(size_t Index)
315 {
316 if (ELFtab != NULL)
317 {
318 for (size_t i = 0; i < NbELFtabStruct; i++)
319 {
320 if ((ELFtab[i]->Type == ELF_strtab_TYPE) && ((ELFtab[i]->PtrDataTab) != NULL))
321 {
322 return ((char *)(ELFtab[i]->PtrDataTab->d_buf) + Index);
323 }
324 }
325 }
326
327 return NULL;
328 }