//\r
// WHO WHEN WHAT\r
// --- ---------- ------------------------------------------------------------\r
-// JPM 12/03/2016 Created this file\r
-// JPM 12/03/2016 DWARF format support\r
+// JPM Dec./2016 Created this file, and added the DWARF format support\r
// JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information\r
-// JPM 10/06/2018 Improve the DWARF parsing information, and the source file text reading\r
+// JPM Oct./2018 Improve the DWARF parsing information, the source file text reading, and Support the used lines source DWARF structure\r
//\r
\r
// To Do\r
#include "LEB128.h"\r
\r
\r
-// Debug definitions\r
+// Definitions for debugging\r
//#define DEBUG_NumCU 0x9 // CU number to debug or undefine it\r
//#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it\r
//#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it\r
//#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)\r
//#define DEBUG_Filename "net_jag.c" // Filename to look for or undefine it\r
\r
+// Definitions for the variables's typetag\r
+#define TypeTag_structure 0x01 // structure\r
+#define TypeTag_pointer 0x02 // pointer\r
+#define TypeTag_subrange 0x04 // (subrange_type?)\r
+#define TypeTag_arraytype 0x08 // array type\r
+#define TypeTag_consttype 0x10 // const type\r
+#define TypeTag_typedef 0x20 // typedef\r
+#define TypeTag_enumeration_type 0x40 // enumeration\r
+#define TypeTag_subroutine_type 0x80 // subroutine\r
+\r
+\r
+// Source line CU structure\r
+typedef struct CUStruct_LineSrc\r
+{\r
+ size_t StartPC;\r
+ size_t NumLineSrc;\r
+ char *PtrLineSrc;\r
+}S_CUStruct_LineSrc;\r
\r
// Source line internal structure\r
typedef struct DMIStruct_LineSrc\r
// StructureMembersStruct *PtrStructureMembers; // Type's structure members\r
}S_BaseTypeStruct;\r
\r
-// Definitions for the variables's typetag\r
-#define TypeTag_structure 0x01 // structure\r
-#define TypeTag_pointer 0x02 // pointer\r
-#define TypeTag_subrange 0x04 // (subrange_type?)\r
-#define TypeTag_arraytype 0x08 // array type\r
-#define TypeTag_consttype 0x10 // const type\r
-#define TypeTag_typedef 0x20 // typedef\r
-#define TypeTag_enumeration_type 0x40 // enumeration\r
-#define TypeTag_subroutine_type 0x80 // subroutine\r
-\r
// Variables internal structure\r
typedef struct VariablesStruct\r
{\r
typedef struct CUStruct\r
{\r
size_t Tag;\r
- size_t LowPC, HighPC;\r
+ size_t LowPC, HighPC; // Memory range for the code\r
char *PtrProducer; // Pointer to the "Producer" text information (mostly compiler and compilation options used)\r
char *PtrSourceFilename; // Source file name\r
char *PtrSourceFileDirectory; // Directory of the source file\r
char *PtrFullFilename; // Pointer to full namefile (directory & filename)\r
- size_t SizeLoadSrc; // Source code size\r
- char *PtrLoadSrc; // Pointer to loaded source code\r
- size_t NbLinesLoadSrc; // Lines source number\r
+ size_t SizeLoadSrc; // Source code text size\r
+ char *PtrLoadSrc; // Pointer to the source code text\r
+ size_t NbLinesLoadSrc; // Total number of lines in the source code text\r
char **PtrLinesLoadSrc; // Pointer lists to each source line put in QT html/text conformity\r
size_t NbSubProgs; // Number of sub programs / routines\r
- SubProgStruct *PtrSubProgs; // Pointer to the sub programs / routines information structure\r
+ SubProgStruct *PtrSubProgs; // Pointer to the sub programs / routines structure\r
size_t NbTypes; // Number of types\r
BaseTypeStruct *PtrTypes; // Pointer to types\r
size_t NbVariables; // Variables number\r
- VariablesStruct *PtrVariables; // Pointer to the global variables list information structure\r
+ VariablesStruct *PtrVariables; // Pointer to the global variables list structure\r
size_t NbFrames; // Frames number\r
+ size_t NbLinesSrc; // Number of used source lines\r
+ CUStruct_LineSrc *PtrLinesSrc; // Pointer to the used source lines list structure\r
}S_CUStruct;\r
\r
\r
free(PtrCU[NbCU].PtrProducer);\r
free(PtrCU[NbCU].PtrSourceFilename);\r
free(PtrCU[NbCU].PtrSourceFileDirectory);\r
+ free(PtrCU[NbCU].PtrLinesSrc);\r
\r
while (PtrCU[NbCU].NbLinesLoadSrc--)\r
{\r
// Get the source lines table located in the CU\r
if (dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK)\r
{\r
+ if (cnt)\r
+ {\r
+ PtrCU[NbCU].NbLinesSrc = cnt;\r
+ PtrCU[NbCU].PtrLinesSrc = (CUStruct_LineSrc *)calloc(cnt, sizeof(CUStruct_LineSrc));\r
+ for (Dwarf_Signed i = 0; i < cnt; i++)\r
+ {\r
+ if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
+ {\r
+ if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
+ {\r
+ PtrCU[NbCU].PtrLinesSrc[i].StartPC = return_lineaddr;\r
+ PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc = return_uvalue;\r
+ }\r
+ }\r
+ }\r
+ }\r
}\r
\r
// Check if the CU has child\r
}\r
}\r
\r
- // Init lines source information based on each source code line numbers\r
+ // Init lines source information for each source code line numbers and for each subprogs\r
for (size_t j = 0; j < PtrCU[NbCU].NbSubProgs; j++)\r
{\r
// Check if the subprog / function's line exists in the source code\r
}\r
}\r
\r
+ // Set information based on used line numbers\r
+ if (PtrCU[NbCU].PtrLinesSrc)\r
+ {\r
+ // Set the line source pointer for each used line numbers\r
+ if (PtrCU[NbCU].PtrLinesLoadSrc)\r
+ {\r
+ for (size_t i = 0; i < PtrCU[NbCU].NbLinesSrc; i++)\r
+ {\r
+ PtrCU[NbCU].PtrLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc - 1];\r
+ }\r
+ }\r
+\r
+ // Setup memory range for the code if CU doesn't have already this information\r
+ // It is taken from the used lines structure\r
+ if (!PtrCU[NbCU].LowPC && !PtrCU[NbCU].HighPC)\r
+ {\r
+ PtrCU[NbCU].LowPC = PtrCU[NbCU].PtrLinesSrc[0].StartPC;\r
+ PtrCU[NbCU].HighPC = PtrCU[NbCU].PtrLinesSrc[PtrCU[NbCU].NbLinesSrc - 1].StartPC;\r
+ }\r
+ }\r
+\r
// Init global variables information based on types information\r
for (size_t i = 0; i < PtrCU[NbCU].NbVariables; i++)\r
{\r
\r
\r
// Get local variable Op based on his address and index (starting by 1)\r
-// Return 0 if not found\r
-// May return 0 if there isn't Op linked to the variable's index\r
+// Return 0 if not found, may return 0 if there isn't Op linked to the variable's index\r
size_t DWARFManager_GetLocalVariableOp(size_t Adr, size_t Index)\r
{\r
size_t i, j;\r
}\r
\r
\r
-// Get local variable type name based on his index (starting by 1)\r
-// Return NULL if not found\r
-// May return NULL if there is not type linked to the variable's index\r
+// Get local variable type name based on his index (starting by 1) and an address\r
+// Return NULL if not found, may also return NULL if there is no type linked to the variable's index\r
char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)\r
{\r
size_t i, j;\r
\r
\r
// Get Compilation Unit / global variables numbers\r
-// Return variables number\r
+// Return number of variables\r
size_t DWARFManager_GetNbGlobalVariables(void)\r
{\r
size_t NbVariables = 0, i;\r
\r
\r
// Get global variable memory address based on his name\r
-// Return 0 if not found\r
-// Note: Return the first occurence found\r
+// Return 0 if not found, or will return the first occurence found\r
size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)\r
{\r
size_t i, j;\r
\r
\r
// Get global variable name based on his index (starting by 1)\r
-// Return name's pointer text found\r
-// Return NULL if not found\r
+// Return name's pointer text found, or will return NULL if no variable can be found\r
char *DWARFManager_GetGlobalVariableName(size_t Index)\r
{\r
size_t i;\r
\r
\r
// Get text line from source based on address and his tag\r
+// A tag can be either 0 or a DW_TAG_subprogram\r
+// DW_TAG_subprogram will look for the line pointing to the function\r
// Return NULL if no text line has been found\r
char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)\r
{\r
}\r
\r
\r
-// Get line number based on the address and the tag\r
+// Get line number based on the address and a tag\r
+// A tag can be either 0 or a DW_TAG_subprogram\r
+// DW_TAG_subprogram will look for the line pointing to the function name as described in the source code\r
// Return 0 if no line number has been found\r
size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)\r
{\r
}\r
\r
\r
-// Get function name based on address and his range\r
-// Return NULL if no function name has been found\r
+// Get function name based on an address\r
+// Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address\r
char *DWARFManager_GetFunctionName(size_t Adr)\r
{\r
size_t i, j;\r
}\r
\r
\r
-// Get source code filename based on index\r
+// Get source code filename based on index (starting from 0)\r
char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
{\r
return (PtrCU[Index].PtrFullFilename);\r