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