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