Update the breakpoint feature
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DWARFManager.cpp
CommitLineData
ebcb0f3d
JPM
1//\r
2// DWARFManager.cpp: DWARF format manager\r
3//\r
4// by Jean-Paul Mari\r
5//\r
6// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
c4fe5864 7// RG = Richard Goedeken\r
ebcb0f3d
JPM
8//\r
9// WHO WHEN WHAT\r
10// --- ---------- ------------------------------------------------------------\r
5fa7aa73 11// JPM Dec./2016 Created this file, and added the DWARF format support\r
6564336c 12// JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information\r
f0dd2f7b 13// JPM Oct./2018 Improve the DWARF parsing information, and the source file text reading; support the used source lines from DWARF structure, and the search paths for the files\r
aae93d86 14// JPM Aug./2019 Added new functions to handle DWARF information, full filename fix\r
258b1c16 15// JPM Mar./2020 Fix a random crash when reading the source lines information\r
009df4d7 16// JPM Aug./2020 Added a source code file date check when reading DWARF information\r
c4fe5864 17// RG Jan./2021 Linux build fixes\r
f8dde18d
JPM
18//\r
19\r
20// To Do\r
21// To use pointers instead of arrays usage\r
22// \r
ebcb0f3d
JPM
23\r
24\r
41d6f5f7
JPM
25#include <stdlib.h>\r
26#include <stdio.h>\r
27#include <stdint.h>\r
28#include <string.h>\r
009df4d7
JPM
29#include <time.h>\r
30#include <sys/types.h>\r
31#include <sys/stat.h>\r
32#include "libdwarf.h"\r
33#include "dwarf.h"\r
f8dde18d 34#include "LEB128.h"\r
009df4d7 35#include "DWARFManager.h"\r
41d6f5f7 36\r
5fa7aa73 37// Definitions for debugging\r
aae93d86 38//#define DEBUG_NumCU 0x3 // CU number to debug or undefine it\r
ce32526a 39//#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it\r
f8dde18d
JPM
40//#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it\r
41//#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)\r
aae93d86
JPM
42//#define DEBUG_Filename "crt0" // Filename to look for or undefine it\r
43\r
44// Definitions for handling data\r
45//#define CONVERT_QT_HML // Text will be converted as HTML\r
ebcb0f3d 46\r
5fa7aa73
JPM
47// Definitions for the variables's typetag\r
48#define TypeTag_structure 0x01 // structure\r
49#define TypeTag_pointer 0x02 // pointer\r
50#define TypeTag_subrange 0x04 // (subrange_type?)\r
51#define TypeTag_arraytype 0x08 // array type\r
52#define TypeTag_consttype 0x10 // const type\r
53#define TypeTag_typedef 0x20 // typedef\r
54#define TypeTag_enumeration_type 0x40 // enumeration\r
55#define TypeTag_subroutine_type 0x80 // subroutine\r
56\r
57\r
58// Source line CU structure\r
59typedef struct CUStruct_LineSrc\r
60{\r
61 size_t StartPC;\r
62 size_t NumLineSrc;\r
63 char *PtrLineSrc;\r
64}S_CUStruct_LineSrc;\r
ebcb0f3d
JPM
65\r
66// Source line internal structure\r
f8dde18d 67typedef struct DMIStruct_LineSrc\r
ebcb0f3d
JPM
68{\r
69 size_t Tag;\r
70 size_t StartPC;\r
71 size_t NumLineSrc;\r
72 char *PtrLineSrc;\r
73}S_DMIStruct_LineSrc;\r
74\r
f8dde18d
JPM
75// Enumeration structure\r
76typedef struct EnumerationStruct\r
77{\r
78 char *PtrName; // Enumeration's name\r
79 size_t value; // Enumeration's value\r
80}S_EnumerationStruct;\r
81\r
82// Structure members structure\r
83//typedef struct StructureMembersStruct\r
84//{\r
85//}S_StructureMembersStruct;\r
86\r
ebcb0f3d 87// Base type internal structure\r
f8dde18d 88typedef struct BaseTypeStruct\r
ebcb0f3d 89{\r
f8dde18d
JPM
90 size_t Tag; // Type's Tag\r
91 size_t Offset; // Type's offset\r
92 size_t TypeOffset; // Type's offset on another type\r
93 size_t ByteSize; // Type's Byte Size\r
94 size_t Encoding; // Type's encoding\r
95 char *PtrName; // Type's name\r
96 size_t NbEnumeration; // Type's enumeration numbers\r
97 EnumerationStruct *PtrEnumeration; // Type's enumeration\r
98// StructureMembersStruct *PtrStructureMembers; // Type's structure members\r
ebcb0f3d
JPM
99}S_BaseTypeStruct;\r
100\r
101// Variables internal structure\r
f8dde18d 102typedef struct VariablesStruct\r
ebcb0f3d 103{\r
0203b5fd
JPM
104 size_t Op; // Variable's DW_OP\r
105 union\r
106 {\r
107 size_t Addr; // Variable memory address\r
108 int Offset; // Variable stack offset (signed)\r
109 };\r
ebcb0f3d
JPM
110 char *PtrName; // Variable's name\r
111 size_t TypeOffset; // Offset pointing on the Variable's Type\r
112 size_t TypeByteSize; // Variable's Type byte size\r
113 size_t TypeTag; // Variable's Type Tag\r
114 size_t TypeEncoding; // Variable's Type encoding\r
115 char *PtrTypeName; // Variable's Type name\r
116}S_VariablesStruct;\r
117\r
118// Sub program internal structure\r
f8dde18d 119typedef struct SubProgStruct\r
ebcb0f3d
JPM
120{\r
121 size_t Tag;\r
122 size_t NumLineSrc;\r
123 size_t StartPC;\r
124 size_t LowPC, HighPC;\r
0203b5fd 125 size_t FrameBase;\r
ebcb0f3d 126 char *PtrLineSrc;\r
0203b5fd
JPM
127 char *PtrSubprogramName; // Sub program name\r
128 size_t NbLinesSrc; // Number of lines source used by the sub program\r
129 DMIStruct_LineSrc *PtrLinesSrc; // Pointer of the lines source for the sub program\r
130 size_t NbVariables; // Variables number\r
131 VariablesStruct *PtrVariables; // Pointer to the local variables list information structure\r
ebcb0f3d
JPM
132}S_SubProgStruct;\r
133\r
134// Compilation Unit internal structure\r
f8dde18d 135typedef struct CUStruct\r
ebcb0f3d
JPM
136{\r
137 size_t Tag;\r
aae93d86 138 size_t Language; // Language (C, etc.) used by the source code\r
5fa7aa73 139 size_t LowPC, HighPC; // Memory range for the code\r
009df4d7 140 char *PtrProducer; // "Producer" text information (mostly compiler and compilation options used)\r
f8dde18d
JPM
141 char *PtrSourceFilename; // Source file name\r
142 char *PtrSourceFileDirectory; // Directory of the source file\r
ebcb0f3d 143 char *PtrFullFilename; // Pointer to full namefile (directory & filename)\r
5fa7aa73
JPM
144 size_t SizeLoadSrc; // Source code text size\r
145 char *PtrLoadSrc; // Pointer to the source code text\r
146 size_t NbLinesLoadSrc; // Total number of lines in the source code text\r
ebcb0f3d
JPM
147 char **PtrLinesLoadSrc; // Pointer lists to each source line put in QT html/text conformity\r
148 size_t NbSubProgs; // Number of sub programs / routines\r
5fa7aa73 149 SubProgStruct *PtrSubProgs; // Pointer to the sub programs / routines structure\r
f8dde18d
JPM
150 size_t NbTypes; // Number of types\r
151 BaseTypeStruct *PtrTypes; // Pointer to types\r
ebcb0f3d 152 size_t NbVariables; // Variables number\r
5fa7aa73 153 VariablesStruct *PtrVariables; // Pointer to the global variables list structure\r
65597951 154 size_t NbFrames; // Frames number\r
aae93d86
JPM
155 size_t NbUsedLinesSrc; // Number of used source lines\r
156 size_t LastNumUsedLinesSrc; // Last number line used\r
157 CUStruct_LineSrc *PtrUsedLinesSrc; // Pointer to the used source lines list structure\r
158 char **PtrUsedLinesLoadSrc; // Pointer lists to each used source line referenced by the CUStruct_LineSrc structure\r
159 size_t *PtrUsedNumLines; // List of the number lines used\r
c89f8ff7 160 struct stat _statbuf; // File information\r
009df4d7 161 DWARFstatus Status; // File status\r
ebcb0f3d
JPM
162}S_CUStruct;\r
163\r
164\r
165// Dwarf management\r
166uint32_t LibDwarf;\r
167uint32_t NbCU;\r
168Dwarf_Ptr errarg;\r
169Dwarf_Error error;\r
170Dwarf_Debug dbg;\r
171CUStruct *PtrCU;\r
f0dd2f7b
JPM
172char **ListSearchPaths;\r
173size_t NbSearchPaths;\r
c89f8ff7 174struct stat FileElfExeInfo;\r
ebcb0f3d
JPM
175\r
176\r
177//\r
178Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg);\r
179void DWARFManager_InitDMI(void);\r
180void DWARFManager_CloseDMI(void);\r
181bool DWARFManager_ElfClose(void);\r
182char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine);\r
0203b5fd 183void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables);\r
f0dd2f7b
JPM
184void DWARFManager_SourceFileSearchPathsInit(void);\r
185void DWARFManager_SourceFileSearchPathsReset(void);\r
186void DWARFManager_SourceFileSearchPathsClose(void);\r
aae93d86 187void DWARFManager_ConformSlachesBackslashes(char *Ptr);\r
ebcb0f3d
JPM
188\r
189\r
190//\r
191Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg)\r
192{\r
193 return 0;\r
194}\r
195\r
196\r
f0dd2f7b
JPM
197// Dwarf manager list search paths init\r
198void DWARFManager_SourceFileSearchPathsInit(void)\r
199{\r
200 ListSearchPaths = NULL;\r
201 NbSearchPaths = 0;\r
202}\r
203\r
204\r
205// Dwarf manager list search paths reset\r
206void DWARFManager_SourceFileSearchPathsReset(void)\r
207{\r
208 ListSearchPaths = NULL;\r
209 NbSearchPaths = 0;\r
210}\r
211\r
212\r
213// Dwarf manager list search paths close\r
214void DWARFManager_SourceFileSearchPathsClose(void)\r
215{\r
216 DWARFManager_SourceFileSearchPathsReset();\r
217}\r
218\r
219\r
ebcb0f3d
JPM
220// Dwarf manager init\r
221void DWARFManager_Init(void)\r
222{\r
f0dd2f7b 223 DWARFManager_SourceFileSearchPathsInit();\r
ebcb0f3d
JPM
224 LibDwarf = DW_DLV_NO_ENTRY;\r
225}\r
226\r
227\r
f0dd2f7b
JPM
228// Dwarf manager settings\r
229void DWARFManager_Set(size_t NbPathsInList, char **PtrListPaths)\r
230{\r
231 // Search paths init\r
232 ListSearchPaths = PtrListPaths;\r
233 NbSearchPaths = NbPathsInList;\r
234}\r
235\r
236\r
ebcb0f3d
JPM
237// Dwarf manager Reset\r
238bool DWARFManager_Reset(void)\r
239{\r
f0dd2f7b 240 DWARFManager_SourceFileSearchPathsReset();\r
ebcb0f3d
JPM
241 return DWARFManager_ElfClose();\r
242}\r
243\r
244\r
245// Dwarf manager Close\r
246bool DWARFManager_Close(void)\r
247{\r
f0dd2f7b 248 DWARFManager_SourceFileSearchPathsClose();\r
ebcb0f3d
JPM
249 return(DWARFManager_Reset());\r
250}\r
251\r
252\r
253// Dwarf manager Elf init\r
c89f8ff7 254int DWARFManager_ElfInit(Elf *ElfPtr, struct stat FileElfInfo)\r
ebcb0f3d
JPM
255{\r
256 if ((LibDwarf = dwarf_elf_init(ElfPtr, DW_DLC_READ, (Dwarf_Handler)DWARFManager_ErrorHandler, errarg, &dbg, &error)) == DW_DLV_OK)\r
257 {\r
009df4d7 258 FileElfExeInfo = FileElfInfo;\r
ebcb0f3d
JPM
259 DWARFManager_InitDMI();\r
260 }\r
261\r
262 return LibDwarf;\r
263}\r
264\r
265\r
266// Dwarf manager Elf close\r
267bool DWARFManager_ElfClose(void)\r
268{\r
269 if (LibDwarf == DW_DLV_OK)\r
270 {\r
271 DWARFManager_CloseDMI();\r
272\r
273 if (dwarf_finish(dbg, &error) == DW_DLV_OK)\r
274 {\r
275 LibDwarf = DW_DLV_NO_ENTRY;\r
276 return true;\r
277 }\r
278 else\r
279 {\r
280 return false;\r
281 }\r
282 }\r
283 else\r
284 {\r
285 return true;\r
286 }\r
287}\r
288\r
289\r
290// Dwarf manager Compilation Units close\r
291void DWARFManager_CloseDMI(void)\r
292{\r
293 while (NbCU--)\r
294 {\r
295 free(PtrCU[NbCU].PtrFullFilename);\r
296 free(PtrCU[NbCU].PtrLoadSrc);\r
297 free(PtrCU[NbCU].PtrProducer);\r
f8dde18d
JPM
298 free(PtrCU[NbCU].PtrSourceFilename);\r
299 free(PtrCU[NbCU].PtrSourceFileDirectory);\r
aae93d86
JPM
300 free(PtrCU[NbCU].PtrUsedLinesSrc);\r
301 free(PtrCU[NbCU].PtrUsedLinesLoadSrc);\r
302 free(PtrCU[NbCU].PtrUsedNumLines);\r
ebcb0f3d
JPM
303\r
304 while (PtrCU[NbCU].NbLinesLoadSrc--)\r
305 {\r
306 free(PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].NbLinesLoadSrc]);\r
307 }\r
308 free(PtrCU[NbCU].PtrLinesLoadSrc);\r
309\r
310 while (PtrCU[NbCU].NbSubProgs--)\r
311 {\r
0203b5fd
JPM
312 while (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables--)\r
313 {\r
314 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName);\r
315 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrTypeName);\r
316 }\r
317 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables);\r
318\r
ebcb0f3d
JPM
319 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc);\r
320 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName);\r
321 }\r
322 free(PtrCU[NbCU].PtrSubProgs);\r
323\r
324 while (PtrCU[NbCU].NbTypes--)\r
325 {\r
326 free(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName);\r
327 }\r
328 free(PtrCU[NbCU].PtrTypes);\r
329\r
330 while (PtrCU[NbCU].NbVariables--)\r
331 {\r
332 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);\r
333 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrTypeName);\r
334 }\r
335 free(PtrCU[NbCU].PtrVariables);\r
336 }\r
337\r
338 free(PtrCU);\r
339}\r
340\r
341\r
342// Dwarf manager Compilation Units initialisations\r
343void DWARFManager_InitDMI(void)\r
344{\r
345 Dwarf_Unsigned next_cu_header, return_uvalue;\r
346 Dwarf_Error error;\r
347 Dwarf_Attribute *atlist;\r
348 Dwarf_Attribute return_attr1;\r
349 Dwarf_Half return_tagval, return_attr;\r
350 Dwarf_Addr return_lowpc, return_highpc, return_lineaddr;\r
351 Dwarf_Block *return_block;\r
352 Dwarf_Signed atcnt, cnt;\r
0203b5fd 353 Dwarf_Die return_sib, return_die, return_sub, return_subdie;\r
ebcb0f3d
JPM
354 Dwarf_Off return_offset;\r
355 Dwarf_Line *linebuf;\r
356 FILE *SrcFile;\r
ebcb0f3d 357 char *return_string;\r
1155c536 358 char *Ptr, *Ptr1;\r
ebcb0f3d
JPM
359\r
360 // Initialisation for the Compilation Units table\r
361 NbCU = 0;\r
362 PtrCU = NULL;\r
363\r
364 // loop on the available Compilation Unit\r
365 while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &next_cu_header, &error) == DW_DLV_OK)\r
366 {\r
367 // Allocation of an additional Compilation Unit structure in the table\r
368 if (Ptr = (char *)realloc(PtrCU, ((NbCU + 1) * sizeof(CUStruct))))\r
369 {\r
370 // Compilation Unit RAZ\r
371 PtrCU = (CUStruct *)Ptr;\r
372 memset(PtrCU + NbCU, 0, sizeof(CUStruct));\r
373\r
41d6f5f7
JPM
374 // Debug specific CU\r
375#ifdef DEBUG_NumCU\r
376 if (NbCU == DEBUG_NumCU)\r
377#endif\r
ebcb0f3d 378 {\r
41d6f5f7
JPM
379 // Get 1st Die from the Compilation Unit\r
380 if (dwarf_siblingof(dbg, NULL, &return_sib, &error) == DW_DLV_OK)\r
ebcb0f3d 381 {\r
41d6f5f7
JPM
382 // Get Die's Tag\r
383 if ((dwarf_tag(return_sib, &return_tagval, &error) == DW_DLV_OK))\r
ebcb0f3d 384 {\r
41d6f5f7
JPM
385 PtrCU[NbCU].Tag = return_tagval;\r
386\r
387 // Die type detection\r
388 switch (return_tagval)\r
ebcb0f3d 389 {\r
65597951 390 case DW_TAG_compile_unit:\r
41d6f5f7 391 if (dwarf_attrlist(return_sib, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 392 {\r
41d6f5f7 393 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 394 {\r
41d6f5f7 395 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 396 {\r
41d6f5f7 397 switch (return_attr)\r
ebcb0f3d 398 {\r
65597951
JPM
399 // Start address\r
400 case DW_AT_low_pc:\r
41d6f5f7
JPM
401 if (dwarf_lowpc(return_sib, &return_lowpc, &error) == DW_DLV_OK)\r
402 {\r
403 PtrCU[NbCU].LowPC = return_lowpc;\r
404 }\r
405 break;\r
ebcb0f3d 406\r
65597951
JPM
407 // End address\r
408 case DW_AT_high_pc:\r
41d6f5f7
JPM
409 if (dwarf_highpc(return_sib, &return_highpc, &error) == DW_DLV_OK)\r
410 {\r
411 PtrCU[NbCU].HighPC = return_highpc;\r
412 }\r
413 break;\r
ebcb0f3d 414\r
65597951
JPM
415 // compilation information\r
416 case DW_AT_producer:\r
41d6f5f7
JPM
417 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
418 {\r
419 PtrCU[NbCU].PtrProducer = (char *)calloc(strlen(return_string) + 1, 1);\r
420 strcpy(PtrCU[NbCU].PtrProducer, return_string);\r
421 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
422 }\r
423 break;\r
ebcb0f3d 424\r
65597951
JPM
425 // Filename\r
426 case DW_AT_name:\r
41d6f5f7
JPM
427 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
428 {\r
f8dde18d
JPM
429#ifdef DEBUG_Filename\r
430 if (strstr(return_string, DEBUG_Filename))\r
431#endif\r
432 {\r
433 PtrCU[NbCU].PtrSourceFilename = (char *)calloc((strlen(return_string) + 1), 1);\r
434 strcpy(PtrCU[NbCU].PtrSourceFilename, return_string);\r
435 }\r
41d6f5f7
JPM
436 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
437 }\r
438 break;\r
ebcb0f3d 439\r
65597951
JPM
440 // Directory name\r
441 case DW_AT_comp_dir:\r
41d6f5f7
JPM
442 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
443 {\r
f8dde18d
JPM
444 PtrCU[NbCU].PtrSourceFileDirectory = (char *)calloc((strlen(return_string) + 1), 1);\r
445 strcpy(PtrCU[NbCU].PtrSourceFileDirectory, return_string);\r
41d6f5f7
JPM
446 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
447 }\r
448 break;\r
ebcb0f3d 449\r
aae93d86
JPM
450 // Language\r
451 case DW_AT_language:\r
452 if (dwarf_formudata(atlist[i], &return_uvalue, &error) == DW_DLV_OK)\r
453 {\r
454 PtrCU[NbCU].Language = return_uvalue;\r
455 }\r
456 break;\r
457\r
41d6f5f7
JPM
458 default:\r
459 break;\r
460 }\r
ebcb0f3d 461 }\r
41d6f5f7 462 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
ebcb0f3d 463 }\r
41d6f5f7 464 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
ebcb0f3d 465 }\r
ebcb0f3d 466\r
f0dd2f7b 467 // Check filename presence\r
f8dde18d
JPM
468 if (!PtrCU[NbCU].PtrSourceFilename)\r
469 {\r
470 PtrCU[NbCU].PtrSourceFilename = (char *)calloc(1, 1);\r
471 }\r
472\r
f0dd2f7b 473 // Check directory presence\r
f8dde18d
JPM
474 if (!PtrCU[NbCU].PtrSourceFileDirectory)\r
475 {\r
f0dd2f7b
JPM
476 // Check if file exists in the search paths\r
477 for (size_t i = 0; i < NbSearchPaths; i++)\r
478 {\r
479 PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen((const char *)ListSearchPaths[i]) + 2);\r
480#if defined(_WIN32)\r
481 sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", ListSearchPaths[i], PtrCU[NbCU].PtrSourceFilename);\r
c89f8ff7 482 if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rb"))\r
f0dd2f7b
JPM
483#else\r
484 sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", ListSearchPaths[i], PtrCU[NbCU].PtrSourceFilename);\r
c89f8ff7
RG
485 SrcFile = fopen(PtrCU[NbCU].PtrFullFilename, "rb");\r
486 if (SrcFile == NULL)\r
f0dd2f7b 487#endif\r
f0dd2f7b
JPM
488 {\r
489 PtrCU[NbCU].PtrSourceFileDirectory = (char *)realloc(PtrCU[NbCU].PtrSourceFileDirectory, strlen(ListSearchPaths[i]) + 1);\r
490 strcpy(PtrCU[NbCU].PtrSourceFileDirectory, ListSearchPaths[i]);\r
491 }\r
492 }\r
493\r
494 // File directory doesn't exits\r
495 if (!PtrCU[NbCU].PtrSourceFileDirectory)\r
496 {\r
497 PtrCU[NbCU].PtrSourceFileDirectory = (char *)realloc(PtrCU[NbCU].PtrSourceFileDirectory, 2);\r
498 strcpy(PtrCU[NbCU].PtrSourceFileDirectory, ".");\r
499 }\r
f8dde18d
JPM
500 }\r
501\r
aae93d86
JPM
502 // Conform slashes / backslashes for the filename\r
503 DWARFManager_ConformSlachesBackslashes(PtrCU[NbCU].PtrSourceFilename);\r
504\r
505 // Check if filename contains already the complete directory\r
506 if (PtrCU[NbCU].PtrSourceFilename[1] == ':')\r
ebcb0f3d 507 {\r
aae93d86
JPM
508 // Copy the filename as the full filename\r
509 PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + 1);\r
510 strcpy(PtrCU[NbCU].PtrFullFilename, PtrCU[NbCU].PtrSourceFilename);\r
511 }\r
512 else\r
513 {\r
514 // Create full filename and Conform slashes / backslashes\r
515 PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen(PtrCU[NbCU].PtrSourceFileDirectory) + 2);\r
65597951 516#if defined(_WIN32)\r
aae93d86 517 sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
65597951 518#else\r
aae93d86 519 sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
65597951 520#endif\r
ebcb0f3d 521 }\r
ebcb0f3d 522\r
aae93d86
JPM
523 DWARFManager_ConformSlachesBackslashes(PtrCU[NbCU].PtrFullFilename);\r
524\r
1155c536
JPM
525 // Directory path clean-up\r
526#if defined(_WIN32)\r
527 while ((Ptr1 = Ptr = strstr(PtrCU[NbCU].PtrFullFilename, "\\..\\")))\r
528#else\r
529 while ((Ptr1 = Ptr = strstr(PtrCU[NbCU].PtrFullFilename, "/../")))\r
530#endif\r
531 {\r
532#if defined(_WIN32)\r
533 while (*--Ptr1 != '\\');\r
534#else\r
535 while (*--Ptr1 != '/');\r
536#endif\r
537 strcpy((Ptr1 + 1), (Ptr + 4));\r
538 }\r
539\r
009df4d7 540 // Get the source file information\r
c89f8ff7 541 if (!stat(PtrCU[NbCU].PtrFullFilename, &PtrCU[NbCU]._statbuf))\r
ebcb0f3d 542 {\r
009df4d7
JPM
543 // check the time stamp with the executable\r
544 if (PtrCU[NbCU]._statbuf.st_mtime <= FileElfExeInfo.st_mtime)\r
ebcb0f3d 545 {\r
009df4d7 546 // Open the source file as a binary file\r
c89f8ff7 547#if defined(_WIN32)\r
009df4d7 548 if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rb"))\r
c89f8ff7
RG
549#else\r
550 SrcFile = fopen(PtrCU[NbCU].PtrFullFilename, "rb");\r
551 if (SrcFile == NULL)\r
552#endif\r
ebcb0f3d 553 {\r
009df4d7 554 if (!fseek(SrcFile, 0, SEEK_END))\r
ebcb0f3d 555 {\r
009df4d7 556 if ((PtrCU[NbCU].SizeLoadSrc = ftell(SrcFile)) > 0)\r
ebcb0f3d 557 {\r
009df4d7 558 if (!fseek(SrcFile, 0, SEEK_SET))\r
f795e8ac 559 {\r
009df4d7 560 if (PtrCU[NbCU].PtrLoadSrc = Ptr = Ptr1 = (char *)calloc(1, (PtrCU[NbCU].SizeLoadSrc + 2)))\r
f795e8ac 561 {\r
009df4d7 562 // Read whole file\r
c89f8ff7 563#if defined(_WIN32) \r
009df4d7 564 if (fread_s(PtrCU[NbCU].PtrLoadSrc, PtrCU[NbCU].SizeLoadSrc, PtrCU[NbCU].SizeLoadSrc, 1, SrcFile) != 1)\r
c89f8ff7
RG
565#else\r
566 if (fread(PtrCU[NbCU].PtrLoadSrc, PtrCU[NbCU].SizeLoadSrc, 1, SrcFile) != 1)\r
567#endif\r
f795e8ac 568 {\r
009df4d7
JPM
569 free(PtrCU[NbCU].PtrLoadSrc);\r
570 PtrCU[NbCU].PtrLoadSrc = NULL;\r
571 PtrCU[NbCU].SizeLoadSrc = 0;\r
f795e8ac 572 }\r
009df4d7
JPM
573 else\r
574 {\r
575 // Eliminate all carriage return code '\r' (oxd)\r
576 do\r
577 {\r
578 if ((*Ptr = *Ptr1) != '\r')\r
579 {\r
580 Ptr++;\r
581 }\r
582 } while (*Ptr1++);\r
f795e8ac 583\r
009df4d7
JPM
584 // Get back the new text file size\r
585 PtrCU[NbCU].SizeLoadSrc = strlen(Ptr = PtrCU[NbCU].PtrLoadSrc);\r
f795e8ac 586\r
009df4d7
JPM
587 // Make sure the text file finish with a new line code '\n' (0xa)\r
588 if (PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc - 1] != '\n')\r
589 {\r
590 PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc++] = '\n';\r
591 PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc] = 0;\r
592 }\r
f795e8ac 593\r
009df4d7
JPM
594 // Reallocate text file\r
595 if (PtrCU[NbCU].PtrLoadSrc = Ptr = (char *)realloc(PtrCU[NbCU].PtrLoadSrc, (PtrCU[NbCU].SizeLoadSrc + 1)))\r
f795e8ac 596 {\r
009df4d7
JPM
597 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0\r
598 do\r
599 {\r
600 if (*Ptr == '\n')\r
601 {\r
602 PtrCU[NbCU].NbLinesLoadSrc++;\r
603 *Ptr = 0;\r
604 }\r
605 } while (*++Ptr);\r
f795e8ac 606 }\r
009df4d7 607 }\r
f795e8ac
JPM
608 }\r
609 }\r
41d6f5f7 610 }\r
ebcb0f3d 611 }\r
009df4d7
JPM
612\r
613 fclose(SrcFile);\r
ebcb0f3d 614 }\r
009df4d7
JPM
615 else\r
616 {\r
617 // Source file doesn't exist\r
618 PtrCU[NbCU].Status = DWARFSTATUS_NOFILE;\r
619 }\r
620 }\r
621 else\r
622 {\r
623 // Source file is outdated\r
624 PtrCU[NbCU].Status = DWARFSTATUS_OUTDATEDFILE;\r
ebcb0f3d 625 }\r
009df4d7
JPM
626 }\r
627 else\r
628 {\r
629 // Source file doesn't have information\r
630 PtrCU[NbCU].Status = DWARFSTATUS_NOFILEINFO;\r
ebcb0f3d 631 }\r
41d6f5f7 632 break;\r
ebcb0f3d 633\r
41d6f5f7
JPM
634 default:\r
635 break;\r
636 }\r
ebcb0f3d 637 }\r
ebcb0f3d 638\r
f795e8ac 639 // Get the source lines table located in the CU\r
009df4d7 640 if ((dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK) && (PtrCU[NbCU].Status == DWARFSTATUS_OK))\r
41d6f5f7 641 {\r
5fa7aa73
JPM
642 if (cnt)\r
643 {\r
aae93d86
JPM
644 PtrCU[NbCU].NbUsedLinesSrc = cnt;\r
645 PtrCU[NbCU].PtrUsedLinesSrc = (CUStruct_LineSrc *)calloc(cnt, sizeof(CUStruct_LineSrc));\r
646 PtrCU[NbCU].PtrUsedLinesLoadSrc = (char **)calloc(cnt, sizeof(char *));\r
647 PtrCU[NbCU].PtrUsedNumLines = (size_t *)calloc(cnt, sizeof(size_t));\r
648\r
649 // Get the addresses and their source line numbers\r
5fa7aa73
JPM
650 for (Dwarf_Signed i = 0; i < cnt; i++)\r
651 {\r
652 if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
653 {\r
258b1c16 654 // Get the source line number\r
5fa7aa73
JPM
655 if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
656 {\r
aae93d86
JPM
657 PtrCU[NbCU].PtrUsedLinesSrc[i].StartPC = return_lineaddr;\r
658 PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc = return_uvalue;\r
5fa7aa73
JPM
659 }\r
660 }\r
661 }\r
662 }\r
258b1c16
JPM
663\r
664 // Release the memory used by the source lines table located in the CU\r
665 dwarf_srclines_dealloc(dbg, linebuf, cnt);\r
41d6f5f7 666 }\r
ebcb0f3d 667\r
0203b5fd 668 // Check if the CU has child\r
41d6f5f7 669 if (dwarf_child(return_sib, &return_die, &error) == DW_DLV_OK)\r
ebcb0f3d 670 {\r
41d6f5f7 671 do\r
ebcb0f3d 672 {\r
41d6f5f7
JPM
673 return_sib = return_die;\r
674 if ((dwarf_tag(return_die, &return_tagval, &error) == DW_DLV_OK))\r
ebcb0f3d 675 {\r
41d6f5f7 676 switch (return_tagval)\r
ebcb0f3d 677 {\r
65597951 678 case DW_TAG_lexical_block:\r
41d6f5f7 679 break;\r
ebcb0f3d 680\r
65597951 681 case DW_TAG_variable:\r
41d6f5f7 682 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 683 {\r
41d6f5f7
JPM
684 PtrCU[NbCU].PtrVariables = (VariablesStruct *)realloc(PtrCU[NbCU].PtrVariables, ((PtrCU[NbCU].NbVariables + 1) * sizeof(VariablesStruct)));\r
685 memset(PtrCU[NbCU].PtrVariables + PtrCU[NbCU].NbVariables, 0, sizeof(VariablesStruct));\r
686\r
687 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 688 {\r
41d6f5f7 689 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 690 {\r
41d6f5f7 691 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
ebcb0f3d 692 {\r
41d6f5f7 693 switch (return_attr)\r
ebcb0f3d 694 {\r
65597951 695 case DW_AT_location:\r
41d6f5f7 696 if (dwarf_formblock(return_attr1, &return_block, &error) == DW_DLV_OK)\r
ebcb0f3d 697 {\r
0203b5fd
JPM
698 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].Op = (*((unsigned char *)(return_block->bl_data)));\r
699\r
700 switch (return_block->bl_len)\r
41d6f5f7 701 {\r
0203b5fd 702 case 5:\r
41d6f5f7 703 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));\r
0203b5fd
JPM
704 break;\r
705\r
706 default:\r
707 break;\r
41d6f5f7
JPM
708 }\r
709 dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);\r
ebcb0f3d 710 }\r
41d6f5f7 711 break;\r
ebcb0f3d 712\r
65597951 713 case DW_AT_type:\r
41d6f5f7
JPM
714 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
715 {\r
716 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].TypeOffset = return_offset;\r
717 }\r
718 break;\r
ebcb0f3d 719\r
65597951
JPM
720 // Variable name\r
721 case DW_AT_name:\r
41d6f5f7
JPM
722 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
723 {\r
0203b5fd
JPM
724#ifdef DEBUG_VariableName\r
725 if (!strcmp(return_string, DEBUG_VariableName))\r
726#endif\r
727 {\r
728 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
729 strcpy(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName, return_string);\r
0203b5fd 730 }\r
f8dde18d 731 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
41d6f5f7
JPM
732 }\r
733 break;\r
ebcb0f3d 734\r
65597951 735 default:\r
41d6f5f7
JPM
736 break;\r
737 }\r
ebcb0f3d
JPM
738 }\r
739 }\r
ebcb0f3d 740\r
41d6f5f7
JPM
741 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
742 }\r
ebcb0f3d 743\r
ce32526a
JPM
744 // Check variable's name validity\r
745 if (PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName)\r
746 {\r
747 // Check variable's memory address validity\r
748 if (PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].Addr)\r
749 {\r
750 // Valid variable\r
751 PtrCU[NbCU].NbVariables++;\r
752 }\r
753 else\r
754 {\r
755 // Invalid variable\r
756 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);\r
757 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName = NULL;\r
758 }\r
759 }\r
ebcb0f3d 760\r
41d6f5f7 761 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
ebcb0f3d 762 }\r
41d6f5f7
JPM
763 break;\r
764\r
65597951
JPM
765 case DW_TAG_base_type:\r
766 case DW_TAG_typedef:\r
767 case DW_TAG_structure_type:\r
768 case DW_TAG_pointer_type:\r
769 case DW_TAG_const_type:\r
770 case DW_TAG_array_type:\r
771 case DW_TAG_subrange_type:\r
772 case DW_TAG_subroutine_type:\r
f8dde18d 773 case DW_TAG_enumeration_type:\r
41d6f5f7 774 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 775 {\r
f8dde18d 776 // Allocate memory for this type\r
41d6f5f7
JPM
777 PtrCU[NbCU].PtrTypes = (BaseTypeStruct *)realloc(PtrCU[NbCU].PtrTypes, ((PtrCU[NbCU].NbTypes + 1) * sizeof(BaseTypeStruct)));\r
778 memset(PtrCU[NbCU].PtrTypes + PtrCU[NbCU].NbTypes, 0, sizeof(BaseTypeStruct));\r
779 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Tag = return_tagval;\r
780\r
781 if (dwarf_dieoffset(return_die, &return_offset, &error) == DW_DLV_OK)\r
782 {\r
783 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Offset = return_offset;\r
784 }\r
785\r
786 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 787 {\r
41d6f5f7 788 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 789 {\r
41d6f5f7 790 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
ebcb0f3d 791 {\r
41d6f5f7 792 switch (return_attr)\r
ebcb0f3d 793 {\r
f8dde18d
JPM
794 // \r
795 case DW_AT_sibling:\r
796 break;\r
797\r
798 // Type's type offset\r
65597951 799 case DW_AT_type:\r
41d6f5f7
JPM
800 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
801 {\r
802 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].TypeOffset = return_offset;\r
803 }\r
804 break;\r
ebcb0f3d 805\r
f8dde18d 806 // Type's byte size\r
65597951 807 case DW_AT_byte_size:\r
41d6f5f7
JPM
808 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
809 {\r
810 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].ByteSize = return_uvalue;\r
811 }\r
812 break;\r
ebcb0f3d 813\r
f8dde18d 814 // Type's encoding\r
65597951 815 case DW_AT_encoding:\r
41d6f5f7
JPM
816 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
817 {\r
818 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Encoding = return_uvalue;\r
819 }\r
820 break;\r
ebcb0f3d 821\r
f8dde18d 822 // Type's name\r
65597951 823 case DW_AT_name:\r
41d6f5f7
JPM
824 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
825 {\r
f8dde18d
JPM
826#ifdef DEBUG_TypeName\r
827 if (!strcmp(return_string, DEBUG_TypeName))\r
828#endif\r
829 {\r
830 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
831 strcpy(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName, return_string);\r
832 }\r
41d6f5f7
JPM
833 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
834 }\r
835 break;\r
ebcb0f3d 836\r
f8dde18d
JPM
837 // Type's file number\r
838 case DW_AT_decl_file:\r
839 break;\r
840\r
841 // Type's line number\r
842 case DW_AT_decl_line:\r
843 break;\r
844\r
845 default:\r
41d6f5f7
JPM
846 break;\r
847 }\r
ebcb0f3d
JPM
848 }\r
849 }\r
ebcb0f3d 850\r
41d6f5f7
JPM
851 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
852 }\r
ebcb0f3d 853\r
41d6f5f7 854 PtrCU[NbCU].NbTypes++;\r
ebcb0f3d 855\r
41d6f5f7
JPM
856 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
857 }\r
858 break;\r
ebcb0f3d 859\r
65597951 860 case DW_TAG_subprogram:\r
41d6f5f7 861 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 862 {\r
41d6f5f7
JPM
863 PtrCU[NbCU].PtrSubProgs = (SubProgStruct *)realloc(PtrCU[NbCU].PtrSubProgs, ((PtrCU[NbCU].NbSubProgs + 1) * sizeof(SubProgStruct)));\r
864 memset((void *)(PtrCU[NbCU].PtrSubProgs + PtrCU[NbCU].NbSubProgs), 0, sizeof(SubProgStruct));\r
865 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].Tag = return_tagval;\r
866\r
867 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 868 {\r
41d6f5f7 869 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 870 {\r
41d6f5f7 871 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
ebcb0f3d 872 {\r
41d6f5f7 873 switch (return_attr)\r
ebcb0f3d 874 {\r
65597951 875 // start address\r
0203b5fd 876 case DW_AT_low_pc:\r
41d6f5f7
JPM
877 if (dwarf_lowpc(return_die, &return_lowpc, &error) == DW_DLV_OK)\r
878 {\r
879 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].StartPC = return_lowpc;\r
880 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].LowPC = return_lowpc;\r
881 }\r
882 break;\r
ebcb0f3d 883\r
65597951 884 // end address\r
0203b5fd 885 case DW_AT_high_pc:\r
41d6f5f7
JPM
886 if (dwarf_highpc(return_die, &return_highpc, &error) == DW_DLV_OK)\r
887 {\r
888 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].HighPC = return_highpc;\r
889 }\r
890 break;\r
ebcb0f3d 891\r
65597951 892 // Line number\r
0203b5fd 893 case DW_AT_decl_line:\r
41d6f5f7
JPM
894 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
895 {\r
896 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NumLineSrc = return_uvalue;\r
897 }\r
898 break;\r
ebcb0f3d 899\r
65597951 900 // Frame\r
0203b5fd
JPM
901 case DW_AT_frame_base:\r
902 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
903 {\r
904 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].FrameBase = return_uvalue;\r
65597951 905 PtrCU[NbCU].NbFrames++;\r
0203b5fd
JPM
906 }\r
907 break;\r
908\r
65597951 909 // function name\r
0203b5fd 910 case DW_AT_name:\r
41d6f5f7
JPM
911 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
912 {\r
913 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName = (char *)calloc(strlen(return_string) + 1, 1);\r
914 strcpy(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName, return_string);\r
915 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
916 }\r
917 break;\r
ebcb0f3d 918\r
65597951
JPM
919 case DW_AT_sibling:\r
920 break;\r
921\r
922 case DW_AT_GNU_all_tail_call_sites:\r
923 break;\r
924\r
925 case DW_AT_type:\r
926 break;\r
927\r
928 case DW_AT_prototyped:\r
929 break;\r
930\r
931 // File number\r
932 case DW_AT_decl_file:\r
933 break;\r
934\r
935 case DW_AT_external:\r
936 break;\r
937\r
41d6f5f7
JPM
938 default:\r
939 break;\r
940 }\r
ebcb0f3d
JPM
941 }\r
942 }\r
41d6f5f7 943 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
ebcb0f3d 944 }\r
41d6f5f7 945 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
ebcb0f3d 946\r
f8dde18d 947 // Get source line number and associated block of address\r
ce32526a 948 for (Dwarf_Signed i = 0; i < cnt; ++i)\r
ebcb0f3d 949 {\r
009df4d7
JPM
950 // Check the presence of the line in the memory frame\r
951 if (PtrCU[NbCU].PtrUsedLinesSrc && (PtrCU[NbCU].PtrUsedLinesSrc[i].StartPC >= return_lowpc) && (PtrCU[NbCU].PtrUsedLinesSrc[i].StartPC <= return_highpc))\r
ebcb0f3d 952 {\r
258b1c16
JPM
953 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));\r
954 memset((void *)(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc), 0, sizeof(DMIStruct_LineSrc));\r
aae93d86
JPM
955 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].StartPC = PtrCU[NbCU].PtrUsedLinesSrc[i].StartPC;\r
956 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].NumLineSrc = PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc;\r
258b1c16 957 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc++;\r
ebcb0f3d 958 }\r
41d6f5f7
JPM
959 }\r
960\r
0203b5fd
JPM
961 if (dwarf_child(return_die, &return_subdie, &error) == DW_DLV_OK)\r
962 {\r
963 do\r
964 {\r
965 return_sub = return_subdie;\r
966 if ((dwarf_tag(return_subdie, &return_tagval, &error) == DW_DLV_OK))\r
967 {\r
968 switch (return_tagval)\r
969 {\r
970 case DW_TAG_formal_parameter:\r
971 case DW_TAG_variable:\r
972 if (dwarf_attrlist(return_subdie, &atlist, &atcnt, &error) == DW_DLV_OK)\r
973 {\r
974 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)));\r
975 memset(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables, 0, sizeof(VariablesStruct));\r
976\r
977 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
978 {\r
979 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
980 {\r
981 if (dwarf_attr(return_subdie, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
982 {\r
983 switch (return_attr)\r
984 {\r
65597951 985 case DW_AT_location:\r
0203b5fd
JPM
986 if (dwarf_formblock(return_attr1, &return_block, &error) == DW_DLV_OK)\r
987 {\r
988 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Op = *((unsigned char *)(return_block->bl_data));\r
989\r
990 switch (return_block->bl_len)\r
991 {\r
992 case 1:\r
993 break;\r
994\r
995 case 2:\r
f8dde18d 996 case 3:\r
47b6ecae 997 switch (return_tagval)\r
0203b5fd 998 {\r
65597951 999 case DW_TAG_variable:\r
f8dde18d 1000 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Offset = ReadLEB128((char *)return_block->bl_data + 1);\r
47b6ecae
JPM
1001 break;\r
1002\r
65597951 1003 case DW_TAG_formal_parameter:\r
f8dde18d 1004 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Offset = ReadULEB128((char *)return_block->bl_data + 1);\r
47b6ecae
JPM
1005 break;\r
1006\r
1007 default:\r
1008 break;\r
0203b5fd 1009 }\r
f8dde18d 1010 break;\r
0203b5fd
JPM
1011\r
1012 default:\r
1013 break;\r
1014 }\r
1015 dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);\r
1016 }\r
1017 break;\r
1018\r
65597951 1019 case DW_AT_type:\r
0203b5fd
JPM
1020 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
1021 {\r
1022 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].TypeOffset = return_offset;\r
1023 }\r
1024 break;\r
1025\r
65597951 1026 case DW_AT_name:\r
0203b5fd
JPM
1027 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
1028 {\r
1029#ifdef DEBUG_VariableName\r
1030 if (!strcmp(return_string, DEBUG_VariableName))\r
1031#endif\r
1032 {\r
1033 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
1034 strcpy(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName, return_string);\r
0203b5fd 1035 }\r
f8dde18d 1036 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
0203b5fd
JPM
1037 }\r
1038 break;\r
1039\r
65597951 1040 case DW_AT_decl_file:\r
47b6ecae
JPM
1041 break;\r
1042\r
65597951 1043 case DW_AT_decl_line:\r
47b6ecae
JPM
1044 break;\r
1045\r
0203b5fd
JPM
1046 default:\r
1047 break;\r
1048 }\r
1049 }\r
1050 }\r
1051\r
1052 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
1053 }\r
1054\r
1055 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables++;\r
1056\r
1057 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
1058 }\r
1059 break;\r
1060\r
1061 case DW_TAG_label:\r
1062 break;\r
1063\r
1064 default:\r
1065 break;\r
1066 }\r
1067 }\r
1068 }\r
1069 while (dwarf_siblingof(dbg, return_sub, &return_subdie, &error) == DW_DLV_OK);\r
1070 }\r
1071\r
41d6f5f7 1072 PtrCU[NbCU].NbSubProgs++;\r
ebcb0f3d 1073 }\r
41d6f5f7 1074 break;\r
ebcb0f3d 1075\r
41d6f5f7
JPM
1076 default:\r
1077 break;\r
1078 }\r
ebcb0f3d 1079 }\r
0203b5fd
JPM
1080 }\r
1081 while (dwarf_siblingof(dbg, return_sib, &return_die, &error) == DW_DLV_OK);\r
ebcb0f3d 1082 }\r
41d6f5f7 1083 }\r
ebcb0f3d 1084\r
aae93d86 1085 // Set the source code lines\r
41d6f5f7 1086 if (PtrCU[NbCU].NbLinesLoadSrc)\r
ebcb0f3d 1087 {\r
41d6f5f7 1088 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(PtrCU[NbCU].NbLinesLoadSrc, sizeof(char *)))\r
ebcb0f3d 1089 {\r
ce32526a 1090 for (size_t j = 0; j < PtrCU[NbCU].NbLinesLoadSrc; j++)\r
ebcb0f3d 1091 {\r
41d6f5f7 1092 if (PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)calloc(10000, sizeof(char)))\r
ebcb0f3d 1093 {\r
41d6f5f7 1094 if (Ptr = DWARFManager_GetLineSrcFromNumLine(PtrCU[NbCU].PtrLoadSrc, (j + 1)))\r
ebcb0f3d 1095 {\r
2c837f2e
JPM
1096#ifndef CONVERT_QT_HML\r
1097 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], Ptr);\r
1098#else\r
ce32526a 1099 size_t i = 0;\r
41d6f5f7
JPM
1100\r
1101 while (*Ptr)\r
ebcb0f3d 1102 {\r
41d6f5f7
JPM
1103 switch (*Ptr)\r
1104 {\r
1105 case 9:\r
1106 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");\r
ce32526a 1107 i += 6;\r
41d6f5f7
JPM
1108 break;\r
1109\r
1110 case '<':\r
1111 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&lt;");\r
ce32526a 1112 i += 4;\r
41d6f5f7
JPM
1113 break;\r
1114\r
1115 case '>':\r
1116 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&gt;");\r
ce32526a 1117 i += 4;\r
41d6f5f7 1118 break;\r
ebcb0f3d 1119#if 0\r
41d6f5f7
JPM
1120 case '&':\r
1121 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&amp;");\r
1122 i += strlen("&amp;");\r
1123 break;\r
ebcb0f3d
JPM
1124#endif\r
1125#if 0\r
41d6f5f7
JPM
1126 case '"':\r
1127 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");\r
1128 i += strlen("&quot;");\r
1129 break;\r
ebcb0f3d 1130#endif\r
41d6f5f7
JPM
1131 default:\r
1132 PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;\r
1133 break;\r
1134 }\r
1135 Ptr++;\r
ebcb0f3d 1136 }\r
2c837f2e 1137#endif\r
ebcb0f3d 1138 }\r
ce32526a 1139 PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)realloc(PtrCU[NbCU].PtrLinesLoadSrc[j], strlen(PtrCU[NbCU].PtrLinesLoadSrc[j]) + 1);\r
ebcb0f3d 1140 }\r
ebcb0f3d 1141 }\r
95fe01d7 1142\r
5fa7aa73 1143 // Init lines source information for each source code line numbers and for each subprogs\r
ce32526a 1144 for (size_t j = 0; j < PtrCU[NbCU].NbSubProgs; j++)\r
95fe01d7
JPM
1145 {\r
1146 // Check if the subprog / function's line exists in the source code\r
1147 if (PtrCU[NbCU].PtrSubProgs[j].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
1148 {\r
1149 PtrCU[NbCU].PtrSubProgs[j].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].NumLineSrc - 1];\r
1150 }\r
1151\r
ce32526a 1152 for (size_t k = 0; k < PtrCU[NbCU].PtrSubProgs[j].NbLinesSrc; k++)\r
95fe01d7
JPM
1153 {\r
1154 if (PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
1155 {\r
1156 PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc - 1];\r
1157 }\r
1158 }\r
1159 }\r
ebcb0f3d
JPM
1160 }\r
1161 }\r
41d6f5f7 1162 else\r
ebcb0f3d 1163 {\r
41d6f5f7
JPM
1164 // Set each source lines pointer to NULL\r
1165 if (PtrCU[NbCU].NbSubProgs)\r
ebcb0f3d 1166 {\r
95fe01d7
JPM
1167 // Check the presence of source lines dedicated to the sub progs\r
1168 if (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc)\r
ebcb0f3d 1169 {\r
ce32526a 1170 size_t i = PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc - 1].NumLineSrc;\r
95fe01d7 1171 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(i, sizeof(char *)))\r
41d6f5f7 1172 {\r
ce32526a 1173 for (size_t j = 0; j < i; j++)\r
95fe01d7
JPM
1174 {\r
1175 PtrCU[NbCU].PtrLinesLoadSrc[j] = NULL;\r
1176 }\r
41d6f5f7 1177 }\r
ebcb0f3d
JPM
1178 }\r
1179 }\r
1180 }\r
ebcb0f3d 1181\r
aae93d86
JPM
1182 // Check validity between used number lines and number lines in the source file\r
1183 if (PtrCU[NbCU].LastNumUsedLinesSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
5fa7aa73 1184 {\r
aae93d86
JPM
1185 // Set information based on used line numbers\r
1186 if (PtrCU[NbCU].PtrUsedLinesSrc)\r
5fa7aa73 1187 {\r
aae93d86
JPM
1188 // Set the line source pointers for each used line numbers\r
1189 if (PtrCU[NbCU].PtrLinesLoadSrc)\r
5fa7aa73 1190 {\r
aae93d86
JPM
1191 for (size_t i = 0; i < PtrCU[NbCU].NbUsedLinesSrc; i++)\r
1192 {\r
1193 PtrCU[NbCU].PtrUsedNumLines[i] = PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc - 1;\r
1194 PtrCU[NbCU].PtrUsedLinesLoadSrc[i] = PtrCU[NbCU].PtrUsedLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc - 1];\r
1195 }\r
0536c3ba 1196\r
aae93d86
JPM
1197 // Setup memory range for the code if CU doesn't have already this information\r
1198 // It is taken from the used lines structure\r
1199 if (!PtrCU[NbCU].LowPC && (!PtrCU[NbCU].HighPC || (PtrCU[NbCU].HighPC == ~0)))\r
1200 {\r
1201 PtrCU[NbCU].LowPC = PtrCU[NbCU].PtrUsedLinesSrc[0].StartPC;\r
1202 PtrCU[NbCU].HighPC = PtrCU[NbCU].PtrUsedLinesSrc[PtrCU[NbCU].NbUsedLinesSrc - 1].StartPC;\r
1203 }\r
0536c3ba 1204 }\r
5fa7aa73 1205 }\r
5fa7aa73
JPM
1206 }\r
1207\r
0203b5fd 1208 // Init global variables information based on types information\r
ce32526a 1209 for (size_t i = 0; i < PtrCU[NbCU].NbVariables; i++)\r
ebcb0f3d 1210 {\r
0203b5fd
JPM
1211 DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrVariables + i);\r
1212 }\r
41d6f5f7 1213\r
0203b5fd 1214 // Init local variables information based on types information\r
ce32526a 1215 for (size_t i = 0; i < PtrCU[NbCU].NbSubProgs; i++)\r
0203b5fd 1216 {\r
ce32526a 1217 for (size_t j = 0; j < PtrCU[NbCU].PtrSubProgs[i].NbVariables; j++)\r
ebcb0f3d 1218 {\r
0203b5fd 1219 DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrSubProgs[i].PtrVariables + j);\r
ebcb0f3d
JPM
1220 }\r
1221 }\r
1222 }\r
1223\r
1224 ++NbCU;\r
1225 }\r
1226 } \r
ebcb0f3d
JPM
1227}\r
1228\r
1229\r
aae93d86
JPM
1230// Conform slashes and backslashes\r
1231void DWARFManager_ConformSlachesBackslashes(char *Ptr)\r
1232{\r
1233 while (*Ptr)\r
1234 {\r
1235#if defined(_WIN32)\r
1236 if (*Ptr == '/')\r
1237 {\r
1238 *Ptr = '\\';\r
1239 }\r
1240#else\r
1241 if (*Ptr == '\\')\r
1242 {\r
1243 *Ptr = '/';\r
1244 }\r
1245#endif\r
1246 Ptr++;\r
1247 }\r
1248}\r
1249\r
1250\r
65597951 1251// Variables information initialisation\r
0203b5fd
JPM
1252void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)\r
1253{\r
1254 size_t j, TypeOffset;\r
1255\r
f8dde18d
JPM
1256#ifdef DEBUG_VariableName\r
1257 if (PtrVariables->PtrName && !strcmp(PtrVariables->PtrName, DEBUG_VariableName))\r
1258#endif\r
0203b5fd 1259 {\r
f8dde18d
JPM
1260 PtrVariables->PtrTypeName = (char *)calloc(1000, 1);\r
1261 TypeOffset = PtrVariables->TypeOffset;\r
1262\r
1263 for (j = 0; j < PtrCU[NbCU].NbTypes; j++)\r
0203b5fd 1264 {\r
f8dde18d 1265 if (TypeOffset == PtrCU[NbCU].PtrTypes[j].Offset)\r
0203b5fd 1266 {\r
f8dde18d 1267 switch (PtrCU[NbCU].PtrTypes[j].Tag)\r
0203b5fd 1268 {\r
f8dde18d
JPM
1269 case DW_TAG_subroutine_type:\r
1270 PtrVariables->TypeTag |= TypeTag_subroutine_type;\r
1271 strcat(PtrVariables->PtrTypeName, " (* ) ()");\r
1272 break;\r
1273\r
1274 // Structure type tag\r
1275 case DW_TAG_structure_type:\r
1276 PtrVariables->TypeTag |= TypeTag_structure;\r
1277 if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
0203b5fd 1278 {\r
f951022b
JPM
1279 if (PtrCU[NbCU].PtrTypes[j].PtrName)\r
1280 {\r
1281 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
1282 }\r
0203b5fd 1283 }\r
f8dde18d
JPM
1284 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1285 {\r
1286 j = -1;\r
1287 }\r
1288 else\r
1289 {\r
1290 if ((PtrVariables->TypeTag & TypeTag_pointer))\r
1291 {\r
1292 strcat(PtrVariables->PtrTypeName, " *");\r
1293 }\r
1294 }\r
1295 break;\r
0203b5fd 1296\r
f8dde18d
JPM
1297 // Pointer type tag\r
1298 case DW_TAG_pointer_type:\r
1299 PtrVariables->TypeTag |= TypeTag_pointer;\r
1300 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
1301 PtrVariables->TypeEncoding = 0x10;\r
1302 if (!(TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1303 {\r
1304 strcat(PtrVariables->PtrTypeName, "void *");\r
1305 }\r
1306 else\r
1307 {\r
1308 j = -1;\r
1309 }\r
1310 break;\r
0203b5fd 1311\r
f8dde18d
JPM
1312 case DW_TAG_enumeration_type:\r
1313 PtrVariables->TypeTag |= TypeTag_enumeration_type;\r
1314 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
1315 if (!(PtrVariables->TypeEncoding = PtrCU[NbCU].PtrTypes[j].Encoding))\r
1316 {\r
1317 // Try to determine the possible size\r
1318 switch (PtrVariables->TypeByteSize)\r
1319 {\r
1320 case 4:\r
1321 PtrVariables->TypeEncoding = 0x7;\r
1322 break;\r
0203b5fd 1323\r
f8dde18d
JPM
1324 default:\r
1325 break;\r
1326 }\r
1327 }\r
1328 break;\r
0203b5fd 1329\r
f8dde18d
JPM
1330 // Typedef type tag\r
1331 case DW_TAG_typedef:\r
1332 if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
1333 {\r
1334 PtrVariables->TypeTag |= TypeTag_typedef;\r
1335 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
1336 }\r
1337 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1338 {\r
1339 j = -1;\r
1340 }\r
1341 break;\r
0203b5fd 1342\r
f8dde18d
JPM
1343 // ? type tag\r
1344 case DW_TAG_subrange_type:\r
1345 PtrVariables->TypeTag |= TypeTag_subrange;\r
1346 break;\r
0203b5fd 1347\r
f8dde18d
JPM
1348 // Array type tag\r
1349 case DW_TAG_array_type:\r
1350 PtrVariables->TypeTag |= TypeTag_arraytype;\r
1351 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1352 {\r
1353 j = -1;\r
1354 }\r
1355 break;\r
1356\r
1357 // Const type tag\r
1358 case DW_TAG_const_type:\r
1359 PtrVariables->TypeTag |= TypeTag_consttype;\r
1360 strcat(PtrVariables->PtrTypeName, "const ");\r
1361 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1362 {\r
1363 j = -1;\r
1364 }\r
1365 break;\r
1366\r
1367 // Base type tag\r
1368 case DW_TAG_base_type:\r
1369 if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
1370 {\r
1371 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
1372 }\r
1373 if ((PtrVariables->TypeTag & TypeTag_pointer))\r
1374 {\r
1375 strcat(PtrVariables->PtrTypeName, " *");\r
1376 }\r
1377 else\r
1378 {\r
1379 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
1380 PtrVariables->TypeEncoding = PtrCU[NbCU].PtrTypes[j].Encoding;\r
1381 }\r
1382 if ((PtrVariables->TypeTag & TypeTag_arraytype))\r
1383 {\r
1384 strcat(PtrVariables->PtrTypeName, "[]");\r
1385 }\r
1386 break;\r
1387\r
1388 default:\r
1389 break;\r
1390 }\r
0203b5fd
JPM
1391 }\r
1392 }\r
1393 }\r
1394}\r
1395\r
1396\r
ebcb0f3d
JPM
1397// Get symbol name based from address\r
1398// Return NULL if no symbol name exists\r
1399char *DWARFManager_GetSymbolnameFromAdr(size_t Adr)\r
1400{\r
f0dd2f7b 1401 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1402 {\r
1403 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1404 {\r
f0dd2f7b 1405 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
ebcb0f3d
JPM
1406 {\r
1407 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr))\r
1408 {\r
1409 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;\r
1410 }\r
1411 }\r
1412 }\r
1413 }\r
1414\r
1415 return NULL;\r
1416}\r
1417\r
1418\r
1419// Get complete source filename based from address\r
1420// Return NULL if no source filename exists\r
009df4d7
JPM
1421// Return the existence status in Status if pointer not NULL\r
1422char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, DWARFstatus *Status)\r
ebcb0f3d 1423{\r
f0dd2f7b 1424 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1425 {\r
1426 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1427 {\r
009df4d7 1428 if (Status)\r
e27f08e7 1429 {\r
009df4d7 1430 *Status = PtrCU[i].Status;\r
e27f08e7
JPM
1431 }\r
1432\r
ebcb0f3d
JPM
1433 return PtrCU[i].PtrFullFilename;\r
1434 }\r
1435 }\r
1436\r
1437 return NULL;\r
1438}\r
1439\r
1440\r
f0dd2f7b 1441// Get text line source based on line number (starting from 1)\r
ebcb0f3d
JPM
1442// Return NULL if no text line exists or if line number is 0\r
1443char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine)\r
1444{\r
1445 size_t i = 0;\r
1446 char *PtrLineSrc = NULL;\r
1447\r
1448 if (PtrSrcFile)\r
1449 {\r
1450 while (i != NumLine)\r
1451 {\r
1452 PtrLineSrc = PtrSrcFile;\r
1453 while (*PtrSrcFile++);\r
1454 i++;\r
1455 }\r
1456 }\r
1457\r
1458 return PtrLineSrc;\r
1459}\r
1460\r
1461\r
0203b5fd
JPM
1462// Get number of variables referenced by the function range address\r
1463size_t DWARFManager_GetNbLocalVariables(size_t Adr)\r
1464{\r
f0dd2f7b 1465 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1466 {\r
1467 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1468 {\r
f0dd2f7b 1469 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1470 {\r
1471 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1472 {\r
1473 return PtrCU[i].PtrSubProgs[j].NbVariables;\r
1474 }\r
1475 }\r
1476 }\r
1477 }\r
1478\r
1479 return 0;\r
1480}\r
1481\r
1482\r
f0dd2f7b 1483// Get local variable name based on his index (starting from 1)\r
0203b5fd
JPM
1484// Return name's pointer text found\r
1485// Return NULL if not found\r
1486char *DWARFManager_GetLocalVariableName(size_t Adr, size_t Index)\r
1487{\r
f0dd2f7b 1488 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1489 {\r
1490 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1491 {\r
f0dd2f7b 1492 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1493 {\r
1494 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1495 {\r
1496 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].PtrName;\r
1497 }\r
1498 }\r
1499 }\r
1500 }\r
1501\r
1502 return NULL;\r
1503}\r
1504\r
1505\r
f0dd2f7b 1506// Get local variable's type tag based on his index (starting from 1)\r
0203b5fd
JPM
1507// Return 0 if not found\r
1508size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr, size_t Index)\r
1509{\r
f0dd2f7b 1510 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1511 {\r
1512 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1513 {\r
f0dd2f7b 1514 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1515 {\r
1516 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1517 {\r
1518 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeTag;\r
1519 }\r
1520 }\r
1521 }\r
1522 }\r
1523\r
1524 return 0;\r
1525}\r
1526\r
1527\r
f0dd2f7b
JPM
1528// Get the local variable's offset based on a index (starting from 1)\r
1529// Return 0 if no offset has been found\r
0203b5fd
JPM
1530int DWARFManager_GetLocalVariableOffset(size_t Adr, size_t Index)\r
1531{\r
f0dd2f7b 1532 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1533 {\r
1534 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1535 {\r
f0dd2f7b 1536 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1537 {\r
1538 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1539 {\r
1540 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].Offset;\r
1541 }\r
1542 }\r
1543 }\r
1544 }\r
1545\r
1546 return 0;\r
1547}\r
1548\r
1549\r
f0dd2f7b 1550// Get local variable Type Byte Size based on his address and index (starting from 1)\r
0203b5fd
JPM
1551// Return 0 if not found\r
1552// May return 0 if there is no Type Byte Size linked to the variable's address and index\r
1553size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr, size_t Index)\r
1554{\r
f0dd2f7b 1555 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1556 {\r
1557 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1558 {\r
f0dd2f7b 1559 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1560 {\r
1561 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1562 {\r
1563 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeByteSize;\r
1564 }\r
1565 }\r
1566 }\r
1567 }\r
1568\r
1569 return 0;\r
1570}\r
1571\r
1572\r
f0dd2f7b 1573// Get local variable Type Encoding based on his address and index (starting from 1)\r
0203b5fd
JPM
1574// Return 0 if not found\r
1575// May return 0 if there is no Type Encoding linked to the variable's address and index\r
1576size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr, size_t Index)\r
1577{\r
f0dd2f7b 1578 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1579 {\r
1580 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1581 {\r
f0dd2f7b 1582 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1583 {\r
1584 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1585 {\r
1586 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeEncoding;\r
1587 }\r
1588 }\r
1589 }\r
1590 }\r
1591\r
1592 return 0;\r
1593}\r
1594\r
1595\r
f0dd2f7b 1596// Get local variable Op based on his address and index (starting from 1)\r
5fa7aa73 1597// Return 0 if not found, may return 0 if there isn't Op linked to the variable's index\r
0203b5fd
JPM
1598size_t DWARFManager_GetLocalVariableOp(size_t Adr, size_t Index)\r
1599{\r
f0dd2f7b 1600 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1601 {\r
1602 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1603 {\r
f0dd2f7b 1604 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1605 {\r
1606 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1607 {\r
1608 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].Op;\r
1609 }\r
1610 }\r
1611 }\r
1612 }\r
1613\r
1614 return 0;\r
1615}\r
1616\r
1617\r
f0dd2f7b 1618// Get local variable type name based on his index (starting from 1) and an address\r
5fa7aa73 1619// Return NULL if not found, may also return NULL if there is no type linked to the variable's index\r
0203b5fd
JPM
1620char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)\r
1621{\r
f0dd2f7b 1622 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1623 {\r
1624 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1625 {\r
f0dd2f7b 1626 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1627 {\r
1628 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1629 {\r
1630 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].PtrTypeName;\r
1631 }\r
1632 }\r
1633 }\r
1634 }\r
1635\r
1636 return NULL;\r
1637}\r
1638\r
1639\r
1640// Get Compilation Unit / global variables numbers\r
5fa7aa73 1641// Return number of variables\r
0203b5fd 1642size_t DWARFManager_GetNbGlobalVariables(void)\r
ebcb0f3d 1643{\r
f0dd2f7b 1644 size_t NbVariables = 0;\r
ebcb0f3d 1645\r
f0dd2f7b 1646 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1647 {\r
1648 NbVariables += PtrCU[i].NbVariables;\r
1649 }\r
1650\r
1651 return NbVariables;\r
1652}\r
1653\r
1654\r
f0dd2f7b 1655// Get global variable type name based on his index (starting from 1)\r
ebcb0f3d
JPM
1656// Return NULL if not found\r
1657// May return NULL if there is not type linked to the variable's index\r
0203b5fd 1658char *DWARFManager_GetGlobalVariableTypeName(size_t Index)\r
ebcb0f3d 1659{\r
f0dd2f7b 1660 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1661 {\r
1662 if (PtrCU[i].NbVariables)\r
1663 {\r
1664 if (Index <= PtrCU[i].NbVariables)\r
1665 {\r
1666 return PtrCU[i].PtrVariables[Index - 1].PtrTypeName;\r
1667 }\r
1668 else\r
1669 {\r
1670 Index -= PtrCU[i].NbVariables;\r
1671 }\r
1672 }\r
1673 }\r
1674\r
1675 return NULL;\r
1676}\r
1677\r
1678\r
f0dd2f7b 1679// Get global variable's type tag based on his index (starting from 1)\r
ebcb0f3d 1680// Return 0 if not found\r
0203b5fd 1681size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index)\r
ebcb0f3d 1682{\r
f0dd2f7b 1683 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1684 {\r
1685 if (PtrCU[i].NbVariables)\r
1686 {\r
1687 if (Index <= PtrCU[i].NbVariables)\r
1688 {\r
1689 return PtrCU[i].PtrVariables[Index - 1].TypeTag;\r
1690 }\r
1691 else\r
1692 {\r
1693 Index -= PtrCU[i].NbVariables;\r
1694 }\r
1695 }\r
1696 }\r
1697\r
1698 return 0;\r
1699}\r
1700\r
1701\r
f0dd2f7b 1702// Get global variable byte size based on his index (starting from 1)\r
ebcb0f3d 1703// Return 0 if not found\r
0203b5fd 1704size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index)\r
ebcb0f3d 1705{\r
f0dd2f7b 1706 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1707 {\r
1708 if (PtrCU[i].NbVariables)\r
1709 {\r
1710 if (Index <= PtrCU[i].NbVariables)\r
1711 {\r
1712 return PtrCU[i].PtrVariables[Index - 1].TypeByteSize;\r
1713 }\r
1714 else\r
1715 {\r
1716 Index -= PtrCU[i].NbVariables;\r
1717 }\r
1718 }\r
1719 }\r
1720\r
1721 return 0;\r
1722}\r
1723\r
1724\r
f0dd2f7b 1725// Get global variable encoding based on his index (starting from 1)\r
ebcb0f3d 1726// Return 0 if not found\r
0203b5fd 1727size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index)\r
ebcb0f3d 1728{\r
f0dd2f7b 1729 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1730 {\r
1731 if (PtrCU[i].NbVariables)\r
1732 {\r
1733 if (Index <= PtrCU[i].NbVariables)\r
1734 {\r
1735 return PtrCU[i].PtrVariables[Index - 1].TypeEncoding;\r
1736 }\r
1737 else\r
1738 {\r
1739 Index -= PtrCU[i].NbVariables;\r
1740 }\r
1741 }\r
1742 }\r
1743\r
1744 return 0;\r
1745}\r
1746\r
1747\r
f0dd2f7b 1748// Get global variable memory address based on his index (starting from 1)\r
ebcb0f3d 1749// Return 0 if not found\r
0203b5fd 1750size_t DWARFManager_GetGlobalVariableAdr(size_t Index)\r
ebcb0f3d 1751{\r
f0dd2f7b 1752 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1753 {\r
1754 if (PtrCU[i].NbVariables)\r
1755 {\r
1756 if (Index <= PtrCU[i].NbVariables)\r
1757 {\r
1758 return PtrCU[i].PtrVariables[Index - 1].Addr;\r
1759 }\r
1760 else\r
1761 {\r
1762 Index -= PtrCU[i].NbVariables;\r
1763 }\r
1764 }\r
1765 }\r
1766\r
1767 return 0;\r
1768}\r
1769\r
1770\r
0203b5fd 1771// Get global variable memory address based on his name\r
5fa7aa73 1772// Return 0 if not found, or will return the first occurence found\r
0203b5fd 1773size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)\r
ebcb0f3d 1774{\r
f0dd2f7b 1775 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1776 {\r
1777 if (PtrCU[i].NbVariables)\r
1778 {\r
f0dd2f7b 1779 for (size_t j = 0; j < PtrCU[i].NbVariables; j++)\r
ebcb0f3d
JPM
1780 {\r
1781 if (!strcmp(PtrCU[i].PtrVariables[j].PtrName,VariableName))\r
1782 {\r
1783 return PtrCU[i].PtrVariables[j].Addr;\r
1784 }\r
1785 }\r
1786 }\r
1787 }\r
1788\r
1789 return 0;\r
1790}\r
1791\r
1792\r
f0dd2f7b 1793// Get global variable name based on his index (starting from 1)\r
5fa7aa73 1794// Return name's pointer text found, or will return NULL if no variable can be found\r
0203b5fd 1795char *DWARFManager_GetGlobalVariableName(size_t Index)\r
ebcb0f3d 1796{\r
f0dd2f7b 1797 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1798 {\r
1799 if (PtrCU[i].NbVariables)\r
1800 {\r
1801 if (Index <= PtrCU[i].NbVariables)\r
1802 {\r
1803 return PtrCU[i].PtrVariables[Index - 1].PtrName;\r
1804 }\r
1805 else\r
1806 {\r
1807 Index -= PtrCU[i].NbVariables;\r
1808 }\r
1809 }\r
1810 }\r
1811\r
1812 return NULL;\r
1813}\r
1814\r
1815\r
1816// Get text line from source based on address and his tag\r
5fa7aa73
JPM
1817// A tag can be either 0 or a DW_TAG_subprogram\r
1818// DW_TAG_subprogram will look for the line pointing to the function\r
ebcb0f3d
JPM
1819// Return NULL if no text line has been found\r
1820char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)\r
1821{\r
f0dd2f7b 1822 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1823 {\r
1824 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1825 {\r
f0dd2f7b 1826 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
ebcb0f3d
JPM
1827 {\r
1828 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1829 {\r
1830 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))\r
1831 {\r
1832 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;\r
1833 }\r
1834 else\r
1835 {\r
f0dd2f7b 1836 for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
ebcb0f3d 1837 {\r
f8dde18d
JPM
1838 if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC <= Adr)\r
1839 {\r
1840 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
1841 {\r
1842 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;\r
1843 }\r
1844 }\r
1845 else\r
ebcb0f3d 1846 {\r
f8dde18d 1847 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k - 1].PtrLineSrc;\r
ebcb0f3d
JPM
1848 }\r
1849 }\r
1850 }\r
1851 }\r
1852 }\r
1853 }\r
1854 }\r
1855\r
1856 return NULL;\r
1857}\r
1858\r
1859\r
5fa7aa73
JPM
1860// Get line number based on the address and a tag\r
1861// A tag can be either 0 or a DW_TAG_subprogram\r
1862// DW_TAG_subprogram will look for the line pointing to the function name as described in the source code\r
ebcb0f3d
JPM
1863// Return 0 if no line number has been found\r
1864size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)\r
1865{\r
f0dd2f7b 1866 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1867 {\r
1868 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1869 {\r
f0dd2f7b 1870 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
ebcb0f3d
JPM
1871 {\r
1872 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1873 {\r
1874 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))\r
1875 {\r
1876 return PtrCU[i].PtrSubProgs[j].NumLineSrc;\r
1877 }\r
1878 else\r
1879 {\r
f0dd2f7b 1880 for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
ebcb0f3d
JPM
1881 {\r
1882 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
1883 {\r
1884 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc;\r
1885 }\r
1886 }\r
1887 }\r
1888#if 0\r
1889 if (!Tag || (Tag == DW_TAG_subprogram))\r
1890 {\r
1891 return PtrCU[i].PtrSubProgs[j].NumLineSrc;\r
1892 }\r
1893#endif\r
1894 }\r
1895 }\r
0536c3ba
JPM
1896\r
1897 // Check if a used line is found with the address\r
aae93d86 1898 for (size_t j = 0; j < PtrCU[i].NbUsedLinesSrc; j++)\r
0536c3ba 1899 {\r
aae93d86 1900 if (PtrCU[i].PtrUsedLinesSrc[j].StartPC == Adr)\r
0536c3ba 1901 {\r
aae93d86 1902 return PtrCU[i].PtrUsedLinesSrc[j].NumLineSrc;\r
0536c3ba
JPM
1903 }\r
1904 }\r
ebcb0f3d
JPM
1905 }\r
1906 }\r
1907\r
1908 return 0;\r
1909}\r
1910\r
1911\r
5fa7aa73
JPM
1912// Get function name based on an address\r
1913// Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address\r
0203b5fd
JPM
1914char *DWARFManager_GetFunctionName(size_t Adr)\r
1915{\r
f0dd2f7b 1916 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1917 {\r
1918 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1919 {\r
f0dd2f7b 1920 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1921 {\r
1922 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1923 {\r
1924 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;\r
1925 }\r
1926 }\r
1927 }\r
1928 }\r
1929\r
1930 return NULL;\r
1931}\r
1932\r
1933\r
aae93d86
JPM
1934// Get number of lines of texts source list from source index\r
1935size_t DWARFManager_GetSrcNbListPtrFromIndex(size_t Index, bool Used)\r
1936{\r
1937 if (!Used)\r
1938 {\r
1939 return PtrCU[Index].NbLinesLoadSrc;\r
1940 }\r
1941 else\r
1942 {\r
1943 return PtrCU[Index].NbUsedLinesSrc;\r
1944 }\r
1945}\r
1946\r
1947\r
1948// Get text source line number list pointer from source index\r
1949// Return NULL for the text source used list \r
1950size_t *DWARFManager_GetSrcNumLinesPtrFromIndex(size_t Index, bool Used)\r
1951{\r
1952 if (Used)\r
1953 {\r
1954 return PtrCU[Index].PtrUsedNumLines;\r
1955 }\r
1956 else\r
1957 {\r
1958 return NULL;\r
1959 }\r
1960}\r
1961\r
1962\r
1963// Get text source list pointers from source index\r
1964// Return NULL for the text source used list \r
1965char **DWARFManager_GetSrcListPtrFromIndex(size_t Index, bool Used)\r
1966{\r
1967 if (!Used)\r
1968 {\r
1969 return PtrCU[Index].PtrLinesLoadSrc;\r
1970 }\r
1971 else\r
1972 {\r
1973 return PtrCU[Index].PtrUsedLinesLoadSrc;\r
1974 }\r
1975}\r
1976\r
1977\r
1978// Get source language\r
1979size_t DWARFManager_GetSrcLanguageFromIndex(size_t Index)\r
1980{\r
1981 return PtrCU[Index].Language;\r
1982}\r
1983\r
1984\r
f0dd2f7b 1985// Get text line from source based on address and num line (starting from 1)\r
ebcb0f3d
JPM
1986// Return NULL if no text line has been found\r
1987char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)\r
1988{\r
f0dd2f7b 1989 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1990 {\r
1991 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1992 {\r
f0dd2f7b 1993 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
ebcb0f3d
JPM
1994 {\r
1995 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1996 {\r
1997 if (PtrCU[i].PtrSubProgs[j].NumLineSrc == NumLine)\r
1998 {\r
1999 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;\r
2000 }\r
2001 else\r
2002 {\r
f0dd2f7b 2003 for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
ebcb0f3d
JPM
2004 {\r
2005 if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc == NumLine)\r
2006 {\r
2007 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;\r
2008 }\r
2009 }\r
2010 }\r
2011 }\r
2012 }\r
2013 }\r
2014 }\r
2015\r
2016 return NULL;\r
2017}\r
2018\r
2019\r
f0dd2f7b 2020// Get text line pointer from source, based on address and line number (starting from 1)\r
f795e8ac 2021// Return NULL if no text line has been found, or if requested number line is above the source total number of lines\r
ebcb0f3d
JPM
2022char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)\r
2023{\r
f0dd2f7b 2024 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
2025 {\r
2026 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
2027 {\r
41d6f5f7
JPM
2028 if (NumLine <= PtrCU[i].NbLinesLoadSrc)\r
2029 {\r
2030 return PtrCU[i].PtrLinesLoadSrc[NumLine - 1];\r
2031 }\r
2032 else\r
2033 {\r
2034 return NULL;\r
2035 }\r
ebcb0f3d
JPM
2036 }\r
2037 }\r
2038\r
2039 return NULL;\r
2040}\r
2041\r
6564336c
JPM
2042\r
2043// Get number of source code filenames\r
aae93d86 2044size_t DWARFManager_GetNbSources(void)\r
6564336c
JPM
2045{\r
2046 return NbCU;\r
2047}\r
2048\r
2049\r
aae93d86 2050// Get source code filename, including his directory, based on index (starting from 0)\r
6564336c
JPM
2051char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
2052{\r
2053 return (PtrCU[Index].PtrFullFilename);\r
2054}\r
2055\r
aae93d86
JPM
2056\r
2057// Get source code filename based on index (starting from 0)\r
2058char *DWARFManager_GetNumSourceFilename(size_t Index)\r
2059{\r
2060 return (PtrCU[Index].PtrSourceFilename);\r
2061}\r
2062\r