Example #1
0
static char *processFpuEmulatorFixup( ref_entry *r, orl_sec_offset loop )
{
    char    *fixup;

    if( *r != NULL && (*r)->offset == loop ) {
        fixup = SkipRef( *r );
        if( fixup != NULL ) {
            *r = (*r)->next;
            // there can be second fixup per instruction with 1 byte offset
            // it must be skipped too, displayed is first only
            // first one is significant, second one is segment override only
            if( *r && SkipRef( *r ) != NULL && ( (*r)->offset == loop + 1 ) ) {
                *r = (*r)->next;
            }
            if( Options & PRINT_FPU_EMU_FIXUP ) {
                return( fixup );
            }
        }
    }
    return( NULL );
}
Example #2
0
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 );
}