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