OSDN Git Service

(LibGoblin)
[drdeamon64/drdeamon64.git] / libgoblin / drd64_libgoblin_dwarf_attrform.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_ATTRFORM
38 #include"drd64_libgoblin.h"
39
40
41 /*----------------------------------------------------------------------
42 ----------------------------------------------------------------------*/
43 Byte *
44         DWARF_AttrForm_ReadFormat_Ref_inCU(
45                 LibGoblin_DWARF_DIEValue        *p_val,
46                 Byte    *pb_src, 
47                 QWord   *pqw_remain,
48                 Byte    b_bytes,
49                 Byte    *pb_custart )
50 {
51         Byte    b_size;
52         Word    w_size;
53         DWord   dw_size;
54         QWord   qw_size;
55
56         assert( NULL != pb_src );
57         assert( NULL != p_val );
58
59         if( 1 == b_bytes )      {
60                 pb_src  = DWARF_Common_Read_Byte( &b_size, pb_src, pqw_remain );
61                 qw_size = (QWord)b_size;
62         }
63         else if( 2 == b_bytes ) {
64                 pb_src  = DWARF_Common_Read_Word( &w_size, pb_src, pqw_remain );
65                 qw_size = (QWord)w_size;
66         }
67         else if( 4 == b_bytes ) {
68                 pb_src  = DWARF_Common_Read_DWord( &dw_size, pb_src, pqw_remain );
69                 qw_size = (QWord)dw_size;
70         }
71         else if( 8 == b_bytes ) {
72                 pb_src  = DWARF_Common_Read_QWord( &qw_size, pb_src, pqw_remain );
73         }
74         else    {
75                 pb_src  = DWARF_Common_DecodeULEB128( &qw_size, pb_src, pqw_remain );
76         }
77         if( NULL == pb_src )    { return NULL; }
78
79         p_val->value.pb_link    = pb_custart + qw_size;
80         p_val->b_type                   = LIBGOBLIN_DWARF_INFO_TYPE_LINK;
81         p_val->qw_size                  = (QWord)b_bytes;
82         
83         return pb_src;
84 }
85
86
87 /*----------------------------------------------------------------------
88 ----------------------------------------------------------------------*/
89 Byte *
90         DWARF_AttrForm_ReadFormat_Block(
91                 LibGoblin_DWARF_DIEValue        *p_val,
92                 Byte    *pb_src, 
93                 QWord   *pqw_remain,
94                 int             i_sizebytes )
95 {
96         Byte    b_size;
97         Word    w_size;
98         DWord   dw_size;
99         QWord   qw_size;
100
101         assert( NULL != pb_src );
102         assert( NULL != p_val );
103
104         if( 1 == i_sizebytes )  {
105                 pb_src  = DWARF_Common_Read_Byte( &b_size, pb_src, pqw_remain );
106                 qw_size = (QWord)b_size;
107         }
108         else if( 2 == i_sizebytes )     {
109                 pb_src  = DWARF_Common_Read_Word( &w_size, pb_src, pqw_remain );
110                 qw_size = (QWord)w_size;
111         }
112         else if( 4 == i_sizebytes )     {
113                 pb_src  = DWARF_Common_Read_DWord( &dw_size, pb_src, pqw_remain );
114                 qw_size = (QWord)dw_size;
115         }
116         else if( 8 == i_sizebytes )     {
117                 pb_src  = DWARF_Common_Read_QWord( &qw_size, pb_src, pqw_remain );
118         }
119         else    {
120                 pb_src  = DWARF_Common_DecodeULEB128( &qw_size, pb_src, pqw_remain );
121         }
122
123         if( *pqw_remain >= qw_size )    {
124                 p_val->qw_size                  = qw_size;
125                 p_val->value.pb_data    = pb_src;
126                 p_val->b_type                   = LIBGOBLIN_DWARF_INFO_TYPE_BLOCK;
127                 pb_src                                  += qw_size;
128                 *pqw_remain                             -= qw_size;
129         }
130         else    { pb_src        = NULL; }
131
132         return pb_src;
133 }
134
135 /*----------------------------------------------------------------------
136 ----------------------------------------------------------------------*/
137 Byte *
138         DWARF_AttrForm_ReadFormat_Strp(
139                 LibGoblin_DWARF_DIEValue        *p_val,
140                 Byte    *pb_src, 
141                 QWord   *pqw_remain,
142                 LibGoblin_BinaryInfo    *p_binfo,
143                 Byte    b_bits )
144 {
145         Byte    *pb_string      = NULL;
146         QWord   qw_offset;
147         DWord   dw_offset;
148         LibGoblin_SectionInfo   *psec_dbgstr;
149
150         assert( NULL != pb_src );
151         assert( NULL != p_val );
152
153         psec_dbgstr     = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_STR );
154         assert( NULL != psec_dbgstr );
155         assert( NULL != psec_dbgstr->pb_data );
156
157         if( 8 == b_bits )       {
158                 pb_src          = DWARF_Common_Read_QWord( &qw_offset, pb_src, pqw_remain );
159                 pb_string       = psec_dbgstr->pb_data + qw_offset;
160         }
161         else if( 4 == b_bits )  {
162                 pb_src  = DWARF_Common_Read_DWord( &dw_offset, pb_src, pqw_remain );
163                 pb_string       = psec_dbgstr->pb_data + dw_offset;
164         }
165
166         p_val->value.pstr_value = (char *)pb_string;
167         p_val->b_type                   = LIBGOBLIN_DWARF_INFO_TYPE_STRING;
168         p_val->qw_size                  = 0;
169
170         return pb_src;
171 }
172
173
174 /*----------------------------------------------------------------------
175 ----------------------------------------------------------------------*/
176 Byte *
177         DWARF_AttrForm_ReadFormat_String(
178                 LibGoblin_DWARF_DIEValue        *p_val,
179                 Byte    *pb_src, 
180                 QWord   *pqw_remain )
181 {
182         Byte    *pb_now;
183         QWord   qw_size = 0;
184
185         assert( NULL != pb_src );
186         assert( NULL != p_val );
187
188         pb_now  = pb_src;
189
190         while( (0 < *pqw_remain) && ('\0' != *pb_now) ) {
191                 pb_now++;
192                 qw_size++;
193                 (*pqw_remain)--;
194         }
195
196         if( 0 < *pqw_remain )   {
197                 p_val->value.pstr_value = (char *)pb_src;
198                 p_val->b_type                   = LIBGOBLIN_DWARF_INFO_TYPE_STRING;
199                 p_val->qw_size                  = qw_size;
200
201                 pb_now++;
202                 (*pqw_remain)--;
203         }
204
205         return pb_now;
206 }
207
208
209 /*----------------------------------------------------------------------
210 ----------------------------------------------------------------------*/
211 Byte *
212         DWARF_AttrForm_ReadFormat_Address(
213                 LibGoblin_DWARF_DIEValue        *p_val,
214                 Byte    *pb_src, 
215                 QWord   *pqw_remain,
216                 Byte    b_pointersize )
217 {
218         assert( NULL != pb_src );
219         assert( NULL != p_val );
220
221         if( 8 == b_pointersize )        {
222                 pb_src  = DWARF_Common_Read_QWord(
223                                                 &(p_val->value.qw_value), pb_src, pqw_remain );
224                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
225                 p_val->qw_size  = 8;
226         }
227         else if( 4 == b_pointersize )   {
228                 pb_src  = DWARF_Common_Read_DWord(
229                                                 &(p_val->value.dw_value), pb_src, pqw_remain );
230                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
231                 p_val->qw_size  = 4;
232         }
233         else if( 2 == b_pointersize )   {
234                 pb_src  = DWARF_Common_Read_Word(
235                                                 &(p_val->value.w_value), pb_src, pqw_remain );
236                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
237                 p_val->qw_size  = 2;
238         }
239
240         return pb_src;
241 }
242
243
244 /*----------------------------------------------------------------------
245 ----------------------------------------------------------------------*/
246 Byte *
247         DWARF_AttrForm_ReadFormat_Offset(
248                 LibGoblin_DWARF_DIEValue        *p_val,
249                 Byte    *pb_src, 
250                 QWord   *pqw_remain,
251                 LibGoblin_BinaryInfo    *p_binfo,
252                 Byte    b_bits )
253 {
254         assert( NULL != pb_src );
255         assert( NULL != p_val );
256
257         if( 8 == b_bits )       {
258                 pb_src  = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_src, pqw_remain );
259                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
260                 p_val->qw_size  = 8;
261         }
262         else if( 4 == b_bits )  {
263                 pb_src  = DWARF_Common_Read_DWord( &(p_val->value.dw_value), pb_src, pqw_remain );
264                 p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
265                 p_val->qw_size  = 4;
266         }
267
268         return pb_src;
269 }
270
271
272 /*----------------------------------------------------------------------
273 ----------------------------------------------------------------------*/
274 Byte *
275         DWARF_AttrForm_ReadFormat_InDirect(
276                 LibGoblin_DWARF_DIEValue        *p_val,
277                 Byte    *pb_info,
278                 QWord   *pqw_remains,
279                 LibGoblin_BinaryInfo    *p_binfo,
280                 LibGoblin_DWARF_Info_CUHeader   *p_cuheader )
281 {
282         QWord   qw_size;
283         DWord   dw_form;
284
285         // Get InDirect DW_FORM_*** value. ---
286         pb_info = DWARF_Common_DecodeULEB128( &qw_size, pb_info, pqw_remains );
287         dw_form = (DWord)qw_size;
288
289         // Re-Call Read FormatData Function ---
290         pb_info = DWARF_AttrForm_ReadFormat_Data(
291                                                 p_val, pb_info, pqw_remains, dw_form, p_binfo, p_cuheader );
292
293         return pb_info;
294 }
295
296
297 /*----------------------------------------------------------------------
298 ----------------------------------------------------------------------*/
299 LIBGOBLIN_DWARF_ATTRFORM_EXTERN
300 Byte *
301         DWARF_AttrForm_ReadFormat_Data(
302                 LibGoblin_DWARF_DIEValue        *p_val,
303                 Byte    *pb_info,
304                 QWord   *pqw_remains,
305                 DWord   dw_format,
306                 LibGoblin_BinaryInfo    *p_binfo,
307                 LibGoblin_DWARF_Info_CUHeader   *p_cuheader )
308 {
309         switch( dw_format )     {
310                 case DW_FORM_addr:              // 0x01: address
311                         pb_info = DWARF_AttrForm_ReadFormat_Address(
312                                                                 p_val, pb_info, pqw_remains, p_cuheader->b_pointersize ); 
313                         break;
314                 case DW_FORM_block2:    // 0x03: block
315                         pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, 2);
316                         break;
317                 case DW_FORM_block4:    // 0x04: block
318                         pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, 4);
319                         break;
320                 case DW_FORM_data2:             // 0x05: const.
321                         pb_info = DWARF_Common_Read_Word( &(p_val->value.w_value), pb_info, pqw_remains );
322                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
323                         p_val->qw_size  = 2;
324                         break;
325                 case DW_FORM_data4:             // 0x06: const. line/loc/mac/rng-ptr
326                         pb_info = DWARF_Common_Read_DWord( &(p_val->value.dw_value), pb_info, pqw_remains );
327                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
328                         p_val->qw_size  = 4;
329                         break;
330                 case DW_FORM_data8:             // 0x07: const. line/loc/mac/rng-ptr
331                         pb_info = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_info, pqw_remains );
332                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
333                         p_val->qw_size  = 8;
334                         break;
335                 case DW_FORM_string:    // 0x08: string
336                         pb_info = DWARF_AttrForm_ReadFormat_String( p_val, pb_info, pqw_remains );
337                         break;
338                 case DW_FORM_block:             // 0x09: block
339                         pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, -1);
340                         break;
341                 case DW_FORM_block1:    // 0x0a: block
342                         pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, 1);
343                         break;
344                 case DW_FORM_data1:             // 0x0b: const.
345                         pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
346                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
347                         p_val->qw_size  = 1;
348                         break;
349                 case DW_FORM_flag:              // 0x0c: flag
350                         pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
351                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
352                         p_val->qw_size  = 1;
353                         break;
354                 case DW_FORM_sdata:             // 0x0d: sdata
355                         pb_info = DWARF_Common_DecodeLEB128( &(p_val->value.ii_value), pb_info, pqw_remains );
356                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_INT64;
357                         p_val->qw_size  = 8;
358                         break;
359                 case DW_FORM_strp:              // 0x0e: string (in .debug_str section)
360                         pb_info = DWARF_AttrForm_ReadFormat_Strp(
361                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
362                         break;
363                 case DW_FORM_udata:             // 0x0f: const.
364                         pb_info = DWARF_Common_DecodeULEB128( &(p_val->value.qw_value), pb_info, pqw_remains );
365                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
366                         p_val->qw_size  = 8;
367                         break;
368                 case DW_FORM_ref_addr:  // 0x10: ref.
369                         pb_info = DWARF_AttrForm_ReadFormat_Address(
370                                                                 p_val, pb_info, pqw_remains, p_cuheader->b_pointersize ); 
371                         break;
372                 case DW_FORM_ref1:              // 0x11: ref.
373                         pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
374                                                                 p_val, pb_info, pqw_remains, 1, p_cuheader->pb_custart );
375                         break;
376                 case DW_FORM_ref2:              // 0x12: ref.
377                         pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
378                                                                 p_val, pb_info, pqw_remains, 2, p_cuheader->pb_custart );
379                         break;
380                 case DW_FORM_ref4:              // 0x13: ref.
381                         pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
382                                                                 p_val, pb_info, pqw_remains, 4, p_cuheader->pb_custart );
383                         break;
384                 case DW_FORM_ref8:              // 0x14: ref.
385                         pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
386                                                                 p_val, pb_info, pqw_remains, 8, p_cuheader->pb_custart );
387                         break;
388                 case DW_FORM_ref_udata: // 0x15: ref.
389                         pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
390                                                                 p_val, pb_info, pqw_remains, -1, p_cuheader->pb_custart );
391                         break;
392                 case DW_FORM_indirect:  // 0x16: ref.
393                         pb_info = DWARF_AttrForm_ReadFormat_InDirect(
394                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader );
395                         break;
396                 case DW_FORM_sec_offset:        // 0x17:
397                         // offset from the beginning of the .debug_line section
398                         //  to the first byte of the data making up the line number list for the compilation unit.
399                         // 1: const. value (size: offsetsize)
400                         pb_info = DWARF_AttrForm_ReadFormat_Offset(
401                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
402                         break;
403                 case DW_FORM_exprloc:           // 0x18:
404                         // 1: uLEB128 = length
405                         // 2: info. bytes specified by the length(1:) (DWARF expression)
406                         pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, -1);
407                         break;
408                 case DW_FORM_flag_present:      // 0x19:
409                         // have NONE value because implicitly flag is TRUE.
410                         //   => NONE Proc.
411                         break;
412                 case DW_FORM_ref_sig8:          // 0x20:
413                         // 1: pointer (8byte)
414                         pb_info = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_info, pqw_remains );
415                         p_val->b_type   = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
416                         p_val->qw_size  = 8;
417                         break;
418                 case DW_FORM_GNU_ref_alt:       // 0x1f20:
419                         pb_info = DWARF_AttrForm_ReadFormat_Offset(
420                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
421                         break;
422                 case DW_FORM_GNU_strp_alt:      // 0x1f21:
423                         pb_info = DWARF_AttrForm_ReadFormat_Offset(
424                                                                 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
425                         break;
426                 default:
427                         break;
428         }
429
430         return pb_info;
431 }
432
433
434 /* EOF of drd64_.c ----------------------------------- */