OSDN Git Service

2019/05/09(Thr) 05:29
[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_ABBREV
38 #include"drd64_libgoblin.h"
39
40 /*----------------------------------------------------------------------
41 ----------------------------------------------------------------------*/
42 Byte *
43         LibGoblin_DwarfInfo_ReadFormat_Ref_inCU(
44                 LibGoblin_Dwarf_DIEValue        *p_dievalue,
45                 Byte    *pb_src, 
46                 QWord   *pqw_remain,
47                 Byte    *pb_type,
48                 int             i_sizebytes,
49                 Byte    *pb_custart )
50 {
51         Byte    *pb_link;
52         Byte    b_size;
53         Word    w_size;
54         DWord   dw_size;
55         QWord   qw_size;
56
57         assert( NULL != pb_src );
58         assert( NULL != p_dievalue );
59
60         if( 1 == i_sizebytes )  {
61                 pb_src  = LibGoblin_DwarfCommon_Read_Byte(
62                                                 &b_size, pb_src, pqw_remain );
63                 qw_size = (QWord)b_size;
64         }
65         else if( 2 == i_sizebytes )     {
66                 pb_src  = LibGoblin_DwarfCommon_Read_Word(
67                                                 &w_size, pb_src, pqw_remain );
68                 qw_size = (QWord)w_size;
69         }
70         else if( 4 == i_sizebytes )     {
71                 pb_src  = LibGoblin_DwarfCommon_Read_DWord(
72                                                 &dw_size, pb_src, pqw_remain );
73                 qw_size = (QWord)dw_size;
74         }
75         else if( 8 == i_sizebytes )     {
76                 pb_src  = LibGoblin_DwarfCommon_Read_QWord(
77                                                 &qw_size, pb_src, pqw_remain );
78         }
79         else    {
80                 pb_src  = DWARF_Common_DecodeULEB128(
81                                 &qw_size, pb_src, pqw_remain );
82         }
83         if( NULL == pb_src )    { return NULL; }
84
85         pb_link = pb_custart + qw_size;
86         p_dievalue->pb_link     = pb_link;
87         *pb_type        = LIBGOBLIN_DWARF_INFO_TYPE_LINK;
88         
89         return pb_src;
90 }
91
92
93 /*----------------------------------------------------------------------
94 ----------------------------------------------------------------------*/
95 Byte *
96         LibGoblin_DwarfInfo_ReadFormat_Block(
97                 LibGoblin_Dwarf_DIEValue        *p_dievalue,
98                 Byte    *pb_src, 
99                 QWord   *pqw_remain,
100                 Byte    *pb_type,
101                 int             i_sizebytes )
102 {
103         Byte    b_size;
104         Word    w_size;
105         DWord   dw_size;
106         QWord   qw_size;
107         assert( NULL != pb_src );
108         assert( NULL != p_dievalue );
109
110         if( 1 == i_sizebytes )  {
111                 pb_src  = LibGoblin_DwarfCommon_Read_Byte(
112                                                 &b_size, pb_src, pqw_remain );
113                 qw_size = (QWord)b_size;
114         }
115         else if( 2 == i_sizebytes )     {
116                 pb_src  = LibGoblin_DwarfCommon_Read_Word(
117                                                 &w_size, pb_src, pqw_remain );
118                 qw_size = (QWord)w_size;
119         }
120         else if( 4 == i_sizebytes )     {
121                 pb_src  = LibGoblin_DwarfCommon_Read_DWord(
122                                                 &dw_size, pb_src, pqw_remain );
123                 qw_size = (QWord)dw_size;
124         }
125         else if( 8 == i_sizebytes )     {
126                 pb_src  = LibGoblin_DwarfCommon_Read_QWord(
127                                                 &qw_size, pb_src, pqw_remain );
128         }
129         else    {
130                 pb_src  = DWARF_Common_DecodeULEB128(
131                                 &qw_size, pb_src, pqw_remain );
132         }
133
134         if( NULL == pb_src )    { return NULL; }
135
136         
137         if( *pqw_remain >= qw_size )    {
138                 p_dievalue->t_value.qw_size     = qw_size;
139                 p_dievalue->t_value.pb_data     = pb_src;
140                 *pb_type        = LIBGOBLIN_DWARF_INFO_TYPE_BLOCK;
141                 pb_src          += qw_size;
142                 *pqw_remain     -= qw_size;
143         }
144
145         return pb_src;
146 }
147
148 /*----------------------------------------------------------------------
149 ----------------------------------------------------------------------*/
150 Byte *
151         LibGoblin_DwarfInfo_ReadFormat_Strp(
152                 LibGoblin_Dwarf_DIEValue        *p_dievalue,
153                 Byte    *pb_src, 
154                 QWord   *pqw_remain,
155                 Byte    *pb_type,
156                 Byte    b_bits )
157 {
158         assert( NULL != pb_src );
159         assert( NULL != p_dievalue );
160
161         if( 64 == b_bits )      {
162                 pb_src  = LibGoblin_DwarfCommon_Read_QWord(
163                                         &(p_dievalue->qw_value), pb_src, pqw_remain );
164                 *pb_type        = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
165         }
166         else if( 32 == b_bits ) {
167                 pb_src  = LibGoblin_DwarfCommon_Read_DWord(
168                                         &(p_dievalue->dw_value), pb_src, pqw_remain );
169                 *pb_type        = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
170         }
171
172         return pb_src;
173 }
174 /*----------------------------------------------------------------------
175 ----------------------------------------------------------------------*/
176 Byte *
177         LibGoblin_DwarfInfo_ReadFormat_String(
178                 LibGoblin_Dwarf_DIEValue        *p_dievalue,
179                 Byte    *pb_src, 
180                 QWord   *pqw_remain,
181                 Byte    *pb_type )
182 {
183         Byte    *pb_now;
184
185         assert( NULL != pb_src );
186         assert( NULL != p_dievalue );
187
188         pb_now  = pb_src;
189
190         while( (0 < *pqw_remain) && ('\0' != *pb_now) ) {
191                 pb_now++;
192                 (*pqw_remain)--;
193         }
194
195         if( 0 < *pqw_remain )   {
196                 p_dievalue->str_value   = (char *)pb_src;
197                 *pb_type        = LIBGOBLIN_DWARF_INFO_TYPE_STRING;
198
199                 pb_now++;
200                 (*pqw_remain)--;
201         }
202
203         return pb_now;
204 }
205
206
207 /*----------------------------------------------------------------------
208 ----------------------------------------------------------------------*/
209 Byte *
210         LibGoblin_DwarfInfo_ReadFormat_Address(
211                 LibGoblin_Dwarf_DIEValue        *p_dievalue,
212                 Byte    *pb_src, 
213                 QWord   *pqw_remain,
214                 Byte    *pb_type,
215                 int             i_pointersize )
216 {
217         assert( NULL != pb_src );
218         assert( NULL != p_dievalue );
219
220         if( 8 == i_pointersize )        {
221                 pb_src  = LibGoblin_DwarfCommon_Read_QWord(
222                                         &(p_dievalue->qw_value), pb_src, pqw_remain );
223                 *pb_type        = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
224         }
225         else if( 4 == i_pointersize )   {
226                 pb_src  = LibGoblin_DwarfCommon_Read_DWord(
227                                         &(p_dievalue->dw_value), pb_src, pqw_remain );
228                 *pb_type        = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
229         }
230         else if( 2 == i_pointersize )   {
231                 pb_src  = LibGoblin_DwarfCommon_Read_Word(
232                                         &(p_dievalue->w_value), pb_src, pqw_remain );
233                 *pb_type        = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
234         }
235
236         if( NULL == pb_src )
237                 { *pb_type = LIBGOBLIN_DWARF_INFO_TYPE_NONE; }
238
239         return pb_src;
240 }
241
242
243
244 /*----------------------------------------------------------------------
245 ----------------------------------------------------------------------*/
246 Byte *
247         LibGoblin_DwarfInfo_ReadDIE(
248                 LibGoblin_Dwarf_DIE *p_die,
249                 Byte    *pb_src, 
250                 QWord   *pqw_remains,
251                 LibGoblin_Dwarf_SourceFile      *pt_srcfile,
252                 LibGoblin_DwarfCommon_CUHeader  *p_cuheader )
253 {
254         int             i_cnt;
255         Byte    *pb_abb;
256         Byte    b_type;
257         DWord   dw_abbrev;
258         DWord   dw_attribute;
259         DWord   dw_format;
260         QWord   qw_size;
261         QWord   qw_temp;
262         LibGoblin_Dwarf_AbbrevInfo      *p_abbrev;
263         LibGoblin_Dwarf_AbbrevEntry     t_abbentry;
264
265         //printf(" pnt: %p  ", pb_src);
266         /* Read Reference Abbrev-ID */
267         pb_src  = DWARF_Common_DecodeULEB128(
268                 &qw_temp, pb_src, pqw_remains );
269         dw_abbrev       = (DWord)qw_temp;
270
271         //printf(" abbrev: %ld\n", dw_abbrev);
272
273         if( 0x00000000 == dw_abbrev )   { return pb_src; }
274
275         /* Set Reference Abbrev */
276         p_abbrev        = (pt_srcfile->p_abbrev_info) + (dw_abbrev - 1 );
277         if( NULL == p_abbrev )  { return NULL; }
278
279         pb_abb  = p_abbrev->pb_pos;
280         assert( NULL != pb_abb );
281
282         qw_size = (QWord)p_abbrev->w_size;
283         pb_abb  = LibGoblin_DwarfAbbrev_ReadEntry( &t_abbentry, pb_abb, &qw_size);
284         if( NULL == pb_abb )    { return NULL; }
285
286         p_die->dw_tag           = t_abbentry.dw_tag;
287         p_die->dw_abbrev        = t_abbentry.dw_id;
288         p_die->i_items          = t_abbentry.i_items;
289
290         for( i_cnt = 0; i_cnt < p_die->i_items; i_cnt++ )       {
291                 dw_attribute    = t_abbentry.dw_attribute[ i_cnt ];
292                 dw_format               = t_abbentry.dw_format[ i_cnt ];
293
294                 p_die->dw_attribute[ i_cnt ]    = dw_attribute;
295                 p_die->dw_format[ i_cnt ]               = dw_format;
296                 
297                 switch( dw_format )     {
298                         case DW_FORM_addr:              /* 0x01: address */
299                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Address(
300                                                         &(p_die->t_value[i_cnt]), pb_src, pqw_remains,
301                                                         &b_type, (int)(p_cuheader->b_pointersize) ); 
302                                 break;
303                         case DW_FORM_block2:    /* 0x03: block */
304                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Block(
305                                                         &(p_die->t_value[i_cnt]),
306                                                         pb_src, pqw_remains, &b_type, 2);
307                                 break;
308                         case DW_FORM_block4:    /* 0x04: block */
309                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Block(
310                                                         &(p_die->t_value[i_cnt]),
311                                                         pb_src, pqw_remains, &b_type, 4);
312                                 break;
313                         case DW_FORM_data2:             /* 0x05: const. */
314                                 pb_src  = LibGoblin_DwarfCommon_Read_Word(
315                                                         &(p_die->t_value[i_cnt].w_value),
316                                                         pb_src, pqw_remains );
317                                 b_type  = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
318                                 break;
319                         case DW_FORM_data4:             /* 0x06: const. line/loc/mac/rng-ptr */
320                                 pb_src  = LibGoblin_DwarfCommon_Read_DWord(
321                                                         &(p_die->t_value[i_cnt].dw_value),
322                                                         pb_src, pqw_remains );
323                                 b_type  = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
324                                 break;
325                         case DW_FORM_data8:             /* 0x07: const. line/loc/mac/rng-ptr */
326                                 pb_src  = LibGoblin_DwarfCommon_Read_QWord(
327                                                         &(p_die->t_value[i_cnt].qw_value),
328                                                         pb_src, pqw_remains );
329                                 b_type  = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
330                                 break;
331                         case DW_FORM_string:    /* 0x08: string */
332                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_String(
333                                                         &(p_die->t_value[i_cnt]),
334                                                         pb_src, pqw_remains, &b_type);
335                                 break;
336                         case DW_FORM_block:             /* 0x09: block */
337                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Block(
338                                                         &(p_die->t_value[i_cnt]),
339                                                         pb_src, pqw_remains, &b_type, -1);
340                                 break;
341                         case DW_FORM_block1:    /* 0x0a: block */
342                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Block(
343                                                         &(p_die->t_value[i_cnt]),
344                                                         pb_src, pqw_remains, &b_type, 1);
345                                 break;
346                         case DW_FORM_data1:             /* 0x0b: const. */
347                                 pb_src  = LibGoblin_DwarfCommon_Read_Byte(
348                                                         &(p_die->t_value[i_cnt].b_value),
349                                                         pb_src, pqw_remains );
350                                 b_type  = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
351                                 break;
352                         case DW_FORM_flag:              /* 0x0c: flag */
353                                 pb_src  = LibGoblin_DwarfCommon_Read_Byte(
354                                                         &(p_die->t_value[i_cnt].b_value),
355                                                         pb_src, pqw_remains );
356                                 b_type  = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
357                                 break;
358                         case DW_FORM_sdata:             /* 0x0d: sdata */
359                                 pb_src  = DWARF_Common_DecodeLEB128(
360                                                         &(p_die->t_value[i_cnt].ii_value),
361                                                         pb_src, pqw_remains );
362                                 b_type  = LIBGOBLIN_DWARF_INFO_TYPE_INT64;
363                                 break;
364                         case DW_FORM_strp:              /* 0x0e: string */
365                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Strp(
366                                                         &(p_die->t_value[i_cnt]),
367                                                         pb_src, pqw_remains, &b_type,
368                                                         p_cuheader->b_bits );
369                                 // XXX  reference for .debug_str
370                                 break;
371                         case DW_FORM_udata:             /* 0x0f: const. */
372                                 pb_src  = DWARF_Common_DecodeULEB128(
373                                                         &(p_die->t_value[i_cnt].qw_value),
374                                                         pb_src, pqw_remains );
375                                 b_type  = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
376                                 break;
377                         case DW_FORM_ref_addr:  /* 0x10: ref. */
378                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Address(
379                                                         &(p_die->t_value[i_cnt]),pb_src, pqw_remains,
380                                                         &b_type, (int)(p_cuheader->b_pointersize) ); 
381                                 break;
382                         case DW_FORM_ref1:              /* 0x11: ref. */
383                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Ref_inCU(
384                                                         &(p_die->t_value[i_cnt]),
385                                                         pb_src, pqw_remains, &b_type, 1,
386                                                         pt_srcfile->t_infosec.pb_pos );
387                                 break;
388                         case DW_FORM_ref2:              /* 0x12: ref. */
389                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Ref_inCU(
390                                                         &(p_die->t_value[i_cnt]),
391                                                         pb_src, pqw_remains, &b_type, 2,
392                                                         pt_srcfile->t_infosec.pb_pos );
393                                 break;
394                         case DW_FORM_ref4:              /* 0x13: ref. */
395                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Ref_inCU(
396                                                         &(p_die->t_value[i_cnt]),
397                                                         pb_src, pqw_remains, &b_type, 4,
398                                                         pt_srcfile->t_infosec.pb_pos );
399                                 break;
400                         case DW_FORM_ref8:              /* 0x14: ref. */
401                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Ref_inCU(
402                                                         &(p_die->t_value[i_cnt]),
403                                                         pb_src, pqw_remains, &b_type, 8,
404                                                         pt_srcfile->t_infosec.pb_pos );
405                                 break;
406                         case DW_FORM_ref_udata: /* 0x15: ref. */
407                                 pb_src  = LibGoblin_DwarfInfo_ReadFormat_Ref_inCU(
408                                                         &(p_die->t_value[i_cnt]),
409                                                         pb_src, pqw_remains, &b_type, -1,
410                                                         pt_srcfile->t_infosec.pb_pos );
411                                 break;
412                         case DW_FORM_indirect:  /* 0x16: ref. */
413                                 puts("a");
414                                 break;
415                         default:
416                                 break;
417                 }
418         }
419         
420
421         return pb_src;
422 }
423
424
425 /*----------------------------------------------------------------------
426 ----------------------------------------------------------------------*/
427 Byte *
428         LibGoblin_DwarfInfo_ReadCompileUnit(
429                 LibGoblin_Dwarf_SourceFile      *p_src,
430                 Byte    *pb_data,
431                 QWord   *pqw_size_info )
432 {
433         QWord           qw_unitsize;
434         LibGoblin_DwarfCommon_CUHeader  t_cuheader;
435         LibGoblin_Dwarf_DIE t_die;
436
437         assert( NULL != p_src );
438         assert( NULL != pb_data );
439
440         if( 0 == *pqw_size_info )               { return NULL; }
441         
442         /* Read Compile Unit Header */
443         pb_data = LibGoblin_DwarfCommon_Read_CUHeader(
444                                                 &t_cuheader, pb_data, *pqw_size_info);
445         if( NULL == pb_data )   { return NULL; }
446
447         qw_unitsize             = t_cuheader.qw_unitsize;
448
449 /*      printf( "size: %ld, ver:%d, abbrev off.:%ld, addr.size: %d\n",
450                         t_cuheader.qw_unitsize,
451                         t_cuheader.w_version,
452                         t_cuheader.qw_abbrev_offset,
453                         t_cuheader.b_pointersize); */
454
455         do      {
456                 /* Read Debug Information Entry (DIE */
457                 pb_data = LibGoblin_DwarfInfo_ReadDIE(
458                                         &t_die, pb_data, &qw_unitsize, p_src, &t_cuheader );
459
460                 /* Dispatch for generate Rapid-Access Table by DIE-tag */
461
462         }while( 0 != qw_unitsize ); 
463
464         puts( "OKOK");
465         *pqw_size_info  -= t_cuheader.qw_unitsize;
466
467         return pb_data;
468 }
469
470
471 /*----------------------------------------------------------------------
472 ----------------------------------------------------------------------*/
473 LIBGOBLIN_DWARF_INFO_EXTERN
474 int
475         LibGoblin_DwarfInfo_Analyze(
476                 LibGoblin_BinaryInfo    *p_bin )
477 {
478         int             i_srcfiles;
479         Byte    *pb_data;
480         QWord   qw_size_info;
481         LibGoblin_Dwarf_SourceFile      *p_src;
482         LibGoblin_Debug_Dwarf           *p_dwarf;
483
484         assert( NULL != p_bin );
485
486         p_dwarf = (LibGoblin_Debug_Dwarf *)p_bin->p_debug;
487         assert( NULL != p_dwarf );
488
489         i_srcfiles      = p_dwarf->i_srcfilenum;
490
491         p_src   = p_dwarf->p_src;
492         assert( NULL != p_src );
493
494         /* Get .debug_abbrev section Info */
495         pb_data = ELF_GetSection(
496                                         &qw_size_info, p_bin,
497                                         LIBGOBLIN_SECTION_ID_DEBUG_INFO );
498         if( NULL == pb_data )   { return 0x01; }
499
500         do      {
501                 p_src->t_infosec.pb_pos = pb_data;
502
503                 /* Analyze .debug_info compile unit */
504                 pb_data = LibGoblin_DwarfInfo_ReadCompileUnit(
505                                                 p_src, pb_data, &qw_size_info );
506                 if( NULL == pb_data)    { return 0x02; }
507
508                 p_src++;
509                 i_srcfiles--;
510
511         }while((qw_size_info > 0) && (i_srcfiles > 0));
512         
513         return 0x00;
514 }
515
516
517
518 /* EOF of drd64_.c ----------------------------------- */