Added a source code file date check when reading DWARF information
[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>
009df4d7
JPM
18#include <sys/types.h>
19#include <sys/stat.h>
5fe21518
JPM
20#include "libelf/libelf.h"
21#include "libelf/gelf.h"
cf76e892
JPM
22#include "libdwarf.h"
23#include "log.h"
24#include "ELFManager.h"
25#include "DwarfManager.h"
26
27
4f945aea
JPM
28//#define LOG_SUPPORT // Support log
29
30
cf76e892
JPM
31typedef struct {
32 const char *SectionName;
33 size_t SectionType;
34}ELFSectionType;
35
36typedef 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
47ELFSectionType 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 },
c3b14e59
JPM
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 },
cf76e892 60 { ".debug_aranges", ELF_debug_aranges_TYPE },
c3b14e59 61 { ".debug_frame", ELF_debug_frame_TYPE },
cf76e892 62 { ".debug_info", ELF_debug_info_TYPE },
cf76e892 63 { ".debug_line", ELF_debug_line_TYPE },
cf76e892 64 { ".debug_loc", ELF_debug_loc_TYPE },
c3b14e59
JPM
65 { ".debug_macinfo", ELF_debug_macinfo_TYPE },
66 { ".debug_pubnames", ELF_debug_pubnames_TYPE },
67 { ".debug_pubtypes", ELF_debug_pubtypes_TYPE },
cf76e892 68 { ".debug_ranges", ELF_debug_ranges_TYPE },
c3b14e59
JPM
69 { ".debug_str", ELF_debug_str_TYPE },
70 { ".debug_types", ELF_debug_types_TYPE }
cf76e892
JPM
71};
72
73
74// ELF management
75Elf *ElfMem;
76void *PtrExec; // ELF executable
77
78// ELF Dwarf management
79bool ElfDwarf;
80
81// TAB structure
82size_t NbELFtabStruct;
83ELFTab **ELFtab;
84
85
86char *ELFManager_GetSymbolnameFromSymbolindex(size_t Index);
87
88
89// ELF section type detection
90size_t ELFManager_GetSectionType(char *SectionName)
91{
5fe21518
JPM
92 size_t i;
93
94 for (i = 0; i < ELF_END_TYPE; i++)
cf76e892
JPM
95 {
96 if (!strcmp(ELFTabSectionType[i].SectionName, SectionName))
97 {
98 return (ELFTabSectionType[i].SectionType);
99 }
100 }
101
5fe21518 102 return (size_t)ELF_NO_TYPE;
cf76e892
JPM
103}
104
105
106// ELF manager executable copy
107void *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
118Elf *ELFManager_MemOpen(char *PtrELFExe, size_t Size)
119{
120 return(ElfMem = elf_memory(PtrELFExe, Size));
121}
122
123
124int 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
139void 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
009df4d7 150bool ELFManager_DwarfInit(Elf *PtrElfMem, struct _stat FileElfInfo)
cf76e892 151{
009df4d7 152 return (ElfDwarf = (DWARFManager_ElfInit(PtrElfMem, FileElfInfo) == DW_DLV_OK) ? true : false);
cf76e892
JPM
153}
154
155
156// ELF manager Reset
157void 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
187void ELFManager_Close(void)
188{
189 ELFManager_Reset();
190}
191
192
193// Save the ELF tab in memory
194bool 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
227size_t ELFManager_GetAdrFromSymbolName(char *SymbolName)
228{
229 size_t Adr = 0;
230 GElf_Sym *PtrST, ST;
231
a4e46c05 232 if (ELFtab && SymbolName)
cf76e892
JPM
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
4f945aea
JPM
255// Get function name from his address
256// Return NULL if function name is not found
257char *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
cf76e892
JPM
288// Get Symbol name from his address
289// Return NULL if Symbol name is not found
290char *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 {
4f945aea 307#ifdef LOG_SUPPORT
cf76e892 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);
4f945aea 309#endif
cf76e892
JPM
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
322char *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}