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 +