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
17 // To keep sources text file intact wihtout QT/HTML transformation
30 // Definitions for debugging
31 //#define DEBUG_NumCU 0x9 // CU number to debug or undefine it
32 //#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it
33 //#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it
34 //#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)
35 //#define DEBUG_Filename "net_jag.c" // Filename to look for or undefine it
37 // Definitions for the variables's typetag
38 #define TypeTag_structure 0x01 // structure
39 #define TypeTag_pointer 0x02 // pointer
40 #define TypeTag_subrange 0x04 // (subrange_type?)
41 #define TypeTag_arraytype 0x08 // array type
42 #define TypeTag_consttype 0x10 // const type
43 #define TypeTag_typedef 0x20 // typedef
44 #define TypeTag_enumeration_type 0x40 // enumeration
45 #define TypeTag_subroutine_type 0x80 // subroutine
48 // Source line CU structure
49 typedef struct CUStruct_LineSrc
56 // Source line internal structure
57 typedef struct DMIStruct_LineSrc
65 // Enumeration structure
66 typedef struct EnumerationStruct
68 char *PtrName
; // Enumeration's name
69 size_t value
; // Enumeration's value
72 // Structure members structure
73 //typedef struct StructureMembersStruct
75 //}S_StructureMembersStruct;
77 // Base type internal structure
78 typedef struct BaseTypeStruct
80 size_t Tag
; // Type's Tag
81 size_t Offset
; // Type's offset
82 size_t TypeOffset
; // Type's offset on another type
83 size_t ByteSize
; // Type's Byte Size
84 size_t Encoding
; // Type's encoding
85 char *PtrName
; // Type's name
86 size_t NbEnumeration
; // Type's enumeration numbers
87 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
88 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
91 // Variables internal structure
92 typedef struct VariablesStruct
94 size_t Op
; // Variable's DW_OP
97 size_t Addr
; // Variable memory address
98 int Offset
; // Variable stack offset (signed)
100 char *PtrName
; // Variable's name
101 size_t TypeOffset
; // Offset pointing on the Variable's Type
102 size_t TypeByteSize
; // Variable's Type byte size
103 size_t TypeTag
; // Variable's Type Tag
104 size_t TypeEncoding
; // Variable's Type encoding
105 char *PtrTypeName
; // Variable's Type name
108 // Sub program internal structure
109 typedef struct SubProgStruct
114 size_t LowPC
, HighPC
;
117 char *PtrSubprogramName
; // Sub program name
118 size_t NbLinesSrc
; // Number of lines source used by the sub program
119 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
120 size_t NbVariables
; // Variables number
121 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
124 // Compilation Unit internal structure
125 typedef struct CUStruct
128 size_t LowPC
, HighPC
; // Memory range for the code
129 char *PtrProducer
; // Pointer to the "Producer" text information (mostly compiler and compilation options used)
130 char *PtrSourceFilename
; // Source file name
131 char *PtrSourceFileDirectory
; // Directory of the source file
132 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
133 size_t SizeLoadSrc
; // Source code text size
134 char *PtrLoadSrc
; // Pointer to the source code text
135 size_t NbLinesLoadSrc
; // Total number of lines in the source code text
136 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
137 size_t NbSubProgs
; // Number of sub programs / routines
138 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines structure
139 size_t NbTypes
; // Number of types
140 BaseTypeStruct
*PtrTypes
; // Pointer to types
141 size_t NbVariables
; // Variables number
142 VariablesStruct
*PtrVariables
; // Pointer to the global variables list structure
143 size_t NbFrames
; // Frames number
144 size_t NbLinesSrc
; // Number of used source lines
145 CUStruct_LineSrc
*PtrLinesSrc
; // Pointer to the used source lines list structure
156 char **ListSearchPaths
;
157 size_t NbSearchPaths
;
161 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
162 void DWARFManager_InitDMI(void);
163 void DWARFManager_CloseDMI(void);
164 bool DWARFManager_ElfClose(void);
165 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
166 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
167 void DWARFManager_SourceFileSearchPathsInit(void);
168 void DWARFManager_SourceFileSearchPathsReset(void);
169 void DWARFManager_SourceFileSearchPathsClose(void);
173 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
179 // Dwarf manager list search paths init
180 void DWARFManager_SourceFileSearchPathsInit(void)
182 ListSearchPaths
= NULL
;
187 // Dwarf manager list search paths reset
188 void DWARFManager_SourceFileSearchPathsReset(void)
190 ListSearchPaths
= NULL
;
195 // Dwarf manager list search paths close
196 void DWARFManager_SourceFileSearchPathsClose(void)
198 DWARFManager_SourceFileSearchPathsReset();
202 // Dwarf manager init
203 void DWARFManager_Init(void)
205 DWARFManager_SourceFileSearchPathsInit();
206 LibDwarf
= DW_DLV_NO_ENTRY
;
210 // Dwarf manager settings
211 void DWARFManager_Set(size_t NbPathsInList
, char **PtrListPaths
)
214 ListSearchPaths
= PtrListPaths
;
215 NbSearchPaths
= NbPathsInList
;
219 // Dwarf manager Reset
220 bool DWARFManager_Reset(void)
222 DWARFManager_SourceFileSearchPathsReset();
223 return DWARFManager_ElfClose();
227 // Dwarf manager Close
228 bool DWARFManager_Close(void)
230 DWARFManager_SourceFileSearchPathsClose();
231 return(DWARFManager_Reset());
235 // Dwarf manager Elf init
236 int DWARFManager_ElfInit(Elf
*ElfPtr
)
238 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
240 DWARFManager_InitDMI();
247 // Dwarf manager Elf close
248 bool DWARFManager_ElfClose(void)
250 if (LibDwarf
== DW_DLV_OK
)
252 DWARFManager_CloseDMI();
254 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
256 LibDwarf
= DW_DLV_NO_ENTRY
;
271 // Dwarf manager Compilation Units close
272 void DWARFManager_CloseDMI(void)
276 free(PtrCU
[NbCU
].PtrFullFilename
);
277 free(PtrCU
[NbCU
].PtrLoadSrc
);
278 free(PtrCU
[NbCU
].PtrProducer
);
279 free(PtrCU
[NbCU
].PtrSourceFilename
);
280 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
281 free(PtrCU
[NbCU
].PtrLinesSrc
);
283 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
285 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
287 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
289 while (PtrCU
[NbCU
].NbSubProgs
--)
291 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
293 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
294 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
296 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
298 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
299 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
301 free(PtrCU
[NbCU
].PtrSubProgs
);
303 while (PtrCU
[NbCU
].NbTypes
--)
305 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
307 free(PtrCU
[NbCU
].PtrTypes
);
309 while (PtrCU
[NbCU
].NbVariables
--)
311 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
312 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
314 free(PtrCU
[NbCU
].PtrVariables
);
321 // Dwarf manager Compilation Units initialisations
322 void DWARFManager_InitDMI(void)
324 Dwarf_Unsigned next_cu_header
, return_uvalue
;
326 Dwarf_Attribute
*atlist
;
327 Dwarf_Attribute return_attr1
;
328 Dwarf_Half return_tagval
, return_attr
;
329 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
330 Dwarf_Block
*return_block
;
331 Dwarf_Signed atcnt
, cnt
;
332 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
333 Dwarf_Off return_offset
;
339 // Initialisation for the Compilation Units table
343 // loop on the available Compilation Unit
344 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
346 // Allocation of an additional Compilation Unit structure in the table
347 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
349 // Compilation Unit RAZ
350 PtrCU
= (CUStruct
*)Ptr
;
351 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
355 if (NbCU
== DEBUG_NumCU
)
358 // Get 1st Die from the Compilation Unit
359 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
362 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
364 PtrCU
[NbCU
].Tag
= return_tagval
;
366 // Die type detection
367 switch (return_tagval
)
369 case DW_TAG_compile_unit
:
370 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
372 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
374 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
380 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
382 PtrCU
[NbCU
].LowPC
= return_lowpc
;
388 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
390 PtrCU
[NbCU
].HighPC
= return_highpc
;
394 // compilation information
396 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
398 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
399 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
400 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
406 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
408 #ifdef DEBUG_Filename
409 if (strstr(return_string
, DEBUG_Filename
))
412 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
413 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
415 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
421 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
423 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
424 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
425 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
433 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
435 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
438 // Check filename presence
439 if (!PtrCU
[NbCU
].PtrSourceFilename
)
441 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
444 // Check directory presence
445 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
447 // Check if file exists in the search paths
448 for (size_t i
= 0; i
< NbSearchPaths
; i
++)
450 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen((const char *)ListSearchPaths
[i
]) + 2);
452 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
454 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
456 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
458 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, strlen(ListSearchPaths
[i
]) + 1);
459 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ListSearchPaths
[i
]);
463 // File directory doesn't exits
464 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
466 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, 2);
467 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ".");
471 // Create full filename
472 Ptr
= PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
474 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
476 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
478 // Conform slashes and backslashes
495 // Directory path clean-up
497 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
499 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
503 while (*--Ptr1
!= '\\');
505 while (*--Ptr1
!= '/');
507 strcpy((Ptr1
+ 1), (Ptr
+ 4));
510 // Open the source file as a binary file
511 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
513 if (!fseek(SrcFile
, 0, SEEK_END
))
515 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
517 if (!fseek(SrcFile
, 0, SEEK_SET
))
519 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
522 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
524 free(PtrCU
[NbCU
].PtrLoadSrc
);
525 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
526 PtrCU
[NbCU
].SizeLoadSrc
= 0;
530 // Eliminate all carriage return code '\r' (oxd)
533 if ((*Ptr
= *Ptr1
) != '\r')
540 // Get back the new text file size
541 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
543 // Make sure the text file finish with a new line code '\n' (0xa)
544 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
546 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
547 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
550 // Reallocate text file
551 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
553 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
558 PtrCU
[NbCU
].NbLinesLoadSrc
++;
577 // Get the source lines table located in the CU
578 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
582 PtrCU
[NbCU
].NbLinesSrc
= cnt
;
583 PtrCU
[NbCU
].PtrLinesSrc
= (CUStruct_LineSrc
*)calloc(cnt
, sizeof(CUStruct_LineSrc
));
584 for (Dwarf_Signed i
= 0; i
< cnt
; i
++)
586 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
588 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
590 PtrCU
[NbCU
].PtrLinesSrc
[i
].StartPC
= return_lineaddr
;
591 PtrCU
[NbCU
].PtrLinesSrc
[i
].NumLineSrc
= return_uvalue
;
598 // Check if the CU has child
599 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
603 return_sib
= return_die
;
604 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
606 switch (return_tagval
)
608 case DW_TAG_lexical_block
:
611 case DW_TAG_variable
:
612 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
614 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
615 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
617 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
619 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
621 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
626 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
628 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
630 switch (return_block
->bl_len
)
633 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));
639 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
644 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
646 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
652 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
654 #ifdef DEBUG_VariableName
655 if (!strcmp(return_string
, DEBUG_VariableName
))
658 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
659 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
661 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
671 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
674 // Check variable's name validity
675 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
677 // Check variable's memory address validity
678 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
681 PtrCU
[NbCU
].NbVariables
++;
686 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
687 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
691 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
695 case DW_TAG_base_type
:
697 case DW_TAG_structure_type
:
698 case DW_TAG_pointer_type
:
699 case DW_TAG_const_type
:
700 case DW_TAG_array_type
:
701 case DW_TAG_subrange_type
:
702 case DW_TAG_subroutine_type
:
703 case DW_TAG_enumeration_type
:
704 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
706 // Allocate memory for this type
707 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
708 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
709 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
711 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
713 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
716 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
718 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
720 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
728 // Type's type offset
730 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
732 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
737 case DW_AT_byte_size
:
738 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
740 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
746 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
748 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
754 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
756 #ifdef DEBUG_TypeName
757 if (!strcmp(return_string
, DEBUG_TypeName
))
760 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
761 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
763 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
767 // Type's file number
768 case DW_AT_decl_file
:
771 // Type's line number
772 case DW_AT_decl_line
:
781 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
784 PtrCU
[NbCU
].NbTypes
++;
786 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
790 case DW_TAG_subprogram
:
791 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
793 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
794 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
795 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
797 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
799 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
801 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
807 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
809 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
810 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
816 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
818 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
823 case DW_AT_decl_line
:
824 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
826 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
831 case DW_AT_frame_base
:
832 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
834 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
835 PtrCU
[NbCU
].NbFrames
++;
841 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
843 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
844 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
845 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
852 case DW_AT_GNU_all_tail_call_sites
:
858 case DW_AT_prototyped
:
862 case DW_AT_decl_file
:
873 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
875 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
877 // Get source line number and associated block of address
878 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
880 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
882 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
884 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
886 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
));
887 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
888 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
889 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
890 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
896 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
900 return_sub
= return_subdie
;
901 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
903 switch (return_tagval
)
905 case DW_TAG_formal_parameter
:
906 case DW_TAG_variable
:
907 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
909 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
)));
910 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
912 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
914 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
916 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
921 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
923 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
925 switch (return_block
->bl_len
)
932 switch (return_tagval
)
934 case DW_TAG_variable
:
935 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
938 case DW_TAG_formal_parameter
:
939 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
950 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
955 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
957 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
962 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
964 #ifdef DEBUG_VariableName
965 if (!strcmp(return_string
, DEBUG_VariableName
))
968 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
969 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
971 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
975 case DW_AT_decl_file
:
978 case DW_AT_decl_line
:
987 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
990 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
992 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
1004 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
1007 PtrCU
[NbCU
].NbSubProgs
++;
1016 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
1019 // Release the memory used by the source lines
1020 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
1022 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
1024 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
1027 // Set the source code lines for QT html/text conformity
1028 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
1030 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
1032 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
1034 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
1036 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
1045 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
1050 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
1055 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
1060 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
1061 i
+= strlen("&");
1066 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
1067 i
+= strlen(""");
1071 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
1077 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
1081 // Init lines source information for each source code line numbers and for each subprogs
1082 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
1084 // Check if the subprog / function's line exists in the source code
1085 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1087 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1090 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1092 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1094 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1102 // Set each source lines pointer to NULL
1103 if (PtrCU
[NbCU
].NbSubProgs
)
1105 // Check the presence of source lines dedicated to the sub progs
1106 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1108 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1109 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1111 for (size_t j
= 0; j
< i
; j
++)
1113 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1120 // Set information based on used line numbers
1121 if (PtrCU
[NbCU
].PtrLinesSrc
)
1123 // Set the line source pointer for each used line numbers
1124 if (PtrCU
[NbCU
].PtrLinesLoadSrc
)
1126 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbLinesSrc
; i
++)
1128 PtrCU
[NbCU
].PtrLinesSrc
[i
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrLinesSrc
[i
].NumLineSrc
- 1];
1131 // Setup memory range for the code if CU doesn't have already this information
1132 // It is taken from the used lines structure
1133 if (!PtrCU
[NbCU
].LowPC
&& (!PtrCU
[NbCU
].HighPC
|| (PtrCU
[NbCU
].HighPC
== ~0)))
1135 PtrCU
[NbCU
].LowPC
= PtrCU
[NbCU
].PtrLinesSrc
[0].StartPC
;
1136 PtrCU
[NbCU
].HighPC
= PtrCU
[NbCU
].PtrLinesSrc
[PtrCU
[NbCU
].NbLinesSrc
- 1].StartPC
;
1141 // Init global variables information based on types information
1142 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1144 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1147 // Init local variables information based on types information
1148 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1150 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1152 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1163 // Variables information initialisation
1164 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1166 size_t j
, TypeOffset
;
1168 #ifdef DEBUG_VariableName
1169 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1172 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1173 TypeOffset
= PtrVariables
->TypeOffset
;
1175 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1177 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1179 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1181 case DW_TAG_subroutine_type
:
1182 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1183 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1186 // Structure type tag
1187 case DW_TAG_structure_type
:
1188 PtrVariables
->TypeTag
|= TypeTag_structure
;
1189 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1191 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1193 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1199 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1201 strcat(PtrVariables
->PtrTypeName
, " *");
1207 case DW_TAG_pointer_type
:
1208 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1209 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1210 PtrVariables
->TypeEncoding
= 0x10;
1211 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1213 strcat(PtrVariables
->PtrTypeName
, "void *");
1221 case DW_TAG_enumeration_type
:
1222 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1223 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1224 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1226 // Try to determine the possible size
1227 switch (PtrVariables
->TypeByteSize
)
1230 PtrVariables
->TypeEncoding
= 0x7;
1240 case DW_TAG_typedef
:
1241 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1243 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1244 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1246 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1253 case DW_TAG_subrange_type
:
1254 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1258 case DW_TAG_array_type
:
1259 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1260 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1267 case DW_TAG_const_type
:
1268 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1269 strcat(PtrVariables
->PtrTypeName
, "const ");
1270 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1277 case DW_TAG_base_type
:
1278 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1280 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1282 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1284 strcat(PtrVariables
->PtrTypeName
, " *");
1288 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1289 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1291 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1293 strcat(PtrVariables
->PtrTypeName
, "[]");
1306 // Get symbol name based from address
1307 // Return NULL if no symbol name exists
1308 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1310 for (size_t i
= 0; i
< NbCU
; i
++)
1312 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1314 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1316 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1318 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1328 // Get complete source filename based from address
1329 // Return NULL if no source filename exists
1330 // Return the existence status (true or false) in Error
1331 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1333 for (size_t i
= 0; i
< NbCU
; i
++)
1335 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1337 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1338 return PtrCU
[i
].PtrFullFilename
;
1346 // Get text line source based on line number (starting from 1)
1347 // Return NULL if no text line exists or if line number is 0
1348 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1351 char *PtrLineSrc
= NULL
;
1355 while (i
!= NumLine
)
1357 PtrLineSrc
= PtrSrcFile
;
1358 while (*PtrSrcFile
++);
1367 // Get number of variables referenced by the function range address
1368 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1370 for (size_t i
= 0; i
< NbCU
; i
++)
1372 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1374 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1376 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1378 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1388 // Get local variable name based on his index (starting from 1)
1389 // Return name's pointer text found
1390 // Return NULL if not found
1391 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1393 for (size_t i
= 0; i
< NbCU
; i
++)
1395 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1397 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1399 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1401 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1411 // Get local variable's type tag based on his index (starting from 1)
1412 // Return 0 if not found
1413 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1415 for (size_t i
= 0; i
< NbCU
; i
++)
1417 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1419 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1421 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1423 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1433 // Get the local variable's offset based on a index (starting from 1)
1434 // Return 0 if no offset has been found
1435 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1437 for (size_t i
= 0; i
< NbCU
; i
++)
1439 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1441 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1443 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1445 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1455 // Get local variable Type Byte Size based on his address and index (starting from 1)
1456 // Return 0 if not found
1457 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1458 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1460 for (size_t i
= 0; i
< NbCU
; i
++)
1462 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1464 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1466 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1468 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1478 // Get local variable Type Encoding based on his address and index (starting from 1)
1479 // Return 0 if not found
1480 // May return 0 if there is no Type Encoding linked to the variable's address and index
1481 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1483 for (size_t i
= 0; i
< NbCU
; i
++)
1485 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1487 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1489 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1491 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1501 // Get local variable Op based on his address and index (starting from 1)
1502 // Return 0 if not found, may return 0 if there isn't Op linked to the variable's index
1503 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1505 for (size_t i
= 0; i
< NbCU
; i
++)
1507 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1509 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1511 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1513 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1523 // Get local variable type name based on his index (starting from 1) and an address
1524 // Return NULL if not found, may also return NULL if there is no type linked to the variable's index
1525 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1527 for (size_t i
= 0; i
< NbCU
; i
++)
1529 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1531 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1533 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1535 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1545 // Get Compilation Unit / global variables numbers
1546 // Return number of variables
1547 size_t DWARFManager_GetNbGlobalVariables(void)
1549 size_t NbVariables
= 0;
1551 for (size_t i
= 0; i
< NbCU
; i
++)
1553 NbVariables
+= PtrCU
[i
].NbVariables
;
1560 // Get global variable type name based on his index (starting from 1)
1561 // Return NULL if not found
1562 // May return NULL if there is not type linked to the variable's index
1563 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1565 for (size_t i
= 0; i
< NbCU
; i
++)
1567 if (PtrCU
[i
].NbVariables
)
1569 if (Index
<= PtrCU
[i
].NbVariables
)
1571 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1575 Index
-= PtrCU
[i
].NbVariables
;
1584 // Get global variable's type tag based on his index (starting from 1)
1585 // Return 0 if not found
1586 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1588 for (size_t i
= 0; i
< NbCU
; i
++)
1590 if (PtrCU
[i
].NbVariables
)
1592 if (Index
<= PtrCU
[i
].NbVariables
)
1594 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1598 Index
-= PtrCU
[i
].NbVariables
;
1607 // Get global variable byte size based on his index (starting from 1)
1608 // Return 0 if not found
1609 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1611 for (size_t i
= 0; i
< NbCU
; i
++)
1613 if (PtrCU
[i
].NbVariables
)
1615 if (Index
<= PtrCU
[i
].NbVariables
)
1617 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1621 Index
-= PtrCU
[i
].NbVariables
;
1630 // Get global variable encoding based on his index (starting from 1)
1631 // Return 0 if not found
1632 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1634 for (size_t i
= 0; i
< NbCU
; i
++)
1636 if (PtrCU
[i
].NbVariables
)
1638 if (Index
<= PtrCU
[i
].NbVariables
)
1640 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1644 Index
-= PtrCU
[i
].NbVariables
;
1653 // Get global variable memory address based on his index (starting from 1)
1654 // Return 0 if not found
1655 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1657 for (size_t i
= 0; i
< NbCU
; i
++)
1659 if (PtrCU
[i
].NbVariables
)
1661 if (Index
<= PtrCU
[i
].NbVariables
)
1663 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1667 Index
-= PtrCU
[i
].NbVariables
;
1676 // Get global variable memory address based on his name
1677 // Return 0 if not found, or will return the first occurence found
1678 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1680 for (size_t i
= 0; i
< NbCU
; i
++)
1682 if (PtrCU
[i
].NbVariables
)
1684 for (size_t j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1686 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1688 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1698 // Get global variable name based on his index (starting from 1)
1699 // Return name's pointer text found, or will return NULL if no variable can be found
1700 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1702 for (size_t i
= 0; i
< NbCU
; i
++)
1704 if (PtrCU
[i
].NbVariables
)
1706 if (Index
<= PtrCU
[i
].NbVariables
)
1708 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1712 Index
-= PtrCU
[i
].NbVariables
;
1721 // Get text line from source based on address and his tag
1722 // A tag can be either 0 or a DW_TAG_subprogram
1723 // DW_TAG_subprogram will look for the line pointing to the function
1724 // Return NULL if no text line has been found
1725 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1727 for (size_t i
= 0; i
< NbCU
; i
++)
1729 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1731 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1733 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1735 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1737 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1741 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1743 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1745 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1747 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1752 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1765 // Get line number based on the address and a tag
1766 // A tag can be either 0 or a DW_TAG_subprogram
1767 // DW_TAG_subprogram will look for the line pointing to the function name as described in the source code
1768 // Return 0 if no line number has been found
1769 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1771 for (size_t i
= 0; i
< NbCU
; i
++)
1773 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1775 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1777 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1779 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1781 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1785 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1787 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1789 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1794 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1796 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1802 // Check if a used line is found with the address
1803 for (size_t j
= 0; j
< PtrCU
[i
].NbLinesSrc
; j
++)
1805 if (PtrCU
[i
].PtrLinesSrc
[j
].StartPC
== Adr
)
1807 return PtrCU
[i
].PtrLinesSrc
[j
].NumLineSrc
;
1817 // Get function name based on an address
1818 // Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address
1819 char *DWARFManager_GetFunctionName(size_t Adr
)
1821 for (size_t i
= 0; i
< NbCU
; i
++)
1823 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1825 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1827 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1829 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1839 // Get text line from source based on address and num line (starting from 1)
1840 // Return NULL if no text line has been found
1841 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1843 for (size_t i
= 0; i
< NbCU
; i
++)
1845 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1847 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1849 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1851 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1853 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1857 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1859 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1861 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1874 // Get text line pointer from source, based on address and line number (starting from 1)
1875 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
1876 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1878 for (size_t i
= 0; i
< NbCU
; i
++)
1880 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1882 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1884 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
1897 // Get number of source code filenames
1898 size_t DWARFManager_GetNbFullSourceFilename(void)
1904 // Get source code filename based on index (starting from 0)
1905 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
1907 return (PtrCU
[Index
].PtrFullFilename
);