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, the source file text reading, and Support the used lines source DWARF structure
16 // To use pointers instead of arrays usage
29 // Definitions for debugging
30 //#define DEBUG_NumCU 0x9 // CU number to debug or undefine it
31 //#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it
32 //#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it
33 //#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)
34 //#define DEBUG_Filename "net_jag.c" // Filename to look for or undefine it
36 // Definitions for the variables's typetag
37 #define TypeTag_structure 0x01 // structure
38 #define TypeTag_pointer 0x02 // pointer
39 #define TypeTag_subrange 0x04 // (subrange_type?)
40 #define TypeTag_arraytype 0x08 // array type
41 #define TypeTag_consttype 0x10 // const type
42 #define TypeTag_typedef 0x20 // typedef
43 #define TypeTag_enumeration_type 0x40 // enumeration
44 #define TypeTag_subroutine_type 0x80 // subroutine
47 // Source line CU structure
48 typedef struct CUStruct_LineSrc
55 // Source line internal structure
56 typedef struct DMIStruct_LineSrc
64 // Enumeration structure
65 typedef struct EnumerationStruct
67 char *PtrName
; // Enumeration's name
68 size_t value
; // Enumeration's value
71 // Structure members structure
72 //typedef struct StructureMembersStruct
74 //}S_StructureMembersStruct;
76 // Base type internal structure
77 typedef struct BaseTypeStruct
79 size_t Tag
; // Type's Tag
80 size_t Offset
; // Type's offset
81 size_t TypeOffset
; // Type's offset on another type
82 size_t ByteSize
; // Type's Byte Size
83 size_t Encoding
; // Type's encoding
84 char *PtrName
; // Type's name
85 size_t NbEnumeration
; // Type's enumeration numbers
86 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
87 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
90 // Variables internal structure
91 typedef struct VariablesStruct
93 size_t Op
; // Variable's DW_OP
96 size_t Addr
; // Variable memory address
97 int Offset
; // Variable stack offset (signed)
99 char *PtrName
; // Variable's name
100 size_t TypeOffset
; // Offset pointing on the Variable's Type
101 size_t TypeByteSize
; // Variable's Type byte size
102 size_t TypeTag
; // Variable's Type Tag
103 size_t TypeEncoding
; // Variable's Type encoding
104 char *PtrTypeName
; // Variable's Type name
107 // Sub program internal structure
108 typedef struct SubProgStruct
113 size_t LowPC
, HighPC
;
116 char *PtrSubprogramName
; // Sub program name
117 size_t NbLinesSrc
; // Number of lines source used by the sub program
118 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
119 size_t NbVariables
; // Variables number
120 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
123 // Compilation Unit internal structure
124 typedef struct CUStruct
127 size_t LowPC
, HighPC
; // Memory range for the code
128 char *PtrProducer
; // Pointer to the "Producer" text information (mostly compiler and compilation options used)
129 char *PtrSourceFilename
; // Source file name
130 char *PtrSourceFileDirectory
; // Directory of the source file
131 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
132 size_t SizeLoadSrc
; // Source code text size
133 char *PtrLoadSrc
; // Pointer to the source code text
134 size_t NbLinesLoadSrc
; // Total number of lines in the source code text
135 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
136 size_t NbSubProgs
; // Number of sub programs / routines
137 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines structure
138 size_t NbTypes
; // Number of types
139 BaseTypeStruct
*PtrTypes
; // Pointer to types
140 size_t NbVariables
; // Variables number
141 VariablesStruct
*PtrVariables
; // Pointer to the global variables list structure
142 size_t NbFrames
; // Frames number
143 size_t NbLinesSrc
; // Number of used source lines
144 CUStruct_LineSrc
*PtrLinesSrc
; // Pointer to the used source lines list structure
158 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
159 void DWARFManager_InitDMI(void);
160 void DWARFManager_CloseDMI(void);
161 bool DWARFManager_ElfClose(void);
162 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
163 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
167 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
173 // Dwarf manager init
174 void DWARFManager_Init(void)
176 LibDwarf
= DW_DLV_NO_ENTRY
;
180 // Dwarf manager Reset
181 bool DWARFManager_Reset(void)
183 return DWARFManager_ElfClose();
187 // Dwarf manager Close
188 bool DWARFManager_Close(void)
190 return(DWARFManager_Reset());
194 // Dwarf manager Elf init
195 int DWARFManager_ElfInit(Elf
*ElfPtr
)
197 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
199 DWARFManager_InitDMI();
206 // Dwarf manager Elf close
207 bool DWARFManager_ElfClose(void)
209 if (LibDwarf
== DW_DLV_OK
)
211 DWARFManager_CloseDMI();
213 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
215 LibDwarf
= DW_DLV_NO_ENTRY
;
230 // Dwarf manager Compilation Units close
231 void DWARFManager_CloseDMI(void)
235 free(PtrCU
[NbCU
].PtrFullFilename
);
236 free(PtrCU
[NbCU
].PtrLoadSrc
);
237 free(PtrCU
[NbCU
].PtrProducer
);
238 free(PtrCU
[NbCU
].PtrSourceFilename
);
239 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
240 free(PtrCU
[NbCU
].PtrLinesSrc
);
242 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
244 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
246 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
248 while (PtrCU
[NbCU
].NbSubProgs
--)
250 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
252 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
253 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
255 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
257 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
258 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
260 free(PtrCU
[NbCU
].PtrSubProgs
);
262 while (PtrCU
[NbCU
].NbTypes
--)
264 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
266 free(PtrCU
[NbCU
].PtrTypes
);
268 while (PtrCU
[NbCU
].NbVariables
--)
270 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
271 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
273 free(PtrCU
[NbCU
].PtrVariables
);
280 // Dwarf manager Compilation Units initialisations
281 void DWARFManager_InitDMI(void)
283 Dwarf_Unsigned next_cu_header
, return_uvalue
;
285 Dwarf_Attribute
*atlist
;
286 Dwarf_Attribute return_attr1
;
287 Dwarf_Half return_tagval
, return_attr
;
288 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
289 Dwarf_Block
*return_block
;
290 Dwarf_Signed atcnt
, cnt
;
291 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
292 Dwarf_Off return_offset
;
298 // Initialisation for the Compilation Units table
302 // loop on the available Compilation Unit
303 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
305 // Allocation of an additional Compilation Unit structure in the table
306 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
308 // Compilation Unit RAZ
309 PtrCU
= (CUStruct
*)Ptr
;
310 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
314 if (NbCU
== DEBUG_NumCU
)
317 // Get 1st Die from the Compilation Unit
318 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
321 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
323 PtrCU
[NbCU
].Tag
= return_tagval
;
325 // Die type detection
326 switch (return_tagval
)
328 case DW_TAG_compile_unit
:
329 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
331 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
333 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
339 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
341 PtrCU
[NbCU
].LowPC
= return_lowpc
;
347 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
349 PtrCU
[NbCU
].HighPC
= return_highpc
;
353 // compilation information
355 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
357 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
358 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
359 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
365 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
367 #ifdef DEBUG_Filename
368 if (strstr(return_string
, DEBUG_Filename
))
371 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
372 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
374 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
380 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
382 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
383 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
384 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
392 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
394 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
397 // Check filename validity
398 if (!PtrCU
[NbCU
].PtrSourceFilename
)
400 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
403 // Check directory validity
404 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
406 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc(2, 1);
407 PtrCU
[NbCU
].PtrSourceFileDirectory
[0] = '.';
410 // Create full filename
411 Ptr
= PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
412 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
414 // Conform slashes and backslashes
431 // Directory path clean-up
433 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
435 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
439 while (*--Ptr1
!= '\\');
441 while (*--Ptr1
!= '/');
443 strcpy((Ptr1
+ 1), (Ptr
+ 4));
446 // Open the source file as a binary file
447 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
449 if (!fseek(SrcFile
, 0, SEEK_END
))
451 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
453 if (!fseek(SrcFile
, 0, SEEK_SET
))
455 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
458 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
460 free(PtrCU
[NbCU
].PtrLoadSrc
);
461 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
462 PtrCU
[NbCU
].SizeLoadSrc
= 0;
466 // Eliminate all carriage return code '\r' (oxd)
469 if ((*Ptr
= *Ptr1
) != '\r')
476 // Get back the new text file size
477 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
479 // Make sure the text file finish with a new line code '\n' (0xa)
480 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
482 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
483 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
486 // Reallocate text file
487 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
489 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
494 PtrCU
[NbCU
].NbLinesLoadSrc
++;
513 // Get the source lines table located in the CU
514 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
518 PtrCU
[NbCU
].NbLinesSrc
= cnt
;
519 PtrCU
[NbCU
].PtrLinesSrc
= (CUStruct_LineSrc
*)calloc(cnt
, sizeof(CUStruct_LineSrc
));
520 for (Dwarf_Signed i
= 0; i
< cnt
; i
++)
522 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
524 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
526 PtrCU
[NbCU
].PtrLinesSrc
[i
].StartPC
= return_lineaddr
;
527 PtrCU
[NbCU
].PtrLinesSrc
[i
].NumLineSrc
= return_uvalue
;
534 // Check if the CU has child
535 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
539 return_sib
= return_die
;
540 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
542 switch (return_tagval
)
544 case DW_TAG_lexical_block
:
547 case DW_TAG_variable
:
548 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
550 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
551 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
553 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
555 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
557 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
562 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
564 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
566 switch (return_block
->bl_len
)
569 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));
575 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
580 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
582 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
588 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
590 #ifdef DEBUG_VariableName
591 if (!strcmp(return_string
, DEBUG_VariableName
))
594 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
595 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
597 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
607 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
610 // Check variable's name validity
611 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
613 // Check variable's memory address validity
614 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
617 PtrCU
[NbCU
].NbVariables
++;
622 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
623 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
627 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
631 case DW_TAG_base_type
:
633 case DW_TAG_structure_type
:
634 case DW_TAG_pointer_type
:
635 case DW_TAG_const_type
:
636 case DW_TAG_array_type
:
637 case DW_TAG_subrange_type
:
638 case DW_TAG_subroutine_type
:
639 case DW_TAG_enumeration_type
:
640 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
642 // Allocate memory for this type
643 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
644 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
645 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
647 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
649 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
652 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
654 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
656 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
664 // Type's type offset
666 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
668 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
673 case DW_AT_byte_size
:
674 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
676 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
682 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
684 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
690 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
692 #ifdef DEBUG_TypeName
693 if (!strcmp(return_string
, DEBUG_TypeName
))
696 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
697 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
699 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
703 // Type's file number
704 case DW_AT_decl_file
:
707 // Type's line number
708 case DW_AT_decl_line
:
717 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
720 PtrCU
[NbCU
].NbTypes
++;
722 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
726 case DW_TAG_subprogram
:
727 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
729 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
730 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
731 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
733 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
735 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
737 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
743 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
745 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
746 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
752 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
754 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
759 case DW_AT_decl_line
:
760 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
762 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
767 case DW_AT_frame_base
:
768 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
770 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
771 PtrCU
[NbCU
].NbFrames
++;
777 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
779 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
780 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
781 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
788 case DW_AT_GNU_all_tail_call_sites
:
794 case DW_AT_prototyped
:
798 case DW_AT_decl_file
:
809 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
811 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
813 // Get source line number and associated block of address
814 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
816 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
818 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
820 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
822 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
));
823 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
824 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
825 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
826 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
832 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
836 return_sub
= return_subdie
;
837 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
839 switch (return_tagval
)
841 case DW_TAG_formal_parameter
:
842 case DW_TAG_variable
:
843 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
845 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
)));
846 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
848 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
850 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
852 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
857 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
859 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
861 switch (return_block
->bl_len
)
868 switch (return_tagval
)
870 case DW_TAG_variable
:
871 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
874 case DW_TAG_formal_parameter
:
875 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
886 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
891 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
893 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
898 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
900 #ifdef DEBUG_VariableName
901 if (!strcmp(return_string
, DEBUG_VariableName
))
904 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
905 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
907 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
911 case DW_AT_decl_file
:
914 case DW_AT_decl_line
:
923 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
926 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
928 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
940 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
943 PtrCU
[NbCU
].NbSubProgs
++;
952 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
955 // Release the memory used by the source lines
956 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
958 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
960 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
963 // Set the source code lines for QT html/text conformity
964 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
966 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
968 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
970 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
972 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
981 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
986 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
991 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
996 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
997 i
+= strlen("&");
1002 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
1003 i
+= strlen(""");
1007 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
1013 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
1017 // Init lines source information for each source code line numbers and for each subprogs
1018 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
1020 // Check if the subprog / function's line exists in the source code
1021 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1023 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1026 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1028 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1030 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1038 // Set each source lines pointer to NULL
1039 if (PtrCU
[NbCU
].NbSubProgs
)
1041 // Check the presence of source lines dedicated to the sub progs
1042 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1044 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1045 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1047 for (size_t j
= 0; j
< i
; j
++)
1049 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1056 // Set information based on used line numbers
1057 if (PtrCU
[NbCU
].PtrLinesSrc
)
1059 // Set the line source pointer for each used line numbers
1060 if (PtrCU
[NbCU
].PtrLinesLoadSrc
)
1062 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbLinesSrc
; i
++)
1064 PtrCU
[NbCU
].PtrLinesSrc
[i
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrLinesSrc
[i
].NumLineSrc
- 1];
1068 // Setup memory range for the code if CU doesn't have already this information
1069 // It is taken from the used lines structure
1070 if (!PtrCU
[NbCU
].LowPC
&& !PtrCU
[NbCU
].HighPC
)
1072 PtrCU
[NbCU
].LowPC
= PtrCU
[NbCU
].PtrLinesSrc
[0].StartPC
;
1073 PtrCU
[NbCU
].HighPC
= PtrCU
[NbCU
].PtrLinesSrc
[PtrCU
[NbCU
].NbLinesSrc
- 1].StartPC
;
1077 // Init global variables information based on types information
1078 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1080 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1083 // Init local variables information based on types information
1084 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1086 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1088 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1099 // Variables information initialisation
1100 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1102 size_t j
, TypeOffset
;
1104 #ifdef DEBUG_VariableName
1105 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1108 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1109 TypeOffset
= PtrVariables
->TypeOffset
;
1111 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1113 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1115 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1117 case DW_TAG_subroutine_type
:
1118 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1119 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1122 // Structure type tag
1123 case DW_TAG_structure_type
:
1124 PtrVariables
->TypeTag
|= TypeTag_structure
;
1125 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1127 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1129 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1135 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1137 strcat(PtrVariables
->PtrTypeName
, " *");
1143 case DW_TAG_pointer_type
:
1144 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1145 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1146 PtrVariables
->TypeEncoding
= 0x10;
1147 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1149 strcat(PtrVariables
->PtrTypeName
, "void *");
1157 case DW_TAG_enumeration_type
:
1158 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1159 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1160 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1162 // Try to determine the possible size
1163 switch (PtrVariables
->TypeByteSize
)
1166 PtrVariables
->TypeEncoding
= 0x7;
1176 case DW_TAG_typedef
:
1177 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1179 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1180 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1182 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1189 case DW_TAG_subrange_type
:
1190 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1194 case DW_TAG_array_type
:
1195 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1196 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1203 case DW_TAG_const_type
:
1204 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1205 strcat(PtrVariables
->PtrTypeName
, "const ");
1206 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1213 case DW_TAG_base_type
:
1214 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1216 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1218 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1220 strcat(PtrVariables
->PtrTypeName
, " *");
1224 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1225 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1227 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1229 strcat(PtrVariables
->PtrTypeName
, "[]");
1242 // Get symbol name based from address
1243 // Return NULL if no symbol name exists
1244 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1248 for (i
= 0; i
< NbCU
; i
++)
1250 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1252 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1254 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1256 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1266 // Get complete source filename based from address
1267 // Return NULL if no source filename exists
1268 // Return the existence status (true or false) in Error
1269 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1273 for (i
= 0; i
< NbCU
; i
++)
1275 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1277 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1278 return PtrCU
[i
].PtrFullFilename
;
1286 // Get text line source based on line number (starting by 1)
1287 // Return NULL if no text line exists or if line number is 0
1288 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1291 char *PtrLineSrc
= NULL
;
1295 while (i
!= NumLine
)
1297 PtrLineSrc
= PtrSrcFile
;
1298 while (*PtrSrcFile
++);
1307 // Get number of variables referenced by the function range address
1308 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1312 for (i
= 0; i
< NbCU
; i
++)
1314 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1316 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1318 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1320 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1330 // Get local variable name based on his index (starting by 1)
1331 // Return name's pointer text found
1332 // Return NULL if not found
1333 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1337 for (i
= 0; i
< NbCU
; i
++)
1339 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1341 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1343 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1345 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1355 // Get local variable's type tag based on his index (starting by 1)
1356 // Return 0 if not found
1357 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1361 for (i
= 0; i
< NbCU
; i
++)
1363 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1365 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1367 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1369 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1380 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1384 for (i
= 0; i
< NbCU
; i
++)
1386 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1388 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1390 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1392 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1402 // Get local variable Type Byte Size based on his address and index (starting by 1)
1403 // Return 0 if not found
1404 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1405 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1409 for (i
= 0; i
< NbCU
; i
++)
1411 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1413 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1415 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1417 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1427 // Get local variable Type Encoding based on his address and index (starting by 1)
1428 // Return 0 if not found
1429 // May return 0 if there is no Type Encoding linked to the variable's address and index
1430 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1434 for (i
= 0; i
< NbCU
; i
++)
1436 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1438 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1440 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1442 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1452 // Get local variable Op based on his address and index (starting by 1)
1453 // Return 0 if not found, may return 0 if there isn't Op linked to the variable's index
1454 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1458 for (i
= 0; i
< NbCU
; i
++)
1460 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1462 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1464 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1466 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1476 // Get local variable type name based on his index (starting by 1) and an address
1477 // Return NULL if not found, may also return NULL if there is no type linked to the variable's index
1478 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1482 for (i
= 0; i
< NbCU
; i
++)
1484 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1486 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1488 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1490 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1500 // Get Compilation Unit / global variables numbers
1501 // Return number of variables
1502 size_t DWARFManager_GetNbGlobalVariables(void)
1504 size_t NbVariables
= 0, i
;
1506 for (i
= 0; i
< NbCU
; i
++)
1508 NbVariables
+= PtrCU
[i
].NbVariables
;
1515 // Get global variable type name based on his index (starting by 1)
1516 // Return NULL if not found
1517 // May return NULL if there is not type linked to the variable's index
1518 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1522 for (i
= 0; i
< NbCU
; i
++)
1524 if (PtrCU
[i
].NbVariables
)
1526 if (Index
<= PtrCU
[i
].NbVariables
)
1528 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1532 Index
-= PtrCU
[i
].NbVariables
;
1541 // Get global variable's type tag based on his index (starting by 1)
1542 // Return 0 if not found
1543 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1547 for (i
= 0; i
< NbCU
; i
++)
1549 if (PtrCU
[i
].NbVariables
)
1551 if (Index
<= PtrCU
[i
].NbVariables
)
1553 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1557 Index
-= PtrCU
[i
].NbVariables
;
1566 // Get global variable byte size based on his index (starting by 1)
1567 // Return 0 if not found
1568 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1572 for (i
= 0; i
< NbCU
; i
++)
1574 if (PtrCU
[i
].NbVariables
)
1576 if (Index
<= PtrCU
[i
].NbVariables
)
1578 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1582 Index
-= PtrCU
[i
].NbVariables
;
1591 // Get global variable encoding based on his index (starting by 1)
1592 // Return 0 if not found
1593 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1597 for (i
= 0; i
< NbCU
; i
++)
1599 if (PtrCU
[i
].NbVariables
)
1601 if (Index
<= PtrCU
[i
].NbVariables
)
1603 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1607 Index
-= PtrCU
[i
].NbVariables
;
1616 // Get global variable address based on his index (starting by 1)
1617 // Return 0 if not found
1618 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1622 for (i
= 0; i
< NbCU
; i
++)
1624 if (PtrCU
[i
].NbVariables
)
1626 if (Index
<= PtrCU
[i
].NbVariables
)
1628 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1632 Index
-= PtrCU
[i
].NbVariables
;
1641 // Get global variable memory address based on his name
1642 // Return 0 if not found, or will return the first occurence found
1643 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1647 for (i
= 0; i
< NbCU
; i
++)
1649 if (PtrCU
[i
].NbVariables
)
1651 for (j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1653 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1655 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1665 // Get global variable name based on his index (starting by 1)
1666 // Return name's pointer text found, or will return NULL if no variable can be found
1667 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1671 for (i
= 0; i
< NbCU
; i
++)
1673 if (PtrCU
[i
].NbVariables
)
1675 if (Index
<= PtrCU
[i
].NbVariables
)
1677 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1681 Index
-= PtrCU
[i
].NbVariables
;
1690 // Get text line from source based on address and his tag
1691 // A tag can be either 0 or a DW_TAG_subprogram
1692 // DW_TAG_subprogram will look for the line pointing to the function
1693 // Return NULL if no text line has been found
1694 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1698 for (i
= 0; i
< NbCU
; i
++)
1700 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1702 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1704 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1706 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1708 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1712 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1714 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1716 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1718 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1723 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1736 // Get line number based on the address and a tag
1737 // A tag can be either 0 or a DW_TAG_subprogram
1738 // DW_TAG_subprogram will look for the line pointing to the function name as described in the source code
1739 // Return 0 if no line number has been found
1740 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1744 for (i
= 0; i
< NbCU
; i
++)
1746 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1748 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1750 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1752 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1754 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1758 for (k
= 0; (k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
); k
++)
1760 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1762 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1767 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1769 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1781 // Get function name based on an address
1782 // Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address
1783 char *DWARFManager_GetFunctionName(size_t Adr
)
1787 for (i
= 0; i
< NbCU
; i
++)
1789 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1791 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1793 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1795 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1805 // Get text line from source based on address and num line (starting by 1)
1806 // Return NULL if no text line has been found
1807 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1811 for (i
= 0; i
< NbCU
; i
++)
1813 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1815 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1817 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1819 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1821 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1825 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1827 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1829 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1842 // Get text line pointer from source, based on address and line number (starting by 1)
1843 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
1844 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1848 for (i
= 0; i
< NbCU
; i
++)
1850 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1852 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1854 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
1867 // Get number of source code filenames
1868 size_t DWARFManager_GetNbFullSourceFilename(void)
1874 // Get source code filename based on index (starting from 0)
1875 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
1877 return (PtrCU
[Index
].PtrFullFilename
);