Logo Search packages:      
Sourcecode: libdisasm version File versions  Download package

x86_insn.c

#include <stdio.h>
#include <stdlib.h>

#include "libdis.h"

#ifdef _MSC_VER
        #define snprintf        _snprintf
        #define inline          __inline
#endif

int x86_insn_is_valid( x86_insn_t *insn ) {
      if ( insn && insn->type != insn_invalid && insn->size > 0 ) {
            return 1;
      }

      return 0;
}

uint32_t x86_get_address( x86_insn_t *insn ) {
      x86_oplist_t *op_lst;
        if (! insn || ! insn->operands ) {
            return 0;
        }

      for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
            if ( op_lst->op.type == op_offset ) {
                  return op_lst->op.data.offset;
            } else if ( op_lst->op.type == op_absolute ) {
                  if ( op_lst->op.datatype == op_descr16 ) {
                        return (uint32_t)
                              op_lst->op.data.absolute.offset.off16;
                  }
                  return op_lst->op.data.absolute.offset.off32;
            }
      }
      
      return 0;
}

int32_t x86_get_rel_offset( x86_insn_t *insn ) {
      x86_oplist_t *op_lst;
        if (! insn || ! insn->operands ) {
            return 0;
        }

      for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
            if ( op_lst->op.type == op_relative_near ) {
                  return (int32_t) op_lst->op.data.relative_near;
            } else if ( op_lst->op.type == op_relative_far ) {
                  return op_lst->op.data.relative_far;
            }
      }
      
      return 0;
}

x86_op_t * x86_get_branch_target( x86_insn_t *insn ) {
      x86_oplist_t *op_lst;
        if (! insn || ! insn->operands ) {
            return NULL;
        }

      for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
            if ( op_lst->op.access & op_execute ) {
                  return &(op_lst->op);
            }
      }
      
      return NULL;
}
x86_op_t * x86_get_imm( x86_insn_t *insn ) {
      x86_oplist_t *op_lst;
        if (! insn || ! insn->operands ) {
            return NULL;
        }

      for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
            if ( op_lst->op.type == op_immediate ) {
                  return &(op_lst->op);
            }
      }
      
      return NULL;
}

#define IS_PROPER_IMM( x ) \
      x->op.type == op_immediate && ! (x->op.flags & op_hardcode)
                                             

/* if there is an immediate value in the instruction, return a pointer to
 * it */
unsigned char * x86_get_raw_imm( x86_insn_t *insn ) {
        int size, offset;
        x86_op_t *op  = NULL;

        if (! insn || ! insn->operands ) {
            return(NULL);
        }

      /* a bit inelegant, but oh well... */
      if ( IS_PROPER_IMM( insn->operands ) ) {
            op = &insn->operands->op;
      } else if ( insn->operands->next ) {
            if ( IS_PROPER_IMM( insn->operands->next ) ) {
                  op = &insn->operands->next->op;
            } else if ( insn->operands->next->next && 
                      IS_PROPER_IMM( insn->operands->next->next ) ) {
                  op = &insn->operands->next->next->op;
            }
      }
      
      if (! op ) {
            return( NULL );
      }

      /* immediate data is at the end of the insn */
      size = x86_operand_size( op );
      offset = insn->size - size;
      return( &insn->bytes[offset] );
}


unsigned int x86_operand_size( x86_op_t *op ) {
        switch (op->datatype ) {
                case op_byte:    return 1;
                case op_word:    return 2;
                case op_dword:   return 4;
                case op_qword:   return 8;
                case op_dqword:  return 16;
                case op_sreal:   return 4;
                case op_dreal:   return 8;
                case op_extreal: return 10;
                case op_bcd:     return 10;
                case op_ssimd:   return 16;
                case op_dsimd:   return 16;
                case op_sssimd:  return 4;
                case op_sdsimd:  return 8;
                case op_descr32: return 6;
                case op_descr16: return 4;
                case op_pdescr32: return 6;
                case op_pdescr16: return 6;
            case op_bounds16: return 4;
            case op_bounds32: return 8;
                case op_fpuenv16:  return 14;
                case op_fpuenv32:  return 28;
                case op_fpustate16:  return 94;
                case op_fpustate32:  return 108;
                case op_fpregset: return 512;
            case op_fpreg: return 10;
            case op_none: return 0;
        }
        return(4);      /* default size */
}

void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ) {
        if ( insn ) insn->addr = addr;
}

void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ){
        if ( insn ) insn->offset = offset;
}

void x86_set_insn_function( x86_insn_t *insn, void * func ){
        if ( insn ) insn->function = func;
}

void x86_set_insn_block( x86_insn_t *insn, void * block ){
        if ( insn ) insn->block = block;
}

void x86_tag_insn( x86_insn_t *insn ){
        if ( insn ) insn->tag = 1;
}

void x86_untag_insn( x86_insn_t *insn ){
        if ( insn ) insn->tag = 0;
}

int x86_insn_is_tagged( x86_insn_t *insn ){
        return insn->tag;
}


Generated by  Doxygen 1.6.0   Back to index