2 // DWARFManager.cpp: DWARF format manager
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 // RG = Richard Goedeken
10 // --- ---------- ------------------------------------------------------------
11 // JPM Dec./2016 Created this file, and added the DWARF format support
12 // JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information
13 // JPM Oct./2018 Improve the DWARF parsing information, and the source file text reading; support the used source lines from DWARF structure, and the search paths for the files
14 // JPM Aug./2019 Added new functions to handle DWARF information, full filename fix
15 // JPM Mar./2020 Fix a random crash when reading the source lines information
16 // JPM Aug./2020 Added a source code file date check
17 // RG Jan./2021 Linux build fixes
18 // JPM Apr./2021 Support the structure and union members
22 // To use pointers instead of arrays usage (originally done to check if values are set at the right places)
31 #include <sys/types.h>
36 #include "DWARFManager.h"
38 // Definitions for debugging
39 //#define DEBUG_NumCU 0x2 // CU number to debug or undefine it
40 //#define DEBUG_VariableName "cvar_vars" // Variable name to look for or undefine it
41 //#define DEBUG_TypeName "edict_t" // Type name to look for or undefine it
42 //#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not used / not supported)
43 //#define DEBUG_Filename "crt0" // Filename to look for or undefine it
45 // Definitions for handling data
46 //#define CONVERT_QT_HML // Text will be converted as HTML
48 // Definitions for the variables's typetag
49 #define TypeTag_structure 0x01 // structure
50 #define TypeTag_pointer 0x02 // pointer
51 #define TypeTag_subrange 0x04 // (subrange_type?)
52 #define TypeTag_arraytype 0x08 // array type
53 #define TypeTag_consttype 0x10 // const type
54 #define TypeTag_typedef 0x20 // typedef
55 #define TypeTag_enumeration_type 0x40 // enumeration
56 #define TypeTag_subroutine_type 0x80 // subroutine
57 #define TypeTag_union 0x100 // union
60 // Source line CU structure
61 typedef struct CUStruct_LineSrc
68 // Source line internal structure
69 typedef struct DMIStruct_LineSrc
77 // Enumeration structure
78 typedef struct EnumerationStruct
80 char *PtrName
; // Enumeration's name
81 size_t value
; // Enumeration's value
84 // Structure members structure
85 typedef struct StructureMembersStruct
87 char *PtrName
; // Structure member's name
88 size_t TypeOffset
; // Structure member's offset on another type
89 size_t DataMemberLocation
; // Structure member's data member
90 }S_StructureMembersStruct
;
92 // Base type internal structure
93 typedef struct BaseTypeStruct
95 size_t Tag
; // Type's Tag
96 size_t Offset
; // Type's offset
97 size_t TypeOffset
; // Type's offset on another type
98 size_t ByteSize
; // Type's Byte Size
99 size_t Encoding
; // Type's encoding
100 char *PtrName
; // Type's name
101 size_t NbEnumerations
; // Type's enumeration numbers
102 EnumerationStruct
*PtrEnumerations
; // Type's enumeration
103 size_t NbStructureMembers
; // Type's numbers of structure members
104 StructureMembersStruct
*PtrStructureMembers
; // Type's structure members
107 // Variables internal structure
108 typedef struct VariablesStruct
110 size_t Op
; // Variable's DW_OP
113 size_t Addr
; // Variable memory address
114 int Offset
; // Variable stack offset (signed)
116 char *PtrName
; // Variable's name
117 size_t TypeOffset
; // Offset pointing on the Variable's Type
118 size_t TypeByteSize
; // Variable's Type byte size
119 size_t TypeTag
; // Variable's Type Tag
120 size_t TypeEncoding
; // Variable's Type encoding
121 char *PtrTypeName
; // Variable's Type name
122 size_t NbTabVariables
; // Number of Variable's members
123 VariablesStruct
**TabVariables
; // Variable's Members (used for structures at the moment)
126 // Sub program internal structure
127 typedef struct SubProgStruct
132 size_t LowPC
, HighPC
;
135 char *PtrSubprogramName
; // Sub program name
136 size_t NbLinesSrc
; // Number of lines source used by the sub program
137 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
138 size_t NbVariables
; // Variables number
139 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
142 // Compilation Unit internal structure
143 typedef struct CUStruct
146 size_t Language
; // Language (C, etc.) used by the source code
147 size_t LowPC
, HighPC
; // Memory range for the code
148 char *PtrProducer
; // "Producer" text information (mostly compiler and compilation options used)
149 char *PtrSourceFilename
; // Source file name
150 char *PtrSourceFileDirectory
; // Directory of the source file
151 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
152 size_t SizeLoadSrc
; // Source code text size
153 char *PtrLoadSrc
; // Pointer to the source code text
154 size_t NbLinesLoadSrc
; // Total number of lines in the source code text
155 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
156 size_t NbSubProgs
; // Number of sub programs / routines
157 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines structure
158 size_t NbTypes
; // Number of types
159 BaseTypeStruct
*PtrTypes
; // Pointer to types
160 size_t NbVariables
; // Variables number
161 VariablesStruct
*PtrVariables
; // Pointer to the global variables list structure
162 size_t NbFrames
; // Frames number
163 size_t NbUsedLinesSrc
; // Number of used source lines
164 size_t LastNumUsedLinesSrc
; // Last number line used
165 CUStruct_LineSrc
*PtrUsedLinesSrc
; // Pointer to the used source lines list structure
166 char **PtrUsedLinesLoadSrc
; // Pointer lists to each used source line referenced by the CUStruct_LineSrc structure
167 size_t *PtrUsedNumLines
; // List of the number lines used
168 struct stat _statbuf
; // File information
169 DWARFstatus Status
; // File status
180 char **ListSearchPaths
;
181 size_t NbSearchPaths
;
182 struct stat FileElfExeInfo
;
185 // Function declarations
186 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
187 void DWARFManager_InitDMI(void);
188 void DWARFManager_CloseDMI(void);
189 bool DWARFManager_ElfClose(void);
190 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
191 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
192 void DWARFManager_SourceFileSearchPathsInit(void);
193 void DWARFManager_SourceFileSearchPathsReset(void);
194 void DWARFManager_SourceFileSearchPathsClose(void);
195 void DWARFManager_ConformSlachesBackslashes(char *Ptr
);
197 size_t DWARFManager_GetNbGlobalVariables(void);
198 size_t DWARFManager_GetNbLocalVariables(size_t Adr
);
203 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr
/* perrarg */)
209 // Dwarf manager list search paths init
210 void DWARFManager_SourceFileSearchPathsInit(void)
212 ListSearchPaths
= NULL
;
217 // Dwarf manager list search paths reset
218 void DWARFManager_SourceFileSearchPathsReset(void)
220 ListSearchPaths
= NULL
;
225 // Dwarf manager list search paths close
226 void DWARFManager_SourceFileSearchPathsClose(void)
228 DWARFManager_SourceFileSearchPathsReset();
232 // Dwarf manager init
233 void DWARFManager_Init(void)
235 DWARFManager_SourceFileSearchPathsInit();
236 LibDwarf
= DW_DLV_NO_ENTRY
;
240 // Dwarf manager settings
241 void DWARFManager_Set(size_t NbPathsInList
, char **PtrListPaths
)
244 ListSearchPaths
= PtrListPaths
;
245 NbSearchPaths
= NbPathsInList
;
249 // Dwarf manager Reset
250 bool DWARFManager_Reset(void)
252 DWARFManager_SourceFileSearchPathsReset();
253 return DWARFManager_ElfClose();
257 // Dwarf manager Close
258 bool DWARFManager_Close(void)
260 DWARFManager_SourceFileSearchPathsClose();
261 return(DWARFManager_Reset());
265 // Dwarf manager Elf init
266 int DWARFManager_ElfInit(Elf
*ElfPtr
, struct stat FileElfInfo
)
268 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
270 FileElfExeInfo
= FileElfInfo
;
271 DWARFManager_InitDMI();
278 // Dwarf manager Elf close
279 bool DWARFManager_ElfClose(void)
281 if (LibDwarf
== DW_DLV_OK
)
283 DWARFManager_CloseDMI();
285 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
287 LibDwarf
= DW_DLV_NO_ENTRY
;
302 // Dwarf manager Compilation Units close
303 void DWARFManager_CloseDMI(void)
309 free(PtrCU
[NbCU
].PtrFullFilename
);
310 free(PtrCU
[NbCU
].PtrLoadSrc
);
311 free(PtrCU
[NbCU
].PtrProducer
);
312 free(PtrCU
[NbCU
].PtrSourceFilename
);
313 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
314 free(PtrCU
[NbCU
].PtrUsedLinesSrc
);
315 free(PtrCU
[NbCU
].PtrUsedLinesLoadSrc
);
316 free(PtrCU
[NbCU
].PtrUsedNumLines
);
318 // free lines from the source code
319 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
321 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
323 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
325 // free the functions information
326 while (PtrCU
[NbCU
].NbSubProgs
--)
328 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
330 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
331 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
333 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
335 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
336 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
338 free(PtrCU
[NbCU
].PtrSubProgs
);
341 while (PtrCU
[NbCU
].NbTypes
--)
343 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
345 // free the structure's members
346 while (PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
--)
348 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
[PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
].PtrName
);
350 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
);
352 free(PtrCU
[NbCU
].PtrTypes
);
355 while (PtrCU
[NbCU
].NbVariables
--)
357 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
358 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
360 // free the variable's members
361 while (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].NbTabVariables
--)
363 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TabVariables
[PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].NbTabVariables
]);
366 free(PtrCU
[NbCU
].PtrVariables
);
374 // Dwarf manager Compilation Units initialisations
375 void DWARFManager_InitDMI(void)
377 Dwarf_Unsigned next_cu_header
, return_uvalue
;
379 Dwarf_Attribute
*atlist
;
380 Dwarf_Attribute return_attr1
;
381 Dwarf_Half return_tagval
, return_attr
;
382 Dwarf_Half version
, offset_size
;
383 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
384 Dwarf_Block
*return_block
;
385 Dwarf_Signed atcnt
, cnt
, return_value
;
386 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
387 Dwarf_Off return_offset
;
394 // Initialisation for the Compilation Units table
398 // loop on the available Compilation Unit
399 while (dwarf_next_cu_header_b(dbg
, NULL
, &version
, NULL
, NULL
, &offset_size
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
401 // Allocation of an additional Compilation Unit structure in the table
402 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
404 // Compilation Unit RAZ
405 PtrCU
= (CUStruct
*)Ptr
;
406 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
410 if (NbCU
== DEBUG_NumCU
)
413 // Get 1st Die from the Compilation Unit
414 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
417 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
419 PtrCU
[NbCU
].Tag
= return_tagval
;
421 // Die type detection
422 switch (return_tagval
)
424 case DW_TAG_compile_unit
:
425 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
427 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
429 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
435 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
437 PtrCU
[NbCU
].LowPC
= return_lowpc
;
443 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
445 PtrCU
[NbCU
].HighPC
= return_highpc
;
449 // compilation information
451 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
453 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
454 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
455 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
461 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
463 #ifdef DEBUG_Filename
464 if (strstr(return_string
, DEBUG_Filename
))
467 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
468 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
470 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
476 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
478 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
479 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
480 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
486 if (dwarf_formudata(atlist
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
488 PtrCU
[NbCU
].Language
= return_uvalue
;
496 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
498 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
501 // Check filename presence
502 if (!PtrCU
[NbCU
].PtrSourceFilename
)
504 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
507 // Check directory presence
508 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
510 // Check if file exists in the search paths
511 for (size_t i
= 0; i
< NbSearchPaths
; i
++)
513 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen((const char *)ListSearchPaths
[i
]) + 2);
515 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
516 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
518 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
519 SrcFile
= fopen(PtrCU
[NbCU
].PtrFullFilename
, "rb");
523 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, strlen(ListSearchPaths
[i
]) + 1);
524 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ListSearchPaths
[i
]);
528 // File directory doesn't exits
529 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
531 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, 2);
532 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ".");
536 // Conform slashes / backslashes for the filename
537 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrSourceFilename
);
539 // Check if filename contains already the complete directory
540 if (PtrCU
[NbCU
].PtrSourceFilename
[1] == ':')
542 // Copy the filename as the full filename
543 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + 1);
544 strcpy(PtrCU
[NbCU
].PtrFullFilename
, PtrCU
[NbCU
].PtrSourceFilename
);
548 // Create full filename and Conform slashes / backslashes
549 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
551 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
553 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
557 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrFullFilename
);
559 // Directory path clean-up
561 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
563 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
567 while (*--Ptr1
!= '\\');
569 while (*--Ptr1
!= '/');
571 strcpy((Ptr1
+ 1), (Ptr
+ 4));
574 // Get the source file information
575 if (!stat(PtrCU
[NbCU
].PtrFullFilename
, &PtrCU
[NbCU
]._statbuf
))
577 // check the time stamp with the executable
578 if (PtrCU
[NbCU
]._statbuf
.st_mtime
<= FileElfExeInfo
.st_mtime
)
580 // Open the source file as a binary file
582 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
584 SrcFile
= fopen(PtrCU
[NbCU
].PtrFullFilename
, "rb");
588 if (!fseek(SrcFile
, 0, SEEK_END
))
590 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
592 if (!fseek(SrcFile
, 0, SEEK_SET
))
594 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
597 #if defined(_WIN32) && defined(_MSC_VER)
598 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
600 if (fread(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
603 free(PtrCU
[NbCU
].PtrLoadSrc
);
604 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
605 PtrCU
[NbCU
].SizeLoadSrc
= 0;
609 // Eliminate all carriage return code '\r' (oxd)
612 if ((*Ptr
= *Ptr1
) != '\r')
618 // Get back the new text file size
619 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
621 // Make sure the text file finish with a new line code '\n' (0xa)
622 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
624 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
625 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
628 // Reallocate text file
629 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
631 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
636 PtrCU
[NbCU
].NbLinesLoadSrc
++;
651 // Source file doesn't exist
652 PtrCU
[NbCU
].Status
= DWARFSTATUS_NOFILE
;
657 // Source file is outdated
658 PtrCU
[NbCU
].Status
= DWARFSTATUS_OUTDATEDFILE
;
663 // Source file doesn't have information
664 PtrCU
[NbCU
].Status
= DWARFSTATUS_NOFILEINFO
;
673 // Get the source lines table located in the CU
674 if ((dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
) && (PtrCU
[NbCU
].Status
== DWARFSTATUS_OK
))
678 PtrCU
[NbCU
].NbUsedLinesSrc
= cnt
;
679 PtrCU
[NbCU
].PtrUsedLinesSrc
= (CUStruct_LineSrc
*)calloc(cnt
, sizeof(CUStruct_LineSrc
));
680 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
= (char **)calloc(cnt
, sizeof(char *));
681 PtrCU
[NbCU
].PtrUsedNumLines
= (size_t *)calloc(cnt
, sizeof(size_t));
683 // Get the addresses and their source line numbers
684 for (Dwarf_Signed i
= 0; i
< cnt
; i
++)
686 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
688 // Get the source line number
689 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
691 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
= return_lineaddr
;
692 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
= return_uvalue
;
698 // Release the memory used by the source lines table located in the CU
699 dwarf_srclines_dealloc(dbg
, linebuf
, cnt
);
702 // Check if the CU has child
703 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
707 return_sib
= return_die
;
708 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
710 switch (return_tagval
)
712 case DW_TAG_lexical_block
:
715 case DW_TAG_variable
:
716 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
718 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
719 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
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
)
730 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
732 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
734 switch (return_block
->bl_len
)
737 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));
743 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
748 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
750 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
756 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
758 #ifdef DEBUG_VariableName
759 if (!strcmp(return_string
, DEBUG_VariableName
))
762 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
763 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
765 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
775 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
778 // Check variable's name validity
779 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
781 // Check variable's memory address validity
782 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
785 PtrCU
[NbCU
].NbVariables
++;
790 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
791 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
795 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
799 case DW_TAG_base_type
:
801 case DW_TAG_union_type
:
802 case DW_TAG_structure_type
:
803 case DW_TAG_pointer_type
:
804 case DW_TAG_const_type
:
805 case DW_TAG_array_type
:
806 case DW_TAG_subrange_type
:
807 case DW_TAG_subroutine_type
:
808 case DW_TAG_enumeration_type
:
809 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
811 // Allocate memory for this type
812 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
813 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
814 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
816 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
818 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
821 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
823 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
825 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
833 // Type's type offset
835 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
837 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
842 case DW_AT_byte_size
:
843 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
845 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
851 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
853 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
859 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
861 #ifdef DEBUG_TypeName
862 if (!strcmp(return_string
, DEBUG_TypeName
))
865 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
866 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
868 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
872 // Type's file number
873 case DW_AT_decl_file
:
876 // Type's line number
877 case DW_AT_decl_line
:
886 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
889 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
891 switch (return_tagval
)
893 case DW_TAG_structure_type
:
894 case DW_TAG_union_type
:
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
)
905 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
907 // Allocate memory for this member
908 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
= (StructureMembersStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
, ((PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
+ 1) * sizeof(StructureMembersStruct
)));
909 memset(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
+ PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
, 0, sizeof(StructureMembersStruct
));
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
)
919 case DW_AT_data_member_location
:
920 if (dwarf_whatform(return_attr1
, &form
, &error
) == DW_DLV_OK
)
922 if ((form
== DW_FORM_data1
) || (form
== DW_FORM_data2
) || (form
== DW_FORM_data2
) || (form
== DW_FORM_data4
) || (form
== DW_FORM_data8
) || (form
== DW_FORM_udata
))
924 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
926 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
[PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
].DataMemberLocation
= return_uvalue
;
931 if (form
== DW_FORM_sdata
)
933 if (dwarf_formsdata(return_attr1
, &return_value
, &error
) == DW_DLV_OK
)
935 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
[PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
].DataMemberLocation
= return_value
;
940 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
942 switch (return_block
->bl_len
)
947 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
[PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
].DataMemberLocation
= ReadULEB128((char *)return_block
->bl_data
+ 1);
954 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
962 //dwarf_whatform(return_attr1, &form, &error);
963 if (dwarf_global_formref(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
965 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
[PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
].TypeOffset
= return_uvalue
;
970 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
972 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
[PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
973 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrStructureMembers
[PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
].PtrName
, return_string
);
975 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
979 // Member's file number
980 case DW_AT_decl_file
:
983 // Member's line number
984 case DW_AT_decl_line
:
993 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
995 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].NbStructureMembers
++;
1000 } while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
1005 PtrCU
[NbCU
].NbTypes
++;
1009 case DW_TAG_subprogram
:
1010 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
1012 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
1013 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
1014 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
1016 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
1018 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
1020 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
1022 switch (return_attr
)
1026 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
1028 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
1029 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
1035 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
1037 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
1042 case DW_AT_decl_line
:
1043 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
1045 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
1050 case DW_AT_frame_base
:
1051 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
1053 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
1054 PtrCU
[NbCU
].NbFrames
++;
1060 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
1062 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
1063 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
1064 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
1071 case DW_AT_GNU_all_tail_call_sites
:
1077 case DW_AT_prototyped
:
1081 case DW_AT_decl_file
:
1084 case DW_AT_external
:
1092 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
1094 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
1096 // Get source line number and associated block of address
1097 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
1099 // Check the presence of the line in the memory frame
1100 if (PtrCU
[NbCU
].PtrUsedLinesSrc
&& (PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
>= return_lowpc
) && (PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
<= return_highpc
))
1102 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
));
1103 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
1104 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
;
1105 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
;
1106 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
1110 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
1114 return_sub
= return_subdie
;
1115 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
1117 switch (return_tagval
)
1119 case DW_TAG_formal_parameter
:
1120 case DW_TAG_variable
:
1121 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
1123 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
)));
1124 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
1126 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
1128 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
1130 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
1132 switch (return_attr
)
1134 case DW_AT_location
:
1135 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
1137 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
1139 switch (return_block
->bl_len
)
1146 switch (return_tagval
)
1148 case DW_TAG_variable
:
1149 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
1152 case DW_TAG_formal_parameter
:
1153 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
1164 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
1169 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
1171 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
1176 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
1178 #ifdef DEBUG_VariableName
1179 if (!strcmp(return_string
, DEBUG_VariableName
))
1182 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
1183 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
1185 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
1189 case DW_AT_decl_file
:
1192 case DW_AT_decl_line
:
1201 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
1204 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
1206 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
1218 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
1221 PtrCU
[NbCU
].NbSubProgs
++;
1230 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
1234 // Set the source code lines
1235 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
1237 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
1239 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
1241 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
1243 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
1245 #ifndef CONVERT_QT_HML
1246 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], Ptr
);
1255 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
1260 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
1265 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
1270 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
1271 i
+= strlen("&");
1276 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
1277 i
+= strlen(""");
1281 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
1288 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
1292 // Init lines source information for each source code line numbers and for each subprogs
1293 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
1295 // Check if the subprog / function's line exists in the source code
1296 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1298 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1301 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1303 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1305 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1313 // Set each source lines pointer to NULL
1314 if (PtrCU
[NbCU
].NbSubProgs
)
1316 // Check the presence of source lines dedicated to the sub progs
1317 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1319 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1320 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1322 for (size_t j
= 0; j
< i
; j
++)
1324 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1331 // Check validity between used number lines and number lines in the source file
1332 if (PtrCU
[NbCU
].LastNumUsedLinesSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1334 // Set information based on used line numbers
1335 if (PtrCU
[NbCU
].PtrUsedLinesSrc
)
1337 // Set the line source pointers for each used line numbers
1338 if (PtrCU
[NbCU
].PtrLinesLoadSrc
)
1340 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbUsedLinesSrc
; i
++)
1342 PtrCU
[NbCU
].PtrUsedNumLines
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1;
1343 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1];
1346 // Setup memory range for the code if CU doesn't have already this information
1347 // It is taken from the used lines structure
1348 if (!PtrCU
[NbCU
].LowPC
&& (!PtrCU
[NbCU
].HighPC
|| (PtrCU
[NbCU
].HighPC
== ~0)))
1350 PtrCU
[NbCU
].LowPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[0].StartPC
;
1351 PtrCU
[NbCU
].HighPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[PtrCU
[NbCU
].NbUsedLinesSrc
- 1].StartPC
;
1357 // Init global variables information based on types information
1358 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1360 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1363 // Init local variables information based on types information
1364 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1366 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1368 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1379 // Conform slashes and backslashes
1380 void DWARFManager_ConformSlachesBackslashes(char *Ptr
)
1400 // Variables information initialisation
1401 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1403 #ifdef DEBUG_VariableName
1404 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1407 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1408 size_t TypeOffset
= PtrVariables
->TypeOffset
;
1410 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1412 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1414 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1416 // subroutine / function pointer
1417 case DW_TAG_subroutine_type
:
1418 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1419 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1422 // structure & union type tag
1423 case DW_TAG_structure_type
:
1424 case DW_TAG_union_type
:
1425 PtrVariables
->TypeTag
|= (PtrCU
[NbCU
].PtrTypes
[j
].Tag
== DW_TAG_structure_type
) ? TypeTag_structure
: TypeTag_union
;
1426 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1428 if (PtrCU
[NbCU
].PtrTypes
[j
].PtrName
)
1430 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1433 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1439 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1441 strcat(PtrVariables
->PtrTypeName
, "* ");
1444 if (PtrVariables
->Op
)
1446 // fill the structure members
1447 PtrVariables
->TabVariables
= (VariablesStruct
**)calloc(PtrCU
[NbCU
].PtrTypes
[j
].NbStructureMembers
, sizeof(VariablesStruct
*));
1448 for (size_t i
= 0; i
< PtrCU
[NbCU
].PtrTypes
[j
].NbStructureMembers
; i
++)
1450 //if (PtrVariables->PtrName != PtrCU[NbCU].PtrTypes[j].PtrStructureMembers[i].PtrName)
1452 PtrVariables
->TabVariables
[PtrVariables
->NbTabVariables
] = (VariablesStruct
*)calloc(1, sizeof(VariablesStruct
));
1453 PtrVariables
->TabVariables
[PtrVariables
->NbTabVariables
]->PtrName
= PtrCU
[NbCU
].PtrTypes
[j
].PtrStructureMembers
[i
].PtrName
;
1454 PtrVariables
->TabVariables
[PtrVariables
->NbTabVariables
]->TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].PtrStructureMembers
[i
].TypeOffset
;
1455 PtrVariables
->TabVariables
[PtrVariables
->NbTabVariables
]->Offset
= (int)PtrCU
[NbCU
].PtrTypes
[j
].PtrStructureMembers
[i
].DataMemberLocation
;
1456 DWARFManager_InitInfosVariable(PtrVariables
->TabVariables
[PtrVariables
->NbTabVariables
++]);
1464 case DW_TAG_pointer_type
:
1465 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1466 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1467 PtrVariables
->TypeEncoding
= 0x10;
1468 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1470 strcat(PtrVariables
->PtrTypeName
, "void* ");
1478 case DW_TAG_enumeration_type
:
1479 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1480 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1481 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1483 // Try to determine the possible size
1484 switch (PtrVariables
->TypeByteSize
)
1487 PtrVariables
->TypeEncoding
= 0x7;
1497 case DW_TAG_typedef
:
1498 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1500 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1501 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1503 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1510 case DW_TAG_subrange_type
:
1511 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1515 case DW_TAG_array_type
:
1516 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1517 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1524 case DW_TAG_const_type
:
1525 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1526 strcat(PtrVariables
->PtrTypeName
, "const ");
1527 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1534 case DW_TAG_base_type
:
1535 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1537 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1539 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1541 strcat(PtrVariables
->PtrTypeName
, "* ");
1545 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1546 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1548 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1550 strcat(PtrVariables
->PtrTypeName
, "[]");
1563 // Get symbol name based from address
1564 // Return NULL if no symbol name exists
1565 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1567 for (size_t i
= 0; i
< NbCU
; i
++)
1569 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1571 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1573 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1575 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1585 // Get complete source filename based from address
1586 // Return NULL if no source filename exists
1587 // Return the existence status in Status if pointer not NULL
1588 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, DWARFstatus
*Status
)
1590 for (size_t i
= 0; i
< NbCU
; i
++)
1592 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1596 *Status
= PtrCU
[i
].Status
;
1599 return PtrCU
[i
].PtrFullFilename
;
1607 // Get text line source based on line number (starting from 1)
1608 // Return NULL if no text line exists or if line number is 0
1609 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1612 char *PtrLineSrc
= NULL
;
1616 while (i
!= NumLine
)
1618 PtrLineSrc
= PtrSrcFile
;
1619 while (*PtrSrcFile
++);
1628 // Get number of variables
1629 // A NULL address will return the numbre of global variables, otherwise it will return the number of local variables
1630 size_t DWARFManager_GetNbVariables(size_t Adr
)
1632 // check the address
1635 for (size_t i
= 0; i
< NbCU
; i
++)
1637 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1639 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1641 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1643 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1651 size_t NbVariables
= 0;
1653 for (size_t i
= 0; i
< NbCU
; i
++)
1655 NbVariables
+= PtrCU
[i
].NbVariables
;
1663 return Adr
? DWARFManager_GetNbLocalVariables(Adr
) : DWARFManager_GetNbGlobalVariables();
1668 // Get variable's information
1669 // A NULL address will return the pointer to the global variable structure, otherwise it will return the local's one
1670 void* DWARFManager_GetInfosVariable(size_t Adr
, size_t Index
)
1672 // check the address
1675 // get the pointer's information from a local variable
1676 for (size_t i
= 0; i
< NbCU
; i
++)
1678 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1680 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1682 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1684 return &PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1];
1692 // get the pointer's information from a global variable
1693 for (size_t i
= 0; i
< NbCU
; i
++)
1695 if (PtrCU
[i
].NbVariables
)
1697 if (Index
<= PtrCU
[i
].NbVariables
)
1699 return &PtrCU
[i
].PtrVariables
[Index
- 1];
1703 Index
-= PtrCU
[i
].NbVariables
;
1713 // Get global variable memory address based on his name
1714 // Return 0 if not found, or will return the first occurence found
1715 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1717 for (size_t i
= 0; i
< NbCU
; i
++)
1719 if (PtrCU
[i
].NbVariables
)
1721 for (size_t j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1723 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
, VariableName
))
1725 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1736 // Get number of variables referenced by the function range address
1737 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1739 for (size_t i
= 0; i
< NbCU
; i
++)
1741 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1743 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1745 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1747 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1757 // Get Compilation Unit / global variables numbers
1758 // Return number of variables
1759 size_t DWARFManager_GetNbGlobalVariables(void)
1761 size_t NbVariables
= 0;
1763 for (size_t i
= 0; i
< NbCU
; i
++)
1765 NbVariables
+= PtrCU
[i
].NbVariables
;
1772 // Get local variable name based on his index (starting from 1)
1773 // Return name's pointer text found
1774 // Return NULL if not found
1775 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1777 for (size_t i
= 0; i
< NbCU
; i
++)
1779 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1781 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1783 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1785 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1795 // Get local variable's type tag based on his index (starting from 1)
1796 // Return 0 if not found
1797 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1799 for (size_t i
= 0; i
< NbCU
; i
++)
1801 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1803 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1805 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1807 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1817 // Get the local variable's offset based on a index (starting from 1)
1818 // Return 0 if no offset has been found
1819 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1821 for (size_t i
= 0; i
< NbCU
; i
++)
1823 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1825 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1827 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1829 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1839 // Get local variable Type Byte Size based on his address and index (starting from 1)
1840 // Return 0 if not found
1841 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1842 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1844 for (size_t i
= 0; i
< NbCU
; i
++)
1846 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1848 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1850 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1852 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1862 // Get local variable Type Encoding based on his address and index (starting from 1)
1863 // Return 0 if not found
1864 // May return 0 if there is no Type Encoding linked to the variable's address and index
1865 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1867 for (size_t i
= 0; i
< NbCU
; i
++)
1869 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1871 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1873 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1875 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1885 // Get local variable Op based on his address and index (starting from 1)
1886 // Return 0 if not found, may return 0 if there isn't Op linked to the variable's index
1887 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1889 for (size_t i
= 0; i
< NbCU
; i
++)
1891 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1893 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1895 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1897 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1907 // Get local variable type name based on his index (starting from 1) and an address
1908 // Return NULL if not found, may also return NULL if there is no type linked to the variable's index
1909 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1911 for (size_t i
= 0; i
< NbCU
; i
++)
1913 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1915 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1917 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1919 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1929 // Get global variable type name based on his index (starting from 1)
1930 // Return NULL if not found
1931 // May return NULL if there is not type linked to the variable's index
1932 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1934 for (size_t i
= 0; i
< NbCU
; i
++)
1936 if (PtrCU
[i
].NbVariables
)
1938 if (Index
<= PtrCU
[i
].NbVariables
)
1940 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1944 Index
-= PtrCU
[i
].NbVariables
;
1953 // Get global variable's type tag based on his index (starting from 1)
1954 // Return 0 if not found
1955 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1957 for (size_t i
= 0; i
< NbCU
; i
++)
1959 if (PtrCU
[i
].NbVariables
)
1961 if (Index
<= PtrCU
[i
].NbVariables
)
1963 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1967 Index
-= PtrCU
[i
].NbVariables
;
1976 // Get global variable byte size based on his index (starting from 1)
1977 // Return 0 if not found
1978 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1980 for (size_t i
= 0; i
< NbCU
; i
++)
1982 if (PtrCU
[i
].NbVariables
)
1984 if (Index
<= PtrCU
[i
].NbVariables
)
1986 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1990 Index
-= PtrCU
[i
].NbVariables
;
1999 // Get global variable encoding based on his index (starting from 1)
2000 // Return 0 if not found
2001 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
2003 for (size_t i
= 0; i
< NbCU
; i
++)
2005 if (PtrCU
[i
].NbVariables
)
2007 if (Index
<= PtrCU
[i
].NbVariables
)
2009 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
2013 Index
-= PtrCU
[i
].NbVariables
;
2022 // Get global variable memory address based on his index (starting from 1)
2023 // Return 0 if not found
2024 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
2026 for (size_t i
= 0; i
< NbCU
; i
++)
2028 if (PtrCU
[i
].NbVariables
)
2030 if (Index
<= PtrCU
[i
].NbVariables
)
2032 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
2036 Index
-= PtrCU
[i
].NbVariables
;
2045 // Get global variable name based on his index (starting from 1)
2046 // Return name's pointer text found, or will return NULL if no variable can be found
2047 char *DWARFManager_GetGlobalVariableName(size_t Index
)
2049 for (size_t i
= 0; i
< NbCU
; i
++)
2051 if (PtrCU
[i
].NbVariables
)
2053 if (Index
<= PtrCU
[i
].NbVariables
)
2055 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
2059 Index
-= PtrCU
[i
].NbVariables
;
2069 // Get text line from source based on address and his tag
2070 // A tag can be either 0 or a DW_TAG_subprogram
2071 // DW_TAG_subprogram will look for the line pointing to the function
2072 // Return NULL if no text line has been found
2073 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
2075 for (size_t i
= 0; i
< NbCU
; i
++)
2077 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
2079 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
2081 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
2083 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
2085 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
2089 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
2091 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
2093 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
2095 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
2100 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
2113 // Get line number based on the address and a tag
2114 // A tag can be either 0 or a DW_TAG_subprogram
2115 // DW_TAG_subprogram will look for the line pointing to the function name as described in the source code
2116 // Return 0 if no line number has been found
2117 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
2119 for (size_t i
= 0; i
< NbCU
; i
++)
2121 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
2123 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
2125 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
2127 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
2129 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
2133 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
2135 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
2137 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
2139 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
2144 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].NumLineSrc
;
2149 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
2151 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
2157 // Check if a used line is found with the address
2158 for (size_t j
= 0; j
< PtrCU
[i
].NbUsedLinesSrc
; j
++)
2160 if (PtrCU
[i
].PtrUsedLinesSrc
[j
].StartPC
== Adr
)
2162 return PtrCU
[i
].PtrUsedLinesSrc
[j
].NumLineSrc
;
2172 // Get function name based on an address
2173 // Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address
2174 char *DWARFManager_GetFunctionName(size_t Adr
)
2176 for (size_t i
= 0; i
< NbCU
; i
++)
2178 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
2180 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
2182 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
2184 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
2194 // Get number of lines of texts source list from source index
2195 size_t DWARFManager_GetSrcNbListPtrFromIndex(size_t Index
, bool Used
)
2199 return PtrCU
[Index
].NbLinesLoadSrc
;
2203 return PtrCU
[Index
].NbUsedLinesSrc
;
2208 // Get text source line number list pointer from source index
2209 // Return NULL for the text source used list
2210 size_t *DWARFManager_GetSrcNumLinesPtrFromIndex(size_t Index
, bool Used
)
2214 return PtrCU
[Index
].PtrUsedNumLines
;
2223 // Get text source list pointers from source index
2224 // Return NULL for the text source used list
2225 char **DWARFManager_GetSrcListPtrFromIndex(size_t Index
, bool Used
)
2229 return PtrCU
[Index
].PtrLinesLoadSrc
;
2233 return PtrCU
[Index
].PtrUsedLinesLoadSrc
;
2238 // Get source language
2239 size_t DWARFManager_GetSrcLanguageFromIndex(size_t Index
)
2241 return PtrCU
[Index
].Language
;
2245 // Get text line from source based on address and num line (starting from 1)
2246 // Return NULL if no text line has been found
2247 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
2249 for (size_t i
= 0; i
< NbCU
; i
++)
2251 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
2253 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
2255 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
2257 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
2259 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
2263 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
2265 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
2267 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
2280 // Get text line pointer from source, based on address and line number (starting from 1)
2281 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
2282 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
2284 for (size_t i
= 0; i
< NbCU
; i
++)
2286 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
2288 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
2290 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
2303 // Get number of source code filenames
2304 size_t DWARFManager_GetNbSources(void)
2310 // Get source code filename, including his directory, based on index (starting from 0)
2311 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
2313 return (PtrCU
[Index
].PtrFullFilename
);
2317 // Get source code filename based on index (starting from 0)
2318 char *DWARFManager_GetNumSourceFilename(size_t Index
)
2320 return (PtrCU
[Index
].PtrSourceFilename
);