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