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 when reading DWARF information
17 // RG Jan./2021 Linux build fixes
21 // To use pointers instead of arrays usage
30 #include <sys/types.h>
35 #include "DWARFManager.h"
37 // Definitions for debugging
38 //#define DEBUG_NumCU 0x3 // CU number to debug or undefine it
39 //#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it
40 //#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it
41 //#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)
42 //#define DEBUG_Filename "crt0" // Filename to look for or undefine it
44 // Definitions for handling data
45 //#define CONVERT_QT_HML // Text will be converted as HTML
47 // Definitions for the variables's typetag
48 #define TypeTag_structure 0x01 // structure
49 #define TypeTag_pointer 0x02 // pointer
50 #define TypeTag_subrange 0x04 // (subrange_type?)
51 #define TypeTag_arraytype 0x08 // array type
52 #define TypeTag_consttype 0x10 // const type
53 #define TypeTag_typedef 0x20 // typedef
54 #define TypeTag_enumeration_type 0x40 // enumeration
55 #define TypeTag_subroutine_type 0x80 // subroutine
58 // Source line CU structure
59 typedef struct CUStruct_LineSrc
66 // Source line internal structure
67 typedef struct DMIStruct_LineSrc
75 // Enumeration structure
76 typedef struct EnumerationStruct
78 char *PtrName
; // Enumeration's name
79 size_t value
; // Enumeration's value
82 // Structure members structure
83 //typedef struct StructureMembersStruct
85 //}S_StructureMembersStruct;
87 // Base type internal structure
88 typedef struct BaseTypeStruct
90 size_t Tag
; // Type's Tag
91 size_t Offset
; // Type's offset
92 size_t TypeOffset
; // Type's offset on another type
93 size_t ByteSize
; // Type's Byte Size
94 size_t Encoding
; // Type's encoding
95 char *PtrName
; // Type's name
96 size_t NbEnumeration
; // Type's enumeration numbers
97 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
98 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
101 // Variables internal structure
102 typedef struct VariablesStruct
104 size_t Op
; // Variable's DW_OP
107 size_t Addr
; // Variable memory address
108 int Offset
; // Variable stack offset (signed)
110 char *PtrName
; // Variable's name
111 size_t TypeOffset
; // Offset pointing on the Variable's Type
112 size_t TypeByteSize
; // Variable's Type byte size
113 size_t TypeTag
; // Variable's Type Tag
114 size_t TypeEncoding
; // Variable's Type encoding
115 char *PtrTypeName
; // Variable's Type name
118 // Sub program internal structure
119 typedef struct SubProgStruct
124 size_t LowPC
, HighPC
;
127 char *PtrSubprogramName
; // Sub program name
128 size_t NbLinesSrc
; // Number of lines source used by the sub program
129 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
130 size_t NbVariables
; // Variables number
131 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
134 // Compilation Unit internal structure
135 typedef struct CUStruct
138 size_t Language
; // Language (C, etc.) used by the source code
139 size_t LowPC
, HighPC
; // Memory range for the code
140 char *PtrProducer
; // "Producer" text information (mostly compiler and compilation options used)
141 char *PtrSourceFilename
; // Source file name
142 char *PtrSourceFileDirectory
; // Directory of the source file
143 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
144 size_t SizeLoadSrc
; // Source code text size
145 char *PtrLoadSrc
; // Pointer to the source code text
146 size_t NbLinesLoadSrc
; // Total number of lines in the source code text
147 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
148 size_t NbSubProgs
; // Number of sub programs / routines
149 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines structure
150 size_t NbTypes
; // Number of types
151 BaseTypeStruct
*PtrTypes
; // Pointer to types
152 size_t NbVariables
; // Variables number
153 VariablesStruct
*PtrVariables
; // Pointer to the global variables list structure
154 size_t NbFrames
; // Frames number
155 size_t NbUsedLinesSrc
; // Number of used source lines
156 size_t LastNumUsedLinesSrc
; // Last number line used
157 CUStruct_LineSrc
*PtrUsedLinesSrc
; // Pointer to the used source lines list structure
158 char **PtrUsedLinesLoadSrc
; // Pointer lists to each used source line referenced by the CUStruct_LineSrc structure
159 size_t *PtrUsedNumLines
; // List of the number lines used
160 struct stat _statbuf
; // File information
161 DWARFstatus Status
; // File status
172 char **ListSearchPaths
;
173 size_t NbSearchPaths
;
174 struct stat FileElfExeInfo
;
178 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
179 void DWARFManager_InitDMI(void);
180 void DWARFManager_CloseDMI(void);
181 bool DWARFManager_ElfClose(void);
182 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
183 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
184 void DWARFManager_SourceFileSearchPathsInit(void);
185 void DWARFManager_SourceFileSearchPathsReset(void);
186 void DWARFManager_SourceFileSearchPathsClose(void);
187 void DWARFManager_ConformSlachesBackslashes(char *Ptr
);
191 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
197 // Dwarf manager list search paths init
198 void DWARFManager_SourceFileSearchPathsInit(void)
200 ListSearchPaths
= NULL
;
205 // Dwarf manager list search paths reset
206 void DWARFManager_SourceFileSearchPathsReset(void)
208 ListSearchPaths
= NULL
;
213 // Dwarf manager list search paths close
214 void DWARFManager_SourceFileSearchPathsClose(void)
216 DWARFManager_SourceFileSearchPathsReset();
220 // Dwarf manager init
221 void DWARFManager_Init(void)
223 DWARFManager_SourceFileSearchPathsInit();
224 LibDwarf
= DW_DLV_NO_ENTRY
;
228 // Dwarf manager settings
229 void DWARFManager_Set(size_t NbPathsInList
, char **PtrListPaths
)
232 ListSearchPaths
= PtrListPaths
;
233 NbSearchPaths
= NbPathsInList
;
237 // Dwarf manager Reset
238 bool DWARFManager_Reset(void)
240 DWARFManager_SourceFileSearchPathsReset();
241 return DWARFManager_ElfClose();
245 // Dwarf manager Close
246 bool DWARFManager_Close(void)
248 DWARFManager_SourceFileSearchPathsClose();
249 return(DWARFManager_Reset());
253 // Dwarf manager Elf init
254 int DWARFManager_ElfInit(Elf
*ElfPtr
, struct stat FileElfInfo
)
256 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
258 FileElfExeInfo
= FileElfInfo
;
259 DWARFManager_InitDMI();
266 // Dwarf manager Elf close
267 bool DWARFManager_ElfClose(void)
269 if (LibDwarf
== DW_DLV_OK
)
271 DWARFManager_CloseDMI();
273 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
275 LibDwarf
= DW_DLV_NO_ENTRY
;
290 // Dwarf manager Compilation Units close
291 void DWARFManager_CloseDMI(void)
295 free(PtrCU
[NbCU
].PtrFullFilename
);
296 free(PtrCU
[NbCU
].PtrLoadSrc
);
297 free(PtrCU
[NbCU
].PtrProducer
);
298 free(PtrCU
[NbCU
].PtrSourceFilename
);
299 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
300 free(PtrCU
[NbCU
].PtrUsedLinesSrc
);
301 free(PtrCU
[NbCU
].PtrUsedLinesLoadSrc
);
302 free(PtrCU
[NbCU
].PtrUsedNumLines
);
304 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
306 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
308 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
310 while (PtrCU
[NbCU
].NbSubProgs
--)
312 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
314 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
315 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
317 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
319 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
320 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
322 free(PtrCU
[NbCU
].PtrSubProgs
);
324 while (PtrCU
[NbCU
].NbTypes
--)
326 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
328 free(PtrCU
[NbCU
].PtrTypes
);
330 while (PtrCU
[NbCU
].NbVariables
--)
332 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
333 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
335 free(PtrCU
[NbCU
].PtrVariables
);
342 // Dwarf manager Compilation Units initialisations
343 void DWARFManager_InitDMI(void)
345 Dwarf_Unsigned next_cu_header
, return_uvalue
;
347 Dwarf_Attribute
*atlist
;
348 Dwarf_Attribute return_attr1
;
349 Dwarf_Half return_tagval
, return_attr
;
350 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
351 Dwarf_Block
*return_block
;
352 Dwarf_Signed atcnt
, cnt
;
353 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
354 Dwarf_Off return_offset
;
360 // Initialisation for the Compilation Units table
364 // loop on the available Compilation Unit
365 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
367 // Allocation of an additional Compilation Unit structure in the table
368 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
370 // Compilation Unit RAZ
371 PtrCU
= (CUStruct
*)Ptr
;
372 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
376 if (NbCU
== DEBUG_NumCU
)
379 // Get 1st Die from the Compilation Unit
380 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
383 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
385 PtrCU
[NbCU
].Tag
= return_tagval
;
387 // Die type detection
388 switch (return_tagval
)
390 case DW_TAG_compile_unit
:
391 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
393 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
395 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
401 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
403 PtrCU
[NbCU
].LowPC
= return_lowpc
;
409 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
411 PtrCU
[NbCU
].HighPC
= return_highpc
;
415 // compilation information
417 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
419 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
420 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
421 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
427 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
429 #ifdef DEBUG_Filename
430 if (strstr(return_string
, DEBUG_Filename
))
433 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
434 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
436 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
442 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
444 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
445 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
446 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
452 if (dwarf_formudata(atlist
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
454 PtrCU
[NbCU
].Language
= return_uvalue
;
462 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
464 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
467 // Check filename presence
468 if (!PtrCU
[NbCU
].PtrSourceFilename
)
470 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
473 // Check directory presence
474 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
476 // Check if file exists in the search paths
477 for (size_t i
= 0; i
< NbSearchPaths
; i
++)
479 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen((const char *)ListSearchPaths
[i
]) + 2);
481 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
482 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
484 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
485 SrcFile
= fopen(PtrCU
[NbCU
].PtrFullFilename
, "rb");
489 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, strlen(ListSearchPaths
[i
]) + 1);
490 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ListSearchPaths
[i
]);
494 // File directory doesn't exits
495 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
497 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, 2);
498 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ".");
502 // Conform slashes / backslashes for the filename
503 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrSourceFilename
);
505 // Check if filename contains already the complete directory
506 if (PtrCU
[NbCU
].PtrSourceFilename
[1] == ':')
508 // Copy the filename as the full filename
509 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + 1);
510 strcpy(PtrCU
[NbCU
].PtrFullFilename
, PtrCU
[NbCU
].PtrSourceFilename
);
514 // Create full filename and Conform slashes / backslashes
515 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
517 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
519 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
523 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrFullFilename
);
525 // Directory path clean-up
527 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
529 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
533 while (*--Ptr1
!= '\\');
535 while (*--Ptr1
!= '/');
537 strcpy((Ptr1
+ 1), (Ptr
+ 4));
540 // Get the source file information
541 if (!stat(PtrCU
[NbCU
].PtrFullFilename
, &PtrCU
[NbCU
]._statbuf
))
543 // check the time stamp with the executable
544 if (PtrCU
[NbCU
]._statbuf
.st_mtime
<= FileElfExeInfo
.st_mtime
)
546 // Open the source file as a binary file
548 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
550 SrcFile
= fopen(PtrCU
[NbCU
].PtrFullFilename
, "rb");
554 if (!fseek(SrcFile
, 0, SEEK_END
))
556 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
558 if (!fseek(SrcFile
, 0, SEEK_SET
))
560 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
564 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
566 if (fread(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
569 free(PtrCU
[NbCU
].PtrLoadSrc
);
570 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
571 PtrCU
[NbCU
].SizeLoadSrc
= 0;
575 // Eliminate all carriage return code '\r' (oxd)
578 if ((*Ptr
= *Ptr1
) != '\r')
584 // Get back the new text file size
585 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
587 // Make sure the text file finish with a new line code '\n' (0xa)
588 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
590 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
591 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
594 // Reallocate text file
595 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
597 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
602 PtrCU
[NbCU
].NbLinesLoadSrc
++;
617 // Source file doesn't exist
618 PtrCU
[NbCU
].Status
= DWARFSTATUS_NOFILE
;
623 // Source file is outdated
624 PtrCU
[NbCU
].Status
= DWARFSTATUS_OUTDATEDFILE
;
629 // Source file doesn't have information
630 PtrCU
[NbCU
].Status
= DWARFSTATUS_NOFILEINFO
;
639 // Get the source lines table located in the CU
640 if ((dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
) && (PtrCU
[NbCU
].Status
== DWARFSTATUS_OK
))
644 PtrCU
[NbCU
].NbUsedLinesSrc
= cnt
;
645 PtrCU
[NbCU
].PtrUsedLinesSrc
= (CUStruct_LineSrc
*)calloc(cnt
, sizeof(CUStruct_LineSrc
));
646 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
= (char **)calloc(cnt
, sizeof(char *));
647 PtrCU
[NbCU
].PtrUsedNumLines
= (size_t *)calloc(cnt
, sizeof(size_t));
649 // Get the addresses and their source line numbers
650 for (Dwarf_Signed i
= 0; i
< cnt
; i
++)
652 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
654 // Get the source line number
655 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
657 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
= return_lineaddr
;
658 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
= return_uvalue
;
664 // Release the memory used by the source lines table located in the CU
665 dwarf_srclines_dealloc(dbg
, linebuf
, cnt
);
668 // Check if the CU has child
669 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
673 return_sib
= return_die
;
674 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
676 switch (return_tagval
)
678 case DW_TAG_lexical_block
:
681 case DW_TAG_variable
:
682 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
684 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
685 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
687 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
689 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
691 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
696 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
698 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
700 switch (return_block
->bl_len
)
703 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));
709 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
714 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
716 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
722 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
724 #ifdef DEBUG_VariableName
725 if (!strcmp(return_string
, DEBUG_VariableName
))
728 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
729 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
731 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
741 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
744 // Check variable's name validity
745 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
747 // Check variable's memory address validity
748 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
751 PtrCU
[NbCU
].NbVariables
++;
756 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
757 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
761 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
765 case DW_TAG_base_type
:
767 case DW_TAG_structure_type
:
768 case DW_TAG_pointer_type
:
769 case DW_TAG_const_type
:
770 case DW_TAG_array_type
:
771 case DW_TAG_subrange_type
:
772 case DW_TAG_subroutine_type
:
773 case DW_TAG_enumeration_type
:
774 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
776 // Allocate memory for this type
777 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
778 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
779 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
781 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
783 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
786 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
788 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
790 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
798 // Type's type offset
800 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
802 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
807 case DW_AT_byte_size
:
808 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
810 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
816 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
818 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
824 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
826 #ifdef DEBUG_TypeName
827 if (!strcmp(return_string
, DEBUG_TypeName
))
830 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
831 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
833 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
837 // Type's file number
838 case DW_AT_decl_file
:
841 // Type's line number
842 case DW_AT_decl_line
:
851 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
854 PtrCU
[NbCU
].NbTypes
++;
856 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
860 case DW_TAG_subprogram
:
861 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
863 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
864 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
865 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
867 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
869 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
871 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
877 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
879 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
880 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
886 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
888 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
893 case DW_AT_decl_line
:
894 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
896 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
901 case DW_AT_frame_base
:
902 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
904 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
905 PtrCU
[NbCU
].NbFrames
++;
911 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
913 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
914 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
915 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
922 case DW_AT_GNU_all_tail_call_sites
:
928 case DW_AT_prototyped
:
932 case DW_AT_decl_file
:
943 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
945 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
947 // Get source line number and associated block of address
948 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
950 // Check the presence of the line in the memory frame
951 if (PtrCU
[NbCU
].PtrUsedLinesSrc
&& (PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
>= return_lowpc
) && (PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
<= return_highpc
))
953 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
));
954 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
955 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
;
956 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
;
957 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
961 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
965 return_sub
= return_subdie
;
966 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
968 switch (return_tagval
)
970 case DW_TAG_formal_parameter
:
971 case DW_TAG_variable
:
972 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
974 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
)));
975 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
977 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
979 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
981 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
986 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
988 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
990 switch (return_block
->bl_len
)
997 switch (return_tagval
)
999 case DW_TAG_variable
:
1000 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
1003 case DW_TAG_formal_parameter
:
1004 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
1015 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
1020 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
1022 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
1027 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
1029 #ifdef DEBUG_VariableName
1030 if (!strcmp(return_string
, DEBUG_VariableName
))
1033 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
1034 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
1036 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
1040 case DW_AT_decl_file
:
1043 case DW_AT_decl_line
:
1052 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
1055 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
1057 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
1069 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
1072 PtrCU
[NbCU
].NbSubProgs
++;
1081 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
1085 // Set the source code lines
1086 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
1088 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
1090 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
1092 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
1094 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
1096 #ifndef CONVERT_QT_HML
1097 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], Ptr
);
1106 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
1111 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
1116 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
1121 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
1122 i
+= strlen("&");
1127 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
1128 i
+= strlen(""");
1132 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
1139 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
1143 // Init lines source information for each source code line numbers and for each subprogs
1144 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
1146 // Check if the subprog / function's line exists in the source code
1147 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1149 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1152 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1154 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1156 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1164 // Set each source lines pointer to NULL
1165 if (PtrCU
[NbCU
].NbSubProgs
)
1167 // Check the presence of source lines dedicated to the sub progs
1168 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1170 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1171 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1173 for (size_t j
= 0; j
< i
; j
++)
1175 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1182 // Check validity between used number lines and number lines in the source file
1183 if (PtrCU
[NbCU
].LastNumUsedLinesSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1185 // Set information based on used line numbers
1186 if (PtrCU
[NbCU
].PtrUsedLinesSrc
)
1188 // Set the line source pointers for each used line numbers
1189 if (PtrCU
[NbCU
].PtrLinesLoadSrc
)
1191 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbUsedLinesSrc
; i
++)
1193 PtrCU
[NbCU
].PtrUsedNumLines
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1;
1194 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1];
1197 // Setup memory range for the code if CU doesn't have already this information
1198 // It is taken from the used lines structure
1199 if (!PtrCU
[NbCU
].LowPC
&& (!PtrCU
[NbCU
].HighPC
|| (PtrCU
[NbCU
].HighPC
== ~0)))
1201 PtrCU
[NbCU
].LowPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[0].StartPC
;
1202 PtrCU
[NbCU
].HighPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[PtrCU
[NbCU
].NbUsedLinesSrc
- 1].StartPC
;
1208 // Init global variables information based on types information
1209 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1211 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1214 // Init local variables information based on types information
1215 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1217 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1219 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1230 // Conform slashes and backslashes
1231 void DWARFManager_ConformSlachesBackslashes(char *Ptr
)
1251 // Variables information initialisation
1252 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1254 size_t j
, TypeOffset
;
1256 #ifdef DEBUG_VariableName
1257 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1260 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1261 TypeOffset
= PtrVariables
->TypeOffset
;
1263 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1265 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1267 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1269 case DW_TAG_subroutine_type
:
1270 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1271 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1274 // Structure type tag
1275 case DW_TAG_structure_type
:
1276 PtrVariables
->TypeTag
|= TypeTag_structure
;
1277 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1279 if (PtrCU
[NbCU
].PtrTypes
[j
].PtrName
)
1281 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1284 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1290 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1292 strcat(PtrVariables
->PtrTypeName
, " *");
1298 case DW_TAG_pointer_type
:
1299 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1300 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1301 PtrVariables
->TypeEncoding
= 0x10;
1302 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1304 strcat(PtrVariables
->PtrTypeName
, "void *");
1312 case DW_TAG_enumeration_type
:
1313 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1314 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1315 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1317 // Try to determine the possible size
1318 switch (PtrVariables
->TypeByteSize
)
1321 PtrVariables
->TypeEncoding
= 0x7;
1331 case DW_TAG_typedef
:
1332 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1334 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1335 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1337 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1344 case DW_TAG_subrange_type
:
1345 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1349 case DW_TAG_array_type
:
1350 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1351 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1358 case DW_TAG_const_type
:
1359 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1360 strcat(PtrVariables
->PtrTypeName
, "const ");
1361 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1368 case DW_TAG_base_type
:
1369 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1371 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1373 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1375 strcat(PtrVariables
->PtrTypeName
, " *");
1379 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1380 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1382 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1384 strcat(PtrVariables
->PtrTypeName
, "[]");
1397 // Get symbol name based from address
1398 // Return NULL if no symbol name exists
1399 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1401 for (size_t i
= 0; i
< NbCU
; i
++)
1403 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1405 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1407 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1409 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1419 // Get complete source filename based from address
1420 // Return NULL if no source filename exists
1421 // Return the existence status in Status if pointer not NULL
1422 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, DWARFstatus
*Status
)
1424 for (size_t i
= 0; i
< NbCU
; i
++)
1426 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1430 *Status
= PtrCU
[i
].Status
;
1433 return PtrCU
[i
].PtrFullFilename
;
1441 // Get text line source based on line number (starting from 1)
1442 // Return NULL if no text line exists or if line number is 0
1443 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1446 char *PtrLineSrc
= NULL
;
1450 while (i
!= NumLine
)
1452 PtrLineSrc
= PtrSrcFile
;
1453 while (*PtrSrcFile
++);
1462 // Get number of variables referenced by the function range address
1463 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1465 for (size_t i
= 0; i
< NbCU
; i
++)
1467 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1469 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1471 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1473 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1483 // Get local variable name based on his index (starting from 1)
1484 // Return name's pointer text found
1485 // Return NULL if not found
1486 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1488 for (size_t i
= 0; i
< NbCU
; i
++)
1490 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1492 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1494 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1496 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1506 // Get local variable's type tag based on his index (starting from 1)
1507 // Return 0 if not found
1508 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1510 for (size_t i
= 0; i
< NbCU
; i
++)
1512 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1514 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1516 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1518 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1528 // Get the local variable's offset based on a index (starting from 1)
1529 // Return 0 if no offset has been found
1530 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1532 for (size_t i
= 0; i
< NbCU
; i
++)
1534 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1536 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1538 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1540 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1550 // Get local variable Type Byte Size based on his address and index (starting from 1)
1551 // Return 0 if not found
1552 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1553 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1555 for (size_t i
= 0; i
< NbCU
; i
++)
1557 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1559 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1561 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1563 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1573 // Get local variable Type Encoding based on his address and index (starting from 1)
1574 // Return 0 if not found
1575 // May return 0 if there is no Type Encoding linked to the variable's address and index
1576 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1578 for (size_t i
= 0; i
< NbCU
; i
++)
1580 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1582 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1584 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1586 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1596 // Get local variable Op based on his address and index (starting from 1)
1597 // Return 0 if not found, may return 0 if there isn't Op linked to the variable's index
1598 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1600 for (size_t i
= 0; i
< NbCU
; i
++)
1602 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1604 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1606 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1608 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1618 // Get local variable type name based on his index (starting from 1) and an address
1619 // Return NULL if not found, may also return NULL if there is no type linked to the variable's index
1620 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1622 for (size_t i
= 0; i
< NbCU
; i
++)
1624 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1626 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1628 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1630 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1640 // Get Compilation Unit / global variables numbers
1641 // Return number of variables
1642 size_t DWARFManager_GetNbGlobalVariables(void)
1644 size_t NbVariables
= 0;
1646 for (size_t i
= 0; i
< NbCU
; i
++)
1648 NbVariables
+= PtrCU
[i
].NbVariables
;
1655 // Get global variable type name based on his index (starting from 1)
1656 // Return NULL if not found
1657 // May return NULL if there is not type linked to the variable's index
1658 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1660 for (size_t i
= 0; i
< NbCU
; i
++)
1662 if (PtrCU
[i
].NbVariables
)
1664 if (Index
<= PtrCU
[i
].NbVariables
)
1666 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1670 Index
-= PtrCU
[i
].NbVariables
;
1679 // Get global variable's type tag based on his index (starting from 1)
1680 // Return 0 if not found
1681 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1683 for (size_t i
= 0; i
< NbCU
; i
++)
1685 if (PtrCU
[i
].NbVariables
)
1687 if (Index
<= PtrCU
[i
].NbVariables
)
1689 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1693 Index
-= PtrCU
[i
].NbVariables
;
1702 // Get global variable byte size based on his index (starting from 1)
1703 // Return 0 if not found
1704 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1706 for (size_t i
= 0; i
< NbCU
; i
++)
1708 if (PtrCU
[i
].NbVariables
)
1710 if (Index
<= PtrCU
[i
].NbVariables
)
1712 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1716 Index
-= PtrCU
[i
].NbVariables
;
1725 // Get global variable encoding based on his index (starting from 1)
1726 // Return 0 if not found
1727 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1729 for (size_t i
= 0; i
< NbCU
; i
++)
1731 if (PtrCU
[i
].NbVariables
)
1733 if (Index
<= PtrCU
[i
].NbVariables
)
1735 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1739 Index
-= PtrCU
[i
].NbVariables
;
1748 // Get global variable memory address based on his index (starting from 1)
1749 // Return 0 if not found
1750 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1752 for (size_t i
= 0; i
< NbCU
; i
++)
1754 if (PtrCU
[i
].NbVariables
)
1756 if (Index
<= PtrCU
[i
].NbVariables
)
1758 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1762 Index
-= PtrCU
[i
].NbVariables
;
1771 // Get global variable memory address based on his name
1772 // Return 0 if not found, or will return the first occurence found
1773 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1775 for (size_t i
= 0; i
< NbCU
; i
++)
1777 if (PtrCU
[i
].NbVariables
)
1779 for (size_t j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1781 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1783 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1793 // Get global variable name based on his index (starting from 1)
1794 // Return name's pointer text found, or will return NULL if no variable can be found
1795 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1797 for (size_t i
= 0; i
< NbCU
; i
++)
1799 if (PtrCU
[i
].NbVariables
)
1801 if (Index
<= PtrCU
[i
].NbVariables
)
1803 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1807 Index
-= PtrCU
[i
].NbVariables
;
1816 // Get text line from source based on address and his tag
1817 // A tag can be either 0 or a DW_TAG_subprogram
1818 // DW_TAG_subprogram will look for the line pointing to the function
1819 // Return NULL if no text line has been found
1820 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1822 for (size_t i
= 0; i
< NbCU
; i
++)
1824 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1826 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1828 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1830 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1832 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1836 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1838 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1840 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1842 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1847 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1860 // Get line number based on the address and a tag
1861 // A tag can be either 0 or a DW_TAG_subprogram
1862 // DW_TAG_subprogram will look for the line pointing to the function name as described in the source code
1863 // Return 0 if no line number has been found
1864 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1866 for (size_t i
= 0; i
< NbCU
; i
++)
1868 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1870 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1872 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1874 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1876 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1880 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1882 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1884 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1886 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1891 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].NumLineSrc
;
1896 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1898 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1904 // Check if a used line is found with the address
1905 for (size_t j
= 0; j
< PtrCU
[i
].NbUsedLinesSrc
; j
++)
1907 if (PtrCU
[i
].PtrUsedLinesSrc
[j
].StartPC
== Adr
)
1909 return PtrCU
[i
].PtrUsedLinesSrc
[j
].NumLineSrc
;
1919 // Get function name based on an address
1920 // Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address
1921 char *DWARFManager_GetFunctionName(size_t Adr
)
1923 for (size_t i
= 0; i
< NbCU
; i
++)
1925 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1927 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1929 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1931 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1941 // Get number of lines of texts source list from source index
1942 size_t DWARFManager_GetSrcNbListPtrFromIndex(size_t Index
, bool Used
)
1946 return PtrCU
[Index
].NbLinesLoadSrc
;
1950 return PtrCU
[Index
].NbUsedLinesSrc
;
1955 // Get text source line number list pointer from source index
1956 // Return NULL for the text source used list
1957 size_t *DWARFManager_GetSrcNumLinesPtrFromIndex(size_t Index
, bool Used
)
1961 return PtrCU
[Index
].PtrUsedNumLines
;
1970 // Get text source list pointers from source index
1971 // Return NULL for the text source used list
1972 char **DWARFManager_GetSrcListPtrFromIndex(size_t Index
, bool Used
)
1976 return PtrCU
[Index
].PtrLinesLoadSrc
;
1980 return PtrCU
[Index
].PtrUsedLinesLoadSrc
;
1985 // Get source language
1986 size_t DWARFManager_GetSrcLanguageFromIndex(size_t Index
)
1988 return PtrCU
[Index
].Language
;
1992 // Get text line from source based on address and num line (starting from 1)
1993 // Return NULL if no text line has been found
1994 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1996 for (size_t i
= 0; i
< NbCU
; i
++)
1998 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
2000 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
2002 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
2004 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
2006 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
2010 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
2012 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
2014 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
2027 // Get text line pointer from source, based on address and line number (starting from 1)
2028 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
2029 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
2031 for (size_t i
= 0; i
< NbCU
; i
++)
2033 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
2035 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
2037 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
2050 // Get number of source code filenames
2051 size_t DWARFManager_GetNbSources(void)
2057 // Get source code filename, including his directory, based on index (starting from 0)
2058 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
2060 return (PtrCU
[Index
].PtrFullFilename
);
2064 // Get source code filename based on index (starting from 0)
2065 char *DWARFManager_GetNumSourceFilename(size_t Index
)
2067 return (PtrCU
[Index
].PtrSourceFilename
);