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
23 //#define DEBUG_NumCU 0x6 // CU number to debug or undefine it
24 //#define DEBUG_VariableName "argc" // Variable name to look for or undefine it
27 // Source line internal structure
28 struct DMIStruct_LineSrc
36 // Base type internal structure
39 size_t Tag
; // Type's Tag
40 size_t Offset
; // Type's offset
41 size_t TypeOffset
; // Type's offset on another type
42 size_t ByteSize
; // Type's Byte Size
43 size_t Encoding
; // Type's encoding
44 char *PtrName
; // Type's name
47 // Definitions for the variables's typetag
48 #define TypeTag_structure 0x01 // structure
49 #define TypeTag_pointer 0x02 // pointer
50 #define TypeTag_0x04 0x04
51 #define TypeTag_arraytype 0x08 // array type
52 #define TypeTag_consttype 0x10 // const type
53 #define TypeTag_typedef 0x20 // typedef
55 // Variables internal structure
56 struct VariablesStruct
58 size_t Op
; // Variable's DW_OP
61 size_t Addr
; // Variable memory address
62 int Offset
; // Variable stack offset (signed)
64 char *PtrName
; // Variable's name
65 size_t TypeOffset
; // Offset pointing on the Variable's Type
66 size_t TypeByteSize
; // Variable's Type byte size
67 size_t TypeTag
; // Variable's Type Tag
68 size_t TypeEncoding
; // Variable's Type encoding
69 char *PtrTypeName
; // Variable's Type name
72 // Sub program internal structure
81 char *PtrSubprogramName
; // Sub program name
82 size_t NbLinesSrc
; // Number of lines source used by the sub program
83 DMIStruct_LineSrc
*PtrLinesSrc
; // Pointer of the lines source for the sub program
84 size_t NbVariables
; // Variables number
85 VariablesStruct
*PtrVariables
; // Pointer to the local variables list information structure
88 // Compilation Unit internal structure
93 char *PtrProducer
; // Pointer to the "Producer" information (compiler and compilation options used)
94 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
95 size_t SizeLoadSrc
; // Source code size
96 char *PtrLoadSrc
; // Pointer to loaded source code
97 size_t NbLinesLoadSrc
; // Lines source number
98 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
99 size_t NbSubProgs
; // Number of sub programs / routines
100 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines information structure
102 BaseTypeStruct
*PtrTypes
;
103 size_t NbVariables
; // Variables number
104 VariablesStruct
*PtrVariables
; // Pointer to the global variables list information structure
105 size_t NbFrames
; // Frames number
119 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
120 void DWARFManager_InitDMI(void);
121 void DWARFManager_CloseDMI(void);
122 bool DWARFManager_ElfClose(void);
123 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
124 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
);
128 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
134 // Dwarf manager init
135 void DWARFManager_Init(void)
137 LibDwarf
= DW_DLV_NO_ENTRY
;
141 // Dwarf manager Reset
142 bool DWARFManager_Reset(void)
144 return DWARFManager_ElfClose();
148 // Dwarf manager Close
149 bool DWARFManager_Close(void)
151 return(DWARFManager_Reset());
155 // Dwarf manager Elf init
156 int DWARFManager_ElfInit(Elf
*ElfPtr
)
158 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
160 DWARFManager_InitDMI();
167 // Dwarf manager Elf close
168 bool DWARFManager_ElfClose(void)
170 if (LibDwarf
== DW_DLV_OK
)
172 DWARFManager_CloseDMI();
174 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
176 LibDwarf
= DW_DLV_NO_ENTRY
;
191 // Dwarf manager Compilation Units close
192 void DWARFManager_CloseDMI(void)
196 free(PtrCU
[NbCU
].PtrFullFilename
);
197 free(PtrCU
[NbCU
].PtrLoadSrc
);
198 free(PtrCU
[NbCU
].PtrProducer
);
200 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
202 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
204 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
206 while (PtrCU
[NbCU
].NbSubProgs
--)
208 while (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
--)
210 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
);
211 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrTypeName
);
213 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
);
215 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
216 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
218 free(PtrCU
[NbCU
].PtrSubProgs
);
220 while (PtrCU
[NbCU
].NbTypes
--)
222 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
224 free(PtrCU
[NbCU
].PtrTypes
);
226 while (PtrCU
[NbCU
].NbVariables
--)
228 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
229 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
231 free(PtrCU
[NbCU
].PtrVariables
);
238 // Dwarf manager Compilation Units initialisations
239 void DWARFManager_InitDMI(void)
241 Dwarf_Unsigned next_cu_header
, return_uvalue
;
243 Dwarf_Attribute
*atlist
;
244 Dwarf_Attribute return_attr1
;
245 Dwarf_Half return_tagval
, return_attr
;
246 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
247 Dwarf_Block
*return_block
;
248 Dwarf_Signed atcnt
, cnt
;
249 Dwarf_Die return_sib
, return_die
, return_sub
, return_subdie
;
250 Dwarf_Off return_offset
;
256 char *SourceFilename
= NULL
;
257 char *SourceFileDirectory
= NULL
;
258 char *SourceFullFilename
= NULL
;
260 // Initialisation for the Compilation Units table
264 // loop on the available Compilation Unit
265 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
267 // Allocation of an additional Compilation Unit structure in the table
268 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
270 // Compilation Unit RAZ
271 PtrCU
= (CUStruct
*)Ptr
;
272 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
276 if (NbCU
== DEBUG_NumCU
)
279 // Get 1st Die from the Compilation Unit
280 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
283 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
285 PtrCU
[NbCU
].Tag
= return_tagval
;
287 // Die type detection
288 switch (return_tagval
)
290 case DW_TAG_compile_unit
:
291 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
293 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
295 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
301 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
303 PtrCU
[NbCU
].LowPC
= return_lowpc
;
309 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
311 PtrCU
[NbCU
].HighPC
= return_highpc
;
315 // compilation information
317 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
319 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
320 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
321 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
327 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
329 SourceFilename
= (char *)realloc(SourceFilename
, strlen(return_string
) + 1);
330 strcpy(SourceFilename
, return_string
);
331 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
337 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
339 SourceFileDirectory
= (char *)realloc(SourceFileDirectory
, strlen(return_string
) + 1);
340 strcpy(SourceFileDirectory
, return_string
);
341 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
349 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
351 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
354 Ptr
= SourceFullFilename
= (char *)realloc(SourceFullFilename
, strlen(SourceFilename
) + strlen(SourceFileDirectory
) + 2);
356 sprintf(SourceFullFilename
, "%s\\%s", SourceFileDirectory
, SourceFilename
);
358 sprintf(SourceFullFilename
, "%s/%s", SourceFileDirectory
, SourceFilename
);
375 PtrCU
[NbCU
].PtrFullFilename
= (char *)calloc(strlen(SourceFullFilename
) + 1, 1);
376 strcpy((char *)PtrCU
[NbCU
].PtrFullFilename
, SourceFullFilename
);
379 if (!fopen_s(&SrcFile
, SourceFullFilename
, "rt"))
381 if (!(SrcFile
= fopen(SourceFullFilename
, "rt")))
384 if (!fseek(SrcFile
, 0, SEEK_END
))
386 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
388 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)calloc((PtrCU
[NbCU
].SizeLoadSrc
+ 1), 1))
391 if (PtrCU
[NbCU
].SizeLoadSrc
< fread(Ptr
, 1, PtrCU
[NbCU
].SizeLoadSrc
, SrcFile
))
393 free(PtrCU
[NbCU
].PtrLoadSrc
);
394 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
395 PtrCU
[NbCU
].SizeLoadSrc
= 0;
403 PtrCU
[NbCU
].NbLinesLoadSrc
++;
420 // Get the source lines table located in the Compilation Unit
421 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
425 // Check if the CU has child
426 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
430 return_sib
= return_die
;
431 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
433 switch (return_tagval
)
435 case DW_TAG_lexical_block
:
438 case DW_TAG_variable
:
439 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
441 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
442 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
444 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
446 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
448 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
453 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
455 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].Op
= (*((unsigned char *)(return_block
->bl_data
)));
457 switch (return_block
->bl_len
)
460 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));
466 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
471 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
473 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
479 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
481 #ifdef DEBUG_VariableName
482 if (!strcmp(return_string
, DEBUG_VariableName
))
485 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
486 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
487 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
498 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
501 PtrCU
[NbCU
].NbVariables
++;
503 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
507 case DW_TAG_base_type
:
509 case DW_TAG_structure_type
:
510 case DW_TAG_pointer_type
:
511 case DW_TAG_const_type
:
512 case DW_TAG_array_type
:
513 case DW_TAG_subrange_type
:
514 case DW_TAG_subroutine_type
:
515 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
517 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
518 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
519 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
521 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
523 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
526 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
528 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
530 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
535 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
537 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
541 case DW_AT_byte_size
:
542 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
544 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
549 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
551 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
556 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
558 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
559 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
560 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
570 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
573 PtrCU
[NbCU
].NbTypes
++;
575 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
579 case DW_TAG_subprogram
:
580 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
582 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
583 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
584 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
586 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
588 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
590 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
596 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
598 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
599 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
605 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
607 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
612 case DW_AT_decl_line
:
613 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
615 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
620 case DW_AT_frame_base
:
621 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
623 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].FrameBase
= return_uvalue
;
624 PtrCU
[NbCU
].NbFrames
++;
630 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
632 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
633 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
634 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
641 case DW_AT_GNU_all_tail_call_sites
:
647 case DW_AT_prototyped
:
651 case DW_AT_decl_file
:
662 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
664 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
666 for (i
= 0; i
< (size_t)cnt
; ++i
)
668 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
670 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
672 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
674 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
));
675 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
676 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
677 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
678 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
684 if (dwarf_child(return_die
, &return_subdie
, &error
) == DW_DLV_OK
)
688 return_sub
= return_subdie
;
689 if ((dwarf_tag(return_subdie
, &return_tagval
, &error
) == DW_DLV_OK
))
691 switch (return_tagval
)
693 case DW_TAG_formal_parameter
:
694 case DW_TAG_variable
:
695 if (dwarf_attrlist(return_subdie
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
697 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
)));
698 memset(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
, 0, sizeof(VariablesStruct
));
700 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
702 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
704 if (dwarf_attr(return_subdie
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
709 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
711 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Op
= *((unsigned char *)(return_block
->bl_data
));
713 switch (return_block
->bl_len
)
719 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
= *((char *)(return_block
->bl_data
) + 1);
721 switch (return_tagval
)
723 case DW_TAG_variable
:
724 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].Offset
-= 0x80;
727 case DW_TAG_formal_parameter
:
737 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
742 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
744 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].TypeOffset
= return_offset
;
749 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
751 #ifdef DEBUG_VariableName
752 if (!strcmp(return_string
, DEBUG_VariableName
))
755 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
756 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrVariables
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
].PtrName
, return_string
);
757 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
762 case DW_AT_decl_file
:
765 case DW_AT_decl_line
:
774 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
777 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbVariables
++;
779 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
791 while (dwarf_siblingof(dbg
, return_sub
, &return_subdie
, &error
) == DW_DLV_OK
);
794 PtrCU
[NbCU
].NbSubProgs
++;
803 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
806 // Release the memory used by the source lines
807 for (i
= 0; i
< (size_t)cnt
; ++i
)
809 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
811 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
814 // Set the source code lines for QT html/text conformity
815 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
817 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
819 for (j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
821 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
823 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
832 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
833 i
+= strlen(" ");
837 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
842 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
847 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
848 i
+= strlen("&");
853 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
854 i
+= strlen(""");
858 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
864 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], i
+ 1);
868 // Init lines source information based on each source code line numbers
869 for (j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
871 // Check if the subprog / function's line exists in the source code
872 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
874 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
877 for (k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
879 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
881 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
889 // Set each source lines pointer to NULL
890 if (PtrCU
[NbCU
].NbSubProgs
)
892 // Check the presence of source lines dedicated to the sub progs
893 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
895 i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
896 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
898 for (j
= 0; j
< i
; j
++)
900 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
907 // Init global variables information based on types information
908 for (i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
910 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrVariables
+ i
);
913 // Init local variables information based on types information
914 for (i
= 0; i
< PtrCU
[NbCU
].NbSubProgs
; i
++)
916 for (j
= 0; j
< PtrCU
[NbCU
].PtrSubProgs
[i
].NbVariables
; j
++)
918 DWARFManager_InitInfosVariable(PtrCU
[NbCU
].PtrSubProgs
[i
].PtrVariables
+ j
);
927 free(SourceFilename
);
928 free(SourceFileDirectory
);
929 free(SourceFullFilename
);
933 // Variables information initialisation
934 void DWARFManager_InitInfosVariable(VariablesStruct
*PtrVariables
)
936 size_t j
, TypeOffset
;
938 PtrVariables
->PtrTypeName
= (char *)calloc(1000, 1);
939 TypeOffset
= PtrVariables
->TypeOffset
;
941 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
943 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
945 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
947 // Structure type tag
948 case DW_TAG_structure_type
:
949 PtrVariables
->TypeTag
|= TypeTag_structure
;
950 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
956 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
958 strcat(PtrVariables
->PtrTypeName
, " *");
964 case DW_TAG_pointer_type
:
965 PtrVariables
->TypeTag
|= TypeTag_pointer
;
966 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
967 PtrVariables
->TypeEncoding
= 0x10;
968 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
970 strcat(PtrVariables
->PtrTypeName
, "void *");
980 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
982 PtrVariables
->TypeTag
|= TypeTag_typedef
;
983 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
985 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
992 case DW_TAG_subrange_type
:
993 PtrVariables
->TypeTag
|= TypeTag_0x04
;
997 case DW_TAG_array_type
:
998 PtrVariables
->TypeTag
|= TypeTag_arraytype
;
999 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1006 case DW_TAG_const_type
:
1007 PtrVariables
->TypeTag
|= TypeTag_consttype
;
1008 strcat(PtrVariables
->PtrTypeName
, "const ");
1009 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
1016 case DW_TAG_base_type
:
1017 if (!(PtrVariables
->TypeTag
& TypeTag_typedef
))
1019 strcat(PtrVariables
->PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
1021 if ((PtrVariables
->TypeTag
& TypeTag_pointer
))
1023 strcat(PtrVariables
->PtrTypeName
, " *");
1027 PtrVariables
->TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
1028 PtrVariables
->TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
1030 if ((PtrVariables
->TypeTag
& TypeTag_arraytype
))
1032 strcat(PtrVariables
->PtrTypeName
, "[]");
1044 // Get symbol name based from address
1045 // Return NULL if no symbol name exists
1046 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
1050 for (i
= 0; i
< NbCU
; i
++)
1052 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1054 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1056 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
1058 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1068 // Get complete source filename based from address
1069 // Return NULL if no source filename exists
1070 // Return the existence status (true or false) in Error
1071 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
1075 for (i
= 0; i
< NbCU
; i
++)
1077 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1079 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
1080 return PtrCU
[i
].PtrFullFilename
;
1088 // Get text line source based on line number (starting by 1)
1089 // Return NULL if no text line exists or if line number is 0
1090 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
1093 char *PtrLineSrc
= NULL
;
1097 while (i
!= NumLine
)
1099 PtrLineSrc
= PtrSrcFile
;
1100 while (*PtrSrcFile
++);
1109 // Get number of variables referenced by the function range address
1110 size_t DWARFManager_GetNbLocalVariables(size_t Adr
)
1114 for (i
= 0; i
< NbCU
; i
++)
1116 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1118 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1120 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1122 return PtrCU
[i
].PtrSubProgs
[j
].NbVariables
;
1132 // Get local variable name based on his index (starting by 1)
1133 // Return name's pointer text found
1134 // Return NULL if not found
1135 char *DWARFManager_GetLocalVariableName(size_t Adr
, size_t Index
)
1139 for (i
= 0; i
< NbCU
; i
++)
1141 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1143 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1145 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1147 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrName
;
1157 // Get local variable's type tag based on his index (starting by 1)
1158 // Return 0 if not found
1159 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr
, size_t Index
)
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 ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1171 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeTag
;
1182 int DWARFManager_GetLocalVariableOffset(size_t Adr
, size_t Index
)
1186 for (i
= 0; i
< NbCU
; i
++)
1188 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1190 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1192 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1194 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Offset
;
1204 // Get local variable Type Byte Size based on his address and index (starting by 1)
1205 // Return 0 if not found
1206 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1207 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr
, size_t Index
)
1211 for (i
= 0; i
< NbCU
; i
++)
1213 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1215 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1217 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1219 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeByteSize
;
1229 // Get local variable Type Encoding based on his address and index (starting by 1)
1230 // Return 0 if not found
1231 // May return 0 if there is no Type Encoding linked to the variable's address and index
1232 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr
, size_t Index
)
1236 for (i
= 0; i
< NbCU
; i
++)
1238 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1240 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1242 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1244 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].TypeEncoding
;
1254 // Get local variable Op based on his address and index (starting by 1)
1255 // Return 0 if not found
1256 // May return 0 if there isn't Op linked to the variable's index
1257 size_t DWARFManager_GetLocalVariableOp(size_t Adr
, size_t Index
)
1261 for (i
= 0; i
< NbCU
; i
++)
1263 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1265 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1267 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1269 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].Op
;
1279 // Get local variable type name based on his index (starting by 1)
1280 // Return NULL if not found
1281 // May return NULL if there is not type linked to the variable's index
1282 char *DWARFManager_GetLocalVariableTypeName(size_t Adr
, size_t Index
)
1286 for (i
= 0; i
< NbCU
; i
++)
1288 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1290 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1292 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1294 return PtrCU
[i
].PtrSubProgs
[j
].PtrVariables
[Index
- 1].PtrTypeName
;
1304 // Get Compilation Unit / global variables numbers
1305 // Return variables number
1306 size_t DWARFManager_GetNbGlobalVariables(void)
1308 size_t NbVariables
= 0, i
;
1310 for (i
= 0; i
< NbCU
; i
++)
1312 NbVariables
+= PtrCU
[i
].NbVariables
;
1319 // Get global variable type name based on his index (starting by 1)
1320 // Return NULL if not found
1321 // May return NULL if there is not type linked to the variable's index
1322 char *DWARFManager_GetGlobalVariableTypeName(size_t Index
)
1326 for (i
= 0; i
< NbCU
; i
++)
1328 if (PtrCU
[i
].NbVariables
)
1330 if (Index
<= PtrCU
[i
].NbVariables
)
1332 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
1336 Index
-= PtrCU
[i
].NbVariables
;
1345 // Get global variable's type tag based on his index (starting by 1)
1346 // Return 0 if not found
1347 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index
)
1351 for (i
= 0; i
< NbCU
; i
++)
1353 if (PtrCU
[i
].NbVariables
)
1355 if (Index
<= PtrCU
[i
].NbVariables
)
1357 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
1361 Index
-= PtrCU
[i
].NbVariables
;
1370 // Get global variable byte size based on his index (starting by 1)
1371 // Return 0 if not found
1372 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index
)
1376 for (i
= 0; i
< NbCU
; i
++)
1378 if (PtrCU
[i
].NbVariables
)
1380 if (Index
<= PtrCU
[i
].NbVariables
)
1382 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
1386 Index
-= PtrCU
[i
].NbVariables
;
1395 // Get global variable encoding based on his index (starting by 1)
1396 // Return 0 if not found
1397 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index
)
1401 for (i
= 0; i
< NbCU
; i
++)
1403 if (PtrCU
[i
].NbVariables
)
1405 if (Index
<= PtrCU
[i
].NbVariables
)
1407 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
1411 Index
-= PtrCU
[i
].NbVariables
;
1420 // Get global variable address based on his index (starting by 1)
1421 // Return 0 if not found
1422 size_t DWARFManager_GetGlobalVariableAdr(size_t Index
)
1426 for (i
= 0; i
< NbCU
; i
++)
1428 if (PtrCU
[i
].NbVariables
)
1430 if (Index
<= PtrCU
[i
].NbVariables
)
1432 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1436 Index
-= PtrCU
[i
].NbVariables
;
1445 // Get global variable memory address based on his name
1446 // Return 0 if not found
1447 // Note: Return the first occurence found
1448 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName
)
1452 for (i
= 0; i
< NbCU
; i
++)
1454 if (PtrCU
[i
].NbVariables
)
1456 for (j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1458 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1460 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1470 // Get global variable name based on his index (starting by 1)
1471 // Return name's pointer text found
1472 // Return NULL if not found
1473 char *DWARFManager_GetGlobalVariableName(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].PtrName
;
1487 Index
-= PtrCU
[i
].NbVariables
;
1496 // Get text line from source based on address and his tag
1497 // Return NULL if no text line has been found
1498 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1502 for (i
= 0; i
< NbCU
; i
++)
1504 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1506 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1508 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1510 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1512 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1516 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1518 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1520 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1533 // Get line number based on the address and the tag
1534 // Return 0 if no line number has been found
1535 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1539 for (i
= 0; i
< NbCU
; i
++)
1541 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1543 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1545 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1547 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1549 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1553 for (k
= 0; (k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
); k
++)
1555 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1557 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1562 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1564 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1576 // Get function name based on address and his range
1577 // Return NULL if no function name has been found
1578 char *DWARFManager_GetFunctionName(size_t Adr
)
1582 for (i
= 0; i
< NbCU
; i
++)
1584 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1586 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1588 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1590 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
1600 // Get text line from source based on address and num line (starting by 1)
1601 // Return NULL if no text line has been found
1602 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1606 for (i
= 0; i
< NbCU
; i
++)
1608 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1610 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1612 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1614 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1616 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1620 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1622 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1624 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1637 // Get text line from source based on address and num line (starting by 1)
1638 // Return NULL if no text line has been found
1639 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1643 for (i
= 0; i
< NbCU
; i
++)
1645 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1647 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1649 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];