return_val DumpASMSection( section_ptr section, unsigned_8 *contents, dis_sec_size size, unsigned pass ) { hash_data *h_data; label_list sec_label_list; label_entry l_entry; ref_list sec_ref_list; ref_entry r_entry; return_val err; hash_key h_key; h_key.u.sec_handle = section->shnd; h_data = HashTableQuery( HandleToLabelListTable, h_key ); if( h_data != NULL ) { sec_label_list = h_data->u.sec_label_list; l_entry = sec_label_list->first; } else { sec_label_list = NULL; l_entry = NULL; } r_entry = NULL; h_data = HashTableQuery( HandleToRefListTable, h_key ); if( h_data != NULL ) { sec_ref_list = h_data->u.sec_ref_list; if( sec_ref_list != NULL ) { r_entry = sec_ref_list->first; } } if( pass == 1 ) { DoPass1Relocs( contents, r_entry, 0, size ); return( RC_OKAY ); } if( size == 0 ) { if( IsMasmOutput() ) { PrintHeader( section ); dumpAsmLabel( l_entry, section, 0, 0, NULL, NULL ); PrintTail( section ); } return( RC_OKAY ); } PrintHeader( section ); err = DumpASMDataFromSection( contents, 0, size, &l_entry, &r_entry, section ); if( size > 0 ) { l_entry = dumpAsmLabel( l_entry, section, size, size, NULL, NULL ); } BufferConcatNL(); BufferPrint(); if( err == RC_OKAY ) { PrintTail( section ); } return( err ); }
return_val DumpASMSection( section_ptr sec, unsigned_8 *contents, orl_sec_size size, unsigned pass ) { hash_data *data_ptr; label_list sec_label_list; label_entry l_entry; ref_list sec_ref_list; ref_entry r_entry; return_val err; data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) sec->shnd ); if( data_ptr ) { sec_label_list = (label_list) *data_ptr; l_entry = sec_label_list->first; } else { sec_label_list = NULL; l_entry = NULL; } r_entry = NULL; data_ptr = HashTableQuery( HandleToRefListTable, (hash_value) sec->shnd ); if( data_ptr ) { sec_ref_list = (ref_list) *data_ptr; if( sec_ref_list != NULL ) { r_entry = sec_ref_list->first; } } if( pass == 1 ) { DoPass1Relocs( contents, r_entry, 0, size ); return( RC_OKAY ); } if( size == 0 ) { if( IsMasmOutput() ) { PrintHeader( sec ); dumpAsmLabel( l_entry, sec, 0, 0, NULL, NULL ); PrintTail( sec ); } return( RC_OKAY ); } PrintHeader( sec ); err = DumpASMDataFromSection( contents, 0, size, &l_entry, &r_entry, sec ); if( size > 0 ) { l_entry = dumpAsmLabel( l_entry, sec, size, size, NULL, NULL ); } BufferConcatNL(); BufferPrint(); if( err == RC_OKAY ) { PrintTail( sec ); } return( err ); }
return_val DoPass1( orl_sec_handle shnd, unsigned_8 *contents, orl_sec_size size, ref_list sec_ref_list, scantab_ptr stl ) // perform pass 1 on one section { orl_sec_offset loop; dis_dec_ins decoded; dis_value value; dis_return dr; unnamed_label_return_struct rs; return_val error; unsigned i; ref_entry r_entry; dis_inst_flags flags; orl_sec_offset op_pos; int is_intel; int adjusted; sa_disasm_struct sds; sds.data = contents; sds.last = size - 1; if( sec_ref_list != NULL ) { r_entry = sec_ref_list->first; } else { r_entry = NULL; } flags.u.all = DIF_NONE; if( GetMachineType() == ORL_MACHINE_TYPE_I386 ) { if( ( GetFormat() != ORL_OMF ) || ( ORLSecGetFlags( shnd ) & ORL_SEC_FLAG_USE_32 ) ) { flags.u.x86 = DIF_X86_USE32_FLAGS; } is_intel = 1; } else { is_intel = IsIntelx86(); } for( loop = 0; loop < size; loop += decoded.size ) { // skip data in code segment while( stl && ( loop > stl->end ) ) { stl = stl->next; } if( stl && ( loop >= stl->start ) ) { decoded.size = 0; if( is_intel ) { r_entry = DoPass1Relocs( contents, r_entry, loop, stl->end ); } loop = stl->end; stl = stl->next; continue; } // data may not be listed in scan table, but a fixup at this offset will // give it away while( r_entry && ( ( r_entry->offset < loop ) || SkipRef(r_entry) ) ) { r_entry = r_entry->next; } if( r_entry && ( r_entry->offset == loop ) ) { if( is_intel || IsDataReloc( r_entry ) ) { // we just skip the data op_pos = loop; decoded.size = 0; loop += RelocSize( r_entry ); r_entry = DoPass1Relocs( contents, r_entry, op_pos, loop ); continue; } } DisDecodeInit( &DHnd, &decoded ); decoded.flags.u.all |= flags.u.all; sds.offs = loop; dr = DisDecode( &DHnd, &sds, &decoded ); // if an invalid instruction was found, there is nothing we can do. if( dr != DR_OK ) return( RC_ERROR ); for( i = 0; i < decoded.num_ops; ++i ) { adjusted = 0; op_pos = loop + decoded.op[i].op_position; switch( decoded.op[i].type & DO_MASK ) { case DO_IMMED: if( !is_intel ) break; /* fall through */ case DO_RELATIVE: case DO_MEMORY_REL: if( ( decoded.op[i].type & DO_MASK ) != DO_IMMED ) { decoded.op[i].value += loop; adjusted = 1; } /* fall through */ case DO_ABSOLUTE: case DO_MEMORY_ABS: // Check for reloc at this location while( r_entry && r_entry->offset < op_pos ) { r_entry = r_entry->next; } if( r_entry && ( r_entry->offset == op_pos ) ) { if( is_intel && r_entry->label->shnd && ( r_entry->type != ORL_RELOC_TYPE_SEGMENT ) && ( r_entry->label->type == LTYP_SECTION ) ) { /* For section offsets under intel we MUST generate a * local label because the offset might change when the * code is re-assembled */ if( r_entry->addend ) { r_entry->no_val = 0; CreateUnnamedLabel( r_entry->label->shnd, HandleAddend( r_entry ), &rs ); } else { r_entry->no_val = 1; if( adjusted && isSelfReloc( r_entry ) && ( r_entry->label->type == LTYP_SECTION ) ) { /* This is a kludgy reloc done under OMF */ decoded.op[i].value -= loop; decoded.op[i].value -= decoded.size; switch( RelocSize( r_entry ) ) { case( 2 ): decoded.op[i].value = (uint_16)(decoded.op[i].value); case( 1 ): decoded.op[i].value = (uint_8)(decoded.op[i].value); } } value = decoded.op[i].value; if( value < 0 || value > ORLSecGetSize( r_entry->label->shnd ) ) { // can't fold it into the label position - BBB Oct 28, 1996 value = 0; r_entry->no_val = 0; } CreateUnnamedLabel( r_entry->label->shnd, value, &rs ); } if( rs.error != RC_OKAY ) return( rs.error ); r_entry->label = rs.entry; } else { // fixme: got to handle other types of relocs here } } else if( ( decoded.op[i].type & DO_MASK ) != DO_IMMED ) { if( decoded.op[i].base == DR_NONE && decoded.op[i].index == DR_NONE ) { switch( decoded.op[i].type & DO_MASK ) { case DO_MEMORY_REL: case DO_MEMORY_ABS: // use decoded instruction size for absolute memory on amd64. // the cpu will reference rip _after_ the instruction is // completely fetched and decoded. // relocations in pass2 are not applied because they break // relative memory references if no relocation is present! if( GetMachineType() == ORL_MACHINE_TYPE_AMD64 ) { decoded.op[i].value += decoded.size; // I don't know if this is neccessary, but it will generate // labels for memory references if no symbol is present // (ex: executable file) CreateUnnamedLabel( shnd, decoded.op[i].value, &rs ); if( rs.error != RC_OKAY ) return( rs.error ); error = CreateUnnamedLabelRef( shnd, rs.entry, op_pos ); } else { // create an LTYP_ABSOLUTE label CreateAbsoluteLabel( shnd, decoded.op[i].value, &rs ); if( rs.error != RC_OKAY ) return( rs.error ); error = CreateAbsoluteLabelRef( shnd, rs.entry, op_pos ); } break; default: // create an LTYP_UNNAMED label CreateUnnamedLabel( shnd, decoded.op[i].value, &rs ); if( rs.error != RC_OKAY ) return( rs.error ); error = CreateUnnamedLabelRef( shnd, rs.entry, op_pos ); break; } if( error != RC_OKAY ) { return( error ); } } } break; } } } return( RC_OKAY ); }