static void dump_state( state_info *state ) /*****************************************/ { Wdputs( "-- file " ); Putdec( state->file ); Wdputs( " addr " ); if( state->segment != 0 ) { Puthex( state->segment, 4 ); Wdputs( ":" ); } Puthex( state->address, 8 ); Wdputs( " line " ); Putdec( state->line ); Wdputs( " column " ); Putdec( state->column ); if( state->is_stmt ) { Wdputs( " is_stmt" ); } if( state->basic_block ) { Wdputs( " basic_block" ); } if( state->end_sequence ) { Wdputs( " end_sequence" ); } Wdputslc( "\n" ); }
/* * dump_rtn386 - dump a near or far routine defn (386) */ static void dump_rtn386( unsigned_8 *buff ) /*****************************************/ { int pro,epi; unsigned_32 ret_off; unsigned_8 *ptr; int num_parms; unsigned_16 index; char name[256]; int i; dump_block( buff, TRUE ); ptr = buff + sizeof( block_386 ); pro = *ptr++; epi = *ptr++; Wdputs( " prologue size = " ); Putdec( pro ); Wdputs( ", epilogue size = " ); Putdec( epi ); Wdputslc( "\n" ); ret_off = *(unsigned_32 *) ptr; ptr += sizeof( unsigned_32 ); Wdputs( " return address offset (from bp) = " ); Puthex( ret_off, 8 ); Wdputslc( "\n" ); ptr = Get_type_index( ptr, &index ); Wdputs( " return type: " ); Putdec( index ); Wdputslc( "\n" ); Wdputs( " return value: " ); ptr = Dump_location_expression( ptr, " " ); num_parms = *ptr++; for( i = 0; i < num_parms; i++ ) { Wdputs( " Parm " ); Putdec( i ); Wdputs( ": " ); ptr = Dump_location_expression( ptr, " " ); } Get_local_name( name, ptr, buff ); Wdputs( " Name = \"" ); Wdputs( name ); Wdputslc( "\"\n" ); } /* dump_rtn386 */
/* * dump_section - dump the current section */ void Dump_section( void ) /***********************/ { section_dbg_header sdh; Wread( &sdh, sizeof( section_dbg_header ) ); Wdputs( "Section " ); Putdec( sdh.section_id ); Wdputs( " (off=" ); Puthex( Curr_sectoff, 8 ); Wdputslc( ")\n" ); Wdputslc( "=========================\n" ); Dump_header( (char *)&sdh.mod_offset, sdh_msg ); Wdputslc( "\n" ); currSect = sdh.section_id; if( Debug_options & MODULE_INFO ) { dump_module_info( &sdh ); } if( Debug_options & GLOBAL_INFO ) { dump_global_info( &sdh ); } if( Debug_options & ADDR_INFO ) { dump_addr_info( &sdh ); } } /* dump_section */
/* * bit_field_class - dump info */ static void bit_field_class( unsigned_8 *buff, bool bit ) /*******************************************************/ { unsigned_8 *ptr; unsigned_16 index; char name[256]; ptr = buff+3; Wdputs( " field locator = " ); ptr = Dump_location_expression( ptr, " " ); if( bit ) { ptr += 2; } ptr = Get_type_index( ptr, &index ); Get_local_name( name, ptr, buff ); Wdputs( " name = \"" ); Wdputs( name ); Wdputs( "\" type idx = " ); Putdec( index ); Wdputslc( "\n attribute = " ); attribute_byte( buff[2] ); if( bit ) { Wdputslc( " start bit = " ); ptr++; Puthex( *ptr, 2 ); Wdputslc( " bit size = " ); ptr++; Puthex( *ptr, 2 ); } Wdputslc( "\n" ); }
/* * bit_field_struct - dump info */ static void bit_field_struct( unsigned_8 *buff, unsigned_8 size, bool bit ) /*************************************************************************/ { unsigned_8 *ptr; unsigned_16 index; char name[256]; ptr = buff+2+size; if( bit ) { ptr += 2; } ptr = Get_type_index( ptr, &index ); Get_local_name( name, ptr, buff ); Wdputs( " \"" ); Wdputs( name ); Wdputs( "\" offset = " ); ptr = buff+2; Puthex( *ptr, 2*size ); Wdputs( " type idx = " ); Putdec( index ); if( bit ) { Wdputslc( "\n start bit = " ); ptr++; Puthex( *ptr, 2 ); Wdputslc( " bit size = " ); ptr++; Puthex( *ptr, 2 ); } Wdputslc( "\n" ); }
/* * Dump The Resource Table for Windows NE module */ static void dmp_resrc_tab_win( void ) /***********************************/ { unsigned_16 res_type; auto struct resource_type_record res_group; unsigned_32 offset; Resrc_end = 0ul; Wread( &Resrc_shift_cnt, sizeof( unsigned_16 ) ); offset = New_exe_off + Os2_head.resource_off + sizeof( unsigned_16 ); Wdputs( "resource shift count: " ); Putdec( Resrc_shift_cnt ); Wdputslc( "\n" ); for( ;; ) { Wlseek( offset ); Wread( &res_group, sizeof( resource_type_record ) ); offset += sizeof( resource_type_record ); res_type = res_group.type; if( res_type == 0 ) { return; } dmp_resrc_type_nam( res_type ); Wlseek( offset ); dmp_resrc_ent( res_group.num_resources ); offset += res_group.num_resources * sizeof( resource_record ); Wdputslc( "\n" ); } }
/* * param_type_index - dump info */ static void param_type_index( unsigned_8 num_params, unsigned_8 *ptr ) /********************************************************************/ { unsigned_8 i; unsigned_16 index; if( *ptr & 0x80 ) { num_params /= 2; } for( i = 0; i < num_params; i++ ) { Wdputslc( "\n" ); Wdputs( " param " ); Putdec( i+1 ); Wdputs( ": type idx = " ); ptr = Get_type_index( ptr, &index ); Putdec( index ); } Wdputslc( "\n" ); }
static void PutRefRegisters( ref_info *registers ) /************************************************/ { Wdputs( "[ " ); if( registers->scope.free > 0 ) { Puthex( registers->scope.stack[ registers->scope.free - 1 ], 8 ); } else { Puthex( 0, 8 ); } Wdputs( " " ); Putdec( registers->file ); Wdputs( " " ); Putdec( registers->line ); Wdputs( " " ); Putdec( registers->column ); Wdputs( " " ); Puthex( registers->dependent, 8 ); Wdputs( " ]" ); }
/* * base_type_index - dump info */ static unsigned_8 *base_type_index( unsigned_8 *buff ) /****************************************************/ { unsigned_16 index; unsigned_8 *ptr; Wdputs( " base type idx = " ); ptr = Get_type_index( buff, &index ); Putdec( index ); Wdputslc( "\n" ); return( ptr ); }
/* * dump_addr_info - dump out address info */ static void dump_addr_info( section_dbg_header *sdh ) /***************************************************/ { unsigned_32 total_bytes; unsigned_32 bytes_read; seg_info *si; long cpos; long basepos; unsigned_32 len; int i; unsigned_32 seg_off; total_bytes = sdh->section_size - sdh->addr_offset; print_info_title( "Addr" ); bytes_read = 0; si = (seg_info *) Wbuff; basepos = cpos = Curr_sectoff + sdh->addr_offset; while( bytes_read < total_bytes ) { Wlseek( cpos ); Wread( Wbuff, sizeof( seg_info ) ); Wlseek( cpos ); len = sizeof( seg_info ) + (si->num-1) * sizeof( addr_info ); Wread( Wbuff, len ); Wdputs( " Base: fileoff = " ); Puthex( cpos-basepos, 8 ); Wdputs( "H seg = " ); Puthex( si->base.segment, 4 ); Wdputs( "H, off = " ); Puthex( si->base.offset, 8 ); Wdputslc( "H\n" ); seg_off = si->base.offset; for( i = 0; i < si->num; i++ ) { Putdecl( i, 6 ); Wdputs( ") fileoff = " ); Puthex( (long) cpos - basepos + sizeof( seg_info) + i * sizeof( addr_info ) - sizeof( addr_info ), 8 ); Wdputs( "H, Size = " ); Puthex( si->addr[i].size, 8 ); Wdputs( "H @" ); Puthex( seg_off, 8 ); Wdputs( "H, mod_index = " ); Putdec( si->addr[i].mod ); Wdputslc( "\n" ); seg_off += si->addr[i].size; } cpos += len; bytes_read += len; } } /* dump_addr_info */
/* * dump_global_info - dump out global info */ static void dump_global_info( section_dbg_header *sdh ) /*****************************************************/ { unsigned_32 total_bytes; unsigned_32 bytes_read; v3_gbl_info *gi; long cpos; char name[256]; total_bytes = sdh->addr_offset - sdh->gbl_offset; print_info_title( "Global" ); bytes_read = 0; gi = (v3_gbl_info *) Wbuff; cpos = Curr_sectoff + sdh->gbl_offset; while( bytes_read < total_bytes ) { Wlseek( cpos ); Wread( Wbuff, sizeof( v3_gbl_info ) + 255 ); bytes_read += sizeof( v3_gbl_info ) + gi->name[0]; cpos += sizeof( v3_gbl_info ) + gi->name[0]; get_len_prefix_string( name, gi->name ); Wdputs( " Name: " ); Wdputs( name ); Wdputslc( "\n" ); Wdputs( " address = " ); Puthex( gi->addr.segment, 4 ); Wdputc( ':' ); Puthex( gi->addr.offset, 8 ); Wdputslc( "\n" ); Wdputs( " module index = " ); Putdec( gi->mod ); Wdputslc( "\n" ); Wdputs( " kind: " ); if( gi->kind & GBL_KIND_STATIC ) { Wdputs( " (static pubdef)" ); } if( gi->kind & GBL_KIND_CODE ) { Wdputs( " (code)" ); } if( gi->kind & GBL_KIND_DATA ) { Wdputs( " (data)" ); } Wdputslc( "\n" ); } Wdputslc( "\n" ); } /* dump_global_info */
/* * printout a resource name */ static void dmp_resrc_nam( unsigned_16 res_type ) /***********************************************/ { char *name; Wdputc( ' ' ); if( res_type & SEG_RESRC_HIGH ) { res_type &= ~SEG_RESRC_HIGH; Wdputs( "resource id: " ); Putdec( res_type ); Wdputslc( "\n" ); } else { name = get_resrc_nam( res_type ); Wdputs( name ); Wdputslc( "\n" ); free( name ); } }
/* * near_far_proc - dump info */ static void near_far_proc( unsigned_8 *buff ) /*******************************************/ { unsigned_8 *ptr; unsigned_16 index; unsigned_8 num_parms; ptr = buff + 2; Wdputs( " return type = " ); num_parms = buff[0] - 4; if( *ptr & 0x80 ) { num_parms--; } ptr = Get_type_index( ptr, &index ); Putdec( index ); ptr++; param_type_index( num_parms, ptr ); }
/* * dump some resource entries */ static void dmp_resrc_ent( unsigned_16 num_resources ) /****************************************************/ { struct resource_record *res_ent_tab; struct resource_record *res_ent; unsigned_16 res_group_size; unsigned_16 res_num; if( num_resources == 0 ) { return; } res_group_size = num_resources * sizeof( struct resource_record ); res_ent = res_ent_tab = Wmalloc( res_group_size ); Wread( res_ent_tab, res_group_size ); for( res_num = 0; res_num != num_resources; res_num++ ) { Wdputs( " # " ); Putdec( res_num + 1 ); dmp_resrc_desc( res_ent++ ); } free( res_ent_tab ); }
/* * printout a resource type name */ static void dmp_resrc_type_nam( unsigned_16 res_type ) /****************************************************/ { char *name; Wdputc( ' ' ); if( res_type & SEG_RESRC_HIGH ) { res_type &= ~SEG_RESRC_HIGH; if( res_type > 15 ) { Wdputs( "Type number: " ); Putdec( res_type ); Wdputslc( "\n" ); } else { Wdputslc( resource_type[ res_type ] ); } } else { name = get_resrc_nam( res_type ); Wdputs( name ); Wdputslc( "\n" ); free( name ); } }
/* * dump_line_numbers - dump line number info */ static void dump_line_numbers( mod_info *mi ) /*******************************************/ { int i,j; unsigned_32 *offs; int cnt; v3_line_segment *li; unsigned_32 coff; unsigned_16 size; cnt = mi->di[DMND_LINES].u.entries; if( cnt == 0 ) { return; } Wdputslc( "\n" ); Wdputslc( " *** Line Numbers ***\n" ); Wdputslc( " ====================\n" ); offs = alloca( (cnt+1) * sizeof( unsigned_32 ) ); if( offs == NULL ) { Wdputslc( "Error! Not enough stack.\n" ); longjmp( Se_env, 1 ); } Wlseek( Curr_sectoff + mi->di[DMND_LINES].info_off ); Wread( offs, (cnt+1) * sizeof( unsigned_32 ) ); Wdputs( " " ); Putdec( cnt ); Wdputslc( " offset entries:\n" ); for( i = 0; i <= cnt; i++ ) { Wdputs( " offset " ); Putdec( i ); Wdputs( " = " ); Puthex( offs[i], 8 ); Wdputslc( "H\n" ); } for( i = 0; i < cnt; i++ ) { Wlseek( Curr_sectoff + offs[i] ); Wread( Wbuff, sizeof( v3_line_segment ) ); li = (v3_line_segment *) Wbuff; coff = 0; for( ;; ) { size = (li->num-1)* sizeof( line_info ); Wread( Wbuff + sizeof( v3_line_segment ), size ); Wdputslc( " -------------------------------------\n" ); Wdputs( " Data " ); Putdec( i ); Wdputs( ": offset " ); Puthex( offs[i], 8 ); Wdputs( "H, addr info off = " ); Puthex( li->segment, 8 ); Wdputs( "H, num = " ); Putdec( li->num ); Wdputslc( "\n" ); for( j = 0; j < li->num; j++ ) { Wdputs( " number =" ); Putdecl( li->line[j].line_number, 5 ); Wdputs( ", code offset = " ); Puthex( li->line[j].code_offset, 8 ); Wdputslc( "H\n" ); } coff += sizeof( v3_line_segment ) + size; if( coff >= (offs[i+1] - offs[i]) ) { break; } Wread( Wbuff, sizeof( v3_line_segment ) ); } } } /* dump_line_numbers */
/* * dump_module_info - dump module info */ static void dump_module_info( section_dbg_header *sdh ) /*****************************************************/ { unsigned_32 bytes_read; mod_info *mi; unsigned_32 total_bytes; long cpos; char name[256]; unsigned_16 index; mod_info *tmi; total_bytes = sdh->gbl_offset - sdh->mod_offset; print_info_title( "Module" ); bytes_read = 0; mi = (mod_info *) Wbuff; tmi = alloca( sizeof( mod_info ) + 255 ); if( tmi == NULL ) { Wdputslc( "Error! Not enough stack.\n" ); longjmp( Se_env, 1 ); } cpos = Curr_sectoff + sdh->mod_offset; index = 0; while( bytes_read < total_bytes ) { Wlseek( cpos ); Wread( Wbuff, sizeof( mod_info ) + 255 ); bytes_read += sizeof( mod_info ) + mi->name[0]; cpos += sizeof( mod_info ) + mi->name[0]; get_len_prefix_string( name, mi->name ); Putdecl( index, 3 ); Wdputs( ") Name: "); Wdputs( name ); Wdputslc( "\n" ); Wdputs( " Language is " ); Wdputs( &Lang_lst[ mi->language ] ); Wdputslc( "\n" ); Wdputs( " Locals: num = " ); Putdec( mi->di[DMND_LOCALS].u.entries ); Wdputs( ", offset = " ); Puthex( mi->di[DMND_LOCALS].info_off, 8 ); Wdputslc( "H\n" ); Wdputs( " Types: num = " ); Putdec( mi->di[DMND_TYPES].u.entries ); Wdputs( ", offset = " ); Puthex( mi->di[DMND_TYPES].info_off, 8 ); Wdputslc( "H\n" ); Wdputs( " Lines: num = " ); Putdec( mi->di[DMND_LINES].u.entries ); Wdputs( ", offset = " ); Puthex( mi->di[DMND_LINES].info_off, 8 ); Wdputslc( "H\n" ); memcpy( tmi, mi, sizeof( mod_info ) + mi->name[0] ); if( Debug_options & LOCALS ) { dump_locals( tmi ); } if( Debug_options & LINE_NUMS ) { dump_line_numbers( tmi ); } if( Debug_options & TYPES ) { dump_types( tmi ); } Wdputslc( "\n" ); index++; } } /* dump_module_info */
/* * dump_locals - dump all local variable information */ static void dump_locals( mod_info *mi ) /*************************************/ { int i; unsigned_32 *offs; int cnt; unsigned_32 coff; unsigned_8 buff[256]; char name[256]; set_base *sb; set_base386 *sb386; unsigned_8 *ptr; addr32_ptr *p32; addr48_ptr *p48; unsigned_16 index; cnt = mi->di[DMND_LOCALS].u.entries; if( cnt == 0 ) { return; } Wdputslc( "\n" ); Wdputslc( " *** Locals ***\n" ); Wdputslc( " ==============\n" ); offs = alloca( (cnt+1) * sizeof( unsigned_32 ) ); if( offs == NULL ) { Wdputslc( "Error! Not enough stack.\n" ); longjmp( Se_env, 1 ); } Wlseek( Curr_sectoff + mi->di[DMND_LOCALS].info_off ); Wread( offs, (cnt+1) * sizeof( unsigned_32 ) ); for( i = 0; i < cnt; i++ ) { coff = 0; Wdputs( " Data " ); Putdec( i ); Wdputs( ": offset " ); Puthex( offs[i], 8 ); Wdputslc( "\n" ); for( ;; ) { Wlseek( coff + Curr_sectoff + offs[i] ); Wread( buff, sizeof( buff ) ); Wdputs( " " ); Puthex( coff, 4 ); Wdputs( ": " ); switch( buff[1] ) { case MODULE: Wdputslc( "MODULE\n" ); ptr = buff+2; p32 = (addr32_ptr *)ptr; ptr += sizeof( addr32_ptr ); ptr = Get_type_index( ptr, &index ); Get_local_name( name, ptr, buff ); Wdputs( " \"" ); Wdputs( name ); Wdputs( "\" addr = " ); Puthex( p32->segment, 4 ); Wdputc( ':' ); Puthex( p32->offset, 4 ); Wdputs( ", type = " ); Putdec( index ); Wdputslc( "\n" ); break; case LOCAL: Wdputslc( "LOCAL\n" ); ptr = buff+2; Wdputs( " address: " ); ptr = Dump_location_expression( ptr, " " ); ptr = Get_type_index( ptr, &index ); Get_local_name( name, ptr, buff ); Wdputs( " name = \"" ); Wdputs( name ); Wdputs( "\", type = " ); Putdec( index ); Wdputslc( "\n" ); break; case MODULE_386: Wdputslc( "MODULE_386\n" ); ptr = buff+2; p48 = (addr48_ptr *)ptr; ptr += sizeof( addr48_ptr ); ptr = Get_type_index( ptr, &index ); Get_local_name( name, ptr, buff ); Wdputs( " \"" ); Wdputs( name ); Wdputs( "\" addr = " ); Puthex( p48->segment, 4 ); Wdputc( ':' ); Puthex( p48->offset, 8 ); Wdputs( ", type = " ); Putdec( index ); Wdputslc( "\n" ); break; case MODULE_LOC: Wdputslc( "MODULE_LOC\n" ); ptr = buff+2; Wdputs( " address: " ); ptr = Dump_location_expression( ptr, " " ); ptr = Get_type_index( ptr, &index ); Get_local_name( name, ptr, buff ); Wdputs( " name = \"" ); Wdputs( name ); Wdputs( "\", type = " ); Putdec( index ); Wdputslc( "\n" ); break; case BLOCK: Wdputslc( "BLOCK\n" ); dump_block( buff, FALSE ); break; case NEAR_RTN: Wdputslc( "NEAR_RTN\n" ); dump_rtn( buff ); break; case FAR_RTN: Wdputslc( "FAR_RTN\n" ); dump_rtn( buff ); break; case BLOCK_386: Wdputslc( "BLOCK_386\n" ); dump_block( buff, TRUE ); break; case NEAR_RTN_386: Wdputslc( "NEAR_RTN_386\n" ); dump_rtn386( buff ); break; case FAR_RTN_386: Wdputslc( "FAR_RTN_386\n" ); dump_rtn386( buff ); break; case MEMBER_SCOPE: Wdputslc( "MEMBER_SCOPE\n" ); index = 5; ptr = buff+2; Wdputs( " parent offset = " ); Puthex( *ptr, 4 ); ptr += 2; if( *ptr & 0x80 ) { index = 6; } Wdputs( " class type = " ); ptr = Get_type_index( ptr, &index ); Putdec( index ); if( buff[0] > index ) { Wdputslc( "\n object ptr type = " ); Puthex( *ptr++, 2 ); Wdputs( " object loc = " ); Dump_location_expression( ptr, " " ); } Wdputslc( "\n" ); break; case ADD_PREV_SEG: Wdputslc( "ADD_PREV_SEG\n" ); Wdputs( " segment increment = " ); Puthex( *(buff+2), 4 ); Wdputslc( "\n" ); break; case SET_BASE: Wdputslc( "SET_BASE\n" ); sb = (set_base *) buff; Wdputs( " base = " ); Puthex( sb->seg, 4 ); Wdputc( ':' ); Puthex( sb->off, 4 ); Wdputslc( "\n" ); break; case SET_BASE_386: Wdputslc( "SET_BASE_386\n" ); sb386 = (set_base386 *) buff; Wdputs( " base = " ); Puthex( sb386->seg, 4 ); Wdputc( ':' ); Puthex( sb386->off, 8 ); Wdputslc( "\n" ); break; } coff += buff[0]; if( coff >= (offs[i+1] - offs[i]) ) { break; } } } } /* dump_locals */
void Dump_lines( const uint_8 *input, uint length ) /*************************************************/ { const uint_8 *p; const uint_8 *stmt_start; uint opcode_base; uint *opcode_lengths; uint u; uint file_index; const uint_8 *name; uint_32 mod_time; uint_32 file_length; uint_32 directory; uint_8 op_code; uint_32 op_len; uint_32 tmp; uint line_range; int line_base; int_32 itmp; int default_is_stmt; state_info state; uint min_instr; uint_32 unit_length; const uint_8 *unit_base; p = input; while( p - input < length ) { unit_length = get_u32( (uint_32 *)p ); p += sizeof( uint_32 ); unit_base = p; Wdputs( "total_length: " ); Puthex( unit_length, 8 ); Wdputslc( "\nversion: " ); Puthex( get_u16( (uint_16 *)p ), 4 ); p += sizeof( uint_16 ); Wdputslc( "\nprologue_length: " ); Puthex( get_u32( (uint_32 *)p ), 8 ); stmt_start = p; stmt_start += get_u32( (uint_32 *)p ); p += sizeof( uint_32 ); stmt_start += sizeof( uint_32 ); min_instr = *p; Wdputslc( "\nminimum_instruction_length: " ); Puthex( min_instr, 2 ); p += 1; default_is_stmt = *p; Wdputslc( "\ndefault_is_stmt: " ); Puthex( default_is_stmt, 2 ); p += 1; line_base = *(int_8 *)p; Wdputslc( "\nline_base: " ); Puthex( line_base, 2 ); p += 1; line_range = *(uint_8 *)p; Wdputslc( "\nline_range: " ); Puthex( line_range, 2 ); p += 1; opcode_base = *p; Wdputslc( "\nopcode_base: " ); Puthex( opcode_base, 2 ); Wdputslc( "\n" ); p += 1; opcode_lengths = malloc( sizeof( uint ) * opcode_base ); Wdputslc( "standard_opcode_lengths:\n" ); for( u = 0; u < opcode_base - 1; ++u ) { opcode_lengths[ u ] = *p; ++p; Putdecl( u, 4 ); Wdputs( ": " ); Putdec( opcode_lengths[ u ] ); Wdputslc( "\n" ); } Wdputs( "-- current_offset = " ); Puthex( p - input, 8 ); Wdputslc( "\n" ); if( p - input >= length ) return; Wdputslc( "include directories\n" ); file_index = 0; while( *p != 0 ) { ++file_index; name = p; p += strlen( (char *)p ) + 1; Wdputs( "path " ); Putdec( file_index ); Wdputs( ": '" ); Wdputs( (char *)name ); Wdputslc( "'\n" ); if( p - input >= length ) return; } p++; Wdputslc( "file names\n" ); file_index = 0; while( *p != 0 ) { ++file_index; name = p; p += strlen( (char *)p ) + 1; p = DecodeULEB128( p, &directory ); p = DecodeULEB128( p, &mod_time ); p = DecodeULEB128( p, &file_length ); Wdputs( "file " ); Putdec( file_index ); Wdputs( ": '" ); Wdputs( (char *)name ); Wdputs( "' directory " ); Putdec( directory ); Wdputs( " mod_time " ); Puthex( mod_time, 8 ); Wdputs( " length " ); Puthex( file_length, 8 ); Wdputslc( "\n" ); if( p - input >= length ) return; } p++; init_state( &state, default_is_stmt ); Wdputs( "-- current_offset = " ); Puthex( p - input, 8 ); if( p != stmt_start ) { Wdputs( ":***Prologue length off***" ); } Wdputslc( "\n" ); while( p - unit_base < unit_length ) { op_code = *p; ++p; if( op_code == 0 ) { /* extended op_code */ p = DecodeULEB128( p, &op_len ); Wdputs( "len: " ); Putdecl( op_len, 3 ); Wdputc( ' ' ); op_code = *p; ++p; --op_len; switch( op_code ) { case DW_LNE_end_sequence: Wdputslc( "END_SEQUENCE\n" ); state.end_sequence = 1; dump_state( &state ); init_state( &state, default_is_stmt ); p+= op_len; break; case DW_LNE_set_address: Wdputs( "SET_ADDRESS " ); if( op_len == 4 ) { tmp = get_u32( (uint_32 *)p ); } else if( op_len == 2 ) { tmp = get_u16( (uint_16 *)p ); } else { tmp = 0xffffffff; } state.address = tmp; Puthex( tmp, op_len*2 ); Wdputslc( "\n" ); p += op_len; break; case DW_LNE_set_segment: Wdputs( "SET_SEGMENT " ); if( op_len == 4 ) { tmp = get_u32( (uint_32 *)p ); } else if( op_len == 2 ) { tmp = get_u16( (uint_16 *)p ); } else { tmp = 0xffffffff; } state.segment = tmp; Puthex( tmp, op_len*2 ); Wdputslc( "\n" ); p += op_len; break; case DW_LNE_define_file: ++file_index; name = p; p += strlen( (char *)p ) + 1; p = DecodeULEB128( p, &directory ); p = DecodeULEB128( p, &mod_time ); p = DecodeULEB128( p, &file_length ); Wdputs( "DEFINE_FILE " ); Putdec( file_index ); Wdputs( ": '" ); Wdputs( (char *)name ); Wdputs( "' directory " ); Putdec( directory ); Wdputs( " mod_time " ); Puthex( mod_time, 8 ); Wdputs( " length " ); Puthex( file_length, 8 ); break; default: Wdputs( "** unknown extended opcode: " ); Puthex( op_code, 2 ); Wdputslc( "\n" ); p += op_len; break; } } else if( op_code < opcode_base ) { get_standard_op( op_code ); switch( op_code ) { case DW_LNS_copy: dump_state( &state ); state.basic_block = 0; break; case DW_LNS_advance_pc: p = DecodeLEB128( p, &itmp ); Putdec( itmp ); state.address += itmp * min_instr; break; case DW_LNS_advance_line: p = DecodeLEB128( p, &itmp ); Putdec( itmp ); state.line += itmp; break; case DW_LNS_set_file: p = DecodeLEB128( p, &itmp ); Putdec( itmp ); state.file = itmp; break; case DW_LNS_set_column: p = DecodeLEB128( p, &itmp ); Putdec( itmp ); state.column = itmp; break; case DW_LNS_negate_stmt: state.is_stmt = !state.is_stmt; break; case DW_LNS_set_basic_block: state.basic_block = 1; break; case DW_LNS_const_add_pc: state.address += ( ( 255 - opcode_base ) / line_range ) * min_instr; break; case DW_LNS_fixed_advance_pc: tmp = get_u16( (uint_16 *)p ); p += sizeof( uint_16 ); Puthex( tmp, 4 ); state.address += tmp; break; default: for( u = 0; u < opcode_lengths[ op_code - 1 ]; ++u ) { p = DecodeLEB128( p, &itmp ); Puthex( itmp, 8 ); } } } else { Wdputs( "SPECIAL " ); Puthex( op_code, 2 ); op_code -= opcode_base; Wdputs( ": addr incr: " ); Putdec( op_code / line_range ); Wdputs( " line incr: " ); Putdec( line_base + op_code % line_range ); state.line += line_base + op_code % line_range; state.address += ( op_code / line_range ) * min_instr; dump_state( &state ); state.basic_block = 0; } Wdputslc( "\n" ); } free( opcode_lengths ); Wdputs( "-- current_offset = " ); Puthex( p - input, 8 ); Wdputslc( "\n" ); } }
static void DmpLoc( uint_8 const *p, uint length, uint addr_size ) /****************************************************************/ { uint_8 const *end; uint_8 op; dw_locop_op opr; int_32 op1s; uint_32 op1u; int_32 op2s; uint_32 addr; end = &p[length]; Wdputslc( "\n Loc expr: " ); if( p == end ) { Wdputslc( "<NULL>\n" ); } while( p < end ) { op = *p; ++p; Wdputs( OpName[ op ] ); opr = LocOpr[ op ]; if( opr == DW_LOP_REG1 || opr == DW_LOP_BRG1 ) { Wdputs( "/" ); } else { Wdputs( " " ); } switch( opr ) { case DW_LOP_NOOP: break; case DW_LOP_ADDR: if( addr_size == 4 ) { addr = *(uint_32 *)p; } else if( addr_size == 2 ) { addr = *(uint_16 *)p; } else if( addr_size == 1 ) { addr = *(uint_8 *)p; } else { addr = 0; } Puthex( addr, addr_size * 2 ); p += addr_size; break; case DW_LOP_OPU1: op1u = *(uint_8 *)p; p += sizeof( uint_8 ); Putdec( op1u ); break; case DW_LOP_OPS1: op1s = *(int_8 *)p; p += sizeof(int_8 ); Putdec( op1s ); break; case DW_LOP_OPU2: op1u = get_u16( (uint_16 *)p ); p += sizeof( uint_16 ); Putdec( op1u ); break; case DW_LOP_OPS2: op1s = get_s16( (int_16 *)p ); p += sizeof( int_16 ); Putdec( op1s ); break; case DW_LOP_OPU4: op1u = get_u32( (uint_32 *)p ); p += sizeof( uint_32 ); Putdec( op1u ); break; case DW_LOP_OPS4: op1s = get_s32( (int_32 *)p ); p += sizeof( int_32 ); Putdec( op1s ); break; case DW_LOP_U128: p = DecodeULEB128( p, &op1u ); Putdec( op1u ); break; case DW_LOP_S128: p = DecodeSLEB128( p, &op1s ); Putdecs( op1s ); break; case DW_LOP_U128_S128: p = DecodeULEB128( p, &op1u ); p = DecodeSLEB128( p, &op2s ); Putdec( op1u ); Wdputs( "," ); Putdecs( op2s ); break; case DW_LOP_LIT1: op1u = op-DW_OP_lit0; op = DW_OP_lit0; break; case DW_LOP_REG1: op1u = op-DW_OP_reg0; op = DW_OP_reg0; Wdputs( RegName[ op1u] ); break; case DW_LOP_BRG1: op1u = op-DW_OP_breg0; p = DecodeSLEB128( p, &op2s ); Wdputs( RegName[ op1u] ); if( op2s < 0 ) { Wdputs( " -" ); op2s = -op2s; } else { Wdputs( " +" ); } Putdec( op2s ); op = DW_OP_breg0; break; } Wdputslc( " " ); } Wdputslc( "\n" ); }
static void dump_ref( const uint_8 *input, uint length ) /******************************************************/ { const uint_8 *p; uint_8 op_code; uint_32 tmp; int_32 itmp; uint_32 unit_length; const uint_8 *unit_base; ref_info registers = { { 0, 0, NULL }, 0L, 1L, 1L, 1 }; p = input; while( p - input < length ) { unit_length = get_u32( (uint_32 *)p ); p += sizeof( uint_32 ); unit_base = p; Wdputs( "total_length: " ); Puthex( get_u32( (uint_32 *)p ), 8 ); Wdputslc( "\n" ); while( p - unit_base < unit_length ) { op_code = *p++; if( op_code < REF_CODE_BASE ) { get_reference_op( op_code ); switch( op_code ) { case REF_BEGIN_SCOPE: Puthex( get_u32( (uint_32 *)p ), 8 ); ScopePush( ®isters.scope, get_u32( (uint_32 *)p ) ); p += sizeof( uint_32 ); break; case REF_END_SCOPE: ScopePop( ®isters.scope ); break; case REF_COPY: Wdputs( " " ); PutRefRegisters( ®isters ); break; case REF_SET_FILE: p = DecodeULEB128( p, &tmp ); Putdec( tmp ); registers.file = tmp; break; case REF_SET_LINE: p = DecodeULEB128( p, &tmp ); Putdec( tmp ); registers.line = tmp; registers.column = 0; break; case REF_SET_COLUMN: p = DecodeULEB128( p, &tmp ); Putdec( tmp ); registers.column = tmp; break; case REF_ADD_LINE: p = DecodeSLEB128( p, &itmp ); Putdecs( itmp ); registers.line += itmp; break; case REF_ADD_COLUMN: p = DecodeULEB128( p, &tmp ); Putdec( tmp ); registers.column += tmp; break; } } else { op_code -= REF_CODE_BASE; Wdputs( "REF line += " ); Putdec( op_code / REF_COLUMN_RANGE ); registers.line += op_code / REF_COLUMN_RANGE; Wdputs( ", column += " ); Putdec( op_code % REF_COLUMN_RANGE ); registers.column += op_code % REF_COLUMN_RANGE; Wdputs( ", " ); Puthex( get_u32( (uint_32 *)p ), 8 ); registers.dependent = get_u32( (uint_32 *)p ); Wdputs( " " ); PutRefRegisters( ®isters ); p += sizeof( uint_32 ); } Wdputslc( "\n" ); } } }
static void StartType( char *name, int index ){ Wdputs( name ); Wdputs( "(" ); Putdec( index ); Wdputslc( ")\n" ); }
/* * Dump the program and section headers. */ static void dmp_prog_sec( unsigned_32 start ) /*******************************************/ { Elf32_Phdr elf_prog; Elf32_Shdr elf_sec; unsigned_32 offset; char *string_table; int i; // grab the string table, if it exists if( Options_dmp & DEBUG_INFO ) { set_dwarf( start ); } if( Elf_head.e_shstrndx ) { offset = Elf_head.e_shoff + Elf_head.e_shstrndx * Elf_head.e_shentsize+start; Wlseek( offset ); Wread( &elf_sec, sizeof( Elf32_Shdr ) ); swap_shdr( &elf_sec ); string_table = Wmalloc( elf_sec.sh_size ); Wlseek( elf_sec.sh_offset + start ); Wread( string_table, elf_sec.sh_size ); } else { string_table = 0; } if( Elf_head.e_phnum ) { Banner( "ELF Program Header" ); offset = Elf_head.e_phoff + start; for( i = 0; i < Elf_head.e_phnum; i++ ) { Wdputs( " Program Header #" ); Putdec( i + 1 ); Wdputslc( "\n" ); if( start != 0 ) { Wdputs("File Offset:"); Puthex( offset, 8 ); Wdputslc( "\n"); } Wlseek( offset ); Wread( &elf_prog, sizeof( Elf32_Phdr ) ); swap_phdr( &elf_prog ); // elf_prog.p_offset += start; //Relocate file pos offset += sizeof( Elf32_Phdr ); Data_count++; dmp_prog_type( elf_prog.p_type ); Dump_header( &elf_prog, elf_prog_msg ); dmp_prog_flgs( elf_prog.p_flags ); if( Options_dmp & (DOS_SEG_DMP | OS2_SEG_DMP) ) { if( Segspec == 0 || Segspec == Data_count ) { Dmp_seg_data( elf_prog.p_offset + start, elf_prog.p_filesz ); } } else if( elf_prog.p_type == PT_NOTE ) { dmp_sec_note( elf_prog.p_offset + start, elf_prog.p_filesz ); } Wdputslc( "\n" ); } } if( Elf_head.e_shnum ) { Banner( "ELF Section Header" ); offset = Elf_head.e_shoff+start; for( i = 0; i < Elf_head.e_shnum; i++ ) { Wlseek( offset ); Wread( &elf_sec, sizeof( Elf32_Shdr ) ); swap_shdr( &elf_sec ); // elf_sec.sh_offset += start; // relocate file pos Wdputs( " Section Header #" ); Putdec( i ); if( string_table ) { Wdputs( " \"" ); Wdputs( &(string_table[elf_sec.sh_name]) ); Wdputs( "\"" ); } Wdputslc( "\n" ); if( start != 0 ) { Wdputs( "File Offset:" ); Puthex( offset, 8 ); Wdputslc( "\n" ); } dmp_sec_type( elf_sec.sh_type ); Dump_header( &elf_sec.sh_name, elf_sec_msg ); dmp_sec_flgs( elf_sec.sh_flags ); if( Options_dmp & FIX_DMP ) { if( elf_sec.sh_type==SHT_REL || elf_sec.sh_type==SHT_RELA ) { Elf32_Shdr rel_sec; Elf32_Rela elf_rela; int loc, ctr, rel_size; Wdputs( "relocation information for section #" ); Putdec( elf_sec.sh_info ); Wlseek( Elf_head.e_shoff + start + Elf_head.e_shentsize * elf_sec.sh_info ); Wread( &rel_sec, sizeof( Elf32_Shdr ) ); swap_shdr( &rel_sec ); if( string_table ) { Wdputs( " \"" ); Wdputs( &string_table[rel_sec.sh_name] ); Wdputs( "\"" ); } else { Wdputs( " no_name (no associated string table)" ); } Wdputslc( ":\n" ); Wdputs( "symbol index refers to section #" ); Putdec( elf_sec.sh_link ); Wdputslc( "\n" ); Wdputslc( "Offset Sym Idx Addend Type Offset Sym Idx Addend Type\n" ); rel_size = (elf_sec.sh_type == SHT_REL ? sizeof( Elf32_Rel ) : sizeof( Elf32_Rela )); for( loc = 0, ctr = 0; loc < elf_sec.sh_size; loc += rel_size, ctr++ ) { Wlseek( elf_sec.sh_offset + start + loc ); Wread( &elf_rela, rel_size ); Puthex( elf_rela.r_offset, 8 ); Wdputc( ' ' ); Puthex( ELF32_R_SYM( elf_rela.r_info ), 8 ); Wdputc( ' ' ); if( elf_sec.sh_type == SHT_RELA ) { Puthex( elf_rela.r_addend, 8 ); } else { Wdputs( "n/a " ); } Wdputc( ' ' ); Puthex( ELF32_R_TYPE( elf_rela.r_info ), 2 ); if( ctr % 2 == 1 ) { Wdputslc( "\n" ); } else { Wdputs( " " ); } } if( ctr % 2 != 0 ) { Wdputslc( "\n" ); } } } if( Options_dmp & DEBUG_INFO ) { Wdputslc( "\n" ); if( string_table ) { dmp_sec_data( &(string_table[elf_sec.sh_name]), elf_sec.sh_type, elf_sec.sh_offset+start, elf_sec.sh_size ); } else { dmp_sec_data( NULL, elf_sec.sh_type, elf_sec.sh_offset+start, elf_sec.sh_size ); } } else if( Options_dmp & OS2_SEG_DMP ) { if( elf_sec.sh_size && elf_sec.sh_type != SHT_NOBITS ) { Wdputslc( "Section dump:\n" ); Dmp_seg_data( elf_sec.sh_offset + start, elf_sec.sh_size ); } } Wdputslc( "\n" ); offset += Elf_head.e_shentsize; } } if( string_table ) { free( string_table ); } }
/* * dump_single_location_entry - dump a single location expression entry */ static unsigned_8 *dump_single_location_entry( unsigned_8 *buff ) /***************************************************************/ { unsigned_8 type; addr32_ptr *p32; addr48_ptr *p48; int i; int num; type = *buff; buff++; switch( type ) { case 0: Wdputslc( "<none>\n" ); break; case BP_OFFSET_BYTE: Wdputs( "BP_OFFSET_BYTE( " ); Puthex( *buff, 2 ); Wdputslc( " )\n" ); buff++; break; case BP_OFFSET_WORD: Wdputs( "BP_OFFSET_WORD( " ); Puthex( *buff, 4 ); Wdputslc( " )\n" ); buff += sizeof( unsigned_16 ); break; case BP_OFFSET_DWORD: Wdputs( "BP_OFFSET_DWORD( " ); Puthex( *buff, 8 ); Wdputslc( " )\n" ); buff += sizeof( unsigned_32 ); break; case CONST_ADDR286: p32 = (addr32_ptr *) buff; buff += sizeof( addr32_ptr ); Wdputs( "CONST_ADDR286( " ); Puthex( p32->segment, 4 ); Wdputc( ':' ); Puthex( p32->offset, 4 ); Wdputslc( " )\n" ); break; case CONST_ADDR386: p48 = (addr48_ptr *) buff; buff += sizeof( addr48_ptr ); Wdputs( "CONST_ADDR386( " ); Puthex( p48->segment, 4 ); Wdputc( ':' ); Puthex( p48->offset, 8 ); Wdputslc( " )\n" ); break; case CONST_INT_1: Wdputs( "CONST_INT_1( " ); Puthex( *buff, 2 ); Wdputslc( " )\n" ); buff++; break; case CONST_INT_2: Wdputs( "CONST_INT_2( " ); Puthex( *buff, 4 ); Wdputslc( " )\n" ); buff += sizeof( unsigned_16 ); break; case CONST_INT_4: Wdputs( "CONST_INT_4( " ); Puthex( *buff, 8 ); Wdputslc( " )\n" ); buff += sizeof( unsigned_32 ); break; case IND_REG_CALLOC_NEAR: Wdputs( "IND_REG_CALLOC_NEAR( " ); Wdputs( regLocStrs[ *buff ] ); Wdputslc( " )\n" ); buff++; break; case IND_REG_CALLOC_FAR: Wdputs( "IND_REG_CALLOC_FAR( " ); Wdputs( regLocStrs[ *buff ] ); Wdputc( ':' ); Wdputs( regLocStrs[ *(buff+1) ] ); Wdputslc( " )\n" ); buff += 2; break; case IND_REG_RALLOC_NEAR: Wdputs( "IND_REG_RALLOC_NEAR( " ); Wdputs( regLocStrs[ *buff ] ); Wdputslc( " )\n" ); buff++; break; case IND_REG_RALLOC_FAR: Wdputs( "IND_REG_RALLOC_FAR( " ); Wdputs( regLocStrs[ *buff ] ); Wdputc( ':' ); Wdputs( regLocStrs[ *(buff+1) ] ); Wdputslc( " )\n" ); buff += 2; break; case OPERATOR_IND_2: Wdputslc( "OPERATOR_IND_2\n" ); break; case OPERATOR_IND_4: Wdputslc( "OPERATOR_IND_4\n" ); break; case OPERATOR_IND_ADDR286: Wdputslc( "OPERATOR_IND_ADDR286\n" ); break; case OPERATOR_IND_ADDR386: Wdputslc( "OPERATOR_IND_ADDR386\n" ); break; case OPERATOR_ZEB: Wdputslc( "OPERATOR_ZEB\n" ); break; case OPERATOR_ZEW: Wdputslc( "OPERATOR_ZEW\n" ); break; case OPERATOR_MK_FP: Wdputslc( "OPERATOR_MK_FP\n" ); break; case OPERATOR_POP: Wdputslc( "OPERATOR_POP\n" ); break; case OPERATOR_XCHG: Wdputs( "OPERATOR_XCHG: " ); Puthex( *buff, 2 ); Wdputslc( "\n" ); buff++; break; case OPERATOR_ADD: Wdputslc( "OPERATOR_ADD\n" ); break; case OPERATOR_DUP: Wdputslc( "OPERATOR_DUP\n" ); break; case OPERATOR_NOP: Wdputslc( "OPERATOR_NOP\n" ); break; default: if( type & 0x30 ) { num = (type & 0x0f)+1; Wdputs( "MULTI_REG(" ); Putdec( num ); Wdputs( "): " ); for( i=0;i<num;i++ ) { Wdputs( regLocStrs[ *buff ] ); if( i != num-1 ) { Wdputs( ", " ); } else { Wdputslc( "\n" ); } buff++; } } else if( type & 0x40 ) { Wdputs( "REG: " ); Wdputs( regLocStrs[ type & 0x0f ] ); Wdputslc( "\n" ); } else { Wdputslc( "**** UNKNOWN LOCATION EXPRESSION!! ****\n" ); } break; } return( buff ); } /* dump_single_location_entry */
/* * Dump_types - dump all typing information */ void Dmp_type( int cnt, unsigned_32 *offs ) /*****************************************/ { int i; addr32_ptr *p32; addr48_ptr *p48; unsigned_8 *ptr; unsigned_16 index; unsigned_16 curr_index; unsigned_32 coff; char name[256]; unsigned_8 buff[256]; for( i = 0; i < cnt; i++ ) { coff = 0; Wdputs( " Data " ); Putdec( i ); Wdputs( ": offset " ); Puthex( offs[i], 8 ); Wdputslc( "\n" ); curr_index = 0; for( ;; ) { Wlseek( coff + Curr_sectoff + offs[i] ); Wread( buff, sizeof( buff ) ); Wdputs( " " ); Puthex( coff, 4 ); Wdputs( ": " ); ptr = buff+2; switch( buff[1] ) { case SCALAR: StartType( "SCALAR", ++curr_index ); ptr = buff+3; Get_local_name( name, ptr, buff ); Wdputs( " \"" ); Wdputs( name ); Wdputs( "\" scalar type = " ); scalar_type( buff[2] ); Wdputslc( "\n" ); break; case SCOPE: StartType( "SCOPE", ++curr_index); Get_local_name( name, ptr, buff ); Wdputs( " \"" ); Wdputs( name ); Wdputslc( "\"\n" ); break; case NAME: StartType( "NAME", ++curr_index); ptr = Get_type_index( ptr, &index ); ptr = Get_type_index( ptr, &index ); Get_local_name( name, ptr, buff ); Wdputs( " \"" ); Wdputs( name ); Wdputs( "\" type idx = " ); Putdec( index ); Wdputs( " scope idx = " ); ptr = Get_type_index( buff+2, &index ); Putdec( index ); Wdputslc( "\n" ); break; case CUE_TABLE: Wdputs( "cue table offset=" ); Puthex( *(unsigned_32 *)ptr, 8 ); Wdputslc( "\n" ); break; case TYPE_EOF: return; case BYTE_INDEX: StartType( "BYTE_INDEX ARRAY", ++curr_index); array_index( ptr, 1 ); break; case WORD_INDEX: StartType( "WORD_INDEX ARRAY", ++curr_index); array_index( ptr, 2 ); break; case LONG_INDEX: StartType( "LONG_INDEX ARRAY", ++curr_index); array_index( ptr, 4 ); break; case TYPE_INDEX: StartType( "TYPE_INDEX ARRAY", ++curr_index); Wdputs( " index type = " ); ptr = Get_type_index( ptr, &index ); Putdec( index ); base_type_index( ptr ); break; case DESC_INDEX: StartType( "DESC_INDEX ARRAY", ++curr_index); desc_array( ptr, false ); break; case DESC_INDEX_386: StartType( "DESC_INDEX ARRAY", ++curr_index); desc_array( ptr, true ); break; case BYTE_RANGE: StartType( "BYTE_RANGE", ++curr_index); range( ptr, 1 ); break; case WORD_RANGE: StartType( "WORD_RANGE", ++curr_index); range( ptr, 2 ); break; case LONG_RANGE: StartType( "LONG_RANGE", ++curr_index); range( ptr, 4 ); break; case PTR_NEAR: StartType( "NEAR PTR", ++curr_index); Wdputs( " " ); near_ptr( buff ); break; case PTR_FAR: StartType( "FAR PTR", ++curr_index); Wdputs( " " ); base_type_index( ptr ); break; case PTR_HUGE: StartType( "HUGE PTR", ++curr_index); Wdputs( " " ); base_type_index( ptr ); break; case PTR_NEAR_DEREF: StartType( "NEAR_DEREF PTR", ++curr_index); Wdputs( " " ); near_ptr( buff ); break; case PTR_FAR_DEREF: StartType( "FAR_DEREF PTR", ++curr_index); Wdputs( " " ); base_type_index( ptr ); break; case PTR_HUGE_DEREF: StartType( "HUGE_DEREF PTR", ++curr_index); Wdputs( " " ); base_type_index( ptr ); break; case PTR_NEAR386: StartType( "NEAR386 PTR", ++curr_index); Wdputs( " " ); near_ptr( buff ); break; case PTR_FAR386: StartType( "FAR386 PTR", ++curr_index); Wdputs( " " ); base_type_index( ptr ); break; case PTR_NEAR386_DEREF: StartType( "NEAR386_DEREF PTR", ++curr_index); Wdputs( " " ); near_ptr( buff ); break; case PTR_FAR386_DEREF: StartType( "FAR386_DEREF PTR", ++curr_index); Wdputs( "\n " ); base_type_index( ptr ); break; case CLIST: StartType( "ENUM_LIST", ++curr_index); Wdputs( " number of consts = " ); Puthex( *ptr, 4 ); Wdputs( " scalar type = " ); scalar_type( buff[4] ); Wdputslc( "\n" ); break; case CONST_BYTE: Wdputslc( "CONST_BYTE\n" ); enum_const( buff, 1 ); break; case CONST_WORD: Wdputslc( "CONST_WORD\n" ); enum_const( buff, 2 ); break; case CONST_LONG: Wdputslc( "CONST_LONG\n" ); enum_const( buff, 4 ); break; case FLIST: StartType( "FIELD_LIST", ++curr_index); Wdputs( " number of fields = " ); Puthex( *ptr, 4 ); if( buff[0] > 4 ) { Wdputs( " size = " ); ptr += 2; Puthex( *ptr, 8 ); } Wdputslc( "\n" ); break; case FIELD_BYTE: Wdputslc( "FIELD_BYTE\n" ); bit_field_struct( buff, 1, false ); break; case FIELD_WORD: Wdputslc( "FIELD_WORD\n" ); bit_field_struct( buff, 2, false ); break; case FIELD_LONG: Wdputslc( "FIELD_LONG\n" ); bit_field_struct( buff, 4, false ); break; case BIT_BYTE: Wdputslc( "BIT_BYTE\n" ); bit_field_struct( buff, 1, true ); break; case BIT_WORD: Wdputslc( "BIT_WORD\n" ); bit_field_struct( buff, 2, true ); break; case BIT_LONG: Wdputslc( "BIT_LONG\n" ); bit_field_struct( buff, 4, true ); break; case FIELD_CLASS: Wdputslc( "FIELD_CLASS\n" ); bit_field_class( buff, false ); break; case BIT_CLASS: Wdputslc( "BIT_CLASS\n" ); bit_field_class( buff, true ); break; case INHERIT_CLASS: Wdputslc( "INHERIT_CLASS\n" ); Wdputs( " adjust locator = " ); ptr = Dump_location_expression( ptr, " " ); Wdputs( " ancestor type = " ); Get_type_index( ptr, &index ); Putdec( index ); Wdputslc( "\n" ); break; case PNEAR: StartType( "NEAR PROC", ++curr_index); near_far_proc( buff ); break; case PFAR: StartType( "FAR PROC", ++curr_index); near_far_proc( buff ); break; case PNEAR386: StartType( "NEAR386 PROC", ++curr_index); near_far_proc( buff ); break; case PFAR386: StartType( "FAR386 PROC", ++curr_index); near_far_proc( buff ); break; case EXT_PARMS: Wdputslc( "EXT_PARMS\n" ); param_type_index( (unsigned_8)buff[0]-2, ptr ); break; case CHAR_BYTE: StartType( "CHAR_BYTE", ++curr_index); Wdputs( " length = " ); Puthex( *ptr, 2 ); Wdputslc( "\n" ); break; case CHAR_WORD: StartType( "CHAR_WORD", ++curr_index); Wdputs( " length = " ); Puthex( *ptr, 4 ); Wdputslc( "\n" ); break; case CHAR_LONG: StartType( "CHAR_LONG", ++curr_index); Wdputs( " length = " ); Puthex( *ptr, 8 ); Wdputslc( "\n" ); break; case CHAR_IND: StartType( "CHAR_IND", ++curr_index); Wdputs( " scalar type = " ); scalar_type( buff[2] ); p32 = (addr32_ptr *)ptr; Puthex( p32->segment, 4 ); Wdputc( ':' ); Puthex( p32->offset, 4 ); Wdputslc( "\n" ); break; case CHAR_IND_386: StartType( "CHAR_IND_386", ++curr_index); Wdputs( " scalar type = " ); scalar_type( buff[2] ); p48 = (addr48_ptr *)ptr; Puthex( p48->segment, 4 ); Wdputc( ':' ); Puthex( p48->offset, 8 ); Wdputslc( "\n" ); break; case CHAR_LOCATION: StartType( "CHAR_LOC", ++curr_index); Wdputs( " scalar type = " ); scalar_type( buff[2] ); Wdputs( " size locator = " ); ptr = Dump_location_expression( ptr + 1, " " ); Wdputslc( "\n" ); break; } coff += buff[0]; if( coff >= (offs[i+1] - offs[i]) ) { break; } } } } /* Dmp_type */
static void dmp_symtab( unsigned long offset, unsigned long num_syms ) /********************************************************************/ { coff_symbol *symtab; coff_symbol *start; char * strtab; unsigned_32 strsize; unsigned_32 symidx; unsigned num_aux; char * name; char buff[9]; if( num_syms == 0 ) { Wdputslc( "No symbols in object file\n" ); Wdputslc( "\n" ); return; } Wlseek( Coff_off + offset ); Banner( "Symbol Table" ); start = Wmalloc( num_syms * sizeof(coff_symbol) ); symtab = start; Wread( start, num_syms * sizeof(coff_symbol) ); Wread( &strsize, sizeof(unsigned_32) ); if( strsize != 0 ) { strsize -= sizeof(unsigned_32); } if( strsize != 0 ) { strtab = Wmalloc( strsize ); Wread( strtab, strsize ); } else { strtab = NULL; } buff[8] = '\0'; for( symidx = 0; symidx < num_syms; symidx++ ) { if( symtab->name.non_name.zeros == 0 ) { name = strtab + symtab->name.non_name.offset - 4; } else if( symtab->name.name_string[8] == '\0' ) { name = symtab->name.name_string; } else { memcpy( buff, symtab->name.name_string, 8 ); name = buff; } Wdputs( "Idx: " ); Puthex( symidx, 8 ); Wdputs( " Name: " ); Wdputs( name ); Wdputslc( "\n" ); Wdputs( "Value: " ); Puthex( symtab->value, 8 ); Wdputs( " Sec #: " ); Puthex( symtab->sec_num, 4 ); Wdputs( " Type: " ); Puthex( symtab->type, 4 ); Wdputs( " Class: " ); Puthex( symtab->storage_class, 2 ); Wdputs( " # Aux Syms: " ); Putdec( symtab->num_aux ); Wdputslc( "\n" ); num_aux = symtab->num_aux; symtab++; if( num_aux > 0 ) { dmp_mult_data_line((char *)symtab, 0, num_aux * sizeof(coff_symbol)); symtab += num_aux; symidx += num_aux; } Wdputslc( "\n" ); } Wdputslc( "\n" ); if( strsize != 0 ) { Banner( "String Table" ); dmp_mult_data_line( strtab, 0, strsize ); Wdputslc( "\n" ); } free( start ); free( strtab ); }