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