DWARF information support updates
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DWARFManager.cpp
index d8bdb9c..a90bf39 100644 (file)
 // 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
+// JPM   Aug./2020  Added a source code file date check\r
 //  RG   Jan./2021  Linux build fixes\r
+// JPM   Apr./2021  Support the structure and union members\r
 //\r
 \r
 // To Do\r
-// To use pointers instead of arrays usage\r
+// To use pointers instead of arrays usage (originally done to check if values are set at the right places)\r
 // \r
 \r
 \r
 #include "DWARFManager.h"\r
 \r
 // Definitions for debugging\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_NumCU                  0x2                             // CU number to debug or undefine it\r
+//#define DEBUG_VariableName   "cvar_vars"                             // Variable name to look for or undefine it\r
+//#define DEBUG_TypeName               "edict_t"                       // Type name to look for or undefine it\r
+//#define DEBUG_TypeDef                        DW_TAG_typedef          // Type def to look for or undefine it (not used / not supported)\r
 //#define DEBUG_Filename               "crt0"                  // Filename to look for or undefine it\r
 \r
 // Definitions for handling data\r
@@ -53,6 +54,7 @@
 #define        TypeTag_typedef                         0x20                    // typedef\r
 #define TypeTag_enumeration_type       0x40                    // enumeration\r
 #define TypeTag_subroutine_type                0x80                    // subroutine\r
+#define TypeTag_union                          0x100                   // union\r
 \r
 \r
 // Source line CU structure\r
@@ -75,14 +77,17 @@ typedef struct DMIStruct_LineSrc
 // Enumeration structure\r
 typedef struct EnumerationStruct\r
 {\r
-       char *PtrName;                                                  // Enumeration's name\r
-       size_t value;                                                   // Enumeration's value\r
+       char *PtrName;                                                                  // Enumeration's name\r
+       size_t value;                                                                   // Enumeration's value\r
 }S_EnumerationStruct;\r
 \r
 // Structure members structure\r
-//typedef struct StructureMembersStruct\r
-//{\r
-//}S_StructureMembersStruct;\r
+typedef struct StructureMembersStruct\r
+{\r
+       char *PtrName;                                                                  // Structure member's name\r
+       size_t TypeOffset;                                                              // Structure member's offset on another type\r
+       size_t DataMemberLocation;                                              // Structure member's data member\r
+}S_StructureMembersStruct;\r
 \r
 // Base type internal structure\r
 typedef struct BaseTypeStruct\r
@@ -93,26 +98,29 @@ typedef struct BaseTypeStruct
        size_t ByteSize;                                                                // Type's Byte Size\r
        size_t Encoding;                                                                // Type's encoding\r
        char *PtrName;                                                                  // Type's name\r
-       size_t NbEnumeration;                                                   // Type's enumeration numbers\r
-       EnumerationStruct *PtrEnumeration;                              // Type's enumeration\r
-//     StructureMembersStruct *PtrStructureMembers;    // Type's structure members\r
+       size_t NbEnumerations;                                                  // Type's enumeration numbers\r
+       EnumerationStruct *PtrEnumerations;                             // Type's enumeration\r
+       size_t NbStructureMembers;                                              // Type's numbers of structure members\r
+       StructureMembersStruct *PtrStructureMembers;    // Type's structure members\r
 }S_BaseTypeStruct;\r
 \r
 // Variables internal structure\r
 typedef struct VariablesStruct\r
 {\r
-       size_t Op;                                                              // Variable's DW_OP\r
+       size_t Op;                                                                              // Variable's DW_OP\r
        union\r
        {\r
-               size_t Addr;                                            // Variable memory address\r
-               int Offset;                                                     // Variable stack offset (signed)\r
+               size_t Addr;                                                            // Variable memory address\r
+               int Offset;                                                                     // Variable stack offset (signed)\r
        };\r
-       char *PtrName;                                                  // Variable's name\r
-       size_t TypeOffset;                                              // Offset pointing on the Variable's Type\r
-       size_t TypeByteSize;                                    // Variable's Type byte size\r
-       size_t TypeTag;                                                 // Variable's Type Tag\r
-       size_t TypeEncoding;                                    // Variable's Type encoding\r
-       char *PtrTypeName;                                              // Variable's Type name\r
+       char *PtrName;                                                                  // Variable's name\r
+       size_t TypeOffset;                                                              // Offset pointing on the Variable's Type\r
+       size_t TypeByteSize;                                                    // Variable's Type byte size\r
+       size_t TypeTag;                                                                 // Variable's Type Tag\r
+       size_t TypeEncoding;                                                    // Variable's Type encoding\r
+       char *PtrTypeName;                                                              // Variable's Type name\r
+       size_t NbTabVariables;                                                  // Number of Variable's members\r
+       VariablesStruct **TabVariables;                                 // Variable's Members (used for structures at the moment)\r
 }S_VariablesStruct;\r
 \r
 // Sub program internal structure\r
@@ -174,7 +182,7 @@ size_t NbSearchPaths;
 struct stat FileElfExeInfo;\r
 \r
 \r
-//\r
+// Function declarations\r
 Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg);\r
 void DWARFManager_InitDMI(void);\r
 void DWARFManager_CloseDMI(void);\r
@@ -185,10 +193,14 @@ void DWARFManager_SourceFileSearchPathsInit(void);
 void DWARFManager_SourceFileSearchPathsReset(void);\r
 void DWARFManager_SourceFileSearchPathsClose(void);\r
 void DWARFManager_ConformSlachesBackslashes(char *Ptr);\r
+#if 0\r
+size_t DWARFManager_GetNbGlobalVariables(void);\r
+size_t DWARFManager_GetNbLocalVariables(size_t Adr);\r
+#endif\r
 \r
 \r
 //\r
-Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg)\r
+Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr /* perrarg */)\r
 {\r
        return  0;\r
 }\r
@@ -290,8 +302,10 @@ bool DWARFManager_ElfClose(void)
 // Dwarf manager Compilation Units close\r
 void DWARFManager_CloseDMI(void)\r
 {\r
+       // loop on all CU\r
        while (NbCU--)\r
        {\r
+               // free pointers\r
                free(PtrCU[NbCU].PtrFullFilename);\r
                free(PtrCU[NbCU].PtrLoadSrc);\r
                free(PtrCU[NbCU].PtrProducer);\r
@@ -301,12 +315,14 @@ void DWARFManager_CloseDMI(void)
                free(PtrCU[NbCU].PtrUsedLinesLoadSrc);\r
                free(PtrCU[NbCU].PtrUsedNumLines);\r
 \r
+               // free lines from the source code\r
                while (PtrCU[NbCU].NbLinesLoadSrc--)\r
                {\r
                        free(PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].NbLinesLoadSrc]);\r
                }\r
                free(PtrCU[NbCU].PtrLinesLoadSrc);\r
 \r
+               // free the functions information\r
                while (PtrCU[NbCU].NbSubProgs--)\r
                {\r
                        while (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables--)\r
@@ -321,20 +337,36 @@ void DWARFManager_CloseDMI(void)
                }\r
                free(PtrCU[NbCU].PtrSubProgs);\r
 \r
+               // free the types\r
                while (PtrCU[NbCU].NbTypes--)\r
                {\r
                        free(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName);\r
+\r
+                       // free the structure's members\r
+                       while (PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers--)\r
+                       {\r
+                               free(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers[PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers].PtrName);\r
+                       }\r
+                       free(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers);\r
                }\r
                free(PtrCU[NbCU].PtrTypes);\r
 \r
+               // free variables\r
                while (PtrCU[NbCU].NbVariables--)\r
                {\r
                        free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);\r
                        free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrTypeName);\r
+\r
+                       // free the variable's members\r
+                       while (PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].NbTabVariables--)\r
+                       {\r
+                               free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].TabVariables[PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].NbTabVariables]);\r
+                       }\r
                }\r
                free(PtrCU[NbCU].PtrVariables);\r
        }\r
 \r
+       // free the CU\r
        free(PtrCU);\r
 }\r
 \r
@@ -347,12 +379,14 @@ void DWARFManager_InitDMI(void)
        Dwarf_Attribute *atlist;\r
        Dwarf_Attribute return_attr1;\r
        Dwarf_Half return_tagval, return_attr;\r
+       Dwarf_Half version, offset_size;\r
        Dwarf_Addr return_lowpc, return_highpc, return_lineaddr;\r
        Dwarf_Block *return_block;\r
-       Dwarf_Signed atcnt, cnt;\r
+       Dwarf_Signed atcnt, cnt, return_value;\r
        Dwarf_Die return_sib, return_die, return_sub, return_subdie;\r
        Dwarf_Off return_offset;\r
        Dwarf_Line *linebuf;\r
+       Dwarf_Half form;\r
        FILE *SrcFile;\r
        char *return_string;\r
        char *Ptr, *Ptr1;\r
@@ -362,7 +396,7 @@ void DWARFManager_InitDMI(void)
        PtrCU = NULL;\r
 \r
        // loop on the available Compilation Unit\r
-       while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &next_cu_header, &error) == DW_DLV_OK)\r
+       while (dwarf_next_cu_header_b(dbg, NULL, &version, NULL, NULL, &offset_size, NULL, &next_cu_header, &error) == DW_DLV_OK)\r
        {\r
                // Allocation of an additional Compilation Unit structure in the table\r
                if (Ptr = (char *)realloc(PtrCU, ((NbCU + 1) * sizeof(CUStruct))))\r
@@ -764,6 +798,7 @@ void DWARFManager_InitDMI(void)
 \r
                                                                case DW_TAG_base_type:\r
                                                                case DW_TAG_typedef:\r
+                                                               case DW_TAG_union_type:\r
                                                                case DW_TAG_structure_type:\r
                                                                case DW_TAG_pointer_type:\r
                                                                case DW_TAG_const_type:\r
@@ -851,9 +886,123 @@ void DWARFManager_InitDMI(void)
                                                                                        dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
                                                                                }\r
 \r
-                                                                               PtrCU[NbCU].NbTypes++;\r
-\r
                                                                                dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
+\r
+                                                                               switch (return_tagval)\r
+                                                                               {\r
+                                                                               case DW_TAG_structure_type:\r
+                                                                               case DW_TAG_union_type:\r
+                                                                                       if (dwarf_child(return_die, &return_subdie, &error) == DW_DLV_OK)\r
+                                                                                       {\r
+                                                                                               do\r
+                                                                                               {\r
+                                                                                                       return_sub = return_subdie;\r
+                                                                                                       if ((dwarf_tag(return_subdie, &return_tagval, &error) == DW_DLV_OK))\r
+                                                                                                       {\r
+                                                                                                               switch (return_tagval)\r
+                                                                                                               {\r
+                                                                                                               case DW_TAG_member:\r
+                                                                                                                       if (dwarf_attrlist(return_subdie, &atlist, &atcnt, &error) == DW_DLV_OK)\r
+                                                                                                                       {\r
+                                                                                                                               // Allocate memory for this member\r
+                                                                                                                               PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers = (StructureMembersStruct *)realloc(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers, ((PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers + 1) * sizeof(StructureMembersStruct)));\r
+                                                                                                                               memset(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers + PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers, 0, sizeof(StructureMembersStruct));\r
+\r
+                                                                                                                               for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
+                                                                                                                               {\r
+                                                                                                                                       if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
+                                                                                                                                       {\r
+                                                                                                                                               if (dwarf_attr(return_subdie, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
+                                                                                                                                               {\r
+                                                                                                                                                       switch (return_attr)\r
+                                                                                                                                                       {\r
+                                                                                                                                                       case DW_AT_data_member_location:\r
+                                                                                                                                                               if (dwarf_whatform(return_attr1, &form, &error) == DW_DLV_OK)\r
+                                                                                                                                                               {\r
+                                                                                                                                                                       if ((form == DW_FORM_data1) || (form == DW_FORM_data2) || (form == DW_FORM_data2) || (form == DW_FORM_data4) || (form == DW_FORM_data8) || (form == DW_FORM_udata))\r
+                                                                                                                                                                       {\r
+                                                                                                                                                                               if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
+                                                                                                                                                                               {\r
+                                                                                                                                                                                       PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers[PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers].DataMemberLocation = return_uvalue;\r
+                                                                                                                                                                               }\r
+                                                                                                                                                                       }\r
+                                                                                                                                                                       else\r
+                                                                                                                                                                       {\r
+                                                                                                                                                                               if (form == DW_FORM_sdata)\r
+                                                                                                                                                                               {\r
+                                                                                                                                                                                       if (dwarf_formsdata(return_attr1, &return_value, &error) == DW_DLV_OK)\r
+                                                                                                                                                                                       {\r
+                                                                                                                                                                                               PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers[PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers].DataMemberLocation = return_value;\r
+                                                                                                                                                                                       }\r
+                                                                                                                                                                               }\r
+                                                                                                                                                                               else\r
+                                                                                                                                                                               {\r
+                                                                                                                                                                                       if (dwarf_formblock(return_attr1, &return_block, &error) == DW_DLV_OK)\r
+                                                                                                                                                                                       {\r
+                                                                                                                                                                                               switch (return_block->bl_len)\r
+                                                                                                                                                                                               {\r
+                                                                                                                                                                                               case 2:\r
+                                                                                                                                                                                               case 3:\r
+                                                                                                                                                                                               case 4:\r
+                                                                                                                                                                                                       PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers[PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers].DataMemberLocation = ReadULEB128((char *)return_block->bl_data + 1);\r
+                                                                                                                                                                                                       break;\r
+\r
+                                                                                                                                                                                               default:\r
+                                                                                                                                                                                                       break;\r
+                                                                                                                                                                                               }\r
+\r
+                                                                                                                                                                                               dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);\r
+                                                                                                                                                                                       }\r
+                                                                                                                                                                               }\r
+                                                                                                                                                                       }\r
+                                                                                                                                                               }\r
+                                                                                                                                                               break;\r
+\r
+                                                                                                                                                       case DW_AT_type:\r
+                                                                                                                                                               //dwarf_whatform(return_attr1, &form, &error);\r
+                                                                                                                                                               if (dwarf_global_formref(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
+                                                                                                                                                               {\r
+                                                                                                                                                                       PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers[PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers].TypeOffset = return_uvalue;\r
+                                                                                                                                                               }\r
+                                                                                                                                                               break;\r
+\r
+                                                                                                                                                       case DW_AT_name:\r
+                                                                                                                                                               if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
+                                                                                                                                                               {\r
+                                                                                                                                                                       PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers[PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
+                                                                                                                                                                       strcpy(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrStructureMembers[PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers].PtrName, return_string);\r
+\r
+                                                                                                                                                                       dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
+                                                                                                                                                               }\r
+                                                                                                                                                               break;\r
+\r
+                                                                                                                                                               // Member's file number\r
+                                                                                                                                                       case DW_AT_decl_file:\r
+                                                                                                                                                               break;\r
+\r
+                                                                                                                                                               // Member's line number\r
+                                                                                                                                                       case DW_AT_decl_line:\r
+                                                                                                                                                               break;\r
+\r
+                                                                                                                                                       default:\r
+                                                                                                                                                               break;\r
+                                                                                                                                                       }\r
+                                                                                                                                               }\r
+                                                                                                                                       }\r
+                                                                                                                               }\r
+                                                                                                                               dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
+\r
+                                                                                                                               PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].NbStructureMembers++;\r
+                                                                                                                       }\r
+                                                                                                                       break;\r
+                                                                                                               }\r
+                                                                                                       }\r
+                                                                                               } while (dwarf_siblingof(dbg, return_sub, &return_subdie, &error) == DW_DLV_OK);\r
+                                                                                       }\r
+                                                                                       break;\r
+                                                                               }\r
+\r
+                                                                               PtrCU[NbCU].NbTypes++;\r
                                                                        }\r
                                                                        break;\r
 \r
@@ -1251,29 +1400,29 @@ void DWARFManager_ConformSlachesBackslashes(char *Ptr)
 // Variables information initialisation\r
 void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)\r
 {\r
-       size_t j, TypeOffset;\r
-\r
 #ifdef DEBUG_VariableName\r
        if (PtrVariables->PtrName && !strcmp(PtrVariables->PtrName, DEBUG_VariableName))\r
 #endif\r
        {\r
                PtrVariables->PtrTypeName = (char *)calloc(1000, 1);\r
-               TypeOffset = PtrVariables->TypeOffset;\r
+               size_t TypeOffset = PtrVariables->TypeOffset;\r
 \r
-               for (j = 0; j < PtrCU[NbCU].NbTypes; j++)\r
+               for (size_t j = 0; j < PtrCU[NbCU].NbTypes; j++)\r
                {\r
                        if (TypeOffset == PtrCU[NbCU].PtrTypes[j].Offset)\r
                        {\r
                                switch (PtrCU[NbCU].PtrTypes[j].Tag)\r
                                {\r
+                                       // subroutine / function pointer\r
                                case DW_TAG_subroutine_type:\r
                                        PtrVariables->TypeTag |= TypeTag_subroutine_type;\r
                                        strcat(PtrVariables->PtrTypeName, " (* ) ()");\r
                                        break;\r
 \r
-                                       // Structure type tag\r
+                                       // structure & union type tag\r
                                case DW_TAG_structure_type:\r
-                                       PtrVariables->TypeTag |= TypeTag_structure;\r
+                               case DW_TAG_union_type:\r
+                                       PtrVariables->TypeTag |= (PtrCU[NbCU].PtrTypes[j].Tag == DW_TAG_structure_type) ? TypeTag_structure : TypeTag_union;\r
                                        if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
                                        {\r
                                                if (PtrCU[NbCU].PtrTypes[j].PtrName)\r
@@ -1289,19 +1438,36 @@ void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)
                                        {\r
                                                if ((PtrVariables->TypeTag & TypeTag_pointer))\r
                                                {\r
-                                                       strcat(PtrVariables->PtrTypeName, " *");\r
+                                                       strcat(PtrVariables->PtrTypeName, "* ");\r
+                                               }\r
+\r
+                                               if (PtrVariables->Op)\r
+                                               {\r
+                                                       // fill the structure members\r
+                                                       PtrVariables->TabVariables = (VariablesStruct**)calloc(PtrCU[NbCU].PtrTypes[j].NbStructureMembers, sizeof(VariablesStruct*));\r
+                                                       for (size_t i = 0; i < PtrCU[NbCU].PtrTypes[j].NbStructureMembers; i++)\r
+                                                       {\r
+                                                               //if (PtrVariables->PtrName != PtrCU[NbCU].PtrTypes[j].PtrStructureMembers[i].PtrName)\r
+                                                               {\r
+                                                                       PtrVariables->TabVariables[PtrVariables->NbTabVariables] = (VariablesStruct*)calloc(1, sizeof(VariablesStruct));\r
+                                                                       PtrVariables->TabVariables[PtrVariables->NbTabVariables]->PtrName = PtrCU[NbCU].PtrTypes[j].PtrStructureMembers[i].PtrName;\r
+                                                                       PtrVariables->TabVariables[PtrVariables->NbTabVariables]->TypeOffset = PtrCU[NbCU].PtrTypes[j].PtrStructureMembers[i].TypeOffset;\r
+                                                                       PtrVariables->TabVariables[PtrVariables->NbTabVariables]->Offset = (int)PtrCU[NbCU].PtrTypes[j].PtrStructureMembers[i].DataMemberLocation;\r
+                                                                       DWARFManager_InitInfosVariable(PtrVariables->TabVariables[PtrVariables->NbTabVariables++]);\r
+                                                               }\r
+                                                       }\r
                                                }\r
                                        }\r
                                        break;\r
 \r
-                                       // Pointer type tag\r
+                                       // pointer type tag\r
                                case DW_TAG_pointer_type:\r
                                        PtrVariables->TypeTag |= TypeTag_pointer;\r
                                        PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
                                        PtrVariables->TypeEncoding = 0x10;\r
                                        if (!(TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
                                        {\r
-                                               strcat(PtrVariables->PtrTypeName, "void *");\r
+                                               strcat(PtrVariables->PtrTypeName, "void");\r
                                        }\r
                                        else\r
                                        {\r
@@ -1372,7 +1538,7 @@ void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)
                                        }\r
                                        if ((PtrVariables->TypeTag & TypeTag_pointer))\r
                                        {\r
-                                               strcat(PtrVariables->PtrTypeName, " *");\r
+                                               strcat(PtrVariables->PtrTypeName, "");\r
                                        }\r
                                        else\r
                                        {\r
@@ -1459,6 +1625,114 @@ char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine)
 }\r
 \r
 \r
+// Get number of variables\r
+// A NULL address will return the numbre of global variables, otherwise it will return the number of local variables\r
+size_t DWARFManager_GetNbVariables(size_t Adr)\r
+{\r
+       // check the address\r
+       if (Adr)\r
+       {\r
+               for (size_t i = 0; i < NbCU; i++)\r
+               {\r
+                       if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
+                       {\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 PtrCU[i].PtrSubProgs[j].NbVariables;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               size_t NbVariables = 0;\r
+\r
+               for (size_t i = 0; i < NbCU; i++)\r
+               {\r
+                       NbVariables += PtrCU[i].NbVariables;\r
+               }\r
+\r
+               return NbVariables;\r
+       }\r
+\r
+       return 0;\r
+#if 0\r
+       return Adr ? DWARFManager_GetNbLocalVariables(Adr) : DWARFManager_GetNbGlobalVariables();\r
+#endif\r
+}\r
+\r
+\r
+// Get variable's information\r
+// A NULL address will return the pointer to the global variable structure, otherwise it will return the local's one\r
+void* DWARFManager_GetInfosVariable(size_t Adr, size_t Index)\r
+{\r
+       // check the address\r
+       if (Adr)\r
+       {\r
+               // get the pointer's information from a local variable\r
+               for (size_t i = 0; i < NbCU; i++)\r
+               {\r
+                       if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
+                       {\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 &PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1];\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               // get the pointer's information from a global variable\r
+               for (size_t i = 0; i < NbCU; i++)\r
+               {\r
+                       if (PtrCU[i].NbVariables)\r
+                       {\r
+                               if (Index <= PtrCU[i].NbVariables)\r
+                               {\r
+                                       return &PtrCU[i].PtrVariables[Index - 1];\r
+                               }\r
+                               else\r
+                               {\r
+                                       Index -= PtrCU[i].NbVariables;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       return NULL;\r
+}\r
+\r
+\r
+// Get global variable memory address based on his name\r
+// Return 0 if not found, or will return the first occurence found\r
+size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)\r
+{\r
+       for (size_t i = 0; i < NbCU; i++)\r
+       {\r
+               if (PtrCU[i].NbVariables)\r
+               {\r
+                       for (size_t j = 0; j < PtrCU[i].NbVariables; j++)\r
+                       {\r
+                               if (!strcmp(PtrCU[i].PtrVariables[j].PtrName, VariableName))\r
+                               {\r
+                                       return PtrCU[i].PtrVariables[j].Addr;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+\r
+#if 0\r
 // Get number of variables referenced by the function range address\r
 size_t DWARFManager_GetNbLocalVariables(size_t Adr)\r
 {\r
@@ -1480,6 +1754,21 @@ size_t DWARFManager_GetNbLocalVariables(size_t Adr)
 }\r
 \r
 \r
+// Get Compilation Unit / global variables numbers\r
+// Return number of variables\r
+size_t DWARFManager_GetNbGlobalVariables(void)\r
+{\r
+       size_t NbVariables = 0;\r
+\r
+       for (size_t i = 0; i < NbCU; i++)\r
+       {\r
+               NbVariables += PtrCU[i].NbVariables;\r
+       }\r
+\r
+       return NbVariables;\r
+}\r
+\r
+\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
@@ -1637,21 +1926,6 @@ char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)
 }\r
 \r
 \r
-// Get Compilation Unit / global variables numbers\r
-// Return number of variables\r
-size_t DWARFManager_GetNbGlobalVariables(void)\r
-{\r
-       size_t NbVariables = 0;\r
-\r
-       for (size_t i = 0; i < NbCU; i++)\r
-       {\r
-               NbVariables += PtrCU[i].NbVariables;\r
-       }\r
-\r
-       return NbVariables;\r
-}\r
-\r
-\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
@@ -1768,28 +2042,6 @@ size_t DWARFManager_GetGlobalVariableAdr(size_t Index)
 }\r
 \r
 \r
-// Get global variable memory address based on his name\r
-// Return 0 if not found, or will return the first occurence found\r
-size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)\r
-{\r
-       for (size_t i = 0; i < NbCU; i++)\r
-       {\r
-               if (PtrCU[i].NbVariables)\r
-               {\r
-                       for (size_t j = 0; j < PtrCU[i].NbVariables; j++)\r
-                       {\r
-                               if (!strcmp(PtrCU[i].PtrVariables[j].PtrName,VariableName))\r
-                               {\r
-                                       return PtrCU[i].PtrVariables[j].Addr;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
-\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
@@ -1811,6 +2063,7 @@ char *DWARFManager_GetGlobalVariableName(size_t Index)
 \r
        return NULL;\r
 }\r
+#endif\r
 \r
 \r
 // Get text line from source based on address and his tag\r
@@ -1879,9 +2132,16 @@ size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
                                        {\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
+                                                       if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC <= Adr)\r
+                                                       {\r
+                                                               if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
+                                                               {\r
+                                                                       return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc;\r
+                                                               }\r
+                                                       }\r
+                                                       else\r
                                                        {\r
-                                                               return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc;\r
+                                                               return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k - 1].NumLineSrc;\r
                                                        }\r
                                                }\r
                                        }\r