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 Aug./2019 Added new functions to handle DWARF information, full filename fix
17 // To use pointers instead of arrays usage
30 // Definitions for debugging
31 //#define DEBUG_NumCU 0x3 // 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 "crt0" // Filename to look for or undefine it
37 // Definitions for handling data
38 //#define CONVERT_QT_HML // Text will be converted as HTML
40 // Definitions for the variables's typetag
41 #define TypeTag_structure 0x01 // structure
42 #define TypeTag_pointer 0x02 // pointer
43 #define TypeTag_subrange 0x04 // (subrange_type?)
44 #define TypeTag_arraytype 0x08 // array type
45 #define TypeTag_consttype 0x10 // const type
46 #define TypeTag_typedef 0x20 // typedef
47 #define TypeTag_enumeration_type 0x40 // enumeration
48 #define TypeTag_subroutine_type 0x80 // subroutine
51 // Source line CU structure
52 typedef struct CUStruct_LineSrc
59 // Source line internal structure
60 typedef struct DMIStruct_LineSrc
68 // Enumeration structure
69 typedef struct EnumerationStruct
71 char *PtrName
; // Enumeration's name
72 size_t value
; // Enumeration's value
75 // Structure members structure
76 //typedef struct StructureMembersStruct
78 //}S_StructureMembersStruct;
80 // Base type internal structure
81 typedef struct BaseTypeStruct
83 size_t Tag
; // Type's Tag
84 size_t Offset
; // Type's offset
85 size_t TypeOffset
; // Type's offset on another type
86 size_t ByteSize
; // Type's Byte Size
87 size_t Encoding
; // Type's encoding
88 char *PtrName
; // Type's name
89 size_t NbEnumeration
; // Type's enumeration numbers
90 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
91 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
94 // Variables internal structure
95 typedef struct VariablesStruct
97 size_t Op
; // Variable's DW_OP
100 size_t Addr
; // Variable memory address
101 int Offset
; // Variable stack offset (signed)
103 char *PtrName
; // Variable's name
104 size_t TypeOffset
; // Offset pointing on the Variable's Type
105 size_t TypeByteSize
; // Variable's Type byte size
106 size_t TypeTag
; // Variable's Type Tag
107 size_t TypeEncoding
; // Variable's Type encoding
108 char *PtrTypeName
; // Variable's Type name
111 // Sub program internal structure
112 typedef struct SubProgStruct
117 size_t LowPC
, HighPC
;
120 char *PtrSubprogramName
; // Sub program name
121 size_t NbLinesSrc
; // Number of lines source used by the sub program
122 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
123 size_t NbVariables
; // Variables number
124 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
127 // Compilation Unit internal structure
128 typedef struct CUStruct
131 size_t Language
; // Language (C, etc.) used by the source code
132 size_t LowPC
, HighPC
; // Memory range for the code
133 char *PtrProducer
; // Pointer to the "Producer" text information (mostly compiler and compilation options used)
134 char *PtrSourceFilename
; // Source file name
135 char *PtrSourceFileDirectory
; // Directory of the source file
136 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
137 size_t SizeLoadSrc
; // Source code text size
138 char *PtrLoadSrc
; // Pointer to the source code text
139 size_t NbLinesLoadSrc
; // Total number of lines in the source code text
140 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
141 size_t NbSubProgs
; // Number of sub programs / routines
142 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines structure
143 size_t NbTypes
; // Number of types
144 BaseTypeStruct
*PtrTypes
; // Pointer to types
145 size_t NbVariables
; // Variables number
146 VariablesStruct
*PtrVariables
; // Pointer to the global variables list structure
147 size_t NbFrames
; // Frames number
148 size_t NbUsedLinesSrc
; // Number of used source lines
149 size_t LastNumUsedLinesSrc
; // Last number line used
150 CUStruct_LineSrc
*PtrUsedLinesSrc
; // Pointer to the used source lines list structure
151 char **PtrUsedLinesLoadSrc
; // Pointer lists to each used source line referenced by the CUStruct_LineSrc structure
152 size_t *PtrUsedNumLines
; // List of the number lines used
163 char **ListSearchPaths
;
164 size_t NbSearchPaths
;
168 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
169 void DWARFManager_InitDMI(void);
170 void DWARFManager_CloseDMI(void);
171 bool DWARFManager_ElfClose(void);
172 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
173 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
174 void DWARFManager_SourceFileSearchPathsInit(void);
175 void DWARFManager_SourceFileSearchPathsReset(void);
176 void DWARFManager_SourceFileSearchPathsClose(void);
177 void DWARFManager_ConformSlachesBackslashes(char *Ptr
);
181 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
187 // Dwarf manager list search paths init
188 void DWARFManager_SourceFileSearchPathsInit(void)
190 ListSearchPaths
= NULL
;
195 // Dwarf manager list search paths reset
196 void DWARFManager_SourceFileSearchPathsReset(void)
198 ListSearchPaths
= NULL
;
203 // Dwarf manager list search paths close
204 void DWARFManager_SourceFileSearchPathsClose(void)
206 DWARFManager_SourceFileSearchPathsReset();
210 // Dwarf manager init
211 void DWARFManager_Init(void)
213 DWARFManager_SourceFileSearchPathsInit();
214 LibDwarf
= DW_DLV_NO_ENTRY
;
218 // Dwarf manager settings
219 void DWARFManager_Set(size_t NbPathsInList
, char **PtrListPaths
)
222 ListSearchPaths
= PtrListPaths
;
223 NbSearchPaths
= NbPathsInList
;
227 // Dwarf manager Reset
228 bool DWARFManager_Reset(void)
230 DWARFManager_SourceFileSearchPathsReset();
231 return DWARFManager_ElfClose();
235 // Dwarf manager Close
236 bool DWARFManager_Close(void)
238 DWARFManager_SourceFileSearchPathsClose();
239 return(DWARFManager_Reset());
243 // Dwarf manager Elf init
244 int DWARFManager_ElfInit(Elf
*ElfPtr
)
246 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
248 DWARFManager_InitDMI();
255 // Dwarf manager Elf close
256 bool DWARFManager_ElfClose(void)
258 if (LibDwarf
== DW_DLV_OK
)
260 DWARFManager_CloseDMI();
262 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
264 LibDwarf
= DW_DLV_NO_ENTRY
;
279 // Dwarf manager Compilation Units close
280 void DWARFManager_CloseDMI(void)
284 free(PtrCU
[NbCU
].PtrFullFilename
);
285 free(PtrCU
[NbCU
].PtrLoadSrc
);
286 free(PtrCU
[NbCU
].PtrProducer
);
287 free(PtrCU
[NbCU
].PtrSourceFilename
);
288 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
289 free(PtrCU
[NbCU
].PtrUsedLinesSrc
);
290 free(PtrCU
[NbCU
].PtrUsedLinesLoadSrc
);
291 free(PtrCU
[NbCU
].PtrUsedNumLines
);
293 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
295 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
297 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
299 while (PtrCU
[NbCU
].NbSubProgs
--)
301 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
303 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
304 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
306 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
308 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
309 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
311 free(PtrCU
[NbCU
].PtrSubProgs
);
313 while (PtrCU
[NbCU
].NbTypes
--)
315 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
317 free(PtrCU
[NbCU
].PtrTypes
);
319 while (PtrCU
[NbCU
].NbVariables
--)
321 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
322 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
324 free(PtrCU
[NbCU
].PtrVariables
);
331 // Dwarf manager Compilation Units initialisations
332 void DWARFManager_InitDMI(void)
334 Dwarf_Unsigned next_cu_header
, return_uvalue
;
336 Dwarf_Attribute
*atlist
;
337 Dwarf_Attribute return_attr1
;
338 Dwarf_Half return_tagval
, return_attr
;
339 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
340 Dwarf_Block
*return_block
;
341 Dwarf_Signed atcnt
, cnt
;
342 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
343 Dwarf_Off return_offset
;
349 // Initialisation for the Compilation Units table
353 // loop on the available Compilation Unit
354 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
356 // Allocation of an additional Compilation Unit structure in the table
357 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
359 // Compilation Unit RAZ
360 PtrCU
= (CUStruct
*)Ptr
;
361 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
365 if (NbCU
== DEBUG_NumCU
)
368 // Get 1st Die from the Compilation Unit
369 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
372 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
374 PtrCU
[NbCU
].Tag
= return_tagval
;
376 // Die type detection
377 switch (return_tagval
)
379 case DW_TAG_compile_unit
:
380 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
382 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
384 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
390 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
392 PtrCU
[NbCU
].LowPC
= return_lowpc
;
398 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
400 PtrCU
[NbCU
].HighPC
= return_highpc
;
404 // compilation information
406 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
408 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
409 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
410 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
416 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
418 #ifdef DEBUG_Filename
419 if (strstr(return_string
, DEBUG_Filename
))
422 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
423 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
425 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
431 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
433 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
434 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
435 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
441 if (dwarf_formudata(atlist
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
443 PtrCU
[NbCU
].Language
= return_uvalue
;
451 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
453 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
456 // Check filename presence
457 if (!PtrCU
[NbCU
].PtrSourceFilename
)
459 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
462 // Check directory presence
463 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
465 // Check if file exists in the search paths
466 for (size_t i
= 0; i
< NbSearchPaths
; i
++)
468 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen((const char *)ListSearchPaths
[i
]) + 2);
470 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
472 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
474 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
476 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, strlen(ListSearchPaths
[i
]) + 1);
477 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ListSearchPaths
[i
]);
481 // File directory doesn't exits
482 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
484 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, 2);
485 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ".");
489 // Conform slashes / backslashes for the filename
490 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrSourceFilename
);
492 // Check if filename contains already the complete directory
493 if (PtrCU
[NbCU
].PtrSourceFilename
[1] == ':')
495 // Copy the filename as the full filename
496 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + 1);
497 strcpy(PtrCU
[NbCU
].PtrFullFilename
, PtrCU
[NbCU
].PtrSourceFilename
);
501 // Create full filename and Conform slashes / backslashes
502 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
504 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
506 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
510 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrFullFilename
);
512 // Directory path clean-up
514 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
516 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
520 while (*--Ptr1
!= '\\');
522 while (*--Ptr1
!= '/');
524 strcpy((Ptr1
+ 1), (Ptr
+ 4));
527 // Open the source file as a binary file
528 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
530 if (!fseek(SrcFile
, 0, SEEK_END
))
532 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
534 if (!fseek(SrcFile
, 0, SEEK_SET
))
536 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
539 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
541 free(PtrCU
[NbCU
].PtrLoadSrc
);
542 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
543 PtrCU
[NbCU
].SizeLoadSrc
= 0;
547 // Eliminate all carriage return code '\r' (oxd)
550 if ((*Ptr
= *Ptr1
) != '\r')
557 // Get back the new text file size
558 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
560 // Make sure the text file finish with a new line code '\n' (0xa)
561 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
563 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
564 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
567 // Reallocate text file
568 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
570 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
575 PtrCU
[NbCU
].NbLinesLoadSrc
++;
594 // Get the source lines table located in the CU
595 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
599 PtrCU
[NbCU
].NbUsedLinesSrc
= cnt
;
600 PtrCU
[NbCU
].PtrUsedLinesSrc
= (CUStruct_LineSrc
*)calloc(cnt
, sizeof(CUStruct_LineSrc
));
601 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
= (char **)calloc(cnt
, sizeof(char *));
602 PtrCU
[NbCU
].PtrUsedNumLines
= (size_t *)calloc(cnt
, sizeof(size_t));
604 // Get the addresses and their source line numbers
605 for (Dwarf_Signed i
= 0; i
< cnt
; i
++)
607 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
609 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
611 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
= return_lineaddr
;
612 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
= return_uvalue
;
614 // Get the last used line number in the source file
615 if (PtrCU
[NbCU
].LastNumUsedLinesSrc
< PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
)
617 PtrCU
[NbCU
].LastNumUsedLinesSrc
= PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
;
625 // Check if the CU has child
626 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
630 return_sib
= return_die
;
631 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
633 switch (return_tagval
)
635 case DW_TAG_lexical_block
:
638 case DW_TAG_variable
:
639 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
641 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
642 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
644 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
646 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
648 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
653 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
655 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
657 switch (return_block
->bl_len
)
660 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));
666 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
671 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
673 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
679 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
681 #ifdef DEBUG_VariableName
682 if (!strcmp(return_string
, DEBUG_VariableName
))
685 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
686 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
688 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
698 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
701 // Check variable's name validity
702 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
704 // Check variable's memory address validity
705 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
708 PtrCU
[NbCU
].NbVariables
++;
713 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
714 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
718 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
722 case DW_TAG_base_type
:
724 case DW_TAG_structure_type
:
725 case DW_TAG_pointer_type
:
726 case DW_TAG_const_type
:
727 case DW_TAG_array_type
:
728 case DW_TAG_subrange_type
:
729 case DW_TAG_subroutine_type
:
730 case DW_TAG_enumeration_type
:
731 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
733 // Allocate memory for this type
734 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
735 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
736 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
738 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
740 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
743 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
745 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
747 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
755 // Type's type offset
757 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
759 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
764 case DW_AT_byte_size
:
765 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
767 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
773 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
775 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
781 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
783 #ifdef DEBUG_TypeName
784 if (!strcmp(return_string
, DEBUG_TypeName
))
787 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
788 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
790 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
794 // Type's file number
795 case DW_AT_decl_file
:
798 // Type's line number
799 case DW_AT_decl_line
:
808 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
811 PtrCU
[NbCU
].NbTypes
++;
813 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
817 case DW_TAG_subprogram
:
818 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
820 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
821 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
822 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
824 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
826 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
828 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
834 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
836 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
837 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
843 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
845 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
850 case DW_AT_decl_line
:
851 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
853 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
858 case DW_AT_frame_base
:
859 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
861 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
862 PtrCU
[NbCU
].NbFrames
++;
868 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
870 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
871 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
872 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
879 case DW_AT_GNU_all_tail_call_sites
:
885 case DW_AT_prototyped
:
889 case DW_AT_decl_file
:
900 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
902 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
904 // Get source line number and associated block of address
905 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
907 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
909 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
911 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
913 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
));
914 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
915 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
916 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
917 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
923 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
927 return_sub
= return_subdie
;
928 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
930 switch (return_tagval
)
932 case DW_TAG_formal_parameter
:
933 case DW_TAG_variable
:
934 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
936 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
)));
937 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
939 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
941 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
943 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
948 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
950 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
952 switch (return_block
->bl_len
)
959 switch (return_tagval
)
961 case DW_TAG_variable
:
962 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
965 case DW_TAG_formal_parameter
:
966 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
977 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
982 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
984 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
989 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
991 #ifdef DEBUG_VariableName
992 if (!strcmp(return_string
, DEBUG_VariableName
))
995 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
996 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
998 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
1002 case DW_AT_decl_file
:
1005 case DW_AT_decl_line
:
1014 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
1017 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
1019 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
1031 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
1034 PtrCU
[NbCU
].NbSubProgs
++;
1043 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
1046 // Release the memory used by the source lines
1047 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
1049 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
1051 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
1054 // Set the source code lines
1055 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
1057 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
1059 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
1061 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
1063 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
1071 #ifdef CONVERT_QT_HML
1073 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
1078 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
1083 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
1088 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
1089 i
+= strlen("&");
1094 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
1095 i
+= strlen(""");
1100 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
1106 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
1110 // Init lines source information for each source code line numbers and for each subprogs
1111 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
1113 // Check if the subprog / function's line exists in the source code
1114 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1116 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1119 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1121 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1123 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1131 // Set each source lines pointer to NULL
1132 if (PtrCU
[NbCU
].NbSubProgs
)
1134 // Check the presence of source lines dedicated to the sub progs
1135 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1137 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1138 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1140 for (size_t j
= 0; j
< i
; j
++)
1142 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1149 // Check validity between used number lines and number lines in the source file
1150 if (PtrCU
[NbCU
].LastNumUsedLinesSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1152 // Set information based on used line numbers
1153 if (PtrCU
[NbCU
].PtrUsedLinesSrc
)
1155 // Set the line source pointers for each used line numbers
1156 if (PtrCU
[NbCU
].PtrLinesLoadSrc
)
1158 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbUsedLinesSrc
; i
++)
1160 PtrCU
[NbCU
].PtrUsedNumLines
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1;
1161 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1];
1164 // Setup memory range for the code if CU doesn't have already this information
1165 // It is taken from the used lines structure
1166 if (!PtrCU
[NbCU
].LowPC
&& (!PtrCU
[NbCU
].HighPC
|| (PtrCU
[NbCU
].HighPC
== ~0)))
1168 PtrCU
[NbCU
].LowPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[0].StartPC
;
1169 PtrCU
[NbCU
].HighPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[PtrCU
[NbCU
].NbUsedLinesSrc
- 1].StartPC
;
1175 // Init global variables information based on types information
1176 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1178 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1181 // Init local variables information based on types information
1182 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1184 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1186 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1197 // Conform slashes and backslashes
1198 void DWARFManager_ConformSlachesBackslashes(char *Ptr
)
1218 // Variables information initialisation
1219 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1221 size_t j
, TypeOffset
;
1223 #ifdef DEBUG_VariableName
1224 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1227 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1228 TypeOffset
= PtrVariables
->TypeOffset
;
1230 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1232 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1234 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1236 case DW_TAG_subroutine_type
:
1237 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1238 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1241 // Structure type tag
1242 case DW_TAG_structure_type
:
1243 PtrVariables
->TypeTag
|= TypeTag_structure
;
1244 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1246 if (PtrCU
[NbCU
].PtrTypes
[j
].PtrName
)
1248 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1251 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1257 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1259 strcat(PtrVariables
->PtrTypeName
, " *");
1265 case DW_TAG_pointer_type
:
1266 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1267 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1268 PtrVariables
->TypeEncoding
= 0x10;
1269 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1271 strcat(PtrVariables
->PtrTypeName
, "void *");
1279 case DW_TAG_enumeration_type
:
1280 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1281 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1282 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1284 // Try to determine the possible size
1285 switch (PtrVariables
->TypeByteSize
)
1288 PtrVariables
->TypeEncoding
= 0x7;
1298 case DW_TAG_typedef
:
1299 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1301 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1302 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1304 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1311 case DW_TAG_subrange_type
:
1312 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1316 case DW_TAG_array_type
:
1317 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1318 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1325 case DW_TAG_const_type
:
1326 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1327 strcat(PtrVariables
->PtrTypeName
, "const ");
1328 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1335 case DW_TAG_base_type
:
1336 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1338 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1340 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1342 strcat(PtrVariables
->PtrTypeName
, " *");
1346 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1347 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1349 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1351 strcat(PtrVariables
->PtrTypeName
, "[]");
1364 // Get symbol name based from address
1365 // Return NULL if no symbol name exists
1366 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1368 for (size_t i
= 0; i
< NbCU
; i
++)
1370 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1372 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1374 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1376 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1386 // Get complete source filename based from address
1387 // Return NULL if no source filename exists
1388 // Return the existence status (true or false) in Error
1389 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1391 for (size_t i
= 0; i
< NbCU
; i
++)
1393 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1395 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1396 return PtrCU
[i
].PtrFullFilename
;
1404 // Get text line source based on line number (starting from 1)
1405 // Return NULL if no text line exists or if line number is 0
1406 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1409 char *PtrLineSrc
= NULL
;
1413 while (i
!= NumLine
)
1415 PtrLineSrc
= PtrSrcFile
;
1416 while (*PtrSrcFile
++);
1425 // Get number of variables referenced by the function range address
1426 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1428 for (size_t i
= 0; i
< NbCU
; i
++)
1430 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1432 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1434 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1436 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1446 // Get local variable name based on his index (starting from 1)
1447 // Return name's pointer text found
1448 // Return NULL if not found
1449 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1451 for (size_t i
= 0; i
< NbCU
; i
++)
1453 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1455 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1457 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1459 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1469 // Get local variable's type tag based on his index (starting from 1)
1470 // Return 0 if not found
1471 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1473 for (size_t i
= 0; i
< NbCU
; i
++)
1475 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1477 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1479 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1481 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1491 // Get the local variable's offset based on a index (starting from 1)
1492 // Return 0 if no offset has been found
1493 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1495 for (size_t i
= 0; i
< NbCU
; i
++)
1497 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1499 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1501 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1503 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1513 // Get local variable Type Byte Size based on his address and index (starting from 1)
1514 // Return 0 if not found
1515 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1516 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1518 for (size_t i
= 0; i
< NbCU
; i
++)
1520 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1522 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1524 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1526 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1536 // Get local variable Type Encoding based on his address and index (starting from 1)
1537 // Return 0 if not found
1538 // May return 0 if there is no Type Encoding linked to the variable's address and index
1539 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1541 for (size_t i
= 0; i
< NbCU
; i
++)
1543 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1545 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1547 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1549 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1559 // Get local variable Op based on his address and index (starting from 1)
1560 // Return 0 if not found, may return 0 if there isn't Op linked to the variable's index
1561 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1563 for (size_t i
= 0; i
< NbCU
; i
++)
1565 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1567 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1569 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1571 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1581 // Get local variable type name based on his index (starting from 1) and an address
1582 // Return NULL if not found, may also return NULL if there is no type linked to the variable's index
1583 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1585 for (size_t i
= 0; i
< NbCU
; i
++)
1587 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1589 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1591 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1593 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1603 // Get Compilation Unit / global variables numbers
1604 // Return number of variables
1605 size_t DWARFManager_GetNbGlobalVariables(void)
1607 size_t NbVariables
= 0;
1609 for (size_t i
= 0; i
< NbCU
; i
++)
1611 NbVariables
+= PtrCU
[i
].NbVariables
;
1618 // Get global variable type name based on his index (starting from 1)
1619 // Return NULL if not found
1620 // May return NULL if there is not type linked to the variable's index
1621 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1623 for (size_t i
= 0; i
< NbCU
; i
++)
1625 if (PtrCU
[i
].NbVariables
)
1627 if (Index
<= PtrCU
[i
].NbVariables
)
1629 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1633 Index
-= PtrCU
[i
].NbVariables
;
1642 // Get global variable's type tag based on his index (starting from 1)
1643 // Return 0 if not found
1644 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1646 for (size_t i
= 0; i
< NbCU
; i
++)
1648 if (PtrCU
[i
].NbVariables
)
1650 if (Index
<= PtrCU
[i
].NbVariables
)
1652 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1656 Index
-= PtrCU
[i
].NbVariables
;
1665 // Get global variable byte size based on his index (starting from 1)
1666 // Return 0 if not found
1667 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1669 for (size_t i
= 0; i
< NbCU
; i
++)
1671 if (PtrCU
[i
].NbVariables
)
1673 if (Index
<= PtrCU
[i
].NbVariables
)
1675 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1679 Index
-= PtrCU
[i
].NbVariables
;
1688 // Get global variable encoding based on his index (starting from 1)
1689 // Return 0 if not found
1690 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1692 for (size_t i
= 0; i
< NbCU
; i
++)
1694 if (PtrCU
[i
].NbVariables
)
1696 if (Index
<= PtrCU
[i
].NbVariables
)
1698 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1702 Index
-= PtrCU
[i
].NbVariables
;
1711 // Get global variable memory address based on his index (starting from 1)
1712 // Return 0 if not found
1713 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1715 for (size_t i
= 0; i
< NbCU
; i
++)
1717 if (PtrCU
[i
].NbVariables
)
1719 if (Index
<= PtrCU
[i
].NbVariables
)
1721 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1725 Index
-= PtrCU
[i
].NbVariables
;
1734 // Get global variable memory address based on his name
1735 // Return 0 if not found, or will return the first occurence found
1736 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1738 for (size_t i
= 0; i
< NbCU
; i
++)
1740 if (PtrCU
[i
].NbVariables
)
1742 for (size_t j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1744 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1746 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1756 // Get global variable name based on his index (starting from 1)
1757 // Return name's pointer text found, or will return NULL if no variable can be found
1758 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1760 for (size_t i
= 0; i
< NbCU
; i
++)
1762 if (PtrCU
[i
].NbVariables
)
1764 if (Index
<= PtrCU
[i
].NbVariables
)
1766 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1770 Index
-= PtrCU
[i
].NbVariables
;
1779 // Get text line from source based on address and his tag
1780 // A tag can be either 0 or a DW_TAG_subprogram
1781 // DW_TAG_subprogram will look for the line pointing to the function
1782 // Return NULL if no text line has been found
1783 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1785 for (size_t i
= 0; i
< NbCU
; i
++)
1787 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1789 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1791 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1793 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1795 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1799 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1801 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1803 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1805 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1810 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1823 // Get line number based on the address and a tag
1824 // A tag can be either 0 or a DW_TAG_subprogram
1825 // DW_TAG_subprogram will look for the line pointing to the function name as described in the source code
1826 // Return 0 if no line number has been found
1827 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1829 for (size_t i
= 0; i
< NbCU
; i
++)
1831 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1833 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1835 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1837 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1839 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1843 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1845 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1847 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1852 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1854 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1860 // Check if a used line is found with the address
1861 for (size_t j
= 0; j
< PtrCU
[i
].NbUsedLinesSrc
; j
++)
1863 if (PtrCU
[i
].PtrUsedLinesSrc
[j
].StartPC
== Adr
)
1865 return PtrCU
[i
].PtrUsedLinesSrc
[j
].NumLineSrc
;
1875 // Get function name based on an address
1876 // Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address
1877 char *DWARFManager_GetFunctionName(size_t Adr
)
1879 for (size_t i
= 0; i
< NbCU
; i
++)
1881 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1883 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1885 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1887 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1897 // Get number of lines of texts source list from source index
1898 size_t DWARFManager_GetSrcNbListPtrFromIndex(size_t Index
, bool Used
)
1902 return PtrCU
[Index
].NbLinesLoadSrc
;
1906 return PtrCU
[Index
].NbUsedLinesSrc
;
1911 // Get text source line number list pointer from source index
1912 // Return NULL for the text source used list
1913 size_t *DWARFManager_GetSrcNumLinesPtrFromIndex(size_t Index
, bool Used
)
1917 return PtrCU
[Index
].PtrUsedNumLines
;
1926 // Get text source list pointers from source index
1927 // Return NULL for the text source used list
1928 char **DWARFManager_GetSrcListPtrFromIndex(size_t Index
, bool Used
)
1932 return PtrCU
[Index
].PtrLinesLoadSrc
;
1936 return PtrCU
[Index
].PtrUsedLinesLoadSrc
;
1941 // Get source language
1942 size_t DWARFManager_GetSrcLanguageFromIndex(size_t Index
)
1944 return PtrCU
[Index
].Language
;
1948 // Get text line from source based on address and num line (starting from 1)
1949 // Return NULL if no text line has been found
1950 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1952 for (size_t i
= 0; i
< NbCU
; i
++)
1954 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1956 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1958 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1960 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1962 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1966 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1968 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1970 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1983 // Get text line pointer from source, based on address and line number (starting from 1)
1984 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
1985 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1987 for (size_t i
= 0; i
< NbCU
; i
++)
1989 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1991 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1993 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
2006 // Get number of source code filenames
2007 size_t DWARFManager_GetNbSources(void)
2013 // Get source code filename, including his directory, based on index (starting from 0)
2014 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
2016 return (PtrCU
[Index
].PtrFullFilename
);
2020 // Get source code filename based on index (starting from 0)
2021 char *DWARFManager_GetNumSourceFilename(size_t Index
)
2023 return (PtrCU
[Index
].PtrSourceFilename
);