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