2 // DWARFManager.cpp: DWARF format manager
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
9 // --- ---------- ------------------------------------------------------------
10 // JPM 12/03/2016 Created this file
11 // JPM 12/03/2016 DWARF format support
12 // JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information
13 // JPM 10/06/2018 Improve the DWARF parsing information, and the source file text reading
17 // To use pointers instead of arrays usage
31 //#define DEBUG_NumCU 0x9 // CU number to debug or undefine it
32 //#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it
33 //#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it
34 //#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)
35 //#define DEBUG_Filename "net_jag.c" // Filename to look for or undefine it
38 // Source line internal structure
39 typedef struct DMIStruct_LineSrc
47 // Enumeration structure
48 typedef struct EnumerationStruct
50 char *PtrName
; // Enumeration's name
51 size_t value
; // Enumeration's value
54 // Structure members structure
55 //typedef struct StructureMembersStruct
57 //}S_StructureMembersStruct;
59 // Base type internal structure
60 typedef struct BaseTypeStruct
62 size_t Tag
; // Type's Tag
63 size_t Offset
; // Type's offset
64 size_t TypeOffset
; // Type's offset on another type
65 size_t ByteSize
; // Type's Byte Size
66 size_t Encoding
; // Type's encoding
67 char *PtrName
; // Type's name
68 size_t NbEnumeration
; // Type's enumeration numbers
69 EnumerationStruct
*PtrEnumeration
; // Type's enumeration
70 // StructureMembersStruct *PtrStructureMembers; // Type's structure members
73 // Definitions for the variables's typetag
74 #define TypeTag_structure 0x01 // structure
75 #define TypeTag_pointer 0x02 // pointer
76 #define TypeTag_subrange 0x04 // (subrange_type?)
77 #define TypeTag_arraytype 0x08 // array type
78 #define TypeTag_consttype 0x10 // const type
79 #define TypeTag_typedef 0x20 // typedef
80 #define TypeTag_enumeration_type 0x40 // enumeration
81 #define TypeTag_subroutine_type 0x80 // subroutine
83 // Variables internal structure
84 typedef struct VariablesStruct
86 size_t Op
; // Variable's DW_OP
89 size_t Addr
; // Variable memory address
90 int Offset
; // Variable stack offset (signed)
92 char *PtrName
; // Variable's name
93 size_t TypeOffset
; // Offset pointing on the Variable's Type
94 size_t TypeByteSize
; // Variable's Type byte size
95 size_t TypeTag
; // Variable's Type Tag
96 size_t TypeEncoding
; // Variable's Type encoding
97 char *PtrTypeName
; // Variable's Type name
100 // Sub program internal structure
101 typedef struct SubProgStruct
106 size_t LowPC
, HighPC
;
109 char *PtrSubprogramName
; // Sub program name
110 size_t NbLinesSrc
; // Number of lines source used by the sub program
111 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
112 size_t NbVariables
; // Variables number
113 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
116 // Compilation Unit internal structure
117 typedef struct CUStruct
120 size_t LowPC
, HighPC
;
121 char *PtrProducer
; // Pointer to the "Producer" text information (mostly compiler and compilation options used)
122 char *PtrSourceFilename
; // Source file name
123 char *PtrSourceFileDirectory
; // Directory of the source file
124 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
125 size_t SizeLoadSrc
; // Source code size
126 char *PtrLoadSrc
; // Pointer to loaded source code
127 size_t NbLinesLoadSrc
; // Lines source number
128 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
129 size_t NbSubProgs
; // Number of sub programs / routines
130 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines information structure
131 size_t NbTypes
; // Number of types
132 BaseTypeStruct
*PtrTypes
; // Pointer to types
133 size_t NbVariables
; // Variables number
134 VariablesStruct
*PtrVariables
; // Pointer to the global variables list information structure
135 size_t NbFrames
; // Frames number
149 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
150 void DWARFManager_InitDMI(void);
151 void DWARFManager_CloseDMI(void);
152 bool DWARFManager_ElfClose(void);
153 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
154 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
158 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
164 // Dwarf manager init
165 void DWARFManager_Init(void)
167 LibDwarf
= DW_DLV_NO_ENTRY
;
171 // Dwarf manager Reset
172 bool DWARFManager_Reset(void)
174 return DWARFManager_ElfClose();
178 // Dwarf manager Close
179 bool DWARFManager_Close(void)
181 return(DWARFManager_Reset());
185 // Dwarf manager Elf init
186 int DWARFManager_ElfInit(Elf
*ElfPtr
)
188 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
190 DWARFManager_InitDMI();
197 // Dwarf manager Elf close
198 bool DWARFManager_ElfClose(void)
200 if (LibDwarf
== DW_DLV_OK
)
202 DWARFManager_CloseDMI();
204 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
206 LibDwarf
= DW_DLV_NO_ENTRY
;
221 // Dwarf manager Compilation Units close
222 void DWARFManager_CloseDMI(void)
226 free(PtrCU
[NbCU
].PtrFullFilename
);
227 free(PtrCU
[NbCU
].PtrLoadSrc
);
228 free(PtrCU
[NbCU
].PtrProducer
);
229 free(PtrCU
[NbCU
].PtrSourceFilename
);
230 free(PtrCU
[NbCU
].PtrSourceFileDirectory
);
232 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
234 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
236 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
238 while (PtrCU
[NbCU
].NbSubProgs
--)
240 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
242 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
243 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
245 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
247 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
248 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
250 free(PtrCU
[NbCU
].PtrSubProgs
);
252 while (PtrCU
[NbCU
].NbTypes
--)
254 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
256 free(PtrCU
[NbCU
].PtrTypes
);
258 while (PtrCU
[NbCU
].NbVariables
--)
260 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
261 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
263 free(PtrCU
[NbCU
].PtrVariables
);
270 // Dwarf manager Compilation Units initialisations
271 void DWARFManager_InitDMI(void)
273 Dwarf_Unsigned next_cu_header
, return_uvalue
;
275 Dwarf_Attribute
*atlist
;
276 Dwarf_Attribute return_attr1
;
277 Dwarf_Half return_tagval
, return_attr
;
278 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
279 Dwarf_Block
*return_block
;
280 Dwarf_Signed atcnt
, cnt
;
281 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
282 Dwarf_Off return_offset
;
288 // Initialisation for the Compilation Units table
292 // loop on the available Compilation Unit
293 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
295 // Allocation of an additional Compilation Unit structure in the table
296 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
298 // Compilation Unit RAZ
299 PtrCU
= (CUStruct
*)Ptr
;
300 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
304 if (NbCU
== DEBUG_NumCU
)
307 // Get 1st Die from the Compilation Unit
308 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
311 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
313 PtrCU
[NbCU
].Tag
= return_tagval
;
315 // Die type detection
316 switch (return_tagval
)
318 case DW_TAG_compile_unit
:
319 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
321 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
323 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
329 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
331 PtrCU
[NbCU
].LowPC
= return_lowpc
;
337 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
339 PtrCU
[NbCU
].HighPC
= return_highpc
;
343 // compilation information
345 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
347 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
348 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
349 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
355 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
357 #ifdef DEBUG_Filename
358 if (strstr(return_string
, DEBUG_Filename
))
361 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
362 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
364 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
370 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
372 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
373 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
374 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
382 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
384 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
387 // Check filename validity
388 if (!PtrCU
[NbCU
].PtrSourceFilename
)
390 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
393 // Check directory validity
394 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
396 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc(2, 1);
397 PtrCU
[NbCU
].PtrSourceFileDirectory
[0] = '.';
400 // Create full filename
401 Ptr
= PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
402 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
404 // Conform slashes and backslashes
421 // Directory path clean-up
423 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
425 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
429 while (*--Ptr1
!= '\\');
431 while (*--Ptr1
!= '/');
433 strcpy((Ptr1
+ 1), (Ptr
+ 4));
436 // Open the source file as a binary file
437 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rb"))
439 if (!fseek(SrcFile
, 0, SEEK_END
))
441 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
443 if (!fseek(SrcFile
, 0, SEEK_SET
))
445 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= Ptr1
= (char *)calloc(1, (PtrCU
[NbCU
].SizeLoadSrc
+ 2)))
448 if (fread_s(PtrCU
[NbCU
].PtrLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, PtrCU
[NbCU
].SizeLoadSrc
, 1, SrcFile
) != 1)
450 free(PtrCU
[NbCU
].PtrLoadSrc
);
451 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
452 PtrCU
[NbCU
].SizeLoadSrc
= 0;
456 // Eliminate all carriage return code '\r' (oxd)
459 if ((*Ptr
= *Ptr1
) != '\r')
466 // Get back the new text file size
467 PtrCU
[NbCU
].SizeLoadSrc
= strlen(Ptr
= PtrCU
[NbCU
].PtrLoadSrc
);
469 // Make sure the text file finish with a new line code '\n' (0xa)
470 if (PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
- 1] != '\n')
472 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
++] = '\n';
473 PtrCU
[NbCU
].PtrLoadSrc
[PtrCU
[NbCU
].SizeLoadSrc
] = 0;
476 // Reallocate text file
477 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)realloc(PtrCU
[NbCU
].PtrLoadSrc
, (PtrCU
[NbCU
].SizeLoadSrc
+ 1)))
479 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0
484 PtrCU
[NbCU
].NbLinesLoadSrc
++;
503 // Get the source lines table located in the CU
504 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
508 // Check if the CU has child
509 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
513 return_sib
= return_die
;
514 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
516 switch (return_tagval
)
518 case DW_TAG_lexical_block
:
521 case DW_TAG_variable
:
522 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
524 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
525 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
527 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
529 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
531 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
536 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
538 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
540 switch (return_block
->bl_len
)
543 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));
549 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
554 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
556 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
562 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
564 #ifdef DEBUG_VariableName
565 if (!strcmp(return_string
, DEBUG_VariableName
))
568 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
569 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
571 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
581 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
584 // Check variable's name validity
585 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
)
587 // Check variable's memory address validity
588 if (PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Addr
)
591 PtrCU
[NbCU
].NbVariables
++;
596 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
597 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= NULL
;
601 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
605 case DW_TAG_base_type
:
607 case DW_TAG_structure_type
:
608 case DW_TAG_pointer_type
:
609 case DW_TAG_const_type
:
610 case DW_TAG_array_type
:
611 case DW_TAG_subrange_type
:
612 case DW_TAG_subroutine_type
:
613 case DW_TAG_enumeration_type
:
614 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
616 // Allocate memory for this type
617 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
618 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
619 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
621 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
623 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
626 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
628 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
630 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
638 // Type's type offset
640 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
642 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
647 case DW_AT_byte_size
:
648 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
650 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
656 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
658 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
664 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
666 #ifdef DEBUG_TypeName
667 if (!strcmp(return_string
, DEBUG_TypeName
))
670 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
671 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
673 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
677 // Type's file number
678 case DW_AT_decl_file
:
681 // Type's line number
682 case DW_AT_decl_line
:
691 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
694 PtrCU
[NbCU
].NbTypes
++;
696 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
700 case DW_TAG_subprogram
:
701 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
703 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
704 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
705 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
707 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
709 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
711 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
717 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
719 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
720 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
726 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
728 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
733 case DW_AT_decl_line
:
734 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
736 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
741 case DW_AT_frame_base
:
742 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
744 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
745 PtrCU
[NbCU
].NbFrames
++;
751 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
753 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
754 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
755 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
762 case DW_AT_GNU_all_tail_call_sites
:
768 case DW_AT_prototyped
:
772 case DW_AT_decl_file
:
783 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
785 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
787 // Get source line number and associated block of address
788 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
790 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
792 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
794 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
796 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
));
797 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
798 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
799 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
800 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
806 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
810 return_sub
= return_subdie
;
811 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
813 switch (return_tagval
)
815 case DW_TAG_formal_parameter
:
816 case DW_TAG_variable
:
817 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
819 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
)));
820 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
822 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
824 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
826 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
831 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
833 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
835 switch (return_block
->bl_len
)
842 switch (return_tagval
)
844 case DW_TAG_variable
:
845 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
848 case DW_TAG_formal_parameter
:
849 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
860 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
865 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
867 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
872 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
874 #ifdef DEBUG_VariableName
875 if (!strcmp(return_string
, DEBUG_VariableName
))
878 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
879 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
881 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
885 case DW_AT_decl_file
:
888 case DW_AT_decl_line
:
897 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
900 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
902 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
914 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
917 PtrCU
[NbCU
].NbSubProgs
++;
926 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
929 // Release the memory used by the source lines
930 for (Dwarf_Signed i
= 0; i
< cnt
; ++i
)
932 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
934 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
937 // Set the source code lines for QT html/text conformity
938 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
940 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
942 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
944 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
946 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
955 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
960 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
965 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
970 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
971 i
+= strlen("&");
976 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
977 i
+= strlen(""");
981 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
987 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], strlen(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
]) + 1);
991 // Init lines source information based on each source code line numbers
992 for (size_t j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
994 // Check if the subprog / function's line exists in the source code
995 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
997 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
1000 for (size_t k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1002 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
1004 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
1012 // Set each source lines pointer to NULL
1013 if (PtrCU
[NbCU
].NbSubProgs
)
1015 // Check the presence of source lines dedicated to the sub progs
1016 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
1018 size_t i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
1019 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
1021 for (size_t j
= 0; j
< i
; j
++)
1023 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
1030 // Init global variables information based on types information
1031 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
1033 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
1036 // Init local variables information based on types information
1037 for (size_t i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1039 for (size_t j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1041 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1052 // Variables information initialisation
1053 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1055 size_t j
, TypeOffset
;
1057 #ifdef DEBUG_VariableName
1058 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1061 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1062 TypeOffset
= PtrVariables
->TypeOffset
;
1064 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1066 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1068 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1070 case DW_TAG_subroutine_type
:
1071 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1072 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1075 // Structure type tag
1076 case DW_TAG_structure_type
:
1077 PtrVariables
->TypeTag
|= TypeTag_structure
;
1078 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1080 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1082 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1088 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1090 strcat(PtrVariables
->PtrTypeName
, " *");
1096 case DW_TAG_pointer_type
:
1097 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1098 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1099 PtrVariables
->TypeEncoding
= 0x10;
1100 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1102 strcat(PtrVariables
->PtrTypeName
, "void *");
1110 case DW_TAG_enumeration_type
:
1111 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1112 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1113 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1115 // Try to determine the possible size
1116 switch (PtrVariables
->TypeByteSize
)
1119 PtrVariables
->TypeEncoding
= 0x7;
1129 case DW_TAG_typedef
:
1130 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1132 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1133 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1135 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1142 case DW_TAG_subrange_type
:
1143 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1147 case DW_TAG_array_type
:
1148 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1149 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1156 case DW_TAG_const_type
:
1157 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1158 strcat(PtrVariables
->PtrTypeName
, "const ");
1159 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1166 case DW_TAG_base_type
:
1167 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1169 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1171 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1173 strcat(PtrVariables
->PtrTypeName
, " *");
1177 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1178 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1180 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1182 strcat(PtrVariables
->PtrTypeName
, "[]");
1195 // Get symbol name based from address
1196 // Return NULL if no symbol name exists
1197 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1201 for (i
= 0; i
< NbCU
; i
++)
1203 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1205 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1207 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1209 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1219 // Get complete source filename based from address
1220 // Return NULL if no source filename exists
1221 // Return the existence status (true or false) in Error
1222 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1226 for (i
= 0; i
< NbCU
; i
++)
1228 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1230 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1231 return PtrCU
[i
].PtrFullFilename
;
1239 // Get text line source based on line number (starting by 1)
1240 // Return NULL if no text line exists or if line number is 0
1241 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1244 char *PtrLineSrc
= NULL
;
1248 while (i
!= NumLine
)
1250 PtrLineSrc
= PtrSrcFile
;
1251 while (*PtrSrcFile
++);
1260 // Get number of variables referenced by the function range address
1261 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1265 for (i
= 0; i
< NbCU
; i
++)
1267 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1269 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1271 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1273 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1283 // Get local variable name based on his index (starting by 1)
1284 // Return name's pointer text found
1285 // Return NULL if not found
1286 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1290 for (i
= 0; i
< NbCU
; i
++)
1292 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1294 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1296 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1298 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1308 // Get local variable's type tag based on his index (starting by 1)
1309 // Return 0 if not found
1310 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1314 for (i
= 0; i
< NbCU
; i
++)
1316 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1318 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1320 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1322 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1333 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1337 for (i
= 0; i
< NbCU
; i
++)
1339 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1341 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1343 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1345 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1355 // Get local variable Type Byte Size based on his address and index (starting by 1)
1356 // Return 0 if not found
1357 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1358 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1362 for (i
= 0; i
< NbCU
; i
++)
1364 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1366 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1368 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1370 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1380 // Get local variable Type Encoding based on his address and index (starting by 1)
1381 // Return 0 if not found
1382 // May return 0 if there is no Type Encoding linked to the variable's address and index
1383 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1387 for (i
= 0; i
< NbCU
; i
++)
1389 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1391 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1393 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1395 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1405 // Get local variable Op based on his address and index (starting by 1)
1406 // Return 0 if not found
1407 // May return 0 if there isn't Op linked to the variable's index
1408 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1412 for (i
= 0; i
< NbCU
; i
++)
1414 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1416 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1418 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1420 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1430 // Get local variable type name based on his index (starting by 1)
1431 // Return NULL if not found
1432 // May return NULL if there is not type linked to the variable's index
1433 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1437 for (i
= 0; i
< NbCU
; i
++)
1439 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1441 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1443 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1445 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1455 // Get Compilation Unit / global variables numbers
1456 // Return variables number
1457 size_t DWARFManager_GetNbGlobalVariables(void)
1459 size_t NbVariables
= 0, i
;
1461 for (i
= 0; i
< NbCU
; i
++)
1463 NbVariables
+= PtrCU
[i
].NbVariables
;
1470 // Get global variable type name based on his index (starting by 1)
1471 // Return NULL if not found
1472 // May return NULL if there is not type linked to the variable's index
1473 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1477 for (i
= 0; i
< NbCU
; i
++)
1479 if (PtrCU
[i
].NbVariables
)
1481 if (Index
<= PtrCU
[i
].NbVariables
)
1483 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1487 Index
-= PtrCU
[i
].NbVariables
;
1496 // Get global variable's type tag based on his index (starting by 1)
1497 // Return 0 if not found
1498 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1502 for (i
= 0; i
< NbCU
; i
++)
1504 if (PtrCU
[i
].NbVariables
)
1506 if (Index
<= PtrCU
[i
].NbVariables
)
1508 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1512 Index
-= PtrCU
[i
].NbVariables
;
1521 // Get global variable byte size based on his index (starting by 1)
1522 // Return 0 if not found
1523 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1527 for (i
= 0; i
< NbCU
; i
++)
1529 if (PtrCU
[i
].NbVariables
)
1531 if (Index
<= PtrCU
[i
].NbVariables
)
1533 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1537 Index
-= PtrCU
[i
].NbVariables
;
1546 // Get global variable encoding based on his index (starting by 1)
1547 // Return 0 if not found
1548 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1552 for (i
= 0; i
< NbCU
; i
++)
1554 if (PtrCU
[i
].NbVariables
)
1556 if (Index
<= PtrCU
[i
].NbVariables
)
1558 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1562 Index
-= PtrCU
[i
].NbVariables
;
1571 // Get global variable address based on his index (starting by 1)
1572 // Return 0 if not found
1573 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1577 for (i
= 0; i
< NbCU
; i
++)
1579 if (PtrCU
[i
].NbVariables
)
1581 if (Index
<= PtrCU
[i
].NbVariables
)
1583 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1587 Index
-= PtrCU
[i
].NbVariables
;
1596 // Get global variable memory address based on his name
1597 // Return 0 if not found
1598 // Note: Return the first occurence found
1599 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1603 for (i
= 0; i
< NbCU
; i
++)
1605 if (PtrCU
[i
].NbVariables
)
1607 for (j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1609 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1611 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1621 // Get global variable name based on his index (starting by 1)
1622 // Return name's pointer text found
1623 // Return NULL if not found
1624 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1628 for (i
= 0; i
< NbCU
; i
++)
1630 if (PtrCU
[i
].NbVariables
)
1632 if (Index
<= PtrCU
[i
].NbVariables
)
1634 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1638 Index
-= PtrCU
[i
].NbVariables
;
1647 // Get text line from source based on address and his tag
1648 // Return NULL if no text line has been found
1649 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1653 for (i
= 0; i
< NbCU
; i
++)
1655 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1657 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1659 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1661 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1663 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1667 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1669 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1671 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1673 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1678 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1691 // Get line number based on the address and the tag
1692 // Return 0 if no line number has been found
1693 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1697 for (i
= 0; i
< NbCU
; i
++)
1699 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1701 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1703 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1705 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1707 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1711 for (k
= 0; (k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
); k
++)
1713 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1715 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1720 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1722 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1734 // Get function name based on address and his range
1735 // Return NULL if no function name has been found
1736 char *DWARFManager_GetFunctionName(size_t Adr
)
1740 for (i
= 0; i
< NbCU
; i
++)
1742 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1744 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1746 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1748 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1758 // Get text line from source based on address and num line (starting by 1)
1759 // Return NULL if no text line has been found
1760 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1764 for (i
= 0; i
< NbCU
; i
++)
1766 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1768 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1770 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1772 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1774 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1778 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1780 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1782 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1795 // Get text line pointer from source, based on address and line number (starting by 1)
1796 // Return NULL if no text line has been found, or if requested number line is above the source total number of lines
1797 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1801 for (i
= 0; i
< NbCU
; i
++)
1803 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1805 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1807 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];
1820 // Get number of source code filenames
1821 size_t DWARFManager_GetNbFullSourceFilename(void)
1827 // Get source code filename based on index
1828 char *DWARFManager_GetNumFullSourceFilename(size_t Index
)
1830 return (PtrCU
[Index
].PtrFullFilename
);