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