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