Improved the .heap section detection to avoid a detection error
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DWARFManager.cpp
CommitLineData
ebcb0f3d
JPM
1//\r
2// DWARFManager.cpp: DWARF format manager\r
3//\r
4// by Jean-Paul Mari\r
5//\r
6// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
7//\r
8// WHO WHEN WHAT\r
9// --- ---------- ------------------------------------------------------------\r
10// JPM 12/03/2016 Created this file\r
11// JPM 12/03/2016 DWARF format support\r
12\r
13\r
41d6f5f7
JPM
14#include <stdlib.h>\r
15#include <stdio.h>\r
16#include <stdint.h>\r
17#include <string.h>\r
18#include <libdwarf.h>\r
19#include <dwarf.h>\r
20\r
21\r
22//\r
23//#define DEBUG_NumCU 0x42 // CU number to debug or undefine it\r
ebcb0f3d
JPM
24\r
25\r
26// Source line internal structure\r
27struct DMIStruct_LineSrc\r
28{\r
29 size_t Tag;\r
30 size_t StartPC;\r
31 size_t NumLineSrc;\r
32 char *PtrLineSrc;\r
33}S_DMIStruct_LineSrc;\r
34\r
35// Base type internal structure\r
36struct BaseTypeStruct\r
37{\r
38 size_t Tag; // Type's Tag\r
39 size_t Offset; // Type's offset\r
40 size_t TypeOffset; // Type's offset on another type\r
41 size_t ByteSize; // Type's Byte Size\r
42 size_t Encoding; // Type's encoding\r
43 char *PtrName; // Type's name\r
44}S_BaseTypeStruct;\r
45\r
46// Variables internal structure\r
47struct VariablesStruct\r
48{\r
49 size_t Addr; // Variable memory address\r
50 char *PtrName; // Variable's name\r
51 size_t TypeOffset; // Offset pointing on the Variable's Type\r
52 size_t TypeByteSize; // Variable's Type byte size\r
53 size_t TypeTag; // Variable's Type Tag\r
54 size_t TypeEncoding; // Variable's Type encoding\r
55 char *PtrTypeName; // Variable's Type name\r
56}S_VariablesStruct;\r
57\r
58// Sub program internal structure\r
59struct SubProgStruct\r
60{\r
61 size_t Tag;\r
62 size_t NumLineSrc;\r
63 size_t StartPC;\r
64 size_t LowPC, HighPC;\r
65 char *PtrLineSrc;\r
66 char *PtrSubprogramName;\r
67 size_t NbLinesSrc;\r
68 DMIStruct_LineSrc *PtrLinesSrc;\r
69}S_SubProgStruct;\r
70\r
71// Compilation Unit internal structure\r
72struct CUStruct\r
73{\r
74 size_t Tag;\r
75 size_t LowPC, HighPC;\r
76 char *PtrProducer; // Pointer to the "Producer" information (compiler and compilation options used)\r
77 char *PtrFullFilename; // Pointer to full namefile (directory & filename)\r
78 size_t SizeLoadSrc; // Source code size\r
79 char *PtrLoadSrc; // Pointer to loaded source code\r
80 size_t NbLinesLoadSrc; // Lines source number\r
81 char **PtrLinesLoadSrc; // Pointer lists to each source line put in QT html/text conformity\r
82 size_t NbSubProgs; // Number of sub programs / routines\r
83 SubProgStruct *PtrSubProgs; // Pointer to the sub programs / routines information structure\r
84 size_t NbTypes;\r
85 BaseTypeStruct *PtrTypes;\r
86 size_t NbVariables; // Variables number\r
87 VariablesStruct *PtrVariables; // Pointer to the variables list information structure\r
88}S_CUStruct;\r
89\r
90\r
91// Dwarf management\r
92uint32_t LibDwarf;\r
93uint32_t NbCU;\r
94Dwarf_Ptr errarg;\r
95Dwarf_Error error;\r
96Dwarf_Debug dbg;\r
97CUStruct *PtrCU;\r
98\r
99\r
100//\r
101Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg);\r
102void DWARFManager_InitDMI(void);\r
103void DWARFManager_CloseDMI(void);\r
104bool DWARFManager_ElfClose(void);\r
105char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine);\r
106\r
107\r
108//\r
109Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg)\r
110{\r
111 return 0;\r
112}\r
113\r
114\r
115// Dwarf manager init\r
116void DWARFManager_Init(void)\r
117{\r
118 LibDwarf = DW_DLV_NO_ENTRY;\r
119}\r
120\r
121\r
122// Dwarf manager Reset\r
123bool DWARFManager_Reset(void)\r
124{\r
125 return DWARFManager_ElfClose();\r
126}\r
127\r
128\r
129// Dwarf manager Close\r
130bool DWARFManager_Close(void)\r
131{\r
132 return(DWARFManager_Reset());\r
133}\r
134\r
135\r
136// Dwarf manager Elf init\r
137int DWARFManager_ElfInit(Elf *ElfPtr)\r
138{\r
139 if ((LibDwarf = dwarf_elf_init(ElfPtr, DW_DLC_READ, (Dwarf_Handler)DWARFManager_ErrorHandler, errarg, &dbg, &error)) == DW_DLV_OK)\r
140 {\r
141 DWARFManager_InitDMI();\r
142 }\r
143\r
144 return LibDwarf;\r
145}\r
146\r
147\r
148// Dwarf manager Elf close\r
149bool DWARFManager_ElfClose(void)\r
150{\r
151 if (LibDwarf == DW_DLV_OK)\r
152 {\r
153 DWARFManager_CloseDMI();\r
154\r
155 if (dwarf_finish(dbg, &error) == DW_DLV_OK)\r
156 {\r
157 LibDwarf = DW_DLV_NO_ENTRY;\r
158 return true;\r
159 }\r
160 else\r
161 {\r
162 return false;\r
163 }\r
164 }\r
165 else\r
166 {\r
167 return true;\r
168 }\r
169}\r
170\r
171\r
172// Dwarf manager Compilation Units close\r
173void DWARFManager_CloseDMI(void)\r
174{\r
175 while (NbCU--)\r
176 {\r
177 free(PtrCU[NbCU].PtrFullFilename);\r
178 free(PtrCU[NbCU].PtrLoadSrc);\r
179 free(PtrCU[NbCU].PtrProducer);\r
180\r
181 while (PtrCU[NbCU].NbLinesLoadSrc--)\r
182 {\r
183 free(PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].NbLinesLoadSrc]);\r
184 }\r
185 free(PtrCU[NbCU].PtrLinesLoadSrc);\r
186\r
187 while (PtrCU[NbCU].NbSubProgs--)\r
188 {\r
189 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc);\r
190 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName);\r
191 }\r
192 free(PtrCU[NbCU].PtrSubProgs);\r
193\r
194 while (PtrCU[NbCU].NbTypes--)\r
195 {\r
196 free(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName);\r
197 }\r
198 free(PtrCU[NbCU].PtrTypes);\r
199\r
200 while (PtrCU[NbCU].NbVariables--)\r
201 {\r
202 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);\r
203 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrTypeName);\r
204 }\r
205 free(PtrCU[NbCU].PtrVariables);\r
206 }\r
207\r
208 free(PtrCU);\r
209}\r
210\r
211\r
212// Dwarf manager Compilation Units initialisations\r
213void DWARFManager_InitDMI(void)\r
214{\r
215 Dwarf_Unsigned next_cu_header, return_uvalue;\r
216 Dwarf_Error error;\r
217 Dwarf_Attribute *atlist;\r
218 Dwarf_Attribute return_attr1;\r
219 Dwarf_Half return_tagval, return_attr;\r
220 Dwarf_Addr return_lowpc, return_highpc, return_lineaddr;\r
221 Dwarf_Block *return_block;\r
222 Dwarf_Signed atcnt, cnt;\r
223 Dwarf_Die return_sib, return_die;\r
224 Dwarf_Off return_offset;\r
225 Dwarf_Line *linebuf;\r
226 FILE *SrcFile;\r
227 size_t i, j, k, TypeOffset;\r
228 char *return_string;\r
229 char *Ptr;\r
230 char *SourceFilename = NULL;\r
231 char *SourceFileDirectory = NULL;\r
232 char *SourceFullFilename = NULL;\r
233\r
234 // Initialisation for the Compilation Units table\r
235 NbCU = 0;\r
236 PtrCU = NULL;\r
237\r
238 // loop on the available Compilation Unit\r
239 while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &next_cu_header, &error) == DW_DLV_OK)\r
240 {\r
241 // Allocation of an additional Compilation Unit structure in the table\r
242 if (Ptr = (char *)realloc(PtrCU, ((NbCU + 1) * sizeof(CUStruct))))\r
243 {\r
244 // Compilation Unit RAZ\r
245 PtrCU = (CUStruct *)Ptr;\r
246 memset(PtrCU + NbCU, 0, sizeof(CUStruct));\r
247\r
41d6f5f7
JPM
248 // Debug specific CU\r
249#ifdef DEBUG_NumCU\r
250 if (NbCU == DEBUG_NumCU)\r
251#endif\r
ebcb0f3d 252 {\r
41d6f5f7
JPM
253 // Get 1st Die from the Compilation Unit\r
254 if (dwarf_siblingof(dbg, NULL, &return_sib, &error) == DW_DLV_OK)\r
ebcb0f3d 255 {\r
41d6f5f7
JPM
256 // Get Die's Tag\r
257 if ((dwarf_tag(return_sib, &return_tagval, &error) == DW_DLV_OK))\r
ebcb0f3d 258 {\r
41d6f5f7
JPM
259 PtrCU[NbCU].Tag = return_tagval;\r
260\r
261 // Die type detection\r
262 switch (return_tagval)\r
ebcb0f3d 263 {\r
41d6f5f7
JPM
264 case DW_TAG_compile_unit:\r
265 if (dwarf_attrlist(return_sib, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 266 {\r
41d6f5f7 267 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 268 {\r
41d6f5f7 269 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 270 {\r
41d6f5f7 271 switch (return_attr)\r
ebcb0f3d 272 {\r
41d6f5f7
JPM
273 case DW_AT_low_pc:\r
274 if (dwarf_lowpc(return_sib, &return_lowpc, &error) == DW_DLV_OK)\r
275 {\r
276 PtrCU[NbCU].LowPC = return_lowpc;\r
277 }\r
278 break;\r
ebcb0f3d 279\r
41d6f5f7
JPM
280 case DW_AT_high_pc:\r
281 if (dwarf_highpc(return_sib, &return_highpc, &error) == DW_DLV_OK)\r
282 {\r
283 PtrCU[NbCU].HighPC = return_highpc;\r
284 }\r
285 break;\r
ebcb0f3d 286\r
41d6f5f7
JPM
287 case DW_AT_producer:\r
288 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
289 {\r
290 PtrCU[NbCU].PtrProducer = (char *)calloc(strlen(return_string) + 1, 1);\r
291 strcpy(PtrCU[NbCU].PtrProducer, return_string);\r
292 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
293 }\r
294 break;\r
ebcb0f3d 295\r
41d6f5f7
JPM
296 case DW_AT_name:\r
297 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
298 {\r
299 SourceFilename = (char *)realloc(SourceFilename, strlen(return_string) + 1);\r
300 strcpy(SourceFilename, return_string);\r
301 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
302 }\r
303 break;\r
ebcb0f3d 304\r
41d6f5f7
JPM
305 case DW_AT_comp_dir:\r
306 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
307 {\r
308 SourceFileDirectory = (char *)realloc(SourceFileDirectory, strlen(return_string) + 1);\r
309 strcpy(SourceFileDirectory, return_string);\r
310 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
311 }\r
312 break;\r
ebcb0f3d 313\r
41d6f5f7
JPM
314 default:\r
315 break;\r
316 }\r
ebcb0f3d 317 }\r
41d6f5f7 318 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
ebcb0f3d 319 }\r
41d6f5f7 320 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
ebcb0f3d 321 }\r
ebcb0f3d 322\r
41d6f5f7
JPM
323 Ptr = SourceFullFilename = (char *)realloc(SourceFullFilename, strlen(SourceFilename) + strlen(SourceFileDirectory) + 2);\r
324 sprintf(SourceFullFilename, "%s\\%s", SourceFileDirectory, SourceFilename);\r
325 while (*Ptr)\r
ebcb0f3d 326 {\r
41d6f5f7
JPM
327 if (*Ptr == '/')\r
328 {\r
329 *Ptr = '\\';\r
330 }\r
331 Ptr++;\r
ebcb0f3d 332 }\r
41d6f5f7
JPM
333 PtrCU[NbCU].PtrFullFilename = (char *)calloc(strlen(SourceFullFilename) + 1, 1);\r
334 strcpy((char *)PtrCU[NbCU].PtrFullFilename, SourceFullFilename);\r
ebcb0f3d
JPM
335\r
336#ifndef __CYGWIN__\r
41d6f5f7 337 if (!fopen_s(&SrcFile, SourceFullFilename, "rt"))\r
ebcb0f3d 338#else\r
41d6f5f7 339 if (!(SrcFile = fopen(SourceFullFilename, "rt")))\r
ebcb0f3d 340#endif\r
ebcb0f3d 341 {\r
41d6f5f7 342 if (!fseek(SrcFile, 0, SEEK_END))\r
ebcb0f3d 343 {\r
41d6f5f7 344 if ((PtrCU[NbCU].SizeLoadSrc = ftell(SrcFile)) > 0)\r
ebcb0f3d 345 {\r
41d6f5f7 346 if (PtrCU[NbCU].PtrLoadSrc = Ptr = (char *)calloc((PtrCU[NbCU].SizeLoadSrc + 1), 1))\r
ebcb0f3d 347 {\r
41d6f5f7
JPM
348 rewind(SrcFile);\r
349 if (PtrCU[NbCU].SizeLoadSrc < fread(Ptr, 1, PtrCU[NbCU].SizeLoadSrc, SrcFile))\r
350 {\r
351 free(PtrCU[NbCU].PtrLoadSrc);\r
352 PtrCU[NbCU].PtrLoadSrc = NULL;\r
353 PtrCU[NbCU].SizeLoadSrc = 0;\r
354 }\r
355 else\r
ebcb0f3d 356 {\r
41d6f5f7 357 do\r
ebcb0f3d 358 {\r
41d6f5f7
JPM
359 if (*Ptr == 0xa)\r
360 {\r
361 PtrCU[NbCU].NbLinesLoadSrc++;\r
362 *Ptr = 0;\r
363 }\r
364 } while (*++Ptr);\r
365 }\r
ebcb0f3d
JPM
366 }\r
367 }\r
368 }\r
41d6f5f7 369 fclose(SrcFile);\r
ebcb0f3d 370 }\r
41d6f5f7 371 break;\r
ebcb0f3d 372\r
41d6f5f7
JPM
373 default:\r
374 break;\r
375 }\r
ebcb0f3d 376 }\r
ebcb0f3d 377\r
41d6f5f7
JPM
378 // Get the source lines table located in the Compilation Unit\r
379 if (dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK)\r
380 {\r
381 }\r
ebcb0f3d 382\r
41d6f5f7 383 if (dwarf_child(return_sib, &return_die, &error) == DW_DLV_OK)\r
ebcb0f3d 384 {\r
41d6f5f7 385 do\r
ebcb0f3d 386 {\r
41d6f5f7
JPM
387 return_sib = return_die;\r
388 if ((dwarf_tag(return_die, &return_tagval, &error) == DW_DLV_OK))\r
ebcb0f3d 389 {\r
41d6f5f7 390 switch (return_tagval)\r
ebcb0f3d 391 {\r
41d6f5f7
JPM
392 case DW_TAG_lexical_block:\r
393 break;\r
ebcb0f3d 394\r
41d6f5f7
JPM
395 case DW_TAG_variable:\r
396 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 397 {\r
41d6f5f7
JPM
398 PtrCU[NbCU].PtrVariables = (VariablesStruct *)realloc(PtrCU[NbCU].PtrVariables, ((PtrCU[NbCU].NbVariables + 1) * sizeof(VariablesStruct)));\r
399 memset(PtrCU[NbCU].PtrVariables + PtrCU[NbCU].NbVariables, 0, sizeof(VariablesStruct));\r
400\r
401 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 402 {\r
41d6f5f7 403 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 404 {\r
41d6f5f7 405 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
ebcb0f3d 406 {\r
41d6f5f7 407 switch (return_attr)\r
ebcb0f3d 408 {\r
41d6f5f7
JPM
409 case DW_AT_location:\r
410 if (dwarf_formblock(return_attr1, &return_block, &error) == DW_DLV_OK)\r
ebcb0f3d 411 {\r
41d6f5f7
JPM
412 if (return_block->bl_len == 5)\r
413 {\r
414 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].Addr = (*((unsigned char *)(return_block->bl_data) + 1) << 24) + (*((unsigned char *)(return_block->bl_data) + 2) << 16) + (*((unsigned char *)(return_block->bl_data) + 3) << 8) + (*((unsigned char *)(return_block->bl_data) + 4));\r
415 }\r
416 dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);\r
ebcb0f3d 417 }\r
41d6f5f7 418 break;\r
ebcb0f3d 419\r
41d6f5f7
JPM
420 case DW_AT_type:\r
421 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
422 {\r
423 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].TypeOffset = return_offset;\r
424 }\r
425 break;\r
ebcb0f3d 426\r
41d6f5f7
JPM
427 case DW_AT_name:\r
428 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
429 {\r
430 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
431 strcpy(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName, return_string);\r
432 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
433 }\r
434 break;\r
ebcb0f3d 435\r
41d6f5f7
JPM
436 default:\r
437 break;\r
438 }\r
ebcb0f3d
JPM
439 }\r
440 }\r
ebcb0f3d 441\r
41d6f5f7
JPM
442 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
443 }\r
ebcb0f3d 444\r
41d6f5f7 445 PtrCU[NbCU].NbVariables++;\r
ebcb0f3d 446\r
41d6f5f7 447 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
ebcb0f3d 448 }\r
41d6f5f7
JPM
449 break;\r
450\r
451 case DW_TAG_base_type:\r
452 case DW_TAG_typedef:\r
453 case DW_TAG_structure_type:\r
454 case DW_TAG_pointer_type:\r
455 case DW_TAG_const_type:\r
456 case DW_TAG_array_type:\r
457 case DW_TAG_subrange_type:\r
458 case DW_TAG_subroutine_type:\r
459 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 460 {\r
41d6f5f7
JPM
461 PtrCU[NbCU].PtrTypes = (BaseTypeStruct *)realloc(PtrCU[NbCU].PtrTypes, ((PtrCU[NbCU].NbTypes + 1) * sizeof(BaseTypeStruct)));\r
462 memset(PtrCU[NbCU].PtrTypes + PtrCU[NbCU].NbTypes, 0, sizeof(BaseTypeStruct));\r
463 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Tag = return_tagval;\r
464\r
465 if (dwarf_dieoffset(return_die, &return_offset, &error) == DW_DLV_OK)\r
466 {\r
467 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Offset = return_offset;\r
468 }\r
469\r
470 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 471 {\r
41d6f5f7 472 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 473 {\r
41d6f5f7 474 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
ebcb0f3d 475 {\r
41d6f5f7 476 switch (return_attr)\r
ebcb0f3d 477 {\r
41d6f5f7
JPM
478 case DW_AT_type:\r
479 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
480 {\r
481 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].TypeOffset = return_offset;\r
482 }\r
483 break;\r
ebcb0f3d 484\r
41d6f5f7
JPM
485 case DW_AT_byte_size:\r
486 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
487 {\r
488 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].ByteSize = return_uvalue;\r
489 }\r
490 break;\r
ebcb0f3d 491\r
41d6f5f7
JPM
492 case DW_AT_encoding:\r
493 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
494 {\r
495 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Encoding = return_uvalue;\r
496 }\r
497 break;\r
ebcb0f3d 498\r
41d6f5f7
JPM
499 case DW_AT_name:\r
500 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
501 {\r
502 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
503 strcpy(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName, return_string);\r
504 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
505 }\r
506 break;\r
ebcb0f3d 507\r
41d6f5f7
JPM
508 default:\r
509 break;\r
510 }\r
ebcb0f3d
JPM
511 }\r
512 }\r
ebcb0f3d 513\r
41d6f5f7
JPM
514 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
515 }\r
ebcb0f3d 516\r
41d6f5f7 517 PtrCU[NbCU].NbTypes++;\r
ebcb0f3d 518\r
41d6f5f7
JPM
519 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
520 }\r
521 break;\r
ebcb0f3d 522\r
41d6f5f7
JPM
523 case DW_TAG_subprogram:\r
524 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 525 {\r
41d6f5f7
JPM
526 PtrCU[NbCU].PtrSubProgs = (SubProgStruct *)realloc(PtrCU[NbCU].PtrSubProgs, ((PtrCU[NbCU].NbSubProgs + 1) * sizeof(SubProgStruct)));\r
527 memset((void *)(PtrCU[NbCU].PtrSubProgs + PtrCU[NbCU].NbSubProgs), 0, sizeof(SubProgStruct));\r
528 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].Tag = return_tagval;\r
529\r
530 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 531 {\r
41d6f5f7 532 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 533 {\r
41d6f5f7 534 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
ebcb0f3d 535 {\r
41d6f5f7 536 switch (return_attr)\r
ebcb0f3d 537 {\r
41d6f5f7
JPM
538 case DW_AT_low_pc:\r
539 if (dwarf_lowpc(return_die, &return_lowpc, &error) == DW_DLV_OK)\r
540 {\r
541 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].StartPC = return_lowpc;\r
542 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].LowPC = return_lowpc;\r
543 }\r
544 break;\r
ebcb0f3d 545\r
41d6f5f7
JPM
546 case DW_AT_high_pc:\r
547 if (dwarf_highpc(return_die, &return_highpc, &error) == DW_DLV_OK)\r
548 {\r
549 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].HighPC = return_highpc;\r
550 }\r
551 break;\r
ebcb0f3d 552\r
41d6f5f7
JPM
553 case DW_AT_decl_line:\r
554 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
555 {\r
556 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NumLineSrc = return_uvalue;\r
557 }\r
558 break;\r
ebcb0f3d 559\r
41d6f5f7
JPM
560 case DW_AT_name:\r
561 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
562 {\r
563 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName = (char *)calloc(strlen(return_string) + 1, 1);\r
564 strcpy(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName, return_string);\r
565 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
566 }\r
567 break;\r
ebcb0f3d 568\r
41d6f5f7
JPM
569 default:\r
570 break;\r
571 }\r
ebcb0f3d
JPM
572 }\r
573 }\r
41d6f5f7 574 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
ebcb0f3d 575 }\r
41d6f5f7 576 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
ebcb0f3d 577\r
41d6f5f7 578 for (i = 0; i < (size_t)cnt; ++i)\r
ebcb0f3d 579 {\r
41d6f5f7 580 if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
ebcb0f3d 581 {\r
41d6f5f7 582 if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
ebcb0f3d 583 {\r
41d6f5f7
JPM
584 if ((return_lineaddr >= return_lowpc) && (return_lineaddr <= return_highpc))\r
585 {\r
586 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc = (DMIStruct_LineSrc *)realloc(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc, (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc + 1) * sizeof(DMIStruct_LineSrc));\r
587 memset((void *)(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc), 0, sizeof(DMIStruct_LineSrc));\r
588 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].StartPC = return_lineaddr;\r
589 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].NumLineSrc = return_uvalue;\r
590 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc++;\r
591 }\r
ebcb0f3d
JPM
592 }\r
593 }\r
41d6f5f7
JPM
594 }\r
595\r
596 PtrCU[NbCU].NbSubProgs++;\r
ebcb0f3d 597 }\r
41d6f5f7 598 break;\r
ebcb0f3d 599\r
41d6f5f7
JPM
600 default:\r
601 break;\r
602 }\r
ebcb0f3d 603 }\r
41d6f5f7 604 } while (dwarf_siblingof(dbg, return_sib, &return_die, &error) == DW_DLV_OK);\r
ebcb0f3d 605 }\r
ebcb0f3d 606\r
41d6f5f7
JPM
607 // Release the memory used by the source lines\r
608 for (i = 0; i < (size_t)cnt; ++i)\r
609 dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);\r
610 dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);\r
611 }\r
ebcb0f3d 612\r
41d6f5f7
JPM
613 // Set the source code lines for QT html/text conformity\r
614 if (PtrCU[NbCU].NbLinesLoadSrc)\r
ebcb0f3d 615 {\r
41d6f5f7 616 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(PtrCU[NbCU].NbLinesLoadSrc, sizeof(char *)))\r
ebcb0f3d 617 {\r
41d6f5f7 618 for (j = 0; j < PtrCU[NbCU].NbLinesLoadSrc; j++)\r
ebcb0f3d 619 {\r
41d6f5f7 620 if (PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)calloc(10000, sizeof(char)))\r
ebcb0f3d 621 {\r
41d6f5f7 622 if (Ptr = DWARFManager_GetLineSrcFromNumLine(PtrCU[NbCU].PtrLoadSrc, (j + 1)))\r
ebcb0f3d 623 {\r
41d6f5f7
JPM
624 i = 0;\r
625\r
626 while (*Ptr)\r
ebcb0f3d 627 {\r
41d6f5f7
JPM
628 switch (*Ptr)\r
629 {\r
630 case 9:\r
631 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");\r
632 i += strlen("&nbsp;");\r
633 break;\r
634\r
635 case '<':\r
636 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&lt;");\r
637 i += strlen("&lt;");\r
638 break;\r
639\r
640 case '>':\r
641 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&gt;");\r
642 i += strlen("&gt;");\r
643 break;\r
ebcb0f3d 644#if 0\r
41d6f5f7
JPM
645 case '&':\r
646 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&amp;");\r
647 i += strlen("&amp;");\r
648 break;\r
ebcb0f3d
JPM
649#endif\r
650#if 0\r
41d6f5f7
JPM
651 case '"':\r
652 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");\r
653 i += strlen("&quot;");\r
654 break;\r
ebcb0f3d 655#endif\r
41d6f5f7
JPM
656 default:\r
657 PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;\r
658 break;\r
659 }\r
660 Ptr++;\r
ebcb0f3d 661 }\r
ebcb0f3d 662 }\r
41d6f5f7 663 PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)realloc(PtrCU[NbCU].PtrLinesLoadSrc[j], i + 1);\r
ebcb0f3d 664 }\r
ebcb0f3d
JPM
665 }\r
666 }\r
667 }\r
41d6f5f7 668 else\r
ebcb0f3d 669 {\r
41d6f5f7
JPM
670 // Set each source lines pointer to NULL\r
671 if (PtrCU[NbCU].NbSubProgs)\r
ebcb0f3d 672 {\r
41d6f5f7
JPM
673 i = PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc - 1].NumLineSrc;\r
674 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(i, sizeof(char *)))\r
ebcb0f3d 675 {\r
41d6f5f7
JPM
676 for (j = 0; j < i; j++)\r
677 {\r
678 PtrCU[NbCU].PtrLinesLoadSrc[j] = NULL;\r
679 }\r
ebcb0f3d
JPM
680 }\r
681 }\r
682 }\r
ebcb0f3d 683\r
41d6f5f7
JPM
684 // Init lines source information based on each source code line numbers\r
685 for (j = 0; j < PtrCU[NbCU].NbSubProgs; j++)\r
ebcb0f3d 686 {\r
41d6f5f7
JPM
687 // Check if the subprog / function's line exists in the source code\r
688 if (PtrCU[NbCU].PtrSubProgs[j].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
689 {\r
690 PtrCU[NbCU].PtrSubProgs[j].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].NumLineSrc - 1];\r
691 }\r
ebcb0f3d 692\r
41d6f5f7
JPM
693 for (k = 0; k < PtrCU[NbCU].PtrSubProgs[j].NbLinesSrc; k++)\r
694 {\r
695 PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc - 1];\r
696 }\r
697 }\r
ebcb0f3d 698\r
41d6f5f7
JPM
699 // Init variables information based on types information\r
700 for (i = 0; i < PtrCU[NbCU].NbVariables; i++)\r
ebcb0f3d 701 {\r
41d6f5f7
JPM
702 PtrCU[NbCU].PtrVariables[i].PtrTypeName = (char *)calloc(1000, 1);\r
703 TypeOffset = PtrCU[NbCU].PtrVariables[i].TypeOffset;\r
704\r
705 for (j = 0; j < PtrCU[NbCU].NbTypes; j++)\r
ebcb0f3d 706 {\r
41d6f5f7 707 if (TypeOffset == PtrCU[NbCU].PtrTypes[j].Offset)\r
ebcb0f3d 708 {\r
41d6f5f7 709 switch (PtrCU[NbCU].PtrTypes[j].Tag)\r
ebcb0f3d 710 {\r
41d6f5f7
JPM
711 case DW_TAG_structure_type:\r
712 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x1;\r
713 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
ebcb0f3d 714 {\r
41d6f5f7 715 j = -1;\r
ebcb0f3d 716 }\r
41d6f5f7
JPM
717 else\r
718 {\r
719 if ((PtrCU[NbCU].PtrVariables[i].TypeTag & 0x2))\r
720 {\r
721 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, " *");\r
722 }\r
723 }\r
724 break;\r
ebcb0f3d 725\r
41d6f5f7
JPM
726 case DW_TAG_pointer_type:\r
727 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x2;\r
728 PtrCU[NbCU].PtrVariables[i].TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
729 PtrCU[NbCU].PtrVariables[i].TypeEncoding = 0x10;\r
730 if (!(TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
731 {\r
732 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, "void *");\r
733 }\r
734 else\r
735 {\r
736 j = -1;\r
737 }\r
738 break;\r
ebcb0f3d 739\r
41d6f5f7
JPM
740 case DW_TAG_typedef:\r
741 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x20;\r
742 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
743 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
744 {\r
745 j = -1;\r
746 }\r
747 break;\r
ebcb0f3d 748\r
41d6f5f7
JPM
749 case DW_TAG_subrange_type:\r
750 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x4;\r
751 break;\r
ebcb0f3d 752\r
41d6f5f7
JPM
753 case DW_TAG_array_type:\r
754 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x8;\r
755 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
756 {\r
757 j = -1;\r
758 }\r
759 break;\r
ebcb0f3d 760\r
41d6f5f7
JPM
761 case DW_TAG_const_type:\r
762 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x10;\r
763 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, "const ");\r
764 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
765 {\r
766 j = -1;\r
767 }\r
768 break;\r
ebcb0f3d 769\r
41d6f5f7
JPM
770 case DW_TAG_base_type:\r
771 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
772 if ((PtrCU[NbCU].PtrVariables[i].TypeTag & 0x2))\r
773 {\r
774 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, " *");\r
775 }\r
776 else\r
777 {\r
778 PtrCU[NbCU].PtrVariables[i].TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
779 PtrCU[NbCU].PtrVariables[i].TypeEncoding = PtrCU[NbCU].PtrTypes[j].Encoding;\r
780 }\r
781 if ((PtrCU[NbCU].PtrVariables[i].TypeTag & 0x8))\r
782 {\r
783 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, "[]");\r
784 }\r
785 break;\r
ebcb0f3d 786\r
41d6f5f7
JPM
787 default:\r
788 break;\r
789 }\r
ebcb0f3d
JPM
790 }\r
791 }\r
792 }\r
793 }\r
794\r
795 ++NbCU;\r
796 }\r
797 } \r
798\r
799 free(SourceFilename);\r
800 free(SourceFileDirectory);\r
801 free(SourceFullFilename);\r
802}\r
803\r
804\r
805// Get symbol name based from address\r
806// Return NULL if no symbol name exists\r
807char *DWARFManager_GetSymbolnameFromAdr(size_t Adr)\r
808{\r
809 size_t i, j;\r
810\r
811 for (i = 0; i < NbCU; i++)\r
812 {\r
813 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
814 {\r
815 for (j = 0; (j < PtrCU[i].NbSubProgs); j++)\r
816 {\r
817 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr))\r
818 {\r
819 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;\r
820 }\r
821 }\r
822 }\r
823 }\r
824\r
825 return NULL;\r
826}\r
827\r
828\r
829// Get complete source filename based from address\r
830// Return NULL if no source filename exists\r
831// Return the existence status (true or false) in Error\r
832char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error)\r
833{\r
834 size_t i;\r
835\r
836 for (i = 0; i < NbCU; i++)\r
837 {\r
838 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
839 {\r
840 *Error = PtrCU[i].PtrLoadSrc ? true : false;\r
841 return PtrCU[i].PtrFullFilename;\r
842 }\r
843 }\r
844\r
845 return NULL;\r
846}\r
847\r
848\r
849// Get text line source based on line number (starting by 1)\r
850// Return NULL if no text line exists or if line number is 0\r
851char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine)\r
852{\r
853 size_t i = 0;\r
854 char *PtrLineSrc = NULL;\r
855\r
856 if (PtrSrcFile)\r
857 {\r
858 while (i != NumLine)\r
859 {\r
860 PtrLineSrc = PtrSrcFile;\r
861 while (*PtrSrcFile++);\r
862 i++;\r
863 }\r
864 }\r
865\r
866 return PtrLineSrc;\r
867}\r
868\r
869\r
870// Get Compilation Unit / External variables numbers\r
871// Return variables number\r
872size_t DWARFManager_GetNbExternalVariables(void)\r
873{\r
874 size_t NbVariables = 0, i;\r
875\r
876 for (i = 0; i < NbCU; i++)\r
877 {\r
878 NbVariables += PtrCU[i].NbVariables;\r
879 }\r
880\r
881 return NbVariables;\r
882}\r
883\r
884\r
885// Get external variable type name based on his index (starting by 1)\r
886// Return NULL if not found\r
887// May return NULL if there is not type linked to the variable's index\r
888char *DWARFManager_GetExternalVariableTypeName(size_t Index)\r
889{\r
890 size_t i;\r
891\r
892 for (i = 0; i < NbCU; i++)\r
893 {\r
894 if (PtrCU[i].NbVariables)\r
895 {\r
896 if (Index <= PtrCU[i].NbVariables)\r
897 {\r
898 return PtrCU[i].PtrVariables[Index - 1].PtrTypeName;\r
899 }\r
900 else\r
901 {\r
902 Index -= PtrCU[i].NbVariables;\r
903 }\r
904 }\r
905 }\r
906\r
907 return NULL;\r
908}\r
909\r
910\r
911// Get external variable's type tag based on his index (starting by 1)\r
912// Return 0 if not found\r
913size_t DWARFManager_GetExternalVariableTypeTag(size_t Index)\r
914{\r
915 size_t i;\r
916\r
917 for (i = 0; i < NbCU; i++)\r
918 {\r
919 if (PtrCU[i].NbVariables)\r
920 {\r
921 if (Index <= PtrCU[i].NbVariables)\r
922 {\r
923 return PtrCU[i].PtrVariables[Index - 1].TypeTag;\r
924 }\r
925 else\r
926 {\r
927 Index -= PtrCU[i].NbVariables;\r
928 }\r
929 }\r
930 }\r
931\r
932 return 0;\r
933}\r
934\r
935\r
936// Get external variable byte size based on his index (starting by 1)\r
937// Return 0 if not found\r
938size_t DWARFManager_GetExternalVariableTypeByteSize(size_t Index)\r
939{\r
940 size_t i;\r
941\r
942 for (i = 0; i < NbCU; i++)\r
943 {\r
944 if (PtrCU[i].NbVariables)\r
945 {\r
946 if (Index <= PtrCU[i].NbVariables)\r
947 {\r
948 return PtrCU[i].PtrVariables[Index - 1].TypeByteSize;\r
949 }\r
950 else\r
951 {\r
952 Index -= PtrCU[i].NbVariables;\r
953 }\r
954 }\r
955 }\r
956\r
957 return 0;\r
958}\r
959\r
960\r
961// Get external variable encoding based on his index (starting by 1)\r
962// Return 0 if not found\r
963size_t DWARFManager_GetExternalVariableTypeEncoding(size_t Index)\r
964{\r
965 size_t i;\r
966\r
967 for (i = 0; i < NbCU; i++)\r
968 {\r
969 if (PtrCU[i].NbVariables)\r
970 {\r
971 if (Index <= PtrCU[i].NbVariables)\r
972 {\r
973 return PtrCU[i].PtrVariables[Index - 1].TypeEncoding;\r
974 }\r
975 else\r
976 {\r
977 Index -= PtrCU[i].NbVariables;\r
978 }\r
979 }\r
980 }\r
981\r
982 return 0;\r
983}\r
984\r
985\r
986// Get external variable address based on his index (starting by 1)\r
987// Return 0 if not found\r
988size_t DWARFManager_GetExternalVariableAdr(size_t Index)\r
989{\r
990 size_t i;\r
991\r
992 for (i = 0; i < NbCU; i++)\r
993 {\r
994 if (PtrCU[i].NbVariables)\r
995 {\r
996 if (Index <= PtrCU[i].NbVariables)\r
997 {\r
998 return PtrCU[i].PtrVariables[Index - 1].Addr;\r
999 }\r
1000 else\r
1001 {\r
1002 Index -= PtrCU[i].NbVariables;\r
1003 }\r
1004 }\r
1005 }\r
1006\r
1007 return 0;\r
1008}\r
1009\r
1010\r
1011// Get external variable memory address based on his name\r
1012// Return 0 if not found\r
1013// Note: Return the first occurence found\r
1014size_t DWARFManager_GetExternalVariableAdrFromName(char *VariableName)\r
1015{\r
1016 size_t i, j;\r
1017\r
1018 for (i = 0; i < NbCU; i++)\r
1019 {\r
1020 if (PtrCU[i].NbVariables)\r
1021 {\r
1022 for (j = 0; j < PtrCU[i].NbVariables; j++)\r
1023 {\r
1024 if (!strcmp(PtrCU[i].PtrVariables[j].PtrName,VariableName))\r
1025 {\r
1026 return PtrCU[i].PtrVariables[j].Addr;\r
1027 }\r
1028 }\r
1029 }\r
1030 }\r
1031\r
1032 return 0;\r
1033}\r
1034\r
1035\r
1036// Get external variable name based on his index (starting by 1)\r
1037// Return name's pointer text found\r
1038// Return NULL if not found\r
1039char *DWARFManager_GetExternalVariableName(size_t Index)\r
1040{\r
1041 size_t i;\r
1042\r
1043 for (i = 0; i < NbCU; i++)\r
1044 {\r
1045 if (PtrCU[i].NbVariables)\r
1046 {\r
1047 if (Index <= PtrCU[i].NbVariables)\r
1048 {\r
1049 return PtrCU[i].PtrVariables[Index - 1].PtrName;\r
1050 }\r
1051 else\r
1052 {\r
1053 Index -= PtrCU[i].NbVariables;\r
1054 }\r
1055 }\r
1056 }\r
1057\r
1058 return NULL;\r
1059}\r
1060\r
1061\r
1062// Get text line from source based on address and his tag\r
1063// Return NULL if no text line has been found\r
1064char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)\r
1065{\r
1066 size_t i, j, k;\r
1067\r
1068 for (i = 0; i < NbCU; i++)\r
1069 {\r
1070 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1071 {\r
1072 for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1073 {\r
1074 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1075 {\r
1076 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))\r
1077 {\r
1078 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;\r
1079 }\r
1080 else\r
1081 {\r
1082 for (k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
1083 {\r
1084 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
1085 {\r
1086 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;\r
1087 }\r
1088 }\r
1089 }\r
1090 }\r
1091 }\r
1092 }\r
1093 }\r
1094\r
1095 return NULL;\r
1096}\r
1097\r
1098\r
1099// Get line number based on the address and the tag\r
1100// Return 0 if no line number has been found\r
1101size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)\r
1102{\r
1103 size_t i, j, k;\r
1104\r
1105 for (i = 0; i < NbCU; i++)\r
1106 {\r
1107 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1108 {\r
1109 for (j = 0; (j < PtrCU[i].NbSubProgs); j++)\r
1110 {\r
1111 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1112 {\r
1113 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))\r
1114 {\r
1115 return PtrCU[i].PtrSubProgs[j].NumLineSrc;\r
1116 }\r
1117 else\r
1118 {\r
1119 for (k = 0; (k < PtrCU[i].PtrSubProgs[j].NbLinesSrc); k++)\r
1120 {\r
1121 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
1122 {\r
1123 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc;\r
1124 }\r
1125 }\r
1126 }\r
1127#if 0\r
1128 if (!Tag || (Tag == DW_TAG_subprogram))\r
1129 {\r
1130 return PtrCU[i].PtrSubProgs[j].NumLineSrc;\r
1131 }\r
1132#endif\r
1133 }\r
1134 }\r
1135 }\r
1136 }\r
1137\r
1138 return 0;\r
1139}\r
1140\r
1141\r
1142// Get text line from source based on address and num line (starting by 1)\r
1143// Return NULL if no text line has been found\r
1144char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)\r
1145{\r
1146 size_t i, j, k;\r
1147\r
1148 for (i = 0; i < NbCU; i++)\r
1149 {\r
1150 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1151 {\r
1152 for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1153 {\r
1154 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1155 {\r
1156 if (PtrCU[i].PtrSubProgs[j].NumLineSrc == NumLine)\r
1157 {\r
1158 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;\r
1159 }\r
1160 else\r
1161 {\r
1162 for (k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
1163 {\r
1164 if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc == NumLine)\r
1165 {\r
1166 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;\r
1167 }\r
1168 }\r
1169 }\r
1170 }\r
1171 }\r
1172 }\r
1173 }\r
1174\r
1175 return NULL;\r
1176}\r
1177\r
1178\r
1179// Get text line from source based on address and num line (starting by 1)\r
1180// Return NULL if no text line has been found\r
1181char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)\r
1182{\r
1183 size_t i;\r
1184\r
1185 for (i = 0; i < NbCU; i++)\r
1186 {\r
1187 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1188 {\r
41d6f5f7
JPM
1189 if (NumLine <= PtrCU[i].NbLinesLoadSrc)\r
1190 {\r
1191 return PtrCU[i].PtrLinesLoadSrc[NumLine - 1];\r
1192 }\r
1193 else\r
1194 {\r
1195 return NULL;\r
1196 }\r
ebcb0f3d
JPM
1197 }\r
1198 }\r
1199\r
1200 return NULL;\r
1201}\r
1202\r