Worked started for the source tracing
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DWARFManager.cpp
index fed680a..b65227f 100644 (file)
@@ -10,6 +10,7 @@
 // JPM   Dec./2016  Created this file, and added the DWARF format support\r
 // JPM  Sept./2018  Added LEB128 decoding features, and improve the DWARF parsing information\r
 // JPM   Oct./2018  Improve the DWARF parsing information, and the source file text reading; support the used source lines from DWARF structure, and the search paths for the files\r
 // JPM   Dec./2016  Created this file, and added the DWARF format support\r
 // JPM  Sept./2018  Added LEB128 decoding features, and improve the DWARF parsing information\r
 // JPM   Oct./2018  Improve the DWARF parsing information, and the source file text reading; support the used source lines from DWARF structure, and the search paths for the files\r
+// JPM   Aug./2019  Added new functions to handle DWARF information, full filename fix\r
 //\r
 \r
 // To Do\r
 //\r
 \r
 // To Do\r
 \r
 \r
 // Definitions for debugging\r
 \r
 \r
 // Definitions for debugging\r
-//#define DEBUG_NumCU                  0x4d                            // CU number to debug or undefine it\r
+//#define DEBUG_NumCU                  0x44                            // CU number to debug or undefine it\r
 //#define DEBUG_VariableName   "sound_death"                           // Variable name to look for or undefine it\r
 //#define DEBUG_TypeName               "Cbuf_Execute"                  // Type name to look for or undefine it\r
 //#define DEBUG_TypeDef                        DW_TAG_typedef          // Type def to look for or undefine it (not supported)\r
 //#define DEBUG_VariableName   "sound_death"                           // Variable name to look for or undefine it\r
 //#define DEBUG_TypeName               "Cbuf_Execute"                  // Type name to look for or undefine it\r
 //#define DEBUG_TypeDef                        DW_TAG_typedef          // Type def to look for or undefine it (not supported)\r
-//#define DEBUG_Filename               "net_jag.c"                     // Filename to look for or undefine it\r
+//#define DEBUG_Filename               "crt0"                  // Filename to look for or undefine it\r
+\r
+// Definitions for handling data\r
+//#define CONVERT_QT_HML                                                               // Text will be converted as HTML\r
 \r
 // Definitions for the variables's typetag\r
 #define        TypeTag_structure                       0x01                    // structure\r
 \r
 // Definitions for the variables's typetag\r
 #define        TypeTag_structure                       0x01                    // structure\r
@@ -125,6 +129,7 @@ typedef struct SubProgStruct
 typedef struct CUStruct\r
 {\r
        size_t Tag;\r
 typedef struct CUStruct\r
 {\r
        size_t Tag;\r
+       size_t Language;                                                                // Language (C, etc.) used by the source code\r
        size_t LowPC, HighPC;                                                   // Memory range for the code\r
        char *PtrProducer;                                                              // Pointer to the "Producer" text information (mostly compiler and compilation options used)\r
        char *PtrSourceFilename;                                                // Source file name\r
        size_t LowPC, HighPC;                                                   // Memory range for the code\r
        char *PtrProducer;                                                              // Pointer to the "Producer" text information (mostly compiler and compilation options used)\r
        char *PtrSourceFilename;                                                // Source file name\r
@@ -141,8 +146,11 @@ typedef struct CUStruct
        size_t NbVariables;                                                             // Variables number\r
        VariablesStruct *PtrVariables;                                  // Pointer to the global variables list structure\r
        size_t NbFrames;                                                                // Frames number\r
        size_t NbVariables;                                                             // Variables number\r
        VariablesStruct *PtrVariables;                                  // Pointer to the global variables list structure\r
        size_t NbFrames;                                                                // Frames number\r
-       size_t NbLinesSrc;                                                              // Number of used source lines\r
-       CUStruct_LineSrc *PtrLinesSrc;                                  // Pointer to the used source lines list structure\r
+       size_t NbUsedLinesSrc;                                                  // Number of used source lines\r
+       size_t LastNumUsedLinesSrc;                                             // Last used source number line\r
+       CUStruct_LineSrc *PtrUsedLinesSrc;                              // Pointer to the used source lines list structure\r
+       char **PtrUsedLinesLoadSrc;                                             // Pointer lists to each used source line referenced by the CUStruct_LineSrc structure\r
+       size_t *PtrUsedNumLines;                                                // Pointer list to the number lines used\r
 }S_CUStruct;\r
 \r
 \r
 }S_CUStruct;\r
 \r
 \r
@@ -167,6 +175,7 @@ void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables);
 void DWARFManager_SourceFileSearchPathsInit(void);\r
 void DWARFManager_SourceFileSearchPathsReset(void);\r
 void DWARFManager_SourceFileSearchPathsClose(void);\r
 void DWARFManager_SourceFileSearchPathsInit(void);\r
 void DWARFManager_SourceFileSearchPathsReset(void);\r
 void DWARFManager_SourceFileSearchPathsClose(void);\r
+void DWARFManager_ConformSlachesBackslashes(char *Ptr);\r
 \r
 \r
 //\r
 \r
 \r
 //\r
@@ -278,7 +287,9 @@ void DWARFManager_CloseDMI(void)
                free(PtrCU[NbCU].PtrProducer);\r
                free(PtrCU[NbCU].PtrSourceFilename);\r
                free(PtrCU[NbCU].PtrSourceFileDirectory);\r
                free(PtrCU[NbCU].PtrProducer);\r
                free(PtrCU[NbCU].PtrSourceFilename);\r
                free(PtrCU[NbCU].PtrSourceFileDirectory);\r
-               free(PtrCU[NbCU].PtrLinesSrc);\r
+               free(PtrCU[NbCU].PtrUsedLinesSrc);\r
+               free(PtrCU[NbCU].PtrUsedLinesLoadSrc);\r
+               free(PtrCU[NbCU].PtrUsedNumLines);\r
 \r
                while (PtrCU[NbCU].NbLinesLoadSrc--)\r
                {\r
 \r
                while (PtrCU[NbCU].NbLinesLoadSrc--)\r
                {\r
@@ -426,6 +437,14 @@ void DWARFManager_InitDMI(void)
                                                                                        }\r
                                                                                        break;\r
 \r
                                                                                        }\r
                                                                                        break;\r
 \r
+                                                                                       // Language\r
+                                                                               case DW_AT_language:\r
+                                                                                       if (dwarf_formudata(atlist[i], &return_uvalue, &error) == DW_DLV_OK)\r
+                                                                                       {\r
+                                                                                               PtrCU[NbCU].Language = return_uvalue;\r
+                                                                                       }\r
+                                                                                       break;\r
+\r
                                                                                default:\r
                                                                                        break;\r
                                                                                }\r
                                                                                default:\r
                                                                                        break;\r
                                                                                }\r
@@ -468,30 +487,29 @@ void DWARFManager_InitDMI(void)
                                                                }\r
                                                        }\r
 \r
                                                                }\r
                                                        }\r
 \r
-                                                       // Create full filename\r
-                                                       Ptr = PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen(PtrCU[NbCU].PtrSourceFileDirectory) + 2);\r
-#if defined(_WIN32)\r
-                                                       sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
-#else\r
-                                                       sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
-#endif\r
-                                                       // Conform slashes and backslashes\r
-                                                       while (*Ptr)\r
+                                                       // Conform slashes / backslashes for the filename\r
+                                                       DWARFManager_ConformSlachesBackslashes(PtrCU[NbCU].PtrSourceFilename);\r
+\r
+                                                       // Check if filename contains already the complete directory\r
+                                                       if (PtrCU[NbCU].PtrSourceFilename[1] == ':')\r
+                                                       {\r
+                                                               // Copy the filename as the full filename\r
+                                                               PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + 1);\r
+                                                               strcpy(PtrCU[NbCU].PtrFullFilename, PtrCU[NbCU].PtrSourceFilename);\r
+                                                       }\r
+                                                       else\r
                                                        {\r
                                                        {\r
+                                                               // Create full filename and Conform slashes / backslashes\r
+                                                               PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen(PtrCU[NbCU].PtrSourceFileDirectory) + 2);\r
 #if defined(_WIN32)\r
 #if defined(_WIN32)\r
-                                                               if (*Ptr == '/')\r
-                                                               {\r
-                                                                       *Ptr = '\\';\r
-                                                               }\r
+                                                               sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
 #else\r
 #else\r
-                                                               if (*Ptr == '\\')\r
-                                                               {\r
-                                                                       *Ptr = '/';\r
-                                                               }\r
+                                                               sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
 #endif\r
 #endif\r
-                                                               Ptr++;\r
                                                        }\r
 \r
                                                        }\r
 \r
+                                                       DWARFManager_ConformSlachesBackslashes(PtrCU[NbCU].PtrFullFilename);\r
+\r
                                                        // Directory path clean-up\r
 #if defined(_WIN32)\r
                                                        while ((Ptr1 = Ptr = strstr(PtrCU[NbCU].PtrFullFilename, "\\..\\")))\r
                                                        // Directory path clean-up\r
 #if defined(_WIN32)\r
                                                        while ((Ptr1 = Ptr = strstr(PtrCU[NbCU].PtrFullFilename, "\\..\\")))\r
@@ -579,16 +597,26 @@ void DWARFManager_InitDMI(void)
                                        {\r
                                                if (cnt)\r
                                                {\r
                                        {\r
                                                if (cnt)\r
                                                {\r
-                                                       PtrCU[NbCU].NbLinesSrc = cnt;\r
-                                                       PtrCU[NbCU].PtrLinesSrc = (CUStruct_LineSrc *)calloc(cnt, sizeof(CUStruct_LineSrc));\r
+                                                       PtrCU[NbCU].NbUsedLinesSrc = cnt;\r
+                                                       PtrCU[NbCU].PtrUsedLinesSrc = (CUStruct_LineSrc *)calloc(cnt, sizeof(CUStruct_LineSrc));\r
+                                                       PtrCU[NbCU].PtrUsedLinesLoadSrc = (char **)calloc(cnt, sizeof(char *));\r
+                                                       PtrCU[NbCU].PtrUsedNumLines = (size_t *)calloc(cnt, sizeof(size_t));\r
+\r
+                                                       // Get the addresses and their source line numbers\r
                                                        for (Dwarf_Signed i = 0; i < cnt; i++)\r
                                                        {\r
                                                                if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
                                                                {\r
                                                                        if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
                                                                        {\r
                                                        for (Dwarf_Signed i = 0; i < cnt; i++)\r
                                                        {\r
                                                                if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
                                                                {\r
                                                                        if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
                                                                        {\r
-                                                                               PtrCU[NbCU].PtrLinesSrc[i].StartPC = return_lineaddr;\r
-                                                                               PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc = return_uvalue;\r
+                                                                               PtrCU[NbCU].PtrUsedLinesSrc[i].StartPC = return_lineaddr;\r
+                                                                               PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc = return_uvalue;\r
+\r
+                                                                               // Get the last used line number in the source file\r
+                                                                               if (PtrCU[NbCU].LastNumUsedLinesSrc < PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc)\r
+                                                                               {\r
+                                                                                       PtrCU[NbCU].LastNumUsedLinesSrc = PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc;\r
+                                                                               }\r
                                                                        }\r
                                                                }\r
                                                        }\r
                                                                        }\r
                                                                }\r
                                                        }\r
@@ -1041,6 +1069,7 @@ void DWARFManager_InitDMI(void)
                                                                        {\r
                                                                                switch (*Ptr)\r
                                                                                {\r
                                                                        {\r
                                                                                switch (*Ptr)\r
                                                                                {\r
+#ifdef CONVERT_QT_HML\r
                                                                                case 9:\r
                                                                                        strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");\r
                                                                                        i += 6;\r
                                                                                case 9:\r
                                                                                        strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");\r
                                                                                        i += 6;\r
@@ -1066,6 +1095,7 @@ void DWARFManager_InitDMI(void)
                                                                                        strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");\r
                                                                                        i += strlen("&quot;");\r
                                                                                        break;\r
                                                                                        strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");\r
                                                                                        i += strlen("&quot;");\r
                                                                                        break;\r
+#endif\r
 #endif\r
                                                                                default:\r
                                                                                        PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;\r
 #endif\r
                                                                                default:\r
                                                                                        PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;\r
@@ -1117,23 +1147,28 @@ void DWARFManager_InitDMI(void)
                                        }\r
                                }\r
 \r
                                        }\r
                                }\r
 \r
-                               // Set information based on used line numbers\r
-                               if (PtrCU[NbCU].PtrLinesSrc)\r
+                               // Check validity between used number lines and number lines in the source file\r
+                               if (PtrCU[NbCU].LastNumUsedLinesSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
                                {\r
                                {\r
-                                       // Set the line source pointer for each used line numbers\r
-                                       if (PtrCU[NbCU].PtrLinesLoadSrc)\r
+                                       // Set information based on used line numbers\r
+                                       if (PtrCU[NbCU].PtrUsedLinesSrc)\r
                                        {\r
                                        {\r
-                                               for (size_t i = 0; i < PtrCU[NbCU].NbLinesSrc; i++)\r
+                                               // Set the line source pointers for each used line numbers\r
+                                               if (PtrCU[NbCU].PtrLinesLoadSrc)\r
                                                {\r
                                                {\r
-                                                       PtrCU[NbCU].PtrLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc - 1];\r
-                                               }\r
+                                                       for (size_t i = 0; i < PtrCU[NbCU].NbUsedLinesSrc; i++)\r
+                                                       {\r
+                                                               PtrCU[NbCU].PtrUsedNumLines[i] = PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc - 1;\r
+                                                               PtrCU[NbCU].PtrUsedLinesLoadSrc[i] = PtrCU[NbCU].PtrUsedLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc - 1];\r
+                                                       }\r
 \r
 \r
-                                               // Setup memory range for the code if CU doesn't have already this information\r
-                                               // It is taken from the used lines structure\r
-                                               if (!PtrCU[NbCU].LowPC && (!PtrCU[NbCU].HighPC || (PtrCU[NbCU].HighPC == ~0)))\r
-                                               {\r
-                                                       PtrCU[NbCU].LowPC = PtrCU[NbCU].PtrLinesSrc[0].StartPC;\r
-                                                       PtrCU[NbCU].HighPC = PtrCU[NbCU].PtrLinesSrc[PtrCU[NbCU].NbLinesSrc - 1].StartPC;\r
+                                                       // Setup memory range for the code if CU doesn't have already this information\r
+                                                       // It is taken from the used lines structure\r
+                                                       if (!PtrCU[NbCU].LowPC && (!PtrCU[NbCU].HighPC || (PtrCU[NbCU].HighPC == ~0)))\r
+                                                       {\r
+                                                               PtrCU[NbCU].LowPC = PtrCU[NbCU].PtrUsedLinesSrc[0].StartPC;\r
+                                                               PtrCU[NbCU].HighPC = PtrCU[NbCU].PtrUsedLinesSrc[PtrCU[NbCU].NbUsedLinesSrc - 1].StartPC;\r
+                                                       }\r
                                                }\r
                                        }\r
                                }\r
                                                }\r
                                        }\r
                                }\r
@@ -1160,6 +1195,27 @@ void DWARFManager_InitDMI(void)
 }\r
 \r
 \r
 }\r
 \r
 \r
+// Conform slashes and backslashes\r
+void DWARFManager_ConformSlachesBackslashes(char *Ptr)\r
+{\r
+       while (*Ptr)\r
+       {\r
+#if defined(_WIN32)\r
+               if (*Ptr == '/')\r
+               {\r
+                       *Ptr = '\\';\r
+               }\r
+#else\r
+               if (*Ptr == '\\')\r
+               {\r
+                       *Ptr = '/';\r
+               }\r
+#endif\r
+               Ptr++;\r
+       }\r
+}\r
+\r
+\r
 // Variables information initialisation\r
 void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)\r
 {\r
 // Variables information initialisation\r
 void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)\r
 {\r
@@ -1803,11 +1859,11 @@ size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
                        }\r
 \r
                        // Check if a used line is found with the address\r
                        }\r
 \r
                        // Check if a used line is found with the address\r
-                       for (size_t j = 0; j < PtrCU[i].NbLinesSrc; j++)\r
+                       for (size_t j = 0; j < PtrCU[i].NbUsedLinesSrc; j++)\r
                        {\r
                        {\r
-                               if (PtrCU[i].PtrLinesSrc[j].StartPC == Adr)\r
+                               if (PtrCU[i].PtrUsedLinesSrc[j].StartPC == Adr)\r
                                {\r
                                {\r
-                                       return PtrCU[i].PtrLinesSrc[j].NumLineSrc;\r
+                                       return PtrCU[i].PtrUsedLinesSrc[j].NumLineSrc;\r
                                }\r
                        }\r
                }\r
                                }\r
                        }\r
                }\r
@@ -1839,6 +1895,57 @@ char *DWARFManager_GetFunctionName(size_t Adr)
 }\r
 \r
 \r
 }\r
 \r
 \r
+// Get number of lines of texts source list from source index\r
+size_t DWARFManager_GetSrcNbListPtrFromIndex(size_t Index, bool Used)\r
+{\r
+       if (!Used)\r
+       {\r
+               return PtrCU[Index].NbLinesLoadSrc;\r
+       }\r
+       else\r
+       {\r
+               return PtrCU[Index].NbUsedLinesSrc;\r
+       }\r
+}\r
+\r
+\r
+// Get text source line number list pointer from source index\r
+// Return NULL for the text source used list \r
+size_t *DWARFManager_GetSrcNumLinesPtrFromIndex(size_t Index, bool Used)\r
+{\r
+       if (Used)\r
+       {\r
+               return  PtrCU[Index].PtrUsedNumLines;\r
+       }\r
+       else\r
+       {\r
+               return NULL;\r
+       }\r
+}\r
+\r
+\r
+// Get text source list pointers from source index\r
+// Return NULL for the text source used list \r
+char **DWARFManager_GetSrcListPtrFromIndex(size_t Index, bool Used)\r
+{\r
+       if (!Used)\r
+       {\r
+               return PtrCU[Index].PtrLinesLoadSrc;\r
+       }\r
+       else\r
+       {\r
+               return PtrCU[Index].PtrUsedLinesLoadSrc;\r
+       }\r
+}\r
+\r
+\r
+// Get source language\r
+size_t DWARFManager_GetSrcLanguageFromIndex(size_t Index)\r
+{\r
+       return PtrCU[Index].Language;\r
+}\r
+\r
+\r
 // Get text line from source based on address and num line (starting from 1)\r
 // Return NULL if no text line has been found\r
 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)\r
 // Get text line from source based on address and num line (starting from 1)\r
 // Return NULL if no text line has been found\r
 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)\r
@@ -1898,15 +2005,22 @@ char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)
 \r
 \r
 // Get number of source code filenames\r
 \r
 \r
 // Get number of source code filenames\r
-size_t DWARFManager_GetNbFullSourceFilename(void)\r
+size_t DWARFManager_GetNbSources(void)\r
 {\r
        return NbCU;\r
 }\r
 \r
 \r
 {\r
        return NbCU;\r
 }\r
 \r
 \r
-// Get source code filename based on index (starting from 0)\r
+// Get source code filename, including his directory, based on index (starting from 0)\r
 char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
 {\r
        return (PtrCU[Index].PtrFullFilename);\r
 }\r
 \r
 char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
 {\r
        return (PtrCU[Index].PtrFullFilename);\r
 }\r
 \r
+\r
+// Get source code filename based on index (starting from 0)\r
+char *DWARFManager_GetNumSourceFilename(size_t Index)\r
+{\r
+       return (PtrCU[Index].PtrSourceFilename);\r
+}\r
+\r