Added the support for the used lines source's DWARF structure.
authorJean-Paul Mari <djipi.mari@gmail.com>
Tue, 9 Oct 2018 18:49:05 +0000 (14:49 -0400)
committerJean-Paul Mari <djipi.mari@gmail.com>
Tue, 9 Oct 2018 18:49:05 +0000 (14:49 -0400)
Added the Rx version's contact in the help text

docs/vj_ReleaseNotes.txt
src/debugger/DWARFManager.cpp
src/gui/app.cpp

index 70c4756..fb3e78b 100644 (file)
@@ -65,6 +65,9 @@ Git commit: TBD
 32) Improve source code file reading to avoid additional text/bytes reading\r
 33) Help & content texts updates\r
 34) Fixed a crash legacy issue when emulator launches in Alpine mode without a valid rom\r
 32) Improve source code file reading to avoid additional text/bytes reading\r
 33) Help & content texts updates\r
 34) Fixed a crash legacy issue when emulator launches in Alpine mode without a valid rom\r
+35) Added the support for the used lines source's DWARF structure\r
+-- Mostly used to handle missing subprogram's lines information, and missing CU's low/high PC\r
+36) Added the Rx version's contact in the help text\r
 \r
 Release 3 (13th November 2017)\r
 ------------------------------\r
 \r
 Release 3 (13th November 2017)\r
 ------------------------------\r
index e522e4f..bd6507b 100644 (file)
@@ -7,10 +7,9 @@
 //\r
 // WHO  WHEN        WHAT\r
 // ---  ----------  ------------------------------------------------------------\r
 //\r
 // WHO  WHEN        WHAT\r
 // ---  ----------  ------------------------------------------------------------\r
-// JPM  12/03/2016  Created this file\r
-// JPM  12/03/2016  DWARF format support\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  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
+// JPM   Oct./2018  Improve the DWARF parsing information, the source file text reading, and Support the used lines source DWARF structure\r
 //\r
 \r
 // To Do\r
 //\r
 \r
 // To Do\r
 #include "LEB128.h"\r
 \r
 \r
 #include "LEB128.h"\r
 \r
 \r
-// Debug definitions\r
+// Definitions for debugging\r
 //#define DEBUG_NumCU                  0x9                                     // 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_Filename               "net_jag.c"                     // Filename to look for or undefine it\r
 \r
 //#define DEBUG_NumCU                  0x9                                     // 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_Filename               "net_jag.c"                     // Filename to look for or undefine it\r
 \r
+// Definitions for the variables's typetag\r
+#define        TypeTag_structure                       0x01                    // structure\r
+#define        TypeTag_pointer                         0x02                    // pointer\r
+#define        TypeTag_subrange                        0x04                    // (subrange_type?)\r
+#define        TypeTag_arraytype                       0x08                    // array type\r
+#define        TypeTag_consttype                       0x10                    // const type\r
+#define        TypeTag_typedef                         0x20                    // typedef\r
+#define TypeTag_enumeration_type       0x40                    // enumeration\r
+#define TypeTag_subroutine_type                0x80                    // subroutine\r
+\r
+\r
+// Source line CU structure\r
+typedef struct CUStruct_LineSrc\r
+{\r
+       size_t StartPC;\r
+       size_t NumLineSrc;\r
+       char *PtrLineSrc;\r
+}S_CUStruct_LineSrc;\r
 \r
 // Source line internal structure\r
 typedef struct DMIStruct_LineSrc\r
 \r
 // Source line internal structure\r
 typedef struct DMIStruct_LineSrc\r
@@ -70,16 +87,6 @@ typedef struct BaseTypeStruct
 //     StructureMembersStruct *PtrStructureMembers;    // Type's structure members\r
 }S_BaseTypeStruct;\r
 \r
 //     StructureMembersStruct *PtrStructureMembers;    // Type's structure members\r
 }S_BaseTypeStruct;\r
 \r
-// Definitions for the variables's typetag\r
-#define        TypeTag_structure                       0x01                    // structure\r
-#define        TypeTag_pointer                         0x02                    // pointer\r
-#define        TypeTag_subrange                        0x04                    // (subrange_type?)\r
-#define        TypeTag_arraytype                       0x08                    // array type\r
-#define        TypeTag_consttype                       0x10                    // const type\r
-#define        TypeTag_typedef                         0x20                    // typedef\r
-#define TypeTag_enumeration_type       0x40                    // enumeration\r
-#define TypeTag_subroutine_type                0x80                    // subroutine\r
-\r
 // Variables internal structure\r
 typedef struct VariablesStruct\r
 {\r
 // Variables internal structure\r
 typedef struct VariablesStruct\r
 {\r
@@ -117,22 +124,24 @@ typedef struct SubProgStruct
 typedef struct CUStruct\r
 {\r
        size_t Tag;\r
 typedef struct CUStruct\r
 {\r
        size_t Tag;\r
-       size_t LowPC, HighPC;\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
        char *PtrSourceFileDirectory;                                   // Directory of the source file\r
        char *PtrFullFilename;                                                  // Pointer to full namefile (directory & filename)\r
        char *PtrProducer;                                                              // Pointer to the "Producer" text information (mostly compiler and compilation options used)\r
        char *PtrSourceFilename;                                                // Source file name\r
        char *PtrSourceFileDirectory;                                   // Directory of the source file\r
        char *PtrFullFilename;                                                  // Pointer to full namefile (directory & filename)\r
-       size_t SizeLoadSrc;                                                             // Source code size\r
-       char *PtrLoadSrc;                                                               // Pointer to loaded source code\r
-       size_t NbLinesLoadSrc;                                                  // Lines source number\r
+       size_t SizeLoadSrc;                                                             // Source code text size\r
+       char *PtrLoadSrc;                                                               // Pointer to the source code text\r
+       size_t NbLinesLoadSrc;                                                  // Total number of lines in the source code text\r
        char **PtrLinesLoadSrc;                                                 // Pointer lists to each source line put in QT html/text conformity\r
        size_t NbSubProgs;                                                              // Number of sub programs / routines\r
        char **PtrLinesLoadSrc;                                                 // Pointer lists to each source line put in QT html/text conformity\r
        size_t NbSubProgs;                                                              // Number of sub programs / routines\r
-       SubProgStruct *PtrSubProgs;                                             // Pointer to the sub programs / routines information structure\r
+       SubProgStruct *PtrSubProgs;                                             // Pointer to the sub programs / routines structure\r
        size_t NbTypes;                                                                 // Number of types\r
        BaseTypeStruct *PtrTypes;                                               // Pointer to types\r
        size_t NbVariables;                                                             // Variables number\r
        size_t NbTypes;                                                                 // Number of types\r
        BaseTypeStruct *PtrTypes;                                               // Pointer to types\r
        size_t NbVariables;                                                             // Variables number\r
-       VariablesStruct *PtrVariables;                                  // Pointer to the global variables list information structure\r
+       VariablesStruct *PtrVariables;                                  // Pointer to the global variables list structure\r
        size_t NbFrames;                                                                // Frames number\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
 }S_CUStruct;\r
 \r
 \r
 }S_CUStruct;\r
 \r
 \r
@@ -228,6 +237,7 @@ 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
 \r
                while (PtrCU[NbCU].NbLinesLoadSrc--)\r
                {\r
 \r
                while (PtrCU[NbCU].NbLinesLoadSrc--)\r
                {\r
@@ -503,6 +513,22 @@ void DWARFManager_InitDMI(void)
                                        // Get the source lines table located in the CU\r
                                        if (dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK)\r
                                        {\r
                                        // Get the source lines table located in the CU\r
                                        if (dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK)\r
                                        {\r
+                                               if (cnt)\r
+                                               {\r
+                                                       PtrCU[NbCU].NbLinesSrc = cnt;\r
+                                                       PtrCU[NbCU].PtrLinesSrc = (CUStruct_LineSrc *)calloc(cnt, sizeof(CUStruct_LineSrc));\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
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                               }\r
                                        }\r
 \r
                                        // Check if the CU has child\r
                                        }\r
 \r
                                        // Check if the CU has child\r
@@ -988,7 +1014,7 @@ void DWARFManager_InitDMI(void)
                                                        }\r
                                                }\r
 \r
                                                        }\r
                                                }\r
 \r
-                                               // Init lines source information based on each source code line numbers\r
+                                               // Init lines source information for each source code line numbers and for each subprogs\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
                                                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
@@ -1027,6 +1053,27 @@ void DWARFManager_InitDMI(void)
                                        }\r
                                }\r
 \r
                                        }\r
                                }\r
 \r
+                               // Set information based on used line numbers\r
+                               if (PtrCU[NbCU].PtrLinesSrc)\r
+                               {\r
+                                       // Set the line source pointer for each used line numbers\r
+                                       if (PtrCU[NbCU].PtrLinesLoadSrc)\r
+                                       {\r
+                                               for (size_t i = 0; i < PtrCU[NbCU].NbLinesSrc; i++)\r
+                                               {\r
+                                                       PtrCU[NbCU].PtrLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrLinesSrc[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)\r
+                                       {\r
+                                               PtrCU[NbCU].LowPC = PtrCU[NbCU].PtrLinesSrc[0].StartPC;\r
+                                               PtrCU[NbCU].HighPC = PtrCU[NbCU].PtrLinesSrc[PtrCU[NbCU].NbLinesSrc - 1].StartPC;\r
+                                       }\r
+                               }\r
+\r
                                // Init global variables information based on types information\r
                                for (size_t i = 0; i < PtrCU[NbCU].NbVariables; i++)\r
                                {\r
                                // Init global variables information based on types information\r
                                for (size_t i = 0; i < PtrCU[NbCU].NbVariables; i++)\r
                                {\r
@@ -1403,8 +1450,7 @@ size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr, size_t Index)
 \r
 \r
 // Get local variable Op based on his address and index (starting by 1)\r
 \r
 \r
 // Get local variable Op based on his address and index (starting by 1)\r
-// Return 0 if not found\r
-// May return 0 if there isn't Op linked to the variable's index\r
+// Return 0 if not found, may return 0 if there isn't Op linked to the variable's index\r
 size_t DWARFManager_GetLocalVariableOp(size_t Adr, size_t Index)\r
 {\r
        size_t i, j;\r
 size_t DWARFManager_GetLocalVariableOp(size_t Adr, size_t Index)\r
 {\r
        size_t i, j;\r
@@ -1427,9 +1473,8 @@ size_t DWARFManager_GetLocalVariableOp(size_t Adr, size_t Index)
 }\r
 \r
 \r
 }\r
 \r
 \r
-// Get local variable type name based on his index (starting by 1)\r
-// Return NULL if not found\r
-// May return NULL if there is not type linked to the variable's index\r
+// Get local variable type name based on his index (starting by 1) and an address\r
+// Return NULL if not found, may also return NULL if there is no type linked to the variable's index\r
 char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)\r
 {\r
        size_t i, j;\r
 char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)\r
 {\r
        size_t i, j;\r
@@ -1453,7 +1498,7 @@ char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)
 \r
 \r
 // Get Compilation Unit / global variables numbers\r
 \r
 \r
 // Get Compilation Unit / global variables numbers\r
-// Return variables number\r
+// Return number of variables\r
 size_t DWARFManager_GetNbGlobalVariables(void)\r
 {\r
        size_t NbVariables = 0, i;\r
 size_t DWARFManager_GetNbGlobalVariables(void)\r
 {\r
        size_t NbVariables = 0, i;\r
@@ -1594,8 +1639,7 @@ size_t DWARFManager_GetGlobalVariableAdr(size_t Index)
 \r
 \r
 // Get global variable memory address based on his name\r
 \r
 \r
 // Get global variable memory address based on his name\r
-// Return 0 if not found\r
-// Note: Return the first occurence found\r
+// Return 0 if not found, or will return the first occurence found\r
 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)\r
 {\r
        size_t i, j;\r
 size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)\r
 {\r
        size_t i, j;\r
@@ -1619,8 +1663,7 @@ size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)
 \r
 \r
 // Get global variable name based on his index (starting by 1)\r
 \r
 \r
 // Get global variable name based on his index (starting by 1)\r
-// Return name's pointer text found\r
-// Return NULL if not found\r
+// Return name's pointer text found, or will return NULL if no variable can be found\r
 char *DWARFManager_GetGlobalVariableName(size_t Index)\r
 {\r
        size_t i;\r
 char *DWARFManager_GetGlobalVariableName(size_t Index)\r
 {\r
        size_t i;\r
@@ -1645,6 +1688,8 @@ char *DWARFManager_GetGlobalVariableName(size_t Index)
 \r
 \r
 // Get text line from source based on address and his tag\r
 \r
 \r
 // Get text line from source based on address and his tag\r
+// A tag can be either 0 or a DW_TAG_subprogram\r
+// DW_TAG_subprogram will look for the line pointing to the function\r
 // Return NULL if no text line has been found\r
 char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)\r
 {\r
 // Return NULL if no text line has been found\r
 char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)\r
 {\r
@@ -1688,7 +1733,9 @@ char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)
 }\r
 \r
 \r
 }\r
 \r
 \r
-// Get line number based on the address and the tag\r
+// Get line number based on the address and a tag\r
+// A tag can be either 0 or a DW_TAG_subprogram\r
+// DW_TAG_subprogram will look for the line pointing to the function name as described in the source code\r
 // Return 0 if no line number has been found\r
 size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)\r
 {\r
 // Return 0 if no line number has been found\r
 size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)\r
 {\r
@@ -1731,8 +1778,8 @@ size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
 }\r
 \r
 \r
 }\r
 \r
 \r
-// Get function name based on address and his range\r
-// Return NULL if no function name has been found\r
+// Get function name based on an address\r
+// Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address\r
 char *DWARFManager_GetFunctionName(size_t Adr)\r
 {\r
        size_t i, j;\r
 char *DWARFManager_GetFunctionName(size_t Adr)\r
 {\r
        size_t i, j;\r
@@ -1824,7 +1871,7 @@ size_t DWARFManager_GetNbFullSourceFilename(void)
 }\r
 \r
 \r
 }\r
 \r
 \r
-// Get source code filename based on index\r
+// Get source code filename based on index (starting from 0)\r
 char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
 {\r
        return (PtrCU[Index].PtrFullFilename);\r
 char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
 {\r
        return (PtrCU[Index].PtrFullFilename);\r
index 6eb8493..b9903e0 100644 (file)
 // JLH  01/21/2011  Added SDL initialization\r
 // JLH  06/26/2011  Added fix to keep SDL from hijacking main() on win32\r
 // JLH  05/24/2012  Added option switches\r
 // JLH  01/21/2011  Added SDL initialization\r
 // JLH  06/26/2011  Added fix to keep SDL from hijacking main() on win32\r
 // JLH  05/24/2012  Added option switches\r
-// JLH  03/05/2013  Fixed console redireciton on win32 platform  :-P\r
-// JPM  06/06/2016  Visual Studio support\r
-// JPM  06/19/2016  Soft debugger support (--debugger)\r
+// JLH  03/05/2013  Fixed console redirection on win32 platform  :-P\r
+// JPM  Sept./2016  Visual Studio support, and Soft debugger support (--debugger)\r
 // JPM  09/  /2017  Added option (--dram-max) to support 8MB ram (which doesn't exist)\r
 // JPM  09/  /2017  Added option (--dram-max) to support 8MB ram (which doesn't exist)\r
-// JPM  09/06/2017  Added the 'Rx' word to the emulator name and updated the credits line\r
-// JPM  09/08/2017  Added option (--es-all, --es-ui, --es-alpine & --es-debugger) to support the erase settings\r
+// JPM  Sept./2017  Added the 'Rx' word to the emulator name, updated the credits line, added option (--es-all, --es-ui, --es-alpine & --es-debugger) to support the erase settings\r
+// JPM  10/09/2018  Added the Rx version's contact in the help text\r
 //\r
 \r
 #include "app.h"\r
 //\r
 \r
 #include "app.h"\r
@@ -179,6 +178,7 @@ bool ParseCommandLine(int argc, char * argv[])
                                "Based upon the work by James Hammons (Linux/WIN32), Niels Wagenaar (Linux/WIN32),\n"\r
                                "Carwin Jones (BeOS), and Adam Green (MacOS)\n"\r
                                "Contact: http://sdlemu.ngemu.com/ | sdlemu@ngemu.com\n"\r
                                "Based upon the work by James Hammons (Linux/WIN32), Niels Wagenaar (Linux/WIN32),\n"\r
                                "Carwin Jones (BeOS), and Adam Green (MacOS)\n"\r
                                "Contact: http://sdlemu.ngemu.com/ | sdlemu@ngemu.com\n"\r
+                               "Contact: https://github.com/djipi/Virtual-Jaguar-Rx | djipi.mari@gmail.com\n"\r
                                "\n"\r
                                "Usage:\n"\r
                                "   virtualjaguar [<filename>] [switches]\n"\r
                                "\n"\r
                                "Usage:\n"\r
                                "   virtualjaguar [<filename>] [switches]\n"\r