2 // DWARFManager.cpp: DWARF format manager
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
9 // --- ---------- ------------------------------------------------------------
10 // JPM Dec./2016 Created this file, and added the DWARF format support
11 // JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information
12 // JPM Oct./2018 Improve the DWARF parsing information, and the source file text reading; support the used source lines from DWARF structure, and the search paths for the files
13 // JPM Mar./2020 Fix a random crash when reading the source lines information
17 // To use pointers instead of arrays usage
18 // To keep sources text file intact wihtout QT/HTML transformation
31 // Definitions for debugging
32 //#define DEBUG_NumCU 0x4d // CU number to debug or undefine it
33 //#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it
34 //#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it
35 //#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)
36 //#define DEBUG_Filename "net_jag.c" // Filename to look for or undefine it
38 // Definitions for the variables's typetag
39 #define TypeTag_structure 0x01 // structure
40 #define TypeTag_pointer 0x02 // pointer
41 #define TypeTag_subrange 0x04 // (subrange_type?)
42 #define TypeTag_arraytype 0x08 // array type
43 #define TypeTag_consttype 0x10 // const type
44 #define TypeTag_typedef 0x20 // typedef
45 #define TypeTag_enumeration_type 0x40 // enumeration
46 #define TypeTag_subroutine_type 0x80 // subroutine
49 // Source line CU structure
50 typedef struct CUStruct_LineSrc
57 // Source line internal structure
58 typedef struct DMIStruct_LineSrc
66 // Enumeration structure
67 typedef struct EnumerationStruct
69 char *PtrName
; // Enumeration's name
70 size_t value
; // Enumeration's value
73 // Structure members structure
74 //typedef struct StructureMembersStruct
76 //}S_StructureMembersStruct;
78 // Base type internal structure
79 typedef struct BaseTypeStruct
81 size_t Tag
; // Type's Tag
82 size_t Offset
; // Type's offset
83 size_t TypeOffset
; // Type's offset on another type
84 size_t ByteSize
; // Type's Byte Size
85 size_t Encoding
; // Type's encoding
86 char *PtrName
; // Type's name
87 size_t NbEnumeration
; // Type's enumeration numbers
88 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
89 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
92 // Variables internal structure
93 typedef struct VariablesStruct
95 size_t Op
; // Variable's DW_OP
98 size_t Addr
; // Variable memory address
99 int Offset
; // Variable stack offset (signed)
101 char *PtrName
; // Variable's name
102 size_t TypeOffset
; // Offset pointing on the Variable's Type
103 size_t TypeByteSize
; // Variable's Type byte size
104 size_t TypeTag
; // Variable's Type Tag
105 size_t TypeEncoding
; // Variable's Type encoding
106 char *PtrTypeName
; // Variable's Type name
109 // Sub program internal structure
110 typedef struct SubProgStruct
115 size_t LowPC
, HighPC
;
118 char *PtrSubprogramName
; // Sub program name
119 size_t NbLinesSrc
; // Number of lines source used by the sub program
120 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
121 size_t NbVariables
; // Variables number
122 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
125 // Compilation Unit internal structure
126 typedef struct CUStruct
129 size_t LowPC
, HighPC
; // Memory range for the code
130 char *PtrProducer
; // Pointer to the "Producer" text information (mostly compiler and compilation options used)
131 char *PtrSourceFilename
; // Source file name
132 char *PtrSourceFileDirectory
; // Directory of the source file
133 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
134 size_t SizeLoadSrc
; // Source code text size
135 char *PtrLoadSrc
; // Pointer to the source code text
136 size_t NbLinesLoadSrc
; // Total number of lines in the source code text
137 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
138 size_t NbSubProgs
; // Number of sub programs / routines
139 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines structure
140 size_t NbTypes
; // Number of types
141 BaseTypeStruct
*PtrTypes
; // Pointer to types
142 size_t NbVariables
; // Variables number
143 VariablesStruct
*PtrVariables
; // Pointer to the global variables list structure
144 size_t NbFrames
; // Frames number
145 size_t NbLinesSrc
; // Number of used source lines
146 CUStruct_LineSrc
*PtrLinesSrc
; // Pointer to the used source lines list structure
157 char **ListSearchPaths
;
158 size_t NbSearchPaths
;
162 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
163 void DWARFManager_InitDMI(void);
164 void DWARFManager_CloseDMI(void);
165 bool DWARFManager_ElfClose(void);
166 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
167 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
168 void DWARFManager_SourceFileSearchPathsInit(void);
169 void DWARFManager_SourceFileSearchPathsReset(void);
170 void DWARFManager_SourceFileSearchPathsClose(void);
174 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
180 // Dwarf manager list search paths init
181 void DWARFManager_SourceFileSearchPathsInit(void)
183 ListSearchPaths
= NULL
;
188 // Dwarf manager list search paths reset
189 void DWARFManager_SourceFileSearchPathsReset(void)
191 ListSearchPaths
= NULL
;
196 // Dwarf manager list search paths close
197 void DWARFManager_SourceFileSearchPathsClose(void)
199 DWARFManager_SourceFileSearchPathsReset();
203 // Dwarf manager init
204 void DWARFManager_Init(void)
206 DWARFManager_SourceFileSearchPathsInit();
207 LibDwarf
= DW_DLV_NO_ENTRY
;
211 // Dwarf manager settings
212 void DWARFManager_Set(size_t NbPathsInList
, char **PtrListPaths
)
215 ListSearchPaths
= PtrListPaths
;
216 NbSearchPaths
= NbPathsInList
;
220 // Dwarf manager Reset
221 bool DWARFManager_Reset(void)
223 DWARFManager_SourceFileSearchPathsReset();
224 return DWARFManager_ElfClose();
228 // Dwarf manager Close
229 bool DWARFManager_Close(void)
231 DWARFManager_SourceFileSearchPathsClose();
232 return(DWARFManager_Reset());
236 // Dwarf manager Elf init
237 int DWARFManager_ElfInit(Elf
*ElfPtr
)
239 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
241 DWARFManager_InitDMI();
248 // Dwarf manager Elf close
249 bool DWARFManager_ElfClose(void)
251 if (LibDwarf
== DW_DLV_OK
)
253 DWARFManager_CloseDMI();
255 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
257 LibDwarf
= DW_DLV_NO_ENTRY
;
272 // Dwarf manager Compilation Units close
273 void DWARFManager_CloseDMI(void)
277 free(PtrCU
[NbCU
].PtrFullFilename
);
278 free(PtrCU
[NbCU
].PtrLoadSrc
);
279 free(PtrCU
[NbCU
].PtrProducer
);
280 free(PtrCU
[NbCU
].PtrSourceFilename
);
281 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
282 free(PtrCU
[NbCU
].PtrLinesSrc
);
284 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
286 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
288 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
290 while (PtrCU
[NbCU
].NbSubProgs
--)
292 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
294 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
295 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
297 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
299 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
300 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
302 free(PtrCU
[NbCU
].PtrSubProgs
);
304 while (PtrCU
[NbCU
].NbTypes
--)
306 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
308 free(PtrCU
[NbCU
].PtrTypes
);
310 while (PtrCU
[NbCU
].NbVariables
--)
312 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
313 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
315 free(PtrCU
[NbCU
].PtrVariables
);
322 // Dwarf manager Compilation Units initialisations
323 void DWARFManager_InitDMI(void)
325 Dwarf_Unsigned next_cu_header
, return_uvalue
;
327 Dwarf_Attribute
*atlist
;
328 Dwarf_Attribute return_attr1
;
329 Dwarf_Half return_tagval
, return_attr
;
330 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
331 Dwarf_Block
*return_block
;
332 Dwarf_Signed atcnt
, cnt
;
333 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
334 Dwarf_Off return_offset
;
340 // Initialisation for the Compilation Units table
344 // loop on the available Compilation Unit
345 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
347 // Allocation of an additional Compilation Unit structure in the table
348 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
350 // Compilation Unit RAZ
351 PtrCU
= (CUStruct
*)Ptr
;
352 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
356 if (NbCU
== DEBUG_NumCU
)
359 // Get 1st Die from the Compilation Unit
360 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
363 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
365 PtrCU
[NbCU
].Tag
= return_tagval
;
367 // Die type detection
368 switch (return_tagval
)
370 case DW_TAG_compile_unit
:
371 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
373 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
375 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
381 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
383 PtrCU
[NbCU
].LowPC
= return_lowpc
;
389 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
391 PtrCU
[NbCU
].HighPC
= return_highpc
;
395 // compilation information
397 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
399 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
400 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
401 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
407 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
409 #ifdef DEBUG_Filename
410 if (strstr(return_string
, DEBUG_Filename
))
413 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
414 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
416 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
422 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
424 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
425 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
426 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
434 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
436 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
439 // Check filename presence
440 if (!PtrCU
[NbCU
].PtrSourceFilename
)
442 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
445 // Check directory presence
446 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
448 // Check if file exists in the search paths
449 for (size_t i
= 0; i
< NbSearchPaths
; i
++)
451 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen((const char *)ListSearchPaths
[i
]) + 2);
453 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
455 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
457 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
459 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, strlen(ListSearchPaths
[i
]) + 1);
460 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ListSearchPaths
[i
]);
464 // File directory doesn't exits
465 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
467 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, 2);
468 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ".");
472 // Create full filename
473 Ptr
= PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
475 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
477 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
479 // Conform slashes and backslashes
496 // Directory path clean-up
498 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
500 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
504 while (*--Ptr1
!= '\\');
506 while (*--Ptr1
!= '/');
508 strcpy((Ptr1
+ 1), (Ptr
+ 4));
511 // Open the source file as a binary file
512 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
514 if (!fseek(SrcFile
, 0, SEEK_END
))
516 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
518 if (!fseek(SrcFile
, 0, SEEK_SET
))
520 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
523 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
525 free(PtrCU
[NbCU
].PtrLoadSrc
);
526 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
527 PtrCU
[NbCU
].SizeLoadSrc
= 0;
531 // Eliminate all carriage return code '\r' (oxd)
534 if ((*Ptr
= *Ptr1
) != '\r')
541 // Get back the new text file size
542 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
544 // Make sure the text file finish with a new line code '\n' (0xa)
545 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
547 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
548 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
551 // Reallocate text file
552 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
554 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
559 PtrCU
[NbCU
].NbLinesLoadSrc
++;
578 // Get the source lines table located in the CU
579 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
583 PtrCU
[NbCU
].NbLinesSrc
= cnt
;
584 PtrCU
[NbCU
].PtrLinesSrc
= (CUStruct_LineSrc
*)calloc(cnt
, sizeof(CUStruct_LineSrc
));
585 for (Dwarf_Signed i
= 0; i
< cnt
; i
++)
587 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
589 // Get the source line number
590 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
592 PtrCU
[NbCU
].PtrLinesSrc
[i
].StartPC
= return_lineaddr
;
593 PtrCU
[NbCU
].PtrLinesSrc
[i
].NumLineSrc
= return_uvalue
;
599 // Release the memory used by the source lines table located in the CU
600 dwarf_srclines_dealloc(dbg
, linebuf
, cnt
);
603 // Check if the CU has child
604 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
608 return_sib
= return_die
;
609 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
611 switch (return_tagval
)
613 case DW_TAG_lexical_block
:
616 case DW_TAG_variable
:
617 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
619 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
620 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
622 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
624 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
626 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
631 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
633 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
635 switch (return_block
->bl_len
)
638 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));
644 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
649 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
651 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
657 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
659 #ifdef DEBUG_VariableName
660 if (!strcmp(return_string
, DEBUG_VariableName
))
663 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
664 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
666 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
676 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
679 // Check variable's name validity
680 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
682 // Check variable's memory address validity
683 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
686 PtrCU
[NbCU
].NbVariables
++;
691 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
692 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
696 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
700 case DW_TAG_base_type
:
702 case DW_TAG_structure_type
:
703 case DW_TAG_pointer_type
:
704 case DW_TAG_const_type
:
705 case DW_TAG_array_type
:
706 case DW_TAG_subrange_type
:
707 case DW_TAG_subroutine_type
:
708 case DW_TAG_enumeration_type
:
709 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
711 // Allocate memory for this type
712 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
713 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
714 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
716 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
718 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
721 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
723 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
725 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
733 // Type's type offset
735 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
737 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
742 case DW_AT_byte_size
:
743 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
745 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
751 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
753 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
759 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
761 #ifdef DEBUG_TypeName
762 if (!strcmp(return_string
, DEBUG_TypeName
))
765 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
766 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
768 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
772 // Type's file number
773 case DW_AT_decl_file
:
776 // Type's line number
777 case DW_AT_decl_line
:
786 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
789 PtrCU
[NbCU
].NbTypes
++;
791 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
795 case DW_TAG_subprogram
:
796 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
798 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
799 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
800 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
802 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
804 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
806 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
812 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
814 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
815 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
821 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
823 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
828 case DW_AT_decl_line
:
829 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
831 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
836 case DW_AT_frame_base
:
837 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
839 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
840 PtrCU
[NbCU
].NbFrames
++;
846 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
848 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
849 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
850 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
857 case DW_AT_GNU_all_tail_call_sites
:
863 case DW_AT_prototyped
:
867 case DW_AT_decl_file
:
878 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
880 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
882 // Get source line number and associated block of address
883 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
885 if ((PtrCU
[NbCU
].PtrLinesSrc
[i
].StartPC
>= return_lowpc
) && (PtrCU
[NbCU
].PtrLinesSrc
[i
].StartPC
<= return_highpc
))
887 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
));
888 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
889 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= PtrCU
[NbCU
].PtrLinesSrc
[i
].StartPC
;
890 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= PtrCU
[NbCU
].PtrLinesSrc
[i
].NumLineSrc
;
891 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
895 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
899 return_sub
= return_subdie
;
900 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
902 switch (return_tagval
)
904 case DW_TAG_formal_parameter
:
905 case DW_TAG_variable
:
906 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
908 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
, ((PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
909 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
911 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
913 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
915 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
920 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
922 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
924 switch (return_block
->bl_len
)
931 switch (return_tagval
)
933 case DW_TAG_variable
:
934 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
937 case DW_TAG_formal_parameter
:
938 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
949 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
954 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
956 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
961 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
963 #ifdef DEBUG_VariableName
964 if (!strcmp(return_string
, DEBUG_VariableName
))
967 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
968 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
970 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
974 case DW_AT_decl_file
:
977 case DW_AT_decl_line
:
986 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
989 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
991 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
1003 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
1006 PtrCU
[NbCU
].NbSubProgs
++;
1015 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
1019 // Set the source code lines for QT html/text conformity
1020 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
1022 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
1024 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
1026 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
1028 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
1037 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
1042 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
1047 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
1052 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
1053 i
+= strlen("&");
1058 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
1059 i
+= strlen(""");
1063 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
1069 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
1073 // Init lines source information for each source code line numbers and for each subprogs
1074 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
1076 // Check if the subprog / function's line exists in the source code
1077 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1079 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1082 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1084 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1086 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1094 // Set each source lines pointer to NULL
1095 if (PtrCU
[NbCU
].NbSubProgs
)
1097 // Check the presence of source lines dedicated to the sub progs
1098 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1100 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1101 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1103 for (size_t j
= 0; j
< i
; j
++)
1105 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1112 // Set information based on used line numbers
1113 if (PtrCU
[NbCU
].PtrLinesSrc
)
1115 // Set the line source pointer for each used line numbers
1116 if (PtrCU
[NbCU
].PtrLinesLoadSrc
)
1118 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbLinesSrc
; i
++)
1120 PtrCU
[NbCU
].PtrLinesSrc
[i
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrLinesSrc
[i
].NumLineSrc
- 1];
1123 // Setup memory range for the code if CU doesn't have already this information
1124 // It is taken from the used lines structure
1125 if (!PtrCU
[NbCU
].LowPC
&& (!PtrCU
[NbCU
].HighPC
|| (PtrCU
[NbCU
].HighPC
== ~0)))
1127 PtrCU
[NbCU
].LowPC
= PtrCU
[NbCU
].PtrLinesSrc
[0].StartPC
;
1128 PtrCU
[NbCU
].HighPC
= PtrCU
[NbCU
].PtrLinesSrc
[PtrCU
[NbCU
].NbLinesSrc
- 1].StartPC
;
1133 // Init global variables information based on types information
1134 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1136 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1139 // Init local variables information based on types information
1140 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1142 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1144 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1155 // Variables information initialisation
1156 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1158 size_t j
, TypeOffset
;
1160 #ifdef DEBUG_VariableName
1161 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1164 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1165 TypeOffset
= PtrVariables
->TypeOffset
;
1167 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1169 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1171 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1173 case DW_TAG_subroutine_type
:
1174 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1175 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1178 // Structure type tag
1179 case DW_TAG_structure_type
:
1180 PtrVariables
->TypeTag
|= TypeTag_structure
;
1181 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1183 if (PtrCU
[NbCU
].PtrTypes
[j
].PtrName
)
1185 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1188 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1194 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1196 strcat(PtrVariables
->PtrTypeName
, " *");
1202 case DW_TAG_pointer_type
:
1203 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1204 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1205 PtrVariables
->TypeEncoding
= 0x10;
1206 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1208 strcat(PtrVariables
->PtrTypeName
, "void *");
1216 case DW_TAG_enumeration_type
:
1217 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1218 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1219 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1221 // Try to determine the possible size
1222 switch (PtrVariables
->TypeByteSize
)
1225 PtrVariables
->TypeEncoding
= 0x7;
1235 case DW_TAG_typedef
:
1236 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1238 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1239 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1241 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1248 case DW_TAG_subrange_type
:
1249 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1253 case DW_TAG_array_type
:
1254 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1255 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1262 case DW_TAG_const_type
:
1263 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1264 strcat(PtrVariables
->PtrTypeName
, "const ");
1265 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1272 case DW_TAG_base_type
:
1273 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1275 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1277 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1279 strcat(PtrVariables
->PtrTypeName
, " *");
1283 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1284 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1286 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1288 strcat(PtrVariables
->PtrTypeName
, "[]");
1301 // Get symbol name based from address
1302 // Return NULL if no symbol name exists
1303 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1305 for (size_t i
= 0; i
< NbCU
; i
++)
1307 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1309 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1311 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1313 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1323 // Get complete source filename based from address
1324 // Return NULL if no source filename exists
1325 // Return the existence status (true or false) in Error
1326 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1328 for (size_t i
= 0; i
< NbCU
; i
++)
1330 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1332 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1333 return PtrCU
[i
].PtrFullFilename
;
1341 // Get text line source based on line number (starting from 1)
1342 // Return NULL if no text line exists or if line number is 0
1343 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1346 char *PtrLineSrc
= NULL
;
1350 while (i
!= NumLine
)
1352 PtrLineSrc
= PtrSrcFile
;
1353 while (*PtrSrcFile
++);
1362 // Get number of variables referenced by the function range address
1363 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1365 for (size_t i
= 0; i
< NbCU
; i
++)
1367 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1369 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1371 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1373 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1383 // Get local variable name based on his index (starting from 1)
1384 // Return name's pointer text found
1385 // Return NULL if not found
1386 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1388 for (size_t i
= 0; i
< NbCU
; i
++)
1390 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1392 for (size_t 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].PtrName
;
1406 // Get local variable's type tag based on his index (starting from 1)
1407 // Return 0 if not found
1408 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1410 for (size_t i
= 0; i
< NbCU
; i
++)
1412 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1414 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1416 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1418 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1428 // Get the local variable's offset based on a index (starting from 1)
1429 // Return 0 if no offset has been found
1430 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1432 for (size_t i
= 0; i
< NbCU
; i
++)
1434 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1436 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1438 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1440 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1450 // Get local variable Type Byte Size based on his address and index (starting from 1)
1451 // Return 0 if not found
1452 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1453 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1455 for (size_t i
= 0; i
< NbCU
; i
++)
1457 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1459 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1461 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1463 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1473 // Get local variable Type Encoding based on his address and index (starting from 1)
1474 // Return 0 if not found
1475 // May return 0 if there is no Type Encoding linked to the variable's address and index
1476 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1478 for (size_t i
= 0; i
< NbCU
; i
++)
1480 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1482 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1484 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1486 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1496 // Get local variable Op based on his address and index (starting from 1)
1497 // Return 0 if not found, may return 0 if there isn't Op linked to the variable's index
1498 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1500 for (size_t i
= 0; i
< NbCU
; i
++)
1502 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1504 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1506 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1508 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1518 // Get local variable type name based on his index (starting from 1) and an address
1519 // Return NULL if not found, may also return NULL if there is no type linked to the variable's index
1520 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1522 for (size_t i
= 0; i
< NbCU
; i
++)
1524 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1526 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1528 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1530 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1540 // Get Compilation Unit / global variables numbers
1541 // Return number of variables
1542 size_t DWARFManager_GetNbGlobalVariables(void)
1544 size_t NbVariables
= 0;
1546 for (size_t i
= 0; i
< NbCU
; i
++)
1548 NbVariables
+= PtrCU
[i
].NbVariables
;
1555 // Get global variable type name based on his index (starting from 1)
1556 // Return NULL if not found
1557 // May return NULL if there is not type linked to the variable's index
1558 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1560 for (size_t i
= 0; i
< NbCU
; i
++)
1562 if (PtrCU
[i
].NbVariables
)
1564 if (Index
<= PtrCU
[i
].NbVariables
)
1566 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1570 Index
-= PtrCU
[i
].NbVariables
;
1579 // Get global variable's type tag based on his index (starting from 1)
1580 // Return 0 if not found
1581 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1583 for (size_t i
= 0; i
< NbCU
; i
++)
1585 if (PtrCU
[i
].NbVariables
)
1587 if (Index
<= PtrCU
[i
].NbVariables
)
1589 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1593 Index
-= PtrCU
[i
].NbVariables
;
1602 // Get global variable byte size based on his index (starting from 1)
1603 // Return 0 if not found
1604 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1606 for (size_t i
= 0; i
< NbCU
; i
++)
1608 if (PtrCU
[i
].NbVariables
)
1610 if (Index
<= PtrCU
[i
].NbVariables
)
1612 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1616 Index
-= PtrCU
[i
].NbVariables
;
1625 // Get global variable encoding based on his index (starting from 1)
1626 // Return 0 if not found
1627 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1629 for (size_t i
= 0; i
< NbCU
; i
++)
1631 if (PtrCU
[i
].NbVariables
)
1633 if (Index
<= PtrCU
[i
].NbVariables
)
1635 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1639 Index
-= PtrCU
[i
].NbVariables
;
1648 // Get global variable memory address based on his index (starting from 1)
1649 // Return 0 if not found
1650 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1652 for (size_t i
= 0; i
< NbCU
; i
++)
1654 if (PtrCU
[i
].NbVariables
)
1656 if (Index
<= PtrCU
[i
].NbVariables
)
1658 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1662 Index
-= PtrCU
[i
].NbVariables
;
1671 // Get global variable memory address based on his name
1672 // Return 0 if not found, or will return the first occurence found
1673 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1675 for (size_t i
= 0; i
< NbCU
; i
++)
1677 if (PtrCU
[i
].NbVariables
)
1679 for (size_t j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1681 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1683 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1693 // Get global variable name based on his index (starting from 1)
1694 // Return name's pointer text found, or will return NULL if no variable can be found
1695 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1697 for (size_t i
= 0; i
< NbCU
; i
++)
1699 if (PtrCU
[i
].NbVariables
)
1701 if (Index
<= PtrCU
[i
].NbVariables
)
1703 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1707 Index
-= PtrCU
[i
].NbVariables
;
1716 // Get text line from source based on address and his tag
1717 // A tag can be either 0 or a DW_TAG_subprogram
1718 // DW_TAG_subprogram will look for the line pointing to the function
1719 // Return NULL if no text line has been found
1720 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1722 for (size_t i
= 0; i
< NbCU
; i
++)
1724 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1726 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1728 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1730 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1732 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1736 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1738 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1740 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1742 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1747 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1760 // Get line number based on the address and a tag
1761 // A tag can be either 0 or a DW_TAG_subprogram
1762 // DW_TAG_subprogram will look for the line pointing to the function name as described in the source code
1763 // Return 0 if no line number has been found
1764 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1766 for (size_t i
= 0; i
< NbCU
; i
++)
1768 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1770 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1772 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1774 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1776 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1780 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1782 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1784 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1789 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1791 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1797 // Check if a used line is found with the address
1798 for (size_t j
= 0; j
< PtrCU
[i
].NbLinesSrc
; j
++)
1800 if (PtrCU
[i
].PtrLinesSrc
[j
].StartPC
== Adr
)
1802 return PtrCU
[i
].PtrLinesSrc
[j
].NumLineSrc
;
1812 // Get function name based on an address
1813 // Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address
1814 char *DWARFManager_GetFunctionName(size_t Adr
)
1816 for (size_t i
= 0; i
< NbCU
; i
++)
1818 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1820 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1822 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1824 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1834 // Get text line from source based on address and num line (starting from 1)
1835 // Return NULL if no text line has been found
1836 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1838 for (size_t i
= 0; i
< NbCU
; i
++)
1840 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1842 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1844 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1846 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1848 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1852 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1854 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1856 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1869 // Get text line pointer from source, based on address and line number (starting from 1)
1870 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
1871 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1873 for (size_t i
= 0; i
< NbCU
; i
++)
1875 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1877 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1879 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
1892 // Get number of source code filenames
1893 size_t DWARFManager_GetNbFullSourceFilename(void)
1899 // Get source code filename based on index (starting from 0)
1900 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
1902 return (PtrCU
[Index
].PtrFullFilename
);