toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_insn.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_insn.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,182 @@
     1.4 +#include <stdio.h>
     1.5 +#include <stdlib.h>
     1.6 +
     1.7 +#include "libdis.h"
     1.8 +
     1.9 +#ifdef _MSC_VER
    1.10 +        #define snprintf        _snprintf
    1.11 +        #define inline          __inline
    1.12 +#endif
    1.13 +
    1.14 +int x86_insn_is_valid( x86_insn_t *insn ) {
    1.15 +	if ( insn && insn->type != insn_invalid && insn->size > 0 ) {
    1.16 +		return 1;
    1.17 +	}
    1.18 +
    1.19 +	return 0;
    1.20 +}
    1.21 +
    1.22 +uint32_t x86_get_address( x86_insn_t *insn ) {
    1.23 +	x86_oplist_t *op_lst;
    1.24 +        if (! insn || ! insn->operands ) {
    1.25 +        	return 0;
    1.26 +        }
    1.27 +
    1.28 +	for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
    1.29 +		if ( op_lst->op.type == op_offset ) {
    1.30 +			return op_lst->op.data.offset;
    1.31 +		} else if ( op_lst->op.type == op_absolute ) {
    1.32 +			if ( op_lst->op.datatype == op_descr16 ) {
    1.33 +				return (uint32_t)
    1.34 +					op_lst->op.data.absolute.offset.off16;
    1.35 +			}
    1.36 +			return op_lst->op.data.absolute.offset.off32;
    1.37 +		}
    1.38 +	}
    1.39 +	
    1.40 +	return 0;
    1.41 +}
    1.42 +
    1.43 +int32_t x86_get_rel_offset( x86_insn_t *insn ) {
    1.44 +	x86_oplist_t *op_lst;
    1.45 +        if (! insn || ! insn->operands ) {
    1.46 +        	return 0;
    1.47 +        }
    1.48 +
    1.49 +	for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
    1.50 +		if ( op_lst->op.type == op_relative_near ) {
    1.51 +			return (int32_t) op_lst->op.data.relative_near;
    1.52 +		} else if ( op_lst->op.type == op_relative_far ) {
    1.53 +			return op_lst->op.data.relative_far;
    1.54 +		}
    1.55 +	}
    1.56 +	
    1.57 +	return 0;
    1.58 +}
    1.59 +
    1.60 +x86_op_t * x86_get_branch_target( x86_insn_t *insn ) {
    1.61 +	x86_oplist_t *op_lst;
    1.62 +        if (! insn || ! insn->operands ) {
    1.63 +        	return NULL;
    1.64 +        }
    1.65 +
    1.66 +	for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
    1.67 +		if ( op_lst->op.access & op_execute ) {
    1.68 +			return &(op_lst->op);
    1.69 +		}
    1.70 +	}
    1.71 +	
    1.72 +	return NULL;
    1.73 +}
    1.74 +x86_op_t * x86_get_imm( x86_insn_t *insn ) {
    1.75 +	x86_oplist_t *op_lst;
    1.76 +        if (! insn || ! insn->operands ) {
    1.77 +        	return NULL;
    1.78 +        }
    1.79 +
    1.80 +	for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
    1.81 +		if ( op_lst->op.type == op_immediate ) {
    1.82 +			return &(op_lst->op);
    1.83 +		}
    1.84 +	}
    1.85 +	
    1.86 +	return NULL;
    1.87 +}
    1.88 +
    1.89 +#define IS_PROPER_IMM( x ) \
    1.90 +	x->op.type == op_immediate && ! (x->op.flags & op_hardcode)
    1.91 +							   
    1.92 +
    1.93 +/* if there is an immediate value in the instruction, return a pointer to
    1.94 + * it */
    1.95 +unsigned char * x86_get_raw_imm( x86_insn_t *insn ) {
    1.96 +        int size, offset;
    1.97 +        x86_op_t *op  = NULL;
    1.98 +
    1.99 +        if (! insn || ! insn->operands ) {
   1.100 +        	return(NULL);
   1.101 +        }
   1.102 +
   1.103 +	/* a bit inelegant, but oh well... */
   1.104 +	if ( IS_PROPER_IMM( insn->operands ) ) {
   1.105 +		op = &insn->operands->op;
   1.106 +	} else if ( insn->operands->next ) {
   1.107 +		if ( IS_PROPER_IMM( insn->operands->next ) ) {
   1.108 +			op = &insn->operands->next->op;
   1.109 +		} else if ( insn->operands->next->next && 
   1.110 +			    IS_PROPER_IMM( insn->operands->next->next ) ) {
   1.111 +			op = &insn->operands->next->next->op;
   1.112 +		}
   1.113 +	}
   1.114 +	
   1.115 +	if (! op ) {
   1.116 +		return( NULL );
   1.117 +	}
   1.118 +
   1.119 +	/* immediate data is at the end of the insn */
   1.120 +	size = x86_operand_size( op );
   1.121 +	offset = insn->size - size;
   1.122 +	return( &insn->bytes[offset] );
   1.123 +}
   1.124 +
   1.125 +
   1.126 +unsigned int x86_operand_size( x86_op_t *op ) {
   1.127 +        switch (op->datatype ) {
   1.128 +                case op_byte:    return 1;
   1.129 +                case op_word:    return 2;
   1.130 +                case op_dword:   return 4;
   1.131 +                case op_qword:   return 8;
   1.132 +                case op_dqword:  return 16;
   1.133 +                case op_sreal:   return 4;
   1.134 +                case op_dreal:   return 8;
   1.135 +                case op_extreal: return 10;
   1.136 +                case op_bcd:     return 10;
   1.137 +                case op_ssimd:   return 16;
   1.138 +                case op_dsimd:   return 16;
   1.139 +                case op_sssimd:  return 4;
   1.140 +                case op_sdsimd:  return 8;
   1.141 +                case op_descr32: return 6;
   1.142 +                case op_descr16: return 4;
   1.143 +                case op_pdescr32: return 6;
   1.144 +                case op_pdescr16: return 6;
   1.145 +		case op_bounds16: return 4;
   1.146 +		case op_bounds32: return 8;
   1.147 +                case op_fpuenv16:  return 14;
   1.148 +                case op_fpuenv32:  return 28;
   1.149 +                case op_fpustate16:  return 94;
   1.150 +                case op_fpustate32:  return 108;
   1.151 +                case op_fpregset: return 512;
   1.152 +		case op_fpreg: return 10;
   1.153 +		case op_none: return 0;
   1.154 +        }
   1.155 +        return(4);      /* default size */
   1.156 +}
   1.157 +
   1.158 +void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ) {
   1.159 +        if ( insn ) insn->addr = addr;
   1.160 +}
   1.161 +
   1.162 +void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ){
   1.163 +        if ( insn ) insn->offset = offset;
   1.164 +}
   1.165 +
   1.166 +void x86_set_insn_function( x86_insn_t *insn, void * func ){
   1.167 +        if ( insn ) insn->function = func;
   1.168 +}
   1.169 +
   1.170 +void x86_set_insn_block( x86_insn_t *insn, void * block ){
   1.171 +        if ( insn ) insn->block = block;
   1.172 +}
   1.173 +
   1.174 +void x86_tag_insn( x86_insn_t *insn ){
   1.175 +        if ( insn ) insn->tag = 1;
   1.176 +}
   1.177 +
   1.178 +void x86_untag_insn( x86_insn_t *insn ){
   1.179 +        if ( insn ) insn->tag = 0;
   1.180 +}
   1.181 +
   1.182 +int x86_insn_is_tagged( x86_insn_t *insn ){
   1.183 +        return insn->tag;
   1.184 +}
   1.185 +

mercurial