Пример #1
0
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 );
}
Пример #2
0
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 );
}
Пример #3
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 );
}