0a3012c1559f937ff80f61ab02612f9f580222e5
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / DWARFManager.cpp
1 //
2 // DWARFManager.cpp: DWARF format manager
3 //
4 // by Jean-Paul Mari
5 //
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 //
8 // WHO WHEN WHAT
9 // --- ---------- ------------------------------------------------------------
10 // JPM 12/03/2016 Created this file
11 // JPM 12/03/2016 DWARF format support
12
13
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <stdint.h>
17 #include <string.h>
18 #include <libdwarf.h>
19 #include <dwarf.h>
20
21
22 // Source line internal structure
23 struct DMIStruct_LineSrc
24 {
25 size_t Tag;
26 size_t StartPC;
27 size_t NumLineSrc;
28 char *PtrLineSrc;
29 }S_DMIStruct_LineSrc;
30
31 // Base type internal structure
32 struct BaseTypeStruct
33 {
34 size_t Tag; // Type's Tag
35 size_t Offset; // Type's offset
36 size_t TypeOffset; // Type's offset on another type
37 size_t ByteSize; // Type's Byte Size
38 size_t Encoding; // Type's encoding
39 char *PtrName; // Type's name
40 }S_BaseTypeStruct;
41
42 // Variables internal structure
43 struct VariablesStruct
44 {
45 size_t Addr; // Variable memory address
46 char *PtrName; // Variable's name
47 size_t TypeOffset; // Offset pointing on the Variable's Type
48 size_t TypeByteSize; // Variable's Type byte size
49 size_t TypeTag; // Variable's Type Tag
50 size_t TypeEncoding; // Variable's Type encoding
51 char *PtrTypeName; // Variable's Type name
52 }S_VariablesStruct;
53
54 // Sub program internal structure
55 struct SubProgStruct
56 {
57 size_t Tag;
58 size_t NumLineSrc;
59 size_t StartPC;
60 size_t LowPC, HighPC;
61 char *PtrLineSrc;
62 char *PtrSubprogramName;
63 size_t NbLinesSrc;
64 DMIStruct_LineSrc *PtrLinesSrc;
65 }S_SubProgStruct;
66
67 // Compilation Unit internal structure
68 struct CUStruct
69 {
70 size_t Tag;
71 size_t LowPC, HighPC;
72 char *PtrProducer; // Pointer to the "Producer" information (compiler and compilation options used)
73 char *PtrFullFilename; // Pointer to full namefile (directory & filename)
74 size_t SizeLoadSrc; // Source code size
75 char *PtrLoadSrc; // Pointer to loaded source code
76 size_t NbLinesLoadSrc; // Lines source number
77 char **PtrLinesLoadSrc; // Pointer lists to each source line put in QT html/text conformity
78 size_t NbSubProgs; // Number of sub programs / routines
79 SubProgStruct *PtrSubProgs; // Pointer to the sub programs / routines information structure
80 size_t NbTypes;
81 BaseTypeStruct *PtrTypes;
82 size_t NbVariables; // Variables number
83 VariablesStruct *PtrVariables; // Pointer to the variables list information structure
84 }S_CUStruct;
85
86
87 // Dwarf management
88 uint32_t LibDwarf;
89 uint32_t NbCU;
90 Dwarf_Ptr errarg;
91 Dwarf_Error error;
92 Dwarf_Debug dbg;
93 CUStruct *PtrCU;
94
95
96 //
97 Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg);
98 void DWARFManager_InitDMI(void);
99 void DWARFManager_CloseDMI(void);
100 bool DWARFManager_ElfClose(void);
101 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine);
102
103
104 //
105 Dwarf_Handler DWARFManager_ErrorHandler(Dwarf_Ptr perrarg)
106 {
107 return 0;
108 }
109
110
111 // Dwarf manager init
112 void DWARFManager_Init(void)
113 {
114 LibDwarf = DW_DLV_NO_ENTRY;
115 }
116
117
118 // Dwarf manager Reset
119 bool DWARFManager_Reset(void)
120 {
121 return DWARFManager_ElfClose();
122 }
123
124
125 // Dwarf manager Close
126 bool DWARFManager_Close(void)
127 {
128 return(DWARFManager_Reset());
129 }
130
131
132 // Dwarf manager Elf init
133 int DWARFManager_ElfInit(Elf *ElfPtr)
134 {
135 if ((LibDwarf = dwarf_elf_init(ElfPtr, DW_DLC_READ, (Dwarf_Handler)DWARFManager_ErrorHandler, errarg, &dbg, &error)) == DW_DLV_OK)
136 {
137 DWARFManager_InitDMI();
138 }
139
140 return LibDwarf;
141 }
142
143
144 // Dwarf manager Elf close
145 bool DWARFManager_ElfClose(void)
146 {
147 if (LibDwarf == DW_DLV_OK)
148 {
149 DWARFManager_CloseDMI();
150
151 if (dwarf_finish(dbg, &error) == DW_DLV_OK)
152 {
153 LibDwarf = DW_DLV_NO_ENTRY;
154 return true;
155 }
156 else
157 {
158 return false;
159 }
160 }
161 else
162 {
163 return true;
164 }
165 }
166
167
168 // Dwarf manager Compilation Units close
169 void DWARFManager_CloseDMI(void)
170 {
171 while (NbCU--)
172 {
173 free(PtrCU[NbCU].PtrFullFilename);
174 free(PtrCU[NbCU].PtrLoadSrc);
175 free(PtrCU[NbCU].PtrProducer);
176
177 while (PtrCU[NbCU].NbLinesLoadSrc--)
178 {
179 free(PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].NbLinesLoadSrc]);
180 }
181 free(PtrCU[NbCU].PtrLinesLoadSrc);
182
183 while (PtrCU[NbCU].NbSubProgs--)
184 {
185 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc);
186 free(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName);
187 }
188 free(PtrCU[NbCU].PtrSubProgs);
189
190 while (PtrCU[NbCU].NbTypes--)
191 {
192 free(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName);
193 }
194 free(PtrCU[NbCU].PtrTypes);
195
196 while (PtrCU[NbCU].NbVariables--)
197 {
198 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName);
199 free(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrTypeName);
200 }
201 free(PtrCU[NbCU].PtrVariables);
202 }
203
204 free(PtrCU);
205 }
206
207
208 // Dwarf manager Compilation Units initialisations
209 void DWARFManager_InitDMI(void)
210 {
211 Dwarf_Unsigned next_cu_header, return_uvalue;
212 Dwarf_Error error;
213 Dwarf_Attribute *atlist;
214 Dwarf_Attribute return_attr1;
215 Dwarf_Half return_tagval, return_attr;
216 Dwarf_Addr return_lowpc, return_highpc, return_lineaddr;
217 Dwarf_Block *return_block;
218 Dwarf_Signed atcnt, cnt;
219 Dwarf_Die return_sib, return_die;
220 Dwarf_Off return_offset;
221 Dwarf_Line *linebuf;
222 FILE *SrcFile;
223 size_t i, j, k, TypeOffset;
224 char *return_string;
225 char *Ptr;
226 char *SourceFilename = NULL;
227 char *SourceFileDirectory = NULL;
228 char *SourceFullFilename = NULL;
229
230 // Initialisation for the Compilation Units table
231 NbCU = 0;
232 PtrCU = NULL;
233
234 // loop on the available Compilation Unit
235 while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &next_cu_header, &error) == DW_DLV_OK)
236 {
237 // Allocation of an additional Compilation Unit structure in the table
238 if (Ptr = (char *)realloc(PtrCU, ((NbCU + 1) * sizeof(CUStruct))))
239 {
240 // Compilation Unit RAZ
241 PtrCU = (CUStruct *)Ptr;
242 memset(PtrCU + NbCU, 0, sizeof(CUStruct));
243
244 // Get 1st Die from the Compilation Unit
245 if (dwarf_siblingof(dbg, NULL, &return_sib, &error) == DW_DLV_OK)
246 {
247 // Get Die's Tag
248 if ((dwarf_tag(return_sib, &return_tagval, &error) == DW_DLV_OK))
249 {
250 PtrCU[NbCU].Tag = return_tagval;
251
252 // Die type detection
253 switch (return_tagval)
254 {
255 case DW_TAG_compile_unit:
256 if (dwarf_attrlist(return_sib, &atlist, &atcnt, &error) == DW_DLV_OK)
257 {
258 for (Dwarf_Signed i = 0; i < atcnt; ++i)
259 {
260 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)
261 {
262 switch (return_attr)
263 {
264 case DW_AT_low_pc:
265 if (dwarf_lowpc(return_sib, &return_lowpc, &error) == DW_DLV_OK)
266 {
267 PtrCU[NbCU].LowPC = return_lowpc;
268 }
269 break;
270
271 case DW_AT_high_pc:
272 if (dwarf_highpc(return_sib, &return_highpc, &error) == DW_DLV_OK)
273 {
274 PtrCU[NbCU].HighPC = return_highpc;
275 }
276 break;
277
278 case DW_AT_producer:
279 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)
280 {
281 PtrCU[NbCU].PtrProducer = (char *)calloc(strlen(return_string) + 1, 1);
282 strcpy(PtrCU[NbCU].PtrProducer, return_string);
283 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);
284 }
285 break;
286
287 case DW_AT_name:
288 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)
289 {
290 SourceFilename = (char *)realloc(SourceFilename, strlen(return_string) + 1);
291 strcpy(SourceFilename, return_string);
292 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);
293 }
294 break;
295
296 case DW_AT_comp_dir:
297 if (dwarf_formstring(atlist[i], &return_string, &error) == DW_DLV_OK)
298 {
299 SourceFileDirectory = (char *)realloc(SourceFileDirectory, strlen(return_string) + 1);
300 strcpy(SourceFileDirectory, return_string);
301 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);
302 }
303 break;
304
305 default:
306 break;
307 }
308 }
309 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
310 }
311 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
312 }
313
314 Ptr = SourceFullFilename = (char *)realloc(SourceFullFilename, strlen(SourceFilename) + strlen(SourceFileDirectory) + 2);
315 sprintf(SourceFullFilename, "%s\\%s", SourceFileDirectory, SourceFilename);
316 while (*Ptr)
317 {
318 if (*Ptr == '/')
319 {
320 *Ptr = '\\';
321 }
322 Ptr++;
323 }
324 PtrCU[NbCU].PtrFullFilename = (char *)calloc(strlen(SourceFullFilename) + 1, 1);
325 strcpy((char *)PtrCU[NbCU].PtrFullFilename, SourceFullFilename);
326
327 #ifndef __CYGWIN__
328 if (!fopen_s(&SrcFile, SourceFullFilename, "rt"))
329 #else
330 if (!(SrcFile = fopen(SourceFullFilename, "rt")))
331 #endif
332 {
333 if (!fseek(SrcFile, 0, SEEK_END))
334 {
335 if ((PtrCU[NbCU].SizeLoadSrc = ftell(SrcFile)) > 0)
336 {
337 if (PtrCU[NbCU].PtrLoadSrc = Ptr = (char *)calloc((PtrCU[NbCU].SizeLoadSrc + 1), 1))
338 {
339 rewind(SrcFile);
340 if (PtrCU[NbCU].SizeLoadSrc < fread(Ptr, 1, PtrCU[NbCU].SizeLoadSrc, SrcFile))
341 {
342 free(PtrCU[NbCU].PtrLoadSrc);
343 PtrCU[NbCU].PtrLoadSrc = NULL;
344 PtrCU[NbCU].SizeLoadSrc = 0;
345 }
346 else
347 {
348 do
349 {
350 if (*Ptr == 0xa)
351 {
352 PtrCU[NbCU].NbLinesLoadSrc++;
353 *Ptr = 0;
354 }
355 } while (*++Ptr);
356 }
357 }
358 }
359 }
360 fclose(SrcFile);
361 }
362 break;
363
364 default:
365 break;
366 }
367 }
368
369 // Get the source lines table located in the Compilation Unit
370 if (dwarf_srclines(return_sib, &linebuf, &cnt, &error) == DW_DLV_OK)
371 {
372 }
373
374 if (dwarf_child(return_sib, &return_die, &error) == DW_DLV_OK)
375 {
376 do
377 {
378 return_sib = return_die;
379 if ((dwarf_tag(return_die, &return_tagval, &error) == DW_DLV_OK))
380 {
381 switch (return_tagval)
382 {
383 case DW_TAG_lexical_block:
384 break;
385
386 case DW_TAG_variable:
387 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)
388 {
389 PtrCU[NbCU].PtrVariables = (VariablesStruct *)realloc(PtrCU[NbCU].PtrVariables, ((PtrCU[NbCU].NbVariables + 1) * sizeof(VariablesStruct)));
390 memset(PtrCU[NbCU].PtrVariables + PtrCU[NbCU].NbVariables, 0, sizeof(VariablesStruct));
391
392 for (Dwarf_Signed i = 0; i < atcnt; ++i)
393 {
394 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)
395 {
396 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)
397 {
398 switch (return_attr)
399 {
400 case DW_AT_location:
401 if (dwarf_formblock(return_attr1, &return_block, &error) == DW_DLV_OK)
402 {
403 if (return_block->bl_len == 5)
404 {
405 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));
406 }
407 dwarf_dealloc(dbg, return_block, DW_DLA_BLOCK);
408 }
409 break;
410
411 case DW_AT_type:
412 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)
413 {
414 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].TypeOffset = return_offset;
415 }
416 break;
417
418 case DW_AT_name:
419 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)
420 {
421 PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName = (char *)calloc(strlen(return_string) + 1, 1);
422 strcpy(PtrCU[NbCU].PtrVariables[PtrCU[NbCU].NbVariables].PtrName, return_string);
423 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);
424 }
425 break;
426
427 default:
428 break;
429 }
430 }
431 }
432
433 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
434 }
435
436 PtrCU[NbCU].NbVariables++;
437
438 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
439 }
440 break;
441
442 case DW_TAG_base_type:
443 case DW_TAG_typedef:
444 case DW_TAG_structure_type:
445 case DW_TAG_pointer_type:
446 case DW_TAG_const_type:
447 case DW_TAG_array_type:
448 case DW_TAG_subrange_type:
449 case DW_TAG_subroutine_type:
450 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)
451 {
452 PtrCU[NbCU].PtrTypes = (BaseTypeStruct *)realloc(PtrCU[NbCU].PtrTypes, ((PtrCU[NbCU].NbTypes + 1) * sizeof(BaseTypeStruct)));
453 memset(PtrCU[NbCU].PtrTypes + PtrCU[NbCU].NbTypes, 0, sizeof(BaseTypeStruct));
454 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Tag = return_tagval;
455
456 if (dwarf_dieoffset(return_die, &return_offset, &error) == DW_DLV_OK)
457 {
458 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Offset = return_offset;
459 }
460
461 for (Dwarf_Signed i = 0; i < atcnt; ++i)
462 {
463 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)
464 {
465 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)
466 {
467 switch (return_attr)
468 {
469 case DW_AT_type:
470 if (dwarf_global_formref(return_attr1, &return_offset, &error) == DW_DLV_OK)
471 {
472 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].TypeOffset = return_offset;
473 }
474 break;
475
476 case DW_AT_byte_size:
477 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)
478 {
479 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].ByteSize = return_uvalue;
480 }
481 break;
482
483 case DW_AT_encoding:
484 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)
485 {
486 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].Encoding = return_uvalue;
487 }
488 break;
489
490 case DW_AT_name:
491 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)
492 {
493 PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName = (char *)calloc(strlen(return_string) + 1, 1);
494 strcpy(PtrCU[NbCU].PtrTypes[PtrCU[NbCU].NbTypes].PtrName, return_string);
495 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);
496 }
497 break;
498
499 default:
500 break;
501 }
502 }
503 }
504
505 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
506 }
507
508 PtrCU[NbCU].NbTypes++;
509
510 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
511 }
512 break;
513
514 case DW_TAG_subprogram:
515 if (dwarf_attrlist(return_die, &atlist, &atcnt, &error) == DW_DLV_OK)
516 {
517 PtrCU[NbCU].PtrSubProgs = (SubProgStruct *)realloc(PtrCU[NbCU].PtrSubProgs, ((PtrCU[NbCU].NbSubProgs + 1) * sizeof(SubProgStruct)));
518 memset((void *)(PtrCU[NbCU].PtrSubProgs + PtrCU[NbCU].NbSubProgs), 0, sizeof(SubProgStruct));
519 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].Tag = return_tagval;
520
521 for (Dwarf_Signed i = 0; i < atcnt; ++i)
522 {
523 if (dwarf_whatattr(atlist[i], &return_attr, &error) == DW_DLV_OK)
524 {
525 if (dwarf_attr(return_die, return_attr, &return_attr1, &error) == DW_DLV_OK)
526 {
527 switch (return_attr)
528 {
529 case DW_AT_low_pc:
530 if (dwarf_lowpc(return_die, &return_lowpc, &error) == DW_DLV_OK)
531 {
532 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].StartPC = return_lowpc;
533 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].LowPC = return_lowpc;
534 }
535 break;
536
537 case DW_AT_high_pc:
538 if (dwarf_highpc(return_die, &return_highpc, &error) == DW_DLV_OK)
539 {
540 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].HighPC = return_highpc;
541 }
542 break;
543
544 case DW_AT_decl_line:
545 if (dwarf_formudata(return_attr1, &return_uvalue, &error) == DW_DLV_OK)
546 {
547 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NumLineSrc = return_uvalue;
548 }
549 break;
550
551 case DW_AT_name:
552 if (dwarf_formstring(return_attr1, &return_string, &error) == DW_DLV_OK)
553 {
554 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName = (char *)calloc(strlen(return_string) + 1, 1);
555 strcpy(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrSubprogramName, return_string);
556 dwarf_dealloc(dbg, return_string, DW_DLA_STRING);
557 }
558 break;
559
560 default:
561 break;
562 }
563 }
564 }
565 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
566 }
567 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
568
569 for (i = 0; i < (size_t)cnt; ++i)
570 {
571 if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)
572 {
573 if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)
574 {
575 if ((return_lineaddr >= return_lowpc) && (return_lineaddr <= return_highpc))
576 {
577 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));
578 memset((void *)(PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc + PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc), 0, sizeof(DMIStruct_LineSrc));
579 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].StartPC = return_lineaddr;
580 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc].NumLineSrc = return_uvalue;
581 PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs].NbLinesSrc++;
582 }
583 }
584 }
585 }
586
587 PtrCU[NbCU].NbSubProgs++;
588 }
589 break;
590
591 default:
592 break;
593 }
594 }
595 }
596 while (dwarf_siblingof(dbg, return_sib, &return_die, &error) == DW_DLV_OK);
597 }
598
599 // Release the memory used by the source lines
600 for (i = 0; i < (size_t)cnt; ++i)
601 dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
602 dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
603 }
604
605 // Set the source code lines for QT html/text conformity
606 if (PtrCU[NbCU].NbLinesLoadSrc)
607 {
608 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(PtrCU[NbCU].NbLinesLoadSrc, sizeof(char *)))
609 {
610 for (j = 0; j < PtrCU[NbCU].NbLinesLoadSrc; j++)
611 {
612 if (PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)calloc(10000, sizeof(char)))
613 {
614 if (Ptr = DWARFManager_GetLineSrcFromNumLine(PtrCU[NbCU].PtrLoadSrc, (j + 1)))
615 {
616 i = 0;
617
618 while (*Ptr)
619 {
620 switch (*Ptr)
621 {
622 case 9:
623 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");
624 i += strlen("&nbsp;");
625 break;
626
627 case '<':
628 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&lt;");
629 i += strlen("&lt;");
630 break;
631
632 case '>':
633 strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&gt;");
634 i += strlen("&gt;");
635 break;
636 #if 0
637 case '&':
638 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&amp;");
639 i += strlen("&amp;");
640 break;
641 #endif
642 #if 0
643 case '"':
644 strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");
645 i += strlen("&quot;");
646 break;
647 #endif
648 default:
649 PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;
650 break;
651 }
652 Ptr++;
653 }
654 }
655 PtrCU[NbCU].PtrLinesLoadSrc[j] = (char *)realloc(PtrCU[NbCU].PtrLinesLoadSrc[j], i + 1);
656 }
657 }
658 }
659 }
660 else
661 {
662 // Set each source lines pointer to NULL
663 if (PtrCU[NbCU].NbSubProgs)
664 {
665 i = PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].PtrLinesSrc[PtrCU[NbCU].PtrSubProgs[PtrCU[NbCU].NbSubProgs - 1].NbLinesSrc - 1].NumLineSrc;
666 if (PtrCU[NbCU].PtrLinesLoadSrc = (char **)calloc(i, sizeof(char *)))
667 {
668 for (j = 0; j < i; j++)
669 {
670 PtrCU[NbCU].PtrLinesLoadSrc[j] = NULL;
671 }
672 }
673 }
674 }
675
676 // Init lines source information based on each source code line numbers
677 for (j = 0; j < PtrCU[NbCU].NbSubProgs; j++)
678 {
679 PtrCU[NbCU].PtrSubProgs[j].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].NumLineSrc - 1];
680
681 for (k = 0; k < PtrCU[NbCU].PtrSubProgs[j].NbLinesSrc; k++)
682 {
683 PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc - 1];
684 }
685 }
686
687 // Init variables information based on types information
688 for (i = 0; i < PtrCU[NbCU].NbVariables; i++)
689 {
690 PtrCU[NbCU].PtrVariables[i].PtrTypeName = (char *)calloc(1000, 1);
691 TypeOffset = PtrCU[NbCU].PtrVariables[i].TypeOffset;
692
693 for (j = 0; j < PtrCU[NbCU].NbTypes; j++)
694 {
695 if (TypeOffset == PtrCU[NbCU].PtrTypes[j].Offset)
696 {
697 switch (PtrCU[NbCU].PtrTypes[j].Tag)
698 {
699 case DW_TAG_structure_type:
700 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x1;
701 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
702 {
703 j = -1;
704 }
705 else
706 {
707 if ((PtrCU[NbCU].PtrVariables[i].TypeTag & 0x2))
708 {
709 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, " *");
710 }
711 }
712 break;
713
714 case DW_TAG_pointer_type:
715 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x2;
716 PtrCU[NbCU].PtrVariables[i].TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;
717 PtrCU[NbCU].PtrVariables[i].TypeEncoding = 0x10;
718 if (!(TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
719 {
720 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, "void *");
721 }
722 else
723 {
724 j = -1;
725 }
726 break;
727
728 case DW_TAG_typedef:
729 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x20;
730 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);
731 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
732 {
733 j = -1;
734 }
735 break;
736
737 case DW_TAG_subrange_type:
738 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x4;
739 break;
740
741 case DW_TAG_array_type:
742 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x8;
743 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
744 {
745 j = -1;
746 }
747 break;
748
749 case DW_TAG_const_type:
750 PtrCU[NbCU].PtrVariables[i].TypeTag |= 0x10;
751 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, "const ");
752 if ((TypeOffset = PtrCU[NbCU].PtrTypes[j].TypeOffset))
753 {
754 j = -1;
755 }
756 break;
757
758 case DW_TAG_base_type:
759 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, PtrCU[NbCU].PtrTypes[j].PtrName);
760 if ((PtrCU[NbCU].PtrVariables[i].TypeTag & 0x2))
761 {
762 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, " *");
763 }
764 else
765 {
766 PtrCU[NbCU].PtrVariables[i].TypeByteSize = PtrCU[NbCU].PtrTypes[j].ByteSize;
767 PtrCU[NbCU].PtrVariables[i].TypeEncoding = PtrCU[NbCU].PtrTypes[j].Encoding;
768 }
769 if ((PtrCU[NbCU].PtrVariables[i].TypeTag & 0x8))
770 {
771 strcat(PtrCU[NbCU].PtrVariables[i].PtrTypeName, "[]");
772 }
773 break;
774
775 default:
776 break;
777 }
778 }
779 }
780 }
781
782 ++NbCU;
783 }
784 }
785
786 free(SourceFilename);
787 free(SourceFileDirectory);
788 free(SourceFullFilename);
789 }
790
791
792 // Get symbol name based from address
793 // Return NULL if no symbol name exists
794 char *DWARFManager_GetSymbolnameFromAdr(size_t Adr)
795 {
796 size_t i, j;
797
798 for (i = 0; i < NbCU; i++)
799 {
800 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
801 {
802 for (j = 0; (j < PtrCU[i].NbSubProgs); j++)
803 {
804 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr))
805 {
806 return PtrCU[i].PtrSubProgs[j].PtrSubprogramName;
807 }
808 }
809 }
810 }
811
812 return NULL;
813 }
814
815
816 // Get complete source filename based from address
817 // Return NULL if no source filename exists
818 // Return the existence status (true or false) in Error
819 char *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error)
820 {
821 size_t i;
822
823 for (i = 0; i < NbCU; i++)
824 {
825 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
826 {
827 *Error = PtrCU[i].PtrLoadSrc ? true : false;
828 return PtrCU[i].PtrFullFilename;
829 }
830 }
831
832 return NULL;
833 }
834
835
836 // Get text line source based on line number (starting by 1)
837 // Return NULL if no text line exists or if line number is 0
838 char *DWARFManager_GetLineSrcFromNumLine(char *PtrSrcFile, size_t NumLine)
839 {
840 size_t i = 0;
841 char *PtrLineSrc = NULL;
842
843 if (PtrSrcFile)
844 {
845 while (i != NumLine)
846 {
847 PtrLineSrc = PtrSrcFile;
848 while (*PtrSrcFile++);
849 i++;
850 }
851 }
852
853 return PtrLineSrc;
854 }
855
856
857 // Get Compilation Unit / External variables numbers
858 // Return variables number
859 size_t DWARFManager_GetNbExternalVariables(void)
860 {
861 size_t NbVariables = 0, i;
862
863 for (i = 0; i < NbCU; i++)
864 {
865 NbVariables += PtrCU[i].NbVariables;
866 }
867
868 return NbVariables;
869 }
870
871
872 // Get external variable type name based on his index (starting by 1)
873 // Return NULL if not found
874 // May return NULL if there is not type linked to the variable's index
875 char *DWARFManager_GetExternalVariableTypeName(size_t Index)
876 {
877 size_t i;
878
879 for (i = 0; i < NbCU; i++)
880 {
881 if (PtrCU[i].NbVariables)
882 {
883 if (Index <= PtrCU[i].NbVariables)
884 {
885 return PtrCU[i].PtrVariables[Index - 1].PtrTypeName;
886 }
887 else
888 {
889 Index -= PtrCU[i].NbVariables;
890 }
891 }
892 }
893
894 return NULL;
895 }
896
897
898 // Get external variable's type tag based on his index (starting by 1)
899 // Return 0 if not found
900 size_t DWARFManager_GetExternalVariableTypeTag(size_t Index)
901 {
902 size_t i;
903
904 for (i = 0; i < NbCU; i++)
905 {
906 if (PtrCU[i].NbVariables)
907 {
908 if (Index <= PtrCU[i].NbVariables)
909 {
910 return PtrCU[i].PtrVariables[Index - 1].TypeTag;
911 }
912 else
913 {
914 Index -= PtrCU[i].NbVariables;
915 }
916 }
917 }
918
919 return 0;
920 }
921
922
923 // Get external variable byte size based on his index (starting by 1)
924 // Return 0 if not found
925 size_t DWARFManager_GetExternalVariableTypeByteSize(size_t Index)
926 {
927 size_t i;
928
929 for (i = 0; i < NbCU; i++)
930 {
931 if (PtrCU[i].NbVariables)
932 {
933 if (Index <= PtrCU[i].NbVariables)
934 {
935 return PtrCU[i].PtrVariables[Index - 1].TypeByteSize;
936 }
937 else
938 {
939 Index -= PtrCU[i].NbVariables;
940 }
941 }
942 }
943
944 return 0;
945 }
946
947
948 // Get external variable encoding based on his index (starting by 1)
949 // Return 0 if not found
950 size_t DWARFManager_GetExternalVariableTypeEncoding(size_t Index)
951 {
952 size_t i;
953
954 for (i = 0; i < NbCU; i++)
955 {
956 if (PtrCU[i].NbVariables)
957 {
958 if (Index <= PtrCU[i].NbVariables)
959 {
960 return PtrCU[i].PtrVariables[Index - 1].TypeEncoding;
961 }
962 else
963 {
964 Index -= PtrCU[i].NbVariables;
965 }
966 }
967 }
968
969 return 0;
970 }
971
972
973 // Get external variable address based on his index (starting by 1)
974 // Return 0 if not found
975 size_t DWARFManager_GetExternalVariableAdr(size_t Index)
976 {
977 size_t i;
978
979 for (i = 0; i < NbCU; i++)
980 {
981 if (PtrCU[i].NbVariables)
982 {
983 if (Index <= PtrCU[i].NbVariables)
984 {
985 return PtrCU[i].PtrVariables[Index - 1].Addr;
986 }
987 else
988 {
989 Index -= PtrCU[i].NbVariables;
990 }
991 }
992 }
993
994 return 0;
995 }
996
997
998 // Get external variable memory address based on his name
999 // Return 0 if not found
1000 // Note: Return the first occurence found
1001 size_t DWARFManager_GetExternalVariableAdrFromName(char *VariableName)
1002 {
1003 size_t i, j;
1004
1005 for (i = 0; i < NbCU; i++)
1006 {
1007 if (PtrCU[i].NbVariables)
1008 {
1009 for (j = 0; j < PtrCU[i].NbVariables; j++)
1010 {
1011 if (!strcmp(PtrCU[i].PtrVariables[j].PtrName,VariableName))
1012 {
1013 return PtrCU[i].PtrVariables[j].Addr;
1014 }
1015 }
1016 }
1017 }
1018
1019 return 0;
1020 }
1021
1022
1023 // Get external variable name based on his index (starting by 1)
1024 // Return name's pointer text found
1025 // Return NULL if not found
1026 char *DWARFManager_GetExternalVariableName(size_t Index)
1027 {
1028 size_t i;
1029
1030 for (i = 0; i < NbCU; i++)
1031 {
1032 if (PtrCU[i].NbVariables)
1033 {
1034 if (Index <= PtrCU[i].NbVariables)
1035 {
1036 return PtrCU[i].PtrVariables[Index - 1].PtrName;
1037 }
1038 else
1039 {
1040 Index -= PtrCU[i].NbVariables;
1041 }
1042 }
1043 }
1044
1045 return NULL;
1046 }
1047
1048
1049 // Get text line from source based on address and his tag
1050 // Return NULL if no text line has been found
1051 char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag)
1052 {
1053 size_t i, j, k;
1054
1055 for (i = 0; i < NbCU; i++)
1056 {
1057 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1058 {
1059 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1060 {
1061 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1062 {
1063 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))
1064 {
1065 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;
1066 }
1067 else
1068 {
1069 for (k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)
1070 {
1071 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))
1072 {
1073 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;
1074 }
1075 }
1076 }
1077 }
1078 }
1079 }
1080 }
1081
1082 return NULL;
1083 }
1084
1085
1086 // Get line number based on the address and the tag
1087 // Return 0 if no line number has been found
1088 size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
1089 {
1090 size_t i, j, k;
1091
1092 for (i = 0; i < NbCU; i++)
1093 {
1094 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1095 {
1096 for (j = 0; (j < PtrCU[i].NbSubProgs); j++)
1097 {
1098 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1099 {
1100 if ((PtrCU[i].PtrSubProgs[j].StartPC == Adr) && (!Tag || (Tag == DW_TAG_subprogram)))
1101 {
1102 return PtrCU[i].PtrSubProgs[j].NumLineSrc;
1103 }
1104 else
1105 {
1106 for (k = 0; (k < PtrCU[i].PtrSubProgs[j].NbLinesSrc); k++)
1107 {
1108 if ((PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].StartPC == Adr) && (!Tag || (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].Tag == Tag)))
1109 {
1110 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc;
1111 }
1112 }
1113 }
1114 #if 0
1115 if (!Tag || (Tag == DW_TAG_subprogram))
1116 {
1117 return PtrCU[i].PtrSubProgs[j].NumLineSrc;
1118 }
1119 #endif
1120 }
1121 }
1122 }
1123 }
1124
1125 return 0;
1126 }
1127
1128
1129 // Get text line from source based on address and num line (starting by 1)
1130 // Return NULL if no text line has been found
1131 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)
1132 {
1133 size_t i, j, k;
1134
1135 for (i = 0; i < NbCU; i++)
1136 {
1137 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1138 {
1139 for (j = 0; j < PtrCU[i].NbSubProgs; j++)
1140 {
1141 if ((Adr >= PtrCU[i].PtrSubProgs[j].LowPC) && (Adr < PtrCU[i].PtrSubProgs[j].HighPC))
1142 {
1143 if (PtrCU[i].PtrSubProgs[j].NumLineSrc == NumLine)
1144 {
1145 return PtrCU[i].PtrSubProgs[j].PtrLineSrc;
1146 }
1147 else
1148 {
1149 for (k = 0; k < PtrCU[i].PtrSubProgs[j].NbLinesSrc; k++)
1150 {
1151 if (PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].NumLineSrc == NumLine)
1152 {
1153 return PtrCU[i].PtrSubProgs[j].PtrLinesSrc[k].PtrLineSrc;
1154 }
1155 }
1156 }
1157 }
1158 }
1159 }
1160 }
1161
1162 return NULL;
1163 }
1164
1165
1166 // Get text line from source based on address and num line (starting by 1)
1167 // Return NULL if no text line has been found
1168 char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)
1169 {
1170 size_t i;
1171
1172 for (i = 0; i < NbCU; i++)
1173 {
1174 if ((Adr >= PtrCU[i].LowPC) && (Adr < PtrCU[i].HighPC))
1175 {
1176 return PtrCU[i].PtrLinesLoadSrc[NumLine - 1];
1177 }
1178 }
1179
1180 return NULL;
1181 }
1182