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