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