1 /*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
4 for INTEL64(R), AMD64(R)
6 Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
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.
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.
29 DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
31 /* File Info -----------------------------------------------------------
35 ----------------------------------------------------------------------*/
37 #define DRD64_SRC_LIBGOBLIN_DWARF_ATTRFORM
38 #include"drd64_libgoblin.h"
41 /*----------------------------------------------------------------------
42 ----------------------------------------------------------------------*/
44 DWARF_AttrForm_ReadFormat_Ref_inCU(
45 LibGoblin_DWARF_DIEValue *p_val,
56 assert( NULL != pb_src );
57 assert( NULL != p_val );
60 pb_src = DWARF_Common_Read_Byte( &b_size, pb_src, pqw_remain );
61 qw_size = (QWord)b_size;
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;
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;
71 else if( 8 == b_bytes ) {
72 pb_src = DWARF_Common_Read_QWord( &qw_size, pb_src, pqw_remain );
75 pb_src = DWARF_Common_DecodeULEB128( &qw_size, pb_src, pqw_remain );
77 if( NULL == pb_src ) { return NULL; }
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;
87 /*----------------------------------------------------------------------
88 ----------------------------------------------------------------------*/
90 DWARF_AttrForm_ReadFormat_Block(
91 LibGoblin_DWARF_DIEValue *p_val,
101 assert( NULL != pb_src );
102 assert( NULL != p_val );
104 if( 1 == i_sizebytes ) {
105 pb_src = DWARF_Common_Read_Byte( &b_size, pb_src, pqw_remain );
106 qw_size = (QWord)b_size;
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;
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;
116 else if( 8 == i_sizebytes ) {
117 pb_src = DWARF_Common_Read_QWord( &qw_size, pb_src, pqw_remain );
120 pb_src = DWARF_Common_DecodeULEB128( &qw_size, pb_src, pqw_remain );
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;
128 *pqw_remain -= qw_size;
130 else { pb_src = NULL; }
135 /*----------------------------------------------------------------------
136 ----------------------------------------------------------------------*/
138 DWARF_AttrForm_ReadFormat_Strp(
139 LibGoblin_DWARF_DIEValue *p_val,
142 LibGoblin_BinaryInfo *p_binfo,
145 Byte *pb_string = NULL;
148 LibGoblin_SectionInfo *psec_dbgstr;
150 assert( NULL != pb_src );
151 assert( NULL != p_val );
153 psec_dbgstr = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_STR );
154 assert( NULL != psec_dbgstr );
155 assert( NULL != psec_dbgstr->pb_data );
158 pb_src = DWARF_Common_Read_QWord( &qw_offset, pb_src, pqw_remain );
159 pb_string = psec_dbgstr->pb_data + qw_offset;
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;
166 p_val->value.pstr_value = (char *)pb_string;
167 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_STRING;
174 /*----------------------------------------------------------------------
175 ----------------------------------------------------------------------*/
177 DWARF_AttrForm_ReadFormat_String(
178 LibGoblin_DWARF_DIEValue *p_val,
185 assert( NULL != pb_src );
186 assert( NULL != p_val );
190 while( (0 < *pqw_remain) && ('\0' != *pb_now) ) {
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;
209 /*----------------------------------------------------------------------
210 ----------------------------------------------------------------------*/
212 DWARF_AttrForm_ReadFormat_Address(
213 LibGoblin_DWARF_DIEValue *p_val,
218 assert( NULL != pb_src );
219 assert( NULL != p_val );
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;
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;
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;
244 /*----------------------------------------------------------------------
245 ----------------------------------------------------------------------*/
247 DWARF_AttrForm_ReadFormat_Offset(
248 LibGoblin_DWARF_DIEValue *p_val,
251 LibGoblin_BinaryInfo *p_binfo,
254 assert( NULL != pb_src );
255 assert( NULL != p_val );
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;
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;
272 /*----------------------------------------------------------------------
273 ----------------------------------------------------------------------*/
275 DWARF_AttrForm_ReadFormat_InDirect(
276 LibGoblin_DWARF_DIEValue *p_val,
279 LibGoblin_BinaryInfo *p_binfo,
280 LibGoblin_DWARF_Info_CUHeader *p_cuheader )
285 // Get InDirect DW_FORM_*** value. ---
286 pb_info = DWARF_Common_DecodeULEB128( &qw_size, pb_info, pqw_remains );
287 dw_form = (DWord)qw_size;
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 );
297 /*----------------------------------------------------------------------
298 ----------------------------------------------------------------------*/
300 DWARF_AttrForm_ReadFormat_Data(
301 LibGoblin_DWARF_DIEValue *p_val,
305 LibGoblin_BinaryInfo *p_binfo,
306 LibGoblin_DWARF_Info_CUHeader *p_cuheader )
308 p_val->dw_format = dw_format;
310 switch( dw_format ) {
311 case DW_FORM_addr: // 0x01: address
312 pb_info = DWARF_AttrForm_ReadFormat_Address(
313 p_val, pb_info, pqw_remains, p_cuheader->b_pointersize );
315 case DW_FORM_block2: // 0x03: block
316 pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, 2);
318 case DW_FORM_block4: // 0x04: block
319 pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, 4);
321 case DW_FORM_data2: // 0x05: const.
322 pb_info = DWARF_Common_Read_Word( &(p_val->value.w_value), pb_info, pqw_remains );
323 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
326 case DW_FORM_data4: // 0x06: const. line/loc/mac/rng-ptr
327 pb_info = DWARF_Common_Read_DWord( &(p_val->value.dw_value), pb_info, pqw_remains );
328 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
331 case DW_FORM_data8: // 0x07: const. line/loc/mac/rng-ptr
332 pb_info = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_info, pqw_remains );
333 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
336 case DW_FORM_string: // 0x08: string
337 pb_info = DWARF_AttrForm_ReadFormat_String( p_val, pb_info, pqw_remains );
339 case DW_FORM_block: // 0x09: block
340 pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, -1);
342 case DW_FORM_block1: // 0x0a: block
343 pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, 1);
345 case DW_FORM_data1: // 0x0b: const.
346 pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
347 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
350 case DW_FORM_flag: // 0x0c: flag
351 pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
352 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
355 case DW_FORM_sdata: // 0x0d: sdata
356 pb_info = DWARF_Common_DecodeLEB128( &(p_val->value.ii_value), pb_info, pqw_remains );
357 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_INT64;
360 case DW_FORM_strp: // 0x0e: string (in .debug_str section)
361 pb_info = DWARF_AttrForm_ReadFormat_Strp(
362 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
364 case DW_FORM_udata: // 0x0f: const.
365 pb_info = DWARF_Common_DecodeULEB128( &(p_val->value.qw_value), pb_info, pqw_remains );
366 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
369 case DW_FORM_ref_addr: // 0x10: ref.
370 pb_info = DWARF_AttrForm_ReadFormat_Address(
371 p_val, pb_info, pqw_remains, p_cuheader->b_pointersize );
373 case DW_FORM_ref1: // 0x11: ref.
374 pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
375 p_val, pb_info, pqw_remains, 1, p_cuheader->pb_custart );
377 case DW_FORM_ref2: // 0x12: ref.
378 pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
379 p_val, pb_info, pqw_remains, 2, p_cuheader->pb_custart );
381 case DW_FORM_ref4: // 0x13: ref.
382 pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
383 p_val, pb_info, pqw_remains, 4, p_cuheader->pb_custart );
385 case DW_FORM_ref8: // 0x14: ref.
386 pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
387 p_val, pb_info, pqw_remains, 8, p_cuheader->pb_custart );
389 case DW_FORM_ref_udata: // 0x15: ref.
390 pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
391 p_val, pb_info, pqw_remains, -1, p_cuheader->pb_custart );
393 case DW_FORM_indirect: // 0x16: ref.
394 pb_info = DWARF_AttrForm_ReadFormat_InDirect(
395 p_val, pb_info, pqw_remains, p_binfo, p_cuheader );
397 case DW_FORM_sec_offset: // 0x17:
398 // offset from the beginning of the .debug_line section
399 // to the first byte of the data making up the line number list for the compilation unit.
400 // 1: const. value (size: offsetsize)
401 pb_info = DWARF_AttrForm_ReadFormat_Offset(
402 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
404 case DW_FORM_exprloc: // 0x18:
405 // 1: uLEB128 = length
406 // 2: info. bytes specified by the length(1:) (DWARF expression)
407 pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, -1);
409 case DW_FORM_flag_present: // 0x19:
410 // have NONE value because implicitly flag is TRUE.
413 case DW_FORM_ref_sig8: // 0x20:
414 // 1: pointer (8byte)
415 pb_info = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_info, pqw_remains );
416 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
419 case DW_FORM_GNU_ref_alt: // 0x1f20:
420 pb_info = DWARF_AttrForm_ReadFormat_Offset(
421 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
423 case DW_FORM_GNU_strp_alt: // 0x1f21:
424 pb_info = DWARF_AttrForm_ReadFormat_Offset(
425 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
435 /*----------------------------------------------------------------------
436 ----------------------------------------------------------------------*/
437 LIBGOBLIN_DWARF_ATTRFORM_EXTERN
439 DWARF_AttrForm_ReadDIEValue(
442 DWARF_AbbrevEntry *p_abbrev,
443 LibGoblin_BinaryInfo *p_binfo,
444 LibGoblin_DWARF_Info_CUHeader *p_cuheader )
449 LibGoblin_DWARF_DIEValue *p_val;
451 // Read Debug Information Entry (DIE) ---
452 memset( p_binfo->dwarf.p_infoval, 0x00, sizeof( LibGoblin_DWARF_DIEValue ) * p_abbrev->i_items );
453 p_val = p_binfo->dwarf.p_infoval;
455 memset( p_binfo->dwarf.t_attr, 0x00, sizeof( p_binfo->dwarf.t_attr) );
456 p_binfo->dwarf.i_extattrs = 0;
458 for( i_cnt = 0; i_cnt < p_abbrev->i_items; i_cnt++, p_val++ ) {
459 pb_info = DWARF_AttrForm_ReadFormat_Data(
460 p_val, pb_info, pqw_remains, p_abbrev->dw_format[i_cnt], p_binfo, p_cuheader );
462 dw_attribute = p_abbrev->dw_attribute[ i_cnt ];
463 if( LIBGOBLIN_DWARF_ATTR_DEF_MAX >= dw_attribute ) {
464 p_binfo->dwarf.t_attr[dw_attribute].dw_attribute = dw_attribute;
465 p_binfo->dwarf.t_attr[dw_attribute].p_val = p_val;
467 else if( LIBGOBLIN_DWARF_ATTR_MAX >= dw_attribute ) {
468 dw_ext = LIBGOBLIN_DWARF_ATTR_DEF_MAX + 1 + p_binfo->dwarf.i_extattrs;
469 p_binfo->dwarf.t_attr[dw_ext].dw_attribute = dw_attribute;
470 p_binfo->dwarf.t_attr[dw_ext].p_val = p_val;
471 p_binfo->dwarf.i_extattrs++;
482 /*----------------------------------------------------------------------
483 ----------------------------------------------------------------------*/
484 LIBGOBLIN_DWARF_ATTRFORM_EXTERN
485 LibGoblin_DWARF_DIEValue *
486 DWARF_AttrForm_GetDIEValue(
487 LibGoblin_BinaryInfo *p_binfo,
491 LibGoblin_DWARF_DIEValue *p_retval = NULL;
493 assert( NULL != p_binfo );
495 if( LIBGOBLIN_DWARF_ATTR_MAX < dw_attribute ) {
496 goto goto_DWARF_AttrForm_GetDIEValue_post;
499 if( LIBGOBLIN_DWARF_ATTR_DEF_MAX >= dw_attribute ) {
500 p_retval = p_binfo->dwarf.t_attr[dw_attribute].p_val;
501 goto goto_DWARF_AttrForm_GetDIEValue_post;
504 for( i_cnt = (LIBGOBLIN_DWARF_ATTR_DEF_MAX + 1); i_cnt <= LIBGOBLIN_DWARF_ATTR_MAX; i_cnt++ ) {
505 if( p_binfo->dwarf.t_attr[i_cnt].dw_attribute == dw_attribute ) {
506 p_retval = p_binfo->dwarf.t_attr[dw_attribute].p_val;
511 goto_DWARF_AttrForm_GetDIEValue_post:
516 /*----------------------------------------------------------------------
517 ----------------------------------------------------------------------*/
518 LIBGOBLIN_DWARF_ATTRFORM_EXTERN
520 DWARF_AttrForm_ExtensionDIEValue(
521 LibGoblin_DWARF_DIEValue *p_val )
525 if( LIBGOBLIN_DWARF_INFO_TYPE_BYTE == p_val->b_type )
526 { qw_value = (QWord)p_val->value.b_value; }
527 else if( LIBGOBLIN_DWARF_INFO_TYPE_WORD == p_val->b_type )
528 { qw_value = (QWord)p_val->value.w_value; }
529 else if( LIBGOBLIN_DWARF_INFO_TYPE_DWORD == p_val->b_type )
530 { qw_value = (QWord)p_val->value.dw_value; }
531 else if( LIBGOBLIN_DWARF_INFO_TYPE_QWORD == p_val->b_type )
532 { qw_value = (QWord)p_val->value.qw_value; }
536 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
537 p_val->value.qw_value = qw_value;
544 /* EOF of drd64_.c ----------------------------------- */