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