2 // DWARFManager.cpp: DWARF format manager
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
9 // --- ---------- ------------------------------------------------------------
10 // JPM Dec./2016 Created this file, and added the DWARF format support
11 // JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information
12 // JPM Oct./2018 Improve the DWARF parsing information, and the source file text reading; support the used source lines from DWARF structure, and the search paths for the files
13 // JPM Aug./2019 Added new functions to handle DWARF information, full filename fix
17 // To use pointers instead of arrays usage
18 // To keep sources text file intact wihtout QT/HTML transformation
31 // Definitions for debugging
32 //#define DEBUG_NumCU 0x44 // CU number to debug or undefine it
33 //#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it
34 //#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it
35 //#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)
36 //#define DEBUG_Filename "crt0" // Filename to look for or undefine it
38 // Definitions for handling data
39 //#define CONVERT_QT_HML // Text will be converted as HTML
41 // Definitions for the variables's typetag
42 #define TypeTag_structure 0x01 // structure
43 #define TypeTag_pointer 0x02 // pointer
44 #define TypeTag_subrange 0x04 // (subrange_type?)
45 #define TypeTag_arraytype 0x08 // array type
46 #define TypeTag_consttype 0x10 // const type
47 #define TypeTag_typedef 0x20 // typedef
48 #define TypeTag_enumeration_type 0x40 // enumeration
49 #define TypeTag_subroutine_type 0x80 // subroutine
52 // Source line CU structure
53 typedef struct CUStruct_LineSrc
60 // Source line internal structure
61 typedef struct DMIStruct_LineSrc
69 // Enumeration structure
70 typedef struct EnumerationStruct
72 char *PtrName
; // Enumeration's name
73 size_t value
; // Enumeration's value
76 // Structure members structure
77 //typedef struct StructureMembersStruct
79 //}S_StructureMembersStruct;
81 // Base type internal structure
82 typedef struct BaseTypeStruct
84 size_t Tag
; // Type's Tag
85 size_t Offset
; // Type's offset
86 size_t TypeOffset
; // Type's offset on another type
87 size_t ByteSize
; // Type's Byte Size
88 size_t Encoding
; // Type's encoding
89 char *PtrName
; // Type's name
90 size_t NbEnumeration
; // Type's enumeration numbers
91 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
92 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
95 // Variables internal structure
96 typedef struct VariablesStruct
98 size_t Op
; // Variable's DW_OP
101 size_t Addr
; // Variable memory address
102 int Offset
; // Variable stack offset (signed)
104 char *PtrName
; // Variable's name
105 size_t TypeOffset
; // Offset pointing on the Variable's Type
106 size_t TypeByteSize
; // Variable's Type byte size
107 size_t TypeTag
; // Variable's Type Tag
108 size_t TypeEncoding
; // Variable's Type encoding
109 char *PtrTypeName
; // Variable's Type name
112 // Sub program internal structure
113 typedef struct SubProgStruct
118 size_t LowPC
, HighPC
;
121 char *PtrSubprogramName
; // Sub program name
122 size_t NbLinesSrc
; // Number of lines source used by the sub program
123 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
124 size_t NbVariables
; // Variables number
125 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
128 // Compilation Unit internal structure
129 typedef struct CUStruct
132 size_t Language
; // Language (C, etc.) used by the source code
133 size_t LowPC
, HighPC
; // Memory range for the code
134 char *PtrProducer
; // Pointer to the "Producer" text information (mostly compiler and compilation options used)
135 char *PtrSourceFilename
; // Source file name
136 char *PtrSourceFileDirectory
; // Directory of the source file
137 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
138 size_t SizeLoadSrc
; // Source code text size
139 char *PtrLoadSrc
; // Pointer to the source code text
140 size_t NbLinesLoadSrc
; // Total number of lines in the source code text
141 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
142 size_t NbSubProgs
; // Number of sub programs / routines
143 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines structure
144 size_t NbTypes
; // Number of types
145 BaseTypeStruct
*PtrTypes
; // Pointer to types
146 size_t NbVariables
; // Variables number
147 VariablesStruct
*PtrVariables
; // Pointer to the global variables list structure
148 size_t NbFrames
; // Frames number
149 size_t NbUsedLinesSrc
; // Number of used source lines
150 size_t LastNumUsedLinesSrc
; // Last used source number line
151 CUStruct_LineSrc
*PtrUsedLinesSrc
; // Pointer to the used source lines list structure
152 char **PtrUsedLinesLoadSrc
; // Pointer lists to each used source line referenced by the CUStruct_LineSrc structure
153 size_t *PtrUsedNumLines
; // Pointer list to the number lines used
164 char **ListSearchPaths
;
165 size_t NbSearchPaths
;
169 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
170 void DWARFManager_InitDMI(void);
171 void DWARFManager_CloseDMI(void);
172 bool DWARFManager_ElfClose(void);
173 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
174 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
175 void DWARFManager_SourceFileSearchPathsInit(void);
176 void DWARFManager_SourceFileSearchPathsReset(void);
177 void DWARFManager_SourceFileSearchPathsClose(void);
178 void DWARFManager_ConformSlachesBackslashes(char *Ptr
);
182 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
188 // Dwarf manager list search paths init
189 void DWARFManager_SourceFileSearchPathsInit(void)
191 ListSearchPaths
= NULL
;
196 // Dwarf manager list search paths reset
197 void DWARFManager_SourceFileSearchPathsReset(void)
199 ListSearchPaths
= NULL
;
204 // Dwarf manager list search paths close
205 void DWARFManager_SourceFileSearchPathsClose(void)
207 DWARFManager_SourceFileSearchPathsReset();
211 // Dwarf manager init
212 void DWARFManager_Init(void)
214 DWARFManager_SourceFileSearchPathsInit();
215 LibDwarf
= DW_DLV_NO_ENTRY
;
219 // Dwarf manager settings
220 void DWARFManager_Set(size_t NbPathsInList
, char **PtrListPaths
)
223 ListSearchPaths
= PtrListPaths
;
224 NbSearchPaths
= NbPathsInList
;
228 // Dwarf manager Reset
229 bool DWARFManager_Reset(void)
231 DWARFManager_SourceFileSearchPathsReset();
232 return DWARFManager_ElfClose();
236 // Dwarf manager Close
237 bool DWARFManager_Close(void)
239 DWARFManager_SourceFileSearchPathsClose();
240 return(DWARFManager_Reset());
244 // Dwarf manager Elf init
245 int DWARFManager_ElfInit(Elf
*ElfPtr
)
247 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
249 DWARFManager_InitDMI();
256 // Dwarf manager Elf close
257 bool DWARFManager_ElfClose(void)
259 if (LibDwarf
== DW_DLV_OK
)
261 DWARFManager_CloseDMI();
263 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
265 LibDwarf
= DW_DLV_NO_ENTRY
;
280 // Dwarf manager Compilation Units close
281 void DWARFManager_CloseDMI(void)
285 free(PtrCU
[NbCU
].PtrFullFilename
);
286 free(PtrCU
[NbCU
].PtrLoadSrc
);
287 free(PtrCU
[NbCU
].PtrProducer
);
288 free(PtrCU
[NbCU
].PtrSourceFilename
);
289 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
290 free(PtrCU
[NbCU
].PtrUsedLinesSrc
);
291 free(PtrCU
[NbCU
].PtrUsedLinesLoadSrc
);
292 free(PtrCU
[NbCU
].PtrUsedNumLines
);
294 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
296 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
298 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
300 while (PtrCU
[NbCU
].NbSubProgs
--)
302 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
304 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
305 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
307 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
309 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
310 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
312 free(PtrCU
[NbCU
].PtrSubProgs
);
314 while (PtrCU
[NbCU
].NbTypes
--)
316 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
318 free(PtrCU
[NbCU
].PtrTypes
);
320 while (PtrCU
[NbCU
].NbVariables
--)
322 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
323 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
325 free(PtrCU
[NbCU
].PtrVariables
);
332 // Dwarf manager Compilation Units initialisations
333 void DWARFManager_InitDMI(void)
335 Dwarf_Unsigned next_cu_header
, return_uvalue
;
337 Dwarf_Attribute
*atlist
;
338 Dwarf_Attribute return_attr1
;
339 Dwarf_Half return_tagval
, return_attr
;
340 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
341 Dwarf_Block
*return_block
;
342 Dwarf_Signed atcnt
, cnt
;
343 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
344 Dwarf_Off return_offset
;
350 // Initialisation for the Compilation Units table
354 // loop on the available Compilation Unit
355 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
357 // Allocation of an additional Compilation Unit structure in the table
358 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
360 // Compilation Unit RAZ
361 PtrCU
= (CUStruct
*)Ptr
;
362 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
366 if (NbCU
== DEBUG_NumCU
)
369 // Get 1st Die from the Compilation Unit
370 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
373 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
375 PtrCU
[NbCU
].Tag
= return_tagval
;
377 // Die type detection
378 switch (return_tagval
)
380 case DW_TAG_compile_unit
:
381 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
383 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
385 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
391 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
393 PtrCU
[NbCU
].LowPC
= return_lowpc
;
399 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
401 PtrCU
[NbCU
].HighPC
= return_highpc
;
405 // compilation information
407 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
409 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
410 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
411 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
417 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
419 #ifdef DEBUG_Filename
420 if (strstr(return_string
, DEBUG_Filename
))
423 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
424 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
426 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
432 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
434 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
435 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
436 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
442 if (dwarf_formudata(atlist
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
444 PtrCU
[NbCU
].Language
= return_uvalue
;
452 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
454 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
457 // Check filename presence
458 if (!PtrCU
[NbCU
].PtrSourceFilename
)
460 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
463 // Check directory presence
464 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
466 // Check if file exists in the search paths
467 for (size_t i
= 0; i
< NbSearchPaths
; i
++)
469 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen((const char *)ListSearchPaths
[i
]) + 2);
471 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
473 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", ListSearchPaths
[i
], PtrCU
[NbCU
].PtrSourceFilename
);
475 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
477 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, strlen(ListSearchPaths
[i
]) + 1);
478 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ListSearchPaths
[i
]);
482 // File directory doesn't exits
483 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
485 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)realloc(PtrCU
[NbCU
].PtrSourceFileDirectory
, 2);
486 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, ".");
490 // Conform slashes / backslashes for the filename
491 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrSourceFilename
);
493 // Check if filename contains already the complete directory
494 if (PtrCU
[NbCU
].PtrSourceFilename
[1] == ':')
496 // Copy the filename as the full filename
497 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + 1);
498 strcpy(PtrCU
[NbCU
].PtrFullFilename
, PtrCU
[NbCU
].PtrSourceFilename
);
502 // Create full filename and Conform slashes / backslashes
503 PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
505 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
507 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s/%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
511 DWARFManager_ConformSlachesBackslashes(PtrCU
[NbCU
].PtrFullFilename
);
513 // Directory path clean-up
515 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
517 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
521 while (*--Ptr1
!= '\\');
523 while (*--Ptr1
!= '/');
525 strcpy((Ptr1
+ 1), (Ptr
+ 4));
528 // Open the source file as a binary file
529 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
531 if (!fseek(SrcFile
, 0, SEEK_END
))
533 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
535 if (!fseek(SrcFile
, 0, SEEK_SET
))
537 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
540 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
542 free(PtrCU
[NbCU
].PtrLoadSrc
);
543 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
544 PtrCU
[NbCU
].SizeLoadSrc
= 0;
548 // Eliminate all carriage return code '\r' (oxd)
551 if ((*Ptr
= *Ptr1
) != '\r')
558 // Get back the new text file size
559 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
561 // Make sure the text file finish with a new line code '\n' (0xa)
562 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
564 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
565 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
568 // Reallocate text file
569 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
571 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
576 PtrCU
[NbCU
].NbLinesLoadSrc
++;
595 // Get the source lines table located in the CU
596 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
600 PtrCU
[NbCU
].NbUsedLinesSrc
= cnt
;
601 PtrCU
[NbCU
].PtrUsedLinesSrc
= (CUStruct_LineSrc
*)calloc(cnt
, sizeof(CUStruct_LineSrc
));
602 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
= (char **)calloc(cnt
, sizeof(char *));
603 PtrCU
[NbCU
].PtrUsedNumLines
= (size_t *)calloc(cnt
, sizeof(size_t));
605 // Get the addresses and their source line numbers
606 for (Dwarf_Signed i
= 0; i
< cnt
; i
++)
608 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
610 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
612 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].StartPC
= return_lineaddr
;
613 PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
= return_uvalue
;
615 // Get the last used line number in the source file
616 if (PtrCU
[NbCU
].LastNumUsedLinesSrc
< PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
)
618 PtrCU
[NbCU
].LastNumUsedLinesSrc
= PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
;
626 // Check if the CU has child
627 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
631 return_sib
= return_die
;
632 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
634 switch (return_tagval
)
636 case DW_TAG_lexical_block
:
639 case DW_TAG_variable
:
640 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
642 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
643 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
645 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
647 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
649 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
654 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
656 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
658 switch (return_block
->bl_len
)
661 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));
667 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
672 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
674 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
680 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
682 #ifdef DEBUG_VariableName
683 if (!strcmp(return_string
, DEBUG_VariableName
))
686 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
687 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
689 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
699 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
702 // Check variable's name validity
703 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
705 // Check variable's memory address validity
706 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
709 PtrCU
[NbCU
].NbVariables
++;
714 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
715 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
719 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
723 case DW_TAG_base_type
:
725 case DW_TAG_structure_type
:
726 case DW_TAG_pointer_type
:
727 case DW_TAG_const_type
:
728 case DW_TAG_array_type
:
729 case DW_TAG_subrange_type
:
730 case DW_TAG_subroutine_type
:
731 case DW_TAG_enumeration_type
:
732 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
734 // Allocate memory for this type
735 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
736 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
737 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
739 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
741 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
744 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
746 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
748 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
756 // Type's type offset
758 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
760 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
765 case DW_AT_byte_size
:
766 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
768 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
774 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
776 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
782 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
784 #ifdef DEBUG_TypeName
785 if (!strcmp(return_string
, DEBUG_TypeName
))
788 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
789 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
791 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
795 // Type's file number
796 case DW_AT_decl_file
:
799 // Type's line number
800 case DW_AT_decl_line
:
809 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
812 PtrCU
[NbCU
].NbTypes
++;
814 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
818 case DW_TAG_subprogram
:
819 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
821 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
822 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
823 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
825 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
827 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
829 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
835 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
837 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
838 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
844 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
846 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
851 case DW_AT_decl_line
:
852 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
854 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
859 case DW_AT_frame_base
:
860 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
862 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
863 PtrCU
[NbCU
].NbFrames
++;
869 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
871 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
872 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
873 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
880 case DW_AT_GNU_all_tail_call_sites
:
886 case DW_AT_prototyped
:
890 case DW_AT_decl_file
:
901 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
903 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
905 // Get source line number and associated block of address
906 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
908 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
910 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
912 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
914 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
));
915 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
916 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
917 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
918 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
924 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
928 return_sub
= return_subdie
;
929 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
931 switch (return_tagval
)
933 case DW_TAG_formal_parameter
:
934 case DW_TAG_variable
:
935 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
937 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
)));
938 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
940 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
942 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
944 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
949 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
951 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
953 switch (return_block
->bl_len
)
960 switch (return_tagval
)
962 case DW_TAG_variable
:
963 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
966 case DW_TAG_formal_parameter
:
967 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
978 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
983 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
985 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
990 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
992 #ifdef DEBUG_VariableName
993 if (!strcmp(return_string
, DEBUG_VariableName
))
996 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
997 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
999 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
1003 case DW_AT_decl_file
:
1006 case DW_AT_decl_line
:
1015 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
1018 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
1020 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
1032 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
1035 PtrCU
[NbCU
].NbSubProgs
++;
1044 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
1047 // Release the memory used by the source lines
1048 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
1050 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
1052 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
1055 // Set the source code lines for QT html/text conformity
1056 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
1058 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
1060 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
1062 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
1064 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
1072 #ifdef CONVERT_QT_HML
1074 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
1079 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
1084 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
1089 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
1090 i
+= strlen("&");
1095 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
1096 i
+= strlen(""");
1101 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
1107 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
1111 // Init lines source information for each source code line numbers and for each subprogs
1112 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
1114 // Check if the subprog / function's line exists in the source code
1115 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1117 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1120 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1122 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1124 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1132 // Set each source lines pointer to NULL
1133 if (PtrCU
[NbCU
].NbSubProgs
)
1135 // Check the presence of source lines dedicated to the sub progs
1136 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1138 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1139 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1141 for (size_t j
= 0; j
< i
; j
++)
1143 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1150 // Check validity between used number lines and number lines in the source file
1151 if (PtrCU
[NbCU
].LastNumUsedLinesSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1153 // Set information based on used line numbers
1154 if (PtrCU
[NbCU
].PtrUsedLinesSrc
)
1156 // Set the line source pointers for each used line numbers
1157 if (PtrCU
[NbCU
].PtrLinesLoadSrc
)
1159 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbUsedLinesSrc
; i
++)
1161 PtrCU
[NbCU
].PtrUsedNumLines
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1;
1162 PtrCU
[NbCU
].PtrUsedLinesLoadSrc
[i
] = PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrUsedLinesSrc
[i
].NumLineSrc
- 1];
1165 // Setup memory range for the code if CU doesn't have already this information
1166 // It is taken from the used lines structure
1167 if (!PtrCU
[NbCU
].LowPC
&& (!PtrCU
[NbCU
].HighPC
|| (PtrCU
[NbCU
].HighPC
== ~0)))
1169 PtrCU
[NbCU
].LowPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[0].StartPC
;
1170 PtrCU
[NbCU
].HighPC
= PtrCU
[NbCU
].PtrUsedLinesSrc
[PtrCU
[NbCU
].NbUsedLinesSrc
- 1].StartPC
;
1176 // Init global variables information based on types information
1177 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1179 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1182 // Init local variables information based on types information
1183 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1185 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1187 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1198 // Conform slashes and backslashes
1199 void DWARFManager_ConformSlachesBackslashes(char *Ptr
)
1219 // Variables information initialisation
1220 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1222 size_t j
, TypeOffset
;
1224 #ifdef DEBUG_VariableName
1225 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1228 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1229 TypeOffset
= PtrVariables
->TypeOffset
;
1231 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1233 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1235 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1237 case DW_TAG_subroutine_type
:
1238 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1239 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1242 // Structure type tag
1243 case DW_TAG_structure_type
:
1244 PtrVariables
->TypeTag
|= TypeTag_structure
;
1245 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1247 if (PtrCU
[NbCU
].PtrTypes
[j
].PtrName
)
1249 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1252 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1258 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1260 strcat(PtrVariables
->PtrTypeName
, " *");
1266 case DW_TAG_pointer_type
:
1267 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1268 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1269 PtrVariables
->TypeEncoding
= 0x10;
1270 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1272 strcat(PtrVariables
->PtrTypeName
, "void *");
1280 case DW_TAG_enumeration_type
:
1281 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1282 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1283 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1285 // Try to determine the possible size
1286 switch (PtrVariables
->TypeByteSize
)
1289 PtrVariables
->TypeEncoding
= 0x7;
1299 case DW_TAG_typedef
:
1300 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1302 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1303 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1305 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1312 case DW_TAG_subrange_type
:
1313 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1317 case DW_TAG_array_type
:
1318 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1319 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1326 case DW_TAG_const_type
:
1327 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1328 strcat(PtrVariables
->PtrTypeName
, "const ");
1329 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1336 case DW_TAG_base_type
:
1337 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1339 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1341 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1343 strcat(PtrVariables
->PtrTypeName
, " *");
1347 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1348 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1350 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1352 strcat(PtrVariables
->PtrTypeName
, "[]");
1365 // Get symbol name based from address
1366 // Return NULL if no symbol name exists
1367 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1369 for (size_t i
= 0; i
< NbCU
; i
++)
1371 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1373 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1375 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1377 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1387 // Get complete source filename based from address
1388 // Return NULL if no source filename exists
1389 // Return the existence status (true or false) in Error
1390 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1392 for (size_t i
= 0; i
< NbCU
; i
++)
1394 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1396 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1397 return PtrCU
[i
].PtrFullFilename
;
1405 // Get text line source based on line number (starting from 1)
1406 // Return NULL if no text line exists or if line number is 0
1407 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1410 char *PtrLineSrc
= NULL
;
1414 while (i
!= NumLine
)
1416 PtrLineSrc
= PtrSrcFile
;
1417 while (*PtrSrcFile
++);
1426 // Get number of variables referenced by the function range address
1427 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1429 for (size_t i
= 0; i
< NbCU
; i
++)
1431 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1433 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1435 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1437 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1447 // Get local variable name based on his index (starting from 1)
1448 // Return name's pointer text found
1449 // Return NULL if not found
1450 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1452 for (size_t i
= 0; i
< NbCU
; i
++)
1454 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1456 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1458 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1460 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1470 // Get local variable's type tag based on his index (starting from 1)
1471 // Return 0 if not found
1472 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1474 for (size_t i
= 0; i
< NbCU
; i
++)
1476 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1478 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1480 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1482 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1492 // Get the local variable's offset based on a index (starting from 1)
1493 // Return 0 if no offset has been found
1494 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1496 for (size_t i
= 0; i
< NbCU
; i
++)
1498 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1500 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1502 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1504 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1514 // Get local variable Type Byte Size based on his address and index (starting from 1)
1515 // Return 0 if not found
1516 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1517 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1519 for (size_t i
= 0; i
< NbCU
; i
++)
1521 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1523 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1525 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1527 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1537 // Get local variable Type Encoding based on his address and index (starting from 1)
1538 // Return 0 if not found
1539 // May return 0 if there is no Type Encoding linked to the variable's address and index
1540 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1542 for (size_t i
= 0; i
< NbCU
; i
++)
1544 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1546 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1548 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1550 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1560 // Get local variable Op based on his address and index (starting from 1)
1561 // Return 0 if not found, may return 0 if there isn't Op linked to the variable's index
1562 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1564 for (size_t i
= 0; i
< NbCU
; i
++)
1566 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1568 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1570 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1572 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1582 // Get local variable type name based on his index (starting from 1) and an address
1583 // Return NULL if not found, may also return NULL if there is no type linked to the variable's index
1584 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1586 for (size_t i
= 0; i
< NbCU
; i
++)
1588 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1590 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1592 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1594 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1604 // Get Compilation Unit / global variables numbers
1605 // Return number of variables
1606 size_t DWARFManager_GetNbGlobalVariables(void)
1608 size_t NbVariables
= 0;
1610 for (size_t i
= 0; i
< NbCU
; i
++)
1612 NbVariables
+= PtrCU
[i
].NbVariables
;
1619 // Get global variable type name based on his index (starting from 1)
1620 // Return NULL if not found
1621 // May return NULL if there is not type linked to the variable's index
1622 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1624 for (size_t i
= 0; i
< NbCU
; i
++)
1626 if (PtrCU
[i
].NbVariables
)
1628 if (Index
<= PtrCU
[i
].NbVariables
)
1630 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1634 Index
-= PtrCU
[i
].NbVariables
;
1643 // Get global variable's type tag based on his index (starting from 1)
1644 // Return 0 if not found
1645 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1647 for (size_t i
= 0; i
< NbCU
; i
++)
1649 if (PtrCU
[i
].NbVariables
)
1651 if (Index
<= PtrCU
[i
].NbVariables
)
1653 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1657 Index
-= PtrCU
[i
].NbVariables
;
1666 // Get global variable byte size based on his index (starting from 1)
1667 // Return 0 if not found
1668 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1670 for (size_t i
= 0; i
< NbCU
; i
++)
1672 if (PtrCU
[i
].NbVariables
)
1674 if (Index
<= PtrCU
[i
].NbVariables
)
1676 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1680 Index
-= PtrCU
[i
].NbVariables
;
1689 // Get global variable encoding based on his index (starting from 1)
1690 // Return 0 if not found
1691 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1693 for (size_t i
= 0; i
< NbCU
; i
++)
1695 if (PtrCU
[i
].NbVariables
)
1697 if (Index
<= PtrCU
[i
].NbVariables
)
1699 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1703 Index
-= PtrCU
[i
].NbVariables
;
1712 // Get global variable memory address based on his index (starting from 1)
1713 // Return 0 if not found
1714 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1716 for (size_t i
= 0; i
< NbCU
; i
++)
1718 if (PtrCU
[i
].NbVariables
)
1720 if (Index
<= PtrCU
[i
].NbVariables
)
1722 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1726 Index
-= PtrCU
[i
].NbVariables
;
1735 // Get global variable memory address based on his name
1736 // Return 0 if not found, or will return the first occurence found
1737 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1739 for (size_t i
= 0; i
< NbCU
; i
++)
1741 if (PtrCU
[i
].NbVariables
)
1743 for (size_t j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1745 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1747 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1757 // Get global variable name based on his index (starting from 1)
1758 // Return name's pointer text found, or will return NULL if no variable can be found
1759 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1761 for (size_t i
= 0; i
< NbCU
; i
++)
1763 if (PtrCU
[i
].NbVariables
)
1765 if (Index
<= PtrCU
[i
].NbVariables
)
1767 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1771 Index
-= PtrCU
[i
].NbVariables
;
1780 // Get text line from source based on address and his tag
1781 // A tag can be either 0 or a DW_TAG_subprogram
1782 // DW_TAG_subprogram will look for the line pointing to the function
1783 // Return NULL if no text line has been found
1784 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1786 for (size_t i
= 0; i
< NbCU
; i
++)
1788 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1790 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1792 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1794 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1796 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1800 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1802 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1804 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1806 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1811 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1824 // Get line number based on the address and a tag
1825 // A tag can be either 0 or a DW_TAG_subprogram
1826 // DW_TAG_subprogram will look for the line pointing to the function name as described in the source code
1827 // Return 0 if no line number has been found
1828 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1830 for (size_t i
= 0; i
< NbCU
; i
++)
1832 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1834 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1836 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1838 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1840 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1844 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1846 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1848 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1853 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1855 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1861 // Check if a used line is found with the address
1862 for (size_t j
= 0; j
< PtrCU
[i
].NbUsedLinesSrc
; j
++)
1864 if (PtrCU
[i
].PtrUsedLinesSrc
[j
].StartPC
== Adr
)
1866 return PtrCU
[i
].PtrUsedLinesSrc
[j
].NumLineSrc
;
1876 // Get function name based on an address
1877 // Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address
1878 char *DWARFManager_GetFunctionName(size_t Adr
)
1880 for (size_t i
= 0; i
< NbCU
; i
++)
1882 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1884 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1886 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1888 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1898 // Get number of lines of texts source list from source index
1899 size_t DWARFManager_GetSrcNbListPtrFromIndex(size_t Index
, bool Used
)
1903 return PtrCU
[Index
].NbLinesLoadSrc
;
1907 return PtrCU
[Index
].NbUsedLinesSrc
;
1912 // Get text source line number list pointer from source index
1913 // Return NULL for the text source used list
1914 size_t *DWARFManager_GetSrcNumLinesPtrFromIndex(size_t Index
, bool Used
)
1918 return PtrCU
[Index
].PtrUsedNumLines
;
1927 // Get text source list pointers from source index
1928 // Return NULL for the text source used list
1929 char **DWARFManager_GetSrcListPtrFromIndex(size_t Index
, bool Used
)
1933 return PtrCU
[Index
].PtrLinesLoadSrc
;
1937 return PtrCU
[Index
].PtrUsedLinesLoadSrc
;
1942 // Get source language
1943 size_t DWARFManager_GetSrcLanguageFromIndex(size_t Index
)
1945 return PtrCU
[Index
].Language
;
1949 // Get text line from source based on address and num line (starting from 1)
1950 // Return NULL if no text line has been found
1951 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1953 for (size_t i
= 0; i
< NbCU
; i
++)
1955 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1957 for (size_t j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1959 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1961 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1963 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1967 for (size_t k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1969 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1971 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1984 // Get text line pointer from source, based on address and line number (starting from 1)
1985 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
1986 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1988 for (size_t i
= 0; i
< NbCU
; i
++)
1990 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1992 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1994 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
2007 // Get number of source code filenames
2008 size_t DWARFManager_GetNbSources(void)
2014 // Get source code filename, including his directory, based on index (starting from 0)
2015 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
2017 return (PtrCU
[Index
].PtrFullFilename
);
2021 // Get source code filename based on index (starting from 0)
2022 char *DWARFManager_GetNumSourceFilename(size_t Index
)
2024 return (PtrCU
[Index
].PtrSourceFilename
);