Added a source code file date check when reading DWARF information
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DWARFManager.cpp
index bd6507b..e0e07b9 100644 (file)
@@ -9,7 +9,10 @@
 // ---  ----------  ------------------------------------------------------------\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
+// JPM   Mar./2020  Fix a random crash when reading the source lines information\r
+// JPM   Aug./2020  Added a source code file date check when reading DWARF information\r
 //\r
 \r
 // To Do\r
 #include <stdio.h>\r
 #include <stdint.h>\r
 #include <string.h>\r
-#include <libdwarf.h>\r
-#include <dwarf.h>\r
+#include <time.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include "libdwarf.h"\r
+#include "dwarf.h"\r
 #include "LEB128.h"\r
+#include "DWARFManager.h"\r
 \r
 \r
 // Definitions for debugging\r
-//#define DEBUG_NumCU                  0x9                                     // CU number to debug or undefine it\r
+//#define DEBUG_NumCU                  0x3                             // 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
@@ -124,8 +134,9 @@ typedef struct SubProgStruct
 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 *PtrProducer;                                                              // "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
@@ -140,8 +151,13 @@ typedef struct CUStruct
        size_t NbVariables;                                                             // Variables number\r
        VariablesStruct *PtrVariables;                                  // Pointer to the global variables list structure\r
        size_t NbFrames;                                                                // Frames number\r
-       size_t 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 number line used\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;                                                // List of the number lines used\r
+       struct _stat _statbuf;                                                  // File information\r
+       DWARFstatus Status;                                                             // File status\r
 }S_CUStruct;\r
 \r
 \r
@@ -152,6 +168,9 @@ Dwarf_Ptr errarg;
 Dwarf_Error error;\r
 Dwarf_Debug dbg;\r
 CUStruct *PtrCU;\r
+char **ListSearchPaths;\r
+size_t NbSearchPaths;\r
+struct _stat FileElfExeInfo;\r
 \r
 \r
 //\r
@@ -161,6 +180,10 @@ void DWARFManager_CloseDMI(void);
 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
@@ -170,16 +193,50 @@ Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg)
 }\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
@@ -187,15 +244,17 @@ bool DWARFManager_Reset(void)
 // Dwarf manager Close\r
 bool DWARFManager_Close(void)\r
 {\r
+       DWARFManager_SourceFileSearchPathsClose();\r
        return(DWARFManager_Reset());\r
 }\r
 \r
 \r
 // Dwarf manager Elf init\r
-int    DWARFManager_ElfInit(Elf *ElfPtr)\r
+int    DWARFManager_ElfInit(Elf *ElfPtr, struct _stat FileElfInfo)\r
 {\r
        if ((LibDwarf = dwarf_elf_init(ElfPtr, DW_DLC_READ, (Dwarf_Handler)DWARFManager_ErrorHandler, errarg, &dbg, &error)) == DW_DLV_OK)\r
        {\r
+               FileElfExeInfo = FileElfInfo;\r
                DWARFManager_InitDMI();\r
        }\r
 \r
@@ -237,7 +296,9 @@ void DWARFManager_CloseDMI(void)
                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
@@ -385,6 +446,14 @@ void DWARFManager_InitDMI(void)
                                                                                        }\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
@@ -394,40 +463,62 @@ void DWARFManager_InitDMI(void)
                                                                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
@@ -443,65 +534,88 @@ void DWARFManager_InitDMI(void)
                                                                strcpy((Ptr1 + 1), (Ptr + 4));\r
                                                        }\r
 \r
-                                                       // Open the source file as a binary file\r
-                                                       if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rb"))\r
+                                                       // Get the source file information\r
+                                                       if (!_stat(PtrCU[NbCU].PtrFullFilename, &PtrCU[NbCU]._statbuf))\r
                                                        {\r
-                                                               if (!fseek(SrcFile, 0, SEEK_END))\r
+                                                               // check the time stamp with the executable\r
+                                                               if (PtrCU[NbCU]._statbuf.st_mtime <= FileElfExeInfo.st_mtime)\r
                                                                {\r
-                                                                       if ((PtrCU[NbCU].SizeLoadSrc = ftell(SrcFile)) > 0)\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_SET))\r
+                                                                               if (!fseek(SrcFile, 0, SEEK_END))\r
                                                                                {\r
-                                                                                       if (PtrCU[NbCU].PtrLoadSrc = Ptr = Ptr1 = (char *)calloc(1, (PtrCU[NbCU].SizeLoadSrc + 2)))\r
+                                                                                       if ((PtrCU[NbCU].SizeLoadSrc = ftell(SrcFile)) > 0)\r
                                                                                        {\r
-                                                                                               // Read whole file\r
-                                                                                               if (fread_s(PtrCU[NbCU].PtrLoadSrc, PtrCU[NbCU].SizeLoadSrc, PtrCU[NbCU].SizeLoadSrc, 1, SrcFile) != 1)\r
+                                                                                               if (!fseek(SrcFile, 0, SEEK_SET))\r
                                                                                                {\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
+                                                                                                       if (PtrCU[NbCU].PtrLoadSrc = Ptr = Ptr1 = (char *)calloc(1, (PtrCU[NbCU].SizeLoadSrc + 2)))\r
                                                                                                        {\r
-                                                                                                               if ((*Ptr = *Ptr1) != '\r')\r
+                                                                                                               // Read whole file\r
+                                                                                                               if (fread_s(PtrCU[NbCU].PtrLoadSrc, PtrCU[NbCU].SizeLoadSrc, PtrCU[NbCU].SizeLoadSrc, 1, SrcFile) != 1)\r
                                                                                                                {\r
-                                                                                                                       Ptr++;\r
+                                                                                                                       free(PtrCU[NbCU].PtrLoadSrc);\r
+                                                                                                                       PtrCU[NbCU].PtrLoadSrc = NULL;\r
+                                                                                                                       PtrCU[NbCU].SizeLoadSrc = 0;\r
                                                                                                                }\r
-                                                                                                       }\r
-                                                                                                       while (*Ptr1++);\r
+                                                                                                               else\r
+                                                                                                               {\r
+                                                                                                                       // Eliminate all carriage return code '\r' (oxd)\r
+                                                                                                                       do\r
+                                                                                                                       {\r
+                                                                                                                               if ((*Ptr = *Ptr1) != '\r')\r
+                                                                                                                               {\r
+                                                                                                                                       Ptr++;\r
+                                                                                                                               }\r
+                                                                                                                       } while (*Ptr1++);\r
 \r
-                                                                                                       // Get back the new text file size\r
-                                                                                                       PtrCU[NbCU].SizeLoadSrc = strlen(Ptr = PtrCU[NbCU].PtrLoadSrc);\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].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc++] = '\n';\r
-                                                                                                               PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc] = 0;\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].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc++] = '\n';\r
+                                                                                                                               PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc] = 0;\r
+                                                                                                                       }\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
+                                                                                                                       // Reallocate text file\r
+                                                                                                                       if (PtrCU[NbCU].PtrLoadSrc = Ptr = (char *)realloc(PtrCU[NbCU].PtrLoadSrc, (PtrCU[NbCU].SizeLoadSrc + 1)))\r
                                                                                                                        {\r
-                                                                                                                               PtrCU[NbCU].NbLinesLoadSrc++;\r
-                                                                                                                               *Ptr = 0;\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
-                                                                                                               } while (*++Ptr);\r
+                                                                                                               }\r
                                                                                                        }\r
                                                                                                }\r
                                                                                        }\r
                                                                                }\r
+\r
+                                                                               fclose(SrcFile);\r
+                                                                       }\r
+                                                                       else\r
+                                                                       {\r
+                                                                               // Source file doesn't exist\r
+                                                                               PtrCU[NbCU].Status = DWARFSTATUS_NOFILE;\r
                                                                        }\r
                                                                }\r
-                                                               fclose(SrcFile);\r
+                                                               else\r
+                                                               {\r
+                                                                       // Source file is outdated\r
+                                                                       PtrCU[NbCU].Status = DWARFSTATUS_OUTDATEDFILE;\r
+                                                               }\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               // Source file doesn't have information\r
+                                                               PtrCU[NbCU].Status = DWARFSTATUS_NOFILEINFO;\r
                                                        }\r
                                                        break;\r
 \r
@@ -511,24 +625,32 @@ void DWARFManager_InitDMI(void)
                                        }\r
 \r
                                        // Get the source lines table located in the CU\r
-                                       if (dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK)\r
+                                       if ((dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK) && (PtrCU[NbCU].Status == DWARFSTATUS_OK))\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
+                                                                       // Get the source line number\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
                                                                }\r
                                                        }\r
                                                }\r
+\r
+                                               // Release the memory used by the source lines table located in the CU\r
+                                               dwarf_srclines_dealloc(dbg, linebuf, cnt);\r
                                        }\r
 \r
                                        // Check if the CU has child\r
@@ -813,19 +935,14 @@ void DWARFManager_InitDMI(void)
                                                                                // Get source line number and associated block of address\r
                                                                                for (Dwarf_Signed i = 0; i < cnt; ++i)\r
                                                                                {\r
-                                                                                       if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
+                                                                                       // Check the presence of the line in the memory frame\r
+                                                                                       if (PtrCU[NbCU].PtrUsedLinesSrc && (PtrCU[NbCU].PtrUsedLinesSrc[i].StartPC >= return_lowpc) && (PtrCU[NbCU].PtrUsedLinesSrc[i].StartPC <= return_highpc))\r
                                                                                        {\r
-                                                                                               if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
-                                                                                               {\r
-                                                                                                       if ((return_lineaddr >= return_lowpc) && (return_lineaddr <= return_highpc))\r
-                                                                                                       {\r
-                                                                                                               PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc = (DMIStruct_LineSrc *)realloc(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc, (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc + 1) * sizeof(DMIStruct_LineSrc));\r
-                                                                                                               memset((void *)(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc), 0, sizeof(DMIStruct_LineSrc));\r
-                                                                                                               PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].StartPC = return_lineaddr;\r
-                                                                                                               PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].NumLineSrc = return_uvalue;\r
-                                                                                                               PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc++;\r
-                                                                                                       }\r
-                                                                                               }\r
+                                                                                               PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc = (DMIStruct_LineSrc *)realloc(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc, (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc + 1) * sizeof(DMIStruct_LineSrc));\r
+                                                                                               memset((void *)(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc), 0, sizeof(DMIStruct_LineSrc));\r
+                                                                                               PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].StartPC = PtrCU[NbCU].PtrUsedLinesSrc[i].StartPC;\r
+                                                                                               PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].NumLineSrc = PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc;\r
+                                                                                               PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc++;\r
                                                                                        }\r
                                                                                }\r
 \r
@@ -951,16 +1068,9 @@ void DWARFManager_InitDMI(void)
                                                }\r
                                                while (dwarf_siblingof(dbg, return_sib, &return_die, &error) == DW_DLV_OK);\r
                                        }\r
-\r
-                                       // Release the memory used by the source lines\r
-                                       for (Dwarf_Signed i = 0; i < cnt; ++i)\r
-                                       {\r
-                                               dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);\r
-                                       }\r
-                                       dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);\r
                                }\r
 \r
-                               // Set the source code lines for QT html/text conformity\r
+                               // Set the source code lines\r
                                if (PtrCU[NbCU].NbLinesLoadSrc)\r
                                {\r
                                        if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(PtrCU[NbCU].NbLinesLoadSrc, sizeof(char *)))\r
@@ -977,6 +1087,7 @@ void DWARFManager_InitDMI(void)
                                                                        {\r
                                                                                switch (*Ptr)\r
                                                                                {\r
+#ifdef CONVERT_QT_HML\r
                                                                                case 9:\r
                                                                                        strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");\r
                                                                                        i += 6;\r
@@ -1002,6 +1113,7 @@ void DWARFManager_InitDMI(void)
                                                                                        strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");\r
                                                                                        i += strlen("&quot;");\r
                                                                                        break;\r
+#endif\r
 #endif\r
                                                                                default:\r
                                                                                        PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;\r
@@ -1053,24 +1165,29 @@ void DWARFManager_InitDMI(void)
                                        }\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
@@ -1096,6 +1213,27 @@ void DWARFManager_InitDMI(void)
 }\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
@@ -1124,7 +1262,10 @@ void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)
                                        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
@@ -1243,13 +1384,11 @@ void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)
 // 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
@@ -1265,16 +1404,18 @@ char *DWARFManager_GetSymbolnameFromAdr(size_t Adr)
 \r
 // Get complete source filename based from address\r
 // Return NULL if no source filename exists\r
-// Return the existence status (true or false) in Error\r
-char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error)\r
+// Return the existence status in Status if pointer not NULL\r
+char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, DWARFstatus *Status)\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
-                       *Error = PtrCU[i].PtrLoadSrc ? true : false;\r
+                       if (Status)\r
+                       {\r
+                               *Status = PtrCU[i].Status;\r
+                       }\r
+\r
                        return PtrCU[i].PtrFullFilename;\r
                }\r
        }\r
@@ -1283,7 +1424,7 @@ char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error)
 }\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
@@ -1307,13 +1448,11 @@ char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine)
 // 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
@@ -1327,18 +1466,16 @@ size_t DWARFManager_GetNbLocalVariables(size_t Adr)
 }\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
@@ -1352,17 +1489,15 @@ char *DWARFManager_GetLocalVariableName(size_t Adr, size_t Index)
 }\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
@@ -1376,16 +1511,15 @@ size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr, size_t Index)
 }\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
@@ -1399,18 +1533,16 @@ int DWARFManager_GetLocalVariableOffset(size_t Adr, size_t Index)
 }\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
@@ -1424,18 +1556,16 @@ size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr, size_t Index)
 }\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
@@ -1449,17 +1579,15 @@ size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr, size_t Index)
 }\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
@@ -1473,17 +1601,15 @@ size_t DWARFManager_GetLocalVariableOp(size_t Adr, size_t Index)
 }\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
@@ -1501,9 +1627,9 @@ char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)
 // 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
@@ -1512,14 +1638,12 @@ size_t DWARFManager_GetNbGlobalVariables(void)
 }\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
@@ -1538,13 +1662,11 @@ char *DWARFManager_GetGlobalVariableTypeName(size_t Index)
 }\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
@@ -1563,13 +1685,11 @@ size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index)
 }\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
@@ -1588,13 +1708,11 @@ size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index)
 }\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
@@ -1613,13 +1731,11 @@ size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index)
 }\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
@@ -1642,13 +1758,11 @@ size_t DWARFManager_GetGlobalVariableAdr(size_t Index)
 // 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
@@ -1662,13 +1776,11 @@ size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)
 }\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
@@ -1693,13 +1805,11 @@ char *DWARFManager_GetGlobalVariableName(size_t Index)
 // 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
@@ -1709,7 +1819,7 @@ char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)
                                        }\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
@@ -1739,13 +1849,11 @@ char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)
 // 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
@@ -1755,7 +1863,7 @@ size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
                                        }\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
@@ -1771,6 +1879,15 @@ size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
 #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
@@ -1782,13 +1899,11 @@ size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
 // 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
@@ -1802,17 +1917,66 @@ char *DWARFManager_GetFunctionName(size_t Adr)
 }\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
@@ -1822,7 +1986,7 @@ char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)
                                        }\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
@@ -1839,13 +2003,11 @@ char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)
 }\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
@@ -1865,15 +2027,22 @@ char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)
 \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