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
14 // JPM Mar./2020 Fix a random crash when reading the source lines information
15 // JPM Aug./2020 Added a source code file date check when reading DWARF information
19 // To use pointers instead of arrays usage
28 #include <sys/types.h>
33 #include "DWARFManager.h"
35 // Definitions for debugging
36 //#define DEBUG_NumCU 0x3 // CU number to debug or undefine it
37 //#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it
38 //#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it
39 //#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)
40 //#define DEBUG_Filename "crt0" // Filename to look for or undefine it
42 // Definitions for handling data
43 //#define CONVERT_QT_HML // Text will be converted as HTML
45 // Definitions for the variables's typetag
46 #define TypeTag_structure 0x01 // structure
47 #define TypeTag_pointer 0x02 // pointer
48 #define TypeTag_subrange 0x04 // (subrange_type?)
49 #define TypeTag_arraytype 0x08 // array type
50 #define TypeTag_consttype 0x10 // const type
51 #define TypeTag_typedef 0x20 // typedef
52 #define TypeTag_enumeration_type 0x40 // enumeration
53 #define TypeTag_subroutine_type 0x80 // subroutine
56 // Source line CU structure
57 typedef struct CUStruct_LineSrc
64 // Source line internal structure
65 typedef struct DMIStruct_LineSrc
73 // Enumeration structure
74 typedef struct EnumerationStruct
76 char *PtrName
; // Enumeration's name
77 size_t value
; // Enumeration's value
80 // Structure members structure
81 //typedef struct StructureMembersStruct
83 //}S_StructureMembersStruct;
85 // Base type internal structure
86 typedef struct BaseTypeStruct
88 size_t Tag
; // Type's Tag
89 size_t Offset
; // Type's offset
90 size_t TypeOffset
; // Type's offset on another type
91 size_t ByteSize
; // Type's Byte Size
92 size_t Encoding
; // Type's encoding
93 char *PtrName
; // Type's name
94 size_t NbEnumeration
; // Type's enumeration numbers
95 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
96 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
99 // Variables internal structure
100 typedef struct VariablesStruct
102 size_t Op
; // Variable's DW_OP
105 size_t Addr
; // Variable memory address
106 int Offset
; // Variable stack offset (signed)
108 char *PtrName
; // Variable's name
109 size_t TypeOffset
; // Offset pointing on the Variable's Type
110 size_t TypeByteSize
; // Variable's Type byte size
111 size_t TypeTag
; // Variable's Type Tag
112 size_t TypeEncoding
; // Variable's Type encoding
113 char *PtrTypeName
; // Variable's Type name
116 // Sub program internal structure
117 typedef struct SubProgStruct
122 size_t LowPC
, HighPC
;
125 char *PtrSubprogramName
; // Sub program name
126 size_t NbLinesSrc
; // Number of lines source used by the sub program
127 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
128 size_t NbVariables
; // Variables number
129 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
132 // Compilation Unit internal structure
133 typedef struct CUStruct
136 size_t Language
; // Language (C, etc.) used by the source code
137 size_t LowPC
, HighPC
; // Memory range for the code
138 char *PtrProducer
; // "Producer" text information (mostly compiler and compilation options used)
139 char *PtrSourceFilename
; // Source file name
140 char *PtrSourceFileDirectory
; // Directory of the source file
141 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
142 size_t SizeLoadSrc
; // Source code text size
143 char *PtrLoadSrc
; // Pointer to the source code text
144 size_t NbLinesLoadSrc
; // Total number of lines in the source code text
145 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
146 size_t NbSubProgs
; // Number of sub programs / routines
147 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines structure
148 size_t NbTypes
; // Number of types
149 BaseTypeStruct
*PtrTypes
; // Pointer to types
150 size_t NbVariables
; // Variables number
151 VariablesStruct
*PtrVariables
; // Pointer to the global variables list structure
152 size_t NbFrames
; // Frames number
153 size_t NbUsedLinesSrc
; // Number of used source lines
154 size_t LastNumUsedLinesSrc
; // Last number line used
155 CUStruct_LineSrc
*PtrUsedLinesSrc
; // Pointer to the used source lines list structure
156 char **PtrUsedLinesLoadSrc
; // Pointer lists to each used source line referenced by the CUStruct_LineSrc structure
157 size_t *PtrUsedNumLines
; // List of the number lines used
158 struct stat _statbuf
; // File information
159 DWARFstatus Status
; // File status
170 char **ListSearchPaths
;
171 size_t NbSearchPaths
;
172 struct stat FileElfExeInfo
;
176 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
177 void DWARFManager_InitDMI(void);
178 void DWARFManager_CloseDMI(void);
179 bool DWARFManager_ElfClose(void);
180 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
181 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
182 void DWARFManager_SourceFileSearchPathsInit(void);
183 void DWARFManager_SourceFileSearchPathsReset(void);
184 void DWARFManager_SourceFileSearchPathsClose(void);
185 void DWARFManager_ConformSlachesBackslashes(char *Ptr
);
189 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
195 // Dwarf manager list search paths init
196 void DWARFManager_SourceFileSearchPathsInit(void)
198 ListSearchPaths
= NULL
;
203 // Dwarf manager list search paths reset
204 void DWARFManager_SourceFileSearchPathsReset(void)
206 ListSearchPaths
= NULL
;
211 // Dwarf manager list search paths close
212 void DWARFManager_SourceFileSearchPathsClose(void)
214 DWARFManager_SourceFileSearchPathsReset();
218 // Dwarf manager init
219 void DWARFManager_Init(void)
221 DWARFManager_SourceFileSearchPathsInit();
222 LibDwarf
= DW_DLV_NO_ENTRY
;
226 // Dwarf manager settings
227 void DWARFManager_Set(size_t NbPathsInList
, char **PtrListPaths
)
230 ListSearchPaths
= PtrListPaths
;
231 NbSearchPaths
= NbPathsInList
;
235 // Dwarf manager Reset
236 bool DWARFManager_Reset(void)
238 DWARFManager_SourceFileSearchPathsReset();
239 return DWARFManager_ElfClose();
243 // Dwarf manager Close
244 bool DWARFManager_Close(void)
246 DWARFManager_SourceFileSearchPathsClose();
247 return(DWARFManager_Reset());
251 // Dwarf manager Elf init
252 int DWARFManager_ElfInit(Elf
*ElfPtr
, struct stat FileElfInfo
)
254 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
256 FileElfExeInfo
= FileElfInfo
;
257 DWARFManager_InitDMI();
264 // Dwarf manager Elf close
265 bool DWARFManager_ElfClose(void)
267 if (LibDwarf
== DW_DLV_OK
)
269 DWARFManager_CloseDMI();
271 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
273 LibDwarf
= DW_DLV_NO_ENTRY
;
288 // Dwarf manager Compilation Units close
289 void DWARFManager_CloseDMI(void)
293 free(PtrCU
[NbCU
].PtrFullFilename
);
294 free(PtrCU
[NbCU
].PtrLoadSrc
);
295 free(PtrCU
[NbCU
].PtrProducer
);
296 free(PtrCU
[NbCU
].PtrSourceFilename
);
297 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
298 free(PtrCU
[NbCU
].PtrUsedLinesSrc
);
299 free(PtrCU
[NbCU
].PtrUsedLinesLoadSrc
);
300 free(PtrCU
[NbCU
].PtrUsedNumLines
);
302 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
304 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
306 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
308 while (PtrCU
[NbCU
].NbSubProgs
--)
310 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
312 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
313 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
315 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
317 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
318 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
320 free(PtrCU
[NbCU
].PtrSubProgs
);
322 while (PtrCU
[NbCU
].NbTypes
--)
324 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
326 free(PtrCU
[NbCU
].PtrTypes
);
328 while (PtrCU
[NbCU
].NbVariables
--)
330 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
331 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
333 free(PtrCU
[NbCU
].PtrVariables
);
340 // Dwarf manager Compilation Units initialisations
341 void DWARFManager_InitDMI(void)
343 Dwarf_Unsigned next_cu_header
, return_uvalue
;
345 Dwarf_Attribute
*atlist
;
346 Dwarf_Attribute return_attr1
;
347 Dwarf_Half return_tagval
, return_attr
;
348 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
349 Dwarf_Block
*return_block
;
350 Dwarf_Signed atcnt
, cnt
;
351 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
352 Dwarf_Off return_offset
;
358 // Initialisation for the Compilation Units table
362 // loop on the available Compilation Unit
363 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
365 // Allocation of an additional Compilation Unit structure in the table
366 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
368 // Compilation Unit RAZ
369 PtrCU
= (CUStruct
*)Ptr
;
370 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
374 if (NbCU
== DEBUG_NumCU
)
377 // Get 1st Die from the Compilation Unit
378 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
381 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
383 PtrCU
[NbCU
].Tag
= return_tagval
;
385 // Die type detection
386 switch (return_tagval
)
388 case DW_TAG_compile_unit
:
389 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
391 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
393 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
399 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
401 PtrCU
[NbCU
].LowPC
= return_lowpc
;
407 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
409 PtrCU
[NbCU
].HighPC
= return_highpc
;
413 // compilation information
415 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
417 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
418 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
419 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
425 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
427 #ifdef DEBUG_Filename
428 if (strstr(return_string
, DEBUG_Filename
))
431 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
432 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
434 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
440 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
442 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
443 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
444 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
450 if (dwarf_formudata(atlist
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
452 PtrCU
[NbCU
].Language
= return_uvalue
;
460 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
462 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
465 // Check filename presence
466 if (!PtrCU
[NbCU
].PtrSourceFilename
)
468 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
471 // Check directory presence
472 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
474 // Check if file exists in the search paths
475 for (size_t i
= 0; i
< NbSearchPaths
; i
++)
477 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen((const char *)ListSearchPaths
[i
]) + 2);
479 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
480 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
482 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
483 SrcFile
= fopen(PtrCU
[NbCU
].PtrFullFilename
, "rb");
487 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, strlen(ListSearchPaths
[i
]) + 1);
488 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ListSearchPaths
[i
]);
492 // File directory doesn't exits
493 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
495 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, 2);
496 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ".");
500 // Conform slashes / backslashes for the filename
501 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrSourceFilename
);
503 // Check if filename contains already the complete directory
504 if (PtrCU
[NbCU
].PtrSourceFilename
[1] == ':')
506 // Copy the filename as the full filename
507 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + 1);
508 strcpy(PtrCU
[NbCU
].PtrFullFilename
, PtrCU
[NbCU
].PtrSourceFilename
);
512 // Create full filename and Conform slashes / backslashes
513 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
515 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
517 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
521 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrFullFilename
);
523 // Directory path clean-up
525 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
527 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
531 while (*--Ptr1
!= '\\');
533 while (*--Ptr1
!= '/');
535 strcpy((Ptr1
+ 1), (Ptr
+ 4));
538 // Get the source file information
539 if (!stat(PtrCU
[NbCU
].PtrFullFilename
, &PtrCU
[NbCU
]._statbuf
))
541 // check the time stamp with the executable
542 if (PtrCU
[NbCU
]._statbuf
.st_mtime
<= FileElfExeInfo
.st_mtime
)
544 // Open the source file as a binary file
546 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
548 SrcFile
= fopen(PtrCU
[NbCU
].PtrFullFilename
, "rb");
552 if (!fseek(SrcFile
, 0, SEEK_END
))
554 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
556 if (!fseek(SrcFile
, 0, SEEK_SET
))
558 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
562 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
564 if (fread(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
567 free(PtrCU
[NbCU
].PtrLoadSrc
);
568 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
569 PtrCU
[NbCU
].SizeLoadSrc
= 0;
573 // Eliminate all carriage return code '\r' (oxd)
576 if ((*Ptr
= *Ptr1
) != '\r')
582 // Get back the new text file size
583 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
585 // Make sure the text file finish with a new line code '\n' (0xa)
586 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
588 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
589 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
592 // Reallocate text file
593 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
595 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
600 PtrCU
[NbCU
].NbLinesLoadSrc
++;
615 // Source file doesn't exist
616 PtrCU
[NbCU
].Status
= DWARFSTATUS_NOFILE
;
621 // Source file is outdated
622 PtrCU
[NbCU
].Status
= DWARFSTATUS_OUTDATEDFILE
;
627 // Source file doesn't have information
628 PtrCU
[NbCU
].Status
= DWARFSTATUS_NOFILEINFO
;
637 // Get the source lines table located in the CU
638 if ((dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
) && (PtrCU
[NbCU
].Status
== DWARFSTATUS_OK
))
642 PtrCU
[NbCU
].NbUsedLinesSrc
= cnt
;
643 PtrCU
[NbCU
].PtrUsedLinesSrc
= (CUStruct_LineSrc
*)calloc(cnt
, sizeof(CUStruct_LineSrc
));
644 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
= (char **)calloc(cnt
, sizeof(char *));
645 PtrCU
[NbCU
].PtrUsedNumLines
= (size_t *)calloc(cnt
, sizeof(size_t));
647 // Get the addresses and their source line numbers
648 for (Dwarf_Signed i
= 0; i
< cnt
; i
++)
650 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
652 // Get the source line number
653 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
655 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
= return_lineaddr
;
656 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
= return_uvalue
;
662 // Release the memory used by the source lines table located in the CU
663 dwarf_srclines_dealloc(dbg
, linebuf
, cnt
);
666 // Check if the CU has child
667 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
671 return_sib
= return_die
;
672 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
674 switch (return_tagval
)
676 case DW_TAG_lexical_block
:
679 case DW_TAG_variable
:
680 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
682 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
683 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
685 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
687 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
689 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
694 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
696 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
698 switch (return_block
->bl_len
)
701 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));
707 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
712 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
714 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
720 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
722 #ifdef DEBUG_VariableName
723 if (!strcmp(return_string
, DEBUG_VariableName
))
726 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
727 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
729 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
739 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
742 // Check variable's name validity
743 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
745 // Check variable's memory address validity
746 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
749 PtrCU
[NbCU
].NbVariables
++;
754 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
755 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
759 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
763 case DW_TAG_base_type
:
765 case DW_TAG_structure_type
:
766 case DW_TAG_pointer_type
:
767 case DW_TAG_const_type
:
768 case DW_TAG_array_type
:
769 case DW_TAG_subrange_type
:
770 case DW_TAG_subroutine_type
:
771 case DW_TAG_enumeration_type
:
772 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
774 // Allocate memory for this type
775 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
776 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
777 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
779 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
781 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
784 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
786 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
788 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
796 // Type's type offset
798 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
800 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
805 case DW_AT_byte_size
:
806 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
808 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
814 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
816 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
822 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
824 #ifdef DEBUG_TypeName
825 if (!strcmp(return_string
, DEBUG_TypeName
))
828 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
829 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
831 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
835 // Type's file number
836 case DW_AT_decl_file
:
839 // Type's line number
840 case DW_AT_decl_line
:
849 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
852 PtrCU
[NbCU
].NbTypes
++;
854 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
858 case DW_TAG_subprogram
:
859 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
861 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
862 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
863 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
865 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
867 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
869 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
875 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
877 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
878 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
884 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
886 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
891 case DW_AT_decl_line
:
892 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
894 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
899 case DW_AT_frame_base
:
900 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
902 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
903 PtrCU
[NbCU
].NbFrames
++;
909 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
911 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
912 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
913 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
920 case DW_AT_GNU_all_tail_call_sites
:
926 case DW_AT_prototyped
:
930 case DW_AT_decl_file
:
941 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
943 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
945 // Get source line number and associated block of address
946 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
948 // Check the presence of the line in the memory frame
949 if (PtrCU
[NbCU
].PtrUsedLinesSrc
&& (PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
>= return_lowpc
) && (PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
<= return_highpc
))
951 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
));
952 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
953 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
;
954 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
;
955 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
959 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
963 return_sub
= return_subdie
;
964 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
966 switch (return_tagval
)
968 case DW_TAG_formal_parameter
:
969 case DW_TAG_variable
:
970 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
972 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
)));
973 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
975 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
977 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
979 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
984 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
986 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
988 switch (return_block
->bl_len
)
995 switch (return_tagval
)
997 case DW_TAG_variable
:
998 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
1001 case DW_TAG_formal_parameter
:
1002 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
1013 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
1018 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
1020 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
1025 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
1027 #ifdef DEBUG_VariableName
1028 if (!strcmp(return_string
, DEBUG_VariableName
))
1031 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
1032 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
1034 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
1038 case DW_AT_decl_file
:
1041 case DW_AT_decl_line
:
1050 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
1053 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
1055 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
1067 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
1070 PtrCU
[NbCU
].NbSubProgs
++;
1079 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
1083 // Set the source code lines
1084 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
1086 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
1088 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
1090 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
1092 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
1100 #ifdef CONVERT_QT_HML
1102 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
1107 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
1112 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
1117 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
1118 i
+= strlen("&");
1123 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
1124 i
+= strlen(""");
1129 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
1135 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
1139 // Init lines source information for each source code line numbers and for each subprogs
1140 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
1142 // Check if the subprog / function's line exists in the source code
1143 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1145 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1148 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1150 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1152 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1160 // Set each source lines pointer to NULL
1161 if (PtrCU
[NbCU
].NbSubProgs
)
1163 // Check the presence of source lines dedicated to the sub progs
1164 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1166 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1167 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1169 for (size_t j
= 0; j
< i
; j
++)
1171 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1178 // Check validity between used number lines and number lines in the source file
1179 if (PtrCU
[NbCU
].LastNumUsedLinesSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1181 // Set information based on used line numbers
1182 if (PtrCU
[NbCU
].PtrUsedLinesSrc
)
1184 // Set the line source pointers for each used line numbers
1185 if (PtrCU
[NbCU
].PtrLinesLoadSrc
)
1187 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbUsedLinesSrc
; i
++)
1189 PtrCU
[NbCU
].PtrUsedNumLines
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1;
1190 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1];
1193 // Setup memory range for the code if CU doesn't have already this information
1194 // It is taken from the used lines structure
1195 if (!PtrCU
[NbCU
].LowPC
&& (!PtrCU
[NbCU
].HighPC
|| (PtrCU
[NbCU
].HighPC
== ~0)))
1197 PtrCU
[NbCU
].LowPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[0].StartPC
;
1198 PtrCU
[NbCU
].HighPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[PtrCU
[NbCU
].NbUsedLinesSrc
- 1].StartPC
;
1204 // Init global variables information based on types information
1205 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1207 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1210 // Init local variables information based on types information
1211 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1213 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1215 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1226 // Conform slashes and backslashes
1227 void DWARFManager_ConformSlachesBackslashes(char *Ptr
)
1247 // Variables information initialisation
1248 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1250 size_t j
, TypeOffset
;
1252 #ifdef DEBUG_VariableName
1253 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1256 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1257 TypeOffset
= PtrVariables
->TypeOffset
;
1259 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1261 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1263 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1265 case DW_TAG_subroutine_type
:
1266 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1267 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1270 // Structure type tag
1271 case DW_TAG_structure_type
:
1272 PtrVariables
->TypeTag
|= TypeTag_structure
;
1273 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1275 if (PtrCU
[NbCU
].PtrTypes
[j
].PtrName
)
1277 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1280 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1286 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1288 strcat(PtrVariables
->PtrTypeName
, " *");
1294 case DW_TAG_pointer_type
:
1295 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1296 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1297 PtrVariables
->TypeEncoding
= 0x10;
1298 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1300 strcat(PtrVariables
->PtrTypeName
, "void *");
1308 case DW_TAG_enumeration_type
:
1309 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1310 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1311 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1313 // Try to determine the possible size
1314 switch (PtrVariables
->TypeByteSize
)
1317 PtrVariables
->TypeEncoding
= 0x7;
1327 case DW_TAG_typedef
:
1328 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1330 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1331 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1333 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1340 case DW_TAG_subrange_type
:
1341 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1345 case DW_TAG_array_type
:
1346 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1347 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1354 case DW_TAG_const_type
:
1355 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1356 strcat(PtrVariables
->PtrTypeName
, "const ");
1357 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1364 case DW_TAG_base_type
:
1365 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1367 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1369 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1371 strcat(PtrVariables
->PtrTypeName
, " *");
1375 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1376 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1378 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1380 strcat(PtrVariables
->PtrTypeName
, "[]");
1393 // Get symbol name based from address
1394 // Return NULL if no symbol name exists
1395 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1397 for (size_t i
= 0; i
< NbCU
; i
++)
1399 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1401 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1403 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1405 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1415 // Get complete source filename based from address
1416 // Return NULL if no source filename exists
1417 // Return the existence status in Status if pointer not NULL
1418 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, DWARFstatus
*Status
)
1420 for (size_t i
= 0; i
< NbCU
; i
++)
1422 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1426 *Status
= PtrCU
[i
].Status
;
1429 return PtrCU
[i
].PtrFullFilename
;
1437 // Get text line source based on line number (starting from 1)
1438 // Return NULL if no text line exists or if line number is 0
1439 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1442 char *PtrLineSrc
= NULL
;
1446 while (i
!= NumLine
)
1448 PtrLineSrc
= PtrSrcFile
;
1449 while (*PtrSrcFile
++);
1458 // Get number of variables referenced by the function range address
1459 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1461 for (size_t i
= 0; i
< NbCU
; i
++)
1463 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1465 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1467 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1469 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1479 // Get local variable name based on his index (starting from 1)
1480 // Return name's pointer text found
1481 // Return NULL if not found
1482 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1484 for (size_t i
= 0; i
< NbCU
; i
++)
1486 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1488 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1490 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1492 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1502 // Get local variable's type tag based on his index (starting from 1)
1503 // Return 0 if not found
1504 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1506 for (size_t i
= 0; i
< NbCU
; i
++)
1508 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1510 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1512 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1514 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1524 // Get the local variable's offset based on a index (starting from 1)
1525 // Return 0 if no offset has been found
1526 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1528 for (size_t i
= 0; i
< NbCU
; i
++)
1530 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1532 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1534 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1536 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1546 // Get local variable Type Byte Size based on his address and index (starting from 1)
1547 // Return 0 if not found
1548 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1549 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1551 for (size_t i
= 0; i
< NbCU
; i
++)
1553 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1555 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1557 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1559 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1569 // Get local variable Type Encoding based on his address and index (starting from 1)
1570 // Return 0 if not found
1571 // May return 0 if there is no Type Encoding linked to the variable's address and index
1572 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1574 for (size_t i
= 0; i
< NbCU
; i
++)
1576 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1578 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1580 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1582 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1592 // Get local variable Op based on his address and index (starting from 1)
1593 // Return 0 if not found, may return 0 if there isn't Op linked to the variable's index
1594 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1596 for (size_t i
= 0; i
< NbCU
; i
++)
1598 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1600 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1602 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1604 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1614 // Get local variable type name based on his index (starting from 1) and an address
1615 // Return NULL if not found, may also return NULL if there is no type linked to the variable's index
1616 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1618 for (size_t i
= 0; i
< NbCU
; i
++)
1620 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1622 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1624 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1626 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1636 // Get Compilation Unit / global variables numbers
1637 // Return number of variables
1638 size_t DWARFManager_GetNbGlobalVariables(void)
1640 size_t NbVariables
= 0;
1642 for (size_t i
= 0; i
< NbCU
; i
++)
1644 NbVariables
+= PtrCU
[i
].NbVariables
;
1651 // Get global variable type name based on his index (starting from 1)
1652 // Return NULL if not found
1653 // May return NULL if there is not type linked to the variable's index
1654 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1656 for (size_t i
= 0; i
< NbCU
; i
++)
1658 if (PtrCU
[i
].NbVariables
)
1660 if (Index
<= PtrCU
[i
].NbVariables
)
1662 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1666 Index
-= PtrCU
[i
].NbVariables
;
1675 // Get global variable's type tag based on his index (starting from 1)
1676 // Return 0 if not found
1677 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1679 for (size_t i
= 0; i
< NbCU
; i
++)
1681 if (PtrCU
[i
].NbVariables
)
1683 if (Index
<= PtrCU
[i
].NbVariables
)
1685 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1689 Index
-= PtrCU
[i
].NbVariables
;
1698 // Get global variable byte size based on his index (starting from 1)
1699 // Return 0 if not found
1700 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1702 for (size_t i
= 0; i
< NbCU
; i
++)
1704 if (PtrCU
[i
].NbVariables
)
1706 if (Index
<= PtrCU
[i
].NbVariables
)
1708 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1712 Index
-= PtrCU
[i
].NbVariables
;
1721 // Get global variable encoding based on his index (starting from 1)
1722 // Return 0 if not found
1723 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1725 for (size_t i
= 0; i
< NbCU
; i
++)
1727 if (PtrCU
[i
].NbVariables
)
1729 if (Index
<= PtrCU
[i
].NbVariables
)
1731 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1735 Index
-= PtrCU
[i
].NbVariables
;
1744 // Get global variable memory address based on his index (starting from 1)
1745 // Return 0 if not found
1746 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1748 for (size_t i
= 0; i
< NbCU
; i
++)
1750 if (PtrCU
[i
].NbVariables
)
1752 if (Index
<= PtrCU
[i
].NbVariables
)
1754 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1758 Index
-= PtrCU
[i
].NbVariables
;
1767 // Get global variable memory address based on his name
1768 // Return 0 if not found, or will return the first occurence found
1769 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1771 for (size_t i
= 0; i
< NbCU
; i
++)
1773 if (PtrCU
[i
].NbVariables
)
1775 for (size_t j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1777 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1779 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1789 // Get global variable name based on his index (starting from 1)
1790 // Return name's pointer text found, or will return NULL if no variable can be found
1791 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1793 for (size_t i
= 0; i
< NbCU
; i
++)
1795 if (PtrCU
[i
].NbVariables
)
1797 if (Index
<= PtrCU
[i
].NbVariables
)
1799 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1803 Index
-= PtrCU
[i
].NbVariables
;
1812 // Get text line from source based on address and his tag
1813 // A tag can be either 0 or a DW_TAG_subprogram
1814 // DW_TAG_subprogram will look for the line pointing to the function
1815 // Return NULL if no text line has been found
1816 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1818 for (size_t i
= 0; i
< NbCU
; i
++)
1820 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1822 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1824 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1826 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1828 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1832 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1834 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1836 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1838 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1843 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1856 // Get line number based on the address and a tag
1857 // A tag can be either 0 or a DW_TAG_subprogram
1858 // DW_TAG_subprogram will look for the line pointing to the function name as described in the source code
1859 // Return 0 if no line number has been found
1860 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1862 for (size_t i
= 0; i
< NbCU
; i
++)
1864 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1866 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1868 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1870 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1872 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1876 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1878 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1880 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1885 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1887 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1893 // Check if a used line is found with the address
1894 for (size_t j
= 0; j
< PtrCU
[i
].NbUsedLinesSrc
; j
++)
1896 if (PtrCU
[i
].PtrUsedLinesSrc
[j
].StartPC
== Adr
)
1898 return PtrCU
[i
].PtrUsedLinesSrc
[j
].NumLineSrc
;
1908 // Get function name based on an address
1909 // Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address
1910 char *DWARFManager_GetFunctionName(size_t Adr
)
1912 for (size_t i
= 0; i
< NbCU
; i
++)
1914 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1916 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1918 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1920 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1930 // Get number of lines of texts source list from source index
1931 size_t DWARFManager_GetSrcNbListPtrFromIndex(size_t Index
, bool Used
)
1935 return PtrCU
[Index
].NbLinesLoadSrc
;
1939 return PtrCU
[Index
].NbUsedLinesSrc
;
1944 // Get text source line number list pointer from source index
1945 // Return NULL for the text source used list
1946 size_t *DWARFManager_GetSrcNumLinesPtrFromIndex(size_t Index
, bool Used
)
1950 return PtrCU
[Index
].PtrUsedNumLines
;
1959 // Get text source list pointers from source index
1960 // Return NULL for the text source used list
1961 char **DWARFManager_GetSrcListPtrFromIndex(size_t Index
, bool Used
)
1965 return PtrCU
[Index
].PtrLinesLoadSrc
;
1969 return PtrCU
[Index
].PtrUsedLinesLoadSrc
;
1974 // Get source language
1975 size_t DWARFManager_GetSrcLanguageFromIndex(size_t Index
)
1977 return PtrCU
[Index
].Language
;
1981 // Get text line from source based on address and num line (starting from 1)
1982 // Return NULL if no text line has been found
1983 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1985 for (size_t i
= 0; i
< NbCU
; i
++)
1987 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1989 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1991 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1993 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1995 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1999 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
2001 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
2003 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
2016 // Get text line pointer from source, based on address and line number (starting from 1)
2017 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
2018 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
2020 for (size_t i
= 0; i
< NbCU
; i
++)
2022 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
2024 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
2026 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
2039 // Get number of source code filenames
2040 size_t DWARFManager_GetNbSources(void)
2046 // Get source code filename, including his directory, based on index (starting from 0)
2047 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
2049 return (PtrCU
[Index
].PtrFullFilename
);
2053 // Get source code filename based on index (starting from 0)
2054 char *DWARFManager_GetNumSourceFilename(size_t Index
)
2056 return (PtrCU
[Index
].PtrSourceFilename
);