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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial