381776323c68ac272cc06a79df6d6e509b598853
[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 if (return_tagval == DW_TAG_variable)
679 {
680 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Offset -= 0x80;
681 }
682 break;
683
684 default:
685 break;
686 }
687 dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);
688 }
689 break;
690
691 case DW_AT_type:
692 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)
693 {
694 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].TypeOffset = return_offset;
695 }
696 break;
697
698 case DW_AT_name:
699 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)
700 {
701 #ifdef DEBUG_VariableName
702 if (!strcmp(return_string, DEBUG_VariableName))
703 #endif
704 {
705 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName = (char *)calloc(strlen(return_string) + 1, 1);
706 strcpy(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName, return_string);
707 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);
708 }
709 }
710 break;
711
712 default:
713 break;
714 }
715 }
716 }
717
718 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
719 }
720
721 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables++;
722
723 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
724 }
725 break;
726
727 case DW_TAG_label:
728 break;
729
730 default:
731 break;
732 }
733 }
734 }
735 while (dwarf_siblingof(dbg, return_sub, &return_subdie, &error) == DW_DLV_OK);
736 }
737
738 PtrCU[NbCU].NbSubProgs++;
739 }
740 break;
741
742 default:
743 break;
744 }
745 }
746 }
747 while (dwarf_siblingof(dbg, return_sib, &return_die, &error) == DW_DLV_OK);
748 }
749
750 // Release the memory used by the source lines
751 for (i = 0; i < (size_t)cnt; ++i)
752 dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
753 dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
754 }
755
756 // Set the source code lines for QT html/text conformity
757 if (PtrCU[NbCU].NbLinesLoadSrc)
758 {
759 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(PtrCU[NbCU].NbLinesLoadSrc, sizeof(char *)))
760 {
761 for (j = 0; j < PtrCU[NbCU].NbLinesLoadSrc; j++)
762 {
763 if (PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)calloc(10000, sizeof(char)))
764 {
765 if (Ptr = DWARFManager_GetLineSrcFromNumLine(PtrCU[NbCU].PtrLoadSrc, (j + 1)))
766 {
767 i = 0;
768
769 while (*Ptr)
770 {
771 switch (*Ptr)
772 {
773 case 9:
774 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");
775 i += strlen("&nbsp;");
776 break;
777
778 case '<':
779 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&lt;");
780 i += strlen("&lt;");
781 break;
782
783 case '>':
784 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&gt;");
785 i += strlen("&gt;");
786 break;
787 #if 0
788 case '&':
789 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&amp;");
790 i += strlen("&amp;");
791 break;
792 #endif
793 #if 0
794 case '"':
795 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");
796 i += strlen("&quot;");
797 break;
798 #endif
799 default:
800 PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;
801 break;
802 }
803 Ptr++;
804 }
805 }
806 PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)realloc(PtrCU[NbCU].PtrLinesLoadSrc[j], i + 1);
807 }
808 }
809
810 // Init lines source information based on each source code line numbers
811 for (j = 0; j < PtrCU[NbCU].NbSubProgs; j++)
812 {
813 // Check if the subprog / function's line exists in the source code
814 if (PtrCU[NbCU].PtrSubProgs[j].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)
815 {
816 PtrCU[NbCU].PtrSubProgs[j].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].NumLineSrc - 1];
817 }
818
819 for (k = 0; k < PtrCU[NbCU].PtrSubProgs[j].NbLinesSrc; k++)
820 {
821 if (PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)
822 {
823 PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc - 1];
824 }
825 }
826 }
827 }
828 }
829 else
830 {
831 // Set each source lines pointer to NULL
832 if (PtrCU[NbCU].NbSubProgs)
833 {
834 // Check the presence of source lines dedicated to the sub progs
835 if (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc)
836 {
837 i = PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc - 1].NumLineSrc;
838 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(i, sizeof(char *)))
839 {
840 for (j = 0; j < i; j++)
841 {
842 PtrCU[NbCU].PtrLinesLoadSrc[j] = NULL;
843 }
844 }
845 }
846 }
847 }
848
849 // Init global variables information based on types information
850 for (i = 0; i < PtrCU[NbCU].NbVariables; i++)
851 {
852 DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrVariables + i);
853 }
854
855 // Init local variables information based on types information
856 for (i = 0; i < PtrCU[NbCU].NbSubProgs; i++)
857 {
858 for (j = 0; j < PtrCU[NbCU].PtrSubProgs[i].NbVariables; j++)
859 {
860 DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrSubProgs[i].PtrVariables + j);
861 }
862 }
863 }
864
865 ++NbCU;
866 }
867 }
868
869 free(SourceFilename);
870 free(SourceFileDirectory);
871 free(SourceFullFilename);
872 }
873
874
875 //
876 void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)
877 {
878 size_t j, TypeOffset;
879
880 PtrVariables->PtrTypeName = (char *)calloc(1000, 1);
881 TypeOffset = PtrVariables->TypeOffset;
882
883 for (j = 0; j < PtrCU[NbCU].NbTypes; j++)
884 {
885 if (TypeOffset == PtrCU[NbCU].PtrTypes[j].Offset)
886 {
887 switch (PtrCU[NbCU].PtrTypes[j].Tag)
888 {
889 case DW_TAG_structure_type:
890 PtrVariables->TypeTag |= 0x1;
891 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
892 {
893 j = -1;
894 }
895 else
896 {
897 if ((PtrVariables->TypeTag & 0x2))
898 {
899 strcat(PtrVariables->PtrTypeName, " *");
900 }
901 }
902 break;
903
904 case DW_TAG_pointer_type:
905 PtrVariables->TypeTag |= 0x2;
906 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;
907 PtrVariables->TypeEncoding = 0x10;
908 if (!(TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
909 {
910 strcat(PtrVariables->PtrTypeName, "void *");
911 }
912 else
913 {
914 j = -1;
915 }
916 break;
917
918 case DW_TAG_typedef:
919 if (!(PtrVariables->TypeTag & 0x20))
920 {
921 PtrVariables->TypeTag |= 0x20;
922 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);
923 }
924 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
925 {
926 j = -1;
927 }
928 break;
929
930 case DW_TAG_subrange_type:
931 PtrVariables->TypeTag |= 0x4;
932 break;
933
934 case DW_TAG_array_type:
935 PtrVariables->TypeTag |= 0x8;
936 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
937 {
938 j = -1;
939 }
940 break;
941
942 case DW_TAG_const_type:
943 PtrVariables->TypeTag |= 0x10;
944 strcat(PtrVariables->PtrTypeName, "const ");
945 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
946 {
947 j = -1;
948 }
949 break;
950
951 case DW_TAG_base_type:
952 if (!(PtrVariables->TypeTag & 0x20))
953 {
954 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);
955 }
956 if ((PtrVariables->TypeTag & 0x2))
957 {
958 strcat(PtrVariables->PtrTypeName, " *");
959 }
960 else
961 {
962 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;
963 PtrVariables->TypeEncoding = PtrCU[NbCU].PtrTypes[j].Encoding;
964 }
965 if ((PtrVariables->TypeTag & 0x8))
966 {
967 strcat(PtrVariables->PtrTypeName, "[]");
968 }
969 break;
970
971 default:
972 break;
973 }
974 }
975 }
976 }
977
978
979 // Get symbol name based from address
980 // Return NULL if no symbol name exists
981 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr)
982 {
983 size_t i, j;
984
985 for (i = 0; i < NbCU; i++)
986 {
987 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
988 {
989 for (j = 0; (j < PtrCU[i].NbSubProgs); j++)
990 {
991 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr))
992 {
993 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;
994 }
995 }
996 }
997 }
998
999 return NULL;
1000 }
1001
1002
1003 // Get complete source filename based from address
1004 // Return NULL if no source filename exists
1005 // Return the existence status (true or false) in Error
1006 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error)
1007 {
1008 size_t i;
1009
1010 for (i = 0; i < NbCU; i++)
1011 {
1012 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1013 {
1014 *Error = PtrCU[i].PtrLoadSrc ? true : false;
1015 return PtrCU[i].PtrFullFilename;
1016 }
1017 }
1018
1019 return NULL;
1020 }
1021
1022
1023 // Get text line source based on line number (starting by 1)
1024 // Return NULL if no text line exists or if line number is 0
1025 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine)
1026 {
1027 size_t i = 0;
1028 char *PtrLineSrc = NULL;
1029
1030 if (PtrSrcFile)
1031 {
1032 while (i != NumLine)
1033 {
1034 PtrLineSrc = PtrSrcFile;
1035 while (*PtrSrcFile++);
1036 i++;
1037 }
1038 }
1039
1040 return PtrLineSrc;
1041 }
1042
1043
1044 // Get number of variables referenced by the function range address
1045 size_t DWARFManager_GetNbLocalVariables(size_t Adr)
1046 {
1047 size_t i, j;
1048
1049 for (i = 0; i < NbCU; i++)
1050 {
1051 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1052 {
1053 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1054 {
1055 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1056 {
1057 return PtrCU[i].PtrSubProgs[j].NbVariables;
1058 }
1059 }
1060 }
1061 }
1062
1063 return 0;
1064 }
1065
1066
1067 // Get local variable name based on his index (starting by 1)
1068 // Return name's pointer text found
1069 // Return NULL if not found
1070 char *DWARFManager_GetLocalVariableName(size_t Adr, size_t Index)
1071 {
1072 size_t i, j;
1073
1074 for (i = 0; i < NbCU; i++)
1075 {
1076 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1077 {
1078 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1079 {
1080 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1081 {
1082 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].PtrName;
1083 }
1084 }
1085 }
1086 }
1087
1088 return NULL;
1089 }
1090
1091
1092 // Get local variable's type tag based on his index (starting by 1)
1093 // Return 0 if not found
1094 size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr, size_t Index)
1095 {
1096 size_t i, j;
1097
1098 for (i = 0; i < NbCU; i++)
1099 {
1100 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1101 {
1102 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1103 {
1104 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1105 {
1106 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeTag;
1107 }
1108 }
1109 }
1110 }
1111
1112 return 0;
1113 }
1114
1115
1116 //
1117 int DWARFManager_GetLocalVariableOffset(size_t Adr, size_t Index)
1118 {
1119 size_t i, j;
1120
1121 for (i = 0; i < NbCU; i++)
1122 {
1123 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1124 {
1125 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1126 {
1127 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1128 {
1129 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].Offset;
1130 }
1131 }
1132 }
1133 }
1134
1135 return 0;
1136 }
1137
1138
1139 // Get local variable Type Byte Size based on his address and index (starting by 1)
1140 // Return 0 if not found
1141 // May return 0 if there is no Type Byte Size linked to the variable's address and index
1142 size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr, size_t Index)
1143 {
1144 size_t i, j;
1145
1146 for (i = 0; i < NbCU; i++)
1147 {
1148 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1149 {
1150 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1151 {
1152 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1153 {
1154 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeByteSize;
1155 }
1156 }
1157 }
1158 }
1159
1160 return 0;
1161 }
1162
1163
1164 // Get local variable Type Encoding based on his address and index (starting by 1)
1165 // Return 0 if not found
1166 // May return 0 if there is no Type Encoding linked to the variable's address and index
1167 size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr, size_t Index)
1168 {
1169 size_t i, j;
1170
1171 for (i = 0; i < NbCU; i++)
1172 {
1173 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1174 {
1175 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1176 {
1177 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1178 {
1179 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeEncoding;
1180 }
1181 }
1182 }
1183 }
1184
1185 return 0;
1186 }
1187
1188
1189 // Get local variable Op based on his address and index (starting by 1)
1190 // Return 0 if not found
1191 // May return 0 if there isn't Op linked to the variable's index
1192 size_t DWARFManager_GetLocalVariableOp(size_t Adr, size_t Index)
1193 {
1194 size_t i, j;
1195
1196 for (i = 0; i < NbCU; i++)
1197 {
1198 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1199 {
1200 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1201 {
1202 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1203 {
1204 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].Op;
1205 }
1206 }
1207 }
1208 }
1209
1210 return 0;
1211 }
1212
1213
1214 // Get local variable type name based on his index (starting by 1)
1215 // Return NULL if not found
1216 // May return NULL if there is not type linked to the variable's index
1217 char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)
1218 {
1219 size_t i, j;
1220
1221 for (i = 0; i < NbCU; i++)
1222 {
1223 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1224 {
1225 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1226 {
1227 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1228 {
1229 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].PtrTypeName;
1230 }
1231 }
1232 }
1233 }
1234
1235 return NULL;
1236 }
1237
1238
1239 // Get Compilation Unit / global variables numbers
1240 // Return variables number
1241 size_t DWARFManager_GetNbGlobalVariables(void)
1242 {
1243 size_t NbVariables = 0, i;
1244
1245 for (i = 0; i < NbCU; i++)
1246 {
1247 NbVariables += PtrCU[i].NbVariables;
1248 }
1249
1250 return NbVariables;
1251 }
1252
1253
1254 // Get global variable type name based on his index (starting by 1)
1255 // Return NULL if not found
1256 // May return NULL if there is not type linked to the variable's index
1257 char *DWARFManager_GetGlobalVariableTypeName(size_t Index)
1258 {
1259 size_t i;
1260
1261 for (i = 0; i < NbCU; i++)
1262 {
1263 if (PtrCU[i].NbVariables)
1264 {
1265 if (Index <= PtrCU[i].NbVariables)
1266 {
1267 return PtrCU[i].PtrVariables[Index - 1].PtrTypeName;
1268 }
1269 else
1270 {
1271 Index -= PtrCU[i].NbVariables;
1272 }
1273 }
1274 }
1275
1276 return NULL;
1277 }
1278
1279
1280 // Get global variable's type tag based on his index (starting by 1)
1281 // Return 0 if not found
1282 size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index)
1283 {
1284 size_t i;
1285
1286 for (i = 0; i < NbCU; i++)
1287 {
1288 if (PtrCU[i].NbVariables)
1289 {
1290 if (Index <= PtrCU[i].NbVariables)
1291 {
1292 return PtrCU[i].PtrVariables[Index - 1].TypeTag;
1293 }
1294 else
1295 {
1296 Index -= PtrCU[i].NbVariables;
1297 }
1298 }
1299 }
1300
1301 return 0;
1302 }
1303
1304
1305 // Get global variable byte size based on his index (starting by 1)
1306 // Return 0 if not found
1307 size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index)
1308 {
1309 size_t i;
1310
1311 for (i = 0; i < NbCU; i++)
1312 {
1313 if (PtrCU[i].NbVariables)
1314 {
1315 if (Index <= PtrCU[i].NbVariables)
1316 {
1317 return PtrCU[i].PtrVariables[Index - 1].TypeByteSize;
1318 }
1319 else
1320 {
1321 Index -= PtrCU[i].NbVariables;
1322 }
1323 }
1324 }
1325
1326 return 0;
1327 }
1328
1329
1330 // Get global variable encoding based on his index (starting by 1)
1331 // Return 0 if not found
1332 size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index)
1333 {
1334 size_t i;
1335
1336 for (i = 0; i < NbCU; i++)
1337 {
1338 if (PtrCU[i].NbVariables)
1339 {
1340 if (Index <= PtrCU[i].NbVariables)
1341 {
1342 return PtrCU[i].PtrVariables[Index - 1].TypeEncoding;
1343 }
1344 else
1345 {
1346 Index -= PtrCU[i].NbVariables;
1347 }
1348 }
1349 }
1350
1351 return 0;
1352 }
1353
1354
1355 // Get global variable address based on his index (starting by 1)
1356 // Return 0 if not found
1357 size_t DWARFManager_GetGlobalVariableAdr(size_t Index)
1358 {
1359 size_t i;
1360
1361 for (i = 0; i < NbCU; i++)
1362 {
1363 if (PtrCU[i].NbVariables)
1364 {
1365 if (Index <= PtrCU[i].NbVariables)
1366 {
1367 return PtrCU[i].PtrVariables[Index - 1].Addr;
1368 }
1369 else
1370 {
1371 Index -= PtrCU[i].NbVariables;
1372 }
1373 }
1374 }
1375
1376 return 0;
1377 }
1378
1379
1380 // Get global variable memory address based on his name
1381 // Return 0 if not found
1382 // Note: Return the first occurence found
1383 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)
1384 {
1385 size_t i, j;
1386
1387 for (i = 0; i < NbCU; i++)
1388 {
1389 if (PtrCU[i].NbVariables)
1390 {
1391 for (j = 0; j < PtrCU[i].NbVariables; j++)
1392 {
1393 if (!strcmp(PtrCU[i].PtrVariables[j].PtrName,VariableName))
1394 {
1395 return PtrCU[i].PtrVariables[j].Addr;
1396 }
1397 }
1398 }
1399 }
1400
1401 return 0;
1402 }
1403
1404
1405 // Get global variable name based on his index (starting by 1)
1406 // Return name's pointer text found
1407 // Return NULL if not found
1408 char *DWARFManager_GetGlobalVariableName(size_t Index)
1409 {
1410 size_t i;
1411
1412 for (i = 0; i < NbCU; i++)
1413 {
1414 if (PtrCU[i].NbVariables)
1415 {
1416 if (Index <= PtrCU[i].NbVariables)
1417 {
1418 return PtrCU[i].PtrVariables[Index - 1].PtrName;
1419 }
1420 else
1421 {
1422 Index -= PtrCU[i].NbVariables;
1423 }
1424 }
1425 }
1426
1427 return NULL;
1428 }
1429
1430
1431 // Get text line from source based on address and his tag
1432 // Return NULL if no text line has been found
1433 char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)
1434 {
1435 size_t i, j, k;
1436
1437 for (i = 0; i < NbCU; i++)
1438 {
1439 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1440 {
1441 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1442 {
1443 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1444 {
1445 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))
1446 {
1447 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;
1448 }
1449 else
1450 {
1451 for (k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)
1452 {
1453 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))
1454 {
1455 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;
1456 }
1457 }
1458 }
1459 }
1460 }
1461 }
1462 }
1463
1464 return NULL;
1465 }
1466
1467
1468 // Get line number based on the address and the tag
1469 // Return 0 if no line number has been found
1470 size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
1471 {
1472 size_t i, j, k;
1473
1474 for (i = 0; i < NbCU; i++)
1475 {
1476 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1477 {
1478 for (j = 0; (j < PtrCU[i].NbSubProgs); j++)
1479 {
1480 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1481 {
1482 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))
1483 {
1484 return PtrCU[i].PtrSubProgs[j].NumLineSrc;
1485 }
1486 else
1487 {
1488 for (k = 0; (k < PtrCU[i].PtrSubProgs[j].NbLinesSrc); k++)
1489 {
1490 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))
1491 {
1492 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc;
1493 }
1494 }
1495 }
1496 #if 0
1497 if (!Tag || (Tag == DW_TAG_subprogram))
1498 {
1499 return PtrCU[i].PtrSubProgs[j].NumLineSrc;
1500 }
1501 #endif
1502 }
1503 }
1504 }
1505 }
1506
1507 return 0;
1508 }
1509
1510
1511 // Get function name based on address and his range
1512 // Return NULL if no function name has been found
1513 char *DWARFManager_GetFunctionName(size_t Adr)
1514 {
1515 size_t i, j;
1516
1517 for (i = 0; i < NbCU; i++)
1518 {
1519 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1520 {
1521 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1522 {
1523 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1524 {
1525 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;
1526 }
1527 }
1528 }
1529 }
1530
1531 return NULL;
1532 }
1533
1534
1535 // Get text line from source based on address and num line (starting by 1)
1536 // Return NULL if no text line has been found
1537 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)
1538 {
1539 size_t i, j, k;
1540
1541 for (i = 0; i < NbCU; i++)
1542 {
1543 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1544 {
1545 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1546 {
1547 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1548 {
1549 if (PtrCU[i].PtrSubProgs[j].NumLineSrc == NumLine)
1550 {
1551 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;
1552 }
1553 else
1554 {
1555 for (k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)
1556 {
1557 if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc == NumLine)
1558 {
1559 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;
1560 }
1561 }
1562 }
1563 }
1564 }
1565 }
1566 }
1567
1568 return NULL;
1569 }
1570
1571
1572 // Get text line from source based on address and num line (starting by 1)
1573 // Return NULL if no text line has been found
1574 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)
1575 {
1576 size_t i;
1577
1578 for (i = 0; i < NbCU; i++)
1579 {
1580 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1581 {
1582 if (NumLine <= PtrCU[i].NbLinesLoadSrc)
1583 {
1584 return PtrCU[i].PtrLinesLoadSrc[NumLine - 1];
1585 }
1586 else
1587 {
1588 return NULL;
1589 }
1590 }
1591 }
1592
1593 return NULL;
1594 }
1595