Fix a random crash when reading the source lines information
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DWARFManager.cpp
... / ...
CommitLineData
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 Dec./2016 Created this file, and added the DWARF format support\r
11// JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information\r
12// JPM Oct./2018 Improve the DWARF parsing information, and the source file text reading; support the used source lines from DWARF structure, and the search paths for the files\r
13// JPM Mar./2020 Fix a random crash when reading the source lines information\r
14//\r
15\r
16// To Do\r
17// To use pointers instead of arrays usage\r
18// To keep sources text file intact wihtout QT/HTML transformation\r
19// \r
20\r
21\r
22#include <stdlib.h>\r
23#include <stdio.h>\r
24#include <stdint.h>\r
25#include <string.h>\r
26#include <libdwarf.h>\r
27#include <dwarf.h>\r
28#include "LEB128.h"\r
29\r
30\r
31// Definitions for debugging\r
32//#define DEBUG_NumCU 0x4d // CU number to debug or undefine it\r
33//#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it\r
34//#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it\r
35//#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)\r
36//#define DEBUG_Filename "net_jag.c" // Filename to look for or undefine it\r
37\r
38// Definitions for the variables's typetag\r
39#define TypeTag_structure 0x01 // structure\r
40#define TypeTag_pointer 0x02 // pointer\r
41#define TypeTag_subrange 0x04 // (subrange_type?)\r
42#define TypeTag_arraytype 0x08 // array type\r
43#define TypeTag_consttype 0x10 // const type\r
44#define TypeTag_typedef 0x20 // typedef\r
45#define TypeTag_enumeration_type 0x40 // enumeration\r
46#define TypeTag_subroutine_type 0x80 // subroutine\r
47\r
48\r
49// Source line CU structure\r
50typedef struct CUStruct_LineSrc\r
51{\r
52 size_t StartPC;\r
53 size_t NumLineSrc;\r
54 char *PtrLineSrc;\r
55}S_CUStruct_LineSrc;\r
56\r
57// Source line internal structure\r
58typedef struct DMIStruct_LineSrc\r
59{\r
60 size_t Tag;\r
61 size_t StartPC;\r
62 size_t NumLineSrc;\r
63 char *PtrLineSrc;\r
64}S_DMIStruct_LineSrc;\r
65\r
66// Enumeration structure\r
67typedef struct EnumerationStruct\r
68{\r
69 char *PtrName; // Enumeration's name\r
70 size_t value; // Enumeration's value\r
71}S_EnumerationStruct;\r
72\r
73// Structure members structure\r
74//typedef struct StructureMembersStruct\r
75//{\r
76//}S_StructureMembersStruct;\r
77\r
78// Base type internal structure\r
79typedef struct BaseTypeStruct\r
80{\r
81 size_t Tag; // Type's Tag\r
82 size_t Offset; // Type's offset\r
83 size_t TypeOffset; // Type's offset on another type\r
84 size_t ByteSize; // Type's Byte Size\r
85 size_t Encoding; // Type's encoding\r
86 char *PtrName; // Type's name\r
87 size_t NbEnumeration; // Type's enumeration numbers\r
88 EnumerationStruct *PtrEnumeration; // Type's enumeration\r
89// StructureMembersStruct *PtrStructureMembers; // Type's structure members\r
90}S_BaseTypeStruct;\r
91\r
92// Variables internal structure\r
93typedef struct VariablesStruct\r
94{\r
95 size_t Op; // Variable's DW_OP\r
96 union\r
97 {\r
98 size_t Addr; // Variable memory address\r
99 int Offset; // Variable stack offset (signed)\r
100 };\r
101 char *PtrName; // Variable's name\r
102 size_t TypeOffset; // Offset pointing on the Variable's Type\r
103 size_t TypeByteSize; // Variable's Type byte size\r
104 size_t TypeTag; // Variable's Type Tag\r
105 size_t TypeEncoding; // Variable's Type encoding\r
106 char *PtrTypeName; // Variable's Type name\r
107}S_VariablesStruct;\r
108\r
109// Sub program internal structure\r
110typedef struct SubProgStruct\r
111{\r
112 size_t Tag;\r
113 size_t NumLineSrc;\r
114 size_t StartPC;\r
115 size_t LowPC, HighPC;\r
116 size_t FrameBase;\r
117 char *PtrLineSrc;\r
118 char *PtrSubprogramName; // Sub program name\r
119 size_t NbLinesSrc; // Number of lines source used by the sub program\r
120 DMIStruct_LineSrc *PtrLinesSrc; // Pointer of the lines source for the sub program\r
121 size_t NbVariables; // Variables number\r
122 VariablesStruct *PtrVariables; // Pointer to the local variables list information structure\r
123}S_SubProgStruct;\r
124\r
125// Compilation Unit internal structure\r
126typedef struct CUStruct\r
127{\r
128 size_t Tag;\r
129 size_t LowPC, HighPC; // Memory range for the code\r
130 char *PtrProducer; // Pointer to the "Producer" text information (mostly compiler and compilation options used)\r
131 char *PtrSourceFilename; // Source file name\r
132 char *PtrSourceFileDirectory; // Directory of the source file\r
133 char *PtrFullFilename; // Pointer to full namefile (directory & filename)\r
134 size_t SizeLoadSrc; // Source code text size\r
135 char *PtrLoadSrc; // Pointer to the source code text\r
136 size_t NbLinesLoadSrc; // Total number of lines in the source code text\r
137 char **PtrLinesLoadSrc; // Pointer lists to each source line put in QT html/text conformity\r
138 size_t NbSubProgs; // Number of sub programs / routines\r
139 SubProgStruct *PtrSubProgs; // Pointer to the sub programs / routines structure\r
140 size_t NbTypes; // Number of types\r
141 BaseTypeStruct *PtrTypes; // Pointer to types\r
142 size_t NbVariables; // Variables number\r
143 VariablesStruct *PtrVariables; // Pointer to the global variables list structure\r
144 size_t NbFrames; // Frames number\r
145 size_t NbLinesSrc; // Number of used source lines\r
146 CUStruct_LineSrc *PtrLinesSrc; // Pointer to the used source lines list structure\r
147}S_CUStruct;\r
148\r
149\r
150// Dwarf management\r
151uint32_t LibDwarf;\r
152uint32_t NbCU;\r
153Dwarf_Ptr errarg;\r
154Dwarf_Error error;\r
155Dwarf_Debug dbg;\r
156CUStruct *PtrCU;\r
157char **ListSearchPaths;\r
158size_t NbSearchPaths;\r
159\r
160\r
161//\r
162Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg);\r
163void DWARFManager_InitDMI(void);\r
164void DWARFManager_CloseDMI(void);\r
165bool DWARFManager_ElfClose(void);\r
166char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine);\r
167void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables);\r
168void DWARFManager_SourceFileSearchPathsInit(void);\r
169void DWARFManager_SourceFileSearchPathsReset(void);\r
170void DWARFManager_SourceFileSearchPathsClose(void);\r
171\r
172\r
173//\r
174Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg)\r
175{\r
176 return 0;\r
177}\r
178\r
179\r
180// Dwarf manager list search paths init\r
181void DWARFManager_SourceFileSearchPathsInit(void)\r
182{\r
183 ListSearchPaths = NULL;\r
184 NbSearchPaths = 0;\r
185}\r
186\r
187\r
188// Dwarf manager list search paths reset\r
189void DWARFManager_SourceFileSearchPathsReset(void)\r
190{\r
191 ListSearchPaths = NULL;\r
192 NbSearchPaths = 0;\r
193}\r
194\r
195\r
196// Dwarf manager list search paths close\r
197void DWARFManager_SourceFileSearchPathsClose(void)\r
198{\r
199 DWARFManager_SourceFileSearchPathsReset();\r
200}\r
201\r
202\r
203// Dwarf manager init\r
204void DWARFManager_Init(void)\r
205{\r
206 DWARFManager_SourceFileSearchPathsInit();\r
207 LibDwarf = DW_DLV_NO_ENTRY;\r
208}\r
209\r
210\r
211// Dwarf manager settings\r
212void DWARFManager_Set(size_t NbPathsInList, char **PtrListPaths)\r
213{\r
214 // Search paths init\r
215 ListSearchPaths = PtrListPaths;\r
216 NbSearchPaths = NbPathsInList;\r
217}\r
218\r
219\r
220// Dwarf manager Reset\r
221bool DWARFManager_Reset(void)\r
222{\r
223 DWARFManager_SourceFileSearchPathsReset();\r
224 return DWARFManager_ElfClose();\r
225}\r
226\r
227\r
228// Dwarf manager Close\r
229bool DWARFManager_Close(void)\r
230{\r
231 DWARFManager_SourceFileSearchPathsClose();\r
232 return(DWARFManager_Reset());\r
233}\r
234\r
235\r
236// Dwarf manager Elf init\r
237int DWARFManager_ElfInit(Elf *ElfPtr)\r
238{\r
239 if ((LibDwarf = dwarf_elf_init(ElfPtr, DW_DLC_READ, (Dwarf_Handler)DWARFManager_ErrorHandler, errarg, &dbg, &error)) == DW_DLV_OK)\r
240 {\r
241 DWARFManager_InitDMI();\r
242 }\r
243\r
244 return LibDwarf;\r
245}\r
246\r
247\r
248// Dwarf manager Elf close\r
249bool DWARFManager_ElfClose(void)\r
250{\r
251 if (LibDwarf == DW_DLV_OK)\r
252 {\r
253 DWARFManager_CloseDMI();\r
254\r
255 if (dwarf_finish(dbg, &error) == DW_DLV_OK)\r
256 {\r
257 LibDwarf = DW_DLV_NO_ENTRY;\r
258 return true;\r
259 }\r
260 else\r
261 {\r
262 return false;\r
263 }\r
264 }\r
265 else\r
266 {\r
267 return true;\r
268 }\r
269}\r
270\r
271\r
272// Dwarf manager Compilation Units close\r
273void DWARFManager_CloseDMI(void)\r
274{\r
275 while (NbCU--)\r
276 {\r
277 free(PtrCU[NbCU].PtrFullFilename);\r
278 free(PtrCU[NbCU].PtrLoadSrc);\r
279 free(PtrCU[NbCU].PtrProducer);\r
280 free(PtrCU[NbCU].PtrSourceFilename);\r
281 free(PtrCU[NbCU].PtrSourceFileDirectory);\r
282 free(PtrCU[NbCU].PtrLinesSrc);\r
283\r
284 while (PtrCU[NbCU].NbLinesLoadSrc--)\r
285 {\r
286 free(PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].NbLinesLoadSrc]);\r
287 }\r
288 free(PtrCU[NbCU].PtrLinesLoadSrc);\r
289\r
290 while (PtrCU[NbCU].NbSubProgs--)\r
291 {\r
292 while (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables--)\r
293 {\r
294 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName);\r
295 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrTypeName);\r
296 }\r
297 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables);\r
298\r
299 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc);\r
300 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName);\r
301 }\r
302 free(PtrCU[NbCU].PtrSubProgs);\r
303\r
304 while (PtrCU[NbCU].NbTypes--)\r
305 {\r
306 free(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName);\r
307 }\r
308 free(PtrCU[NbCU].PtrTypes);\r
309\r
310 while (PtrCU[NbCU].NbVariables--)\r
311 {\r
312 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);\r
313 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrTypeName);\r
314 }\r
315 free(PtrCU[NbCU].PtrVariables);\r
316 }\r
317\r
318 free(PtrCU);\r
319}\r
320\r
321\r
322// Dwarf manager Compilation Units initialisations\r
323void DWARFManager_InitDMI(void)\r
324{\r
325 Dwarf_Unsigned next_cu_header, return_uvalue;\r
326 Dwarf_Error error;\r
327 Dwarf_Attribute *atlist;\r
328 Dwarf_Attribute return_attr1;\r
329 Dwarf_Half return_tagval, return_attr;\r
330 Dwarf_Addr return_lowpc, return_highpc, return_lineaddr;\r
331 Dwarf_Block *return_block;\r
332 Dwarf_Signed atcnt, cnt;\r
333 Dwarf_Die return_sib, return_die, return_sub, return_subdie;\r
334 Dwarf_Off return_offset;\r
335 Dwarf_Line *linebuf;\r
336 FILE *SrcFile;\r
337 char *return_string;\r
338 char *Ptr, *Ptr1;\r
339\r
340 // Initialisation for the Compilation Units table\r
341 NbCU = 0;\r
342 PtrCU = NULL;\r
343\r
344 // loop on the available Compilation Unit\r
345 while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &next_cu_header, &error) == DW_DLV_OK)\r
346 {\r
347 // Allocation of an additional Compilation Unit structure in the table\r
348 if (Ptr = (char *)realloc(PtrCU, ((NbCU + 1) * sizeof(CUStruct))))\r
349 {\r
350 // Compilation Unit RAZ\r
351 PtrCU = (CUStruct *)Ptr;\r
352 memset(PtrCU + NbCU, 0, sizeof(CUStruct));\r
353\r
354 // Debug specific CU\r
355#ifdef DEBUG_NumCU\r
356 if (NbCU == DEBUG_NumCU)\r
357#endif\r
358 {\r
359 // Get 1st Die from the Compilation Unit\r
360 if (dwarf_siblingof(dbg, NULL, &return_sib, &error) == DW_DLV_OK)\r
361 {\r
362 // Get Die's Tag\r
363 if ((dwarf_tag(return_sib, &return_tagval, &error) == DW_DLV_OK))\r
364 {\r
365 PtrCU[NbCU].Tag = return_tagval;\r
366\r
367 // Die type detection\r
368 switch (return_tagval)\r
369 {\r
370 case DW_TAG_compile_unit:\r
371 if (dwarf_attrlist(return_sib, &atlist, &atcnt, &error) == DW_DLV_OK)\r
372 {\r
373 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
374 {\r
375 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
376 {\r
377 switch (return_attr)\r
378 {\r
379 // Start address\r
380 case DW_AT_low_pc:\r
381 if (dwarf_lowpc(return_sib, &return_lowpc, &error) == DW_DLV_OK)\r
382 {\r
383 PtrCU[NbCU].LowPC = return_lowpc;\r
384 }\r
385 break;\r
386\r
387 // End address\r
388 case DW_AT_high_pc:\r
389 if (dwarf_highpc(return_sib, &return_highpc, &error) == DW_DLV_OK)\r
390 {\r
391 PtrCU[NbCU].HighPC = return_highpc;\r
392 }\r
393 break;\r
394\r
395 // compilation information\r
396 case DW_AT_producer:\r
397 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
398 {\r
399 PtrCU[NbCU].PtrProducer = (char *)calloc(strlen(return_string) + 1, 1);\r
400 strcpy(PtrCU[NbCU].PtrProducer, return_string);\r
401 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
402 }\r
403 break;\r
404\r
405 // Filename\r
406 case DW_AT_name:\r
407 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
408 {\r
409#ifdef DEBUG_Filename\r
410 if (strstr(return_string, DEBUG_Filename))\r
411#endif\r
412 {\r
413 PtrCU[NbCU].PtrSourceFilename = (char *)calloc((strlen(return_string) + 1), 1);\r
414 strcpy(PtrCU[NbCU].PtrSourceFilename, return_string);\r
415 }\r
416 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
417 }\r
418 break;\r
419\r
420 // Directory name\r
421 case DW_AT_comp_dir:\r
422 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
423 {\r
424 PtrCU[NbCU].PtrSourceFileDirectory = (char *)calloc((strlen(return_string) + 1), 1);\r
425 strcpy(PtrCU[NbCU].PtrSourceFileDirectory, return_string);\r
426 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
427 }\r
428 break;\r
429\r
430 default:\r
431 break;\r
432 }\r
433 }\r
434 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
435 }\r
436 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
437 }\r
438\r
439 // Check filename presence\r
440 if (!PtrCU[NbCU].PtrSourceFilename)\r
441 {\r
442 PtrCU[NbCU].PtrSourceFilename = (char *)calloc(1, 1);\r
443 }\r
444\r
445 // Check directory presence\r
446 if (!PtrCU[NbCU].PtrSourceFileDirectory)\r
447 {\r
448 // Check if file exists in the search paths\r
449 for (size_t i = 0; i < NbSearchPaths; i++)\r
450 {\r
451 PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen((const char *)ListSearchPaths[i]) + 2);\r
452#if defined(_WIN32)\r
453 sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", ListSearchPaths[i], PtrCU[NbCU].PtrSourceFilename);\r
454#else\r
455 sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", ListSearchPaths[i], PtrCU[NbCU].PtrSourceFilename);\r
456#endif\r
457 if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rb"))\r
458 {\r
459 PtrCU[NbCU].PtrSourceFileDirectory = (char *)realloc(PtrCU[NbCU].PtrSourceFileDirectory, strlen(ListSearchPaths[i]) + 1);\r
460 strcpy(PtrCU[NbCU].PtrSourceFileDirectory, ListSearchPaths[i]);\r
461 }\r
462 }\r
463\r
464 // File directory doesn't exits\r
465 if (!PtrCU[NbCU].PtrSourceFileDirectory)\r
466 {\r
467 PtrCU[NbCU].PtrSourceFileDirectory = (char *)realloc(PtrCU[NbCU].PtrSourceFileDirectory, 2);\r
468 strcpy(PtrCU[NbCU].PtrSourceFileDirectory, ".");\r
469 }\r
470 }\r
471\r
472 // Create full filename\r
473 Ptr = PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen(PtrCU[NbCU].PtrSourceFileDirectory) + 2);\r
474#if defined(_WIN32)\r
475 sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
476#else\r
477 sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
478#endif\r
479 // Conform slashes and backslashes\r
480 while (*Ptr)\r
481 {\r
482#if defined(_WIN32)\r
483 if (*Ptr == '/')\r
484 {\r
485 *Ptr = '\\';\r
486 }\r
487#else\r
488 if (*Ptr == '\\')\r
489 {\r
490 *Ptr = '/';\r
491 }\r
492#endif\r
493 Ptr++;\r
494 }\r
495\r
496 // Directory path clean-up\r
497#if defined(_WIN32)\r
498 while ((Ptr1 = Ptr = strstr(PtrCU[NbCU].PtrFullFilename, "\\..\\")))\r
499#else\r
500 while ((Ptr1 = Ptr = strstr(PtrCU[NbCU].PtrFullFilename, "/../")))\r
501#endif\r
502 {\r
503#if defined(_WIN32)\r
504 while (*--Ptr1 != '\\');\r
505#else\r
506 while (*--Ptr1 != '/');\r
507#endif\r
508 strcpy((Ptr1 + 1), (Ptr + 4));\r
509 }\r
510\r
511 // Open the source file as a binary file\r
512 if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rb"))\r
513 {\r
514 if (!fseek(SrcFile, 0, SEEK_END))\r
515 {\r
516 if ((PtrCU[NbCU].SizeLoadSrc = ftell(SrcFile)) > 0)\r
517 {\r
518 if (!fseek(SrcFile, 0, SEEK_SET))\r
519 {\r
520 if (PtrCU[NbCU].PtrLoadSrc = Ptr = Ptr1 = (char *)calloc(1, (PtrCU[NbCU].SizeLoadSrc + 2)))\r
521 {\r
522 // Read whole file\r
523 if (fread_s(PtrCU[NbCU].PtrLoadSrc, PtrCU[NbCU].SizeLoadSrc, PtrCU[NbCU].SizeLoadSrc, 1, SrcFile) != 1)\r
524 {\r
525 free(PtrCU[NbCU].PtrLoadSrc);\r
526 PtrCU[NbCU].PtrLoadSrc = NULL;\r
527 PtrCU[NbCU].SizeLoadSrc = 0;\r
528 }\r
529 else\r
530 {\r
531 // Eliminate all carriage return code '\r' (oxd)\r
532 do\r
533 {\r
534 if ((*Ptr = *Ptr1) != '\r')\r
535 {\r
536 Ptr++;\r
537 }\r
538 }\r
539 while (*Ptr1++);\r
540\r
541 // Get back the new text file size\r
542 PtrCU[NbCU].SizeLoadSrc = strlen(Ptr = PtrCU[NbCU].PtrLoadSrc);\r
543\r
544 // Make sure the text file finish with a new line code '\n' (0xa)\r
545 if (PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc - 1] != '\n')\r
546 {\r
547 PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc++] = '\n';\r
548 PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc] = 0;\r
549 }\r
550\r
551 // Reallocate text file\r
552 if (PtrCU[NbCU].PtrLoadSrc = Ptr = (char *)realloc(PtrCU[NbCU].PtrLoadSrc, (PtrCU[NbCU].SizeLoadSrc + 1)))\r
553 {\r
554 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0\r
555 do\r
556 {\r
557 if (*Ptr == '\n')\r
558 {\r
559 PtrCU[NbCU].NbLinesLoadSrc++;\r
560 *Ptr = 0;\r
561 }\r
562 } while (*++Ptr);\r
563 }\r
564 }\r
565 }\r
566 }\r
567 }\r
568 }\r
569 fclose(SrcFile);\r
570 }\r
571 break;\r
572\r
573 default:\r
574 break;\r
575 }\r
576 }\r
577\r
578 // Get the source lines table located in the CU\r
579 if (dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK)\r
580 {\r
581 if (cnt)\r
582 {\r
583 PtrCU[NbCU].NbLinesSrc = cnt;\r
584 PtrCU[NbCU].PtrLinesSrc = (CUStruct_LineSrc *)calloc(cnt, sizeof(CUStruct_LineSrc));\r
585 for (Dwarf_Signed i = 0; i < cnt; i++)\r
586 {\r
587 if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
588 {\r
589 // Get the source line number\r
590 if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
591 {\r
592 PtrCU[NbCU].PtrLinesSrc[i].StartPC = return_lineaddr;\r
593 PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc = return_uvalue;\r
594 }\r
595 }\r
596 }\r
597 }\r
598\r
599 // Release the memory used by the source lines table located in the CU\r
600 dwarf_srclines_dealloc(dbg, linebuf, cnt);\r
601 }\r
602\r
603 // Check if the CU has child\r
604 if (dwarf_child(return_sib, &return_die, &error) == DW_DLV_OK)\r
605 {\r
606 do\r
607 {\r
608 return_sib = return_die;\r
609 if ((dwarf_tag(return_die, &return_tagval, &error) == DW_DLV_OK))\r
610 {\r
611 switch (return_tagval)\r
612 {\r
613 case DW_TAG_lexical_block:\r
614 break;\r
615\r
616 case DW_TAG_variable:\r
617 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
618 {\r
619 PtrCU[NbCU].PtrVariables = (VariablesStruct *)realloc(PtrCU[NbCU].PtrVariables, ((PtrCU[NbCU].NbVariables + 1) * sizeof(VariablesStruct)));\r
620 memset(PtrCU[NbCU].PtrVariables + PtrCU[NbCU].NbVariables, 0, sizeof(VariablesStruct));\r
621\r
622 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
623 {\r
624 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
625 {\r
626 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
627 {\r
628 switch (return_attr)\r
629 {\r
630 case DW_AT_location:\r
631 if (dwarf_formblock(return_attr1, &return_block, &error) == DW_DLV_OK)\r
632 {\r
633 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].Op = (*((unsigned char *)(return_block->bl_data)));\r
634\r
635 switch (return_block->bl_len)\r
636 {\r
637 case 5:\r
638 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
639 break;\r
640\r
641 default:\r
642 break;\r
643 }\r
644 dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);\r
645 }\r
646 break;\r
647\r
648 case DW_AT_type:\r
649 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
650 {\r
651 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].TypeOffset = return_offset;\r
652 }\r
653 break;\r
654\r
655 // Variable name\r
656 case DW_AT_name:\r
657 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
658 {\r
659#ifdef DEBUG_VariableName\r
660 if (!strcmp(return_string, DEBUG_VariableName))\r
661#endif\r
662 {\r
663 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
664 strcpy(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName, return_string);\r
665 }\r
666 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
667 }\r
668 break;\r
669\r
670 default:\r
671 break;\r
672 }\r
673 }\r
674 }\r
675\r
676 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
677 }\r
678\r
679 // Check variable's name validity\r
680 if (PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName)\r
681 {\r
682 // Check variable's memory address validity\r
683 if (PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].Addr)\r
684 {\r
685 // Valid variable\r
686 PtrCU[NbCU].NbVariables++;\r
687 }\r
688 else\r
689 {\r
690 // Invalid variable\r
691 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);\r
692 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName = NULL;\r
693 }\r
694 }\r
695\r
696 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
697 }\r
698 break;\r
699\r
700 case DW_TAG_base_type:\r
701 case DW_TAG_typedef:\r
702 case DW_TAG_structure_type:\r
703 case DW_TAG_pointer_type:\r
704 case DW_TAG_const_type:\r
705 case DW_TAG_array_type:\r
706 case DW_TAG_subrange_type:\r
707 case DW_TAG_subroutine_type:\r
708 case DW_TAG_enumeration_type:\r
709 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
710 {\r
711 // Allocate memory for this type\r
712 PtrCU[NbCU].PtrTypes = (BaseTypeStruct *)realloc(PtrCU[NbCU].PtrTypes, ((PtrCU[NbCU].NbTypes + 1) * sizeof(BaseTypeStruct)));\r
713 memset(PtrCU[NbCU].PtrTypes + PtrCU[NbCU].NbTypes, 0, sizeof(BaseTypeStruct));\r
714 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Tag = return_tagval;\r
715\r
716 if (dwarf_dieoffset(return_die, &return_offset, &error) == DW_DLV_OK)\r
717 {\r
718 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Offset = return_offset;\r
719 }\r
720\r
721 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
722 {\r
723 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
724 {\r
725 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
726 {\r
727 switch (return_attr)\r
728 {\r
729 // \r
730 case DW_AT_sibling:\r
731 break;\r
732\r
733 // Type's type offset\r
734 case DW_AT_type:\r
735 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
736 {\r
737 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].TypeOffset = return_offset;\r
738 }\r
739 break;\r
740\r
741 // Type's byte size\r
742 case DW_AT_byte_size:\r
743 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
744 {\r
745 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].ByteSize = return_uvalue;\r
746 }\r
747 break;\r
748\r
749 // Type's encoding\r
750 case DW_AT_encoding:\r
751 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
752 {\r
753 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Encoding = return_uvalue;\r
754 }\r
755 break;\r
756\r
757 // Type's name\r
758 case DW_AT_name:\r
759 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
760 {\r
761#ifdef DEBUG_TypeName\r
762 if (!strcmp(return_string, DEBUG_TypeName))\r
763#endif\r
764 {\r
765 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
766 strcpy(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName, return_string);\r
767 }\r
768 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
769 }\r
770 break;\r
771\r
772 // Type's file number\r
773 case DW_AT_decl_file:\r
774 break;\r
775\r
776 // Type's line number\r
777 case DW_AT_decl_line:\r
778 break;\r
779\r
780 default:\r
781 break;\r
782 }\r
783 }\r
784 }\r
785\r
786 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
787 }\r
788\r
789 PtrCU[NbCU].NbTypes++;\r
790\r
791 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
792 }\r
793 break;\r
794\r
795 case DW_TAG_subprogram:\r
796 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
797 {\r
798 PtrCU[NbCU].PtrSubProgs = (SubProgStruct *)realloc(PtrCU[NbCU].PtrSubProgs, ((PtrCU[NbCU].NbSubProgs + 1) * sizeof(SubProgStruct)));\r
799 memset((void *)(PtrCU[NbCU].PtrSubProgs + PtrCU[NbCU].NbSubProgs), 0, sizeof(SubProgStruct));\r
800 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].Tag = return_tagval;\r
801\r
802 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
803 {\r
804 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
805 {\r
806 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
807 {\r
808 switch (return_attr)\r
809 {\r
810 // start address\r
811 case DW_AT_low_pc:\r
812 if (dwarf_lowpc(return_die, &return_lowpc, &error) == DW_DLV_OK)\r
813 {\r
814 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].StartPC = return_lowpc;\r
815 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].LowPC = return_lowpc;\r
816 }\r
817 break;\r
818\r
819 // end address\r
820 case DW_AT_high_pc:\r
821 if (dwarf_highpc(return_die, &return_highpc, &error) == DW_DLV_OK)\r
822 {\r
823 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].HighPC = return_highpc;\r
824 }\r
825 break;\r
826\r
827 // Line number\r
828 case DW_AT_decl_line:\r
829 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
830 {\r
831 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NumLineSrc = return_uvalue;\r
832 }\r
833 break;\r
834\r
835 // Frame\r
836 case DW_AT_frame_base:\r
837 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
838 {\r
839 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].FrameBase = return_uvalue;\r
840 PtrCU[NbCU].NbFrames++;\r
841 }\r
842 break;\r
843\r
844 // function name\r
845 case DW_AT_name:\r
846 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
847 {\r
848 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName = (char *)calloc(strlen(return_string) + 1, 1);\r
849 strcpy(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName, return_string);\r
850 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
851 }\r
852 break;\r
853\r
854 case DW_AT_sibling:\r
855 break;\r
856\r
857 case DW_AT_GNU_all_tail_call_sites:\r
858 break;\r
859\r
860 case DW_AT_type:\r
861 break;\r
862\r
863 case DW_AT_prototyped:\r
864 break;\r
865\r
866 // File number\r
867 case DW_AT_decl_file:\r
868 break;\r
869\r
870 case DW_AT_external:\r
871 break;\r
872\r
873 default:\r
874 break;\r
875 }\r
876 }\r
877 }\r
878 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
879 }\r
880 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
881\r
882 // Get source line number and associated block of address\r
883 for (Dwarf_Signed i = 0; i < cnt; ++i)\r
884 {\r
885 if ((PtrCU[NbCU].PtrLinesSrc[i].StartPC >= return_lowpc) && (PtrCU[NbCU].PtrLinesSrc[i].StartPC <= return_highpc))\r
886 {\r
887 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
888 memset((void *)(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc), 0, sizeof(DMIStruct_LineSrc));\r
889 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].StartPC = PtrCU[NbCU].PtrLinesSrc[i].StartPC;\r
890 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].NumLineSrc = PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc;\r
891 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc++;\r
892 }\r
893 }\r
894\r
895 if (dwarf_child(return_die, &return_subdie, &error) == DW_DLV_OK)\r
896 {\r
897 do\r
898 {\r
899 return_sub = return_subdie;\r
900 if ((dwarf_tag(return_subdie, &return_tagval, &error) == DW_DLV_OK))\r
901 {\r
902 switch (return_tagval)\r
903 {\r
904 case DW_TAG_formal_parameter:\r
905 case DW_TAG_variable:\r
906 if (dwarf_attrlist(return_subdie, &atlist, &atcnt, &error) == DW_DLV_OK)\r
907 {\r
908 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables = (VariablesStruct *)realloc(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables, ((PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables + 1) * sizeof(VariablesStruct)));\r
909 memset(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables, 0, sizeof(VariablesStruct));\r
910\r
911 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
912 {\r
913 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
914 {\r
915 if (dwarf_attr(return_subdie, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
916 {\r
917 switch (return_attr)\r
918 {\r
919 case DW_AT_location:\r
920 if (dwarf_formblock(return_attr1, &return_block, &error) == DW_DLV_OK)\r
921 {\r
922 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Op = *((unsigned char *)(return_block->bl_data));\r
923\r
924 switch (return_block->bl_len)\r
925 {\r
926 case 1:\r
927 break;\r
928\r
929 case 2:\r
930 case 3:\r
931 switch (return_tagval)\r
932 {\r
933 case DW_TAG_variable:\r
934 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Offset = ReadLEB128((char *)return_block->bl_data + 1);\r
935 break;\r
936\r
937 case DW_TAG_formal_parameter:\r
938 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Offset = ReadULEB128((char *)return_block->bl_data + 1);\r
939 break;\r
940\r
941 default:\r
942 break;\r
943 }\r
944 break;\r
945\r
946 default:\r
947 break;\r
948 }\r
949 dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);\r
950 }\r
951 break;\r
952\r
953 case DW_AT_type:\r
954 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
955 {\r
956 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].TypeOffset = return_offset;\r
957 }\r
958 break;\r
959\r
960 case DW_AT_name:\r
961 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
962 {\r
963#ifdef DEBUG_VariableName\r
964 if (!strcmp(return_string, DEBUG_VariableName))\r
965#endif\r
966 {\r
967 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
968 strcpy(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName, return_string);\r
969 }\r
970 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
971 }\r
972 break;\r
973\r
974 case DW_AT_decl_file:\r
975 break;\r
976\r
977 case DW_AT_decl_line:\r
978 break;\r
979\r
980 default:\r
981 break;\r
982 }\r
983 }\r
984 }\r
985\r
986 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
987 }\r
988\r
989 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables++;\r
990\r
991 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
992 }\r
993 break;\r
994\r
995 case DW_TAG_label:\r
996 break;\r
997\r
998 default:\r
999 break;\r
1000 }\r
1001 }\r
1002 }\r
1003 while (dwarf_siblingof(dbg, return_sub, &return_subdie, &error) == DW_DLV_OK);\r
1004 }\r
1005\r
1006 PtrCU[NbCU].NbSubProgs++;\r
1007 }\r
1008 break;\r
1009\r
1010 default:\r
1011 break;\r
1012 }\r
1013 }\r
1014 }\r
1015 while (dwarf_siblingof(dbg, return_sib, &return_die, &error) == DW_DLV_OK);\r
1016 }\r
1017 }\r
1018\r
1019 // Set the source code lines for QT html/text conformity\r
1020 if (PtrCU[NbCU].NbLinesLoadSrc)\r
1021 {\r
1022 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(PtrCU[NbCU].NbLinesLoadSrc, sizeof(char *)))\r
1023 {\r
1024 for (size_t j = 0; j < PtrCU[NbCU].NbLinesLoadSrc; j++)\r
1025 {\r
1026 if (PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)calloc(10000, sizeof(char)))\r
1027 {\r
1028 if (Ptr = DWARFManager_GetLineSrcFromNumLine(PtrCU[NbCU].PtrLoadSrc, (j + 1)))\r
1029 {\r
1030 size_t i = 0;\r
1031\r
1032 while (*Ptr)\r
1033 {\r
1034 switch (*Ptr)\r
1035 {\r
1036 case 9:\r
1037 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");\r
1038 i += 6;\r
1039 break;\r
1040\r
1041 case '<':\r
1042 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&lt;");\r
1043 i += 4;\r
1044 break;\r
1045\r
1046 case '>':\r
1047 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&gt;");\r
1048 i += 4;\r
1049 break;\r
1050#if 0\r
1051 case '&':\r
1052 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&amp;");\r
1053 i += strlen("&amp;");\r
1054 break;\r
1055#endif\r
1056#if 0\r
1057 case '"':\r
1058 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");\r
1059 i += strlen("&quot;");\r
1060 break;\r
1061#endif\r
1062 default:\r
1063 PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;\r
1064 break;\r
1065 }\r
1066 Ptr++;\r
1067 }\r
1068 }\r
1069 PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)realloc(PtrCU[NbCU].PtrLinesLoadSrc[j], strlen(PtrCU[NbCU].PtrLinesLoadSrc[j]) + 1);\r
1070 }\r
1071 }\r
1072\r
1073 // Init lines source information for each source code line numbers and for each subprogs\r
1074 for (size_t j = 0; j < PtrCU[NbCU].NbSubProgs; j++)\r
1075 {\r
1076 // Check if the subprog / function's line exists in the source code\r
1077 if (PtrCU[NbCU].PtrSubProgs[j].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
1078 {\r
1079 PtrCU[NbCU].PtrSubProgs[j].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].NumLineSrc - 1];\r
1080 }\r
1081\r
1082 for (size_t k = 0; k < PtrCU[NbCU].PtrSubProgs[j].NbLinesSrc; k++)\r
1083 {\r
1084 if (PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
1085 {\r
1086 PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc - 1];\r
1087 }\r
1088 }\r
1089 }\r
1090 }\r
1091 }\r
1092 else\r
1093 {\r
1094 // Set each source lines pointer to NULL\r
1095 if (PtrCU[NbCU].NbSubProgs)\r
1096 {\r
1097 // Check the presence of source lines dedicated to the sub progs\r
1098 if (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc)\r
1099 {\r
1100 size_t i = PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc - 1].NumLineSrc;\r
1101 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(i, sizeof(char *)))\r
1102 {\r
1103 for (size_t j = 0; j < i; j++)\r
1104 {\r
1105 PtrCU[NbCU].PtrLinesLoadSrc[j] = NULL;\r
1106 }\r
1107 }\r
1108 }\r
1109 }\r
1110 }\r
1111\r
1112 // Set information based on used line numbers\r
1113 if (PtrCU[NbCU].PtrLinesSrc)\r
1114 {\r
1115 // Set the line source pointer for each used line numbers\r
1116 if (PtrCU[NbCU].PtrLinesLoadSrc)\r
1117 {\r
1118 for (size_t i = 0; i < PtrCU[NbCU].NbLinesSrc; i++)\r
1119 {\r
1120 PtrCU[NbCU].PtrLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc - 1];\r
1121 }\r
1122\r
1123 // Setup memory range for the code if CU doesn't have already this information\r
1124 // It is taken from the used lines structure\r
1125 if (!PtrCU[NbCU].LowPC && (!PtrCU[NbCU].HighPC || (PtrCU[NbCU].HighPC == ~0)))\r
1126 {\r
1127 PtrCU[NbCU].LowPC = PtrCU[NbCU].PtrLinesSrc[0].StartPC;\r
1128 PtrCU[NbCU].HighPC = PtrCU[NbCU].PtrLinesSrc[PtrCU[NbCU].NbLinesSrc - 1].StartPC;\r
1129 }\r
1130 }\r
1131 }\r
1132\r
1133 // Init global variables information based on types information\r
1134 for (size_t i = 0; i < PtrCU[NbCU].NbVariables; i++)\r
1135 {\r
1136 DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrVariables + i);\r
1137 }\r
1138\r
1139 // Init local variables information based on types information\r
1140 for (size_t i = 0; i < PtrCU[NbCU].NbSubProgs; i++)\r
1141 {\r
1142 for (size_t j = 0; j < PtrCU[NbCU].PtrSubProgs[i].NbVariables; j++)\r
1143 {\r
1144 DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrSubProgs[i].PtrVariables + j);\r
1145 }\r
1146 }\r
1147 }\r
1148\r
1149 ++NbCU;\r
1150 }\r
1151 } \r
1152}\r
1153\r
1154\r
1155// Variables information initialisation\r
1156void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)\r
1157{\r
1158 size_t j, TypeOffset;\r
1159\r
1160#ifdef DEBUG_VariableName\r
1161 if (PtrVariables->PtrName && !strcmp(PtrVariables->PtrName, DEBUG_VariableName))\r
1162#endif\r
1163 {\r
1164 PtrVariables->PtrTypeName = (char *)calloc(1000, 1);\r
1165 TypeOffset = PtrVariables->TypeOffset;\r
1166\r
1167 for (j = 0; j < PtrCU[NbCU].NbTypes; j++)\r
1168 {\r
1169 if (TypeOffset == PtrCU[NbCU].PtrTypes[j].Offset)\r
1170 {\r
1171 switch (PtrCU[NbCU].PtrTypes[j].Tag)\r
1172 {\r
1173 case DW_TAG_subroutine_type:\r
1174 PtrVariables->TypeTag |= TypeTag_subroutine_type;\r
1175 strcat(PtrVariables->PtrTypeName, " (* ) ()");\r
1176 break;\r
1177\r
1178 // Structure type tag\r
1179 case DW_TAG_structure_type:\r
1180 PtrVariables->TypeTag |= TypeTag_structure;\r
1181 if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
1182 {\r
1183 if (PtrCU[NbCU].PtrTypes[j].PtrName)\r
1184 {\r
1185 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
1186 }\r
1187 }\r
1188 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1189 {\r
1190 j = -1;\r
1191 }\r
1192 else\r
1193 {\r
1194 if ((PtrVariables->TypeTag & TypeTag_pointer))\r
1195 {\r
1196 strcat(PtrVariables->PtrTypeName, " *");\r
1197 }\r
1198 }\r
1199 break;\r
1200\r
1201 // Pointer type tag\r
1202 case DW_TAG_pointer_type:\r
1203 PtrVariables->TypeTag |= TypeTag_pointer;\r
1204 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
1205 PtrVariables->TypeEncoding = 0x10;\r
1206 if (!(TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1207 {\r
1208 strcat(PtrVariables->PtrTypeName, "void *");\r
1209 }\r
1210 else\r
1211 {\r
1212 j = -1;\r
1213 }\r
1214 break;\r
1215\r
1216 case DW_TAG_enumeration_type:\r
1217 PtrVariables->TypeTag |= TypeTag_enumeration_type;\r
1218 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
1219 if (!(PtrVariables->TypeEncoding = PtrCU[NbCU].PtrTypes[j].Encoding))\r
1220 {\r
1221 // Try to determine the possible size\r
1222 switch (PtrVariables->TypeByteSize)\r
1223 {\r
1224 case 4:\r
1225 PtrVariables->TypeEncoding = 0x7;\r
1226 break;\r
1227\r
1228 default:\r
1229 break;\r
1230 }\r
1231 }\r
1232 break;\r
1233\r
1234 // Typedef type tag\r
1235 case DW_TAG_typedef:\r
1236 if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
1237 {\r
1238 PtrVariables->TypeTag |= TypeTag_typedef;\r
1239 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
1240 }\r
1241 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1242 {\r
1243 j = -1;\r
1244 }\r
1245 break;\r
1246\r
1247 // ? type tag\r
1248 case DW_TAG_subrange_type:\r
1249 PtrVariables->TypeTag |= TypeTag_subrange;\r
1250 break;\r
1251\r
1252 // Array type tag\r
1253 case DW_TAG_array_type:\r
1254 PtrVariables->TypeTag |= TypeTag_arraytype;\r
1255 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1256 {\r
1257 j = -1;\r
1258 }\r
1259 break;\r
1260\r
1261 // Const type tag\r
1262 case DW_TAG_const_type:\r
1263 PtrVariables->TypeTag |= TypeTag_consttype;\r
1264 strcat(PtrVariables->PtrTypeName, "const ");\r
1265 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1266 {\r
1267 j = -1;\r
1268 }\r
1269 break;\r
1270\r
1271 // Base type tag\r
1272 case DW_TAG_base_type:\r
1273 if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
1274 {\r
1275 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
1276 }\r
1277 if ((PtrVariables->TypeTag & TypeTag_pointer))\r
1278 {\r
1279 strcat(PtrVariables->PtrTypeName, " *");\r
1280 }\r
1281 else\r
1282 {\r
1283 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
1284 PtrVariables->TypeEncoding = PtrCU[NbCU].PtrTypes[j].Encoding;\r
1285 }\r
1286 if ((PtrVariables->TypeTag & TypeTag_arraytype))\r
1287 {\r
1288 strcat(PtrVariables->PtrTypeName, "[]");\r
1289 }\r
1290 break;\r
1291\r
1292 default:\r
1293 break;\r
1294 }\r
1295 }\r
1296 }\r
1297 }\r
1298}\r
1299\r
1300\r
1301// Get symbol name based from address\r
1302// Return NULL if no symbol name exists\r
1303char *DWARFManager_GetSymbolnameFromAdr(size_t Adr)\r
1304{\r
1305 for (size_t i = 0; i < NbCU; i++)\r
1306 {\r
1307 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1308 {\r
1309 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1310 {\r
1311 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr))\r
1312 {\r
1313 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;\r
1314 }\r
1315 }\r
1316 }\r
1317 }\r
1318\r
1319 return NULL;\r
1320}\r
1321\r
1322\r
1323// Get complete source filename based from address\r
1324// Return NULL if no source filename exists\r
1325// Return the existence status (true or false) in Error\r
1326char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error)\r
1327{\r
1328 for (size_t i = 0; i < NbCU; i++)\r
1329 {\r
1330 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1331 {\r
1332 *Error = PtrCU[i].PtrLoadSrc ? true : false;\r
1333 return PtrCU[i].PtrFullFilename;\r
1334 }\r
1335 }\r
1336\r
1337 return NULL;\r
1338}\r
1339\r
1340\r
1341// Get text line source based on line number (starting from 1)\r
1342// Return NULL if no text line exists or if line number is 0\r
1343char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine)\r
1344{\r
1345 size_t i = 0;\r
1346 char *PtrLineSrc = NULL;\r
1347\r
1348 if (PtrSrcFile)\r
1349 {\r
1350 while (i != NumLine)\r
1351 {\r
1352 PtrLineSrc = PtrSrcFile;\r
1353 while (*PtrSrcFile++);\r
1354 i++;\r
1355 }\r
1356 }\r
1357\r
1358 return PtrLineSrc;\r
1359}\r
1360\r
1361\r
1362// Get number of variables referenced by the function range address\r
1363size_t DWARFManager_GetNbLocalVariables(size_t Adr)\r
1364{\r
1365 for (size_t i = 0; i < NbCU; i++)\r
1366 {\r
1367 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1368 {\r
1369 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1370 {\r
1371 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1372 {\r
1373 return PtrCU[i].PtrSubProgs[j].NbVariables;\r
1374 }\r
1375 }\r
1376 }\r
1377 }\r
1378\r
1379 return 0;\r
1380}\r
1381\r
1382\r
1383// Get local variable name based on his index (starting from 1)\r
1384// Return name's pointer text found\r
1385// Return NULL if not found\r
1386char *DWARFManager_GetLocalVariableName(size_t Adr, size_t Index)\r
1387{\r
1388 for (size_t i = 0; i < NbCU; i++)\r
1389 {\r
1390 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1391 {\r
1392 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1393 {\r
1394 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1395 {\r
1396 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].PtrName;\r
1397 }\r
1398 }\r
1399 }\r
1400 }\r
1401\r
1402 return NULL;\r
1403}\r
1404\r
1405\r
1406// Get local variable's type tag based on his index (starting from 1)\r
1407// Return 0 if not found\r
1408size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr, size_t Index)\r
1409{\r
1410 for (size_t i = 0; i < NbCU; i++)\r
1411 {\r
1412 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1413 {\r
1414 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1415 {\r
1416 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1417 {\r
1418 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeTag;\r
1419 }\r
1420 }\r
1421 }\r
1422 }\r
1423\r
1424 return 0;\r
1425}\r
1426\r
1427\r
1428// Get the local variable's offset based on a index (starting from 1)\r
1429// Return 0 if no offset has been found\r
1430int DWARFManager_GetLocalVariableOffset(size_t Adr, size_t Index)\r
1431{\r
1432 for (size_t i = 0; i < NbCU; i++)\r
1433 {\r
1434 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1435 {\r
1436 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1437 {\r
1438 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1439 {\r
1440 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].Offset;\r
1441 }\r
1442 }\r
1443 }\r
1444 }\r
1445\r
1446 return 0;\r
1447}\r
1448\r
1449\r
1450// Get local variable Type Byte Size based on his address and index (starting from 1)\r
1451// Return 0 if not found\r
1452// May return 0 if there is no Type Byte Size linked to the variable's address and index\r
1453size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr, size_t Index)\r
1454{\r
1455 for (size_t i = 0; i < NbCU; i++)\r
1456 {\r
1457 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1458 {\r
1459 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1460 {\r
1461 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1462 {\r
1463 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeByteSize;\r
1464 }\r
1465 }\r
1466 }\r
1467 }\r
1468\r
1469 return 0;\r
1470}\r
1471\r
1472\r
1473// Get local variable Type Encoding based on his address and index (starting from 1)\r
1474// Return 0 if not found\r
1475// May return 0 if there is no Type Encoding linked to the variable's address and index\r
1476size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr, size_t Index)\r
1477{\r
1478 for (size_t i = 0; i < NbCU; i++)\r
1479 {\r
1480 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1481 {\r
1482 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1483 {\r
1484 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1485 {\r
1486 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeEncoding;\r
1487 }\r
1488 }\r
1489 }\r
1490 }\r
1491\r
1492 return 0;\r
1493}\r
1494\r
1495\r
1496// Get local variable Op based on his address and index (starting from 1)\r
1497// Return 0 if not found, may return 0 if there isn't Op linked to the variable's index\r
1498size_t DWARFManager_GetLocalVariableOp(size_t Adr, size_t Index)\r
1499{\r
1500 for (size_t i = 0; i < NbCU; i++)\r
1501 {\r
1502 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1503 {\r
1504 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1505 {\r
1506 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1507 {\r
1508 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].Op;\r
1509 }\r
1510 }\r
1511 }\r
1512 }\r
1513\r
1514 return 0;\r
1515}\r
1516\r
1517\r
1518// Get local variable type name based on his index (starting from 1) and an address\r
1519// Return NULL if not found, may also return NULL if there is no type linked to the variable's index\r
1520char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)\r
1521{\r
1522 for (size_t i = 0; i < NbCU; i++)\r
1523 {\r
1524 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1525 {\r
1526 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1527 {\r
1528 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1529 {\r
1530 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].PtrTypeName;\r
1531 }\r
1532 }\r
1533 }\r
1534 }\r
1535\r
1536 return NULL;\r
1537}\r
1538\r
1539\r
1540// Get Compilation Unit / global variables numbers\r
1541// Return number of variables\r
1542size_t DWARFManager_GetNbGlobalVariables(void)\r
1543{\r
1544 size_t NbVariables = 0;\r
1545\r
1546 for (size_t i = 0; i < NbCU; i++)\r
1547 {\r
1548 NbVariables += PtrCU[i].NbVariables;\r
1549 }\r
1550\r
1551 return NbVariables;\r
1552}\r
1553\r
1554\r
1555// Get global variable type name based on his index (starting from 1)\r
1556// Return NULL if not found\r
1557// May return NULL if there is not type linked to the variable's index\r
1558char *DWARFManager_GetGlobalVariableTypeName(size_t Index)\r
1559{\r
1560 for (size_t i = 0; i < NbCU; i++)\r
1561 {\r
1562 if (PtrCU[i].NbVariables)\r
1563 {\r
1564 if (Index <= PtrCU[i].NbVariables)\r
1565 {\r
1566 return PtrCU[i].PtrVariables[Index - 1].PtrTypeName;\r
1567 }\r
1568 else\r
1569 {\r
1570 Index -= PtrCU[i].NbVariables;\r
1571 }\r
1572 }\r
1573 }\r
1574\r
1575 return NULL;\r
1576}\r
1577\r
1578\r
1579// Get global variable's type tag based on his index (starting from 1)\r
1580// Return 0 if not found\r
1581size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index)\r
1582{\r
1583 for (size_t i = 0; i < NbCU; i++)\r
1584 {\r
1585 if (PtrCU[i].NbVariables)\r
1586 {\r
1587 if (Index <= PtrCU[i].NbVariables)\r
1588 {\r
1589 return PtrCU[i].PtrVariables[Index - 1].TypeTag;\r
1590 }\r
1591 else\r
1592 {\r
1593 Index -= PtrCU[i].NbVariables;\r
1594 }\r
1595 }\r
1596 }\r
1597\r
1598 return 0;\r
1599}\r
1600\r
1601\r
1602// Get global variable byte size based on his index (starting from 1)\r
1603// Return 0 if not found\r
1604size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index)\r
1605{\r
1606 for (size_t i = 0; i < NbCU; i++)\r
1607 {\r
1608 if (PtrCU[i].NbVariables)\r
1609 {\r
1610 if (Index <= PtrCU[i].NbVariables)\r
1611 {\r
1612 return PtrCU[i].PtrVariables[Index - 1].TypeByteSize;\r
1613 }\r
1614 else\r
1615 {\r
1616 Index -= PtrCU[i].NbVariables;\r
1617 }\r
1618 }\r
1619 }\r
1620\r
1621 return 0;\r
1622}\r
1623\r
1624\r
1625// Get global variable encoding based on his index (starting from 1)\r
1626// Return 0 if not found\r
1627size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index)\r
1628{\r
1629 for (size_t i = 0; i < NbCU; i++)\r
1630 {\r
1631 if (PtrCU[i].NbVariables)\r
1632 {\r
1633 if (Index <= PtrCU[i].NbVariables)\r
1634 {\r
1635 return PtrCU[i].PtrVariables[Index - 1].TypeEncoding;\r
1636 }\r
1637 else\r
1638 {\r
1639 Index -= PtrCU[i].NbVariables;\r
1640 }\r
1641 }\r
1642 }\r
1643\r
1644 return 0;\r
1645}\r
1646\r
1647\r
1648// Get global variable memory address based on his index (starting from 1)\r
1649// Return 0 if not found\r
1650size_t DWARFManager_GetGlobalVariableAdr(size_t Index)\r
1651{\r
1652 for (size_t i = 0; i < NbCU; i++)\r
1653 {\r
1654 if (PtrCU[i].NbVariables)\r
1655 {\r
1656 if (Index <= PtrCU[i].NbVariables)\r
1657 {\r
1658 return PtrCU[i].PtrVariables[Index - 1].Addr;\r
1659 }\r
1660 else\r
1661 {\r
1662 Index -= PtrCU[i].NbVariables;\r
1663 }\r
1664 }\r
1665 }\r
1666\r
1667 return 0;\r
1668}\r
1669\r
1670\r
1671// Get global variable memory address based on his name\r
1672// Return 0 if not found, or will return the first occurence found\r
1673size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)\r
1674{\r
1675 for (size_t i = 0; i < NbCU; i++)\r
1676 {\r
1677 if (PtrCU[i].NbVariables)\r
1678 {\r
1679 for (size_t j = 0; j < PtrCU[i].NbVariables; j++)\r
1680 {\r
1681 if (!strcmp(PtrCU[i].PtrVariables[j].PtrName,VariableName))\r
1682 {\r
1683 return PtrCU[i].PtrVariables[j].Addr;\r
1684 }\r
1685 }\r
1686 }\r
1687 }\r
1688\r
1689 return 0;\r
1690}\r
1691\r
1692\r
1693// Get global variable name based on his index (starting from 1)\r
1694// Return name's pointer text found, or will return NULL if no variable can be found\r
1695char *DWARFManager_GetGlobalVariableName(size_t Index)\r
1696{\r
1697 for (size_t i = 0; i < NbCU; i++)\r
1698 {\r
1699 if (PtrCU[i].NbVariables)\r
1700 {\r
1701 if (Index <= PtrCU[i].NbVariables)\r
1702 {\r
1703 return PtrCU[i].PtrVariables[Index - 1].PtrName;\r
1704 }\r
1705 else\r
1706 {\r
1707 Index -= PtrCU[i].NbVariables;\r
1708 }\r
1709 }\r
1710 }\r
1711\r
1712 return NULL;\r
1713}\r
1714\r
1715\r
1716// Get text line from source based on address and his tag\r
1717// A tag can be either 0 or a DW_TAG_subprogram\r
1718// DW_TAG_subprogram will look for the line pointing to the function\r
1719// Return NULL if no text line has been found\r
1720char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)\r
1721{\r
1722 for (size_t i = 0; i < NbCU; i++)\r
1723 {\r
1724 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1725 {\r
1726 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1727 {\r
1728 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1729 {\r
1730 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))\r
1731 {\r
1732 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;\r
1733 }\r
1734 else\r
1735 {\r
1736 for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
1737 {\r
1738 if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC <= Adr)\r
1739 {\r
1740 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
1741 {\r
1742 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;\r
1743 }\r
1744 }\r
1745 else\r
1746 {\r
1747 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k - 1].PtrLineSrc;\r
1748 }\r
1749 }\r
1750 }\r
1751 }\r
1752 }\r
1753 }\r
1754 }\r
1755\r
1756 return NULL;\r
1757}\r
1758\r
1759\r
1760// Get line number based on the address and a tag\r
1761// A tag can be either 0 or a DW_TAG_subprogram\r
1762// DW_TAG_subprogram will look for the line pointing to the function name as described in the source code\r
1763// Return 0 if no line number has been found\r
1764size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)\r
1765{\r
1766 for (size_t i = 0; i < NbCU; i++)\r
1767 {\r
1768 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1769 {\r
1770 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1771 {\r
1772 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1773 {\r
1774 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))\r
1775 {\r
1776 return PtrCU[i].PtrSubProgs[j].NumLineSrc;\r
1777 }\r
1778 else\r
1779 {\r
1780 for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
1781 {\r
1782 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
1783 {\r
1784 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc;\r
1785 }\r
1786 }\r
1787 }\r
1788#if 0\r
1789 if (!Tag || (Tag == DW_TAG_subprogram))\r
1790 {\r
1791 return PtrCU[i].PtrSubProgs[j].NumLineSrc;\r
1792 }\r
1793#endif\r
1794 }\r
1795 }\r
1796\r
1797 // Check if a used line is found with the address\r
1798 for (size_t j = 0; j < PtrCU[i].NbLinesSrc; j++)\r
1799 {\r
1800 if (PtrCU[i].PtrLinesSrc[j].StartPC == Adr)\r
1801 {\r
1802 return PtrCU[i].PtrLinesSrc[j].NumLineSrc;\r
1803 }\r
1804 }\r
1805 }\r
1806 }\r
1807\r
1808 return 0;\r
1809}\r
1810\r
1811\r
1812// Get function name based on an address\r
1813// Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address\r
1814char *DWARFManager_GetFunctionName(size_t Adr)\r
1815{\r
1816 for (size_t i = 0; i < NbCU; i++)\r
1817 {\r
1818 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1819 {\r
1820 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1821 {\r
1822 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1823 {\r
1824 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;\r
1825 }\r
1826 }\r
1827 }\r
1828 }\r
1829\r
1830 return NULL;\r
1831}\r
1832\r
1833\r
1834// Get text line from source based on address and num line (starting from 1)\r
1835// Return NULL if no text line has been found\r
1836char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)\r
1837{\r
1838 for (size_t i = 0; i < NbCU; i++)\r
1839 {\r
1840 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1841 {\r
1842 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
1843 {\r
1844 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1845 {\r
1846 if (PtrCU[i].PtrSubProgs[j].NumLineSrc == NumLine)\r
1847 {\r
1848 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;\r
1849 }\r
1850 else\r
1851 {\r
1852 for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
1853 {\r
1854 if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc == NumLine)\r
1855 {\r
1856 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;\r
1857 }\r
1858 }\r
1859 }\r
1860 }\r
1861 }\r
1862 }\r
1863 }\r
1864\r
1865 return NULL;\r
1866}\r
1867\r
1868\r
1869// Get text line pointer from source, based on address and line number (starting from 1)\r
1870// Return NULL if no text line has been found, or if requested number line is above the source total number of lines\r
1871char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)\r
1872{\r
1873 for (size_t i = 0; i < NbCU; i++)\r
1874 {\r
1875 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1876 {\r
1877 if (NumLine <= PtrCU[i].NbLinesLoadSrc)\r
1878 {\r
1879 return PtrCU[i].PtrLinesLoadSrc[NumLine - 1];\r
1880 }\r
1881 else\r
1882 {\r
1883 return NULL;\r
1884 }\r
1885 }\r
1886 }\r
1887\r
1888 return NULL;\r
1889}\r
1890\r
1891\r
1892// Get number of source code filenames\r
1893size_t DWARFManager_GetNbFullSourceFilename(void)\r
1894{\r
1895 return NbCU;\r
1896}\r
1897\r
1898\r
1899// Get source code filename based on index (starting from 0)\r
1900char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
1901{\r
1902 return (PtrCU[Index].PtrFullFilename);\r
1903}\r
1904\r