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_INFO
38 #include"drd64_libgoblin.h"
40 /*----------------------------------------------------------------------
41 ----------------------------------------------------------------------*/
43 DWARF_Info_ReadFormat_Ref_inCU(
44 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_Info_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_Info_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_Info_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_Info_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_Info_ReadFormat_InDirect(
248 LibGoblin_DWARF_DIEValue *p_val,
251 LibGoblin_BinaryInfo *p_binfo,
252 LibGoblin_DWARF_Info_CUHeader *p_cuheader )
257 // Get InDirect DW_FORM_*** value. ---
258 pb_info = DWARF_Common_DecodeULEB128( &qw_size, pb_info, pqw_remains );
259 dw_form = (DWord)qw_size;
261 // Re-Call Read FormatData Function ---
262 pb_info = DWARF_Info_ReadFormat_Data(
263 p_val, pb_info, pqw_remains, dw_form, p_binfo, p_cuheader );
269 /*----------------------------------------------------------------------
270 ----------------------------------------------------------------------*/
272 DWARF_Info_ReadFormat_Data(
273 LibGoblin_DWARF_DIEValue *p_val,
277 LibGoblin_BinaryInfo *p_binfo,
278 LibGoblin_DWARF_Info_CUHeader *p_cuheader )
282 switch( dw_format ) {
283 case DW_FORM_addr: // 0x01: address
284 pb_info = DWARF_Info_ReadFormat_Address(
285 p_val, pb_info, pqw_remains, p_cuheader->b_pointersize );
287 case DW_FORM_block2: // 0x03: block
288 pb_info = DWARF_Info_ReadFormat_Block( p_val, pb_info, pqw_remains, 2);
290 case DW_FORM_block4: // 0x04: block
291 pb_info = DWARF_Info_ReadFormat_Block( p_val, pb_info, pqw_remains, 4);
293 case DW_FORM_data2: // 0x05: const.
294 pb_info = DWARF_Common_Read_Word( &(p_val->value.w_value), pb_info, pqw_remains );
295 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_WORD;
298 case DW_FORM_data4: // 0x06: const. line/loc/mac/rng-ptr
299 pb_info = DWARF_Common_Read_DWord( &(p_val->value.dw_value), pb_info, pqw_remains );
300 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_DWORD;
303 case DW_FORM_data8: // 0x07: const. line/loc/mac/rng-ptr
304 pb_info = DWARF_Common_Read_QWord( &(p_val->value.qw_value), pb_info, pqw_remains );
305 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
308 case DW_FORM_string: // 0x08: string
309 pb_info = DWARF_Info_ReadFormat_String( p_val, pb_info, pqw_remains );
311 case DW_FORM_block: // 0x09: block
312 pb_info = DWARF_Info_ReadFormat_Block( p_val, pb_info, pqw_remains, -1);
314 case DW_FORM_block1: // 0x0a: block
315 pb_info = DWARF_Info_ReadFormat_Block( p_val, pb_info, pqw_remains, 1);
317 case DW_FORM_data1: // 0x0b: const.
318 pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
319 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
322 case DW_FORM_flag: // 0x0c: flag
323 pb_info = DWARF_Common_Read_Byte( &(p_val->value.b_value), pb_info, pqw_remains );
324 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_BYTE;
327 case DW_FORM_sdata: // 0x0d: sdata
328 pb_info = DWARF_Common_DecodeLEB128( &(p_val->value.ii_value), pb_info, pqw_remains );
329 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_INT64;
332 case DW_FORM_strp: // 0x0e: string (in .debug_str section)
333 pb_info = DWARF_Info_ReadFormat_Strp(
334 p_val, pb_info, pqw_remains, p_binfo, p_cuheader->b_offsetsize );
336 case DW_FORM_udata: // 0x0f: const.
337 pb_info = DWARF_Common_DecodeULEB128( &(p_val->value.qw_value), pb_info, pqw_remains );
338 p_val->b_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
341 case DW_FORM_ref_addr: // 0x10: ref.
342 pb_info = DWARF_Info_ReadFormat_Address(
343 p_val, pb_info, pqw_remains, p_cuheader->b_pointersize );
345 case DW_FORM_ref1: // 0x11: ref.
346 pb_info = DWARF_Info_ReadFormat_Ref_inCU(
347 p_val, pb_info, pqw_remains, 1, p_cuheader->pb_custart );
349 case DW_FORM_ref2: // 0x12: ref.
350 pb_info = DWARF_Info_ReadFormat_Ref_inCU(
351 p_val, pb_info, pqw_remains, 2, p_cuheader->pb_custart );
353 case DW_FORM_ref4: // 0x13: ref.
354 pb_info = DWARF_Info_ReadFormat_Ref_inCU(
355 p_val, pb_info, pqw_remains, 4, p_cuheader->pb_custart );
357 case DW_FORM_ref8: // 0x14: ref.
358 pb_info = DWARF_Info_ReadFormat_Ref_inCU(
359 p_val, pb_info, pqw_remains, 8, p_cuheader->pb_custart );
361 case DW_FORM_ref_udata: // 0x15: ref.
362 pb_info = DWARF_Info_ReadFormat_Ref_inCU(
363 p_val, pb_info, pqw_remains, -1, p_cuheader->pb_custart );
365 case DW_FORM_indirect: // 0x16: ref.
366 pb_info = DWARF_Info_ReadFormat_InDirect(
367 p_val, pb_info, pqw_remains, p_binfo, p_cuheader );
369 case DW_FORM_sec_offset: // 0x17:
371 case DW_FORM_exprloc: // 0x18:
373 case DW_FORM_flag_present: // 0x19:
375 case DW_FORM_ref_sig8: // 0x20:
377 case DW_FORM_GNU_ref_alt: // 0x1f20:
379 case DW_FORM_GNU_strp_alt: // 0x1f21:
389 /*----------------------------------------------------------------------
390 ----------------------------------------------------------------------*/
392 DWARF_Info_ReadCUHeader(
393 LibGoblin_DWARF_Info_CUHeader *p_cuhead,
395 QWord *pqw_size_info )
402 assert( NULL != p_cuhead );
403 assert( NULL != pb_info );
408 // Read unit_length (4Byte + 8Byte(64bit)) ---
409 pb_info = DWARF_Common_Read_DWord( &dw_dword, pb_info, pqw_size_info );
410 if( NULL == pb_info ) { return NULL; }
412 // 64bit - First 4Byte = 0xffffffff
413 if( ((DWord)0xffffffff) == dw_dword ) {
414 pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
415 if( NULL == pb_info ) { return NULL; }
417 p_cuhead->qw_unitsize = (QWord)qw_qword;
419 p_cuhead->b_bits = 64;
420 p_cuhead->b_offsetsize = 8;
422 // 32bit - First 4Byte = value.
424 p_cuhead->qw_unitsize = (QWord)dw_dword;
425 p_cuhead->b_bits = 32;
426 p_cuhead->b_offsetsize = 4;
429 // Read version (2Byte) ---
430 pb_info = DWARF_Common_Read_Word( &(p_cuhead->w_version), pb_info, pqw_size_info );
431 if( NULL == pb_info ) { return NULL; }
434 // Read abbrev_offset (4Byte(32bit), 8Byte(64bit)) ---
435 if( 64 == i_bitflag ) {
436 pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
437 if( NULL == pb_info ) { return NULL; }
440 p_cuhead->qw_abbrev_offset = qw_qword;
443 pb_info = DWARF_Common_Read_DWord( &dw_dword, pb_info, pqw_size_info );
444 if( NULL == pb_info ) { return NULL; }
447 p_cuhead->qw_abbrev_offset = (QWord)dw_dword;
450 // Read address_size (1Byte) ---
451 pb_info = DWARF_Common_Read_Byte( &(p_cuhead->b_pointersize), pb_info, pqw_size_info);
452 if( NULL == pb_info ) { return NULL; }
455 p_cuhead->qw_unitsize -= i_readbytes;
461 /*----------------------------------------------------------------------
462 ----------------------------------------------------------------------*/
463 LIBGOBLIN_DWARF_INFO_EXTERN
466 LibGoblin_BinaryInfo *p_binfo )
481 LibGoblin_SectionInfo *psec_info;
482 LibGoblin_BinaryFile *p_bfile;
483 DWARF_AbbrevEntry *p_abbrev;
484 DWARF_AbbrevEntry *p_arvnow;
485 LibGoblin_DWARF_DIEValue *p_infoval;
486 LibGoblin_DWARF_DIEValue *p_val;
487 LibGoblin_DWARF_Info_CUHeader t_cuheader;
489 assert( NULL != p_binfo );
491 p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile );
492 assert( NULL != p_bfile );
494 i_srcfiles = p_bfile->dwarf.i_srcfiles;
496 p_infoval = p_bfile->dwarf.p_infoval;
498 // Get section Info ---
499 psec_info = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_INFO );
500 assert( NULL != psec_info );
501 if( NULL == psec_info->pb_data ) {
504 pb_info = psec_info->pb_data;
505 qw_size_info = psec_info->qw_size;
508 // Read Compile Unit Header ---
509 pb_custart = pb_info;
510 pb_info = DWARF_Info_ReadCUHeader( &t_cuheader, pb_info, &qw_size_info );
511 if( NULL == pb_info ) {
515 t_cuheader.pb_custart = pb_custart;
516 qw_size_cu = t_cuheader.qw_unitsize;
518 printf( "size: %ld, ver:%d, abbrev off.:%ld, addr.size: %d\n",
519 t_cuheader.qw_unitsize,
520 t_cuheader.w_version,
521 t_cuheader.qw_abbrev_offset,
522 t_cuheader.b_pointersize);
525 i_result = DWARF_Abbrev_ReadAbbrevEntry(
526 &p_abbrev, &i_abbrevs,
527 p_binfo, p_bfile, t_cuheader.qw_abbrev_offset );
531 // Read Reference Abbrev-ID ---
532 pb_info = DWARF_Common_DecodeULEB128( &qw_temp, pb_info, &qw_size_cu );
533 dw_arvid = (DWord)qw_temp;
535 if( 0 == dw_arvid ) {
540 p_arvnow = p_abbrev + (dw_arvid - 1);
542 // Read Debug Information Entry (DIE) ---
543 memset( p_infoval, 0x00, sizeof( LibGoblin_DWARF_DIEValue ) * p_arvnow->i_items );
546 for( i_cnt = 0; i_cnt < p_arvnow->i_items; i_cnt++, p_val++ ) {
547 dw_attribute = p_arvnow->dw_attribute[ i_cnt ];
548 dw_format = p_arvnow->dw_format[ i_cnt ];
550 pb_info = DWARF_Info_ReadFormat_Data(
551 p_val, pb_info, &qw_size_cu, dw_format, p_binfo, &t_cuheader );
554 if( 0x00 != p_arvnow->b_children ) { i_childlv++; }
556 // Dispatch for generate Rapid-Access Table by DIE-tag
558 Debug_DWARF_PrintDIE( p_bfile, p_abbrev, dw_arvid, i_childlv );
560 }while( 0 != qw_size_cu );
561 qw_size_info -= t_cuheader.qw_unitsize;
563 //}while((qw_size_info > 0) && (i_srcfiles > 0));
572 /* EOF of drd64_.c ----------------------------------- */