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