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
22 // Source line internal structure
23 struct DMIStruct_LineSrc
31 // Base type internal structure
34 size_t Tag
; // Type's Tag
35 size_t Offset
; // Type's offset
36 size_t TypeOffset
; // Type's offset on another type
37 size_t ByteSize
; // Type's Byte Size
38 size_t Encoding
; // Type's encoding
39 char *PtrName
; // Type's name
42 // Variables internal structure
43 struct VariablesStruct
45 size_t Addr
; // Variable memory address
46 char *PtrName
; // Variable's name
47 size_t TypeOffset
; // Offset pointing on the Variable's Type
48 size_t TypeByteSize
; // Variable's Type byte size
49 size_t TypeTag
; // Variable's Type Tag
50 size_t TypeEncoding
; // Variable's Type encoding
51 char *PtrTypeName
; // Variable's Type name
54 // Sub program internal structure
62 char *PtrSubprogramName
;
64 DMIStruct_LineSrc
*PtrLinesSrc
;
67 // Compilation Unit internal structure
72 char *PtrProducer
; // Pointer to the "Producer" information (compiler and compilation options used)
73 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
74 size_t SizeLoadSrc
; // Source code size
75 char *PtrLoadSrc
; // Pointer to loaded source code
76 size_t NbLinesLoadSrc
; // Lines source number
77 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
78 size_t NbSubProgs
; // Number of sub programs / routines
79 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines information structure
81 BaseTypeStruct
*PtrTypes
;
82 size_t NbVariables
; // Variables number
83 VariablesStruct
*PtrVariables
; // Pointer to the variables list information structure
97 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
98 void DWARFManager_InitDMI(void);
99 void DWARFManager_CloseDMI(void);
100 bool DWARFManager_ElfClose(void);
101 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
105 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
111 // Dwarf manager init
112 void DWARFManager_Init(void)
114 LibDwarf
= DW_DLV_NO_ENTRY
;
118 // Dwarf manager Reset
119 bool DWARFManager_Reset(void)
121 return DWARFManager_ElfClose();
125 // Dwarf manager Close
126 bool DWARFManager_Close(void)
128 return(DWARFManager_Reset());
132 // Dwarf manager Elf init
133 int DWARFManager_ElfInit(Elf
*ElfPtr
)
135 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
137 DWARFManager_InitDMI();
144 // Dwarf manager Elf close
145 bool DWARFManager_ElfClose(void)
147 if (LibDwarf
== DW_DLV_OK
)
149 DWARFManager_CloseDMI();
151 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
153 LibDwarf
= DW_DLV_NO_ENTRY
;
168 // Dwarf manager Compilation Units close
169 void DWARFManager_CloseDMI(void)
173 free(PtrCU
[NbCU
].PtrFullFilename
);
174 free(PtrCU
[NbCU
].PtrLoadSrc
);
175 free(PtrCU
[NbCU
].PtrProducer
);
177 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
179 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
181 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
183 while (PtrCU
[NbCU
].NbSubProgs
--)
185 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
186 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
188 free(PtrCU
[NbCU
].PtrSubProgs
);
190 while (PtrCU
[NbCU
].NbTypes
--)
192 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
194 free(PtrCU
[NbCU
].PtrTypes
);
196 while (PtrCU
[NbCU
].NbVariables
--)
198 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
199 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
201 free(PtrCU
[NbCU
].PtrVariables
);
208 // Dwarf manager Compilation Units initialisations
209 void DWARFManager_InitDMI(void)
211 Dwarf_Unsigned next_cu_header
, return_uvalue
;
213 Dwarf_Attribute
*atlist
;
214 Dwarf_Attribute return_attr1
;
215 Dwarf_Half return_tagval
, return_attr
;
216 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
217 Dwarf_Block
*return_block
;
218 Dwarf_Signed atcnt
, cnt
;
219 Dwarf_Die return_sib
, return_die
;
220 Dwarf_Off return_offset
;
223 size_t i
, j
, k
, TypeOffset
;
226 char *SourceFilename
= NULL
;
227 char *SourceFileDirectory
= NULL
;
228 char *SourceFullFilename
= NULL
;
230 // Initialisation for the Compilation Units table
234 // loop on the available Compilation Unit
235 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
237 // Allocation of an additional Compilation Unit structure in the table
238 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
240 // Compilation Unit RAZ
241 PtrCU
= (CUStruct
*)Ptr
;
242 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
244 // Get 1st Die from the Compilation Unit
245 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
248 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
250 PtrCU
[NbCU
].Tag
= return_tagval
;
252 // Die type detection
253 switch (return_tagval
)
255 case DW_TAG_compile_unit
:
256 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
258 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
260 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
265 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
267 PtrCU
[NbCU
].LowPC
= return_lowpc
;
272 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
274 PtrCU
[NbCU
].HighPC
= return_highpc
;
279 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
281 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
282 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
283 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
288 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
290 SourceFilename
= (char *)realloc(SourceFilename
, strlen(return_string
) + 1);
291 strcpy(SourceFilename
, return_string
);
292 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
297 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
299 SourceFileDirectory
= (char *)realloc(SourceFileDirectory
, strlen(return_string
) + 1);
300 strcpy(SourceFileDirectory
, return_string
);
301 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
309 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
311 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
314 Ptr
= SourceFullFilename
= (char *)realloc(SourceFullFilename
, strlen(SourceFilename
) + strlen(SourceFileDirectory
) + 2);
315 sprintf(SourceFullFilename
, "%s\\%s", SourceFileDirectory
, SourceFilename
);
324 PtrCU
[NbCU
].PtrFullFilename
= (char *)calloc(strlen(SourceFullFilename
) + 1, 1);
325 strcpy((char *)PtrCU
[NbCU
].PtrFullFilename
, SourceFullFilename
);
328 if (!fopen_s(&SrcFile
, SourceFullFilename
, "rt"))
330 if (!(SrcFile
= fopen(SourceFullFilename
, "rt")))
333 if (!fseek(SrcFile
, 0, SEEK_END
))
335 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
337 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)calloc((PtrCU
[NbCU
].SizeLoadSrc
+ 1), 1))
340 if (PtrCU
[NbCU
].SizeLoadSrc
< fread(Ptr
, 1, PtrCU
[NbCU
].SizeLoadSrc
, SrcFile
))
342 free(PtrCU
[NbCU
].PtrLoadSrc
);
343 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
344 PtrCU
[NbCU
].SizeLoadSrc
= 0;
352 PtrCU
[NbCU
].NbLinesLoadSrc
++;
369 // Get the source lines table located in the Compilation Unit
370 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
374 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
378 return_sib
= return_die
;
379 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
381 switch (return_tagval
)
383 case DW_TAG_lexical_block
:
386 case DW_TAG_variable
:
387 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
389 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
390 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
392 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
394 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
396 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
401 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
403 if (return_block
->bl_len
== 5)
405 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));
407 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
412 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
414 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
419 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
421 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
422 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
423 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
433 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
436 PtrCU
[NbCU
].NbVariables
++;
438 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
442 case DW_TAG_base_type
:
444 case DW_TAG_structure_type
:
445 case DW_TAG_pointer_type
:
446 case DW_TAG_const_type
:
447 case DW_TAG_array_type
:
448 case DW_TAG_subrange_type
:
449 case DW_TAG_subroutine_type
:
450 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
452 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
453 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
454 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
456 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
458 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
461 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
463 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
465 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
470 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
472 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
476 case DW_AT_byte_size
:
477 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
479 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
484 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
486 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
491 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
493 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
494 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
495 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
505 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
508 PtrCU
[NbCU
].NbTypes
++;
510 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
514 case DW_TAG_subprogram
:
515 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
517 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
518 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
519 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
521 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
523 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
525 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
530 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
532 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
533 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
538 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
540 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
544 case DW_AT_decl_line
:
545 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
547 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
552 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
554 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
555 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
556 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
565 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
567 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
569 for (i
= 0; i
< (size_t)cnt
; ++i
)
571 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
573 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
575 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
577 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
));
578 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
579 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
580 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
581 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
587 PtrCU
[NbCU
].NbSubProgs
++;
596 while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
599 // Release the memory used by the source lines
600 for (i
= 0; i
< (size_t)cnt
; ++i
)
601 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
602 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
605 // Set the source code lines for QT html/text conformity
606 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
608 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
610 for (j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
612 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
614 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
623 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
624 i
+= strlen(" ");
628 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
633 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
638 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
639 i
+= strlen("&");
644 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
645 i
+= strlen(""");
649 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
655 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], i
+ 1);
662 // Set each source lines pointer to NULL
663 if (PtrCU
[NbCU
].NbSubProgs
)
665 i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
666 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
668 for (j
= 0; j
< i
; j
++)
670 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
676 // Init lines source information based on each source code line numbers
677 for (j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
679 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
681 for (k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
683 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
687 // Init variables information based on types information
688 for (i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
690 PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
= (char *)calloc(1000, 1);
691 TypeOffset
= PtrCU
[NbCU
].PtrVariables
[i
].TypeOffset
;
693 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
695 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
697 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
699 case DW_TAG_structure_type
:
700 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x1;
701 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
707 if ((PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
& 0x2))
709 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, " *");
714 case DW_TAG_pointer_type
:
715 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x2;
716 PtrCU
[NbCU
].PtrVariables
[i
].TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
717 PtrCU
[NbCU
].PtrVariables
[i
].TypeEncoding
= 0x10;
718 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
720 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, "void *");
729 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x20;
730 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
731 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
737 case DW_TAG_subrange_type
:
738 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x4;
741 case DW_TAG_array_type
:
742 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x8;
743 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
749 case DW_TAG_const_type
:
750 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x10;
751 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, "const ");
752 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
758 case DW_TAG_base_type
:
759 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
760 if ((PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
& 0x2))
762 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, " *");
766 PtrCU
[NbCU
].PtrVariables
[i
].TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
767 PtrCU
[NbCU
].PtrVariables
[i
].TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
769 if ((PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
& 0x8))
771 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, "[]");
786 free(SourceFilename
);
787 free(SourceFileDirectory
);
788 free(SourceFullFilename
);
792 // Get symbol name based from address
793 // Return NULL if no symbol name exists
794 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
798 for (i
= 0; i
< NbCU
; i
++)
800 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
802 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
804 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
806 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
816 // Get complete source filename based from address
817 // Return NULL if no source filename exists
818 // Return the existence status (true or false) in Error
819 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
823 for (i
= 0; i
< NbCU
; i
++)
825 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
827 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
828 return PtrCU
[i
].PtrFullFilename
;
836 // Get text line source based on line number (starting by 1)
837 // Return NULL if no text line exists or if line number is 0
838 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
841 char *PtrLineSrc
= NULL
;
847 PtrLineSrc
= PtrSrcFile
;
848 while (*PtrSrcFile
++);
857 // Get Compilation Unit / External variables numbers
858 // Return variables number
859 size_t DWARFManager_GetNbExternalVariables(void)
861 size_t NbVariables
= 0, i
;
863 for (i
= 0; i
< NbCU
; i
++)
865 NbVariables
+= PtrCU
[i
].NbVariables
;
872 // Get external variable type name based on his index (starting by 1)
873 // Return NULL if not found
874 // May return NULL if there is not type linked to the variable's index
875 char *DWARFManager_GetExternalVariableTypeName(size_t Index
)
879 for (i
= 0; i
< NbCU
; i
++)
881 if (PtrCU
[i
].NbVariables
)
883 if (Index
<= PtrCU
[i
].NbVariables
)
885 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
889 Index
-= PtrCU
[i
].NbVariables
;
898 // Get external variable's type tag based on his index (starting by 1)
899 // Return 0 if not found
900 size_t DWARFManager_GetExternalVariableTypeTag(size_t Index
)
904 for (i
= 0; i
< NbCU
; i
++)
906 if (PtrCU
[i
].NbVariables
)
908 if (Index
<= PtrCU
[i
].NbVariables
)
910 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
914 Index
-= PtrCU
[i
].NbVariables
;
923 // Get external variable byte size based on his index (starting by 1)
924 // Return 0 if not found
925 size_t DWARFManager_GetExternalVariableTypeByteSize(size_t Index
)
929 for (i
= 0; i
< NbCU
; i
++)
931 if (PtrCU
[i
].NbVariables
)
933 if (Index
<= PtrCU
[i
].NbVariables
)
935 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
939 Index
-= PtrCU
[i
].NbVariables
;
948 // Get external variable encoding based on his index (starting by 1)
949 // Return 0 if not found
950 size_t DWARFManager_GetExternalVariableTypeEncoding(size_t Index
)
954 for (i
= 0; i
< NbCU
; i
++)
956 if (PtrCU
[i
].NbVariables
)
958 if (Index
<= PtrCU
[i
].NbVariables
)
960 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
964 Index
-= PtrCU
[i
].NbVariables
;
973 // Get external variable address based on his index (starting by 1)
974 // Return 0 if not found
975 size_t DWARFManager_GetExternalVariableAdr(size_t Index
)
979 for (i
= 0; i
< NbCU
; i
++)
981 if (PtrCU
[i
].NbVariables
)
983 if (Index
<= PtrCU
[i
].NbVariables
)
985 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
989 Index
-= PtrCU
[i
].NbVariables
;
998 // Get external variable memory address based on his name
999 // Return 0 if not found
1000 // Note: Return the first occurence found
1001 size_t DWARFManager_GetExternalVariableAdrFromName(char *VariableName
)
1005 for (i
= 0; i
< NbCU
; i
++)
1007 if (PtrCU
[i
].NbVariables
)
1009 for (j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1011 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1013 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1023 // Get external variable name based on his index (starting by 1)
1024 // Return name's pointer text found
1025 // Return NULL if not found
1026 char *DWARFManager_GetExternalVariableName(size_t Index
)
1030 for (i
= 0; i
< NbCU
; i
++)
1032 if (PtrCU
[i
].NbVariables
)
1034 if (Index
<= PtrCU
[i
].NbVariables
)
1036 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1040 Index
-= PtrCU
[i
].NbVariables
;
1049 // Get text line from source based on address and his tag
1050 // Return NULL if no text line has been found
1051 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1055 for (i
= 0; i
< NbCU
; i
++)
1057 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1059 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1061 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1063 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1065 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1069 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1071 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1073 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1086 // Get line number based on the address and the tag
1087 // Return 0 if no line number has been found
1088 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1092 for (i
= 0; i
< NbCU
; i
++)
1094 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1096 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1098 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1100 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1102 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1106 for (k
= 0; (k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
); k
++)
1108 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1110 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1115 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1117 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1129 // Get text line from source based on address and num line (starting by 1)
1130 // Return NULL if no text line has been found
1131 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1135 for (i
= 0; i
< NbCU
; i
++)
1137 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1139 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1141 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1143 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1145 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1149 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1151 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1153 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1166 // Get text line from source based on address and num line (starting by 1)
1167 // Return NULL if no text line has been found
1168 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1172 for (i
= 0; i
< NbCU
; i
++)
1174 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1176 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];