Beispiel #1
0
size_t DisCliValueString( void *d, dis_dec_ins *ins, unsigned op_num, char *buff, size_t buff_len )
{
    struct pass2        *pd = d;
    size_t              len;
    dis_operand         *op;
    ref_flags           rf;

    buff_len = buff_len;
    buff[0] = '\0';

    rf = RFLAG_DEFAULT;
    op = &ins->op[op_num];
    switch( op->type & DO_MASK ) {
    case DO_RELATIVE:
    case DO_MEMORY_REL:
    case DO_ABSOLUTE:
    case DO_MEMORY_ABS:
        if( pd->r_entry != NULL ) {
            /* if there is an override we must avoid the frame
             */
            if( ( ins->flags.u.x86 & DIS_X86_SEG_OR ) && IsIntelx86() ) {
                rf |= RFLAG_NO_FRAME;
            }
            len = HandleAReference( op->value, ins->size, rf,
                        pd->loop + op->op_position, pd->size, &pd->r_entry,
                        buff );
            if( len != 0 ) {
                return( len );
            }
        }
        switch( op->type & DO_MASK ) {
        case DO_RELATIVE:
        case DO_MEMORY_REL:
            op->value += pd->loop;
            break;
        }
        if( op->base == DR_NONE && op->index == DR_NONE ) {
            FmtSizedHexNum( buff, ins, op_num );
        } else if( op->value > 0 ) {
            FmtHexNum( buff, 0, op->value, FALSE );
        } else if( op->value < 0 ) {
            buff[0] = '-';
            FmtHexNum( &buff[1], 0, -op->value, FALSE );
        }
        break;
    case DO_IMMED:
        if( pd->r_entry != NULL ) {
            rf |= RFLAG_IS_IMMED;
            len = HandleAReference( op->value, ins->size, rf,
                        pd->loop + op->op_position, pd->size, &pd->r_entry,
                        buff );
            if( len != 0 ) {
                return( len );
            }
        }
        FmtSizedHexNum( buff, ins, op_num );
        break;
    }
    return( strlen( buff ) );
}
Beispiel #2
0
static void FmtSizedHexNum( char *buff, dis_dec_ins *ins, unsigned op_num )
{
    unsigned            size;
    unsigned            i;
    unsigned            len;

    static const unsigned long mask[] = {
        0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff
    };

    size = 0;
    for( i = 0; i < ins->num_ops; ++i ) {
        switch( ins->op[i].ref_type ) {
        case DRT_X86_BYTE:
            len = 1;
            break;
        case DRT_X86_WORD:
            len = 2;
            break;
        case DRT_X86_DWORD:
        case DRT_X86_DWORDF:
            len = 4;
            break;
        default:
            len = 0;
            break;
        }
        if( len > size ) size = len;
    }
    if( size == 0 ) size = 4;
    FmtHexNum( buff, size * 2, mask[size] & ins->op[op_num].value );
}
Beispiel #3
0
extern unsigned DisCliValueString( void *d, dis_dec_ins *ins, unsigned op_num, char *buff )
{
    dis_operand         *op;
    code_buff   *header;

    header = (code_buff *)d;
    buff[0] = '\0';
    op = &ins->op[op_num];
    switch( op->type & DO_MASK ) {
    case DO_RELATIVE:
    case DO_MEMORY_REL:
    case DO_ABSOLUTE:
    case DO_MEMORY_ABS:
        switch( op->type & DO_MASK ) {
            case DO_RELATIVE:
            case DO_MEMORY_REL:
                op->value += header->offset;
                break;
        }
        if( op->base == DR_NONE && op->index == DR_NONE ) {
            FmtSizedHexNum( buff, ins, op_num );
        } else if( op->value > 0 ) {
            FmtHexNum( buff, 0, op->value );
        } else if( op->value < 0 ) {
            buff[0] = '-';
            FmtHexNum( &buff[1], 0, -op->value );
        }
        break;
    case DO_IMMED:
        // FmtSizedHexNum( buff, ins, op_num );
        if( op->value < 0 ) {
            buff[0] = '-';
            FmtHexNum( &buff[1], 0, -op->value );
        } else {
            FmtHexNum( buff, 0, op->value );
        }
        break;
    }
    return( strlen( buff ) );
}
Beispiel #4
0
static void FmtSizedHexNum( char *buff, dis_dec_ins *ins, unsigned op_num )
{
    unsigned            size;
    unsigned            len;
    unsigned            i;
    unsigned            mask;
    bool                sign_extended;
    bool                no_prefix;
    signed_32           value;

    mask = 0;
    sign_extended = FALSE;
    no_prefix = FALSE;
    value = ins->op[op_num].value;
    switch( ins->op[op_num].ref_type ) {
    case DRT_SPARC_BYTE:
    case DRT_X86_BYTE:
    case DRT_X64_BYTE:
        size = 2;
        mask = 0x000000ff;
        break;
    case DRT_SPARC_HALF:
    case DRT_X86_WORD:
    case DRT_X64_WORD:
        size = 4;
        mask = 0x0000ffff;
        break;
    case DRT_SPARC_WORD:
    case DRT_SPARC_SFLOAT:
    case DRT_X86_DWORD:
    case DRT_X86_DWORDF:
    case DRT_X64_DWORD:
        size = 8;
        mask = 0xffffffff;
        break;
    case DRT_X64_QWORD:
        sign_extended = TRUE;
        // fall down
    case DRT_SPARC_DWORD:
    case DRT_SPARC_DFLOAT:
        size = 16;
        mask = 0xffffffff;
        break;
    default:
        size = 0;
        for( i = 0; i < ins->num_ops; i++ ) {
            switch( ins->op[i].ref_type ) {
            case DRT_X86_BYTE:
            case DRT_X64_BYTE:
                len = 2;
                if ( len > size ) {
                    size = len;
                    mask = 0x000000ff;
                }
                break;
            case DRT_X86_WORD:
            case DRT_X64_WORD:
                len = 4;
                if ( len > size ) {
                    size = len;
                    mask = 0x0000ffff;
                }
                break;
            case DRT_X86_DWORD:
            case DRT_X86_DWORDF:
            case DRT_X64_DWORD:
                len = 8;
                if ( len > size ) {
                    size = len;
                    mask = 0xffffffff;
                }
                break;
            case DRT_X64_QWORD:
                len = 16;
                if ( len > size ) {
                    size = len;
                    mask = 0xffffffff;
                    sign_extended = TRUE;
                }
                break;
            default:
                break;
            }
        }
        if ( size == 0 ) {
            size = 8;
            mask = 0xffffffff;
        }
        break;
    }
    if( size > 8 ) {
        size = 8;
        if( sign_extended ) {
            if( value < 0 ) {
                FmtHexNum( buff, size, 0xffffffff, no_prefix );
            } else {
                FmtHexNum( buff, size, 0, no_prefix );
            }
            buff += strlen( buff );
            no_prefix = TRUE;
        }
    }
    FmtHexNum( buff, size, mask & value, no_prefix );
}
Beispiel #5
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 ) );
}
Beispiel #6
0
static return_val referenceString( ref_entry r_entry, orl_sec_size size,
                                   char *ext_pref, char *int_pref, char *post,
                                   char *buff, ref_flags flags )
{
    label_entry         l_entry;
    char                *sep = ":";
    char                *frame;
    char                temp[15];

    frame = r_entry->frame;
    if( !frame || ( flags & RFLAG_NO_FRAME ) ) {
        frame = "";
        sep = "";
    }

    l_entry = r_entry->label;
    if( Options & METAWARE_COMPATIBLE || (ext_pref[0]==0 && int_pref[0]==0) ) {
        switch( l_entry->type ) {
        case LTYP_ABSOLUTE:
            FmtHexNum( temp, 0, l_entry->offset, FALSE );
            if( *frame == 0 && ( ( flags & RFLAG_NO_FRAME ) == 0 ) )
                frame = "ds:";
            sprintf( buff, "%s%s[%s]", frame, sep, temp);
            break;
        case LTYP_UNNAMED:
            sprintf( buff, "%s%s%c$%ld%s", frame, sep, LabelChar,
                     (long)l_entry->label.number, post );
            break;
        default:
            sprintf( buff, "%s%s%s%s", frame, sep, l_entry->label.name,
                     post );
            break;
        }
    } else {
        switch( l_entry->type ) {
        case LTYP_EXTERNAL_NAMED:
            sprintf( buff, "%s%s%s%s", ext_pref, frame, sep,
                     l_entry->label.name );
            break;
        case LTYP_NAMED:
        case LTYP_SECTION:
        case LTYP_GROUP:
            sprintf( buff, "%s%s%s%s", int_pref, frame, sep,
                     l_entry->label.name );
            break;

        case LTYP_ABSOLUTE:
            FmtHexNum( temp, 0, l_entry->offset, FALSE );
            if( *frame == 0 && ( ( flags & RFLAG_NO_FRAME ) == 0 ) )
                frame = "ds:";
            sprintf( buff, "%s%s%s[%s]", int_pref, frame, sep, temp);
            break;

        default:
            sprintf( buff, "%s%s%s%c$%ld", int_pref, frame, sep,
                     LabelChar, (long)l_entry->label.number );
            if( l_entry->offset > size ) {
                return( RC_ERROR );
            }
            break;
        }
    }
    return( RC_OKAY );
}