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