PageRenderTime 52ms CodeModel.GetById 12ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 1ms

/thirdparty/breakpad/third_party/libdisasm/x86_insn.c

http://github.com/tomahawk-player/tomahawk
C | 182 lines | 146 code | 32 blank | 4 comment | 50 complexity | 9a1f1002b683b94dedb8a292c505d3b6 MD5 | raw file
  1#include <stdio.h>
  2#include <stdlib.h>
  3
  4#include "libdis.h"
  5
  6#ifdef _MSC_VER
  7        #define snprintf        _snprintf
  8        #define inline          __inline
  9#endif
 10
 11int x86_insn_is_valid( x86_insn_t *insn ) {
 12	if ( insn && insn->type != insn_invalid && insn->size > 0 ) {
 13		return 1;
 14	}
 15
 16	return 0;
 17}
 18
 19uint32_t x86_get_address( x86_insn_t *insn ) {
 20	x86_oplist_t *op_lst;
 21        if (! insn || ! insn->operands ) {
 22        	return 0;
 23        }
 24
 25	for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
 26		if ( op_lst->op.type == op_offset ) {
 27			return op_lst->op.data.offset;
 28		} else if ( op_lst->op.type == op_absolute ) {
 29			if ( op_lst->op.datatype == op_descr16 ) {
 30				return (uint32_t)
 31					op_lst->op.data.absolute.offset.off16;
 32			}
 33			return op_lst->op.data.absolute.offset.off32;
 34		}
 35	}
 36	
 37	return 0;
 38}
 39
 40int32_t x86_get_rel_offset( x86_insn_t *insn ) {
 41	x86_oplist_t *op_lst;
 42        if (! insn || ! insn->operands ) {
 43        	return 0;
 44        }
 45
 46	for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
 47		if ( op_lst->op.type == op_relative_near ) {
 48			return (int32_t) op_lst->op.data.relative_near;
 49		} else if ( op_lst->op.type == op_relative_far ) {
 50			return op_lst->op.data.relative_far;
 51		}
 52	}
 53	
 54	return 0;
 55}
 56
 57x86_op_t * x86_get_branch_target( x86_insn_t *insn ) {
 58	x86_oplist_t *op_lst;
 59        if (! insn || ! insn->operands ) {
 60        	return NULL;
 61        }
 62
 63	for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
 64		if ( op_lst->op.access & op_execute ) {
 65			return &(op_lst->op);
 66		}
 67	}
 68	
 69	return NULL;
 70}
 71x86_op_t * x86_get_imm( x86_insn_t *insn ) {
 72	x86_oplist_t *op_lst;
 73        if (! insn || ! insn->operands ) {
 74        	return NULL;
 75        }
 76
 77	for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
 78		if ( op_lst->op.type == op_immediate ) {
 79			return &(op_lst->op);
 80		}
 81	}
 82	
 83	return NULL;
 84}
 85
 86#define IS_PROPER_IMM( x ) \
 87	x->op.type == op_immediate && ! (x->op.flags & op_hardcode)
 88							   
 89
 90/* if there is an immediate value in the instruction, return a pointer to
 91 * it */
 92unsigned char * x86_get_raw_imm( x86_insn_t *insn ) {
 93        int size, offset;
 94        x86_op_t *op  = NULL;
 95
 96        if (! insn || ! insn->operands ) {
 97        	return(NULL);
 98        }
 99
100	/* a bit inelegant, but oh well... */
101	if ( IS_PROPER_IMM( insn->operands ) ) {
102		op = &insn->operands->op;
103	} else if ( insn->operands->next ) {
104		if ( IS_PROPER_IMM( insn->operands->next ) ) {
105			op = &insn->operands->next->op;
106		} else if ( insn->operands->next->next && 
107			    IS_PROPER_IMM( insn->operands->next->next ) ) {
108			op = &insn->operands->next->next->op;
109		}
110	}
111	
112	if (! op ) {
113		return( NULL );
114	}
115
116	/* immediate data is at the end of the insn */
117	size = x86_operand_size( op );
118	offset = insn->size - size;
119	return( &insn->bytes[offset] );
120}
121
122
123unsigned int x86_operand_size( x86_op_t *op ) {
124        switch (op->datatype ) {
125                case op_byte:    return 1;
126                case op_word:    return 2;
127                case op_dword:   return 4;
128                case op_qword:   return 8;
129                case op_dqword:  return 16;
130                case op_sreal:   return 4;
131                case op_dreal:   return 8;
132                case op_extreal: return 10;
133                case op_bcd:     return 10;
134                case op_ssimd:   return 16;
135                case op_dsimd:   return 16;
136                case op_sssimd:  return 4;
137                case op_sdsimd:  return 8;
138                case op_descr32: return 6;
139                case op_descr16: return 4;
140                case op_pdescr32: return 6;
141                case op_pdescr16: return 6;
142		case op_bounds16: return 4;
143		case op_bounds32: return 8;
144                case op_fpuenv16:  return 14;
145                case op_fpuenv32:  return 28;
146                case op_fpustate16:  return 94;
147                case op_fpustate32:  return 108;
148                case op_fpregset: return 512;
149		case op_fpreg: return 10;
150		case op_none: return 0;
151        }
152        return(4);      /* default size */
153}
154
155void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ) {
156        if ( insn ) insn->addr = addr;
157}
158
159void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ){
160        if ( insn ) insn->offset = offset;
161}
162
163void x86_set_insn_function( x86_insn_t *insn, void * func ){
164        if ( insn ) insn->function = func;
165}
166
167void x86_set_insn_block( x86_insn_t *insn, void * block ){
168        if ( insn ) insn->block = block;
169}
170
171void x86_tag_insn( x86_insn_t *insn ){
172        if ( insn ) insn->tag = 1;
173}
174
175void x86_untag_insn( x86_insn_t *insn ){
176        if ( insn ) insn->tag = 0;
177}
178
179int x86_insn_is_tagged( x86_insn_t *insn ){
180        return insn->tag;
181}
182