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
13 // JPM Oct./2018 Improve the DWARF parsing information
17 // To use pointers instead of arrays usage
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 "cmd.c" // Filename to look for or undefine it
38 // Source line internal structure
39 typedef struct DMIStruct_LineSrc
47 // Enumeration structure
48 typedef struct EnumerationStruct
50 char *PtrName
; // Enumeration's name
51 size_t value
; // Enumeration's value
54 // Structure members structure
55 //typedef struct StructureMembersStruct
57 //}S_StructureMembersStruct;
59 // Base type internal structure
60 typedef struct BaseTypeStruct
62 size_t Tag
; // Type's Tag
63 size_t Offset
; // Type's offset
64 size_t TypeOffset
; // Type's offset on another type
65 size_t ByteSize
; // Type's Byte Size
66 size_t Encoding
; // Type's encoding
67 char *PtrName
; // Type's name
68 size_t NbEnumeration
; // Type's enumeration numbers
69 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
70 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
73 // Definitions for the variables's typetag
74 #define TypeTag_structure 0x01 // structure
75 #define TypeTag_pointer 0x02 // pointer
76 #define TypeTag_subrange 0x04 // (subrange_type?)
77 #define TypeTag_arraytype 0x08 // array type
78 #define TypeTag_consttype 0x10 // const type
79 #define TypeTag_typedef 0x20 // typedef
80 #define TypeTag_enumeration_type 0x40 // enumeration
81 #define TypeTag_subroutine_type 0x80 // subroutine
83 // Variables internal structure
84 typedef struct VariablesStruct
86 size_t Op
; // Variable's DW_OP
89 size_t Addr
; // Variable memory address
90 int Offset
; // Variable stack offset (signed)
92 char *PtrName
; // Variable's name
93 size_t TypeOffset
; // Offset pointing on the Variable's Type
94 size_t TypeByteSize
; // Variable's Type byte size
95 size_t TypeTag
; // Variable's Type Tag
96 size_t TypeEncoding
; // Variable's Type encoding
97 char *PtrTypeName
; // Variable's Type name
100 // Sub program internal structure
101 typedef struct SubProgStruct
106 size_t LowPC
, HighPC
;
109 char *PtrSubprogramName
; // Sub program name
110 size_t NbLinesSrc
; // Number of lines source used by the sub program
111 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
112 size_t NbVariables
; // Variables number
113 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
116 // Compilation Unit internal structure
117 typedef struct CUStruct
120 size_t LowPC
, HighPC
;
121 char *PtrProducer
; // Pointer to the "Producer" text information (mostly compiler and compilation options used)
122 char *PtrSourceFilename
; // Source file name
123 char *PtrSourceFileDirectory
; // Directory of the source file
124 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
125 size_t SizeLoadSrc
; // Source code size
126 char *PtrLoadSrc
; // Pointer to loaded source code
127 size_t NbLinesLoadSrc
; // Lines source number
128 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
129 size_t NbSubProgs
; // Number of sub programs / routines
130 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines information structure
131 size_t NbTypes
; // Number of types
132 BaseTypeStruct
*PtrTypes
; // Pointer to types
133 size_t NbVariables
; // Variables number
134 VariablesStruct
*PtrVariables
; // Pointer to the global variables list information structure
135 size_t NbFrames
; // Frames number
149 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
150 void DWARFManager_InitDMI(void);
151 void DWARFManager_CloseDMI(void);
152 bool DWARFManager_ElfClose(void);
153 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
154 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
158 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
164 // Dwarf manager init
165 void DWARFManager_Init(void)
167 LibDwarf
= DW_DLV_NO_ENTRY
;
171 // Dwarf manager Reset
172 bool DWARFManager_Reset(void)
174 return DWARFManager_ElfClose();
178 // Dwarf manager Close
179 bool DWARFManager_Close(void)
181 return(DWARFManager_Reset());
185 // Dwarf manager Elf init
186 int DWARFManager_ElfInit(Elf
*ElfPtr
)
188 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
190 DWARFManager_InitDMI();
197 // Dwarf manager Elf close
198 bool DWARFManager_ElfClose(void)
200 if (LibDwarf
== DW_DLV_OK
)
202 DWARFManager_CloseDMI();
204 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
206 LibDwarf
= DW_DLV_NO_ENTRY
;
221 // Dwarf manager Compilation Units close
222 void DWARFManager_CloseDMI(void)
226 free(PtrCU
[NbCU
].PtrFullFilename
);
227 free(PtrCU
[NbCU
].PtrLoadSrc
);
228 free(PtrCU
[NbCU
].PtrProducer
);
229 free(PtrCU
[NbCU
].PtrSourceFilename
);
230 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
232 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
234 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
236 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
238 while (PtrCU
[NbCU
].NbSubProgs
--)
240 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
242 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
243 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
245 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
247 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
248 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
250 free(PtrCU
[NbCU
].PtrSubProgs
);
252 while (PtrCU
[NbCU
].NbTypes
--)
254 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
256 free(PtrCU
[NbCU
].PtrTypes
);
258 while (PtrCU
[NbCU
].NbVariables
--)
260 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
261 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
263 free(PtrCU
[NbCU
].PtrVariables
);
270 // Dwarf manager Compilation Units initialisations
271 void DWARFManager_InitDMI(void)
273 Dwarf_Unsigned next_cu_header
, return_uvalue
;
275 Dwarf_Attribute
*atlist
;
276 Dwarf_Attribute return_attr1
;
277 Dwarf_Half return_tagval
, return_attr
;
278 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
279 Dwarf_Block
*return_block
;
280 Dwarf_Signed atcnt
, cnt
;
281 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
282 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 // Check variable's name validity
561 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
563 // Check variable's memory address validity
564 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
567 PtrCU
[NbCU
].NbVariables
++;
572 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
573 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
577 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
581 case DW_TAG_base_type
:
583 case DW_TAG_structure_type
:
584 case DW_TAG_pointer_type
:
585 case DW_TAG_const_type
:
586 case DW_TAG_array_type
:
587 case DW_TAG_subrange_type
:
588 case DW_TAG_subroutine_type
:
589 case DW_TAG_enumeration_type
:
590 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
592 // Allocate memory for this type
593 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
594 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
595 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
597 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
599 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
602 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
604 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
606 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
614 // Type's type offset
616 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
618 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
623 case DW_AT_byte_size
:
624 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
626 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
632 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
634 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
640 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
642 #ifdef DEBUG_TypeName
643 if (!strcmp(return_string
, DEBUG_TypeName
))
646 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
647 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
649 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
653 // Type's file number
654 case DW_AT_decl_file
:
657 // Type's line number
658 case DW_AT_decl_line
:
667 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
670 PtrCU
[NbCU
].NbTypes
++;
672 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
676 case DW_TAG_subprogram
:
677 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
679 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
680 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
681 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
683 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
685 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
687 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
693 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
695 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
696 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
702 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
704 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
709 case DW_AT_decl_line
:
710 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
712 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
717 case DW_AT_frame_base
:
718 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
720 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
721 PtrCU
[NbCU
].NbFrames
++;
727 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
729 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
730 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
731 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
738 case DW_AT_GNU_all_tail_call_sites
:
744 case DW_AT_prototyped
:
748 case DW_AT_decl_file
:
759 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
761 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
763 // Get source line number and associated block of address
764 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
766 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
768 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
770 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
772 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
));
773 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
774 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
775 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
776 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
782 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
786 return_sub
= return_subdie
;
787 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
789 switch (return_tagval
)
791 case DW_TAG_formal_parameter
:
792 case DW_TAG_variable
:
793 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
795 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
)));
796 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
798 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
800 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
802 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
807 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
809 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
811 switch (return_block
->bl_len
)
818 switch (return_tagval
)
820 case DW_TAG_variable
:
821 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
824 case DW_TAG_formal_parameter
:
825 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
836 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
841 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
843 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
848 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
850 #ifdef DEBUG_VariableName
851 if (!strcmp(return_string
, DEBUG_VariableName
))
854 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
855 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
857 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
861 case DW_AT_decl_file
:
864 case DW_AT_decl_line
:
873 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
876 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
878 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
890 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
893 PtrCU
[NbCU
].NbSubProgs
++;
902 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
905 // Release the memory used by the source lines
906 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
908 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
910 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
913 // Set the source code lines for QT html/text conformity
914 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
916 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
918 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
920 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
922 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
931 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
936 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
941 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
946 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
947 i
+= strlen("&");
952 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
953 i
+= strlen(""");
957 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
963 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
967 // Init lines source information based on each source code line numbers
968 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
970 // Check if the subprog / function's line exists in the source code
971 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
973 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
976 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
978 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
980 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
988 // Set each source lines pointer to NULL
989 if (PtrCU
[NbCU
].NbSubProgs
)
991 // Check the presence of source lines dedicated to the sub progs
992 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
994 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
995 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
997 for (size_t j
= 0; j
< i
; j
++)
999 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1006 // Init global variables information based on types information
1007 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1009 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1012 // Init local variables information based on types information
1013 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1015 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1017 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1028 // Variables information initialisation
1029 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1031 size_t j
, TypeOffset
;
1033 #ifdef DEBUG_VariableName
1034 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1037 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1038 TypeOffset
= PtrVariables
->TypeOffset
;
1040 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1042 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1044 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1046 case DW_TAG_subroutine_type
:
1047 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1048 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1051 // Structure type tag
1052 case DW_TAG_structure_type
:
1053 PtrVariables
->TypeTag
|= TypeTag_structure
;
1054 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1056 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1058 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1064 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1066 strcat(PtrVariables
->PtrTypeName
, " *");
1072 case DW_TAG_pointer_type
:
1073 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1074 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1075 PtrVariables
->TypeEncoding
= 0x10;
1076 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1078 strcat(PtrVariables
->PtrTypeName
, "void *");
1086 case DW_TAG_enumeration_type
:
1087 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1088 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1089 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1091 // Try to determine the possible size
1092 switch (PtrVariables
->TypeByteSize
)
1095 PtrVariables
->TypeEncoding
= 0x7;
1105 case DW_TAG_typedef
:
1106 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1108 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1109 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1111 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1118 case DW_TAG_subrange_type
:
1119 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1123 case DW_TAG_array_type
:
1124 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1125 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1132 case DW_TAG_const_type
:
1133 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1134 strcat(PtrVariables
->PtrTypeName
, "const ");
1135 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1142 case DW_TAG_base_type
:
1143 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1145 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1147 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1149 strcat(PtrVariables
->PtrTypeName
, " *");
1153 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1154 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1156 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1158 strcat(PtrVariables
->PtrTypeName
, "[]");
1171 // Get symbol name based from address
1172 // Return NULL if no symbol name exists
1173 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1177 for (i
= 0; i
< NbCU
; i
++)
1179 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1181 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1183 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1185 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1195 // Get complete source filename based from address
1196 // Return NULL if no source filename exists
1197 // Return the existence status (true or false) in Error
1198 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1202 for (i
= 0; i
< NbCU
; i
++)
1204 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1206 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1207 return PtrCU
[i
].PtrFullFilename
;
1215 // Get text line source based on line number (starting by 1)
1216 // Return NULL if no text line exists or if line number is 0
1217 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1220 char *PtrLineSrc
= NULL
;
1224 while (i
!= NumLine
)
1226 PtrLineSrc
= PtrSrcFile
;
1227 while (*PtrSrcFile
++);
1236 // Get number of variables referenced by the function range address
1237 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1241 for (i
= 0; i
< NbCU
; i
++)
1243 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1245 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1247 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1249 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1259 // Get local variable name based on his index (starting by 1)
1260 // Return name's pointer text found
1261 // Return NULL if not found
1262 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1266 for (i
= 0; i
< NbCU
; i
++)
1268 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1270 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1272 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1274 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1284 // Get local variable's type tag based on his index (starting by 1)
1285 // Return 0 if not found
1286 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1290 for (i
= 0; i
< NbCU
; i
++)
1292 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1294 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1296 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1298 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1309 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1313 for (i
= 0; i
< NbCU
; i
++)
1315 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1317 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1319 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1321 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1331 // Get local variable Type Byte Size based on his address and index (starting by 1)
1332 // Return 0 if not found
1333 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1334 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1338 for (i
= 0; i
< NbCU
; i
++)
1340 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1342 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1344 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1346 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1356 // Get local variable Type Encoding based on his address and index (starting by 1)
1357 // Return 0 if not found
1358 // May return 0 if there is no Type Encoding linked to the variable's address and index
1359 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1363 for (i
= 0; i
< NbCU
; i
++)
1365 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1367 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1369 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1371 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1381 // Get local variable Op based on his address and index (starting by 1)
1382 // Return 0 if not found
1383 // May return 0 if there isn't Op linked to the variable's index
1384 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1388 for (i
= 0; i
< NbCU
; i
++)
1390 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1392 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1394 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1396 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1406 // Get local variable type name based on his index (starting by 1)
1407 // Return NULL if not found
1408 // May return NULL if there is not type linked to the variable's index
1409 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1413 for (i
= 0; i
< NbCU
; i
++)
1415 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1417 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1419 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1421 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1431 // Get Compilation Unit / global variables numbers
1432 // Return variables number
1433 size_t DWARFManager_GetNbGlobalVariables(void)
1435 size_t NbVariables
= 0, i
;
1437 for (i
= 0; i
< NbCU
; i
++)
1439 NbVariables
+= PtrCU
[i
].NbVariables
;
1446 // Get global variable type name based on his index (starting by 1)
1447 // Return NULL if not found
1448 // May return NULL if there is not type linked to the variable's index
1449 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1453 for (i
= 0; i
< NbCU
; i
++)
1455 if (PtrCU
[i
].NbVariables
)
1457 if (Index
<= PtrCU
[i
].NbVariables
)
1459 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1463 Index
-= PtrCU
[i
].NbVariables
;
1472 // Get global variable's type tag based on his index (starting by 1)
1473 // Return 0 if not found
1474 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1478 for (i
= 0; i
< NbCU
; i
++)
1480 if (PtrCU
[i
].NbVariables
)
1482 if (Index
<= PtrCU
[i
].NbVariables
)
1484 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1488 Index
-= PtrCU
[i
].NbVariables
;
1497 // Get global variable byte size based on his index (starting by 1)
1498 // Return 0 if not found
1499 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1503 for (i
= 0; i
< NbCU
; i
++)
1505 if (PtrCU
[i
].NbVariables
)
1507 if (Index
<= PtrCU
[i
].NbVariables
)
1509 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1513 Index
-= PtrCU
[i
].NbVariables
;
1522 // Get global variable encoding based on his index (starting by 1)
1523 // Return 0 if not found
1524 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1528 for (i
= 0; i
< NbCU
; i
++)
1530 if (PtrCU
[i
].NbVariables
)
1532 if (Index
<= PtrCU
[i
].NbVariables
)
1534 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1538 Index
-= PtrCU
[i
].NbVariables
;
1547 // Get global variable address based on his index (starting by 1)
1548 // Return 0 if not found
1549 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1553 for (i
= 0; i
< NbCU
; i
++)
1555 if (PtrCU
[i
].NbVariables
)
1557 if (Index
<= PtrCU
[i
].NbVariables
)
1559 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1563 Index
-= PtrCU
[i
].NbVariables
;
1572 // Get global variable memory address based on his name
1573 // Return 0 if not found
1574 // Note: Return the first occurence found
1575 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1579 for (i
= 0; i
< NbCU
; i
++)
1581 if (PtrCU
[i
].NbVariables
)
1583 for (j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1585 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1587 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1597 // Get global variable name based on his index (starting by 1)
1598 // Return name's pointer text found
1599 // Return NULL if not found
1600 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1604 for (i
= 0; i
< NbCU
; i
++)
1606 if (PtrCU
[i
].NbVariables
)
1608 if (Index
<= PtrCU
[i
].NbVariables
)
1610 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1614 Index
-= PtrCU
[i
].NbVariables
;
1623 // Get text line from source based on address and his tag
1624 // Return NULL if no text line has been found
1625 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1629 for (i
= 0; i
< NbCU
; i
++)
1631 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1633 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1635 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1637 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1639 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1643 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1645 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1647 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1649 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1654 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1667 // Get line number based on the address and the tag
1668 // Return 0 if no line number has been found
1669 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1673 for (i
= 0; i
< NbCU
; i
++)
1675 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1677 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1679 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1681 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1683 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1687 for (k
= 0; (k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
); k
++)
1689 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1691 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1696 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1698 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1710 // Get function name based on address and his range
1711 // Return NULL if no function name has been found
1712 char *DWARFManager_GetFunctionName(size_t Adr
)
1716 for (i
= 0; i
< NbCU
; i
++)
1718 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1720 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1722 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1724 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1734 // Get text line from source based on address and num line (starting by 1)
1735 // Return NULL if no text line has been found
1736 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1740 for (i
= 0; i
< NbCU
; i
++)
1742 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1744 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1746 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1748 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1750 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1754 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1756 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1758 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1771 // Get text line from source based on address and num line (starting by 1)
1772 // Return NULL if no text line has been found
1773 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1777 for (i
= 0; i
< NbCU
; i
++)
1779 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1781 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1783 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
1796 // Get number of source code filenames
1797 size_t DWARFManager_GetNbFullSourceFilename(void)
1803 // Get source code filename based on index
1804 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
1806 return (PtrCU
[Index
].PtrFullFilename
);