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_ABBREV
38 #include"drd64_libgoblin.h"
40 /*----------------------------------------------------------------------
41 ----------------------------------------------------------------------*/
43 LibGoblin_DwarfInfo_ReadFormat_Ref_inCU(
44 LibGoblin_Dwarf_DIEValue *p_dievalue,
57 assert( NULL != pb_src );
58 assert( NULL != p_dievalue );
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;
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;
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;
75 else if( 8 == i_sizebytes ) {
76 pb_src = LibGoblin_DwarfCommon_Read_QWord(
77 &qw_size, pb_src, pqw_remain );
80 pb_src = DWARF_Common_DecodeULEB128(
81 &qw_size, pb_src, pqw_remain );
83 if( NULL == pb_src ) { return NULL; }
85 pb_link = pb_custart + qw_size;
86 p_dievalue->pb_link = pb_link;
87 *pb_type = LIBGOBLIN_DWARF_INFO_TYPE_LINK;
93 /*----------------------------------------------------------------------
94 ----------------------------------------------------------------------*/
96 LibGoblin_DwarfInfo_ReadFormat_Block(
97 LibGoblin_Dwarf_DIEValue *p_dievalue,
107 assert( NULL != pb_src );
108 assert( NULL != p_dievalue );
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;
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;
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;
125 else if( 8 == i_sizebytes ) {
126 pb_src = LibGoblin_DwarfCommon_Read_QWord(
127 &qw_size, pb_src, pqw_remain );
130 pb_src = DWARF_Common_DecodeULEB128(
131 &qw_size, pb_src, pqw_remain );
134 if( NULL == pb_src ) { return NULL; }
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;
142 *pqw_remain -= qw_size;
148 /*----------------------------------------------------------------------
149 ----------------------------------------------------------------------*/
151 LibGoblin_DwarfInfo_ReadFormat_Strp(
152 LibGoblin_Dwarf_DIEValue *p_dievalue,
158 assert( NULL != pb_src );
159 assert( NULL != p_dievalue );
162 pb_src = LibGoblin_DwarfCommon_Read_QWord(
163 &(p_dievalue->qw_value), pb_src, pqw_remain );
164 *pb_type = LIBGOBLIN_DWARF_INFO_TYPE_QWORD;
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;
174 /*----------------------------------------------------------------------
175 ----------------------------------------------------------------------*/
177 LibGoblin_DwarfInfo_ReadFormat_String(
178 LibGoblin_Dwarf_DIEValue *p_dievalue,
185 assert( NULL != pb_src );
186 assert( NULL != p_dievalue );
190 while( (0 < *pqw_remain) && ('\0' != *pb_now) ) {
195 if( 0 < *pqw_remain ) {
196 p_dievalue->str_value = (char *)pb_src;
197 *pb_type = LIBGOBLIN_DWARF_INFO_TYPE_STRING;
207 /*----------------------------------------------------------------------
208 ----------------------------------------------------------------------*/
210 LibGoblin_DwarfInfo_ReadFormat_Address(
211 LibGoblin_Dwarf_DIEValue *p_dievalue,
217 assert( NULL != pb_src );
218 assert( NULL != p_dievalue );
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;
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;
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;
237 { *pb_type = LIBGOBLIN_DWARF_INFO_TYPE_NONE; }
244 /*----------------------------------------------------------------------
245 ----------------------------------------------------------------------*/
247 LibGoblin_DwarfInfo_ReadDIE(
248 LibGoblin_Dwarf_DIE *p_die,
251 LibGoblin_Dwarf_SourceFile *pt_srcfile,
252 LibGoblin_DwarfCommon_CUHeader *p_cuheader )
262 LibGoblin_Dwarf_AbbrevInfo *p_abbrev;
263 LibGoblin_Dwarf_AbbrevEntry t_abbentry;
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;
271 //printf(" abbrev: %ld\n", dw_abbrev);
273 if( 0x00000000 == dw_abbrev ) { return pb_src; }
275 /* Set Reference Abbrev */
276 p_abbrev = (pt_srcfile->p_abbrev_info) + (dw_abbrev - 1 );
277 if( NULL == p_abbrev ) { return NULL; }
279 pb_abb = p_abbrev->pb_pos;
280 assert( NULL != pb_abb );
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; }
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;
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 ];
294 p_die->dw_attribute[ i_cnt ] = dw_attribute;
295 p_die->dw_format[ i_cnt ] = dw_format;
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) );
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);
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);
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;
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;
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;
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);
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);
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);
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;
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;
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;
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
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;
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) );
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 );
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 );
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 );
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 );
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 );
412 case DW_FORM_indirect: /* 0x16: ref. */
425 /*----------------------------------------------------------------------
426 ----------------------------------------------------------------------*/
428 LibGoblin_DwarfInfo_ReadCompileUnit(
429 LibGoblin_Dwarf_SourceFile *p_src,
431 QWord *pqw_size_info )
434 LibGoblin_DwarfCommon_CUHeader t_cuheader;
435 LibGoblin_Dwarf_DIE t_die;
437 assert( NULL != p_src );
438 assert( NULL != pb_data );
440 if( 0 == *pqw_size_info ) { return NULL; }
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; }
447 qw_unitsize = t_cuheader.qw_unitsize;
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); */
456 /* Read Debug Information Entry (DIE */
457 pb_data = LibGoblin_DwarfInfo_ReadDIE(
458 &t_die, pb_data, &qw_unitsize, p_src, &t_cuheader );
460 /* Dispatch for generate Rapid-Access Table by DIE-tag */
462 }while( 0 != qw_unitsize );
465 *pqw_size_info -= t_cuheader.qw_unitsize;
471 /*----------------------------------------------------------------------
472 ----------------------------------------------------------------------*/
473 LIBGOBLIN_DWARF_INFO_EXTERN
475 LibGoblin_DwarfInfo_Analyze(
476 LibGoblin_BinaryInfo *p_bin )
481 LibGoblin_Dwarf_SourceFile *p_src;
482 LibGoblin_Debug_Dwarf *p_dwarf;
484 assert( NULL != p_bin );
486 p_dwarf = (LibGoblin_Debug_Dwarf *)p_bin->p_debug;
487 assert( NULL != p_dwarf );
489 i_srcfiles = p_dwarf->i_srcfilenum;
491 p_src = p_dwarf->p_src;
492 assert( NULL != p_src );
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; }
501 p_src->t_infosec.pb_pos = pb_data;
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; }
511 }while((qw_size_info > 0) && (i_srcfiles > 0));
518 /* EOF of drd64_.c ----------------------------------- */