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
26 // Source line internal structure
27 struct DMIStruct_LineSrc
35 // Base type internal structure
38 size_t Tag
; // Type's Tag
39 size_t Offset
; // Type's offset
40 size_t TypeOffset
; // Type's offset on another type
41 size_t ByteSize
; // Type's Byte Size
42 size_t Encoding
; // Type's encoding
43 char *PtrName
; // Type's name
46 // Variables internal structure
47 struct VariablesStruct
49 size_t Addr
; // Variable memory address
50 char *PtrName
; // Variable's name
51 size_t TypeOffset
; // Offset pointing on the Variable's Type
52 size_t TypeByteSize
; // Variable's Type byte size
53 size_t TypeTag
; // Variable's Type Tag
54 size_t TypeEncoding
; // Variable's Type encoding
55 char *PtrTypeName
; // Variable's Type name
58 // Sub program internal structure
66 char *PtrSubprogramName
;
68 DMIStruct_LineSrc
*PtrLinesSrc
;
71 // Compilation Unit internal structure
76 char *PtrProducer
; // Pointer to the "Producer" information (compiler and compilation options used)
77 char *PtrFullFilename
; // Pointer to full namefile (directory & filename)
78 size_t SizeLoadSrc
; // Source code size
79 char *PtrLoadSrc
; // Pointer to loaded source code
80 size_t NbLinesLoadSrc
; // Lines source number
81 char **PtrLinesLoadSrc
; // Pointer lists to each source line put in QT html/text conformity
82 size_t NbSubProgs
; // Number of sub programs / routines
83 SubProgStruct
*PtrSubProgs
; // Pointer to the sub programs / routines information structure
85 BaseTypeStruct
*PtrTypes
;
86 size_t NbVariables
; // Variables number
87 VariablesStruct
*PtrVariables
; // Pointer to the variables list information structure
101 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
);
102 void DWARFManager_InitDMI(void);
103 void DWARFManager_CloseDMI(void);
104 bool DWARFManager_ElfClose(void);
105 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
);
109 Dwarf_Handler
DWARFManager_ErrorHandler(Dwarf_Ptr perrarg
)
115 // Dwarf manager init
116 void DWARFManager_Init(void)
118 LibDwarf
= DW_DLV_NO_ENTRY
;
122 // Dwarf manager Reset
123 bool DWARFManager_Reset(void)
125 return DWARFManager_ElfClose();
129 // Dwarf manager Close
130 bool DWARFManager_Close(void)
132 return(DWARFManager_Reset());
136 // Dwarf manager Elf init
137 int DWARFManager_ElfInit(Elf
*ElfPtr
)
139 if ((LibDwarf
= dwarf_elf_init(ElfPtr
, DW_DLC_READ
, (Dwarf_Handler
)DWARFManager_ErrorHandler
, errarg
, &dbg
, &error
)) == DW_DLV_OK
)
141 DWARFManager_InitDMI();
148 // Dwarf manager Elf close
149 bool DWARFManager_ElfClose(void)
151 if (LibDwarf
== DW_DLV_OK
)
153 DWARFManager_CloseDMI();
155 if (dwarf_finish(dbg
, &error
) == DW_DLV_OK
)
157 LibDwarf
= DW_DLV_NO_ENTRY
;
172 // Dwarf manager Compilation Units close
173 void DWARFManager_CloseDMI(void)
177 free(PtrCU
[NbCU
].PtrFullFilename
);
178 free(PtrCU
[NbCU
].PtrLoadSrc
);
179 free(PtrCU
[NbCU
].PtrProducer
);
181 while (PtrCU
[NbCU
].NbLinesLoadSrc
--)
183 free(PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].NbLinesLoadSrc
]);
185 free(PtrCU
[NbCU
].PtrLinesLoadSrc
);
187 while (PtrCU
[NbCU
].NbSubProgs
--)
189 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
);
190 free(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
);
192 free(PtrCU
[NbCU
].PtrSubProgs
);
194 while (PtrCU
[NbCU
].NbTypes
--)
196 free(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
);
198 free(PtrCU
[NbCU
].PtrTypes
);
200 while (PtrCU
[NbCU
].NbVariables
--)
202 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
);
203 free(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrTypeName
);
205 free(PtrCU
[NbCU
].PtrVariables
);
212 // Dwarf manager Compilation Units initialisations
213 void DWARFManager_InitDMI(void)
215 Dwarf_Unsigned next_cu_header
, return_uvalue
;
217 Dwarf_Attribute
*atlist
;
218 Dwarf_Attribute return_attr1
;
219 Dwarf_Half return_tagval
, return_attr
;
220 Dwarf_Addr return_lowpc
, return_highpc
, return_lineaddr
;
221 Dwarf_Block
*return_block
;
222 Dwarf_Signed atcnt
, cnt
;
223 Dwarf_Die return_sib
, return_die
;
224 Dwarf_Off return_offset
;
227 size_t i
, j
, k
, TypeOffset
;
230 char *SourceFilename
= NULL
;
231 char *SourceFileDirectory
= NULL
;
232 char *SourceFullFilename
= NULL
;
234 // Initialisation for the Compilation Units table
238 // loop on the available Compilation Unit
239 while (dwarf_next_cu_header(dbg
, NULL
, NULL
, NULL
, NULL
, &next_cu_header
, &error
) == DW_DLV_OK
)
241 // Allocation of an additional Compilation Unit structure in the table
242 if (Ptr
= (char *)realloc(PtrCU
, ((NbCU
+ 1) * sizeof(CUStruct
))))
244 // Compilation Unit RAZ
245 PtrCU
= (CUStruct
*)Ptr
;
246 memset(PtrCU
+ NbCU
, 0, sizeof(CUStruct
));
250 if (NbCU
== DEBUG_NumCU
)
253 // Get 1st Die from the Compilation Unit
254 if (dwarf_siblingof(dbg
, NULL
, &return_sib
, &error
) == DW_DLV_OK
)
257 if ((dwarf_tag(return_sib
, &return_tagval
, &error
) == DW_DLV_OK
))
259 PtrCU
[NbCU
].Tag
= return_tagval
;
261 // Die type detection
262 switch (return_tagval
)
264 case DW_TAG_compile_unit
:
265 if (dwarf_attrlist(return_sib
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
267 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
269 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
274 if (dwarf_lowpc(return_sib
, &return_lowpc
, &error
) == DW_DLV_OK
)
276 PtrCU
[NbCU
].LowPC
= return_lowpc
;
281 if (dwarf_highpc(return_sib
, &return_highpc
, &error
) == DW_DLV_OK
)
283 PtrCU
[NbCU
].HighPC
= return_highpc
;
288 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
290 PtrCU
[NbCU
].PtrProducer
= (char *)calloc(strlen(return_string
) + 1, 1);
291 strcpy(PtrCU
[NbCU
].PtrProducer
, return_string
);
292 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
297 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
299 SourceFilename
= (char *)realloc(SourceFilename
, strlen(return_string
) + 1);
300 strcpy(SourceFilename
, return_string
);
301 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
306 if (dwarf_formstring(atlist
[i
], &return_string
, &error
) == DW_DLV_OK
)
308 SourceFileDirectory
= (char *)realloc(SourceFileDirectory
, strlen(return_string
) + 1);
309 strcpy(SourceFileDirectory
, return_string
);
310 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
318 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
320 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
323 Ptr
= SourceFullFilename
= (char *)realloc(SourceFullFilename
, strlen(SourceFilename
) + strlen(SourceFileDirectory
) + 2);
324 sprintf(SourceFullFilename
, "%s\\%s", SourceFileDirectory
, SourceFilename
);
333 PtrCU
[NbCU
].PtrFullFilename
= (char *)calloc(strlen(SourceFullFilename
) + 1, 1);
334 strcpy((char *)PtrCU
[NbCU
].PtrFullFilename
, SourceFullFilename
);
337 if (!fopen_s(&SrcFile
, SourceFullFilename
, "rt"))
339 if (!(SrcFile
= fopen(SourceFullFilename
, "rt")))
342 if (!fseek(SrcFile
, 0, SEEK_END
))
344 if ((PtrCU
[NbCU
].SizeLoadSrc
= ftell(SrcFile
)) > 0)
346 if (PtrCU
[NbCU
].PtrLoadSrc
= Ptr
= (char *)calloc((PtrCU
[NbCU
].SizeLoadSrc
+ 1), 1))
349 if (PtrCU
[NbCU
].SizeLoadSrc
< fread(Ptr
, 1, PtrCU
[NbCU
].SizeLoadSrc
, SrcFile
))
351 free(PtrCU
[NbCU
].PtrLoadSrc
);
352 PtrCU
[NbCU
].PtrLoadSrc
= NULL
;
353 PtrCU
[NbCU
].SizeLoadSrc
= 0;
361 PtrCU
[NbCU
].NbLinesLoadSrc
++;
378 // Get the source lines table located in the Compilation Unit
379 if (dwarf_srclines(return_sib
, &linebuf
, &cnt
, &error
) == DW_DLV_OK
)
383 if (dwarf_child(return_sib
, &return_die
, &error
) == DW_DLV_OK
)
387 return_sib
= return_die
;
388 if ((dwarf_tag(return_die
, &return_tagval
, &error
) == DW_DLV_OK
))
390 switch (return_tagval
)
392 case DW_TAG_lexical_block
:
395 case DW_TAG_variable
:
396 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
398 PtrCU
[NbCU
].PtrVariables
= (VariablesStruct
*)realloc(PtrCU
[NbCU
].PtrVariables
, ((PtrCU
[NbCU
].NbVariables
+ 1) * sizeof(VariablesStruct
)));
399 memset(PtrCU
[NbCU
].PtrVariables
+ PtrCU
[NbCU
].NbVariables
, 0, sizeof(VariablesStruct
));
401 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
403 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
405 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
410 if (dwarf_formblock(return_attr1
, &return_block
, &error
) == DW_DLV_OK
)
412 if (return_block
->bl_len
== 5)
414 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));
416 dwarf_dealloc(dbg
, return_block
, DW_DLA_BLOCK
);
421 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
423 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].TypeOffset
= return_offset
;
428 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
430 PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
431 strcpy(PtrCU
[NbCU
].PtrVariables
[PtrCU
[NbCU
].NbVariables
].PtrName
, return_string
);
432 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
442 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
445 PtrCU
[NbCU
].NbVariables
++;
447 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
451 case DW_TAG_base_type
:
453 case DW_TAG_structure_type
:
454 case DW_TAG_pointer_type
:
455 case DW_TAG_const_type
:
456 case DW_TAG_array_type
:
457 case DW_TAG_subrange_type
:
458 case DW_TAG_subroutine_type
:
459 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
461 PtrCU
[NbCU
].PtrTypes
= (BaseTypeStruct
*)realloc(PtrCU
[NbCU
].PtrTypes
, ((PtrCU
[NbCU
].NbTypes
+ 1) * sizeof(BaseTypeStruct
)));
462 memset(PtrCU
[NbCU
].PtrTypes
+ PtrCU
[NbCU
].NbTypes
, 0, sizeof(BaseTypeStruct
));
463 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Tag
= return_tagval
;
465 if (dwarf_dieoffset(return_die
, &return_offset
, &error
) == DW_DLV_OK
)
467 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Offset
= return_offset
;
470 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
472 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
474 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
479 if (dwarf_global_formref(return_attr1
, &return_offset
, &error
) == DW_DLV_OK
)
481 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].TypeOffset
= return_offset
;
485 case DW_AT_byte_size
:
486 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
488 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].ByteSize
= return_uvalue
;
493 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
495 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].Encoding
= return_uvalue
;
500 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
502 PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
= (char *)calloc(strlen(return_string
) + 1, 1);
503 strcpy(PtrCU
[NbCU
].PtrTypes
[PtrCU
[NbCU
].NbTypes
].PtrName
, return_string
);
504 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
514 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
517 PtrCU
[NbCU
].NbTypes
++;
519 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
523 case DW_TAG_subprogram
:
524 if (dwarf_attrlist(return_die
, &atlist
, &atcnt
, &error
) == DW_DLV_OK
)
526 PtrCU
[NbCU
].PtrSubProgs
= (SubProgStruct
*)realloc(PtrCU
[NbCU
].PtrSubProgs
, ((PtrCU
[NbCU
].NbSubProgs
+ 1) * sizeof(SubProgStruct
)));
527 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
+ PtrCU
[NbCU
].NbSubProgs
), 0, sizeof(SubProgStruct
));
528 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].Tag
= return_tagval
;
530 for (Dwarf_Signed i
= 0; i
< atcnt
; ++i
)
532 if (dwarf_whatattr(atlist
[i
], &return_attr
, &error
) == DW_DLV_OK
)
534 if (dwarf_attr(return_die
, return_attr
, &return_attr1
, &error
) == DW_DLV_OK
)
539 if (dwarf_lowpc(return_die
, &return_lowpc
, &error
) == DW_DLV_OK
)
541 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].StartPC
= return_lowpc
;
542 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].LowPC
= return_lowpc
;
547 if (dwarf_highpc(return_die
, &return_highpc
, &error
) == DW_DLV_OK
)
549 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].HighPC
= return_highpc
;
553 case DW_AT_decl_line
:
554 if (dwarf_formudata(return_attr1
, &return_uvalue
, &error
) == DW_DLV_OK
)
556 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NumLineSrc
= return_uvalue
;
561 if (dwarf_formstring(return_attr1
, &return_string
, &error
) == DW_DLV_OK
)
563 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
= (char *)calloc(strlen(return_string
) + 1, 1);
564 strcpy(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrSubprogramName
, return_string
);
565 dwarf_dealloc(dbg
, return_string
, DW_DLA_STRING
);
574 dwarf_dealloc(dbg
, atlist
[i
], DW_DLA_ATTR
);
576 dwarf_dealloc(dbg
, atlist
, DW_DLA_LIST
);
578 for (i
= 0; i
< (size_t)cnt
; ++i
)
580 if (dwarf_lineaddr(linebuf
[i
], &return_lineaddr
, &error
) == DW_DLV_OK
)
582 if (dwarf_lineno(linebuf
[i
], &return_uvalue
, &error
) == DW_DLV_OK
)
584 if ((return_lineaddr
>= return_lowpc
) && (return_lineaddr
<= return_highpc
))
586 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
));
587 memset((void *)(PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
+ PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
), 0, sizeof(DMIStruct_LineSrc
));
588 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].StartPC
= return_lineaddr
;
589 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
].NumLineSrc
= return_uvalue
;
590 PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
].NbLinesSrc
++;
596 PtrCU
[NbCU
].NbSubProgs
++;
604 } while (dwarf_siblingof(dbg
, return_sib
, &return_die
, &error
) == DW_DLV_OK
);
607 // Release the memory used by the source lines
608 for (i
= 0; i
< (size_t)cnt
; ++i
)
609 dwarf_dealloc(dbg
, linebuf
[i
], DW_DLA_LINE
);
610 dwarf_dealloc(dbg
, linebuf
, DW_DLA_LIST
);
613 // Set the source code lines for QT html/text conformity
614 if (PtrCU
[NbCU
].NbLinesLoadSrc
)
616 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(PtrCU
[NbCU
].NbLinesLoadSrc
, sizeof(char *)))
618 for (j
= 0; j
< PtrCU
[NbCU
].NbLinesLoadSrc
; j
++)
620 if (PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)calloc(10000, sizeof(char)))
622 if (Ptr
= DWARFManager_GetLineSrcFromNumLine(PtrCU
[NbCU
].PtrLoadSrc
, (j
+ 1)))
631 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], " ");
632 i
+= strlen(" ");
636 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "<");
641 strcat(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], ">");
646 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], "&");
647 i
+= strlen("&");
652 strcpy(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], """);
653 i
+= strlen(""");
657 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
][i
++] = *Ptr
;
663 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = (char *)realloc(PtrCU
[NbCU
].PtrLinesLoadSrc
[j
], i
+ 1);
667 // Init lines source information based on each source code line numbers
668 for (j
= 0; j
< PtrCU
[NbCU
].NbSubProgs
; j
++)
670 // Check if the subprog / function's line exists in the source code
671 if (PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
673 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].NumLineSrc
- 1];
676 for (k
= 0; k
< PtrCU
[NbCU
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
678 if (PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
<= PtrCU
[NbCU
].NbLinesLoadSrc
)
680 PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
= PtrCU
[NbCU
].PtrLinesLoadSrc
[PtrCU
[NbCU
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
- 1];
688 // Set each source lines pointer to NULL
689 if (PtrCU
[NbCU
].NbSubProgs
)
691 // Check the presence of source lines dedicated to the sub progs
692 if (PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
)
694 i
= PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].PtrLinesSrc
[PtrCU
[NbCU
].PtrSubProgs
[PtrCU
[NbCU
].NbSubProgs
- 1].NbLinesSrc
- 1].NumLineSrc
;
695 if (PtrCU
[NbCU
].PtrLinesLoadSrc
= (char **)calloc(i
, sizeof(char *)))
697 for (j
= 0; j
< i
; j
++)
699 PtrCU
[NbCU
].PtrLinesLoadSrc
[j
] = NULL
;
706 // Init variables information based on types information
707 for (i
= 0; i
< PtrCU
[NbCU
].NbVariables
; i
++)
709 PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
= (char *)calloc(1000, 1);
710 TypeOffset
= PtrCU
[NbCU
].PtrVariables
[i
].TypeOffset
;
712 for (j
= 0; j
< PtrCU
[NbCU
].NbTypes
; j
++)
714 if (TypeOffset
== PtrCU
[NbCU
].PtrTypes
[j
].Offset
)
716 switch (PtrCU
[NbCU
].PtrTypes
[j
].Tag
)
718 case DW_TAG_structure_type
:
719 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x1;
720 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
726 if ((PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
& 0x2))
728 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, " *");
733 case DW_TAG_pointer_type
:
734 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x2;
735 PtrCU
[NbCU
].PtrVariables
[i
].TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
736 PtrCU
[NbCU
].PtrVariables
[i
].TypeEncoding
= 0x10;
737 if (!(TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
739 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, "void *");
748 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x20;
749 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
750 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
756 case DW_TAG_subrange_type
:
757 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x4;
760 case DW_TAG_array_type
:
761 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x8;
762 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
768 case DW_TAG_const_type
:
769 PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
|= 0x10;
770 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, "const ");
771 if ((TypeOffset
= PtrCU
[NbCU
].PtrTypes
[j
].TypeOffset
))
777 case DW_TAG_base_type
:
778 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, PtrCU
[NbCU
].PtrTypes
[j
].PtrName
);
779 if ((PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
& 0x2))
781 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, " *");
785 PtrCU
[NbCU
].PtrVariables
[i
].TypeByteSize
= PtrCU
[NbCU
].PtrTypes
[j
].ByteSize
;
786 PtrCU
[NbCU
].PtrVariables
[i
].TypeEncoding
= PtrCU
[NbCU
].PtrTypes
[j
].Encoding
;
788 if ((PtrCU
[NbCU
].PtrVariables
[i
].TypeTag
& 0x8))
790 strcat(PtrCU
[NbCU
].PtrVariables
[i
].PtrTypeName
, "[]");
806 free(SourceFilename
);
807 free(SourceFileDirectory
);
808 free(SourceFullFilename
);
812 // Get symbol name based from address
813 // Return NULL if no symbol name exists
814 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr
)
818 for (i
= 0; i
< NbCU
; i
++)
820 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
822 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
824 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
))
826 return PtrCU
[i
].PtrSubProgs
[j
].PtrSubprogramName
;
836 // Get complete source filename based from address
837 // Return NULL if no source filename exists
838 // Return the existence status (true or false) in Error
839 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr
, bool *Error
)
843 for (i
= 0; i
< NbCU
; i
++)
845 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
847 *Error
= PtrCU
[i
].PtrLoadSrc
? true : false;
848 return PtrCU
[i
].PtrFullFilename
;
856 // Get text line source based on line number (starting by 1)
857 // Return NULL if no text line exists or if line number is 0
858 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile
, size_t NumLine
)
861 char *PtrLineSrc
= NULL
;
867 PtrLineSrc
= PtrSrcFile
;
868 while (*PtrSrcFile
++);
877 // Get Compilation Unit / External variables numbers
878 // Return variables number
879 size_t DWARFManager_GetNbExternalVariables(void)
881 size_t NbVariables
= 0, i
;
883 for (i
= 0; i
< NbCU
; i
++)
885 NbVariables
+= PtrCU
[i
].NbVariables
;
892 // Get external variable type name based on his index (starting by 1)
893 // Return NULL if not found
894 // May return NULL if there is not type linked to the variable's index
895 char *DWARFManager_GetExternalVariableTypeName(size_t Index
)
899 for (i
= 0; i
< NbCU
; i
++)
901 if (PtrCU
[i
].NbVariables
)
903 if (Index
<= PtrCU
[i
].NbVariables
)
905 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrTypeName
;
909 Index
-= PtrCU
[i
].NbVariables
;
918 // Get external variable's type tag based on his index (starting by 1)
919 // Return 0 if not found
920 size_t DWARFManager_GetExternalVariableTypeTag(size_t Index
)
924 for (i
= 0; i
< NbCU
; i
++)
926 if (PtrCU
[i
].NbVariables
)
928 if (Index
<= PtrCU
[i
].NbVariables
)
930 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeTag
;
934 Index
-= PtrCU
[i
].NbVariables
;
943 // Get external variable byte size based on his index (starting by 1)
944 // Return 0 if not found
945 size_t DWARFManager_GetExternalVariableTypeByteSize(size_t Index
)
949 for (i
= 0; i
< NbCU
; i
++)
951 if (PtrCU
[i
].NbVariables
)
953 if (Index
<= PtrCU
[i
].NbVariables
)
955 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeByteSize
;
959 Index
-= PtrCU
[i
].NbVariables
;
968 // Get external variable encoding based on his index (starting by 1)
969 // Return 0 if not found
970 size_t DWARFManager_GetExternalVariableTypeEncoding(size_t Index
)
974 for (i
= 0; i
< NbCU
; i
++)
976 if (PtrCU
[i
].NbVariables
)
978 if (Index
<= PtrCU
[i
].NbVariables
)
980 return PtrCU
[i
].PtrVariables
[Index
- 1].TypeEncoding
;
984 Index
-= PtrCU
[i
].NbVariables
;
993 // Get external variable address based on his index (starting by 1)
994 // Return 0 if not found
995 size_t DWARFManager_GetExternalVariableAdr(size_t Index
)
999 for (i
= 0; i
< NbCU
; i
++)
1001 if (PtrCU
[i
].NbVariables
)
1003 if (Index
<= PtrCU
[i
].NbVariables
)
1005 return PtrCU
[i
].PtrVariables
[Index
- 1].Addr
;
1009 Index
-= PtrCU
[i
].NbVariables
;
1018 // Get external variable memory address based on his name
1019 // Return 0 if not found
1020 // Note: Return the first occurence found
1021 size_t DWARFManager_GetExternalVariableAdrFromName(char *VariableName
)
1025 for (i
= 0; i
< NbCU
; i
++)
1027 if (PtrCU
[i
].NbVariables
)
1029 for (j
= 0; j
< PtrCU
[i
].NbVariables
; j
++)
1031 if (!strcmp(PtrCU
[i
].PtrVariables
[j
].PtrName
,VariableName
))
1033 return PtrCU
[i
].PtrVariables
[j
].Addr
;
1043 // Get external variable name based on his index (starting by 1)
1044 // Return name's pointer text found
1045 // Return NULL if not found
1046 char *DWARFManager_GetExternalVariableName(size_t Index
)
1050 for (i
= 0; i
< NbCU
; i
++)
1052 if (PtrCU
[i
].NbVariables
)
1054 if (Index
<= PtrCU
[i
].NbVariables
)
1056 return PtrCU
[i
].PtrVariables
[Index
- 1].PtrName
;
1060 Index
-= PtrCU
[i
].NbVariables
;
1069 // Get text line from source based on address and his tag
1070 // Return NULL if no text line has been found
1071 char *DWARFManager_GetLineSrcFromAdr(size_t Adr
, size_t Tag
)
1075 for (i
= 0; i
< NbCU
; i
++)
1077 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1079 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1081 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1083 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1085 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1089 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1091 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1093 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1106 // Get line number based on the address and the tag
1107 // Return 0 if no line number has been found
1108 size_t DWARFManager_GetNumLineFromAdr(size_t Adr
, size_t Tag
)
1112 for (i
= 0; i
< NbCU
; i
++)
1114 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1116 for (j
= 0; (j
< PtrCU
[i
].NbSubProgs
); j
++)
1118 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1120 if ((PtrCU
[i
].PtrSubProgs
[j
].StartPC
== Adr
) && (!Tag
|| (Tag
== DW_TAG_subprogram
)))
1122 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1126 for (k
= 0; (k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
); k
++)
1128 if ((PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].StartPC
== Adr
) && (!Tag
|| (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].Tag
== Tag
)))
1130 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
;
1135 if (!Tag
|| (Tag
== DW_TAG_subprogram
))
1137 return PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
;
1149 // Get text line from source based on address and num line (starting by 1)
1150 // Return NULL if no text line has been found
1151 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr
, size_t NumLine
)
1155 for (i
= 0; i
< NbCU
; i
++)
1157 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1159 for (j
= 0; j
< PtrCU
[i
].NbSubProgs
; j
++)
1161 if ((Adr
>= PtrCU
[i
].PtrSubProgs
[j
].LowPC
) && (Adr
< PtrCU
[i
].PtrSubProgs
[j
].HighPC
))
1163 if (PtrCU
[i
].PtrSubProgs
[j
].NumLineSrc
== NumLine
)
1165 return PtrCU
[i
].PtrSubProgs
[j
].PtrLineSrc
;
1169 for (k
= 0; k
< PtrCU
[i
].PtrSubProgs
[j
].NbLinesSrc
; k
++)
1171 if (PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].NumLineSrc
== NumLine
)
1173 return PtrCU
[i
].PtrSubProgs
[j
].PtrLinesSrc
[k
].PtrLineSrc
;
1186 // Get text line from source based on address and num line (starting by 1)
1187 // Return NULL if no text line has been found
1188 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr
, size_t NumLine
)
1192 for (i
= 0; i
< NbCU
; i
++)
1194 if ((Adr
>= PtrCU
[i
].LowPC
) && (Adr
< PtrCU
[i
].HighPC
))
1196 if (NumLine
<= PtrCU
[i
].NbLinesLoadSrc
)
1198 return PtrCU
[i
].PtrLinesLoadSrc
[NumLine
- 1];