core: Fix libdwarf and Qt build failure
[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>
c4fe5864 7// RG = Richard Goedeken
cf76e892
JPM
8//
9// WHO WHEN WHAT
10// --- ---------- ------------------------------------------------------------
4f945aea
JPM
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
c3b14e59 14// JPM 03/13/2020 Added ELF & DWARF .debug* types
c4fe5864 15// RG Jan./2021 Linux build fixes
cf76e892
JPM
16//
17
18#include <stdlib.h>
19#include <string.h>
009df4d7
JPM
20#include <sys/types.h>
21#include <sys/stat.h>
c89f8ff7
RG
22#include "libelf.h"
23#include "gelf.h"
cf76e892
JPM
24#include "libdwarf.h"
25#include "log.h"
26#include "ELFManager.h"
c89f8ff7 27#include "DWARFManager.h"
cf76e892
JPM
28
29
4f945aea
JPM
30//#define LOG_SUPPORT // Support log
31
32
cf76e892
JPM
33typedef struct {
34 const char *SectionName;
35 size_t SectionType;
36}ELFSectionType;
37
38typedef 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
49ELFSectionType 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 },
c3b14e59
JPM
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 },
cf76e892 62 { ".debug_aranges", ELF_debug_aranges_TYPE },
c3b14e59 63 { ".debug_frame", ELF_debug_frame_TYPE },
cf76e892 64 { ".debug_info", ELF_debug_info_TYPE },
cf76e892 65 { ".debug_line", ELF_debug_line_TYPE },
cf76e892 66 { ".debug_loc", ELF_debug_loc_TYPE },
c3b14e59
JPM
67 { ".debug_macinfo", ELF_debug_macinfo_TYPE },
68 { ".debug_pubnames", ELF_debug_pubnames_TYPE },
69 { ".debug_pubtypes", ELF_debug_pubtypes_TYPE },
cf76e892 70 { ".debug_ranges", ELF_debug_ranges_TYPE },
c3b14e59
JPM
71 { ".debug_str", ELF_debug_str_TYPE },
72 { ".debug_types", ELF_debug_types_TYPE }
cf76e892
JPM
73};
74
75
76// ELF management
77Elf *ElfMem;
78void *PtrExec; // ELF executable
79
80// ELF Dwarf management
81bool ElfDwarf;
82
83// TAB structure
84size_t NbELFtabStruct;
85ELFTab **ELFtab;
86
87
88char *ELFManager_GetSymbolnameFromSymbolindex(size_t Index);
89
90
91// ELF section type detection
92size_t ELFManager_GetSectionType(char *SectionName)
93{
5fe21518
JPM
94 size_t i;
95
96 for (i = 0; i < ELF_END_TYPE; i++)
cf76e892
JPM
97 {
98 if (!strcmp(ELFTabSectionType[i].SectionName, SectionName))
99 {
100 return (ELFTabSectionType[i].SectionType);
101 }
102 }
103
5fe21518 104 return (size_t)ELF_NO_TYPE;
cf76e892
JPM
105}
106
107
108// ELF manager executable copy
109void *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
120Elf *ELFManager_MemOpen(char *PtrELFExe, size_t Size)
121{
122 return(ElfMem = elf_memory(PtrELFExe, Size));
123}
124
125
126int 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
141void 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
c89f8ff7 152bool ELFManager_DwarfInit(Elf *PtrElfMem, struct stat FileElfInfo)
cf76e892 153{
009df4d7 154 return (ElfDwarf = (DWARFManager_ElfInit(PtrElfMem, FileElfInfo) == DW_DLV_OK) ? true : false);
cf76e892
JPM
155}
156
157
158// ELF manager Reset
159void 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
189void ELFManager_Close(void)
190{
191 ELFManager_Reset();
192}
193
194
195// Save the ELF tab in memory
196bool 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
229size_t ELFManager_GetAdrFromSymbolName(char *SymbolName)
230{
231 size_t Adr = 0;
232 GElf_Sym *PtrST, ST;
233
a4e46c05 234 if (ELFtab && SymbolName)
cf76e892
JPM
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
4f945aea
JPM
257// Get function name from his address
258// Return NULL if function name is not found
259char *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
cf76e892
JPM
290// Get Symbol name from his address
291// Return NULL if Symbol name is not found
292char *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 {
4f945aea 309#ifdef LOG_SUPPORT
cf76e892 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);
4f945aea 311#endif
cf76e892
JPM
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
324char *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}