2 // DWARFManager.cpp: DWARF format manager
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
9 // --- ---------- ------------------------------------------------------------
10 // JPM Dec./2016 Created this file, and added the DWARF format support
11 // JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information
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
16 // To use pointers instead of arrays usage
29 // Definitions for debugging
30 //#define DEBUG_NumCU 0x9 // CU number to debug or undefine it
31 //#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it
32 //#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it
33 //#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)
34 //#define DEBUG_Filename "net_jag.c" // Filename to look for or undefine it
36 // Definitions for the variables's typetag
37 #define TypeTag_structure 0x01 // structure
38 #define TypeTag_pointer 0x02 // pointer
39 #define TypeTag_subrange 0x04 // (subrange_type?)
40 #define TypeTag_arraytype 0x08 // array type
41 #define TypeTag_consttype 0x10 // const type
42 #define TypeTag_typedef 0x20 // typedef
43 #define TypeTag_enumeration_type 0x40 // enumeration
44 #define TypeTag_subroutine_type 0x80 // subroutine
47 // Source line CU structure
48 typedef struct CUStruct_LineSrc
55 // Source line internal structure
56 typedef struct DMIStruct_LineSrc
64 // Enumeration structure
65 typedef struct EnumerationStruct
67 char *PtrName
; // Enumeration's name
68 size_t value
; // Enumeration's value
71 // Structure members structure
72 //typedef struct StructureMembersStruct
74 //}S_StructureMembersStruct;
76 // Base type internal structure
77 typedef struct BaseTypeStruct
79 size_t Tag
; // Type's Tag
80 size_t Offset
; // Type's offset
81 size_t TypeOffset
; // Type's offset on another type
82 size_t ByteSize
; // Type's Byte Size
83 size_t Encoding
; // Type's encoding
84 char *PtrName
; // Type's name
85 size_t NbEnumeration
; // Type's enumeration numbers
86 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
87 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
90 // Variables internal structure
91 typedef struct VariablesStruct
93 size_t Op
; // Variable's DW_OP
96 size_t Addr
; // Variable memory address
97 int Offset
; // Variable stack offset (signed)
99 char *PtrName
; // Variable's name
100 size_t TypeOffset
; // Offset pointing on the Variable's Type
101 size_t TypeByteSize
; // Variable's Type byte size
102 size_t TypeTag
; // Variable's Type Tag
103 size_t TypeEncoding
; // Variable's Type encoding
104 char *PtrTypeName
; // Variable's Type name
107 // Sub program internal structure
108 typedef struct SubProgStruct
113 size_t LowPC
, HighPC
;
116 char *PtrSubprogramName
; // Sub program name
117 size_t NbLinesSrc
; // Number of lines source used by the sub program
118 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
119 size_t NbVariables
; // Variables number
120 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
123 // Compilation Unit internal structure
124 typedef struct CUStruct
127 size_t LowPC
, HighPC
; // Memory range for the code
128 char *PtrProducer
; // Pointer to the "Producer" text information (mostly compiler and compilation options used)
129 char *PtrSourceFilename
; // Source file name
130 char *PtrSourceFileDirectory
; // Directory of the source file
131 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
132 size_t SizeLoadSrc
; // Source code text size
133 char *PtrLoadSrc
; // Pointer to the source code text
134 size_t NbLinesLoadSrc
; // Total number of lines in the source code text
135 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
136 size_t NbSubProgs
; // Number of sub programs / routines
137 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines structure
138 size_t NbTypes
; // Number of types
139 BaseTypeStruct
*PtrTypes
; // Pointer to types
140 size_t NbVariables
; // Variables number
141 VariablesStruct
*PtrVariables
; // Pointer to the global variables list structure
142 size_t NbFrames
; // Frames number
143 size_t NbLinesSrc
; // Number of used source lines
144 CUStruct_LineSrc
*PtrLinesSrc
; // Pointer to the used source lines list structure
155 char **ListSearchPaths
;
156 size_t NbSearchPaths
;
160 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
161 void DWARFManager_InitDMI(void);
162 void DWARFManager_CloseDMI(void);
163 bool DWARFManager_ElfClose(void);
164 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
165 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
166 void DWARFManager_SourceFileSearchPathsInit(void);
167 void DWARFManager_SourceFileSearchPathsReset(void);
168 void DWARFManager_SourceFileSearchPathsClose(void);
172 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
178 // Dwarf manager list search paths init
179 void DWARFManager_SourceFileSearchPathsInit(void)
181 ListSearchPaths
= NULL
;
186 // Dwarf manager list search paths reset
187 void DWARFManager_SourceFileSearchPathsReset(void)
189 ListSearchPaths
= NULL
;
194 // Dwarf manager list search paths close
195 void DWARFManager_SourceFileSearchPathsClose(void)
197 DWARFManager_SourceFileSearchPathsReset();
201 // Dwarf manager init
202 void DWARFManager_Init(void)
204 DWARFManager_SourceFileSearchPathsInit();
205 LibDwarf
= DW_DLV_NO_ENTRY
;
209 // Dwarf manager settings
210 void DWARFManager_Set(size_t NbPathsInList
, char **PtrListPaths
)
213 ListSearchPaths
= PtrListPaths
;
214 NbSearchPaths
= NbPathsInList
;
218 // Dwarf manager Reset
219 bool DWARFManager_Reset(void)
221 DWARFManager_SourceFileSearchPathsReset();
222 return DWARFManager_ElfClose();
226 // Dwarf manager Close
227 bool DWARFManager_Close(void)
229 DWARFManager_SourceFileSearchPathsClose();
230 return(DWARFManager_Reset());
234 // Dwarf manager Elf init
235 int DWARFManager_ElfInit(Elf
*ElfPtr
)
237 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
239 DWARFManager_InitDMI();
246 // Dwarf manager Elf close
247 bool DWARFManager_ElfClose(void)
249 if (LibDwarf
== DW_DLV_OK
)
251 DWARFManager_CloseDMI();
253 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
255 LibDwarf
= DW_DLV_NO_ENTRY
;
270 // Dwarf manager Compilation Units close
271 void DWARFManager_CloseDMI(void)
275 free(PtrCU
[NbCU
].PtrFullFilename
);
276 free(PtrCU
[NbCU
].PtrLoadSrc
);
277 free(PtrCU
[NbCU
].PtrProducer
);
278 free(PtrCU
[NbCU
].PtrSourceFilename
);
279 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
280 free(PtrCU
[NbCU
].PtrLinesSrc
);
282 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
284 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
286 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
288 while (PtrCU
[NbCU
].NbSubProgs
--)
290 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
292 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
293 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
295 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
297 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
298 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
300 free(PtrCU
[NbCU
].PtrSubProgs
);
302 while (PtrCU
[NbCU
].NbTypes
--)
304 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
306 free(PtrCU
[NbCU
].PtrTypes
);
308 while (PtrCU
[NbCU
].NbVariables
--)
310 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
311 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
313 free(PtrCU
[NbCU
].PtrVariables
);
320 // Dwarf manager Compilation Units initialisations
321 void DWARFManager_InitDMI(void)
323 Dwarf_Unsigned next_cu_header
, return_uvalue
;
325 Dwarf_Attribute
*atlist
;
326 Dwarf_Attribute return_attr1
;
327 Dwarf_Half return_tagval
, return_attr
;
328 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
329 Dwarf_Block
*return_block
;
330 Dwarf_Signed atcnt
, cnt
;
331 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
332 Dwarf_Off return_offset
;
338 // Initialisation for the Compilation Units table
342 // loop on the available Compilation Unit
343 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
345 // Allocation of an additional Compilation Unit structure in the table
346 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
348 // Compilation Unit RAZ
349 PtrCU
= (CUStruct
*)Ptr
;
350 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
354 if (NbCU
== DEBUG_NumCU
)
357 // Get 1st Die from the Compilation Unit
358 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
361 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
363 PtrCU
[NbCU
].Tag
= return_tagval
;
365 // Die type detection
366 switch (return_tagval
)
368 case DW_TAG_compile_unit
:
369 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
371 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
373 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
379 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
381 PtrCU
[NbCU
].LowPC
= return_lowpc
;
387 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
389 PtrCU
[NbCU
].HighPC
= return_highpc
;
393 // compilation information
395 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
397 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
398 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
399 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
405 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
407 #ifdef DEBUG_Filename
408 if (strstr(return_string
, DEBUG_Filename
))
411 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
412 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
414 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
420 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
422 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
423 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
424 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
432 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
434 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
437 // Check filename presence
438 if (!PtrCU
[NbCU
].PtrSourceFilename
)
440 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
443 // Check directory presence
444 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
446 // Check if file exists in the search paths
447 for (size_t i
= 0; i
< NbSearchPaths
; i
++)
449 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen((const char *)ListSearchPaths
[i
]) + 2);
451 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
453 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
455 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
457 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, strlen(ListSearchPaths
[i
]) + 1);
458 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ListSearchPaths
[i
]);
462 // File directory doesn't exits
463 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
465 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, 2);
466 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ".");
470 // Create full filename
471 Ptr
= PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
473 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
475 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
477 // Conform slashes and backslashes
494 // Directory path clean-up
496 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
498 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
502 while (*--Ptr1
!= '\\');
504 while (*--Ptr1
!= '/');
506 strcpy((Ptr1
+ 1), (Ptr
+ 4));
509 // Open the source file as a binary file
510 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
512 if (!fseek(SrcFile
, 0, SEEK_END
))
514 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
516 if (!fseek(SrcFile
, 0, SEEK_SET
))
518 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
521 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
523 free(PtrCU
[NbCU
].PtrLoadSrc
);
524 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
525 PtrCU
[NbCU
].SizeLoadSrc
= 0;
529 // Eliminate all carriage return code '\r' (oxd)
532 if ((*Ptr
= *Ptr1
) != '\r')
539 // Get back the new text file size
540 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
542 // Make sure the text file finish with a new line code '\n' (0xa)
543 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
545 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
546 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
549 // Reallocate text file
550 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
552 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
557 PtrCU
[NbCU
].NbLinesLoadSrc
++;
576 // Get the source lines table located in the CU
577 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
581 PtrCU
[NbCU
].NbLinesSrc
= cnt
;
582 PtrCU
[NbCU
].PtrLinesSrc
= (CUStruct_LineSrc
*)calloc(cnt
, sizeof(CUStruct_LineSrc
));
583 for (Dwarf_Signed i
= 0; i
< cnt
; i
++)
585 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
587 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
589 PtrCU
[NbCU
].PtrLinesSrc
[i
].StartPC
= return_lineaddr
;
590 PtrCU
[NbCU
].PtrLinesSrc
[i
].NumLineSrc
= return_uvalue
;
597 // Check if the CU has child
598 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
602 return_sib
= return_die
;
603 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
605 switch (return_tagval
)
607 case DW_TAG_lexical_block
:
610 case DW_TAG_variable
:
611 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
613 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
614 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
616 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
618 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
620 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
625 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
627 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
629 switch (return_block
->bl_len
)
632 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));
638 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
643 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
645 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
651 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
653 #ifdef DEBUG_VariableName
654 if (!strcmp(return_string
, DEBUG_VariableName
))
657 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
658 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
660 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
670 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
673 // Check variable's name validity
674 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
676 // Check variable's memory address validity
677 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
680 PtrCU
[NbCU
].NbVariables
++;
685 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
686 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
690 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
694 case DW_TAG_base_type
:
696 case DW_TAG_structure_type
:
697 case DW_TAG_pointer_type
:
698 case DW_TAG_const_type
:
699 case DW_TAG_array_type
:
700 case DW_TAG_subrange_type
:
701 case DW_TAG_subroutine_type
:
702 case DW_TAG_enumeration_type
:
703 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
705 // Allocate memory for this type
706 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
707 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
708 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
710 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
712 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
715 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
717 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
719 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
727 // Type's type offset
729 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
731 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
736 case DW_AT_byte_size
:
737 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
739 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
745 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
747 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
753 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
755 #ifdef DEBUG_TypeName
756 if (!strcmp(return_string
, DEBUG_TypeName
))
759 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
760 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
762 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
766 // Type's file number
767 case DW_AT_decl_file
:
770 // Type's line number
771 case DW_AT_decl_line
:
780 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
783 PtrCU
[NbCU
].NbTypes
++;
785 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
789 case DW_TAG_subprogram
:
790 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
792 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
793 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
794 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
796 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
798 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
800 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
806 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
808 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
809 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
815 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
817 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
822 case DW_AT_decl_line
:
823 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
825 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
830 case DW_AT_frame_base
:
831 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
833 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
834 PtrCU
[NbCU
].NbFrames
++;
840 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
842 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
843 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
844 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
851 case DW_AT_GNU_all_tail_call_sites
:
857 case DW_AT_prototyped
:
861 case DW_AT_decl_file
:
872 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
874 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
876 // Get source line number and associated block of address
877 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
879 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
881 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
883 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
885 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
));
886 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
887 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
888 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
889 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
895 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
899 return_sub
= return_subdie
;
900 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
902 switch (return_tagval
)
904 case DW_TAG_formal_parameter
:
905 case DW_TAG_variable
:
906 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
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
)));
909 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
911 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
913 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
915 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
920 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
922 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
924 switch (return_block
->bl_len
)
931 switch (return_tagval
)
933 case DW_TAG_variable
:
934 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
937 case DW_TAG_formal_parameter
:
938 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
949 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
954 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
956 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
961 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
963 #ifdef DEBUG_VariableName
964 if (!strcmp(return_string
, DEBUG_VariableName
))
967 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
968 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
970 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
974 case DW_AT_decl_file
:
977 case DW_AT_decl_line
:
986 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
989 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
991 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
1003 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
1006 PtrCU
[NbCU
].NbSubProgs
++;
1015 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
1018 // Release the memory used by the source lines
1019 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
1021 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
1023 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
1026 // Set the source code lines for QT html/text conformity
1027 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
1029 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
1031 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
1033 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
1035 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
1044 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
1049 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
1054 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
1059 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
1060 i
+= strlen("&");
1065 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
1066 i
+= strlen(""");
1070 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
1076 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
1080 // Init lines source information for each source code line numbers and for each subprogs
1081 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
1083 // Check if the subprog / function's line exists in the source code
1084 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1086 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1089 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1091 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1093 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1101 // Set each source lines pointer to NULL
1102 if (PtrCU
[NbCU
].NbSubProgs
)
1104 // Check the presence of source lines dedicated to the sub progs
1105 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1107 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1108 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1110 for (size_t j
= 0; j
< i
; j
++)
1112 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1119 // Set information based on used line numbers
1120 if (PtrCU
[NbCU
].PtrLinesSrc
)
1122 // Set the line source pointer for each used line numbers
1123 if (PtrCU
[NbCU
].PtrLinesLoadSrc
)
1125 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbLinesSrc
; i
++)
1127 PtrCU
[NbCU
].PtrLinesSrc
[i
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrLinesSrc
[i
].NumLineSrc
- 1];
1132 // Init global variables information based on types information
1133 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1135 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1138 // Init local variables information based on types information
1139 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1141 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1143 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1154 // Variables information initialisation
1155 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1157 size_t j
, TypeOffset
;
1159 #ifdef DEBUG_VariableName
1160 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1163 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1164 TypeOffset
= PtrVariables
->TypeOffset
;
1166 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1168 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1170 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1172 case DW_TAG_subroutine_type
:
1173 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1174 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1177 // Structure type tag
1178 case DW_TAG_structure_type
:
1179 PtrVariables
->TypeTag
|= TypeTag_structure
;
1180 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1182 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1184 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1190 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1192 strcat(PtrVariables
->PtrTypeName
, " *");
1198 case DW_TAG_pointer_type
:
1199 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1200 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1201 PtrVariables
->TypeEncoding
= 0x10;
1202 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1204 strcat(PtrVariables
->PtrTypeName
, "void *");
1212 case DW_TAG_enumeration_type
:
1213 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1214 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1215 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1217 // Try to determine the possible size
1218 switch (PtrVariables
->TypeByteSize
)
1221 PtrVariables
->TypeEncoding
= 0x7;
1231 case DW_TAG_typedef
:
1232 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1234 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1235 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1237 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1244 case DW_TAG_subrange_type
:
1245 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1249 case DW_TAG_array_type
:
1250 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1251 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1258 case DW_TAG_const_type
:
1259 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1260 strcat(PtrVariables
->PtrTypeName
, "const ");
1261 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1268 case DW_TAG_base_type
:
1269 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1271 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1273 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1275 strcat(PtrVariables
->PtrTypeName
, " *");
1279 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1280 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1282 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1284 strcat(PtrVariables
->PtrTypeName
, "[]");
1297 // Get symbol name based from address
1298 // Return NULL if no symbol name exists
1299 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1301 for (size_t i
= 0; i
< NbCU
; i
++)
1303 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1305 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1307 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1309 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1319 // Get complete source filename based from address
1320 // Return NULL if no source filename exists
1321 // Return the existence status (true or false) in Error
1322 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1324 for (size_t i
= 0; i
< NbCU
; i
++)
1326 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1328 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1329 return PtrCU
[i
].PtrFullFilename
;
1337 // Get text line source based on line number (starting from 1)
1338 // Return NULL if no text line exists or if line number is 0
1339 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1342 char *PtrLineSrc
= NULL
;
1346 while (i
!= NumLine
)
1348 PtrLineSrc
= PtrSrcFile
;
1349 while (*PtrSrcFile
++);
1358 // Get number of variables referenced by the function range address
1359 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1361 for (size_t i
= 0; i
< NbCU
; i
++)
1363 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1365 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1367 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1369 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1379 // Get local variable name based on his index (starting from 1)
1380 // Return name's pointer text found
1381 // Return NULL if not found
1382 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1384 for (size_t i
= 0; i
< NbCU
; i
++)
1386 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1388 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1390 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1392 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1402 // Get local variable's type tag based on his index (starting from 1)
1403 // Return 0 if not found
1404 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1406 for (size_t i
= 0; i
< NbCU
; i
++)
1408 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1410 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1412 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1414 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1424 // Get the local variable's offset based on a index (starting from 1)
1425 // Return 0 if no offset has been found
1426 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1428 for (size_t i
= 0; i
< NbCU
; i
++)
1430 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1432 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1434 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1436 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1446 // Get local variable Type Byte Size based on his address and index (starting from 1)
1447 // Return 0 if not found
1448 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1449 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1451 for (size_t i
= 0; i
< NbCU
; i
++)
1453 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1455 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1457 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1459 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1469 // Get local variable Type Encoding based on his address and index (starting from 1)
1470 // Return 0 if not found
1471 // May return 0 if there is no Type Encoding linked to the variable's address and index
1472 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1474 for (size_t i
= 0; i
< NbCU
; i
++)
1476 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1478 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1480 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1482 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1492 // Get local variable Op based on his address and index (starting from 1)
1493 // Return 0 if not found, may return 0 if there isn't Op linked to the variable's index
1494 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1496 for (size_t i
= 0; i
< NbCU
; i
++)
1498 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1500 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1502 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1504 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1514 // Get local variable type name based on his index (starting from 1) and an address
1515 // Return NULL if not found, may also return NULL if there is no type linked to the variable's index
1516 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1518 for (size_t i
= 0; i
< NbCU
; i
++)
1520 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1522 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1524 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1526 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1536 // Get Compilation Unit / global variables numbers
1537 // Return number of variables
1538 size_t DWARFManager_GetNbGlobalVariables(void)
1540 size_t NbVariables
= 0;
1542 for (size_t i
= 0; i
< NbCU
; i
++)
1544 NbVariables
+= PtrCU
[i
].NbVariables
;
1551 // Get global variable type name based on his index (starting from 1)
1552 // Return NULL if not found
1553 // May return NULL if there is not type linked to the variable's index
1554 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1556 for (size_t i
= 0; i
< NbCU
; i
++)
1558 if (PtrCU
[i
].NbVariables
)
1560 if (Index
<= PtrCU
[i
].NbVariables
)
1562 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1566 Index
-= PtrCU
[i
].NbVariables
;
1575 // Get global variable's type tag based on his index (starting from 1)
1576 // Return 0 if not found
1577 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1579 for (size_t i
= 0; i
< NbCU
; i
++)
1581 if (PtrCU
[i
].NbVariables
)
1583 if (Index
<= PtrCU
[i
].NbVariables
)
1585 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1589 Index
-= PtrCU
[i
].NbVariables
;
1598 // Get global variable byte size based on his index (starting from 1)
1599 // Return 0 if not found
1600 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1602 for (size_t i
= 0; i
< NbCU
; i
++)
1604 if (PtrCU
[i
].NbVariables
)
1606 if (Index
<= PtrCU
[i
].NbVariables
)
1608 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1612 Index
-= PtrCU
[i
].NbVariables
;
1621 // Get global variable encoding based on his index (starting from 1)
1622 // Return 0 if not found
1623 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1625 for (size_t i
= 0; i
< NbCU
; i
++)
1627 if (PtrCU
[i
].NbVariables
)
1629 if (Index
<= PtrCU
[i
].NbVariables
)
1631 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1635 Index
-= PtrCU
[i
].NbVariables
;
1644 // Get global variable memory address based on his index (starting from 1)
1645 // Return 0 if not found
1646 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1648 for (size_t i
= 0; i
< NbCU
; i
++)
1650 if (PtrCU
[i
].NbVariables
)
1652 if (Index
<= PtrCU
[i
].NbVariables
)
1654 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1658 Index
-= PtrCU
[i
].NbVariables
;
1667 // Get global variable memory address based on his name
1668 // Return 0 if not found, or will return the first occurence found
1669 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1671 for (size_t i
= 0; i
< NbCU
; i
++)
1673 if (PtrCU
[i
].NbVariables
)
1675 for (size_t j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1677 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1679 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1689 // Get global variable name based on his index (starting from 1)
1690 // Return name's pointer text found, or will return NULL if no variable can be found
1691 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1693 for (size_t i
= 0; i
< NbCU
; i
++)
1695 if (PtrCU
[i
].NbVariables
)
1697 if (Index
<= PtrCU
[i
].NbVariables
)
1699 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1703 Index
-= PtrCU
[i
].NbVariables
;
1712 // Get text line from source based on address and his tag
1713 // A tag can be either 0 or a DW_TAG_subprogram
1714 // DW_TAG_subprogram will look for the line pointing to the function
1715 // Return NULL if no text line has been found
1716 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1718 for (size_t i
= 0; i
< NbCU
; i
++)
1720 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1722 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1724 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1726 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1728 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1732 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1734 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1736 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1738 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1743 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1756 // Get line number based on the address and a tag
1757 // A tag can be either 0 or a DW_TAG_subprogram
1758 // DW_TAG_subprogram will look for the line pointing to the function name as described in the source code
1759 // Return 0 if no line number has been found
1760 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1762 for (size_t i
= 0; i
< NbCU
; i
++)
1764 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1766 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1768 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1770 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1772 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1776 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1778 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1780 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1785 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1787 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1799 // Get function name based on an address
1800 // Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address
1801 char *DWARFManager_GetFunctionName(size_t Adr
)
1803 for (size_t i
= 0; i
< NbCU
; i
++)
1805 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1807 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1809 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1811 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1821 // Get text line from source based on address and num line (starting from 1)
1822 // Return NULL if no text line has been found
1823 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1825 for (size_t i
= 0; i
< NbCU
; i
++)
1827 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1829 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1831 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1833 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1835 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1839 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1841 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1843 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1856 // Get text line pointer from source, based on address and line number (starting from 1)
1857 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
1858 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1860 for (size_t i
= 0; i
< NbCU
; i
++)
1862 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1864 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1866 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
1879 // Get number of source code filenames
1880 size_t DWARFManager_GetNbFullSourceFilename(void)
1886 // Get source code filename based on index (starting from 0)
1887 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
1889 return (PtrCU
[Index
].PtrFullFilename
);