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