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