2 // DWARFManager.cpp: DWARF format manager
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
9 // --- ---------- ------------------------------------------------------------
10 // JPM 12/03/2016 Created this file
11 // JPM 12/03/2016 DWARF format support
12 // JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information
16 // To use pointers instead of arrays usage
30 //#define DEBUG_NumCU 0x9 // CU number to debug or undefine it
31 //#define DEBUG_VariableName "alloc" // 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 "cmd.c" // Filename to look for or undefine it
37 // Source line internal structure
38 typedef struct DMIStruct_LineSrc
46 // Enumeration structure
47 typedef struct EnumerationStruct
49 char *PtrName
; // Enumeration's name
50 size_t value
; // Enumeration's value
53 // Structure members structure
54 //typedef struct StructureMembersStruct
56 //}S_StructureMembersStruct;
58 // Base type internal structure
59 typedef struct BaseTypeStruct
61 size_t Tag
; // Type's Tag
62 size_t Offset
; // Type's offset
63 size_t TypeOffset
; // Type's offset on another type
64 size_t ByteSize
; // Type's Byte Size
65 size_t Encoding
; // Type's encoding
66 char *PtrName
; // Type's name
67 size_t NbEnumeration
; // Type's enumeration numbers
68 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
69 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
72 // Definitions for the variables's typetag
73 #define TypeTag_structure 0x01 // structure
74 #define TypeTag_pointer 0x02 // pointer
75 #define TypeTag_subrange 0x04 // (subrange_type?)
76 #define TypeTag_arraytype 0x08 // array type
77 #define TypeTag_consttype 0x10 // const type
78 #define TypeTag_typedef 0x20 // typedef
79 #define TypeTag_enumeration_type 0x40 // enumeration
80 #define TypeTag_subroutine_type 0x80 // subroutine
82 // Variables internal structure
83 typedef struct VariablesStruct
85 size_t Op
; // Variable's DW_OP
88 size_t Addr
; // Variable memory address
89 int Offset
; // Variable stack offset (signed)
91 char *PtrName
; // Variable's name
92 size_t TypeOffset
; // Offset pointing on the Variable's Type
93 size_t TypeByteSize
; // Variable's Type byte size
94 size_t TypeTag
; // Variable's Type Tag
95 size_t TypeEncoding
; // Variable's Type encoding
96 char *PtrTypeName
; // Variable's Type name
99 // Sub program internal structure
100 typedef struct SubProgStruct
105 size_t LowPC
, HighPC
;
108 char *PtrSubprogramName
; // Sub program name
109 size_t NbLinesSrc
; // Number of lines source used by the sub program
110 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
111 size_t NbVariables
; // Variables number
112 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
115 // Compilation Unit internal structure
116 typedef struct CUStruct
119 size_t LowPC
, HighPC
;
120 char *PtrProducer
; // Pointer to the "Producer" text information (mostly compiler and compilation options used)
121 char *PtrSourceFilename
; // Source file name
122 char *PtrSourceFileDirectory
; // Directory of the source file
123 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
124 size_t SizeLoadSrc
; // Source code size
125 char *PtrLoadSrc
; // Pointer to loaded source code
126 size_t NbLinesLoadSrc
; // Lines source number
127 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
128 size_t NbSubProgs
; // Number of sub programs / routines
129 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines information structure
130 size_t NbTypes
; // Number of types
131 BaseTypeStruct
*PtrTypes
; // Pointer to types
132 size_t NbVariables
; // Variables number
133 VariablesStruct
*PtrVariables
; // Pointer to the global variables list information structure
134 size_t NbFrames
; // Frames number
148 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
149 void DWARFManager_InitDMI(void);
150 void DWARFManager_CloseDMI(void);
151 bool DWARFManager_ElfClose(void);
152 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
153 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
157 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
163 // Dwarf manager init
164 void DWARFManager_Init(void)
166 LibDwarf
= DW_DLV_NO_ENTRY
;
170 // Dwarf manager Reset
171 bool DWARFManager_Reset(void)
173 return DWARFManager_ElfClose();
177 // Dwarf manager Close
178 bool DWARFManager_Close(void)
180 return(DWARFManager_Reset());
184 // Dwarf manager Elf init
185 int DWARFManager_ElfInit(Elf
*ElfPtr
)
187 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
189 DWARFManager_InitDMI();
196 // Dwarf manager Elf close
197 bool DWARFManager_ElfClose(void)
199 if (LibDwarf
== DW_DLV_OK
)
201 DWARFManager_CloseDMI();
203 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
205 LibDwarf
= DW_DLV_NO_ENTRY
;
220 // Dwarf manager Compilation Units close
221 void DWARFManager_CloseDMI(void)
225 free(PtrCU
[NbCU
].PtrFullFilename
);
226 free(PtrCU
[NbCU
].PtrLoadSrc
);
227 free(PtrCU
[NbCU
].PtrProducer
);
228 free(PtrCU
[NbCU
].PtrSourceFilename
);
229 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
231 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
233 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
235 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
237 while (PtrCU
[NbCU
].NbSubProgs
--)
239 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
241 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
242 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
244 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
246 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
247 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
249 free(PtrCU
[NbCU
].PtrSubProgs
);
251 while (PtrCU
[NbCU
].NbTypes
--)
253 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
255 free(PtrCU
[NbCU
].PtrTypes
);
257 while (PtrCU
[NbCU
].NbVariables
--)
259 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
260 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
262 free(PtrCU
[NbCU
].PtrVariables
);
269 // Dwarf manager Compilation Units initialisations
270 void DWARFManager_InitDMI(void)
272 Dwarf_Unsigned next_cu_header
, return_uvalue
;
274 Dwarf_Attribute
*atlist
;
275 Dwarf_Attribute return_attr1
;
276 Dwarf_Half return_tagval
, return_attr
;
277 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
278 Dwarf_Block
*return_block
;
279 Dwarf_Signed atcnt
, cnt
;
280 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
281 Dwarf_Off return_offset
;
288 // Initialisation for the Compilation Units table
292 // loop on the available Compilation Unit
293 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
295 // Allocation of an additional Compilation Unit structure in the table
296 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
298 // Compilation Unit RAZ
299 PtrCU
= (CUStruct
*)Ptr
;
300 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
304 if (NbCU
== DEBUG_NumCU
)
307 // Get 1st Die from the Compilation Unit
308 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
311 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
313 PtrCU
[NbCU
].Tag
= return_tagval
;
315 // Die type detection
316 switch (return_tagval
)
318 case DW_TAG_compile_unit
:
319 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
321 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
323 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
329 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
331 PtrCU
[NbCU
].LowPC
= return_lowpc
;
337 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
339 PtrCU
[NbCU
].HighPC
= return_highpc
;
343 // compilation information
345 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
347 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
348 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
349 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
355 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
357 #ifdef DEBUG_Filename
358 if (strstr(return_string
, DEBUG_Filename
))
361 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
362 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
364 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
370 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
372 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
373 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
374 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
382 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
384 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
387 // Check filename validity
388 if (!PtrCU
[NbCU
].PtrSourceFilename
)
390 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
393 // Check directory validity
394 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
396 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc(2, 1);
397 PtrCU
[NbCU
].PtrSourceFileDirectory
[0] = '.';
400 // Create full filename
401 Ptr
= PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
402 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
404 // Conform slashes and backslashes
421 // Directory path clean-up
423 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
425 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
429 while (*--Ptr1
!= '\\');
431 while (*--Ptr1
!= '/');
433 strcpy((Ptr1
+ 1), (Ptr
+ 4));
436 // Read the file as text
438 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rt"))
440 if (!(SrcFile
= fopen(SourceFullFilename
, "rt")))
443 if (!fseek(SrcFile
, 0, SEEK_END
))
445 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
447 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)calloc((PtrCU
[NbCU
].SizeLoadSrc
+ 1), 1))
450 if (PtrCU
[NbCU
].SizeLoadSrc
< fread(Ptr
, 1, PtrCU
[NbCU
].SizeLoadSrc
, SrcFile
))
452 free(PtrCU
[NbCU
].PtrLoadSrc
);
453 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
454 PtrCU
[NbCU
].SizeLoadSrc
= 0;
462 PtrCU
[NbCU
].NbLinesLoadSrc
++;
479 // Get the source lines table located in the Compilation Unit
480 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
484 // Check if the CU has child
485 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
489 return_sib
= return_die
;
490 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
492 switch (return_tagval
)
494 case DW_TAG_lexical_block
:
497 case DW_TAG_variable
:
498 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
500 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
501 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
503 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
505 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
507 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
512 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
514 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
516 switch (return_block
->bl_len
)
519 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));
525 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
530 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
532 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
538 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
540 #ifdef DEBUG_VariableName
541 if (!strcmp(return_string
, DEBUG_VariableName
))
544 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
545 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
547 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
557 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
560 PtrCU
[NbCU
].NbVariables
++;
562 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
566 case DW_TAG_base_type
:
568 case DW_TAG_structure_type
:
569 case DW_TAG_pointer_type
:
570 case DW_TAG_const_type
:
571 case DW_TAG_array_type
:
572 case DW_TAG_subrange_type
:
573 case DW_TAG_subroutine_type
:
574 case DW_TAG_enumeration_type
:
575 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
577 // Allocate memory for this type
578 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
579 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
580 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
582 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
584 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
587 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
589 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
591 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
599 // Type's type offset
601 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
603 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
608 case DW_AT_byte_size
:
609 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
611 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
617 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
619 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
625 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
627 #ifdef DEBUG_TypeName
628 if (!strcmp(return_string
, DEBUG_TypeName
))
631 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
632 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
634 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
638 // Type's file number
639 case DW_AT_decl_file
:
642 // Type's line number
643 case DW_AT_decl_line
:
652 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
655 PtrCU
[NbCU
].NbTypes
++;
657 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
661 case DW_TAG_subprogram
:
662 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
664 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
665 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
666 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
668 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
670 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
672 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
678 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
680 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
681 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
687 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
689 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
694 case DW_AT_decl_line
:
695 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
697 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
702 case DW_AT_frame_base
:
703 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
705 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
706 PtrCU
[NbCU
].NbFrames
++;
712 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
714 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
715 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
716 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
723 case DW_AT_GNU_all_tail_call_sites
:
729 case DW_AT_prototyped
:
733 case DW_AT_decl_file
:
744 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
746 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
748 // Get source line number and associated block of address
749 for (i
= 0; i
< (size_t)cnt
; ++i
)
751 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
753 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
755 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
757 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
));
758 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
759 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
760 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
761 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
767 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
771 return_sub
= return_subdie
;
772 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
774 switch (return_tagval
)
776 case DW_TAG_formal_parameter
:
777 case DW_TAG_variable
:
778 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
780 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
)));
781 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
783 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
785 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
787 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
792 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
794 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
796 switch (return_block
->bl_len
)
803 switch (return_tagval
)
805 case DW_TAG_variable
:
806 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
809 case DW_TAG_formal_parameter
:
810 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
821 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
826 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
828 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
833 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
835 #ifdef DEBUG_VariableName
836 if (!strcmp(return_string
, DEBUG_VariableName
))
839 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
840 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
842 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
846 case DW_AT_decl_file
:
849 case DW_AT_decl_line
:
858 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
861 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
863 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
875 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
878 PtrCU
[NbCU
].NbSubProgs
++;
887 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
890 // Release the memory used by the source lines
891 for (i
= 0; i
< (size_t)cnt
; ++i
)
893 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
895 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
898 // Set the source code lines for QT html/text conformity
899 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
901 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
903 for (j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
905 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
907 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
916 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
917 i
+= strlen(" ");
921 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
926 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
931 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
932 i
+= strlen("&");
937 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
938 i
+= strlen(""");
942 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
948 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], i
+ 1);
952 // Init lines source information based on each source code line numbers
953 for (j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
955 // Check if the subprog / function's line exists in the source code
956 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
958 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
961 for (k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
963 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
965 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
973 // Set each source lines pointer to NULL
974 if (PtrCU
[NbCU
].NbSubProgs
)
976 // Check the presence of source lines dedicated to the sub progs
977 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
979 i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
980 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
982 for (j
= 0; j
< i
; j
++)
984 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
991 // Init global variables information based on types information
992 for (i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
994 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
997 // Init local variables information based on types information
998 for (i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1000 for (j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1002 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1013 // Variables information initialisation
1014 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1016 size_t j
, TypeOffset
;
1018 #ifdef DEBUG_VariableName
1019 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1022 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1023 TypeOffset
= PtrVariables
->TypeOffset
;
1025 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1027 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1029 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1031 case DW_TAG_subroutine_type
:
1032 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1033 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1036 // Structure type tag
1037 case DW_TAG_structure_type
:
1038 PtrVariables
->TypeTag
|= TypeTag_structure
;
1039 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1041 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1043 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1049 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1051 strcat(PtrVariables
->PtrTypeName
, " *");
1057 case DW_TAG_pointer_type
:
1058 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1059 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1060 PtrVariables
->TypeEncoding
= 0x10;
1061 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1063 strcat(PtrVariables
->PtrTypeName
, "void *");
1071 case DW_TAG_enumeration_type
:
1072 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1073 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1074 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1076 // Try to determine the possible size
1077 switch (PtrVariables
->TypeByteSize
)
1080 PtrVariables
->TypeEncoding
= 0x7;
1090 case DW_TAG_typedef
:
1091 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1093 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1094 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1096 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1103 case DW_TAG_subrange_type
:
1104 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1108 case DW_TAG_array_type
:
1109 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1110 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1117 case DW_TAG_const_type
:
1118 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1119 strcat(PtrVariables
->PtrTypeName
, "const ");
1120 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1127 case DW_TAG_base_type
:
1128 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1130 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1132 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1134 strcat(PtrVariables
->PtrTypeName
, " *");
1138 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1139 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1141 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1143 strcat(PtrVariables
->PtrTypeName
, "[]");
1156 // Get symbol name based from address
1157 // Return NULL if no symbol name exists
1158 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1162 for (i
= 0; i
< NbCU
; i
++)
1164 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1166 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1168 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1170 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1180 // Get complete source filename based from address
1181 // Return NULL if no source filename exists
1182 // Return the existence status (true or false) in Error
1183 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1187 for (i
= 0; i
< NbCU
; i
++)
1189 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1191 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1192 return PtrCU
[i
].PtrFullFilename
;
1200 // Get text line source based on line number (starting by 1)
1201 // Return NULL if no text line exists or if line number is 0
1202 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1205 char *PtrLineSrc
= NULL
;
1209 while (i
!= NumLine
)
1211 PtrLineSrc
= PtrSrcFile
;
1212 while (*PtrSrcFile
++);
1221 // Get number of variables referenced by the function range address
1222 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1226 for (i
= 0; i
< NbCU
; i
++)
1228 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1230 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1232 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1234 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1244 // Get local variable name based on his index (starting by 1)
1245 // Return name's pointer text found
1246 // Return NULL if not found
1247 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1251 for (i
= 0; i
< NbCU
; i
++)
1253 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1255 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1257 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1259 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1269 // Get local variable's type tag based on his index (starting by 1)
1270 // Return 0 if not found
1271 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1275 for (i
= 0; i
< NbCU
; i
++)
1277 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1279 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1281 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1283 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1294 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1298 for (i
= 0; i
< NbCU
; i
++)
1300 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1302 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1304 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1306 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1316 // Get local variable Type Byte Size based on his address and index (starting by 1)
1317 // Return 0 if not found
1318 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1319 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1323 for (i
= 0; i
< NbCU
; i
++)
1325 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1327 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1329 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1331 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1341 // Get local variable Type Encoding based on his address and index (starting by 1)
1342 // Return 0 if not found
1343 // May return 0 if there is no Type Encoding linked to the variable's address and index
1344 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1348 for (i
= 0; i
< NbCU
; i
++)
1350 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1352 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1354 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1356 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1366 // Get local variable Op based on his address and index (starting by 1)
1367 // Return 0 if not found
1368 // May return 0 if there isn't Op linked to the variable's index
1369 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1373 for (i
= 0; i
< NbCU
; i
++)
1375 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1377 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1379 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1381 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1391 // Get local variable type name based on his index (starting by 1)
1392 // Return NULL if not found
1393 // May return NULL if there is not type linked to the variable's index
1394 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1398 for (i
= 0; i
< NbCU
; i
++)
1400 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1402 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1404 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1406 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1416 // Get Compilation Unit / global variables numbers
1417 // Return variables number
1418 size_t DWARFManager_GetNbGlobalVariables(void)
1420 size_t NbVariables
= 0, i
;
1422 for (i
= 0; i
< NbCU
; i
++)
1424 NbVariables
+= PtrCU
[i
].NbVariables
;
1431 // Get global variable type name based on his index (starting by 1)
1432 // Return NULL if not found
1433 // May return NULL if there is not type linked to the variable's index
1434 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1438 for (i
= 0; i
< NbCU
; i
++)
1440 if (PtrCU
[i
].NbVariables
)
1442 if (Index
<= PtrCU
[i
].NbVariables
)
1444 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1448 Index
-= PtrCU
[i
].NbVariables
;
1457 // Get global variable's type tag based on his index (starting by 1)
1458 // Return 0 if not found
1459 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1463 for (i
= 0; i
< NbCU
; i
++)
1465 if (PtrCU
[i
].NbVariables
)
1467 if (Index
<= PtrCU
[i
].NbVariables
)
1469 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1473 Index
-= PtrCU
[i
].NbVariables
;
1482 // Get global variable byte size based on his index (starting by 1)
1483 // Return 0 if not found
1484 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1488 for (i
= 0; i
< NbCU
; i
++)
1490 if (PtrCU
[i
].NbVariables
)
1492 if (Index
<= PtrCU
[i
].NbVariables
)
1494 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1498 Index
-= PtrCU
[i
].NbVariables
;
1507 // Get global variable encoding based on his index (starting by 1)
1508 // Return 0 if not found
1509 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1513 for (i
= 0; i
< NbCU
; i
++)
1515 if (PtrCU
[i
].NbVariables
)
1517 if (Index
<= PtrCU
[i
].NbVariables
)
1519 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1523 Index
-= PtrCU
[i
].NbVariables
;
1532 // Get global variable address based on his index (starting by 1)
1533 // Return 0 if not found
1534 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1538 for (i
= 0; i
< NbCU
; i
++)
1540 if (PtrCU
[i
].NbVariables
)
1542 if (Index
<= PtrCU
[i
].NbVariables
)
1544 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1548 Index
-= PtrCU
[i
].NbVariables
;
1557 // Get global variable memory address based on his name
1558 // Return 0 if not found
1559 // Note: Return the first occurence found
1560 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1564 for (i
= 0; i
< NbCU
; i
++)
1566 if (PtrCU
[i
].NbVariables
)
1568 for (j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1570 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1572 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1582 // Get global variable name based on his index (starting by 1)
1583 // Return name's pointer text found
1584 // Return NULL if not found
1585 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1589 for (i
= 0; i
< NbCU
; i
++)
1591 if (PtrCU
[i
].NbVariables
)
1593 if (Index
<= PtrCU
[i
].NbVariables
)
1595 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1599 Index
-= PtrCU
[i
].NbVariables
;
1608 // Get text line from source based on address and his tag
1609 // Return NULL if no text line has been found
1610 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1614 for (i
= 0; i
< NbCU
; i
++)
1616 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1618 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1620 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1622 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1624 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1628 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1630 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1632 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1634 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1639 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1652 // Get line number based on the address and the tag
1653 // Return 0 if no line number has been found
1654 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1658 for (i
= 0; i
< NbCU
; i
++)
1660 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1662 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1664 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1666 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1668 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1672 for (k
= 0; (k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
); k
++)
1674 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1676 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1681 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1683 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1695 // Get function name based on address and his range
1696 // Return NULL if no function name has been found
1697 char *DWARFManager_GetFunctionName(size_t Adr
)
1701 for (i
= 0; i
< NbCU
; i
++)
1703 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1705 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1707 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1709 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1719 // Get text line from source based on address and num line (starting by 1)
1720 // Return NULL if no text line has been found
1721 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1725 for (i
= 0; i
< NbCU
; i
++)
1727 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1729 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1731 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1733 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1735 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1739 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1741 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1743 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1756 // Get text line from source based on address and num line (starting by 1)
1757 // Return NULL if no text line has been found
1758 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1762 for (i
= 0; i
< NbCU
; i
++)
1764 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1766 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1768 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
1781 // Get number of source code filenames
1782 size_t DWARFManager_GetNbFullSourceFilename(void)
1788 // Get source code filename based on index
1789 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
1791 return (PtrCU
[Index
].PtrFullFilename
);