Improve source code file reading to avoid additional text/bytes reading
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DWARFManager.cpp
index bba80ea..e522e4f 100644 (file)
@@ -9,8 +9,8 @@
 // ---  ----------  ------------------------------------------------------------\r
 // JPM  12/03/2016  Created this file\r
 // JPM  12/03/2016  DWARF format support\r
-// JPM  09/12/2018  Added LEB128 decoding features\r
-// JPM  09/14/2018  Improve the DWARF parsing information\r
+// JPM  Sept./2018  Added LEB128 decoding features, and improve the DWARF parsing information\r
+// JPM  10/06/2018  Improve the DWARF parsing information, and the source file text reading\r
 //\r
 \r
 // To Do\r
 #include "LEB128.h"\r
 \r
 \r
-//\r
+// Debug definitions\r
 //#define DEBUG_NumCU                  0x9                                     // CU number to debug or undefine it\r
-//#define DEBUG_VariableName   "alloc"                         // Variable name to look for 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_Filename               "cmd.c"                 // Filename to look for or undefine it\r
+//#define DEBUG_Filename               "net_jag.c"                     // Filename to look for or undefine it\r
 \r
 \r
 // Source line internal structure\r
@@ -282,7 +282,6 @@ void DWARFManager_InitDMI(void)
        Dwarf_Off return_offset;\r
        Dwarf_Line *linebuf;\r
        FILE *SrcFile;\r
-       size_t i, j, k;\r
        char *return_string;\r
        char *Ptr, *Ptr1;\r
 \r
@@ -434,36 +433,60 @@ void DWARFManager_InitDMI(void)
                                                                strcpy((Ptr1 + 1), (Ptr + 4));\r
                                                        }\r
 \r
-                                                       // Read the file as text\r
-#ifndef __CYGWIN__\r
-                                                       if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rt"))\r
-#else\r
-                                                       if (!(SrcFile = fopen(SourceFullFilename, "rt")))\r
-#endif\r
+                                                       // Open the source file as a binary file\r
+                                                       if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rb"))\r
                                                        {\r
                                                                if (!fseek(SrcFile, 0, SEEK_END))\r
                                                                {\r
                                                                        if ((PtrCU[NbCU].SizeLoadSrc = ftell(SrcFile)) > 0)\r
                                                                        {\r
-                                                                               if (PtrCU[NbCU].PtrLoadSrc = Ptr = (char *)calloc((PtrCU[NbCU].SizeLoadSrc + 1), 1))\r
+                                                                               if (!fseek(SrcFile, 0, SEEK_SET))\r
                                                                                {\r
-                                                                                       rewind(SrcFile);\r
-                                                                                       if (PtrCU[NbCU].SizeLoadSrc < fread(Ptr, 1, PtrCU[NbCU].SizeLoadSrc, SrcFile))\r
-                                                                                       {\r
-                                                                                               free(PtrCU[NbCU].PtrLoadSrc);\r
-                                                                                               PtrCU[NbCU].PtrLoadSrc = NULL;\r
-                                                                                               PtrCU[NbCU].SizeLoadSrc = 0;\r
-                                                                                       }\r
-                                                                                       else\r
+                                                                                       if (PtrCU[NbCU].PtrLoadSrc = Ptr = Ptr1 = (char *)calloc(1, (PtrCU[NbCU].SizeLoadSrc + 2)))\r
                                                                                        {\r
-                                                                                               do\r
+                                                                                               // Read whole file\r
+                                                                                               if (fread_s(PtrCU[NbCU].PtrLoadSrc, PtrCU[NbCU].SizeLoadSrc, PtrCU[NbCU].SizeLoadSrc, 1, SrcFile) != 1)\r
                                                                                                {\r
-                                                                                                       if (*Ptr == 0xa)\r
+                                                                                                       free(PtrCU[NbCU].PtrLoadSrc);\r
+                                                                                                       PtrCU[NbCU].PtrLoadSrc = NULL;\r
+                                                                                                       PtrCU[NbCU].SizeLoadSrc = 0;\r
+                                                                                               }\r
+                                                                                               else\r
+                                                                                               {\r
+                                                                                                       // Eliminate all carriage return code '\r' (oxd)\r
+                                                                                                       do\r
+                                                                                                       {\r
+                                                                                                               if ((*Ptr = *Ptr1) != '\r')\r
+                                                                                                               {\r
+                                                                                                                       Ptr++;\r
+                                                                                                               }\r
+                                                                                                       }\r
+                                                                                                       while (*Ptr1++);\r
+\r
+                                                                                                       // Get back the new text file size\r
+                                                                                                       PtrCU[NbCU].SizeLoadSrc = strlen(Ptr = PtrCU[NbCU].PtrLoadSrc);\r
+\r
+                                                                                                       // Make sure the text file finish with a new line code '\n' (0xa)\r
+                                                                                                       if (PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc - 1] != '\n')\r
                                                                                                        {\r
-                                                                                                               PtrCU[NbCU].NbLinesLoadSrc++;\r
-                                                                                                               *Ptr = 0;\r
+                                                                                                               PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc++] = '\n';\r
+                                                                                                               PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc] = 0;\r
                                                                                                        }\r
-                                                                                               } while (*++Ptr);\r
+\r
+                                                                                                       // Reallocate text file\r
+                                                                                                       if (PtrCU[NbCU].PtrLoadSrc = Ptr = (char *)realloc(PtrCU[NbCU].PtrLoadSrc, (PtrCU[NbCU].SizeLoadSrc + 1)))\r
+                                                                                                       {\r
+                                                                                                               // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0\r
+                                                                                                               do\r
+                                                                                                               {\r
+                                                                                                                       if (*Ptr == '\n')\r
+                                                                                                                       {\r
+                                                                                                                               PtrCU[NbCU].NbLinesLoadSrc++;\r
+                                                                                                                               *Ptr = 0;\r
+                                                                                                                       }\r
+                                                                                                               } while (*++Ptr);\r
+                                                                                                       }\r
+                                                                                               }\r
                                                                                        }\r
                                                                                }\r
                                                                        }\r
@@ -477,7 +500,7 @@ void DWARFManager_InitDMI(void)
                                                }\r
                                        }\r
 \r
-                                       // Get the source lines table located in the Compilation Unit\r
+                                       // Get the source lines table located in the CU\r
                                        if (dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK)\r
                                        {\r
                                        }\r
@@ -558,7 +581,22 @@ void DWARFManager_InitDMI(void)
                                                                                        dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
                                                                                }\r
 \r
-                                                                               PtrCU[NbCU].NbVariables++;\r
+                                                                               // Check variable's name validity\r
+                                                                               if (PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName)\r
+                                                                               {\r
+                                                                                       // Check variable's memory address validity\r
+                                                                                       if (PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].Addr)\r
+                                                                                       {\r
+                                                                                               // Valid variable\r
+                                                                                               PtrCU[NbCU].NbVariables++;\r
+                                                                                       }\r
+                                                                                       else\r
+                                                                                       {\r
+                                                                                               // Invalid variable\r
+                                                                                               free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);\r
+                                                                                               PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName = NULL;\r
+                                                                                       }\r
+                                                                               }\r
 \r
                                                                                dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
                                                                        }\r
@@ -747,7 +785,7 @@ void DWARFManager_InitDMI(void)
                                                                                dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
 \r
                                                                                // Get source line number and associated block of address\r
-                                                                               for (i = 0; i < (size_t)cnt; ++i)\r
+                                                                               for (Dwarf_Signed i = 0; i < cnt; ++i)\r
                                                                                {\r
                                                                                        if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
                                                                                        {\r
@@ -889,7 +927,7 @@ void DWARFManager_InitDMI(void)
                                        }\r
 \r
                                        // Release the memory used by the source lines\r
-                                       for (i = 0; i < (size_t)cnt; ++i)\r
+                                       for (Dwarf_Signed i = 0; i < cnt; ++i)\r
                                        {\r
                                                dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);\r
                                        }\r
@@ -901,13 +939,13 @@ void DWARFManager_InitDMI(void)
                                {\r
                                        if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(PtrCU[NbCU].NbLinesLoadSrc, sizeof(char *)))\r
                                        {\r
-                                               for (j = 0; j < PtrCU[NbCU].NbLinesLoadSrc; j++)\r
+                                               for (size_t j = 0; j < PtrCU[NbCU].NbLinesLoadSrc; j++)\r
                                                {\r
                                                        if (PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)calloc(10000, sizeof(char)))\r
                                                        {\r
                                                                if (Ptr = DWARFManager_GetLineSrcFromNumLine(PtrCU[NbCU].PtrLoadSrc, (j + 1)))\r
                                                                {\r
-                                                                       i = 0;\r
+                                                                       size_t i = 0;\r
 \r
                                                                        while (*Ptr)\r
                                                                        {\r
@@ -915,17 +953,17 @@ void DWARFManager_InitDMI(void)
                                                                                {\r
                                                                                case 9:\r
                                                                                        strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");\r
-                                                                                       i += strlen("&nbsp;");\r
+                                                                                       i += 6;\r
                                                                                        break;\r
 \r
                                                                                case '<':\r
                                                                                        strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&lt;");\r
-                                                                                       i += strlen("&lt;");\r
+                                                                                       i += 4;\r
                                                                                        break;\r
 \r
                                                                                case '>':\r
                                                                                        strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&gt;");\r
-                                                                                       i += strlen("&gt;");\r
+                                                                                       i += 4;\r
                                                                                        break;\r
 #if 0\r
                                                                                case '&':\r
@@ -946,12 +984,12 @@ void DWARFManager_InitDMI(void)
                                                                                Ptr++;\r
                                                                        }\r
                                                                }\r
-                                                               PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)realloc(PtrCU[NbCU].PtrLinesLoadSrc[j], i + 1);\r
+                                                               PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)realloc(PtrCU[NbCU].PtrLinesLoadSrc[j], strlen(PtrCU[NbCU].PtrLinesLoadSrc[j]) + 1);\r
                                                        }\r
                                                }\r
 \r
                                                // Init lines source information based on each source code line numbers\r
-                                               for (j = 0; j < PtrCU[NbCU].NbSubProgs; j++)\r
+                                               for (size_t j = 0; j < PtrCU[NbCU].NbSubProgs; j++)\r
                                                {\r
                                                        // Check if the subprog / function's line exists in the source code\r
                                                        if (PtrCU[NbCU].PtrSubProgs[j].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
@@ -959,7 +997,7 @@ void DWARFManager_InitDMI(void)
                                                                PtrCU[NbCU].PtrSubProgs[j].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].NumLineSrc - 1];\r
                                                        }\r
 \r
-                                                       for (k = 0; k < PtrCU[NbCU].PtrSubProgs[j].NbLinesSrc; k++)\r
+                                                       for (size_t k = 0; k < PtrCU[NbCU].PtrSubProgs[j].NbLinesSrc; k++)\r
                                                        {\r
                                                                if (PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
                                                                {\r
@@ -977,10 +1015,10 @@ void DWARFManager_InitDMI(void)
                                                // Check the presence of source lines dedicated to the sub progs\r
                                                if (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc)\r
                                                {\r
-                                                       i = PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc - 1].NumLineSrc;\r
+                                                       size_t i = PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc - 1].NumLineSrc;\r
                                                        if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(i, sizeof(char *)))\r
                                                        {\r
-                                                               for (j = 0; j < i; j++)\r
+                                                               for (size_t j = 0; j < i; j++)\r
                                                                {\r
                                                                        PtrCU[NbCU].PtrLinesLoadSrc[j] = NULL;\r
                                                                }\r
@@ -990,15 +1028,15 @@ void DWARFManager_InitDMI(void)
                                }\r
 \r
                                // Init global variables information based on types information\r
-                               for (i = 0; i < PtrCU[NbCU].NbVariables; i++)\r
+                               for (size_t i = 0; i < PtrCU[NbCU].NbVariables; i++)\r
                                {\r
                                        DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrVariables + i);\r
                                }\r
 \r
                                // Init local variables information based on types information\r
-                               for (i = 0; i < PtrCU[NbCU].NbSubProgs; i++)\r
+                               for (size_t i = 0; i < PtrCU[NbCU].NbSubProgs; i++)\r
                                {\r
-                                       for (j = 0; j < PtrCU[NbCU].PtrSubProgs[i].NbVariables; j++)\r
+                                       for (size_t j = 0; j < PtrCU[NbCU].PtrSubProgs[i].NbVariables; j++)\r
                                        {\r
                                                DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrSubProgs[i].PtrVariables + j);\r
                                        }\r
@@ -1754,8 +1792,8 @@ char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)
 }\r
 \r
 \r
-// Get text line from source based on address and num line (starting by 1)\r
-// Return NULL if no text line has been found\r
+// Get text line pointer from source, based on address and line number (starting by 1)\r
+// Return NULL if no text line has been found, or if requested number line is above the source total number of lines\r
 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)\r
 {\r
        size_t i;\r
@@ -1778,3 +1816,17 @@ char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)
        return NULL;\r
 }\r
 \r
+\r
+// Get number of source code filenames\r
+size_t DWARFManager_GetNbFullSourceFilename(void)\r
+{\r
+       return NbCU;\r
+}\r
+\r
+\r
+// Get source code filename based on index\r
+char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
+{\r
+       return (PtrCU[Index].PtrFullFilename);\r
+}\r
+\r