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 09/12/2018 Added LEB128 decoding features
13 // JPM 09/14/2018 Improve the DWARF parsing information
17 // To use pointers instead of arrays usage
31 //#define DEBUG_NumCU 0x9 // CU number to debug or undefine it
32 //#define DEBUG_VariableName "alloc" // 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 "cmd.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
;
289 // Initialisation for the Compilation Units table
293 // loop on the available Compilation Unit
294 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
296 // Allocation of an additional Compilation Unit structure in the table
297 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
299 // Compilation Unit RAZ
300 PtrCU
= (CUStruct
*)Ptr
;
301 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
305 if (NbCU
== DEBUG_NumCU
)
308 // Get 1st Die from the Compilation Unit
309 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
312 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
314 PtrCU
[NbCU
].Tag
= return_tagval
;
316 // Die type detection
317 switch (return_tagval
)
319 case DW_TAG_compile_unit
:
320 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
322 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
324 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
330 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
332 PtrCU
[NbCU
].LowPC
= return_lowpc
;
338 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
340 PtrCU
[NbCU
].HighPC
= return_highpc
;
344 // compilation information
346 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
348 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
349 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
350 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
356 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
358 #ifdef DEBUG_Filename
359 if (strstr(return_string
, DEBUG_Filename
))
362 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc((strlen(return_string
) + 1), 1);
363 strcpy(PtrCU
[NbCU
].PtrSourceFilename
, return_string
);
365 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
371 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
373 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc((strlen(return_string
) + 1), 1);
374 strcpy(PtrCU
[NbCU
].PtrSourceFileDirectory
, return_string
);
375 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
383 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
385 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
388 // Check filename validity
389 if (!PtrCU
[NbCU
].PtrSourceFilename
)
391 PtrCU
[NbCU
].PtrSourceFilename
= (char *)calloc(1, 1);
394 // Check directory validity
395 if (!PtrCU
[NbCU
].PtrSourceFileDirectory
)
397 PtrCU
[NbCU
].PtrSourceFileDirectory
= (char *)calloc(2, 1);
398 PtrCU
[NbCU
].PtrSourceFileDirectory
[0] = '.';
401 // Create full filename
402 Ptr
= PtrCU
[NbCU
].PtrFullFilename
= (char *)realloc(PtrCU
[NbCU
].PtrFullFilename
, strlen(PtrCU
[NbCU
].PtrSourceFilename
) + strlen(PtrCU
[NbCU
].PtrSourceFileDirectory
) + 2);
403 sprintf(PtrCU
[NbCU
].PtrFullFilename
, "%s\\%s", PtrCU
[NbCU
].PtrSourceFileDirectory
, PtrCU
[NbCU
].PtrSourceFilename
);
405 // Conform slashes and backslashes
422 // Directory path clean-up
424 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "\\..\\")))
426 while ((Ptr1
= Ptr
= strstr(PtrCU
[NbCU
].PtrFullFilename
, "/../")))
430 while (*--Ptr1
!= '\\');
432 while (*--Ptr1
!= '/');
434 strcpy((Ptr1
+ 1), (Ptr
+ 4));
437 // Read the file as text
439 if (!fopen_s(&SrcFile
, PtrCU
[NbCU
].PtrFullFilename
, "rt"))
441 if (!(SrcFile
= fopen(SourceFullFilename
, "rt")))
444 if (!fseek(SrcFile
, 0, SEEK_END
))
446 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
448 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)calloc((PtrCU
[NbCU
].SizeLoadSrc
+ 1), 1))
451 if (PtrCU
[NbCU
].SizeLoadSrc
< fread(Ptr
, 1, PtrCU
[NbCU
].SizeLoadSrc
, SrcFile
))
453 free(PtrCU
[NbCU
].PtrLoadSrc
);
454 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
455 PtrCU
[NbCU
].SizeLoadSrc
= 0;
463 PtrCU
[NbCU
].NbLinesLoadSrc
++;
480 // Get the source lines table located in the Compilation Unit
481 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
485 // Check if the CU has child
486 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
490 return_sib
= return_die
;
491 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
493 switch (return_tagval
)
495 case DW_TAG_lexical_block
:
498 case DW_TAG_variable
:
499 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
501 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
502 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
504 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
506 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
508 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
513 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
515 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
517 switch (return_block
->bl_len
)
520 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));
526 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
531 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
533 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
539 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
541 #ifdef DEBUG_VariableName
542 if (!strcmp(return_string
, DEBUG_VariableName
))
545 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
546 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
548 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
558 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
561 PtrCU
[NbCU
].NbVariables
++;
563 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
567 case DW_TAG_base_type
:
569 case DW_TAG_structure_type
:
570 case DW_TAG_pointer_type
:
571 case DW_TAG_const_type
:
572 case DW_TAG_array_type
:
573 case DW_TAG_subrange_type
:
574 case DW_TAG_subroutine_type
:
575 case DW_TAG_enumeration_type
:
576 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
578 // Allocate memory for this type
579 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
580 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
581 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
583 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
585 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
588 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
590 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
592 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
600 // Type's type offset
602 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
604 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
609 case DW_AT_byte_size
:
610 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
612 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
618 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
620 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
626 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
628 #ifdef DEBUG_TypeName
629 if (!strcmp(return_string
, DEBUG_TypeName
))
632 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
633 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
635 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
639 // Type's file number
640 case DW_AT_decl_file
:
643 // Type's line number
644 case DW_AT_decl_line
:
653 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
656 PtrCU
[NbCU
].NbTypes
++;
658 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
662 case DW_TAG_subprogram
:
663 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
665 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
666 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
667 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
669 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
671 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
673 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
679 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
681 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
682 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
688 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
690 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
695 case DW_AT_decl_line
:
696 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
698 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
703 case DW_AT_frame_base
:
704 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
706 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
707 PtrCU
[NbCU
].NbFrames
++;
713 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
715 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
716 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
717 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
724 case DW_AT_GNU_all_tail_call_sites
:
730 case DW_AT_prototyped
:
734 case DW_AT_decl_file
:
745 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
747 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
749 // Get source line number and associated block of address
750 for (i
= 0; i
< (size_t)cnt
; ++i
)
752 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
754 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
756 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
758 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
));
759 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
760 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
761 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
762 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
768 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
772 return_sub
= return_subdie
;
773 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
775 switch (return_tagval
)
777 case DW_TAG_formal_parameter
:
778 case DW_TAG_variable
:
779 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
781 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
)));
782 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
784 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
786 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
788 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
793 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
795 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
797 switch (return_block
->bl_len
)
804 switch (return_tagval
)
806 case DW_TAG_variable
:
807 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadLEB128((char *)return_block
->bl_data
+ 1);
810 case DW_TAG_formal_parameter
:
811 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= ReadULEB128((char *)return_block
->bl_data
+ 1);
822 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
827 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
829 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
834 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
836 #ifdef DEBUG_VariableName
837 if (!strcmp(return_string
, DEBUG_VariableName
))
840 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
841 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
843 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
847 case DW_AT_decl_file
:
850 case DW_AT_decl_line
:
859 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
862 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
864 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
876 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
879 PtrCU
[NbCU
].NbSubProgs
++;
888 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
891 // Release the memory used by the source lines
892 for (i
= 0; i
< (size_t)cnt
; ++i
)
894 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
896 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
899 // Set the source code lines for QT html/text conformity
900 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
902 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
904 for (j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
906 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
908 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
917 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
918 i
+= strlen(" ");
922 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
927 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
932 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
933 i
+= strlen("&");
938 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
939 i
+= strlen(""");
943 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
949 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], i
+ 1);
953 // Init lines source information based on each source code line numbers
954 for (j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
956 // Check if the subprog / function's line exists in the source code
957 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
959 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
962 for (k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
964 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
966 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
974 // Set each source lines pointer to NULL
975 if (PtrCU
[NbCU
].NbSubProgs
)
977 // Check the presence of source lines dedicated to the sub progs
978 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
980 i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
981 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
983 for (j
= 0; j
< i
; j
++)
985 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
992 // Init global variables information based on types information
993 for (i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
995 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
998 // Init local variables information based on types information
999 for (i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
1001 for (j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
1003 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
1014 // Variables information initialisation
1015 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
1017 size_t j
, TypeOffset
;
1019 #ifdef DEBUG_VariableName
1020 if (PtrVariables
->PtrName
&& !strcmp(PtrVariables
->PtrName
, DEBUG_VariableName
))
1023 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
1024 TypeOffset
= PtrVariables
->TypeOffset
;
1026 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
1028 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
1030 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
1032 case DW_TAG_subroutine_type
:
1033 PtrVariables
->TypeTag
|= TypeTag_subroutine_type
;
1034 strcat(PtrVariables
->PtrTypeName
, " (* ) ()");
1037 // Structure type tag
1038 case DW_TAG_structure_type
:
1039 PtrVariables
->TypeTag
|= TypeTag_structure
;
1040 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1042 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1044 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1050 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1052 strcat(PtrVariables
->PtrTypeName
, " *");
1058 case DW_TAG_pointer_type
:
1059 PtrVariables
->TypeTag
|= TypeTag_pointer
;
1060 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1061 PtrVariables
->TypeEncoding
= 0x10;
1062 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1064 strcat(PtrVariables
->PtrTypeName
, "void *");
1072 case DW_TAG_enumeration_type
:
1073 PtrVariables
->TypeTag
|= TypeTag_enumeration_type
;
1074 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1075 if (!(PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
))
1077 // Try to determine the possible size
1078 switch (PtrVariables
->TypeByteSize
)
1081 PtrVariables
->TypeEncoding
= 0x7;
1091 case DW_TAG_typedef
:
1092 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1094 PtrVariables
->TypeTag
|= TypeTag_typedef
;
1095 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1097 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1104 case DW_TAG_subrange_type
:
1105 PtrVariables
->TypeTag
|= TypeTag_subrange
;
1109 case DW_TAG_array_type
:
1110 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
1111 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1118 case DW_TAG_const_type
:
1119 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1120 strcat(PtrVariables
->PtrTypeName
, "const ");
1121 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1128 case DW_TAG_base_type
:
1129 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1131 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1133 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1135 strcat(PtrVariables
->PtrTypeName
, " *");
1139 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1140 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1142 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1144 strcat(PtrVariables
->PtrTypeName
, "[]");
1157 // Get symbol name based from address
1158 // Return NULL if no symbol name exists
1159 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1163 for (i
= 0; i
< NbCU
; i
++)
1165 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1167 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1169 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1171 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1181 // Get complete source filename based from address
1182 // Return NULL if no source filename exists
1183 // Return the existence status (true or false) in Error
1184 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1188 for (i
= 0; i
< NbCU
; i
++)
1190 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1192 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1193 return PtrCU
[i
].PtrFullFilename
;
1201 // Get text line source based on line number (starting by 1)
1202 // Return NULL if no text line exists or if line number is 0
1203 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1206 char *PtrLineSrc
= NULL
;
1210 while (i
!= NumLine
)
1212 PtrLineSrc
= PtrSrcFile
;
1213 while (*PtrSrcFile
++);
1222 // Get number of variables referenced by the function range address
1223 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1227 for (i
= 0; i
< NbCU
; i
++)
1229 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1231 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1233 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1235 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1245 // Get local variable name based on his index (starting by 1)
1246 // Return name's pointer text found
1247 // Return NULL if not found
1248 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1252 for (i
= 0; i
< NbCU
; i
++)
1254 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1256 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1258 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1260 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1270 // Get local variable's type tag based on his index (starting by 1)
1271 // Return 0 if not found
1272 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
1276 for (i
= 0; i
< NbCU
; i
++)
1278 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1280 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1282 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1284 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1295 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1299 for (i
= 0; i
< NbCU
; i
++)
1301 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1303 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1305 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1307 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1317 // Get local variable Type Byte Size based on his address and index (starting by 1)
1318 // Return 0 if not found
1319 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1320 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1324 for (i
= 0; i
< NbCU
; i
++)
1326 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1328 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1330 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1332 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1342 // Get local variable Type Encoding based on his address and index (starting by 1)
1343 // Return 0 if not found
1344 // May return 0 if there is no Type Encoding linked to the variable's address and index
1345 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1349 for (i
= 0; i
< NbCU
; i
++)
1351 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1353 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1355 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1357 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1367 // Get local variable Op based on his address and index (starting by 1)
1368 // Return 0 if not found
1369 // May return 0 if there isn't Op linked to the variable's index
1370 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1374 for (i
= 0; i
< NbCU
; i
++)
1376 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1378 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1380 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1382 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1392 // Get local variable type name based on his index (starting by 1)
1393 // Return NULL if not found
1394 // May return NULL if there is not type linked to the variable's index
1395 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1399 for (i
= 0; i
< NbCU
; i
++)
1401 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1403 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1405 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1407 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1417 // Get Compilation Unit / global variables numbers
1418 // Return variables number
1419 size_t DWARFManager_GetNbGlobalVariables(void)
1421 size_t NbVariables
= 0, i
;
1423 for (i
= 0; i
< NbCU
; i
++)
1425 NbVariables
+= PtrCU
[i
].NbVariables
;
1432 // Get global variable type name based on his index (starting by 1)
1433 // Return NULL if not found
1434 // May return NULL if there is not type linked to the variable's index
1435 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1439 for (i
= 0; i
< NbCU
; i
++)
1441 if (PtrCU
[i
].NbVariables
)
1443 if (Index
<= PtrCU
[i
].NbVariables
)
1445 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1449 Index
-= PtrCU
[i
].NbVariables
;
1458 // Get global variable's type tag based on his index (starting by 1)
1459 // Return 0 if not found
1460 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1464 for (i
= 0; i
< NbCU
; i
++)
1466 if (PtrCU
[i
].NbVariables
)
1468 if (Index
<= PtrCU
[i
].NbVariables
)
1470 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1474 Index
-= PtrCU
[i
].NbVariables
;
1483 // Get global variable byte size based on his index (starting by 1)
1484 // Return 0 if not found
1485 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1489 for (i
= 0; i
< NbCU
; i
++)
1491 if (PtrCU
[i
].NbVariables
)
1493 if (Index
<= PtrCU
[i
].NbVariables
)
1495 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1499 Index
-= PtrCU
[i
].NbVariables
;
1508 // Get global variable encoding based on his index (starting by 1)
1509 // Return 0 if not found
1510 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1514 for (i
= 0; i
< NbCU
; i
++)
1516 if (PtrCU
[i
].NbVariables
)
1518 if (Index
<= PtrCU
[i
].NbVariables
)
1520 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1524 Index
-= PtrCU
[i
].NbVariables
;
1533 // Get global variable address based on his index (starting by 1)
1534 // Return 0 if not found
1535 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1539 for (i
= 0; i
< NbCU
; i
++)
1541 if (PtrCU
[i
].NbVariables
)
1543 if (Index
<= PtrCU
[i
].NbVariables
)
1545 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1549 Index
-= PtrCU
[i
].NbVariables
;
1558 // Get global variable memory address based on his name
1559 // Return 0 if not found
1560 // Note: Return the first occurence found
1561 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1565 for (i
= 0; i
< NbCU
; i
++)
1567 if (PtrCU
[i
].NbVariables
)
1569 for (j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1571 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1573 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1583 // Get global variable name based on his index (starting by 1)
1584 // Return name's pointer text found
1585 // Return NULL if not found
1586 char *DWARFManager_GetGlobalVariableName(size_t Index
)
1590 for (i
= 0; i
< NbCU
; i
++)
1592 if (PtrCU
[i
].NbVariables
)
1594 if (Index
<= PtrCU
[i
].NbVariables
)
1596 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1600 Index
-= PtrCU
[i
].NbVariables
;
1609 // Get text line from source based on address and his tag
1610 // Return NULL if no text line has been found
1611 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1615 for (i
= 0; i
< NbCU
; i
++)
1617 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1619 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1621 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1623 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1625 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1629 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1631 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
<= Adr
)
1633 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1635 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1640 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
- 1].PtrLineSrc
;
1653 // Get line number based on the address and the tag
1654 // Return 0 if no line number has been found
1655 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1659 for (i
= 0; i
< NbCU
; i
++)
1661 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1663 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1665 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1667 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1669 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1673 for (k
= 0; (k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
); k
++)
1675 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1677 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1682 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1684 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1696 // Get function name based on address and his range
1697 // Return NULL if no function name has been found
1698 char *DWARFManager_GetFunctionName(size_t Adr
)
1702 for (i
= 0; i
< NbCU
; i
++)
1704 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1706 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1708 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1710 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1720 // Get text line from source based on address and num line (starting by 1)
1721 // Return NULL if no text line has been found
1722 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1726 for (i
= 0; i
< NbCU
; i
++)
1728 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1730 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1732 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1734 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1736 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1740 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1742 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1744 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1757 // Get text line from source based on address and num line (starting by 1)
1758 // Return NULL if no text line has been found
1759 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1763 for (i
= 0; i
< NbCU
; i
++)
1765 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1767 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1769 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];