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