// JPM Various efforts to set the ELF format support\r
// JPM Various efforts to set the DWARF format support\r
// JPM 09/15/2018 Support the unsigned char\r
-// JPM 10/06/2018 Cosmetic changes\r
+// JPM Oct./2018 Cosmetic changes, and added source file search paths\r
//\r
\r
// To Do\r
}S_Value;\r
\r
\r
+//\r
+void DBGManager_SourceFileSearchPathsInit(void);\r
+void DBGManager_SourceFileSearchPathsReset(void);\r
+void DBGManager_SourceFileSearchPathsClose(void);\r
+\r
+\r
// Common debugger variables\r
size_t DBGType;\r
char value[1000];\r
+size_t NbSFSearchPaths;\r
+char **SourceFileSearchPaths;\r
+\r
+\r
+// Init the source file search paths\r
+void DBGManager_SourceFileSearchPathsInit(void)\r
+{\r
+ NbSFSearchPaths = 0;\r
+ SourceFileSearchPaths = NULL;\r
+}\r
+\r
+\r
+// Set the source file search paths\r
+// Create individual path for each one provided in the list (separate with ';')\r
+void DBGManager_SourceFileSearchPathsSet(char *ListPaths)\r
+{\r
+ // Check presence of a previous list\r
+ if (NbSFSearchPaths)\r
+ {\r
+ // Reset previous list\r
+ DBGManager_SourceFileSearchPathsReset();\r
+ }\r
+\r
+ // Check if there is a paths list\r
+ if (strlen(ListPaths))\r
+ {\r
+ // Get number of paths\r
+ char *Ptr = ListPaths;\r
+ while(*Ptr)\r
+ {\r
+ while (*Ptr && (*Ptr++ != ';'));\r
+ {\r
+ NbSFSearchPaths++;\r
+ }\r
+ }\r
+\r
+ // Isolate each search path\r
+ SourceFileSearchPaths = (char **)calloc(NbSFSearchPaths, sizeof(char *));\r
+ size_t i = 0;\r
+ Ptr = ListPaths;\r
+\r
+ while (*Ptr)\r
+ {\r
+ // Search the path separator (';')\r
+ char *Ptr1 = Ptr;\r
+ while (*Ptr && (*Ptr++ != ';'));\r
+\r
+ // Copy the inidividual search path\r
+ SourceFileSearchPaths[i] = (char *)calloc(1, (Ptr - Ptr1) + 1);\r
+ strncpy(SourceFileSearchPaths[i], Ptr1, (Ptr - Ptr1));\r
+ if (SourceFileSearchPaths[i][strlen(SourceFileSearchPaths[i]) - 1] == ';')\r
+ {\r
+ SourceFileSearchPaths[i][strlen(SourceFileSearchPaths[i]) - 1] = 0;\r
+ }\r
+ i++;\r
+ }\r
+ }\r
+\r
+ DWARFManager_Set(NbSFSearchPaths, SourceFileSearchPaths);\r
+}\r
+\r
+\r
+// Reset the source file search paths\r
+void DBGManager_SourceFileSearchPathsReset(void)\r
+{\r
+ // Free each path\r
+ while (NbSFSearchPaths)\r
+ {\r
+ free(SourceFileSearchPaths[--NbSFSearchPaths]);\r
+ }\r
+\r
+ // Free the pointers list\r
+ free(SourceFileSearchPaths);\r
+ SourceFileSearchPaths = NULL;\r
+}\r
+\r
+\r
+// Close the source file search paths\r
+void DBGManager_SourceFileSearchPathsClose(void)\r
+{\r
+ DBGManager_SourceFileSearchPathsReset();\r
+}\r
\r
\r
// Common debugger initialisation\r
void DBGManager_Init(void)\r
{\r
+ // DBG initialisations\r
DBGType = DBG_NO_TYPE;\r
+ DBGManager_SourceFileSearchPathsInit();\r
+\r
+ // ELF initialisation \r
ELFManager_Init();\r
+ // DWARF initialisation\r
DWARFManager_Init();\r
}\r
\r
}\r
\r
\r
-// Get debugger type\r
-size_t DBGManager_GetType(void)\r
-{\r
- return DBGType;\r
-}\r
-\r
-\r
-// Common debugger set\r
-void DBGManager_SetType(size_t DBGTypeSet)\r
-{\r
- DBGType |= DBGTypeSet;\r
-}\r
-\r
-\r
// Common debugger close\r
void DBGManager_Close(void)\r
{\r
{\r
ELFManager_Close();\r
}\r
+\r
+ DBGManager_SourceFileSearchPathsClose();\r
+ DBGType = DBG_NO_TYPE;\r
+}\r
+\r
+\r
+// Common debugger set\r
+void DBGManager_SetType(size_t DBGTypeSet)\r
+{\r
+ DBGType |= DBGTypeSet;\r
+}\r
+\r
+\r
+// Get debugger type\r
+size_t DBGManager_GetType(void)\r
+{\r
+ return DBGType;\r
}\r
\r
\r
// --- ---------- ------------------------------------------------------------\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, the source file text reading, and Support the used lines source DWARF structure\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
//\r
\r
// To Do\r
Dwarf_Error error;\r
Dwarf_Debug dbg;\r
CUStruct *PtrCU;\r
+char **ListSearchPaths;\r
+size_t NbSearchPaths;\r
\r
\r
//\r
bool DWARFManager_ElfClose(void);\r
char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine);\r
void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables);\r
+void DWARFManager_SourceFileSearchPathsInit(void);\r
+void DWARFManager_SourceFileSearchPathsReset(void);\r
+void DWARFManager_SourceFileSearchPathsClose(void);\r
\r
\r
//\r
}\r
\r
\r
+// Dwarf manager list search paths init\r
+void DWARFManager_SourceFileSearchPathsInit(void)\r
+{\r
+ ListSearchPaths = NULL;\r
+ NbSearchPaths = 0;\r
+}\r
+\r
+\r
+// Dwarf manager list search paths reset\r
+void DWARFManager_SourceFileSearchPathsReset(void)\r
+{\r
+ ListSearchPaths = NULL;\r
+ NbSearchPaths = 0;\r
+}\r
+\r
+\r
+// Dwarf manager list search paths close\r
+void DWARFManager_SourceFileSearchPathsClose(void)\r
+{\r
+ DWARFManager_SourceFileSearchPathsReset();\r
+}\r
+\r
+\r
// Dwarf manager init\r
void DWARFManager_Init(void)\r
{\r
+ DWARFManager_SourceFileSearchPathsInit();\r
LibDwarf = DW_DLV_NO_ENTRY;\r
}\r
\r
\r
+// Dwarf manager settings\r
+void DWARFManager_Set(size_t NbPathsInList, char **PtrListPaths)\r
+{\r
+ // Search paths init\r
+ ListSearchPaths = PtrListPaths;\r
+ NbSearchPaths = NbPathsInList;\r
+}\r
+\r
+\r
// Dwarf manager Reset\r
bool DWARFManager_Reset(void)\r
{\r
+ DWARFManager_SourceFileSearchPathsReset();\r
return DWARFManager_ElfClose();\r
}\r
\r
// Dwarf manager Close\r
bool DWARFManager_Close(void)\r
{\r
+ DWARFManager_SourceFileSearchPathsClose();\r
return(DWARFManager_Reset());\r
}\r
\r
dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
}\r
\r
- // Check filename validity\r
+ // Check filename presence\r
if (!PtrCU[NbCU].PtrSourceFilename)\r
{\r
PtrCU[NbCU].PtrSourceFilename = (char *)calloc(1, 1);\r
}\r
\r
- // Check directory validity\r
+ // Check directory presence\r
if (!PtrCU[NbCU].PtrSourceFileDirectory)\r
{\r
- PtrCU[NbCU].PtrSourceFileDirectory = (char *)calloc(2, 1);\r
- PtrCU[NbCU].PtrSourceFileDirectory[0] = '.';\r
+ // Check if file exists in the search paths\r
+ for (size_t i = 0; i < NbSearchPaths; i++)\r
+ {\r
+ PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen((const char *)ListSearchPaths[i]) + 2);\r
+#if defined(_WIN32)\r
+ sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", ListSearchPaths[i], PtrCU[NbCU].PtrSourceFilename);\r
+#else\r
+ sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", ListSearchPaths[i], PtrCU[NbCU].PtrSourceFilename);\r
+#endif\r
+ if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rb"))\r
+ {\r
+ PtrCU[NbCU].PtrSourceFileDirectory = (char *)realloc(PtrCU[NbCU].PtrSourceFileDirectory, strlen(ListSearchPaths[i]) + 1);\r
+ strcpy(PtrCU[NbCU].PtrSourceFileDirectory, ListSearchPaths[i]);\r
+ }\r
+ }\r
+\r
+ // File directory doesn't exits\r
+ if (!PtrCU[NbCU].PtrSourceFileDirectory)\r
+ {\r
+ PtrCU[NbCU].PtrSourceFileDirectory = (char *)realloc(PtrCU[NbCU].PtrSourceFileDirectory, 2);\r
+ strcpy(PtrCU[NbCU].PtrSourceFileDirectory, ".");\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
-\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
{\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
// Return NULL if no symbol name exists\r
char *DWARFManager_GetSymbolnameFromAdr(size_t Adr)\r
{\r
- size_t i, j;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; (j < PtrCU[i].NbSubProgs); j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr))\r
{\r
// Return the existence status (true or false) in Error\r
char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error)\r
{\r
- size_t i;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
}\r
\r
\r
-// Get text line source based on line number (starting by 1)\r
+// Get text line source based on line number (starting from 1)\r
// Return NULL if no text line exists or if line number is 0\r
char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine)\r
{\r
// Get number of variables referenced by the function range address\r
size_t DWARFManager_GetNbLocalVariables(size_t Adr)\r
{\r
- size_t i, j;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
\r
\r
-// Get local variable name based on his index (starting by 1)\r
+// Get local variable name based on his index (starting from 1)\r
// Return name's pointer text found\r
// Return NULL if not found\r
char *DWARFManager_GetLocalVariableName(size_t Adr, size_t Index)\r
{\r
- size_t i, j;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
\r
\r
-// Get local variable's type tag based on his index (starting by 1)\r
+// Get local variable's type tag based on his index (starting from 1)\r
// Return 0 if not found\r
size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr, size_t Index)\r
{\r
- size_t i, j;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
\r
\r
-//\r
+// Get the local variable's offset based on a index (starting from 1)\r
+// Return 0 if no offset has been found\r
int DWARFManager_GetLocalVariableOffset(size_t Adr, size_t Index)\r
{\r
- size_t i, j;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
\r
\r
-// Get local variable Type Byte Size based on his address and index (starting by 1)\r
+// Get local variable Type Byte Size based on his address and index (starting from 1)\r
// Return 0 if not found\r
// May return 0 if there is no Type Byte Size linked to the variable's address and index\r
size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr, size_t Index)\r
{\r
- size_t i, j;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
\r
\r
-// Get local variable Type Encoding based on his address and index (starting by 1)\r
+// Get local variable Type Encoding based on his address and index (starting from 1)\r
// Return 0 if not found\r
// May return 0 if there is no Type Encoding linked to the variable's address and index\r
size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr, size_t Index)\r
{\r
- size_t i, j;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
\r
\r
-// Get local variable Op based on his address and index (starting by 1)\r
+// Get local variable Op based on his address and index (starting from 1)\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
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
\r
\r
-// Get local variable type name based on his index (starting by 1) and an address\r
+// Get local variable type name based on his index (starting from 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
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
// Return number of variables\r
size_t DWARFManager_GetNbGlobalVariables(void)\r
{\r
- size_t NbVariables = 0, i;\r
+ size_t NbVariables = 0;\r
\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
NbVariables += PtrCU[i].NbVariables;\r
}\r
}\r
\r
\r
-// Get global variable type name based on his index (starting by 1)\r
+// Get global variable type name based on his index (starting from 1)\r
// Return NULL if not found\r
// May return NULL if there is not type linked to the variable's index\r
char *DWARFManager_GetGlobalVariableTypeName(size_t Index)\r
{\r
- size_t i;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if (PtrCU[i].NbVariables)\r
{\r
}\r
\r
\r
-// Get global variable's type tag based on his index (starting by 1)\r
+// Get global variable's type tag based on his index (starting from 1)\r
// Return 0 if not found\r
size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index)\r
{\r
- size_t i;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if (PtrCU[i].NbVariables)\r
{\r
}\r
\r
\r
-// Get global variable byte size based on his index (starting by 1)\r
+// Get global variable byte size based on his index (starting from 1)\r
// Return 0 if not found\r
size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index)\r
{\r
- size_t i;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if (PtrCU[i].NbVariables)\r
{\r
}\r
\r
\r
-// Get global variable encoding based on his index (starting by 1)\r
+// Get global variable encoding based on his index (starting from 1)\r
// Return 0 if not found\r
size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index)\r
{\r
- size_t i;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if (PtrCU[i].NbVariables)\r
{\r
}\r
\r
\r
-// Get global variable address based on his index (starting by 1)\r
+// Get global variable memory address based on his index (starting from 1)\r
// Return 0 if not found\r
size_t DWARFManager_GetGlobalVariableAdr(size_t Index)\r
{\r
- size_t i;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if (PtrCU[i].NbVariables)\r
{\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
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if (PtrCU[i].NbVariables)\r
{\r
- for (j = 0; j < PtrCU[i].NbVariables; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbVariables; j++)\r
{\r
if (!strcmp(PtrCU[i].PtrVariables[j].PtrName,VariableName))\r
{\r
}\r
\r
\r
-// Get global variable name based on his index (starting by 1)\r
+// Get global variable name based on his index (starting from 1)\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
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if (PtrCU[i].NbVariables)\r
{\r
// Return NULL if no text line has been found\r
char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)\r
{\r
- size_t i, j, k;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
else\r
{\r
- for (k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
+ for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
{\r
if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC <= Adr)\r
{\r
// Return 0 if no line number has been found\r
size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)\r
{\r
- size_t i, j, k;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; (j < PtrCU[i].NbSubProgs); j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
else\r
{\r
- for (k = 0; (k < PtrCU[i].PtrSubProgs[j].NbLinesSrc); k++)\r
+ for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
{\r
if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
{\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
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
\r
\r
-// Get text line from source based on address and num line (starting by 1)\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
{\r
- size_t i, j, k;\r
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
- for (j = 0; j < PtrCU[i].NbSubProgs; j++)\r
+ for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
{\r
if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
{\r
}\r
else\r
{\r
- for (k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
+ for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
{\r
if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc == NumLine)\r
{\r
}\r
\r
\r
-// Get text line pointer from source, based on address and line number (starting by 1)\r
+// Get text line pointer from source, based on address and line number (starting from 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
-\r
- for (i = 0; i < NbCU; i++)\r
+ for (size_t i = 0; i < NbCU; i++)\r
{\r
if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
{\r
//\r
// WHO WHEN WHAT\r
// --- ---------- ------------------------------------------------------------\r
-// JPM 06/19/2016 Created this file\r
-// JPM 06/19/2016 Soft debugger support\r
+// JPM Sept./2016 Created this file, and added Soft debugger support\r
+// JPM 10/09/2018 Added source file search paths\r
//\r
\r
#include "debuggertab.h"\r
#include "settings.h"\r
\r
\r
+// \r
DebuggerTab::DebuggerTab(QWidget * parent/*= 0*/): QWidget(parent)\r
{\r
- QLabel * label3 = new QLabel("Disassembly lines:");\r
- edit3 = new QLineEdit("");\r
- edit3->setPlaceholderText("Number of disassembly lines");\r
- QVBoxLayout * layout1 = new QVBoxLayout;\r
+ // Number of disassembly lines\r
+ QLabel *label3 = new QLabel("Disassembly lines:");\r
+ QVBoxLayout *layout1 = new QVBoxLayout;\r
layout1->addWidget(label3);\r
-\r
- QVBoxLayout * layout2 = new QVBoxLayout;\r
- layout2->addWidget(edit3);\r
-\r
- QHBoxLayout * layout3 = new QHBoxLayout;\r
+ QVBoxLayout *layout2 = new QVBoxLayout;\r
+ nbrdisasmlines = new QLineEdit("");\r
+ nbrdisasmlines->setPlaceholderText("Number of disassembly lines");\r
+ layout2->addWidget(nbrdisasmlines);\r
+\r
+ // Sources code paths\r
+ QLabel *label4 = new QLabel("Source file search paths:");\r
+ QVBoxLayout *layout5 = new QVBoxLayout;\r
+ layout5->addWidget(label4);\r
+ QVBoxLayout *layout6 = new QVBoxLayout;\r
+ sourcefilesearchpaths = new QLineEdit("");\r
+ sourcefilesearchpaths->setMaxLength(sizeof(vjs.sourcefilesearchPaths));\r
+ sourcefilesearchpaths->setPlaceholderText("Each path must be separate by a ';', search is recursive and based on each path");\r
+ layout6->addWidget(sourcefilesearchpaths);\r
+\r
+ QHBoxLayout *layout3 = new QHBoxLayout;\r
layout3->addLayout(layout1);\r
layout3->addLayout(layout2);\r
+ QHBoxLayout *layout7 = new QHBoxLayout;\r
+ layout7->addLayout(layout5);\r
+ layout7->addLayout(layout6);\r
\r
- QVBoxLayout * layout4 = new QVBoxLayout;\r
+ QVBoxLayout *layout4 = new QVBoxLayout;\r
layout4->addLayout(layout3);\r
+ layout4->addLayout(layout7);\r
\r
- // Checkboxes...\r
+ // Checkboxes\r
displayHWlabels = new QCheckBox(tr("Display HW labels"));\r
disasmopcodes = new QCheckBox(tr("Display M68000 opcodes"));\r
displayFullSourceFilename = new QCheckBox(tr("Display source filename"));\r
}\r
\r
\r
+// \r
DebuggerTab::~DebuggerTab()\r
{\r
}\r
{\r
bool ok;\r
\r
- //strcpy(vjs.debuggerROMPath, debuggerTab->edit1->text().toUtf8().data());\r
strcpy(vjs.debuggerROMPath, vjs.alpineROMPath);\r
- //strcpy(vjs.absROMPath, debuggerTab->edit2->text().toUtf8().data());\r
- vjs.nbrdisasmlines = edit3->text().toUInt(&ok, 10);\r
- //vjs.allowWritesToROM = debuggerTab->writeROM->isChecked();\r
+ strcpy(vjs.sourcefilesearchPaths, CheckForTrailingSlash(sourcefilesearchpaths->text()).toUtf8().data());\r
+ vjs.nbrdisasmlines = nbrdisasmlines->text().toUInt(&ok, 10);\r
vjs.displayHWlabels = displayHWlabels->isChecked();\r
vjs.disasmopcodes = disasmopcodes->isChecked();\r
vjs.displayFullSourceFilename = displayFullSourceFilename->isChecked();\r
void DebuggerTab::GetSettings(void)\r
{\r
QVariant v(vjs.nbrdisasmlines);\r
- //debuggerTab->edit1->setText(vjs.debuggerROMPath);\r
- //debuggerTab->edit2->setText(vjs.absROMPath);\r
- edit3->setText(v.toString());\r
- //debuggerTab->writeROM->setChecked(vjs.allowWritesToROM\r
+ nbrdisasmlines->setText(v.toString());\r
+ sourcefilesearchpaths->setText(vjs.sourcefilesearchPaths);\r
displayHWlabels->setChecked(vjs.displayHWlabels);\r
disasmopcodes->setChecked(vjs.disasmopcodes);\r
displayFullSourceFilename->setChecked(vjs.displayFullSourceFilename);\r
}\r
\r
+\r
+// Remove the last character if slash or backslash at the end of each string\r
+// Depend the platform transform slashes or backslashes\r
+QString DebuggerTab::CheckForTrailingSlash(QString s)\r
+{\r
+ if (s.endsWith('/') || s.endsWith('\\'))\r
+ {\r
+ s.remove(s.length() - 1, 1);\r
+ }\r
+#ifdef _WIN32\r
+ s.replace(QString("/"), QString("\\"));\r
+ s.replace(QString("\\;"), QString(";"));\r
+#else\r
+ s.replace(QString("\\"), QString("/"));\r
+ s.replace(QString("/;"), QString(";"));\r
+#endif\r
+ return s;\r
+}\r
// JPM 11/04/2017 Added the local window\r
// JPM 08/31/2018 Added the call stack window\r
// JPM Sept./2018 Added the new Models and BIOS handler, a screenshot feature and source code files browsing\r
+// JPM 10/10/2018 Added search paths in the settings\r
//\r
\r
// FIXED:\r
#include "joystick.h"\r
#include "m68000/m68kinterface.h"\r
\r
+#include "debugger/DBGManager.h"\r
//#include "debugger/VideoWin.h"\r
//#include "debugger/DasmWin.h"\r
#include "debugger/m68KDasmWin.h"\r
// Read settings from the Debugger mode\r
settings.beginGroup("debugger");\r
strcpy(vjs.debuggerROMPath, settings.value("DefaultROM", "").toString().toUtf8().data());\r
+ strcpy(vjs.sourcefilesearchPaths, settings.value("SourceFileSearchPaths", "").toString().toUtf8().data());\r
vjs.nbrdisasmlines = settings.value("NbrDisasmLines", 32).toUInt();\r
vjs.disasmopcodes = settings.value("DisasmOpcodes", true).toBool();\r
vjs.displayHWlabels = settings.value("DisplayHWLabels", true).toBool();\r
\r
// Write important settings to the log file\r
WriteLog("MainWin: Paths\n");\r
- WriteLog(" EEPROMPath = \"%s\"\n", vjs.EEPROMPath);\r
- WriteLog(" ROMPath = \"%s\"\n", vjs.ROMPath);\r
- WriteLog(" AlpineROMPath = \"%s\"\n", vjs.alpineROMPath);\r
- WriteLog("DebuggerROMPath = \"%s\"\n", vjs.debuggerROMPath);\r
- WriteLog(" absROMPath = \"%s\"\n", vjs.absROMPath);\r
- WriteLog("ScreenshotsPath = \"%s\"\n", vjs.screenshotPath);\r
- WriteLog(" Pipelined DSP = %s\n", (vjs.usePipelinedDSP ? "ON" : "off"));\r
+ WriteLog(" EEPROMPath = \"%s\"\n", vjs.EEPROMPath);\r
+ WriteLog(" ROMPath = \"%s\"\n", vjs.ROMPath);\r
+ WriteLog(" AlpineROMPath = \"%s\"\n", vjs.alpineROMPath);\r
+ WriteLog(" DebuggerROMPath = \"%s\"\n", vjs.debuggerROMPath);\r
+ WriteLog(" absROMPath = \"%s\"\n", vjs.absROMPath);\r
+ WriteLog(" ScreenshotsPath = \"%s\"\n", vjs.screenshotPath);\r
+ WriteLog("SourceFileSearchPaths = \"%s\"\n", vjs.sourcefilesearchPaths);\r
+ WriteLog("MainWin: Misc.\n");\r
+ WriteLog(" Pipelined DSP = %s\n", (vjs.usePipelinedDSP ? "ON" : "off"));\r
\r
#if 0\r
// Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, *\r
WriteLog("Read setting = Done\n");\r
\r
ReadProfiles(&settings);\r
+ DBGManager_SourceFileSearchPathsSet(vjs.sourcefilesearchPaths);\r
}\r
\r
\r
settings.setValue("displayFullSourceFilename", vjs.displayFullSourceFilename);\r
settings.setValue("NbrMemory1BrowserWindow", (unsigned int)vjs.nbrmemory1browserwindow);\r
settings.setValue("DefaultROM", vjs.debuggerROMPath);\r
+ settings.setValue("SourceFileSearchPaths", vjs.sourcefilesearchPaths);\r
settings.endGroup();\r
\r
// Write settings from the Keybindings\r
#endif\r
\r
WriteProfiles(&settings);\r
+ DBGManager_SourceFileSearchPathsSet(vjs.sourcefilesearchPaths);\r
}\r
\r
\r