OSDN Git Service

0b15e1110a443499bbdac0d1cd47ff0176f162f1
[drdeamon64/drdeamon64.git] / libgoblin / drd64_libgoblin_dwarf_info.c
1 /*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
2
3                          D r . D e a m o n  6 4
4                         for INTEL64(R), AMD64(R)
5         
6    Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10
11  1. Redistributions of source code must retain the above copyright notice,
12     this list of conditions and the following disclaimer.
13  2. Redistributions in binary form must reproduce the above copyright
14     notice, this list of conditions and the following disclaimer in the
15     documentation and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY Koine Yuusuke(koinec) ``AS IS'' AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL Koine Yuusuke(koinec) OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
30
31 /* File Info -----------------------------------------------------------
32 File: drd64_.c
33 Function: 
34 Comment: 
35 ----------------------------------------------------------------------*/
36
37 #define DRD64_SRC_LIBGOBLIN_DWARF_INFO
38 #include"drd64_libgoblin.h"
39
40 /*----------------------------------------------------------------------
41 ----------------------------------------------------------------------*/
42 Byte *
43         DWARF_Info_ReadFormat_Ref_inCU(
44                 LibGoblin_DWARF_DIEValue        *p_val,
45                 Byte    *pb_src, 
46                 QWord   *pqw_remain,
47                 Byte    b_bytes,
48                 Byte    *pb_custart )
49 {
50         Byte    b_size;
51         Word    w_size;
52         DWord   dw_size;
53         QWord   qw_size;
54
55         assert( NULL != pb_src );
56         assert( NULL != p_val );
57
58         if( 1 == b_bytes )      {
59                 pb_src  = DWARF_Common_Read_Byte( &b_size, pb_src, pqw_remain );
60                 qw_size = (QWord)b_size;
61         }
62         else if( 2 == b_bytes ) {
63                 pb_src  = DWARF_Common_Read_Word( &w_size, pb_src, pqw_remain );
64                 qw_size = (QWord)w_size;
65         }
66         else if( 4 == b_bytes ) {
67                 pb_src  = DWARF_Common_Read_DWord( &dw_size, pb_src, pqw_remain );
68                 qw_size = (QWord)dw_size;
69         }
70         else if( 8 == b_bytes ) {
71                 pb_src  = DWARF_Common_Read_QWord( &qw_size, pb_src, pqw_remain );
72         }
73         else    {
74                 pb_src  = DWARF_Common_DecodeULEB128( &qw_size, pb_src, pqw_remain );
75         }
76         if( NULL == pb_src )    { return NULL; }
77
78         p_val->value.pb_link    = pb_custart + qw_size;
79         p_val->b_type                   = LIBGOBLIN_DWARF_INFO_TYPE_LINK;
80         p_val->qw_size                  = (QWord)b_bytes;
81         
82         return pb_src;
83 }
84
85
86 /*----------------------------------------------------------------------
87 ----------------------------------------------------------------------*/
88 Byte *
89         DWARF_Info_ReadFormat_Block(
90                 LibGoblin_DWARF_DIEValue        *p_val,
91                 Byte    *pb_src, 
92                 QWord   *pqw_remain,
93                 int             i_sizebytes )
94 {
95         Byte    b_size;
96         Word    w_size;
97         DWord   dw_size;
98         QWord   qw_size;
99
100         assert( NULL != pb_src );
101         assert( NULL != p_val );
102
103         if( 1 == i_sizebytes )  {
104                 pb_src  = DWARF_Common_Read_Byte( &b_size, pb_src, pqw_remain );
105                 qw_size = (QWord)b_size;
106         }
107         else if( 2 == i_sizebytes )     {
108                 pb_src  = DWARF_Common_Read_Word( &w_size, pb_src, pqw_remain );
109                 qw_size = (QWord)w_size;
110         }
111         else if( 4 == i_sizebytes )     {
112                 pb_src  = DWARF_Common_Read_DWord( &dw_size, pb_src, pqw_remain );
113                 qw_size = (QWord)dw_size;
114         }
115         else if( 8 == i_sizebytes )     {
116                 pb_src  = DWARF_Common_Read_QWord( &qw_size, pb_src, pqw_remain );
117         }
118         else    {
119                 pb_src  = DWARF_Common_DecodeULEB128( &qw_size, pb_src, pqw_remain );
120         }
121
122         if( *pqw_remain >= qw_size )    {
123                 p_val->qw_size                  = qw_size;
124                 p_val->value.pb_data    = pb_src;
125                 p_val->b_type                   = LIBGOBLIN_DWARF_INFO_TYPE_BLOCK;
126                 pb_src                                  += qw_size;
127                 *pqw_remain                             -= qw_size;
128         }
129         else    { pb_src        = NULL; }
130
131         return pb_src;
132 }
133
134 /*----------------------------------------------------------------------
135 ----------------------------------------------------------------------*/
136 Byte *
137         DWARF_Info_ReadFormat_Strp(
138                 LibGoblin_DWARF_DIEValue        *p_val,
139                 Byte    *pb_src, 
140                 QWord   *pqw_remain,
141                 LibGoblin_BinaryInfo    *p_binfo,
142                 Byte    b_bits )
143 {
144         Byte    *pb_string      = NULL;
145         QWord   qw_offset;
146         DWord   dw_offset;
147         LibGoblin_SectionInfo   *psec_dbgstr;
148
149         assert( NULL != pb_src );
150         assert( NULL != p_val );
151
152         psec_dbgstr     = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_STR );
153         assert( NULL != psec_dbgstr );
154         assert( NULL != psec_dbgstr->pb_data );
155
156         if( 8 == b_bits )       {
157                 pb_src          = DWARF_Common_Read_QWord( &qw_offset, pb_src, pqw_remain );
158                 pb_string       = psec_dbgstr->pb_data + qw_offset;
159         }
160         else if( 4 == b_bits )  {
161                 pb_src  = DWARF_Common_Read_DWord( &dw_offset, pb_src, pqw_remain );
162                 pb_string       = psec_dbgstr->pb_data + dw_offset;
163         }
164
165         p_val->value.pstr_value = (char *)pb_string;
166         p_val->b_type                   = LIBGOBLIN_DWARF_INFO_TYPE_STRING;
167         p_val->qw_size                  = 0;
168
169         return pb_src;
170 }
171
172
173 /*----------------------------------------------------------------------
174 ----------------------------------------------------------------------*/
175 Byte *
176         DWARF_Info_ReadFormat_String(
177                 LibGoblin_DWARF_DIEValue        *p_val,
178                 Byte    *pb_src, 
179                 QWord   *pqw_remain )
180 {
181         Byte    *pb_now;
182         QWord   qw_size = 0;
183
184         assert( NULL != pb_src );
185         assert( NULL != p_val );
186
187         pb_now  = pb_src;
188
189         while( (0 < *pqw_remain) && ('\0' != *pb_now) ) {
190                 pb_now++;
191                 qw_size++;
192                 (*pqw_remain)--;
193         }
194
195         if( 0 < *pqw_remain )   {
196                 p_val->value.pstr_value = (char *)pb_src;
197                 p_val->b_type                   = LIBGOBLIN_DWARF_INFO_TYPE_STRING;
198                 p_val->qw_size                  = qw_size;
199
200                 pb_now++;
201                 (*pqw_remain)--;
202         }
203
204         return pb_now;
205 }
206
207
208 /*----------------------------------------------------------------------
209 ----------------------------------------------------------------------*/
210 Byte *
211         DWARF_Info_ReadFormat_Address(
212                 LibGoblin_DWARF_DIEValue        *p_val,
213                 Byte    *pb_src, 
214                 QWord   *pqw_remain,
215                 Byte    b_pointersize )
216 {
217         assert( NULL != pb_src );
218         assert( NULL != p_val );
219
220         if( 8 == b_pointersize )        {
221                 pb_src  = DWARF_Common_Read_QWord(
222                                                 &(p_val->value.qw_value), pb_src, pqw_remain );
223                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
224                 p_val->qw_size  = 8;
225         }
226         else if( 4 == b_pointersize )   {
227                 pb_src  = DWARF_Common_Read_DWord(
228                                                 &(p_val->value.dw_value), pb_src, pqw_remain );
229                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
230                 p_val->qw_size  = 4;
231         }
232         else if( 2 == b_pointersize )   {
233                 pb_src  = DWARF_Common_Read_Word(
234                                                 &(p_val->value.w_value), pb_src, pqw_remain );
235                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
236                 p_val->qw_size  = 2;
237         }
238
239         return pb_src;
240 }
241
242
243 /*----------------------------------------------------------------------
244 ----------------------------------------------------------------------*/
245 Byte *
246         DWARF_Info_ReadFormat_Offset(
247                 LibGoblin_DWARF_DIEValue        *p_val,
248                 Byte    *pb_src, 
249                 QWord   *pqw_remain,
250                 LibGoblin_BinaryInfo    *p_binfo,
251                 Byte    b_bits )
252 {
253         assert( NULL != pb_src );
254         assert( NULL != p_val );
255
256         if( 8 == b_bits )       {
257                 pb_src  = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_src, pqw_remain );
258                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
259                 p_val->qw_size  = 8;
260         }
261         else if( 4 == b_bits )  {
262                 pb_src  = DWARF_Common_Read_DWord( &(p_val->value.dw_value), pb_src, pqw_remain );
263                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
264                 p_val->qw_size  = 4;
265         }
266
267         return pb_src;
268 }
269
270
271 /*----------------------------------------------------------------------
272 ----------------------------------------------------------------------*/
273 Byte *
274         DWARF_Info_ReadFormat_InDirect(
275                 LibGoblin_DWARF_DIEValue        *p_val,
276                 Byte    *pb_info,
277                 QWord   *pqw_remains,
278                 LibGoblin_BinaryInfo    *p_binfo,
279                 LibGoblin_DWARF_Info_CUHeader   *p_cuheader )
280 {
281         QWord   qw_size;
282         DWord   dw_form;
283
284         // Get InDirect DW_FORM_*** value. ---
285         pb_info = DWARF_Common_DecodeULEB128( &qw_size, pb_info, pqw_remains );
286         dw_form = (DWord)qw_size;
287
288         // Re-Call Read FormatData Function ---
289         pb_info = DWARF_Info_ReadFormat_Data(
290                                                 p_val, pb_info, pqw_remains, dw_form, p_binfo, p_cuheader );
291
292         return pb_info;
293 }
294
295
296 /*----------------------------------------------------------------------
297 ----------------------------------------------------------------------*/
298 Byte *
299         DWARF_Info_ReadFormat_Data(
300                 LibGoblin_DWARF_DIEValue        *p_val,
301                 Byte    *pb_info,
302                 QWord   *pqw_remains,
303                 DWord   dw_format,
304                 LibGoblin_BinaryInfo    *p_binfo,
305                 LibGoblin_DWARF_Info_CUHeader   *p_cuheader )
306 {
307         switch( dw_format )     {
308                 case DW_FORM_addr:              // 0x01: address
309                         pb_info = DWARF_Info_ReadFormat_Address(
310                                                                 p_val, pb_info, pqw_remains, p_cuheader->b_pointersize ); 
311                         break;
312                 case DW_FORM_block2:    // 0x03: block
313                         pb_info = DWARF_Info_ReadFormat_Block( p_val, pb_info, pqw_remains, 2);
314                         break;
315                 case DW_FORM_block4:    // 0x04: block
316                         pb_info = DWARF_Info_ReadFormat_Block( p_val, pb_info, pqw_remains, 4);
317                         break;
318                 case DW_FORM_data2:             // 0x05: const.
319                         pb_info = DWARF_Common_Read_Word( &(p_val->value.w_value), pb_info, pqw_remains );
320                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
321                         p_val->qw_size  = 2;
322                         break;
323                 case DW_FORM_data4:             // 0x06: const. line/loc/mac/rng-ptr
324                         pb_info = DWARF_Common_Read_DWord( &(p_val->value.dw_value), pb_info, pqw_remains );
325                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
326                         p_val->qw_size  = 4;
327                         break;
328                 case DW_FORM_data8:             // 0x07: const. line/loc/mac/rng-ptr
329                         pb_info = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_info, pqw_remains );
330                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
331                         p_val->qw_size  = 8;
332                         break;
333                 case DW_FORM_string:    // 0x08: string
334                         pb_info = DWARF_Info_ReadFormat_String( p_val, pb_info, pqw_remains );
335                         break;
336                 case DW_FORM_block:             // 0x09: block
337                         pb_info = DWARF_Info_ReadFormat_Block( p_val, pb_info, pqw_remains, -1);
338                         break;
339                 case DW_FORM_block1:    // 0x0a: block
340                         pb_info = DWARF_Info_ReadFormat_Block( p_val, pb_info, pqw_remains, 1);
341                         break;
342                 case DW_FORM_data1:             // 0x0b: const.
343                         pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
344                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
345                         p_val->qw_size  = 1;
346                         break;
347                 case DW_FORM_flag:              // 0x0c: flag
348                         pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
349                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
350                         p_val->qw_size  = 1;
351                         break;
352                 case DW_FORM_sdata:             // 0x0d: sdata
353                         pb_info = DWARF_Common_DecodeLEB128( &(p_val->value.ii_value), pb_info, pqw_remains );
354                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_INT64;
355                         p_val->qw_size  = 8;
356                         break;
357                 case DW_FORM_strp:              // 0x0e: string (in .debug_str section)
358                         pb_info = DWARF_Info_ReadFormat_Strp(
359                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
360                         break;
361                 case DW_FORM_udata:             // 0x0f: const.
362                         pb_info = DWARF_Common_DecodeULEB128( &(p_val->value.qw_value), pb_info, pqw_remains );
363                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
364                         p_val->qw_size  = 8;
365                         break;
366                 case DW_FORM_ref_addr:  // 0x10: ref.
367                         pb_info = DWARF_Info_ReadFormat_Address(
368                                                                 p_val, pb_info, pqw_remains, p_cuheader->b_pointersize ); 
369                         break;
370                 case DW_FORM_ref1:              // 0x11: ref.
371                         pb_info = DWARF_Info_ReadFormat_Ref_inCU(
372                                                                 p_val, pb_info, pqw_remains, 1, p_cuheader->pb_custart );
373                         break;
374                 case DW_FORM_ref2:              // 0x12: ref.
375                         pb_info = DWARF_Info_ReadFormat_Ref_inCU(
376                                                                 p_val, pb_info, pqw_remains, 2, p_cuheader->pb_custart );
377                         break;
378                 case DW_FORM_ref4:              // 0x13: ref.
379                         pb_info = DWARF_Info_ReadFormat_Ref_inCU(
380                                                                 p_val, pb_info, pqw_remains, 4, p_cuheader->pb_custart );
381                         break;
382                 case DW_FORM_ref8:              // 0x14: ref.
383                         pb_info = DWARF_Info_ReadFormat_Ref_inCU(
384                                                                 p_val, pb_info, pqw_remains, 8, p_cuheader->pb_custart );
385                         break;
386                 case DW_FORM_ref_udata: // 0x15: ref.
387                         pb_info = DWARF_Info_ReadFormat_Ref_inCU(
388                                                                 p_val, pb_info, pqw_remains, -1, p_cuheader->pb_custart );
389                         break;
390                 case DW_FORM_indirect:  // 0x16: ref.
391                         pb_info = DWARF_Info_ReadFormat_InDirect(
392                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader );
393                         break;
394                 case DW_FORM_sec_offset:        // 0x17:
395                         // offset from the beginning of the .debug_line section
396                         //  to the first byte of the data making up the line number list for the compilation unit.
397                         // 1: const. value (size: offsetsize)
398                         pb_info = DWARF_Info_ReadFormat_Offset(
399                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
400                         break;
401                 case DW_FORM_exprloc:           // 0x18:
402                         // 1: uLEB128 = length
403                         // 2: info. bytes specified by the length(1:) (DWARF expression)
404                         pb_info = DWARF_Info_ReadFormat_Block( p_val, pb_info, pqw_remains, -1);
405                         break;
406                 case DW_FORM_flag_present:      // 0x19:
407                         // have NONE value because implicitly flag is TRUE.
408                         //   => NONE Proc.
409                         break;
410                 case DW_FORM_ref_sig8:          // 0x20:
411                         // 1: pointer (8byte)
412                         pb_info = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_info, pqw_remains );
413                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
414                         p_val->qw_size  = 8;
415                         break;
416                 case DW_FORM_GNU_ref_alt:       // 0x1f20:
417                         pb_info = DWARF_Info_ReadFormat_Offset(
418                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
419                         break;
420                 case DW_FORM_GNU_strp_alt:      // 0x1f21:
421                         pb_info = DWARF_Info_ReadFormat_Offset(
422                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
423                         break;
424                 default:
425                         break;
426         }
427
428         return pb_info;
429 }
430
431
432 /*----------------------------------------------------------------------
433 ----------------------------------------------------------------------*/
434 Byte *
435         DWARF_Info_ReadCUHeader(
436                 LibGoblin_DWARF_Info_CUHeader   *p_cuhead,
437                 Byte    *pb_info,
438                 QWord   *pqw_size_info )
439 {
440         int             i_bitflag;
441         int             i_readbytes;
442         DWord   dw_dword;
443         QWord   qw_qword;
444
445         assert( NULL != p_cuhead );
446         assert( NULL != pb_info );
447
448         i_readbytes     = 0;
449         i_bitflag       = 32;
450
451         // Read unit_length (4Byte + 8Byte(64bit)) ---
452         pb_info = DWARF_Common_Read_DWord( &dw_dword, pb_info, pqw_size_info );
453         if( NULL == pb_info )   { return NULL; }
454
455         //     64bit - First 4Byte = 0xffffffff
456         if( ((DWord)0xffffffff) == dw_dword )   {
457                 pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
458                 if( NULL == pb_info )   { return NULL; }
459
460                 p_cuhead->qw_unitsize   = (QWord)qw_qword;
461                 i_bitflag                               = 64;
462                 p_cuhead->b_bits                = 64;
463                 p_cuhead->b_offsetsize  = 8;
464         }
465         //     32bit - First 4Byte = value.
466         else    {
467                 p_cuhead->qw_unitsize   = (QWord)dw_dword;
468                 p_cuhead->b_bits                = 32;
469                 p_cuhead->b_offsetsize  = 4;
470         }
471
472         // Read version (2Byte) ---
473         pb_info = DWARF_Common_Read_Word( &(p_cuhead->w_version), pb_info, pqw_size_info );
474         if( NULL == pb_info )   { return NULL; }
475         i_readbytes     = 2;
476
477         // Read abbrev_offset (4Byte(32bit), 8Byte(64bit)) ---
478         if( 64 == i_bitflag )   {
479                 pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
480                 if( NULL == pb_info )   { return NULL; }
481                 i_readbytes     += 8;
482
483                 p_cuhead->qw_abbrev_offset      = qw_qword;
484         }
485         else    {
486                 pb_info = DWARF_Common_Read_DWord( &dw_dword, pb_info, pqw_size_info );
487                 if( NULL == pb_info )   { return NULL; }
488                 i_readbytes     += 4;
489
490                 p_cuhead->qw_abbrev_offset      = (QWord)dw_dword;
491         }
492
493         // Read address_size (1Byte) ---
494         pb_info = DWARF_Common_Read_Byte( &(p_cuhead->b_pointersize), pb_info, pqw_size_info);
495         if( NULL == pb_info )   { return NULL; }
496         i_readbytes     += 1;
497
498         p_cuhead->qw_unitsize   -= i_readbytes;
499
500         // for DWARF4 ---
501         if( 4 == p_cuhead->w_version )  {
502                 // Read type-signature (8Byte) ---
503                 pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
504                 if( NULL == pb_info )   { return NULL; }
505                 i_readbytes     += 8;
506
507                 p_cuhead->qw_type_signature     = qw_qword;
508
509                 // Read type_offset (4Byte(32bit), 8Byte(64bit)) ---
510                 if( 64 == i_bitflag )   {
511                         pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
512                         if( NULL == pb_info )   { return NULL; }
513                         i_readbytes     += 8;
514
515                         p_cuhead->qw_type_offset        = qw_qword;
516                 }
517                 else    {
518                         pb_info = DWARF_Common_Read_DWord( &dw_dword, pb_info, pqw_size_info );
519                         if( NULL == pb_info )   { return NULL; }
520                         i_readbytes     += 4;
521
522                         p_cuhead->qw_type_offset        = (QWord)dw_dword;
523                 }
524
525         }
526         
527         return pb_info;
528 }
529
530
531 /*----------------------------------------------------------------------
532 ----------------------------------------------------------------------*/
533 LibGoblin_SrcFile *
534         DWARF_Info_RegistSrcFile_fromTagCompileUnit(
535                 LibGoblin_BinaryInfo    *p_binfo,
536                 LibGoblin_BinaryFile    *p_bfile,
537                 Byte                                    *pb_info,
538                 DWARF_AbbrevEntry               *p_abbrev,
539                 QWord                                   qw_size_cu,
540                 LibGoblin_DWARF_Info_CUHeader   *pt_cuheader )
541 {
542         int                                                     i_childlv;
543         int                                                     i_cnt;
544         char                                            *pstr_srcpath   = NULL;
545         char                                            str_temp[DRD64_MAX_PATH+1];
546         DWord                                           dw_arvid;
547         DWord                                           dw_attribute;
548         DWord                                           dw_format;
549         QWord                                           qw_temp;
550         DWARF_AbbrevEntry                       *p_arvnow;
551         LibGoblin_DWARF_DIEValue        *p_infoval;
552         LibGoblin_DWARF_DIEValue        *p_val;
553         LibGoblin_SrcFile                       *p_srcfile;
554
555         assert( NULL != p_binfo );
556         assert( NULL != p_bfile );
557
558         p_infoval       = p_binfo->dwarf.p_infoval;
559         i_childlv       = 0;
560         do      {
561                 // Read Reference Abbrev-ID ---
562                 pb_info = DWARF_Common_DecodeULEB128( &qw_temp, pb_info, &qw_size_cu );
563                 dw_arvid        = (DWord)qw_temp;
564
565                 if( 0 == dw_arvid )     {
566                         i_childlv--;
567                         continue;
568                 }
569
570                 p_arvnow        = p_abbrev + (dw_arvid - 1);
571
572                 // Read Debug Information Entry (DIE) ---
573                 memset( p_infoval, 0x00, sizeof( LibGoblin_DWARF_DIEValue ) * p_arvnow->i_items );
574                 p_val   = p_infoval;
575
576                 for( i_cnt = 0; i_cnt < p_arvnow->i_items; i_cnt++, p_val++ )   {
577                         dw_attribute    = p_arvnow->dw_attribute[ i_cnt ];
578                         dw_format               = p_arvnow->dw_format[ i_cnt ];
579
580                         pb_info = DWARF_Info_ReadFormat_Data(
581                                                                 p_val, pb_info, &qw_size_cu, dw_format, p_binfo, pt_cuheader );
582                 }
583
584                 if( 0x00 != p_arvnow->b_children )      { i_childlv++; }
585
586                 // Check compile unit tag ---
587                 if( DW_TAG_compile_unit == p_arvnow->dw_tag )   { break; }
588
589         }while( 0 != qw_size_cu ); 
590
591         if( DW_TAG_compile_unit != p_arvnow->dw_tag )   {
592                 return NULL;
593         }
594
595         p_val   = p_binfo->dwarf.p_infoval;
596         for( i_cnt = 0; i_cnt < p_arvnow->i_items; i_cnt++, p_val++ )   {
597                 if( DW_AT_name == p_arvnow->dw_attribute[ i_cnt ] )     {
598                         pstr_srcpath    = p_val->value.pstr_value;
599                         break;
600                 }
601         }
602
603         if( NULL == pstr_srcpath )      {
604                 return NULL;            
605         }
606
607         strncpy( str_temp, pstr_srcpath, DRD64_MAX_PATH );
608         p_srcfile       = SrcFile_DispenseSrcFile( p_bfile, basename( str_temp ) );
609         if( NULL == p_srcfile ) {
610                 return NULL;
611         }
612
613         strncpy( p_srcfile->str_srcpath, dirname( str_temp ), DRD64_MAX_PATH );
614
615         return p_srcfile;
616 }
617
618
619 /*----------------------------------------------------------------------
620 ----------------------------------------------------------------------*/
621 LIBGOBLIN_DWARF_INFO_EXTERN
622 int
623         DWARF_Info_Read(
624                 LibGoblin_BinaryInfo    *p_binfo )
625 {
626         int                                                     i_childlv;
627         int                                                     i_result;
628         int                                                     i_srcfiles;
629         int                                                     i_abbrevs;
630         int                                                     i_cnt;
631         Byte                                            *pb_info;
632         Byte                                            *pb_custart;
633         DWord                                           dw_arvid;
634         DWord                                           dw_attribute;
635         DWord                                           dw_format;
636         QWord                                           qw_temp;
637         QWord                                           qw_size_cu;
638         QWord                                           qw_size_info;
639         LibGoblin_SectionInfo           *psec_info;
640         LibGoblin_BinaryFile            *p_bfile;
641         DWARF_AbbrevEntry                       *p_abbrev;
642         DWARF_AbbrevEntry                       *p_arvnow;
643         LibGoblin_DWARF_DIEValue        *p_infoval;
644         LibGoblin_DWARF_DIEValue        *p_val;
645         LibGoblin_DWARF_Info_CUHeader   t_cuheader;
646         LibGoblin_SrcFile                       *p_srcfile;
647
648         assert( NULL != p_binfo );
649
650         p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile );
651         assert( NULL != p_bfile );
652
653         i_srcfiles      = p_bfile->dwarf.i_srcfiles;
654
655         p_infoval       = p_binfo->dwarf.p_infoval;
656
657         // Get section Info ---
658         psec_info       = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_INFO );
659         assert( NULL != psec_info );
660         if( NULL == psec_info->pb_data )        {
661                 return 0x01;
662         }
663         pb_info                 = psec_info->pb_data;
664         qw_size_info    = psec_info->qw_size;
665
666         do      {
667                 // Read Compile Unit Header ---
668                 pb_custart      = pb_info;
669                 pb_info = DWARF_Info_ReadCUHeader( &t_cuheader, pb_info, &qw_size_info );
670                 if( NULL == pb_info )   {
671                         return 0x02;
672                 }
673
674                 t_cuheader.pb_custart   = pb_custart;
675                 qw_size_cu                              = t_cuheader.qw_unitsize;
676
677                 // Read Abbrev for the now compile unit ---
678                 i_result        = DWARF_Abbrev_ReadAbbrevEntry(
679                                                                 &p_abbrev, &i_abbrevs,
680                                                                 p_binfo, p_bfile, t_cuheader.qw_abbrev_offset );
681
682                 // Read DW_TAG_compile_unit & Regist SrcFile struct. ---
683                 p_srcfile       = DWARF_Info_RegistSrcFile_fromTagCompileUnit(
684                                                                 p_binfo, p_bfile, pb_info, p_abbrev, qw_size_cu, &t_cuheader );
685                 if( NULL != p_srcfile ) {
686                         p_srcfile->dwarf.i_abbrevs      = i_abbrevs;
687                         p_srcfile->dwarf.p_abbrev       = p_abbrev;
688
689                         printf( "\n SrcFile: %s,  Orig.Path: %s\n",
690                                                                 p_srcfile->str_filename, p_srcfile->str_srcpath );
691                 }
692
693                 printf( "    size: %ld, ver:%d, abbrev off.:%ld, addr.size: %d\n",
694                         t_cuheader.qw_unitsize,
695                         t_cuheader.w_version,
696                         t_cuheader.qw_abbrev_offset,
697                         t_cuheader.b_pointersize);
698
699
700                 // Read & Process DWARF info TAG ---
701                 i_childlv       = 0;
702                 do      {
703                         // Read Reference Abbrev-ID ---
704                         pb_info = DWARF_Common_DecodeULEB128( &qw_temp, pb_info, &qw_size_cu );
705                         dw_arvid        = (DWord)qw_temp;
706
707                         if( 0 == dw_arvid )     {
708                                 i_childlv--;
709                                 continue;
710                         }
711
712                         p_arvnow        = p_abbrev + (dw_arvid - 1);
713
714                         // Read Debug Information Entry (DIE) ---
715                         memset( p_infoval, 0x00, sizeof( LibGoblin_DWARF_DIEValue ) * p_arvnow->i_items );
716                         p_val   = p_infoval;
717
718                         for( i_cnt = 0; i_cnt < p_arvnow->i_items; i_cnt++, p_val++ )   {
719                                 dw_attribute    = p_arvnow->dw_attribute[ i_cnt ];
720                                 dw_format               = p_arvnow->dw_format[ i_cnt ];
721
722                                 pb_info = DWARF_Info_ReadFormat_Data(
723                                                                 p_val, pb_info, &qw_size_cu, dw_format, p_binfo, &t_cuheader );
724                         }
725
726                         if( 0x00 != p_arvnow->b_children )      { i_childlv++; }
727
728                         // Dispatch for generate Rapid-Access Table by DIE-tag
729                         i_result        = DWARF_Tag_Dispatch( p_binfo, p_bfile, p_srcfile, p_arvnow );
730
731                         Debug_DWARF_PrintDIE( p_binfo, p_abbrev, dw_arvid, i_childlv );
732
733                 }while( 0 != qw_size_cu ); 
734                 qw_size_info    -= t_cuheader.qw_unitsize;
735
736         }while((qw_size_info > 0) && (i_srcfiles > 0));
737
738         
739         return 0x00;
740 }
741
742
743
744 /* EOF of drd64_.c ----------------------------------- */