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