Esempio n. 1
0
ref_entry DoPass1Relocs( unsigned_8 *contents, ref_entry r_entry,
                         orl_sec_offset start, orl_sec_offset end )
{
    long                                value;
    unnamed_label_return_struct         rs;

    if( !IsIntelx86() )
        return( r_entry );

    while( r_entry && ( r_entry->offset < start ) ) {
        r_entry = r_entry->next;
    }

    while( r_entry && ( r_entry->offset < end ) ) {
        if( r_entry->label->shnd && ( r_entry->label->type == LTYP_SECTION ) ) {
            if( r_entry->addend ) {
                value = HandleAddend( r_entry );
            } else {
                switch( RelocSize( r_entry ) ) {
                case( 6 ):
                case( 4 ):
                    value = *((long *)&(contents[ r_entry->offset ]));
                    break;
                case( 2 ):
                    value = *((short *)&(contents[ r_entry->offset ]));
                    break;
                case( 1 ):
                    value = *((signed char *)&(contents[ r_entry->offset ]));
                    break;
                default:
                    value = 0;
                }
            }
            CreateUnnamedLabel( r_entry->label->shnd, value, &rs );
            if( rs.error == RC_OKAY ) {
                r_entry->label = rs.entry;
                r_entry->no_val = 1;
            }
        }
        r_entry = r_entry->next;
    }
    return( r_entry );
}
Esempio n. 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 );
}
Esempio n. 3
0
size_t HandleAReference( dis_value value, int ins_size, ref_flags flags,
                           orl_sec_offset offset, orl_sec_size sec_size,
                           ref_entry * r_entry, char *buff )
// handle any references at this offset
{
    return_val          error;
    dis_value           nvalue;
    char                *p;

    buff[0] = '\0';
    for( ; *r_entry && (*r_entry)->offset == offset; *r_entry = (*r_entry)->next ) {
        if( (*r_entry)->no_val == 0 ) {
            nvalue = value;
        } else if( (*r_entry)->addend ) {
            nvalue = HandleAddend( *r_entry );
        } else {
            nvalue = 0;
        }
        switch( (*r_entry)->type ) {
        case ORL_RELOC_TYPE_MAX + 1:
        case ORL_RELOC_TYPE_JUMP:
        case ORL_RELOC_TYPE_REL_21_SH:
        case ORL_RELOC_TYPE_WORD_26:
            error = referenceString( *r_entry, sec_size, "j^", "", "",
                                     buff, flags );
            if( error != RC_OKAY ) {
                // label is defined to be beyond the boundaries of the section!
                if( !(DFormat & DFF_ASM) ){
                    BufferStore("\t     %04X", offset );
                    BufferAlignToTab( COMMENT_TAB_POS );
                } else {
                    BufferConcat("\t" );
                }
                BufferConcat( CommentString );
                BufferMsg( LABEL_BEYOND_SECTION );
                BufferConcatNL();
                BufferPrint();
                *r_entry = (*r_entry)->next;
                return( 0 );
            }
            continue; // Don't print addend
            break;
        case ORL_RELOC_TYPE_SEC_REL:
            referenceString( *r_entry, sec_size, "s^", "s^", "@s", buff,
                             flags );
            break;
        case ORL_RELOC_TYPE_HALF_HI:
            referenceString( *r_entry, sec_size, "h^", "h^", "@h", buff,
                             flags );
            break;
        case ORL_RELOC_TYPE_HALF_HA:
            referenceString( *r_entry, sec_size, "ha^", "ha^", "@ha", buff,
                             flags );
            break;
        case ORL_RELOC_TYPE_HALF_LO:
            referenceString( *r_entry, sec_size, "l^", "l^", "@l", buff,
                             flags );
            break;
        case ORL_RELOC_TYPE_REL_14:
        case ORL_RELOC_TYPE_REL_24:
        case ORL_RELOC_TYPE_WORD_14:
        case ORL_RELOC_TYPE_WORD_24:
            nvalue &= ~0x3;
        case ORL_RELOC_TYPE_WORD_16:
        case ORL_RELOC_TYPE_WORD_32:
        case ORL_RELOC_TYPE_WORD_64:
            if( ( (*r_entry)->label->type != LTYP_GROUP ) &&
              ( flags & RFLAG_IS_IMMED ) && IsMasmOutput() ) {
                referenceString( *r_entry, sec_size, "offset ", "offset ",
                                 "", buff, flags );
            } else {
                referenceString( *r_entry, sec_size, "", "", "", buff,
                                 flags );
            }
            break;
        case ORL_RELOC_TYPE_REL_16:
            if( IsIntelx86() && !(*r_entry)->no_val ) {
                nvalue -= ins_size;
            }
            if( ( (*r_entry)->label->type != LTYP_GROUP ) &&
              ( flags & RFLAG_IS_IMMED ) && IsMasmOutput() ) {
                referenceString( *r_entry, sec_size, "offset ", "offset ",
                                 "", buff, flags );
            } else {
                referenceString( *r_entry, sec_size, "", "", "", buff,
                                 flags  );
            }
            break;
        case ORL_RELOC_TYPE_WORD_8:
        case ORL_RELOC_TYPE_WORD_16_SEG:
        case ORL_RELOC_TYPE_WORD_HI_8:
        case ORL_RELOC_TYPE_WORD_32_SEG:
            // Keep these seperate because they are OMF specific
            referenceString( *r_entry, sec_size, "", "", "", buff, flags );
            break;
        case ORL_RELOC_TYPE_SEGMENT:
            if( ( (*r_entry)->label->type != LTYP_GROUP )
                && ( (*r_entry)->label->type != LTYP_SECTION )
                && ( flags & RFLAG_IS_IMMED )
                && IsMasmOutput() ) {
                referenceString( *r_entry, sec_size, "seg ", "seg ", "",
                                 buff, flags );
            } else {
                referenceString( *r_entry, sec_size, "", "", "", buff,
                                 flags );
            }
            break;

        case ORL_RELOC_TYPE_REL_32_NOADJ:
            // this is a little kluge because Brian's ELF files seem to have
            // -4 in the implicit addend for calls and such BBB May 09, 1997
            nvalue += 4;
            // fall through
        case ORL_RELOC_TYPE_REL_8:
        case ORL_RELOC_TYPE_REL_16_SEG:
        case ORL_RELOC_TYPE_REL_HI_8:
        case ORL_RELOC_TYPE_REL_32_SEG:
        case ORL_RELOC_TYPE_REL_32:
        case ORL_RELOC_TYPE_REL_32_ADJ5:
        case ORL_RELOC_TYPE_REL_32_ADJ4:
        case ORL_RELOC_TYPE_REL_32_ADJ3:
        case ORL_RELOC_TYPE_REL_32_ADJ2:
        case ORL_RELOC_TYPE_REL_32_ADJ1:
            // For some reason we add the instruction size to the value
            // of the displacement in a relative call and get a bad
            // offset, due to CORE implementation
            //
            // Main reason :
            // instruction size with displacement and with addend is correct for
            // relative addresses without relocate
            //
            // in amd64 code the instruction size will be added in pass1.c!
            if( (*r_entry)->no_val == 0 && !( GetMachineType() == ORL_MACHINE_TYPE_AMD64 ) ) {
                nvalue -= ins_size;
            }
            referenceString( *r_entry, sec_size, "", "", "", buff, flags );
            break;
        case ORL_RELOC_TYPE_TOCREL_14:
            nvalue &= ~0x3;
        case ORL_RELOC_TYPE_TOCREL_16:
            referenceString( *r_entry, sec_size, "[toc]", "[toc]", "@toc",
                             buff, flags );
            break;
        case ORL_RELOC_TYPE_TOCVREL_14:
            nvalue &= ~0x3;
        case ORL_RELOC_TYPE_TOCVREL_16:
            referenceString( *r_entry, sec_size, "[tocv]", "[tocv]", "@tocv",
                             buff, flags );
            break;
        case ORL_RELOC_TYPE_GOT_16:
            referenceString( *r_entry, sec_size, "", "", "@got", buff, flags );
            break;
        case ORL_RELOC_TYPE_GOT_16_HI:
            referenceString( *r_entry, sec_size, "", "", "@got@h", buff, flags );
            break;
        case ORL_RELOC_TYPE_GOT_16_HA:
            referenceString( *r_entry, sec_size, "", "", "@got@ha", buff, flags );
            break;
        case ORL_RELOC_TYPE_GOT_16_LO:
            referenceString( *r_entry, sec_size, "", "", "@got@l", buff, flags );
            break;
        case ORL_RELOC_TYPE_PLTREL_24:
        case ORL_RELOC_TYPE_PLTREL_32:
        case ORL_RELOC_TYPE_PLT_32:
            referenceString( *r_entry, sec_size, "", "", "@plt", buff, flags );
            break;
        case ORL_RELOC_TYPE_PLT_16_HI:
            referenceString( *r_entry, sec_size, "", "", "@plt@h", buff, flags );
            break;
        case ORL_RELOC_TYPE_PLT_16_HA:
            referenceString( *r_entry, sec_size, "", "", "@plt@ha", buff, flags );
            break;
        case ORL_RELOC_TYPE_PLT_16_LO:
            referenceString( *r_entry, sec_size, "", "", "@plt@l", buff, flags );
            break;
        default:
            continue;
        }
        // LTYP_UNNAMED labels are always at the correct location
        // if( nvalue != 0 && (*r_entry)->label->type != LTYP_UNNAMED ) {
        // not so - BBB Oct 28, 1996
        if(( (*r_entry)->no_val == 0 ) && ( nvalue != 0 )) {
            p = &buff[strlen(buff)];
            if( nvalue < 0 ) {
                *p++ = '-';
                nvalue = -nvalue;
            } else {
                *p++ = '+';
            }
            FmtHexNum( p, 0, nvalue, FALSE );
        }
    }
    return( strlen( buff ) );
}