Work started for the source tracing
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DBGManager.cpp
1 //
2 // DBGManager.cpp: Debugger information 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/21/2016 Created this file
11 // JPM Various efforts to set the ELF format support
12 // JPM Various efforts to set the DWARF format support
13 // JPM 09/15/2018 Support the unsigned char
14 // JPM Oct./2018 Cosmetic changes, added source file search paths, and ELF function name
15 // JPM Aug./2019 Added new functions mainly for source text lines
16 //
17
18 // To Do
19 // To think about unique format to handle variations from ELF, DWARF, etc.
20 //
21
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdint.h>
26 #include "libelf/libelf.h"
27 #include "libelf/gelf.h"
28 #include "log.h"
29 #include "ELFManager.h"
30 #include "DwarfManager.h"
31 #include "DBGManager.h"
32 #include "HWLABELManager.h"
33 #include "settings.h"
34 #include "memory.h"
35
36
37 //
38 struct Value
39 {
40 union
41 {
42 char Ct[10];
43 char C;
44 bool B;
45 double D;
46 float F;
47 int32_t SI;
48 int64_t SL;
49 uint32_t UI;
50 uint64_t UL;
51 };
52 }S_Value;
53
54
55 //
56 void DBGManager_SourceFileSearchPathsInit(void);
57 void DBGManager_SourceFileSearchPathsReset(void);
58 void DBGManager_SourceFileSearchPathsClose(void);
59
60
61 // Common debugger variables
62 size_t DBGType;
63 char value[1000];
64 size_t NbSFSearchPaths;
65 char **SourceFileSearchPaths;
66
67
68 // Init the source file search paths
69 void DBGManager_SourceFileSearchPathsInit(void)
70 {
71 NbSFSearchPaths = 0;
72 SourceFileSearchPaths = NULL;
73 }
74
75
76 // Set the source file search paths
77 // Create individual path for each one provided in the list (separate with ';')
78 void DBGManager_SourceFileSearchPathsSet(char *ListPaths)
79 {
80 // Check presence of a previous list
81 if (NbSFSearchPaths)
82 {
83 // Reset previous list
84 DBGManager_SourceFileSearchPathsReset();
85 }
86
87 // Check if there is a paths list
88 if (strlen(ListPaths))
89 {
90 // Get number of paths
91 char *Ptr = ListPaths;
92 while(*Ptr)
93 {
94 while (*Ptr && (*Ptr++ != ';'));
95 {
96 NbSFSearchPaths++;
97 }
98 }
99
100 // Isolate each search path
101 SourceFileSearchPaths = (char **)calloc(NbSFSearchPaths, sizeof(char *));
102 size_t i = 0;
103 Ptr = ListPaths;
104
105 while (*Ptr)
106 {
107 // Search the path separator (';')
108 char *Ptr1 = Ptr;
109 while (*Ptr && (*Ptr++ != ';'));
110
111 // Copy the inidividual search path
112 SourceFileSearchPaths[i] = (char *)calloc(1, (Ptr - Ptr1) + 1);
113 strncpy(SourceFileSearchPaths[i], Ptr1, (Ptr - Ptr1));
114 if (SourceFileSearchPaths[i][strlen(SourceFileSearchPaths[i]) - 1] == ';')
115 {
116 SourceFileSearchPaths[i][strlen(SourceFileSearchPaths[i]) - 1] = 0;
117 }
118 i++;
119 }
120 }
121
122 DWARFManager_Set(NbSFSearchPaths, SourceFileSearchPaths);
123 }
124
125
126 // Reset the source file search paths
127 void DBGManager_SourceFileSearchPathsReset(void)
128 {
129 // Free each path
130 while (NbSFSearchPaths)
131 {
132 free(SourceFileSearchPaths[--NbSFSearchPaths]);
133 }
134
135 // Free the pointers list
136 free(SourceFileSearchPaths);
137 SourceFileSearchPaths = NULL;
138 }
139
140
141 // Close the source file search paths
142 void DBGManager_SourceFileSearchPathsClose(void)
143 {
144 DBGManager_SourceFileSearchPathsReset();
145 }
146
147
148 // Common debugger initialisation
149 void DBGManager_Init(void)
150 {
151 // DBG initialisations
152 DBGType = DBG_NO_TYPE;
153 DBGManager_SourceFileSearchPathsInit();
154
155 // ELF initialisation
156 ELFManager_Init();
157 // DWARF initialisation
158 DWARFManager_Init();
159 }
160
161
162 // Common debugger reset
163 void DBGManager_Reset(void)
164 {
165 if ((DBGType & DBG_DWARF))
166 {
167 DWARFManager_Reset();
168 }
169
170 if ((DBGType & DBG_ELF))
171 {
172 ELFManager_Reset();
173 }
174
175 //DBGType = vjs.displayHWlabels ? DBG_HWLABEL : DBG_NO_TYPE;
176 DBGType = DBG_NO_TYPE;
177 }
178
179
180 // Common debugger close
181 void DBGManager_Close(void)
182 {
183 if ((DBGType & DBG_DWARF))
184 {
185 DWARFManager_Close();
186 }
187
188 if ((DBGType & DBG_ELF))
189 {
190 ELFManager_Close();
191 }
192
193 DBGManager_SourceFileSearchPathsClose();
194 DBGType = DBG_NO_TYPE;
195 }
196
197
198 // Common debugger set
199 void DBGManager_SetType(size_t DBGTypeSet)
200 {
201 DBGType |= DBGTypeSet;
202 }
203
204
205 // Get debugger type
206 size_t DBGManager_GetType(void)
207 {
208 return DBGType;
209 }
210
211
212 // Get source filename based on the memeory address
213 // return NULL if no source filename
214 char *DBGManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error)
215 {
216 if ((DBGType & DBG_ELFDWARF))
217 {
218 return DWARFManager_GetFullSourceFilenameFromAdr(Adr, Error);
219 }
220 else
221 {
222 return NULL;
223 }
224 }
225
226
227 // Get number of local variables
228 // Return 0 if none has been found
229 size_t DBGManager_GetNbLocalVariables(size_t Adr)
230 {
231 if ((DBGType & DBG_ELFDWARF))
232 {
233 return DWARFManager_GetNbLocalVariables(Adr);
234 }
235 else
236 {
237 return 0;
238 }
239 }
240
241
242 // Get number of global variables
243 // Return 0 if none has been found
244 size_t DBGManager_GetNbGlobalVariables(void)
245 {
246 if ((DBGType & DBG_ELFDWARF))
247 {
248 return DWARFManager_GetNbGlobalVariables();
249 }
250 else
251 {
252 return 0;
253 }
254 }
255
256
257 // Get address from symbol name
258 // Return found address
259 // Return NULL if no symbol has been found
260 size_t DBGManager_GetAdrFromSymbolName(char *SymbolName)
261 {
262 if (SymbolName)
263 {
264 if ((DBGType & DBG_ELF))
265 {
266 return ELFManager_GetAdrFromSymbolName(SymbolName);
267 }
268 }
269
270 return 0;
271 }
272
273
274 // Get global variable's Address based on his Name
275 // Return found Address
276 // Return NULL if no Address has been found
277 size_t DBGManager_GetGlobalVariableAdrFromName(char *VariableName)
278 {
279 if ((DBGType & DBG_ELFDWARF))
280 {
281 return DWARFManager_GetGlobalVariableAdrFromName(VariableName);
282 }
283 else
284 {
285 return 0;
286 }
287 }
288
289
290 // Get local variable's type encoding based on his address and Index
291 // Return the type encoding found
292 // Return 0 if no type encoding has been found
293 size_t DBGManager_GetLocalVariableTypeEncoding(size_t Adr, size_t Index)
294 {
295 if ((DBGType & DBG_ELFDWARF))
296 {
297 return DWARFManager_GetLocalVariableTypeEncoding(Adr, Index);
298 }
299 else
300 {
301 return 0;
302 }
303 }
304
305
306 //
307 int DBGManager_GetLocalVariableOffset(size_t Adr, size_t Index)
308 {
309 if ((DBGType & DBG_ELFDWARF))
310 {
311 return DWARFManager_GetLocalVariableOffset(Adr, Index);
312 }
313 else
314 {
315 return 0;
316 }
317 }
318
319
320 // Get local variable's type byte size based on his address and Index
321 // Return the type's byte size found
322 // Return 0 if no type's byte size has been found
323 size_t DBGManager_GetLocalVariableTypeByteSize(size_t Adr, size_t Index)
324 {
325 if ((DBGType & DBG_ELFDWARF))
326 {
327 return DWARFManager_GetLocalVariableTypeByteSize(Adr, Index);
328 }
329 else
330 {
331 return 0;
332 }
333 }
334
335
336 //
337 size_t DBGManager_GetLocalVariableTypeTag(size_t Adr, size_t Index)
338 {
339 if ((DBGType & DBG_ELFDWARF))
340 {
341 return DWARFManager_GetLocalVariableTypeTag(Adr, Index);
342 }
343 else
344 {
345 return 0;
346 }
347 }
348
349
350 //
351 size_t DBGManager_GetGlobalVariableTypeTag(size_t Index)
352 {
353 if ((DBGType & DBG_ELFDWARF))
354 {
355 return DWARFManager_GetGlobalVariableTypeTag(Index);
356 }
357 else
358 {
359 return 0;
360 }
361 }
362
363
364 // Get global variable's type name based on his Index
365 // Return type name's text pointer found
366 // Return NULL if no type name has been found
367 char *DBGManager_GetGlobalVariableTypeName(size_t Index)
368 {
369 if ((DBGType & DBG_ELFDWARF))
370 {
371 return DWARFManager_GetGlobalVariableTypeName(Index);
372 }
373 else
374 {
375 return NULL;
376 }
377 }
378
379
380 // Get global variable's Address based on his Index
381 // Return the Address found
382 // Return 0 if no Address has been found
383 size_t DBGManager_GetGlobalVariableAdr(size_t Index)
384 {
385 if ((DBGType & DBG_ELFDWARF))
386 {
387 return DWARFManager_GetGlobalVariableAdr(Index);
388 }
389 else
390 {
391 return 0;
392 }
393 }
394
395
396 // Get global variable's type byte size based on his Index
397 // Return the type's byte size found
398 // Return 0 if no type's byte size has been found
399 size_t DBGManager_GetGlobalVariableTypeByteSize(size_t Index)
400 {
401 if ((DBGType & DBG_ELFDWARF))
402 {
403 return DWARFManager_GetGlobalVariableTypeByteSize(Index);
404 }
405 else
406 {
407 return 0;
408 }
409 }
410
411
412 // Get global variable's type encoding based on his Index
413 // Return the type encoding found
414 // Return 0 if no type encoding has been found
415 size_t DBGManager_GetGlobalVariableTypeEncoding(size_t Index)
416 {
417 if ((DBGType & DBG_ELFDWARF))
418 {
419 return DWARFManager_GetGlobalVariableTypeEncoding(Index);
420 }
421 else
422 {
423 return 0;
424 }
425 }
426
427
428 // Get global variable value based on his Index
429 // Return value as a text pointer
430 // Note: Pointer may point on a 0 lenght text
431 char *DBGManager_GetGlobalVariableValue(size_t Index)
432 {
433 size_t Adr = 0;
434 size_t TypeEncoding = DBG_NO_TYPEENCODING;
435 size_t TypeByteSize = 0;
436
437 if ((DBGType & DBG_ELFDWARF))
438 {
439 Adr = DWARFManager_GetGlobalVariableAdr(Index);
440 TypeEncoding = DWARFManager_GetGlobalVariableTypeEncoding(Index);
441 TypeByteSize = DWARFManager_GetGlobalVariableTypeByteSize(Index);
442 }
443
444 return DBGManager_GetVariableValueFromAdr(Adr, TypeEncoding, TypeByteSize);
445 }
446
447
448 // Get variable value based on his Adresse, Encoding Type and Size
449 // Return value as a text pointer
450 // Note: Pointer may point on a 0 length text
451 char *DBGManager_GetVariableValueFromAdr(size_t Adr, size_t TypeEncoding, size_t TypeByteSize)
452 {
453 Value V;
454 char *Ptrvalue = value;
455
456 value[0] = 0;
457
458 #if 0
459 if (Adr)
460 #endif
461 {
462 memset(&V, 0, sizeof(Value));
463 #if 0
464 for (uint32_t i = 0; i < TypeByteSize; i++)
465 jaguarMainRAM[Adr + i] = 0;
466 //jaguarMainRAM[Adr + i] = rand();
467 jaguarMainRAM[Adr + TypeByteSize - 1] = 0x10;
468 #else
469 for (size_t i = 0, j = TypeByteSize; i < TypeByteSize; i++, j--)
470 {
471 V.Ct[i] = jaguarMainRAM[Adr + j - 1];
472 }
473 #endif
474 switch (TypeEncoding)
475 {
476 case DBG_ATE_address:
477 break;
478
479 case DBG_ATE_boolean:
480 sprintf(value, "%s", V.B ? "true" : "false");
481 break;
482
483 case DBG_ATE_complex_float:
484 break;
485
486 case DBG_ATE_float:
487 switch (TypeByteSize)
488 {
489 case 4:
490 sprintf(value, "%F", V.F);
491 break;
492
493 case 8:
494 //V.D = (double)jaguarMainRAM[Adr];
495 //sprintf(value, "%10.10F", V.D);
496 sprintf(value, "%F", V.D);
497 break;
498
499 default:
500 break;
501 }
502 break;
503
504 case DBG_ATE_signed:
505 switch (TypeByteSize)
506 {
507 case 4:
508 sprintf(value, "%i", V.SI);
509 break;
510
511 case 8:
512 sprintf(value, "%i", V.SL);
513 break;
514
515 default:
516 break;
517 }
518 break;
519
520 case DBG_ATE_signed_char:
521 break;
522
523 case DBG_ATE_unsigned:
524 switch (TypeByteSize)
525 {
526 case 4:
527 sprintf(value, "%u", V.UI);
528 break;
529
530 case 8:
531 sprintf(value, "%u", V.UL);
532 break;
533
534 default:
535 break;
536 }
537 break;
538
539 case DBG_ATE_unsigned_char:
540 sprintf(value, "%u", (unsigned int(V.C)));
541 break;
542
543 case DBG_ATE_ptr:
544 switch (TypeByteSize)
545 {
546 case 4:
547 sprintf(value, "0x%06x", V.UI);
548 break;
549
550 default:
551 break;
552 }
553
554 default:
555 break;
556 }
557 }
558
559 return Ptrvalue;
560 }
561
562
563 // Get local variable's type name based on his Index
564 // Return type name's text pointer found
565 // Return NULL if no type name has been found
566 char *DBGManager_GetLocalVariableTypeName(size_t Adr, size_t Index)
567 {
568 if ((DBGType & DBG_ELFDWARF))
569 {
570 return DWARFManager_GetLocalVariableTypeName(Adr, Index);
571 }
572 else
573 {
574 return NULL;
575 }
576 }
577
578
579 // Get local variable Op based on his Index
580 // Return variable Op's found
581 // Return 0 if no variable Op has been found
582 size_t DBGManager_GetLocalVariableOp(size_t Adr, size_t Index)
583 {
584 if ((DBGType & DBG_ELFDWARF))
585 {
586 return DWARFManager_GetLocalVariableOp(Adr, Index);
587 }
588 else
589 {
590 return 0;
591 }
592 }
593
594
595 // Get local variable name based on his Index
596 // Return variable name's text pointer found
597 // Return NULL if no variable name has been found
598 char *DBGManager_GetLocalVariableName(size_t Adr, size_t Index)
599 {
600 if ((DBGType & DBG_ELFDWARF))
601 {
602 return DWARFManager_GetLocalVariableName(Adr, Index);
603 }
604 else
605 {
606 return NULL;
607 }
608 }
609
610
611 // Get global variable name based on his Index
612 // Return variable name's text pointer found
613 // Return NULL if no variable name has been found
614 char *DBGManager_GetGlobalVariableName(size_t Index)
615 {
616 if ((DBGType & DBG_ELFDWARF))
617 {
618 return DWARFManager_GetGlobalVariableName(Index);
619 }
620 else
621 {
622 return NULL;
623 }
624 }
625
626
627 // Get function name from address
628 // Return function name found
629 // Return NULL if no function name has been found
630 char *DBGManager_GetFunctionName(size_t Adr)
631 {
632 char *Symbolname = NULL;
633
634 if ((DBGType & DBG_ELFDWARF))
635 {
636 Symbolname = DWARFManager_GetFunctionName(Adr);
637 }
638
639 if ((DBGType & DBG_ELF) && (Symbolname == NULL))
640 {
641 Symbolname = ELFManager_GetFunctionName(Adr);
642 }
643
644 return Symbolname;
645 }
646
647
648 // Get line number from address and his tag
649 // Return line number on the symbol name found
650 // Return 0 if no symbol name has been found
651 size_t DBGManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
652 {
653 if ((DBGType & DBG_ELFDWARF))
654 {
655 return DWARFManager_GetNumLineFromAdr(Adr, Tag);
656 }
657 else
658 {
659 return 0;
660 }
661 }
662
663
664 // Get symbol name from address
665 // Return text pointer on the symbol name found
666 // Return NULL if no symbol name has been found
667 char *DBGManager_GetSymbolNameFromAdr(size_t Adr)
668 {
669 char *Symbolname;
670
671 //if ((DBGType & DBG_HWLABEL) || vjs.displayHWlabels)
672 if (vjs.displayHWlabels)
673 {
674 Symbolname = HWLABELManager_GetSymbolnameFromAdr(Adr);
675 }
676 else
677 {
678 Symbolname = NULL;
679 }
680 #ifdef _MSC_VER
681 #pragma message("Warning: !!! Need to set the DBG_HWLABEL in DBGType instead to use the setting value !!!")
682 #else
683 #warning "!!! Need to set the DBG_HWLABEL in DBGType instead to use the setting value !!!"
684 #endif // _MSC_VER
685
686 if (Symbolname == NULL)
687 {
688 if ((DBGType & DBG_ELFDWARF))
689 {
690 Symbolname = DWARFManager_GetSymbolnameFromAdr(Adr);
691 }
692
693 if ((DBGType & DBG_ELF) && (Symbolname == NULL))
694 {
695 Symbolname = ELFManager_GetSymbolnameFromAdr(Adr);
696 }
697 }
698
699 return Symbolname;
700 }
701
702
703 // Get source line based on the Address and his Tag
704 // Return text pointer on the source line found
705 // Return NULL if no source line has been found
706 char *DBGManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)
707 {
708 char *TextLine = NULL;
709
710 if ((DBGType & DBG_ELFDWARF))
711 {
712 TextLine = DWARFManager_GetLineSrcFromAdr(Adr, Tag);
713 }
714
715 return TextLine;
716 }
717
718
719 // Get text line from source based on address and num line (starting from 1)
720 // Return NULL if no text line has been found
721 char *DBGManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)
722 {
723 char *TextLine = NULL;
724
725 if ((DBGType & DBG_ELFDWARF))
726 {
727 TextLine = DWARFManager_GetLineSrcFromAdrNumLine(Adr, NumLine);
728 }
729
730 return TextLine;
731 }
732
733
734 // Get text line from source based on address and num line (starting from 1)
735 // Return NULL if no text line has been found
736 char *DBGManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)
737 {
738 char *TextLine = NULL;
739
740 if ((DBGType & DBG_ELFDWARF))
741 {
742 TextLine = DWARFManager_GetLineSrcFromNumLineBaseAdr(Adr, NumLine);
743 }
744
745 return TextLine;
746 }
747
748
749 // Get number of source code filenames
750 size_t DBGManager_GetNbSources(void)
751 {
752 size_t Nbr = 0;
753
754 if ((DBGType & DBG_ELFDWARF))
755 {
756 Nbr = DWARFManager_GetNbSources();
757 }
758
759 return Nbr;
760 }
761
762
763 // Get source code filename based on index
764 char *DBGManager_GetNumSourceFilename(size_t Index)
765 {
766 char *SourceFilename = NULL;
767
768 if ((DBGType & DBG_ELFDWARF))
769 {
770 SourceFilename = DWARFManager_GetNumSourceFilename(Index);
771 }
772
773 return SourceFilename;
774 }
775
776
777 // Get source code filename based on index
778 char *DBGManager_GetNumFullSourceFilename(size_t Index)
779 {
780 char *FullSourceFilename = NULL;
781
782 if ((DBGType & DBG_ELFDWARF))
783 {
784 FullSourceFilename = DWARFManager_GetNumFullSourceFilename(Index);
785 }
786
787 return FullSourceFilename;
788 }
789
790
791 // Get number of lines of texts source list from source index
792 size_t DBGManager_GetSrcNbListPtrFromIndex(size_t Index, bool Used)
793 {
794 size_t NbListPtr = 0;
795
796 if ((DBGType & DBG_ELFDWARF))
797 {
798 NbListPtr = DWARFManager_GetSrcNbListPtrFromIndex(Index, Used);
799 }
800
801 return NbListPtr;
802 }
803
804
805 // Get pointer to the lines number list from source index
806 size_t *DBGManager_GetSrcNumLinesPtrFromIndex(size_t Index, bool Used)
807 {
808 size_t *PtrNumLines = NULL;
809
810 if ((DBGType & DBG_ELFDWARF))
811 {
812 PtrNumLines = DWARFManager_GetSrcNumLinesPtrFromIndex(Index, Used);
813 }
814
815 return PtrNumLines;
816 }
817
818
819 // Get text source list pointers from source index
820 char **DBGManager_GetSrcListPtrFromIndex(size_t Index, bool Used)
821 {
822 char **PtrSource = NULL;
823
824 if ((DBGType & DBG_ELFDWARF))
825 {
826 PtrSource = DWARFManager_GetSrcListPtrFromIndex(Index, Used);
827 }
828
829 return PtrSource;
830 }
831
832
833 // Get source language
834 size_t DBGManager_GetSrcLanguageFromIndex(size_t Index)
835 {
836 size_t Language = 0;
837
838 if ((DBGType & DBG_ELFDWARF))
839 {
840 Language = DWARFManager_GetSrcLanguageFromIndex(Index);
841 }
842
843 return Language;
844 }
845