// --- ---------- ------------------------------------------------------------\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
+// JPM Aug./2019 Added new functions to handle DWARF information, full filename fix\r
//\r
\r
// To Do\r
// To use pointers instead of arrays usage\r
+// To keep sources text file intact wihtout QT/HTML transformation\r
// \r
\r
\r
\r
\r
// Definitions for debugging\r
-//#define DEBUG_NumCU 0x9 // 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_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
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 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
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
+void DWARFManager_ConformSlachesBackslashes(char *Ptr);\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
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
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
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
- sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
+ // Conform slashes / backslashes for the filename\r
+ DWARFManager_ConformSlachesBackslashes(PtrCU[NbCU].PtrSourceFilename);\r
\r
- // Conform slashes and backslashes\r
- while (*Ptr)\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
+ // 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 (*Ptr == '/')\r
- {\r
- *Ptr = '\\';\r
- }\r
+ sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\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
- Ptr++;\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
{\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
- 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
switch (*Ptr)\r
{\r
+#ifdef CONVERT_QT_HML\r
case 9:\r
strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], " ");\r
i += 6;\r
strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], """);\r
i += strlen(""");\r
break;\r
+#endif\r
#endif\r
default:\r
PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;\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
- // 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
- 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
- PtrCU[NbCU].PtrLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc - 1];\r
- }\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
- // 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
+ // 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
\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
PtrVariables->TypeTag |= TypeTag_structure;\r
if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
{\r
- strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
+ if (PtrCU[NbCU].PtrTypes[j].PtrName)\r
+ {\r
+ strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
+ }\r
}\r
if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
{\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
#endif\r
}\r
}\r
+\r
+ // Check if a used line is found with the address\r
+ for (size_t j = 0; j < PtrCU[i].NbUsedLinesSrc; j++)\r
+ {\r
+ if (PtrCU[i].PtrUsedLinesSrc[j].StartPC == Adr)\r
+ {\r
+ return PtrCU[i].PtrUsedLinesSrc[j].NumLineSrc;\r
+ }\r
+ }\r
}\r
}\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 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
{\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
\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
-// 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
+\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