static label_entry handleLabels( char *sec_name, orl_sec_offset offset, orl_sec_offset end, label_entry l_entry, orl_sec_size size ) // handle any labels at this offset and skip all unused non-label symbols { bool is32bit; is32bit = ( size >= 0x10000 ); for( ; ( l_entry != NULL ) && ( l_entry->offset < end ); l_entry = l_entry->next ) { switch( l_entry->type ) { case LTYP_SECTION: case LTYP_NAMED: if( strcmp( l_entry->label.name, sec_name ) == 0 ) continue; /* fall through */ case LTYP_UNNAMED: if( l_entry->offset > offset ) return( l_entry ); break; case LTYP_ABSOLUTE: case LTYP_FUNC_INFO: default: continue; } switch( l_entry->type ) { case LTYP_NAMED: if( !( DFormat & DFF_ASM ) ) { if( offset != 0 && l_entry->binding == ORL_SYM_BINDING_GLOBAL ) { routineSize = offset - routineBase; BufferConcatNL(); BufferMsg( ROUTINE_SIZE ); BufferStore(" %d ", routineSize ); BufferMsg( BYTES ); BufferConcat(", "); BufferMsg( ROUTINE_BASE ); BufferStore(" %s + %04X\n\n", sec_name, routineBase ); routineBase = offset; } } case LTYP_SECTION: if( !( DFormat & DFF_ASM ) ) { PrintLinePrefixAddress( offset, is32bit ); BufferAlignToTab( PREFIX_SIZE_TABS ); } BufferStore( "%s:\n", l_entry->label.name ); break; case LTYP_UNNAMED: if( !( DFormat & DFF_ASM ) ) { PrintLinePrefixAddress( offset, is32bit ); BufferAlignToTab( PREFIX_SIZE_TABS ); } BufferStore( "%c$%d:\n", LabelChar, l_entry->label.number ); break; } BufferPrint(); } return( l_entry ); }
num_errors DoPass2( section_ptr sec, unsigned_8 *contents, orl_sec_size size, label_list sec_label_list, ref_list sec_ref_list ) // perform pass 2 on one section { struct pass2 data; label_entry l_entry; dis_dec_ins decoded; char name[ MAX_INS_NAME ]; char ops[ MAX_OBJ_NAME + 24 ]; // at most 1 label/relocation per instruction, plus room for registers, brackets and other crap dis_inst_flags flags; scantab_ptr st; int is_intel; sa_disasm_struct sds; char *FPU_fixup; int pos_tabs; bool is32bit; routineBase = 0; st = sec->scan; data.size = size; sds.data = contents; sds.last = size - 1; l_entry = NULL; if( sec_label_list != NULL ) { l_entry = sec_label_list->first; } if( sec_ref_list != NULL ) { data.r_entry = sec_ref_list->first; } else { data.r_entry = NULL; } data.disassembly_errors = 0; if( source_mix ) { GetSourceFile( sec ); } PrintHeader( sec ); if( size && sec_label_list ) PrintAssumeHeader( sec ); flags.u.all = DIF_NONE; if( GetMachineType() == ORL_MACHINE_TYPE_I386 ) { if( ( GetFormat() != ORL_OMF ) || ( ORLSecGetFlags( sec->shnd ) & ORL_SEC_FLAG_USE_32 ) ) { flags.u.x86 = DIF_X86_USE32_FLAGS; } is_intel = 1; } else { is_intel = IsIntelx86(); } is32bit = ( size >= 0x10000 ); for( data.loop = 0; data.loop < size; data.loop += decoded.size ) { // process data in code segment while( st && ( data.loop > st->end ) ) { st = st->next; } if( st && ( data.loop >= st->start ) ) { decoded.size = 0; processDataInCode( sec, contents, &data, st->end - data.loop, &l_entry ); st = st->next; continue; } // data may not be listed in scan table, but a fixup at this offset will // give it away while( data.r_entry && ( data.r_entry->offset < data.loop ) ) { data.r_entry = data.r_entry->next; } FPU_fixup = processFpuEmulatorFixup( &data.r_entry, data.loop ); if( data.r_entry && ( data.r_entry->offset == data.loop ) ) { if( is_intel || IsDataReloc( data.r_entry ) ) { // we just skip the data decoded.size = 0; processDataInCode( sec, contents, &data, RelocSize( data.r_entry ), &l_entry ); continue; } } if( source_mix ) { MixSource( data.loop ); } DisDecodeInit( &DHnd, &decoded ); decoded.flags.u.all |= flags.u.all; sds.offs = data.loop; DisDecode( &DHnd, &sds, &decoded ); if( sec_label_list ) { l_entry = handleLabels( sec->name, data.loop, data.loop + decoded.size, l_entry, size ); if( ( l_entry != NULL ) && ( l_entry->offset > data.loop ) && ( l_entry->offset < data.loop + decoded.size ) ) { /* If we have a label planted in the middle of this instruction (see inline memchr for example), put out a couple of data bytes, and then restart decode and label process from offset of actual label. */ decoded.size = 0; processDataInCode( sec, contents, &data, l_entry->offset - data.loop, &l_entry ); continue; } } DisFormat( &DHnd, &data, &decoded, DFormat, name, sizeof( name ), ops, sizeof( ops ) ); if( FPU_fixup != NULL ) { if( !(DFormat & DFF_ASM) ) { BufferAlignToTab( PREFIX_SIZE_TABS ); } BufferStore( "\t%sFPU fixup %s\n", CommentString, FPU_fixup ); } if( !(DFormat & DFF_ASM) ) { unsigned_64 *tmp_64; unsigned_32 *tmp_32; unsigned_16 *tmp_16; tmp_64 = (unsigned_64 *)(contents + data.loop); tmp_32 = (unsigned_32 *)(contents + data.loop); tmp_16 = (unsigned_16 *)(contents + data.loop); if( DHnd.need_bswap ) { switch( DisInsSizeInc( &DHnd ) ) { //case 8: SWAP_64( *tmp_64 ); // break; case 4: SWAP_32( *tmp_32 ); break; case 2: SWAP_16( *tmp_16 ); break; default: break; } } PrintLinePrefixAddress( data.loop, is32bit ); PrintLinePrefixData( contents, data.loop, size, DisInsSizeInc( &DHnd ), decoded.size ); BufferAlignToTab( PREFIX_SIZE_TABS ); } BufferStore( "\t%s", name ); if( *ops != '\0' ) { pos_tabs = ( DisInsNameMax( &DHnd ) + TAB_WIDTH ) / TAB_WIDTH + 1; if( !(DFormat & DFF_ASM) ) { pos_tabs += PREFIX_SIZE_TABS; } BufferAlignToTab( pos_tabs ); BufferConcat( ops ); } BufferConcatNL(); BufferPrint(); } if( sec_label_list ) { l_entry = handleLabels( sec->name, size, (orl_sec_offset)-1, l_entry, size ); } if( !(DFormat & DFF_ASM) ) { routineSize = data.loop - routineBase; BufferConcatNL(); BufferMsg( ROUTINE_SIZE ); BufferStore(" %d ", routineSize ); BufferMsg( BYTES ); BufferConcat(", "); BufferMsg( ROUTINE_BASE ); BufferStore(" %s + %04X\n\n", sec->name, routineBase ); BufferPrint(); } if( source_mix ) { EndSourceMix(); } PrintTail( sec ); return( data.disassembly_errors ); }
return_val DumpPDataSection( section_ptr sec, unsigned_8 *contents, orl_sec_size size, unsigned pass ) { orl_sec_offset loop; hash_data * data_ptr; ref_list r_list; ref_entry r_entry; descriptor_struct descriptor; bool is32bit; if( pass == 1 ) return( OKAY ); if( size == 0 ) return( OKAY ); is32bit = ( size >= 0x10000 ); data_ptr = HashTableQuery( HandleToRefListTable, (hash_value)sec->shnd ); if( *data_ptr ) { r_list = (ref_list)*data_ptr; if( r_list ) { r_entry = r_list->first; } else { r_entry = NULL; } } BufferConcatNL(); PrintHeader( sec ); BufferConcatNL(); for( loop = 0; loop < size; loop += sizeof( descriptor_struct ) ) { if( r_entry == NULL ) break; memcpy( &descriptor, contents + loop, sizeof( descriptor_struct ) ); if( DFormat & DFF_ASM ) { BufferStore( "\t\t" ); BufferStore( "%s %04X\t\t", CommentString, loop ); } else { PrintLinePrefixAddress( loop, is32bit ); BufferAlignToTab( PREFIX_SIZE_TABS ); BufferStore( "%s ", CommentString ); } BufferMsg( PROCEDURE_DESCRIPTOR ); /* Skip over pair relocs */ while( r_entry && (r_entry->type == ORL_RELOC_TYPE_PAIR || r_entry->offset < loop) ) { r_entry = r_entry->next; } switch( r_entry->label->type ) { case LTYP_EXTERNAL_NAMED: BufferStore( "%s", r_entry->label->label.name ); break; case LTYP_NAMED: case LTYP_SECTION: case LTYP_GROUP: BufferStore( "%s", r_entry->label->label.name ); break; default: BufferStore( "%c$%d", LabelChar, r_entry->label->label.number ); break; } BufferConcatNL(); printDescriptor( loop, &descriptor, &r_entry ); } return( OKAY ); }