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