+/*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
+
+ D r . D e a m o n 6 4
+ for INTEL64(R), AMD64(R)
+
+ Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY Koine Yuusuke(koinec) ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL Koine Yuusuke(koinec) OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
+
+/* File Info -----------------------------------------------------------
+File: drd64_.c
+Function:
+Comment:
+----------------------------------------------------------------------*/
+
+#define DRD64_SRC_LIBGOBLIN_DWARF_ATTRFORM
+#include"drd64_libgoblin.h"
+
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+Byte *
+ DWARF_AttrForm_ReadFormat_Ref_inCU(
+ LibGoblin_DWARF_DIEValue *p_val,
+ Byte *pb_src,
+ QWord *pqw_remain,
+ Byte b_bytes,
+ Byte *pb_custart )
+{
+ Byte b_size;
+ Word w_size;
+ DWord dw_size;
+ QWord qw_size;
+
+ assert( NULL != pb_src );
+ assert( NULL != p_val );
+
+ if( 1 == b_bytes ) {
+ pb_src = DWARF_Common_Read_Byte( &b_size, pb_src, pqw_remain );
+ qw_size = (QWord)b_size;
+ }
+ else if( 2 == b_bytes ) {
+ pb_src = DWARF_Common_Read_Word( &w_size, pb_src, pqw_remain );
+ qw_size = (QWord)w_size;
+ }
+ else if( 4 == b_bytes ) {
+ pb_src = DWARF_Common_Read_DWord( &dw_size, pb_src, pqw_remain );
+ qw_size = (QWord)dw_size;
+ }
+ else if( 8 == b_bytes ) {
+ pb_src = DWARF_Common_Read_QWord( &qw_size, pb_src, pqw_remain );
+ }
+ else {
+ pb_src = DWARF_Common_DecodeULEB128( &qw_size, pb_src, pqw_remain );
+ }
+ if( NULL == pb_src ) { return NULL; }
+
+ p_val->value.pb_link = pb_custart + qw_size;
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_LINK;
+ p_val->qw_size = (QWord)b_bytes;
+
+ return pb_src;
+}
+
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+Byte *
+ DWARF_AttrForm_ReadFormat_Block(
+ LibGoblin_DWARF_DIEValue *p_val,
+ Byte *pb_src,
+ QWord *pqw_remain,
+ int i_sizebytes )
+{
+ Byte b_size;
+ Word w_size;
+ DWord dw_size;
+ QWord qw_size;
+
+ assert( NULL != pb_src );
+ assert( NULL != p_val );
+
+ if( 1 == i_sizebytes ) {
+ pb_src = DWARF_Common_Read_Byte( &b_size, pb_src, pqw_remain );
+ qw_size = (QWord)b_size;
+ }
+ else if( 2 == i_sizebytes ) {
+ pb_src = DWARF_Common_Read_Word( &w_size, pb_src, pqw_remain );
+ qw_size = (QWord)w_size;
+ }
+ else if( 4 == i_sizebytes ) {
+ pb_src = DWARF_Common_Read_DWord( &dw_size, pb_src, pqw_remain );
+ qw_size = (QWord)dw_size;
+ }
+ else if( 8 == i_sizebytes ) {
+ pb_src = DWARF_Common_Read_QWord( &qw_size, pb_src, pqw_remain );
+ }
+ else {
+ pb_src = DWARF_Common_DecodeULEB128( &qw_size, pb_src, pqw_remain );
+ }
+
+ if( *pqw_remain >= qw_size ) {
+ p_val->qw_size = qw_size;
+ p_val->value.pb_data = pb_src;
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_BLOCK;
+ pb_src += qw_size;
+ *pqw_remain -= qw_size;
+ }
+ else { pb_src = NULL; }
+
+ return pb_src;
+}
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+Byte *
+ DWARF_AttrForm_ReadFormat_Strp(
+ LibGoblin_DWARF_DIEValue *p_val,
+ Byte *pb_src,
+ QWord *pqw_remain,
+ LibGoblin_BinaryInfo *p_binfo,
+ Byte b_bits )
+{
+ Byte *pb_string = NULL;
+ QWord qw_offset;
+ DWord dw_offset;
+ LibGoblin_SectionInfo *psec_dbgstr;
+
+ assert( NULL != pb_src );
+ assert( NULL != p_val );
+
+ psec_dbgstr = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_STR );
+ assert( NULL != psec_dbgstr );
+ assert( NULL != psec_dbgstr->pb_data );
+
+ if( 8 == b_bits ) {
+ pb_src = DWARF_Common_Read_QWord( &qw_offset, pb_src, pqw_remain );
+ pb_string = psec_dbgstr->pb_data + qw_offset;
+ }
+ else if( 4 == b_bits ) {
+ pb_src = DWARF_Common_Read_DWord( &dw_offset, pb_src, pqw_remain );
+ pb_string = psec_dbgstr->pb_data + dw_offset;
+ }
+
+ p_val->value.pstr_value = (char *)pb_string;
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_STRING;
+ p_val->qw_size = 0;
+
+ return pb_src;
+}
+
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+Byte *
+ DWARF_AttrForm_ReadFormat_String(
+ LibGoblin_DWARF_DIEValue *p_val,
+ Byte *pb_src,
+ QWord *pqw_remain )
+{
+ Byte *pb_now;
+ QWord qw_size = 0;
+
+ assert( NULL != pb_src );
+ assert( NULL != p_val );
+
+ pb_now = pb_src;
+
+ while( (0 < *pqw_remain) && ('\0' != *pb_now) ) {
+ pb_now++;
+ qw_size++;
+ (*pqw_remain)--;
+ }
+
+ if( 0 < *pqw_remain ) {
+ p_val->value.pstr_value = (char *)pb_src;
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_STRING;
+ p_val->qw_size = qw_size;
+
+ pb_now++;
+ (*pqw_remain)--;
+ }
+
+ return pb_now;
+}
+
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+Byte *
+ DWARF_AttrForm_ReadFormat_Address(
+ LibGoblin_DWARF_DIEValue *p_val,
+ Byte *pb_src,
+ QWord *pqw_remain,
+ Byte b_pointersize )
+{
+ assert( NULL != pb_src );
+ assert( NULL != p_val );
+
+ if( 8 == b_pointersize ) {
+ pb_src = DWARF_Common_Read_QWord(
+ &(p_val->value.qw_value), pb_src, pqw_remain );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
+ p_val->qw_size = 8;
+ }
+ else if( 4 == b_pointersize ) {
+ pb_src = DWARF_Common_Read_DWord(
+ &(p_val->value.dw_value), pb_src, pqw_remain );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
+ p_val->qw_size = 4;
+ }
+ else if( 2 == b_pointersize ) {
+ pb_src = DWARF_Common_Read_Word(
+ &(p_val->value.w_value), pb_src, pqw_remain );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
+ p_val->qw_size = 2;
+ }
+
+ return pb_src;
+}
+
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+Byte *
+ DWARF_AttrForm_ReadFormat_Offset(
+ LibGoblin_DWARF_DIEValue *p_val,
+ Byte *pb_src,
+ QWord *pqw_remain,
+ LibGoblin_BinaryInfo *p_binfo,
+ Byte b_bits )
+{
+ assert( NULL != pb_src );
+ assert( NULL != p_val );
+
+ if( 8 == b_bits ) {
+ pb_src = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_src, pqw_remain );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
+ p_val->qw_size = 8;
+ }
+ else if( 4 == b_bits ) {
+ pb_src = DWARF_Common_Read_DWord( &(p_val->value.dw_value), pb_src, pqw_remain );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
+ p_val->qw_size = 4;
+ }
+
+ return pb_src;
+}
+
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+Byte *
+ DWARF_AttrForm_ReadFormat_InDirect(
+ LibGoblin_DWARF_DIEValue *p_val,
+ Byte *pb_info,
+ QWord *pqw_remains,
+ LibGoblin_BinaryInfo *p_binfo,
+ LibGoblin_DWARF_Info_CUHeader *p_cuheader )
+{
+ QWord qw_size;
+ DWord dw_form;
+
+ // Get InDirect DW_FORM_*** value. ---
+ pb_info = DWARF_Common_DecodeULEB128( &qw_size, pb_info, pqw_remains );
+ dw_form = (DWord)qw_size;
+
+ // Re-Call Read FormatData Function ---
+ pb_info = DWARF_AttrForm_ReadFormat_Data(
+ p_val, pb_info, pqw_remains, dw_form, p_binfo, p_cuheader );
+
+ return pb_info;
+}
+
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+LIBGOBLIN_DWARF_ATTRFORM_EXTERN
+Byte *
+ DWARF_AttrForm_ReadFormat_Data(
+ LibGoblin_DWARF_DIEValue *p_val,
+ Byte *pb_info,
+ QWord *pqw_remains,
+ DWord dw_format,
+ LibGoblin_BinaryInfo *p_binfo,
+ LibGoblin_DWARF_Info_CUHeader *p_cuheader )
+{
+ switch( dw_format ) {
+ case DW_FORM_addr: // 0x01: address
+ pb_info = DWARF_AttrForm_ReadFormat_Address(
+ p_val, pb_info, pqw_remains, p_cuheader->b_pointersize );
+ break;
+ case DW_FORM_block2: // 0x03: block
+ pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, 2);
+ break;
+ case DW_FORM_block4: // 0x04: block
+ pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, 4);
+ break;
+ case DW_FORM_data2: // 0x05: const.
+ pb_info = DWARF_Common_Read_Word( &(p_val->value.w_value), pb_info, pqw_remains );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
+ p_val->qw_size = 2;
+ break;
+ case DW_FORM_data4: // 0x06: const. line/loc/mac/rng-ptr
+ pb_info = DWARF_Common_Read_DWord( &(p_val->value.dw_value), pb_info, pqw_remains );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
+ p_val->qw_size = 4;
+ break;
+ case DW_FORM_data8: // 0x07: const. line/loc/mac/rng-ptr
+ pb_info = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_info, pqw_remains );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
+ p_val->qw_size = 8;
+ break;
+ case DW_FORM_string: // 0x08: string
+ pb_info = DWARF_AttrForm_ReadFormat_String( p_val, pb_info, pqw_remains );
+ break;
+ case DW_FORM_block: // 0x09: block
+ pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, -1);
+ break;
+ case DW_FORM_block1: // 0x0a: block
+ pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, 1);
+ break;
+ case DW_FORM_data1: // 0x0b: const.
+ pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
+ p_val->qw_size = 1;
+ break;
+ case DW_FORM_flag: // 0x0c: flag
+ pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
+ p_val->qw_size = 1;
+ break;
+ case DW_FORM_sdata: // 0x0d: sdata
+ pb_info = DWARF_Common_DecodeLEB128( &(p_val->value.ii_value), pb_info, pqw_remains );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_INT64;
+ p_val->qw_size = 8;
+ break;
+ case DW_FORM_strp: // 0x0e: string (in .debug_str section)
+ pb_info = DWARF_AttrForm_ReadFormat_Strp(
+ p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
+ break;
+ case DW_FORM_udata: // 0x0f: const.
+ pb_info = DWARF_Common_DecodeULEB128( &(p_val->value.qw_value), pb_info, pqw_remains );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
+ p_val->qw_size = 8;
+ break;
+ case DW_FORM_ref_addr: // 0x10: ref.
+ pb_info = DWARF_AttrForm_ReadFormat_Address(
+ p_val, pb_info, pqw_remains, p_cuheader->b_pointersize );
+ break;
+ case DW_FORM_ref1: // 0x11: ref.
+ pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
+ p_val, pb_info, pqw_remains, 1, p_cuheader->pb_custart );
+ break;
+ case DW_FORM_ref2: // 0x12: ref.
+ pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
+ p_val, pb_info, pqw_remains, 2, p_cuheader->pb_custart );
+ break;
+ case DW_FORM_ref4: // 0x13: ref.
+ pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
+ p_val, pb_info, pqw_remains, 4, p_cuheader->pb_custart );
+ break;
+ case DW_FORM_ref8: // 0x14: ref.
+ pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
+ p_val, pb_info, pqw_remains, 8, p_cuheader->pb_custart );
+ break;
+ case DW_FORM_ref_udata: // 0x15: ref.
+ pb_info = DWARF_AttrForm_ReadFormat_Ref_inCU(
+ p_val, pb_info, pqw_remains, -1, p_cuheader->pb_custart );
+ break;
+ case DW_FORM_indirect: // 0x16: ref.
+ pb_info = DWARF_AttrForm_ReadFormat_InDirect(
+ p_val, pb_info, pqw_remains, p_binfo, p_cuheader );
+ break;
+ case DW_FORM_sec_offset: // 0x17:
+ // offset from the beginning of the .debug_line section
+ // to the first byte of the data making up the line number list for the compilation unit.
+ // 1: const. value (size: offsetsize)
+ pb_info = DWARF_AttrForm_ReadFormat_Offset(
+ p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
+ break;
+ case DW_FORM_exprloc: // 0x18:
+ // 1: uLEB128 = length
+ // 2: info. bytes specified by the length(1:) (DWARF expression)
+ pb_info = DWARF_AttrForm_ReadFormat_Block( p_val, pb_info, pqw_remains, -1);
+ break;
+ case DW_FORM_flag_present: // 0x19:
+ // have NONE value because implicitly flag is TRUE.
+ // => NONE Proc.
+ break;
+ case DW_FORM_ref_sig8: // 0x20:
+ // 1: pointer (8byte)
+ pb_info = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_info, pqw_remains );
+ p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
+ p_val->qw_size = 8;
+ break;
+ case DW_FORM_GNU_ref_alt: // 0x1f20:
+ pb_info = DWARF_AttrForm_ReadFormat_Offset(
+ p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
+ break;
+ case DW_FORM_GNU_strp_alt: // 0x1f21:
+ pb_info = DWARF_AttrForm_ReadFormat_Offset(
+ p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
+ break;
+ default:
+ break;
+ }
+
+ return pb_info;
+}
+
+
+/* EOF of drd64_.c ----------------------------------- */