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