Fix a crash when emulator, in non-debugger mode, opens the breakpoint UIs at launch
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DWARFManager.cpp
CommitLineData
ebcb0f3d
JPM
1//\r
2// DWARFManager.cpp: DWARF format manager\r
3//\r
4// by Jean-Paul Mari\r
5//\r
6// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
7//\r
8// WHO WHEN WHAT\r
9// --- ---------- ------------------------------------------------------------\r
5fa7aa73 10// JPM Dec./2016 Created this file, and added the DWARF format support\r
6564336c 11// JPM Sept./2018 Added LEB128 decoding features, and improve the DWARF parsing information\r
f0dd2f7b 12// 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
f8dde18d
JPM
13//\r
14\r
15// To Do\r
16// To use pointers instead of arrays usage\r
0536c3ba 17// To keep sources text file intact wihtout QT/HTML transformation\r
f8dde18d 18// \r
ebcb0f3d
JPM
19\r
20\r
41d6f5f7
JPM
21#include <stdlib.h>\r
22#include <stdio.h>\r
23#include <stdint.h>\r
24#include <string.h>\r
25#include <libdwarf.h>\r
26#include <dwarf.h>\r
f8dde18d 27#include "LEB128.h"\r
41d6f5f7
JPM
28\r
29\r
5fa7aa73 30// Definitions for debugging\r
f8dde18d 31//#define DEBUG_NumCU 0x9 // CU number to debug or undefine it\r
ce32526a 32//#define DEBUG_VariableName "sound_death" // Variable name to look for or undefine it\r
f8dde18d
JPM
33//#define DEBUG_TypeName "Cbuf_Execute" // Type name to look for or undefine it\r
34//#define DEBUG_TypeDef DW_TAG_typedef // Type def to look for or undefine it (not supported)\r
f795e8ac 35//#define DEBUG_Filename "net_jag.c" // Filename to look for or undefine it\r
ebcb0f3d 36\r
5fa7aa73
JPM
37// Definitions for the variables's typetag\r
38#define TypeTag_structure 0x01 // structure\r
39#define TypeTag_pointer 0x02 // pointer\r
40#define TypeTag_subrange 0x04 // (subrange_type?)\r
41#define TypeTag_arraytype 0x08 // array type\r
42#define TypeTag_consttype 0x10 // const type\r
43#define TypeTag_typedef 0x20 // typedef\r
44#define TypeTag_enumeration_type 0x40 // enumeration\r
45#define TypeTag_subroutine_type 0x80 // subroutine\r
46\r
47\r
48// Source line CU structure\r
49typedef struct CUStruct_LineSrc\r
50{\r
51 size_t StartPC;\r
52 size_t NumLineSrc;\r
53 char *PtrLineSrc;\r
54}S_CUStruct_LineSrc;\r
ebcb0f3d
JPM
55\r
56// Source line internal structure\r
f8dde18d 57typedef struct DMIStruct_LineSrc\r
ebcb0f3d
JPM
58{\r
59 size_t Tag;\r
60 size_t StartPC;\r
61 size_t NumLineSrc;\r
62 char *PtrLineSrc;\r
63}S_DMIStruct_LineSrc;\r
64\r
f8dde18d
JPM
65// Enumeration structure\r
66typedef struct EnumerationStruct\r
67{\r
68 char *PtrName; // Enumeration's name\r
69 size_t value; // Enumeration's value\r
70}S_EnumerationStruct;\r
71\r
72// Structure members structure\r
73//typedef struct StructureMembersStruct\r
74//{\r
75//}S_StructureMembersStruct;\r
76\r
ebcb0f3d 77// Base type internal structure\r
f8dde18d 78typedef struct BaseTypeStruct\r
ebcb0f3d 79{\r
f8dde18d
JPM
80 size_t Tag; // Type's Tag\r
81 size_t Offset; // Type's offset\r
82 size_t TypeOffset; // Type's offset on another type\r
83 size_t ByteSize; // Type's Byte Size\r
84 size_t Encoding; // Type's encoding\r
85 char *PtrName; // Type's name\r
86 size_t NbEnumeration; // Type's enumeration numbers\r
87 EnumerationStruct *PtrEnumeration; // Type's enumeration\r
88// StructureMembersStruct *PtrStructureMembers; // Type's structure members\r
ebcb0f3d
JPM
89}S_BaseTypeStruct;\r
90\r
91// Variables internal structure\r
f8dde18d 92typedef struct VariablesStruct\r
ebcb0f3d 93{\r
0203b5fd
JPM
94 size_t Op; // Variable's DW_OP\r
95 union\r
96 {\r
97 size_t Addr; // Variable memory address\r
98 int Offset; // Variable stack offset (signed)\r
99 };\r
ebcb0f3d
JPM
100 char *PtrName; // Variable's name\r
101 size_t TypeOffset; // Offset pointing on the Variable's Type\r
102 size_t TypeByteSize; // Variable's Type byte size\r
103 size_t TypeTag; // Variable's Type Tag\r
104 size_t TypeEncoding; // Variable's Type encoding\r
105 char *PtrTypeName; // Variable's Type name\r
106}S_VariablesStruct;\r
107\r
108// Sub program internal structure\r
f8dde18d 109typedef struct SubProgStruct\r
ebcb0f3d
JPM
110{\r
111 size_t Tag;\r
112 size_t NumLineSrc;\r
113 size_t StartPC;\r
114 size_t LowPC, HighPC;\r
0203b5fd 115 size_t FrameBase;\r
ebcb0f3d 116 char *PtrLineSrc;\r
0203b5fd
JPM
117 char *PtrSubprogramName; // Sub program name\r
118 size_t NbLinesSrc; // Number of lines source used by the sub program\r
119 DMIStruct_LineSrc *PtrLinesSrc; // Pointer of the lines source for the sub program\r
120 size_t NbVariables; // Variables number\r
121 VariablesStruct *PtrVariables; // Pointer to the local variables list information structure\r
ebcb0f3d
JPM
122}S_SubProgStruct;\r
123\r
124// Compilation Unit internal structure\r
f8dde18d 125typedef struct CUStruct\r
ebcb0f3d
JPM
126{\r
127 size_t Tag;\r
5fa7aa73 128 size_t LowPC, HighPC; // Memory range for the code\r
f8dde18d
JPM
129 char *PtrProducer; // Pointer to the "Producer" text information (mostly compiler and compilation options used)\r
130 char *PtrSourceFilename; // Source file name\r
131 char *PtrSourceFileDirectory; // Directory of the source file\r
ebcb0f3d 132 char *PtrFullFilename; // Pointer to full namefile (directory & filename)\r
5fa7aa73
JPM
133 size_t SizeLoadSrc; // Source code text size\r
134 char *PtrLoadSrc; // Pointer to the source code text\r
135 size_t NbLinesLoadSrc; // Total number of lines in the source code text\r
ebcb0f3d
JPM
136 char **PtrLinesLoadSrc; // Pointer lists to each source line put in QT html/text conformity\r
137 size_t NbSubProgs; // Number of sub programs / routines\r
5fa7aa73 138 SubProgStruct *PtrSubProgs; // Pointer to the sub programs / routines structure\r
f8dde18d
JPM
139 size_t NbTypes; // Number of types\r
140 BaseTypeStruct *PtrTypes; // Pointer to types\r
ebcb0f3d 141 size_t NbVariables; // Variables number\r
5fa7aa73 142 VariablesStruct *PtrVariables; // Pointer to the global variables list structure\r
65597951 143 size_t NbFrames; // Frames number\r
5fa7aa73
JPM
144 size_t NbLinesSrc; // Number of used source lines\r
145 CUStruct_LineSrc *PtrLinesSrc; // Pointer to the used source lines list structure\r
ebcb0f3d
JPM
146}S_CUStruct;\r
147\r
148\r
149// Dwarf management\r
150uint32_t LibDwarf;\r
151uint32_t NbCU;\r
152Dwarf_Ptr errarg;\r
153Dwarf_Error error;\r
154Dwarf_Debug dbg;\r
155CUStruct *PtrCU;\r
f0dd2f7b
JPM
156char **ListSearchPaths;\r
157size_t NbSearchPaths;\r
ebcb0f3d
JPM
158\r
159\r
160//\r
161Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg);\r
162void DWARFManager_InitDMI(void);\r
163void DWARFManager_CloseDMI(void);\r
164bool DWARFManager_ElfClose(void);\r
165char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine);\r
0203b5fd 166void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables);\r
f0dd2f7b
JPM
167void DWARFManager_SourceFileSearchPathsInit(void);\r
168void DWARFManager_SourceFileSearchPathsReset(void);\r
169void DWARFManager_SourceFileSearchPathsClose(void);\r
ebcb0f3d
JPM
170\r
171\r
172//\r
173Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg)\r
174{\r
175 return 0;\r
176}\r
177\r
178\r
f0dd2f7b
JPM
179// Dwarf manager list search paths init\r
180void DWARFManager_SourceFileSearchPathsInit(void)\r
181{\r
182 ListSearchPaths = NULL;\r
183 NbSearchPaths = 0;\r
184}\r
185\r
186\r
187// Dwarf manager list search paths reset\r
188void DWARFManager_SourceFileSearchPathsReset(void)\r
189{\r
190 ListSearchPaths = NULL;\r
191 NbSearchPaths = 0;\r
192}\r
193\r
194\r
195// Dwarf manager list search paths close\r
196void DWARFManager_SourceFileSearchPathsClose(void)\r
197{\r
198 DWARFManager_SourceFileSearchPathsReset();\r
199}\r
200\r
201\r
ebcb0f3d
JPM
202// Dwarf manager init\r
203void DWARFManager_Init(void)\r
204{\r
f0dd2f7b 205 DWARFManager_SourceFileSearchPathsInit();\r
ebcb0f3d
JPM
206 LibDwarf = DW_DLV_NO_ENTRY;\r
207}\r
208\r
209\r
f0dd2f7b
JPM
210// Dwarf manager settings\r
211void DWARFManager_Set(size_t NbPathsInList, char **PtrListPaths)\r
212{\r
213 // Search paths init\r
214 ListSearchPaths = PtrListPaths;\r
215 NbSearchPaths = NbPathsInList;\r
216}\r
217\r
218\r
ebcb0f3d
JPM
219// Dwarf manager Reset\r
220bool DWARFManager_Reset(void)\r
221{\r
f0dd2f7b 222 DWARFManager_SourceFileSearchPathsReset();\r
ebcb0f3d
JPM
223 return DWARFManager_ElfClose();\r
224}\r
225\r
226\r
227// Dwarf manager Close\r
228bool DWARFManager_Close(void)\r
229{\r
f0dd2f7b 230 DWARFManager_SourceFileSearchPathsClose();\r
ebcb0f3d
JPM
231 return(DWARFManager_Reset());\r
232}\r
233\r
234\r
235// Dwarf manager Elf init\r
236int DWARFManager_ElfInit(Elf *ElfPtr)\r
237{\r
238 if ((LibDwarf = dwarf_elf_init(ElfPtr, DW_DLC_READ, (Dwarf_Handler)DWARFManager_ErrorHandler, errarg, &dbg, &error)) == DW_DLV_OK)\r
239 {\r
240 DWARFManager_InitDMI();\r
241 }\r
242\r
243 return LibDwarf;\r
244}\r
245\r
246\r
247// Dwarf manager Elf close\r
248bool DWARFManager_ElfClose(void)\r
249{\r
250 if (LibDwarf == DW_DLV_OK)\r
251 {\r
252 DWARFManager_CloseDMI();\r
253\r
254 if (dwarf_finish(dbg, &error) == DW_DLV_OK)\r
255 {\r
256 LibDwarf = DW_DLV_NO_ENTRY;\r
257 return true;\r
258 }\r
259 else\r
260 {\r
261 return false;\r
262 }\r
263 }\r
264 else\r
265 {\r
266 return true;\r
267 }\r
268}\r
269\r
270\r
271// Dwarf manager Compilation Units close\r
272void DWARFManager_CloseDMI(void)\r
273{\r
274 while (NbCU--)\r
275 {\r
276 free(PtrCU[NbCU].PtrFullFilename);\r
277 free(PtrCU[NbCU].PtrLoadSrc);\r
278 free(PtrCU[NbCU].PtrProducer);\r
f8dde18d
JPM
279 free(PtrCU[NbCU].PtrSourceFilename);\r
280 free(PtrCU[NbCU].PtrSourceFileDirectory);\r
5fa7aa73 281 free(PtrCU[NbCU].PtrLinesSrc);\r
ebcb0f3d
JPM
282\r
283 while (PtrCU[NbCU].NbLinesLoadSrc--)\r
284 {\r
285 free(PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].NbLinesLoadSrc]);\r
286 }\r
287 free(PtrCU[NbCU].PtrLinesLoadSrc);\r
288\r
289 while (PtrCU[NbCU].NbSubProgs--)\r
290 {\r
0203b5fd
JPM
291 while (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables--)\r
292 {\r
293 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName);\r
294 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrTypeName);\r
295 }\r
296 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables);\r
297\r
ebcb0f3d
JPM
298 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc);\r
299 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName);\r
300 }\r
301 free(PtrCU[NbCU].PtrSubProgs);\r
302\r
303 while (PtrCU[NbCU].NbTypes--)\r
304 {\r
305 free(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName);\r
306 }\r
307 free(PtrCU[NbCU].PtrTypes);\r
308\r
309 while (PtrCU[NbCU].NbVariables--)\r
310 {\r
311 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);\r
312 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrTypeName);\r
313 }\r
314 free(PtrCU[NbCU].PtrVariables);\r
315 }\r
316\r
317 free(PtrCU);\r
318}\r
319\r
320\r
321// Dwarf manager Compilation Units initialisations\r
322void DWARFManager_InitDMI(void)\r
323{\r
324 Dwarf_Unsigned next_cu_header, return_uvalue;\r
325 Dwarf_Error error;\r
326 Dwarf_Attribute *atlist;\r
327 Dwarf_Attribute return_attr1;\r
328 Dwarf_Half return_tagval, return_attr;\r
329 Dwarf_Addr return_lowpc, return_highpc, return_lineaddr;\r
330 Dwarf_Block *return_block;\r
331 Dwarf_Signed atcnt, cnt;\r
0203b5fd 332 Dwarf_Die return_sib, return_die, return_sub, return_subdie;\r
ebcb0f3d
JPM
333 Dwarf_Off return_offset;\r
334 Dwarf_Line *linebuf;\r
335 FILE *SrcFile;\r
ebcb0f3d 336 char *return_string;\r
1155c536 337 char *Ptr, *Ptr1;\r
ebcb0f3d
JPM
338\r
339 // Initialisation for the Compilation Units table\r
340 NbCU = 0;\r
341 PtrCU = NULL;\r
342\r
343 // loop on the available Compilation Unit\r
344 while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &next_cu_header, &error) == DW_DLV_OK)\r
345 {\r
346 // Allocation of an additional Compilation Unit structure in the table\r
347 if (Ptr = (char *)realloc(PtrCU, ((NbCU + 1) * sizeof(CUStruct))))\r
348 {\r
349 // Compilation Unit RAZ\r
350 PtrCU = (CUStruct *)Ptr;\r
351 memset(PtrCU + NbCU, 0, sizeof(CUStruct));\r
352\r
41d6f5f7
JPM
353 // Debug specific CU\r
354#ifdef DEBUG_NumCU\r
355 if (NbCU == DEBUG_NumCU)\r
356#endif\r
ebcb0f3d 357 {\r
41d6f5f7
JPM
358 // Get 1st Die from the Compilation Unit\r
359 if (dwarf_siblingof(dbg, NULL, &return_sib, &error) == DW_DLV_OK)\r
ebcb0f3d 360 {\r
41d6f5f7
JPM
361 // Get Die's Tag\r
362 if ((dwarf_tag(return_sib, &return_tagval, &error) == DW_DLV_OK))\r
ebcb0f3d 363 {\r
41d6f5f7
JPM
364 PtrCU[NbCU].Tag = return_tagval;\r
365\r
366 // Die type detection\r
367 switch (return_tagval)\r
ebcb0f3d 368 {\r
65597951 369 case DW_TAG_compile_unit:\r
41d6f5f7 370 if (dwarf_attrlist(return_sib, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 371 {\r
41d6f5f7 372 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 373 {\r
41d6f5f7 374 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 375 {\r
41d6f5f7 376 switch (return_attr)\r
ebcb0f3d 377 {\r
65597951
JPM
378 // Start address\r
379 case DW_AT_low_pc:\r
41d6f5f7
JPM
380 if (dwarf_lowpc(return_sib, &return_lowpc, &error) == DW_DLV_OK)\r
381 {\r
382 PtrCU[NbCU].LowPC = return_lowpc;\r
383 }\r
384 break;\r
ebcb0f3d 385\r
65597951
JPM
386 // End address\r
387 case DW_AT_high_pc:\r
41d6f5f7
JPM
388 if (dwarf_highpc(return_sib, &return_highpc, &error) == DW_DLV_OK)\r
389 {\r
390 PtrCU[NbCU].HighPC = return_highpc;\r
391 }\r
392 break;\r
ebcb0f3d 393\r
65597951
JPM
394 // compilation information\r
395 case DW_AT_producer:\r
41d6f5f7
JPM
396 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
397 {\r
398 PtrCU[NbCU].PtrProducer = (char *)calloc(strlen(return_string) + 1, 1);\r
399 strcpy(PtrCU[NbCU].PtrProducer, return_string);\r
400 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
401 }\r
402 break;\r
ebcb0f3d 403\r
65597951
JPM
404 // Filename\r
405 case DW_AT_name:\r
41d6f5f7
JPM
406 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
407 {\r
f8dde18d
JPM
408#ifdef DEBUG_Filename\r
409 if (strstr(return_string, DEBUG_Filename))\r
410#endif\r
411 {\r
412 PtrCU[NbCU].PtrSourceFilename = (char *)calloc((strlen(return_string) + 1), 1);\r
413 strcpy(PtrCU[NbCU].PtrSourceFilename, return_string);\r
414 }\r
41d6f5f7
JPM
415 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
416 }\r
417 break;\r
ebcb0f3d 418\r
65597951
JPM
419 // Directory name\r
420 case DW_AT_comp_dir:\r
41d6f5f7
JPM
421 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)\r
422 {\r
f8dde18d
JPM
423 PtrCU[NbCU].PtrSourceFileDirectory = (char *)calloc((strlen(return_string) + 1), 1);\r
424 strcpy(PtrCU[NbCU].PtrSourceFileDirectory, return_string);\r
41d6f5f7
JPM
425 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
426 }\r
427 break;\r
ebcb0f3d 428\r
41d6f5f7
JPM
429 default:\r
430 break;\r
431 }\r
ebcb0f3d 432 }\r
41d6f5f7 433 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
ebcb0f3d 434 }\r
41d6f5f7 435 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
ebcb0f3d 436 }\r
ebcb0f3d 437\r
f0dd2f7b 438 // Check filename presence\r
f8dde18d
JPM
439 if (!PtrCU[NbCU].PtrSourceFilename)\r
440 {\r
441 PtrCU[NbCU].PtrSourceFilename = (char *)calloc(1, 1);\r
442 }\r
443\r
f0dd2f7b 444 // Check directory presence\r
f8dde18d
JPM
445 if (!PtrCU[NbCU].PtrSourceFileDirectory)\r
446 {\r
f0dd2f7b
JPM
447 // Check if file exists in the search paths\r
448 for (size_t i = 0; i < NbSearchPaths; i++)\r
449 {\r
450 PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen((const char *)ListSearchPaths[i]) + 2);\r
451#if defined(_WIN32)\r
452 sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", ListSearchPaths[i], PtrCU[NbCU].PtrSourceFilename);\r
453#else\r
454 sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", ListSearchPaths[i], PtrCU[NbCU].PtrSourceFilename);\r
455#endif\r
456 if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rb"))\r
457 {\r
458 PtrCU[NbCU].PtrSourceFileDirectory = (char *)realloc(PtrCU[NbCU].PtrSourceFileDirectory, strlen(ListSearchPaths[i]) + 1);\r
459 strcpy(PtrCU[NbCU].PtrSourceFileDirectory, ListSearchPaths[i]);\r
460 }\r
461 }\r
462\r
463 // File directory doesn't exits\r
464 if (!PtrCU[NbCU].PtrSourceFileDirectory)\r
465 {\r
466 PtrCU[NbCU].PtrSourceFileDirectory = (char *)realloc(PtrCU[NbCU].PtrSourceFileDirectory, 2);\r
467 strcpy(PtrCU[NbCU].PtrSourceFileDirectory, ".");\r
468 }\r
f8dde18d
JPM
469 }\r
470\r
471 // Create full filename\r
472 Ptr = PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen(PtrCU[NbCU].PtrSourceFileDirectory) + 2);\r
f0dd2f7b 473#if defined(_WIN32)\r
f8dde18d 474 sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
f0dd2f7b
JPM
475#else\r
476 sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
477#endif\r
f8dde18d 478 // Conform slashes and backslashes\r
41d6f5f7 479 while (*Ptr)\r
ebcb0f3d 480 {\r
65597951 481#if defined(_WIN32)\r
41d6f5f7
JPM
482 if (*Ptr == '/')\r
483 {\r
484 *Ptr = '\\';\r
485 }\r
65597951
JPM
486#else\r
487 if (*Ptr == '\\')\r
488 {\r
489 *Ptr = '/';\r
490 }\r
491#endif\r
41d6f5f7 492 Ptr++;\r
ebcb0f3d 493 }\r
ebcb0f3d 494\r
1155c536
JPM
495 // Directory path clean-up\r
496#if defined(_WIN32)\r
497 while ((Ptr1 = Ptr = strstr(PtrCU[NbCU].PtrFullFilename, "\\..\\")))\r
498#else\r
499 while ((Ptr1 = Ptr = strstr(PtrCU[NbCU].PtrFullFilename, "/../")))\r
500#endif\r
501 {\r
502#if defined(_WIN32)\r
503 while (*--Ptr1 != '\\');\r
504#else\r
505 while (*--Ptr1 != '/');\r
506#endif\r
507 strcpy((Ptr1 + 1), (Ptr + 4));\r
508 }\r
509\r
f795e8ac
JPM
510 // Open the source file as a binary file\r
511 if (!fopen_s(&SrcFile, PtrCU[NbCU].PtrFullFilename, "rb"))\r
ebcb0f3d 512 {\r
41d6f5f7 513 if (!fseek(SrcFile, 0, SEEK_END))\r
ebcb0f3d 514 {\r
41d6f5f7 515 if ((PtrCU[NbCU].SizeLoadSrc = ftell(SrcFile)) > 0)\r
ebcb0f3d 516 {\r
f795e8ac 517 if (!fseek(SrcFile, 0, SEEK_SET))\r
ebcb0f3d 518 {\r
f795e8ac 519 if (PtrCU[NbCU].PtrLoadSrc = Ptr = Ptr1 = (char *)calloc(1, (PtrCU[NbCU].SizeLoadSrc + 2)))\r
ebcb0f3d 520 {\r
f795e8ac
JPM
521 // Read whole file\r
522 if (fread_s(PtrCU[NbCU].PtrLoadSrc, PtrCU[NbCU].SizeLoadSrc, PtrCU[NbCU].SizeLoadSrc, 1, SrcFile) != 1)\r
ebcb0f3d 523 {\r
f795e8ac
JPM
524 free(PtrCU[NbCU].PtrLoadSrc);\r
525 PtrCU[NbCU].PtrLoadSrc = NULL;\r
526 PtrCU[NbCU].SizeLoadSrc = 0;\r
527 }\r
528 else\r
529 {\r
530 // Eliminate all carriage return code '\r' (oxd)\r
531 do\r
532 {\r
533 if ((*Ptr = *Ptr1) != '\r')\r
534 {\r
535 Ptr++;\r
536 }\r
537 }\r
538 while (*Ptr1++);\r
539\r
540 // Get back the new text file size\r
541 PtrCU[NbCU].SizeLoadSrc = strlen(Ptr = PtrCU[NbCU].PtrLoadSrc);\r
542\r
543 // Make sure the text file finish with a new line code '\n' (0xa)\r
544 if (PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc - 1] != '\n')\r
41d6f5f7 545 {\r
f795e8ac
JPM
546 PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc++] = '\n';\r
547 PtrCU[NbCU].PtrLoadSrc[PtrCU[NbCU].SizeLoadSrc] = 0;\r
41d6f5f7 548 }\r
f795e8ac
JPM
549\r
550 // Reallocate text file\r
551 if (PtrCU[NbCU].PtrLoadSrc = Ptr = (char *)realloc(PtrCU[NbCU].PtrLoadSrc, (PtrCU[NbCU].SizeLoadSrc + 1)))\r
552 {\r
553 // Count line numbers, based on the new line code '\n' (0xa), and finish each line with 0\r
554 do\r
555 {\r
556 if (*Ptr == '\n')\r
557 {\r
558 PtrCU[NbCU].NbLinesLoadSrc++;\r
559 *Ptr = 0;\r
560 }\r
561 } while (*++Ptr);\r
562 }\r
563 }\r
41d6f5f7 564 }\r
ebcb0f3d
JPM
565 }\r
566 }\r
567 }\r
41d6f5f7 568 fclose(SrcFile);\r
ebcb0f3d 569 }\r
41d6f5f7 570 break;\r
ebcb0f3d 571\r
41d6f5f7
JPM
572 default:\r
573 break;\r
574 }\r
ebcb0f3d 575 }\r
ebcb0f3d 576\r
f795e8ac 577 // Get the source lines table located in the CU\r
41d6f5f7
JPM
578 if (dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK)\r
579 {\r
5fa7aa73
JPM
580 if (cnt)\r
581 {\r
582 PtrCU[NbCU].NbLinesSrc = cnt;\r
583 PtrCU[NbCU].PtrLinesSrc = (CUStruct_LineSrc *)calloc(cnt, sizeof(CUStruct_LineSrc));\r
584 for (Dwarf_Signed i = 0; i < cnt; i++)\r
585 {\r
586 if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
587 {\r
588 if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
589 {\r
590 PtrCU[NbCU].PtrLinesSrc[i].StartPC = return_lineaddr;\r
591 PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc = return_uvalue;\r
592 }\r
593 }\r
594 }\r
595 }\r
41d6f5f7 596 }\r
ebcb0f3d 597\r
0203b5fd 598 // Check if the CU has child\r
41d6f5f7 599 if (dwarf_child(return_sib, &return_die, &error) == DW_DLV_OK)\r
ebcb0f3d 600 {\r
41d6f5f7 601 do\r
ebcb0f3d 602 {\r
41d6f5f7
JPM
603 return_sib = return_die;\r
604 if ((dwarf_tag(return_die, &return_tagval, &error) == DW_DLV_OK))\r
ebcb0f3d 605 {\r
41d6f5f7 606 switch (return_tagval)\r
ebcb0f3d 607 {\r
65597951 608 case DW_TAG_lexical_block:\r
41d6f5f7 609 break;\r
ebcb0f3d 610\r
65597951 611 case DW_TAG_variable:\r
41d6f5f7 612 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 613 {\r
41d6f5f7
JPM
614 PtrCU[NbCU].PtrVariables = (VariablesStruct *)realloc(PtrCU[NbCU].PtrVariables, ((PtrCU[NbCU].NbVariables + 1) * sizeof(VariablesStruct)));\r
615 memset(PtrCU[NbCU].PtrVariables + PtrCU[NbCU].NbVariables, 0, sizeof(VariablesStruct));\r
616\r
617 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 618 {\r
41d6f5f7 619 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 620 {\r
41d6f5f7 621 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
ebcb0f3d 622 {\r
41d6f5f7 623 switch (return_attr)\r
ebcb0f3d 624 {\r
65597951 625 case DW_AT_location:\r
41d6f5f7 626 if (dwarf_formblock(return_attr1, &return_block, &error) == DW_DLV_OK)\r
ebcb0f3d 627 {\r
0203b5fd
JPM
628 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].Op = (*((unsigned char *)(return_block->bl_data)));\r
629\r
630 switch (return_block->bl_len)\r
41d6f5f7 631 {\r
0203b5fd 632 case 5:\r
41d6f5f7 633 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].Addr = (*((unsigned char *)(return_block->bl_data) + 1) << 24) + (*((unsigned char *)(return_block->bl_data) + 2) << 16) + (*((unsigned char *)(return_block->bl_data) + 3) << 8) + (*((unsigned char *)(return_block->bl_data) + 4));\r
0203b5fd
JPM
634 break;\r
635\r
636 default:\r
637 break;\r
41d6f5f7
JPM
638 }\r
639 dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);\r
ebcb0f3d 640 }\r
41d6f5f7 641 break;\r
ebcb0f3d 642\r
65597951 643 case DW_AT_type:\r
41d6f5f7
JPM
644 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
645 {\r
646 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].TypeOffset = return_offset;\r
647 }\r
648 break;\r
ebcb0f3d 649\r
65597951
JPM
650 // Variable name\r
651 case DW_AT_name:\r
41d6f5f7
JPM
652 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
653 {\r
0203b5fd
JPM
654#ifdef DEBUG_VariableName\r
655 if (!strcmp(return_string, DEBUG_VariableName))\r
656#endif\r
657 {\r
658 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
659 strcpy(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName, return_string);\r
0203b5fd 660 }\r
f8dde18d 661 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
41d6f5f7
JPM
662 }\r
663 break;\r
ebcb0f3d 664\r
65597951 665 default:\r
41d6f5f7
JPM
666 break;\r
667 }\r
ebcb0f3d
JPM
668 }\r
669 }\r
ebcb0f3d 670\r
41d6f5f7
JPM
671 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
672 }\r
ebcb0f3d 673\r
ce32526a
JPM
674 // Check variable's name validity\r
675 if (PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName)\r
676 {\r
677 // Check variable's memory address validity\r
678 if (PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].Addr)\r
679 {\r
680 // Valid variable\r
681 PtrCU[NbCU].NbVariables++;\r
682 }\r
683 else\r
684 {\r
685 // Invalid variable\r
686 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);\r
687 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName = NULL;\r
688 }\r
689 }\r
ebcb0f3d 690\r
41d6f5f7 691 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
ebcb0f3d 692 }\r
41d6f5f7
JPM
693 break;\r
694\r
65597951
JPM
695 case DW_TAG_base_type:\r
696 case DW_TAG_typedef:\r
697 case DW_TAG_structure_type:\r
698 case DW_TAG_pointer_type:\r
699 case DW_TAG_const_type:\r
700 case DW_TAG_array_type:\r
701 case DW_TAG_subrange_type:\r
702 case DW_TAG_subroutine_type:\r
f8dde18d 703 case DW_TAG_enumeration_type:\r
41d6f5f7 704 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 705 {\r
f8dde18d 706 // Allocate memory for this type\r
41d6f5f7
JPM
707 PtrCU[NbCU].PtrTypes = (BaseTypeStruct *)realloc(PtrCU[NbCU].PtrTypes, ((PtrCU[NbCU].NbTypes + 1) * sizeof(BaseTypeStruct)));\r
708 memset(PtrCU[NbCU].PtrTypes + PtrCU[NbCU].NbTypes, 0, sizeof(BaseTypeStruct));\r
709 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Tag = return_tagval;\r
710\r
711 if (dwarf_dieoffset(return_die, &return_offset, &error) == DW_DLV_OK)\r
712 {\r
713 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Offset = return_offset;\r
714 }\r
715\r
716 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 717 {\r
41d6f5f7 718 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 719 {\r
41d6f5f7 720 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
ebcb0f3d 721 {\r
41d6f5f7 722 switch (return_attr)\r
ebcb0f3d 723 {\r
f8dde18d
JPM
724 // \r
725 case DW_AT_sibling:\r
726 break;\r
727\r
728 // Type's type offset\r
65597951 729 case DW_AT_type:\r
41d6f5f7
JPM
730 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
731 {\r
732 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].TypeOffset = return_offset;\r
733 }\r
734 break;\r
ebcb0f3d 735\r
f8dde18d 736 // Type's byte size\r
65597951 737 case DW_AT_byte_size:\r
41d6f5f7
JPM
738 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
739 {\r
740 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].ByteSize = return_uvalue;\r
741 }\r
742 break;\r
ebcb0f3d 743\r
f8dde18d 744 // Type's encoding\r
65597951 745 case DW_AT_encoding:\r
41d6f5f7
JPM
746 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
747 {\r
748 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Encoding = return_uvalue;\r
749 }\r
750 break;\r
ebcb0f3d 751\r
f8dde18d 752 // Type's name\r
65597951 753 case DW_AT_name:\r
41d6f5f7
JPM
754 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
755 {\r
f8dde18d
JPM
756#ifdef DEBUG_TypeName\r
757 if (!strcmp(return_string, DEBUG_TypeName))\r
758#endif\r
759 {\r
760 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
761 strcpy(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName, return_string);\r
762 }\r
41d6f5f7
JPM
763 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
764 }\r
765 break;\r
ebcb0f3d 766\r
f8dde18d
JPM
767 // Type's file number\r
768 case DW_AT_decl_file:\r
769 break;\r
770\r
771 // Type's line number\r
772 case DW_AT_decl_line:\r
773 break;\r
774\r
775 default:\r
41d6f5f7
JPM
776 break;\r
777 }\r
ebcb0f3d
JPM
778 }\r
779 }\r
ebcb0f3d 780\r
41d6f5f7
JPM
781 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
782 }\r
ebcb0f3d 783\r
41d6f5f7 784 PtrCU[NbCU].NbTypes++;\r
ebcb0f3d 785\r
41d6f5f7
JPM
786 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
787 }\r
788 break;\r
ebcb0f3d 789\r
65597951 790 case DW_TAG_subprogram:\r
41d6f5f7 791 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)\r
ebcb0f3d 792 {\r
41d6f5f7
JPM
793 PtrCU[NbCU].PtrSubProgs = (SubProgStruct *)realloc(PtrCU[NbCU].PtrSubProgs, ((PtrCU[NbCU].NbSubProgs + 1) * sizeof(SubProgStruct)));\r
794 memset((void *)(PtrCU[NbCU].PtrSubProgs + PtrCU[NbCU].NbSubProgs), 0, sizeof(SubProgStruct));\r
795 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].Tag = return_tagval;\r
796\r
797 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
ebcb0f3d 798 {\r
41d6f5f7 799 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
ebcb0f3d 800 {\r
41d6f5f7 801 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
ebcb0f3d 802 {\r
41d6f5f7 803 switch (return_attr)\r
ebcb0f3d 804 {\r
65597951 805 // start address\r
0203b5fd 806 case DW_AT_low_pc:\r
41d6f5f7
JPM
807 if (dwarf_lowpc(return_die, &return_lowpc, &error) == DW_DLV_OK)\r
808 {\r
809 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].StartPC = return_lowpc;\r
810 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].LowPC = return_lowpc;\r
811 }\r
812 break;\r
ebcb0f3d 813\r
65597951 814 // end address\r
0203b5fd 815 case DW_AT_high_pc:\r
41d6f5f7
JPM
816 if (dwarf_highpc(return_die, &return_highpc, &error) == DW_DLV_OK)\r
817 {\r
818 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].HighPC = return_highpc;\r
819 }\r
820 break;\r
ebcb0f3d 821\r
65597951 822 // Line number\r
0203b5fd 823 case DW_AT_decl_line:\r
41d6f5f7
JPM
824 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
825 {\r
826 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NumLineSrc = return_uvalue;\r
827 }\r
828 break;\r
ebcb0f3d 829\r
65597951 830 // Frame\r
0203b5fd
JPM
831 case DW_AT_frame_base:\r
832 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)\r
833 {\r
834 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].FrameBase = return_uvalue;\r
65597951 835 PtrCU[NbCU].NbFrames++;\r
0203b5fd
JPM
836 }\r
837 break;\r
838\r
65597951 839 // function name\r
0203b5fd 840 case DW_AT_name:\r
41d6f5f7
JPM
841 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
842 {\r
843 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName = (char *)calloc(strlen(return_string) + 1, 1);\r
844 strcpy(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName, return_string);\r
845 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
846 }\r
847 break;\r
ebcb0f3d 848\r
65597951
JPM
849 case DW_AT_sibling:\r
850 break;\r
851\r
852 case DW_AT_GNU_all_tail_call_sites:\r
853 break;\r
854\r
855 case DW_AT_type:\r
856 break;\r
857\r
858 case DW_AT_prototyped:\r
859 break;\r
860\r
861 // File number\r
862 case DW_AT_decl_file:\r
863 break;\r
864\r
865 case DW_AT_external:\r
866 break;\r
867\r
41d6f5f7
JPM
868 default:\r
869 break;\r
870 }\r
ebcb0f3d
JPM
871 }\r
872 }\r
41d6f5f7 873 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
ebcb0f3d 874 }\r
41d6f5f7 875 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
ebcb0f3d 876\r
f8dde18d 877 // Get source line number and associated block of address\r
ce32526a 878 for (Dwarf_Signed i = 0; i < cnt; ++i)\r
ebcb0f3d 879 {\r
41d6f5f7 880 if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
ebcb0f3d 881 {\r
41d6f5f7 882 if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
ebcb0f3d 883 {\r
41d6f5f7
JPM
884 if ((return_lineaddr >= return_lowpc) && (return_lineaddr <= return_highpc))\r
885 {\r
886 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
887 memset((void *)(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc), 0, sizeof(DMIStruct_LineSrc));\r
888 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].StartPC = return_lineaddr;\r
889 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].NumLineSrc = return_uvalue;\r
890 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc++;\r
891 }\r
ebcb0f3d
JPM
892 }\r
893 }\r
41d6f5f7
JPM
894 }\r
895\r
0203b5fd
JPM
896 if (dwarf_child(return_die, &return_subdie, &error) == DW_DLV_OK)\r
897 {\r
898 do\r
899 {\r
900 return_sub = return_subdie;\r
901 if ((dwarf_tag(return_subdie, &return_tagval, &error) == DW_DLV_OK))\r
902 {\r
903 switch (return_tagval)\r
904 {\r
905 case DW_TAG_formal_parameter:\r
906 case DW_TAG_variable:\r
907 if (dwarf_attrlist(return_subdie, &atlist, &atcnt, &error) == DW_DLV_OK)\r
908 {\r
909 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables = (VariablesStruct *)realloc(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables, ((PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables + 1) * sizeof(VariablesStruct)));\r
910 memset(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables, 0, sizeof(VariablesStruct));\r
911\r
912 for (Dwarf_Signed i = 0; i < atcnt; ++i)\r
913 {\r
914 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)\r
915 {\r
916 if (dwarf_attr(return_subdie, return_attr, &return_attr1, &error) == DW_DLV_OK)\r
917 {\r
918 switch (return_attr)\r
919 {\r
65597951 920 case DW_AT_location:\r
0203b5fd
JPM
921 if (dwarf_formblock(return_attr1, &return_block, &error) == DW_DLV_OK)\r
922 {\r
923 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Op = *((unsigned char *)(return_block->bl_data));\r
924\r
925 switch (return_block->bl_len)\r
926 {\r
927 case 1:\r
928 break;\r
929\r
930 case 2:\r
f8dde18d 931 case 3:\r
47b6ecae 932 switch (return_tagval)\r
0203b5fd 933 {\r
65597951 934 case DW_TAG_variable:\r
f8dde18d 935 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Offset = ReadLEB128((char *)return_block->bl_data + 1);\r
47b6ecae
JPM
936 break;\r
937\r
65597951 938 case DW_TAG_formal_parameter:\r
f8dde18d 939 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].Offset = ReadULEB128((char *)return_block->bl_data + 1);\r
47b6ecae
JPM
940 break;\r
941\r
942 default:\r
943 break;\r
0203b5fd 944 }\r
f8dde18d 945 break;\r
0203b5fd
JPM
946\r
947 default:\r
948 break;\r
949 }\r
950 dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);\r
951 }\r
952 break;\r
953\r
65597951 954 case DW_AT_type:\r
0203b5fd
JPM
955 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)\r
956 {\r
957 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].TypeOffset = return_offset;\r
958 }\r
959 break;\r
960\r
65597951 961 case DW_AT_name:\r
0203b5fd
JPM
962 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)\r
963 {\r
964#ifdef DEBUG_VariableName\r
965 if (!strcmp(return_string, DEBUG_VariableName))\r
966#endif\r
967 {\r
968 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName = (char *)calloc(strlen(return_string) + 1, 1);\r
969 strcpy(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrVariables[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables].PtrName, return_string);\r
0203b5fd 970 }\r
f8dde18d 971 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);\r
0203b5fd
JPM
972 }\r
973 break;\r
974\r
65597951 975 case DW_AT_decl_file:\r
47b6ecae
JPM
976 break;\r
977\r
65597951 978 case DW_AT_decl_line:\r
47b6ecae
JPM
979 break;\r
980\r
0203b5fd
JPM
981 default:\r
982 break;\r
983 }\r
984 }\r
985 }\r
986\r
987 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);\r
988 }\r
989\r
990 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbVariables++;\r
991\r
992 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);\r
993 }\r
994 break;\r
995\r
996 case DW_TAG_label:\r
997 break;\r
998\r
999 default:\r
1000 break;\r
1001 }\r
1002 }\r
1003 }\r
1004 while (dwarf_siblingof(dbg, return_sub, &return_subdie, &error) == DW_DLV_OK);\r
1005 }\r
1006\r
41d6f5f7 1007 PtrCU[NbCU].NbSubProgs++;\r
ebcb0f3d 1008 }\r
41d6f5f7 1009 break;\r
ebcb0f3d 1010\r
41d6f5f7
JPM
1011 default:\r
1012 break;\r
1013 }\r
ebcb0f3d 1014 }\r
0203b5fd
JPM
1015 }\r
1016 while (dwarf_siblingof(dbg, return_sib, &return_die, &error) == DW_DLV_OK);\r
ebcb0f3d 1017 }\r
ebcb0f3d 1018\r
41d6f5f7 1019 // Release the memory used by the source lines\r
ce32526a 1020 for (Dwarf_Signed i = 0; i < cnt; ++i)\r
47b6ecae 1021 {\r
41d6f5f7 1022 dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);\r
47b6ecae 1023 }\r
41d6f5f7
JPM
1024 dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);\r
1025 }\r
ebcb0f3d 1026\r
41d6f5f7
JPM
1027 // Set the source code lines for QT html/text conformity\r
1028 if (PtrCU[NbCU].NbLinesLoadSrc)\r
ebcb0f3d 1029 {\r
41d6f5f7 1030 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(PtrCU[NbCU].NbLinesLoadSrc, sizeof(char *)))\r
ebcb0f3d 1031 {\r
ce32526a 1032 for (size_t j = 0; j < PtrCU[NbCU].NbLinesLoadSrc; j++)\r
ebcb0f3d 1033 {\r
41d6f5f7 1034 if (PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)calloc(10000, sizeof(char)))\r
ebcb0f3d 1035 {\r
41d6f5f7 1036 if (Ptr = DWARFManager_GetLineSrcFromNumLine(PtrCU[NbCU].PtrLoadSrc, (j + 1)))\r
ebcb0f3d 1037 {\r
ce32526a 1038 size_t i = 0;\r
41d6f5f7
JPM
1039\r
1040 while (*Ptr)\r
ebcb0f3d 1041 {\r
41d6f5f7
JPM
1042 switch (*Ptr)\r
1043 {\r
1044 case 9:\r
1045 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");\r
ce32526a 1046 i += 6;\r
41d6f5f7
JPM
1047 break;\r
1048\r
1049 case '<':\r
1050 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&lt;");\r
ce32526a 1051 i += 4;\r
41d6f5f7
JPM
1052 break;\r
1053\r
1054 case '>':\r
1055 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&gt;");\r
ce32526a 1056 i += 4;\r
41d6f5f7 1057 break;\r
ebcb0f3d 1058#if 0\r
41d6f5f7
JPM
1059 case '&':\r
1060 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&amp;");\r
1061 i += strlen("&amp;");\r
1062 break;\r
ebcb0f3d
JPM
1063#endif\r
1064#if 0\r
41d6f5f7
JPM
1065 case '"':\r
1066 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");\r
1067 i += strlen("&quot;");\r
1068 break;\r
ebcb0f3d 1069#endif\r
41d6f5f7
JPM
1070 default:\r
1071 PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;\r
1072 break;\r
1073 }\r
1074 Ptr++;\r
ebcb0f3d 1075 }\r
ebcb0f3d 1076 }\r
ce32526a 1077 PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)realloc(PtrCU[NbCU].PtrLinesLoadSrc[j], strlen(PtrCU[NbCU].PtrLinesLoadSrc[j]) + 1);\r
ebcb0f3d 1078 }\r
ebcb0f3d 1079 }\r
95fe01d7 1080\r
5fa7aa73 1081 // Init lines source information for each source code line numbers and for each subprogs\r
ce32526a 1082 for (size_t j = 0; j < PtrCU[NbCU].NbSubProgs; j++)\r
95fe01d7
JPM
1083 {\r
1084 // Check if the subprog / function's line exists in the source code\r
1085 if (PtrCU[NbCU].PtrSubProgs[j].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
1086 {\r
1087 PtrCU[NbCU].PtrSubProgs[j].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].NumLineSrc - 1];\r
1088 }\r
1089\r
ce32526a 1090 for (size_t k = 0; k < PtrCU[NbCU].PtrSubProgs[j].NbLinesSrc; k++)\r
95fe01d7
JPM
1091 {\r
1092 if (PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
1093 {\r
1094 PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc - 1];\r
1095 }\r
1096 }\r
1097 }\r
ebcb0f3d
JPM
1098 }\r
1099 }\r
41d6f5f7 1100 else\r
ebcb0f3d 1101 {\r
41d6f5f7
JPM
1102 // Set each source lines pointer to NULL\r
1103 if (PtrCU[NbCU].NbSubProgs)\r
ebcb0f3d 1104 {\r
95fe01d7
JPM
1105 // Check the presence of source lines dedicated to the sub progs\r
1106 if (PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc)\r
ebcb0f3d 1107 {\r
ce32526a 1108 size_t i = PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc - 1].NumLineSrc;\r
95fe01d7 1109 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(i, sizeof(char *)))\r
41d6f5f7 1110 {\r
ce32526a 1111 for (size_t j = 0; j < i; j++)\r
95fe01d7
JPM
1112 {\r
1113 PtrCU[NbCU].PtrLinesLoadSrc[j] = NULL;\r
1114 }\r
41d6f5f7 1115 }\r
ebcb0f3d
JPM
1116 }\r
1117 }\r
1118 }\r
ebcb0f3d 1119\r
5fa7aa73
JPM
1120 // Set information based on used line numbers\r
1121 if (PtrCU[NbCU].PtrLinesSrc)\r
1122 {\r
1123 // Set the line source pointer for each used line numbers\r
1124 if (PtrCU[NbCU].PtrLinesLoadSrc)\r
1125 {\r
1126 for (size_t i = 0; i < PtrCU[NbCU].NbLinesSrc; i++)\r
1127 {\r
1128 PtrCU[NbCU].PtrLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc - 1];\r
1129 }\r
0536c3ba
JPM
1130\r
1131 // Setup memory range for the code if CU doesn't have already this information\r
1132 // It is taken from the used lines structure\r
1133 if (!PtrCU[NbCU].LowPC && (!PtrCU[NbCU].HighPC || (PtrCU[NbCU].HighPC == ~0)))\r
1134 {\r
1135 PtrCU[NbCU].LowPC = PtrCU[NbCU].PtrLinesSrc[0].StartPC;\r
1136 PtrCU[NbCU].HighPC = PtrCU[NbCU].PtrLinesSrc[PtrCU[NbCU].NbLinesSrc - 1].StartPC;\r
1137 }\r
5fa7aa73 1138 }\r
5fa7aa73
JPM
1139 }\r
1140\r
0203b5fd 1141 // Init global variables information based on types information\r
ce32526a 1142 for (size_t i = 0; i < PtrCU[NbCU].NbVariables; i++)\r
ebcb0f3d 1143 {\r
0203b5fd
JPM
1144 DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrVariables + i);\r
1145 }\r
41d6f5f7 1146\r
0203b5fd 1147 // Init local variables information based on types information\r
ce32526a 1148 for (size_t i = 0; i < PtrCU[NbCU].NbSubProgs; i++)\r
0203b5fd 1149 {\r
ce32526a 1150 for (size_t j = 0; j < PtrCU[NbCU].PtrSubProgs[i].NbVariables; j++)\r
ebcb0f3d 1151 {\r
0203b5fd 1152 DWARFManager_InitInfosVariable(PtrCU[NbCU].PtrSubProgs[i].PtrVariables + j);\r
ebcb0f3d
JPM
1153 }\r
1154 }\r
1155 }\r
1156\r
1157 ++NbCU;\r
1158 }\r
1159 } \r
ebcb0f3d
JPM
1160}\r
1161\r
1162\r
65597951 1163// Variables information initialisation\r
0203b5fd
JPM
1164void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)\r
1165{\r
1166 size_t j, TypeOffset;\r
1167\r
f8dde18d
JPM
1168#ifdef DEBUG_VariableName\r
1169 if (PtrVariables->PtrName && !strcmp(PtrVariables->PtrName, DEBUG_VariableName))\r
1170#endif\r
0203b5fd 1171 {\r
f8dde18d
JPM
1172 PtrVariables->PtrTypeName = (char *)calloc(1000, 1);\r
1173 TypeOffset = PtrVariables->TypeOffset;\r
1174\r
1175 for (j = 0; j < PtrCU[NbCU].NbTypes; j++)\r
0203b5fd 1176 {\r
f8dde18d 1177 if (TypeOffset == PtrCU[NbCU].PtrTypes[j].Offset)\r
0203b5fd 1178 {\r
f8dde18d 1179 switch (PtrCU[NbCU].PtrTypes[j].Tag)\r
0203b5fd 1180 {\r
f8dde18d
JPM
1181 case DW_TAG_subroutine_type:\r
1182 PtrVariables->TypeTag |= TypeTag_subroutine_type;\r
1183 strcat(PtrVariables->PtrTypeName, " (* ) ()");\r
1184 break;\r
1185\r
1186 // Structure type tag\r
1187 case DW_TAG_structure_type:\r
1188 PtrVariables->TypeTag |= TypeTag_structure;\r
1189 if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
0203b5fd 1190 {\r
f8dde18d 1191 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
0203b5fd 1192 }\r
f8dde18d
JPM
1193 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1194 {\r
1195 j = -1;\r
1196 }\r
1197 else\r
1198 {\r
1199 if ((PtrVariables->TypeTag & TypeTag_pointer))\r
1200 {\r
1201 strcat(PtrVariables->PtrTypeName, " *");\r
1202 }\r
1203 }\r
1204 break;\r
0203b5fd 1205\r
f8dde18d
JPM
1206 // Pointer type tag\r
1207 case DW_TAG_pointer_type:\r
1208 PtrVariables->TypeTag |= TypeTag_pointer;\r
1209 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
1210 PtrVariables->TypeEncoding = 0x10;\r
1211 if (!(TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1212 {\r
1213 strcat(PtrVariables->PtrTypeName, "void *");\r
1214 }\r
1215 else\r
1216 {\r
1217 j = -1;\r
1218 }\r
1219 break;\r
0203b5fd 1220\r
f8dde18d
JPM
1221 case DW_TAG_enumeration_type:\r
1222 PtrVariables->TypeTag |= TypeTag_enumeration_type;\r
1223 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
1224 if (!(PtrVariables->TypeEncoding = PtrCU[NbCU].PtrTypes[j].Encoding))\r
1225 {\r
1226 // Try to determine the possible size\r
1227 switch (PtrVariables->TypeByteSize)\r
1228 {\r
1229 case 4:\r
1230 PtrVariables->TypeEncoding = 0x7;\r
1231 break;\r
0203b5fd 1232\r
f8dde18d
JPM
1233 default:\r
1234 break;\r
1235 }\r
1236 }\r
1237 break;\r
0203b5fd 1238\r
f8dde18d
JPM
1239 // Typedef type tag\r
1240 case DW_TAG_typedef:\r
1241 if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
1242 {\r
1243 PtrVariables->TypeTag |= TypeTag_typedef;\r
1244 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
1245 }\r
1246 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1247 {\r
1248 j = -1;\r
1249 }\r
1250 break;\r
0203b5fd 1251\r
f8dde18d
JPM
1252 // ? type tag\r
1253 case DW_TAG_subrange_type:\r
1254 PtrVariables->TypeTag |= TypeTag_subrange;\r
1255 break;\r
0203b5fd 1256\r
f8dde18d
JPM
1257 // Array type tag\r
1258 case DW_TAG_array_type:\r
1259 PtrVariables->TypeTag |= TypeTag_arraytype;\r
1260 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1261 {\r
1262 j = -1;\r
1263 }\r
1264 break;\r
1265\r
1266 // Const type tag\r
1267 case DW_TAG_const_type:\r
1268 PtrVariables->TypeTag |= TypeTag_consttype;\r
1269 strcat(PtrVariables->PtrTypeName, "const ");\r
1270 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))\r
1271 {\r
1272 j = -1;\r
1273 }\r
1274 break;\r
1275\r
1276 // Base type tag\r
1277 case DW_TAG_base_type:\r
1278 if (!(PtrVariables->TypeTag & TypeTag_typedef))\r
1279 {\r
1280 strcat(PtrVariables->PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);\r
1281 }\r
1282 if ((PtrVariables->TypeTag & TypeTag_pointer))\r
1283 {\r
1284 strcat(PtrVariables->PtrTypeName, " *");\r
1285 }\r
1286 else\r
1287 {\r
1288 PtrVariables->TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;\r
1289 PtrVariables->TypeEncoding = PtrCU[NbCU].PtrTypes[j].Encoding;\r
1290 }\r
1291 if ((PtrVariables->TypeTag & TypeTag_arraytype))\r
1292 {\r
1293 strcat(PtrVariables->PtrTypeName, "[]");\r
1294 }\r
1295 break;\r
1296\r
1297 default:\r
1298 break;\r
1299 }\r
0203b5fd
JPM
1300 }\r
1301 }\r
1302 }\r
1303}\r
1304\r
1305\r
ebcb0f3d
JPM
1306// Get symbol name based from address\r
1307// Return NULL if no symbol name exists\r
1308char *DWARFManager_GetSymbolnameFromAdr(size_t Adr)\r
1309{\r
f0dd2f7b 1310 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1311 {\r
1312 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1313 {\r
f0dd2f7b 1314 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
ebcb0f3d
JPM
1315 {\r
1316 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr))\r
1317 {\r
1318 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;\r
1319 }\r
1320 }\r
1321 }\r
1322 }\r
1323\r
1324 return NULL;\r
1325}\r
1326\r
1327\r
1328// Get complete source filename based from address\r
1329// Return NULL if no source filename exists\r
1330// Return the existence status (true or false) in Error\r
1331char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error)\r
1332{\r
f0dd2f7b 1333 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1334 {\r
1335 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1336 {\r
1337 *Error = PtrCU[i].PtrLoadSrc ? true : false;\r
1338 return PtrCU[i].PtrFullFilename;\r
1339 }\r
1340 }\r
1341\r
1342 return NULL;\r
1343}\r
1344\r
1345\r
f0dd2f7b 1346// Get text line source based on line number (starting from 1)\r
ebcb0f3d
JPM
1347// Return NULL if no text line exists or if line number is 0\r
1348char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine)\r
1349{\r
1350 size_t i = 0;\r
1351 char *PtrLineSrc = NULL;\r
1352\r
1353 if (PtrSrcFile)\r
1354 {\r
1355 while (i != NumLine)\r
1356 {\r
1357 PtrLineSrc = PtrSrcFile;\r
1358 while (*PtrSrcFile++);\r
1359 i++;\r
1360 }\r
1361 }\r
1362\r
1363 return PtrLineSrc;\r
1364}\r
1365\r
1366\r
0203b5fd
JPM
1367// Get number of variables referenced by the function range address\r
1368size_t DWARFManager_GetNbLocalVariables(size_t Adr)\r
1369{\r
f0dd2f7b 1370 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1371 {\r
1372 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1373 {\r
f0dd2f7b 1374 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1375 {\r
1376 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1377 {\r
1378 return PtrCU[i].PtrSubProgs[j].NbVariables;\r
1379 }\r
1380 }\r
1381 }\r
1382 }\r
1383\r
1384 return 0;\r
1385}\r
1386\r
1387\r
f0dd2f7b 1388// Get local variable name based on his index (starting from 1)\r
0203b5fd
JPM
1389// Return name's pointer text found\r
1390// Return NULL if not found\r
1391char *DWARFManager_GetLocalVariableName(size_t Adr, size_t Index)\r
1392{\r
f0dd2f7b 1393 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1394 {\r
1395 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1396 {\r
f0dd2f7b 1397 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1398 {\r
1399 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1400 {\r
1401 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].PtrName;\r
1402 }\r
1403 }\r
1404 }\r
1405 }\r
1406\r
1407 return NULL;\r
1408}\r
1409\r
1410\r
f0dd2f7b 1411// Get local variable's type tag based on his index (starting from 1)\r
0203b5fd
JPM
1412// Return 0 if not found\r
1413size_t DWARFManager_GetLocalVariableTypeTag(size_t Adr, size_t Index)\r
1414{\r
f0dd2f7b 1415 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1416 {\r
1417 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1418 {\r
f0dd2f7b 1419 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1420 {\r
1421 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1422 {\r
1423 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeTag;\r
1424 }\r
1425 }\r
1426 }\r
1427 }\r
1428\r
1429 return 0;\r
1430}\r
1431\r
1432\r
f0dd2f7b
JPM
1433// Get the local variable's offset based on a index (starting from 1)\r
1434// Return 0 if no offset has been found\r
0203b5fd
JPM
1435int DWARFManager_GetLocalVariableOffset(size_t Adr, size_t Index)\r
1436{\r
f0dd2f7b 1437 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1438 {\r
1439 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1440 {\r
f0dd2f7b 1441 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1442 {\r
1443 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1444 {\r
1445 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].Offset;\r
1446 }\r
1447 }\r
1448 }\r
1449 }\r
1450\r
1451 return 0;\r
1452}\r
1453\r
1454\r
f0dd2f7b 1455// Get local variable Type Byte Size based on his address and index (starting from 1)\r
0203b5fd
JPM
1456// Return 0 if not found\r
1457// May return 0 if there is no Type Byte Size linked to the variable's address and index\r
1458size_t DWARFManager_GetLocalVariableTypeByteSize(size_t Adr, size_t Index)\r
1459{\r
f0dd2f7b 1460 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1461 {\r
1462 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1463 {\r
f0dd2f7b 1464 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1465 {\r
1466 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1467 {\r
1468 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeByteSize;\r
1469 }\r
1470 }\r
1471 }\r
1472 }\r
1473\r
1474 return 0;\r
1475}\r
1476\r
1477\r
f0dd2f7b 1478// Get local variable Type Encoding based on his address and index (starting from 1)\r
0203b5fd
JPM
1479// Return 0 if not found\r
1480// May return 0 if there is no Type Encoding linked to the variable's address and index\r
1481size_t DWARFManager_GetLocalVariableTypeEncoding(size_t Adr, size_t Index)\r
1482{\r
f0dd2f7b 1483 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1484 {\r
1485 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1486 {\r
f0dd2f7b 1487 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1488 {\r
1489 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1490 {\r
1491 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].TypeEncoding;\r
1492 }\r
1493 }\r
1494 }\r
1495 }\r
1496\r
1497 return 0;\r
1498}\r
1499\r
1500\r
f0dd2f7b 1501// Get local variable Op based on his address and index (starting from 1)\r
5fa7aa73 1502// Return 0 if not found, may return 0 if there isn't Op linked to the variable's index\r
0203b5fd
JPM
1503size_t DWARFManager_GetLocalVariableOp(size_t Adr, size_t Index)\r
1504{\r
f0dd2f7b 1505 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1506 {\r
1507 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1508 {\r
f0dd2f7b 1509 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1510 {\r
1511 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1512 {\r
1513 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].Op;\r
1514 }\r
1515 }\r
1516 }\r
1517 }\r
1518\r
1519 return 0;\r
1520}\r
1521\r
1522\r
f0dd2f7b 1523// Get local variable type name based on his index (starting from 1) and an address\r
5fa7aa73 1524// Return NULL if not found, may also return NULL if there is no type linked to the variable's index\r
0203b5fd
JPM
1525char *DWARFManager_GetLocalVariableTypeName(size_t Adr, size_t Index)\r
1526{\r
f0dd2f7b 1527 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1528 {\r
1529 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1530 {\r
f0dd2f7b 1531 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1532 {\r
1533 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1534 {\r
1535 return PtrCU[i].PtrSubProgs[j].PtrVariables[Index - 1].PtrTypeName;\r
1536 }\r
1537 }\r
1538 }\r
1539 }\r
1540\r
1541 return NULL;\r
1542}\r
1543\r
1544\r
1545// Get Compilation Unit / global variables numbers\r
5fa7aa73 1546// Return number of variables\r
0203b5fd 1547size_t DWARFManager_GetNbGlobalVariables(void)\r
ebcb0f3d 1548{\r
f0dd2f7b 1549 size_t NbVariables = 0;\r
ebcb0f3d 1550\r
f0dd2f7b 1551 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1552 {\r
1553 NbVariables += PtrCU[i].NbVariables;\r
1554 }\r
1555\r
1556 return NbVariables;\r
1557}\r
1558\r
1559\r
f0dd2f7b 1560// Get global variable type name based on his index (starting from 1)\r
ebcb0f3d
JPM
1561// Return NULL if not found\r
1562// May return NULL if there is not type linked to the variable's index\r
0203b5fd 1563char *DWARFManager_GetGlobalVariableTypeName(size_t Index)\r
ebcb0f3d 1564{\r
f0dd2f7b 1565 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1566 {\r
1567 if (PtrCU[i].NbVariables)\r
1568 {\r
1569 if (Index <= PtrCU[i].NbVariables)\r
1570 {\r
1571 return PtrCU[i].PtrVariables[Index - 1].PtrTypeName;\r
1572 }\r
1573 else\r
1574 {\r
1575 Index -= PtrCU[i].NbVariables;\r
1576 }\r
1577 }\r
1578 }\r
1579\r
1580 return NULL;\r
1581}\r
1582\r
1583\r
f0dd2f7b 1584// Get global variable's type tag based on his index (starting from 1)\r
ebcb0f3d 1585// Return 0 if not found\r
0203b5fd 1586size_t DWARFManager_GetGlobalVariableTypeTag(size_t Index)\r
ebcb0f3d 1587{\r
f0dd2f7b 1588 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1589 {\r
1590 if (PtrCU[i].NbVariables)\r
1591 {\r
1592 if (Index <= PtrCU[i].NbVariables)\r
1593 {\r
1594 return PtrCU[i].PtrVariables[Index - 1].TypeTag;\r
1595 }\r
1596 else\r
1597 {\r
1598 Index -= PtrCU[i].NbVariables;\r
1599 }\r
1600 }\r
1601 }\r
1602\r
1603 return 0;\r
1604}\r
1605\r
1606\r
f0dd2f7b 1607// Get global variable byte size based on his index (starting from 1)\r
ebcb0f3d 1608// Return 0 if not found\r
0203b5fd 1609size_t DWARFManager_GetGlobalVariableTypeByteSize(size_t Index)\r
ebcb0f3d 1610{\r
f0dd2f7b 1611 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1612 {\r
1613 if (PtrCU[i].NbVariables)\r
1614 {\r
1615 if (Index <= PtrCU[i].NbVariables)\r
1616 {\r
1617 return PtrCU[i].PtrVariables[Index - 1].TypeByteSize;\r
1618 }\r
1619 else\r
1620 {\r
1621 Index -= PtrCU[i].NbVariables;\r
1622 }\r
1623 }\r
1624 }\r
1625\r
1626 return 0;\r
1627}\r
1628\r
1629\r
f0dd2f7b 1630// Get global variable encoding based on his index (starting from 1)\r
ebcb0f3d 1631// Return 0 if not found\r
0203b5fd 1632size_t DWARFManager_GetGlobalVariableTypeEncoding(size_t Index)\r
ebcb0f3d 1633{\r
f0dd2f7b 1634 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1635 {\r
1636 if (PtrCU[i].NbVariables)\r
1637 {\r
1638 if (Index <= PtrCU[i].NbVariables)\r
1639 {\r
1640 return PtrCU[i].PtrVariables[Index - 1].TypeEncoding;\r
1641 }\r
1642 else\r
1643 {\r
1644 Index -= PtrCU[i].NbVariables;\r
1645 }\r
1646 }\r
1647 }\r
1648\r
1649 return 0;\r
1650}\r
1651\r
1652\r
f0dd2f7b 1653// Get global variable memory address based on his index (starting from 1)\r
ebcb0f3d 1654// Return 0 if not found\r
0203b5fd 1655size_t DWARFManager_GetGlobalVariableAdr(size_t Index)\r
ebcb0f3d 1656{\r
f0dd2f7b 1657 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1658 {\r
1659 if (PtrCU[i].NbVariables)\r
1660 {\r
1661 if (Index <= PtrCU[i].NbVariables)\r
1662 {\r
1663 return PtrCU[i].PtrVariables[Index - 1].Addr;\r
1664 }\r
1665 else\r
1666 {\r
1667 Index -= PtrCU[i].NbVariables;\r
1668 }\r
1669 }\r
1670 }\r
1671\r
1672 return 0;\r
1673}\r
1674\r
1675\r
0203b5fd 1676// Get global variable memory address based on his name\r
5fa7aa73 1677// Return 0 if not found, or will return the first occurence found\r
0203b5fd 1678size_t DWARFManager_GetGlobalVariableAdrFromName(char *VariableName)\r
ebcb0f3d 1679{\r
f0dd2f7b 1680 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1681 {\r
1682 if (PtrCU[i].NbVariables)\r
1683 {\r
f0dd2f7b 1684 for (size_t j = 0; j < PtrCU[i].NbVariables; j++)\r
ebcb0f3d
JPM
1685 {\r
1686 if (!strcmp(PtrCU[i].PtrVariables[j].PtrName,VariableName))\r
1687 {\r
1688 return PtrCU[i].PtrVariables[j].Addr;\r
1689 }\r
1690 }\r
1691 }\r
1692 }\r
1693\r
1694 return 0;\r
1695}\r
1696\r
1697\r
f0dd2f7b 1698// Get global variable name based on his index (starting from 1)\r
5fa7aa73 1699// Return name's pointer text found, or will return NULL if no variable can be found\r
0203b5fd 1700char *DWARFManager_GetGlobalVariableName(size_t Index)\r
ebcb0f3d 1701{\r
f0dd2f7b 1702 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1703 {\r
1704 if (PtrCU[i].NbVariables)\r
1705 {\r
1706 if (Index <= PtrCU[i].NbVariables)\r
1707 {\r
1708 return PtrCU[i].PtrVariables[Index - 1].PtrName;\r
1709 }\r
1710 else\r
1711 {\r
1712 Index -= PtrCU[i].NbVariables;\r
1713 }\r
1714 }\r
1715 }\r
1716\r
1717 return NULL;\r
1718}\r
1719\r
1720\r
1721// Get text line from source based on address and his tag\r
5fa7aa73
JPM
1722// A tag can be either 0 or a DW_TAG_subprogram\r
1723// DW_TAG_subprogram will look for the line pointing to the function\r
ebcb0f3d
JPM
1724// Return NULL if no text line has been found\r
1725char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)\r
1726{\r
f0dd2f7b 1727 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1728 {\r
1729 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1730 {\r
f0dd2f7b 1731 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
ebcb0f3d
JPM
1732 {\r
1733 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1734 {\r
1735 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))\r
1736 {\r
1737 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;\r
1738 }\r
1739 else\r
1740 {\r
f0dd2f7b 1741 for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
ebcb0f3d 1742 {\r
f8dde18d
JPM
1743 if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC <= Adr)\r
1744 {\r
1745 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
1746 {\r
1747 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;\r
1748 }\r
1749 }\r
1750 else\r
ebcb0f3d 1751 {\r
f8dde18d 1752 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k - 1].PtrLineSrc;\r
ebcb0f3d
JPM
1753 }\r
1754 }\r
1755 }\r
1756 }\r
1757 }\r
1758 }\r
1759 }\r
1760\r
1761 return NULL;\r
1762}\r
1763\r
1764\r
5fa7aa73
JPM
1765// Get line number based on the address and a tag\r
1766// A tag can be either 0 or a DW_TAG_subprogram\r
1767// DW_TAG_subprogram will look for the line pointing to the function name as described in the source code\r
ebcb0f3d
JPM
1768// Return 0 if no line number has been found\r
1769size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)\r
1770{\r
f0dd2f7b 1771 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1772 {\r
1773 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1774 {\r
f0dd2f7b 1775 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
ebcb0f3d
JPM
1776 {\r
1777 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1778 {\r
1779 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))\r
1780 {\r
1781 return PtrCU[i].PtrSubProgs[j].NumLineSrc;\r
1782 }\r
1783 else\r
1784 {\r
f0dd2f7b 1785 for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
ebcb0f3d
JPM
1786 {\r
1787 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))\r
1788 {\r
1789 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc;\r
1790 }\r
1791 }\r
1792 }\r
1793#if 0\r
1794 if (!Tag || (Tag == DW_TAG_subprogram))\r
1795 {\r
1796 return PtrCU[i].PtrSubProgs[j].NumLineSrc;\r
1797 }\r
1798#endif\r
1799 }\r
1800 }\r
0536c3ba
JPM
1801\r
1802 // Check if a used line is found with the address\r
1803 for (size_t j = 0; j < PtrCU[i].NbLinesSrc; j++)\r
1804 {\r
1805 if (PtrCU[i].PtrLinesSrc[j].StartPC == Adr)\r
1806 {\r
1807 return PtrCU[i].PtrLinesSrc[j].NumLineSrc;\r
1808 }\r
1809 }\r
ebcb0f3d
JPM
1810 }\r
1811 }\r
1812\r
1813 return 0;\r
1814}\r
1815\r
1816\r
5fa7aa73
JPM
1817// Get function name based on an address\r
1818// Return NULL if no function name has been found, otherwise will return the function name in the range of the provided address\r
0203b5fd
JPM
1819char *DWARFManager_GetFunctionName(size_t Adr)\r
1820{\r
f0dd2f7b 1821 for (size_t i = 0; i < NbCU; i++)\r
0203b5fd
JPM
1822 {\r
1823 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1824 {\r
f0dd2f7b 1825 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
0203b5fd
JPM
1826 {\r
1827 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1828 {\r
1829 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;\r
1830 }\r
1831 }\r
1832 }\r
1833 }\r
1834\r
1835 return NULL;\r
1836}\r
1837\r
1838\r
f0dd2f7b 1839// Get text line from source based on address and num line (starting from 1)\r
ebcb0f3d
JPM
1840// Return NULL if no text line has been found\r
1841char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)\r
1842{\r
f0dd2f7b 1843 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1844 {\r
1845 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1846 {\r
f0dd2f7b 1847 for (size_t j = 0; j < PtrCU[i].NbSubProgs; j++)\r
ebcb0f3d
JPM
1848 {\r
1849 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))\r
1850 {\r
1851 if (PtrCU[i].PtrSubProgs[j].NumLineSrc == NumLine)\r
1852 {\r
1853 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;\r
1854 }\r
1855 else\r
1856 {\r
f0dd2f7b 1857 for (size_t k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)\r
ebcb0f3d
JPM
1858 {\r
1859 if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc == NumLine)\r
1860 {\r
1861 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;\r
1862 }\r
1863 }\r
1864 }\r
1865 }\r
1866 }\r
1867 }\r
1868 }\r
1869\r
1870 return NULL;\r
1871}\r
1872\r
1873\r
f0dd2f7b 1874// Get text line pointer from source, based on address and line number (starting from 1)\r
f795e8ac 1875// Return NULL if no text line has been found, or if requested number line is above the source total number of lines\r
ebcb0f3d
JPM
1876char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)\r
1877{\r
f0dd2f7b 1878 for (size_t i = 0; i < NbCU; i++)\r
ebcb0f3d
JPM
1879 {\r
1880 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))\r
1881 {\r
41d6f5f7
JPM
1882 if (NumLine <= PtrCU[i].NbLinesLoadSrc)\r
1883 {\r
1884 return PtrCU[i].PtrLinesLoadSrc[NumLine - 1];\r
1885 }\r
1886 else\r
1887 {\r
1888 return NULL;\r
1889 }\r
ebcb0f3d
JPM
1890 }\r
1891 }\r
1892\r
1893 return NULL;\r
1894}\r
1895\r
6564336c
JPM
1896\r
1897// Get number of source code filenames\r
1898size_t DWARFManager_GetNbFullSourceFilename(void)\r
1899{\r
1900 return NbCU;\r
1901}\r
1902\r
1903\r
5fa7aa73 1904// Get source code filename based on index (starting from 0)\r
6564336c
JPM
1905char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
1906{\r
1907 return (PtrCU[Index].PtrFullFilename);\r
1908}\r
1909\r