Added ELF & DWARF .debug* types
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / ELFManager.cpp
CommitLineData
cf76e892
JPM
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// --- ---------- ------------------------------------------------------------
4f945aea
JPM
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
c3b14e59 13// JPM 03/13/2020 Added ELF & DWARF .debug* types
cf76e892
JPM
14//
15
16#include <stdlib.h>
17#include <string.h>
5fe21518
JPM
18#include "libelf/libelf.h"
19#include "libelf/gelf.h"
cf76e892
JPM
20#include "libdwarf.h"
21#include "log.h"
22#include "ELFManager.h"
23#include "DwarfManager.h"
24
25
4f945aea
JPM
26//#define LOG_SUPPORT // Support log
27
28
cf76e892
JPM
29typedef struct {
30 const char *SectionName;
31 size_t SectionType;
32}ELFSectionType;
33
34typedef 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
45ELFSectionType 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 },
c3b14e59
JPM
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 },
cf76e892 58 { ".debug_aranges", ELF_debug_aranges_TYPE },
c3b14e59 59 { ".debug_frame", ELF_debug_frame_TYPE },
cf76e892 60 { ".debug_info", ELF_debug_info_TYPE },
cf76e892 61 { ".debug_line", ELF_debug_line_TYPE },
cf76e892 62 { ".debug_loc", ELF_debug_loc_TYPE },
c3b14e59
JPM
63 { ".debug_macinfo", ELF_debug_macinfo_TYPE },
64 { ".debug_pubnames", ELF_debug_pubnames_TYPE },
65 { ".debug_pubtypes", ELF_debug_pubtypes_TYPE },
cf76e892 66 { ".debug_ranges", ELF_debug_ranges_TYPE },
c3b14e59
JPM
67 { ".debug_str", ELF_debug_str_TYPE },
68 { ".debug_types", ELF_debug_types_TYPE }
cf76e892
JPM
69};
70
71
72// ELF management
73Elf *ElfMem;
74void *PtrExec; // ELF executable
75
76// ELF Dwarf management
77bool ElfDwarf;
78
79// TAB structure
80size_t NbELFtabStruct;
81ELFTab **ELFtab;
82
83
84char *ELFManager_GetSymbolnameFromSymbolindex(size_t Index);
85
86
87// ELF section type detection
88size_t ELFManager_GetSectionType(char *SectionName)
89{
5fe21518
JPM
90 size_t i;
91
92 for (i = 0; i < ELF_END_TYPE; i++)
cf76e892
JPM
93 {
94 if (!strcmp(ELFTabSectionType[i].SectionName, SectionName))
95 {
96 return (ELFTabSectionType[i].SectionType);
97 }
98 }
99
5fe21518 100 return (size_t)ELF_NO_TYPE;
cf76e892
JPM
101}
102
103
104// ELF manager executable copy
105void *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
116Elf *ELFManager_MemOpen(char *PtrELFExe, size_t Size)
117{
118 return(ElfMem = elf_memory(PtrELFExe, Size));
119}
120
121
122int 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
137void 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
148bool ELFManager_DwarfInit(Elf *PtrElfMem)
149{
150 return (ElfDwarf = (DWARFManager_ElfInit(PtrElfMem) == DW_DLV_OK) ? true : false);
151}
152
153
154// ELF manager Reset
155void 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
185void ELFManager_Close(void)
186{
187 ELFManager_Reset();
188}
189
190
191// Save the ELF tab in memory
192bool 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
225size_t ELFManager_GetAdrFromSymbolName(char *SymbolName)
226{
227 size_t Adr = 0;
228 GElf_Sym *PtrST, ST;
229
a4e46c05 230 if (ELFtab && SymbolName)
cf76e892
JPM
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
4f945aea
JPM
253// Get function name from his address
254// Return NULL if function name is not found
255char *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
cf76e892
JPM
286// Get Symbol name from his address
287// Return NULL if Symbol name is not found
288char *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 {
4f945aea 305#ifdef LOG_SUPPORT
cf76e892 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);
4f945aea 307#endif
cf76e892
JPM
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
320char *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}