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