| File: | root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/crashreporter/google-breakpad/src/processor/./../../../../../../toolkit/crashreporter/google-breakpad/src/third_party/libdisasm/x86_disasm.c |
| Warning: | line 155, column 25 Value stored to 'next_addr' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | #include <stdio.h> |
| 2 | #include <stdlib.h> |
| 3 | #include <string.h> |
| 4 | |
| 5 | #include "libdis.h" |
| 6 | #include "ia32_insn.h" |
| 7 | #include "ia32_invariant.h" |
| 8 | #include "x86_operand_list.h" |
| 9 | |
| 10 | |
| 11 | #ifdef _MSC_VER |
| 12 | #define snprintf _snprintf |
| 13 | #define inline __inline |
| 14 | #endif |
| 15 | |
| 16 | unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len, |
| 17 | uint32_t buf_rva, unsigned int offset, |
| 18 | x86_insn_t *insn ){ |
| 19 | int len, size; |
| 20 | unsigned char bytes[MAX_INSTRUCTION_SIZE20]; |
| 21 | |
| 22 | if ( ! buf || ! insn || ! buf_len ) { |
| 23 | /* caller screwed up somehow */ |
| 24 | return 0; |
| 25 | } |
| 26 | |
| 27 | |
| 28 | /* ensure we are all NULLed up */ |
| 29 | memset( insn, 0, sizeof(x86_insn_t) ); |
| 30 | insn->addr = buf_rva + offset; |
| 31 | insn->offset = offset; |
| 32 | /* default to invalid insn */ |
| 33 | insn->type = insn_invalid; |
| 34 | insn->group = insn_none; |
| 35 | |
| 36 | if ( offset >= buf_len ) { |
| 37 | /* another caller screwup ;) */ |
| 38 | x86_report_error(report_disasm_bounds, (void*)(long)(buf_rva+offset)); |
| 39 | return 0; |
| 40 | } |
| 41 | |
| 42 | len = buf_len - offset; |
| 43 | |
| 44 | /* copy enough bytes for disassembly into buffer : this |
| 45 | * helps prevent buffer overruns at the end of a file */ |
| 46 | memset( bytes, 0, MAX_INSTRUCTION_SIZE20 ); |
| 47 | memcpy( bytes, &buf[offset], (len < MAX_INSTRUCTION_SIZE20) ? len : |
| 48 | MAX_INSTRUCTION_SIZE20 ); |
| 49 | |
| 50 | /* actually do the disassembly */ |
| 51 | /* TODO: allow switching when more disassemblers are added */ |
| 52 | size = ia32_disasm_addr( bytes, len, insn); |
| 53 | |
| 54 | /* check and see if we had an invalid instruction */ |
| 55 | if (! size ) { |
| 56 | x86_report_error(report_invalid_insn, (void*)(long)(buf_rva+offset)); |
| 57 | return 0; |
| 58 | } |
| 59 | |
| 60 | /* check if we overran the end of the buffer */ |
| 61 | if ( size > len ) { |
| 62 | x86_report_error( report_insn_bounds, (void*)(long)(buf_rva + offset)); |
| 63 | MAKE_INVALID( insn, bytes )strcpy( insn->mnemonic, "invalid" ); x86_oplist_free( insn ); insn->size = 1; insn->group = insn_none; insn->type = insn_invalid; memcpy( insn->bytes, bytes, 1 );; |
| 64 | return 0; |
| 65 | } |
| 66 | |
| 67 | /* fill bytes field of insn */ |
| 68 | memcpy( insn->bytes, bytes, size ); |
| 69 | |
| 70 | return size; |
| 71 | } |
| 72 | |
| 73 | unsigned int x86_disasm_range( unsigned char *buf, uint32_t buf_rva, |
| 74 | unsigned int offset, unsigned int len, |
| 75 | DISASM_CALLBACK func, void *arg ) { |
| 76 | x86_insn_t insn; |
| 77 | unsigned int buf_len, size, count = 0, bytes = 0; |
| 78 | |
| 79 | /* buf_len is implied by the arguments */ |
| 80 | buf_len = len + offset; |
| 81 | |
| 82 | while ( bytes < len ) { |
| 83 | size = x86_disasm( buf, buf_len, buf_rva, offset + bytes, |
| 84 | &insn ); |
| 85 | if ( size ) { |
| 86 | /* invoke callback if it exists */ |
| 87 | if ( func ) { |
| 88 | (*func)( &insn, arg ); |
| 89 | } |
| 90 | bytes += size; |
| 91 | count ++; |
| 92 | } else { |
| 93 | /* error */ |
| 94 | bytes++; /* try next byte */ |
| 95 | } |
| 96 | |
| 97 | x86_oplist_free( &insn ); |
| 98 | } |
| 99 | |
| 100 | return( count ); |
| 101 | } |
| 102 | |
| 103 | static inline int follow_insn_dest( x86_insn_t *insn ) { |
| 104 | if ( insn->type == insn_jmp || insn->type == insn_jcc || |
| 105 | insn->type == insn_call || insn->type == insn_callcc ) { |
| 106 | return(1); |
| 107 | } |
| 108 | return(0); |
| 109 | } |
| 110 | |
| 111 | static inline int insn_doesnt_return( x86_insn_t *insn ) { |
| 112 | return( (insn->type == insn_jmp || insn->type == insn_return) ? 1: 0 ); |
| 113 | } |
| 114 | |
| 115 | static int32_t internal_resolver( x86_op_t *op, x86_insn_t *insn ){ |
| 116 | int32_t next_addr = -1; |
| 117 | if ( x86_optype_is_address(op->type)( op->type == op_absolute || op->type == op_offset ) ) { |
| 118 | next_addr = op->data.sdword; |
| 119 | } else if ( op->type == op_relative_near ) { |
| 120 | next_addr = insn->addr + insn->size + op->data.relative_near; |
| 121 | } else if ( op->type == op_relative_far ) { |
| 122 | next_addr = insn->addr + insn->size + op->data.relative_far; |
| 123 | } |
| 124 | return( next_addr ); |
| 125 | } |
| 126 | |
| 127 | unsigned int x86_disasm_forward( unsigned char *buf, unsigned int buf_len, |
| 128 | uint32_t buf_rva, unsigned int offset, |
| 129 | DISASM_CALLBACK func, void *arg, |
| 130 | DISASM_RESOLVER resolver, void *r_arg ){ |
| 131 | x86_insn_t insn; |
| 132 | x86_op_t *op; |
| 133 | int32_t next_addr; |
| 134 | uint32_t next_offset; |
| 135 | unsigned int size, count = 0, bytes = 0, cont = 1; |
| 136 | |
| 137 | while ( cont && bytes < buf_len ) { |
| 138 | size = x86_disasm( buf, buf_len, buf_rva, offset + bytes, |
| 139 | &insn ); |
| 140 | |
| 141 | if ( size ) { |
| 142 | /* invoke callback if it exists */ |
| 143 | if ( func ) { |
| 144 | (*func)( &insn, arg ); |
| 145 | } |
| 146 | bytes += size; |
| 147 | count ++; |
| 148 | } else { |
| 149 | /* error */ |
| 150 | bytes++; /* try next byte */ |
| 151 | } |
| 152 | |
| 153 | if ( follow_insn_dest(&insn) ) { |
| 154 | op = x86_get_dest_operand( &insn )x86_operand_1st( &insn ); |
| 155 | next_addr = -1; |
Value stored to 'next_addr' is never read | |
| 156 | |
| 157 | /* if caller supplied a resolver, use it to determine |
| 158 | * the address to disassemble */ |
| 159 | if ( resolver ) { |
| 160 | next_addr = resolver(op, &insn, r_arg); |
| 161 | } else { |
| 162 | next_addr = internal_resolver(op, &insn); |
| 163 | } |
| 164 | |
| 165 | if (next_addr != -1 ) { |
| 166 | next_offset = next_addr - buf_rva; |
| 167 | /* if offset is in this buffer... */ |
| 168 | if ( (uint32_t)next_addr >= buf_rva && |
| 169 | next_offset < buf_len ) { |
| 170 | /* go ahead and disassemble */ |
| 171 | count += x86_disasm_forward( buf, |
| 172 | buf_len, |
| 173 | buf_rva, |
| 174 | next_offset, |
| 175 | func, arg, |
| 176 | resolver, r_arg ); |
| 177 | } else { |
| 178 | /* report unresolved address */ |
| 179 | x86_report_error( report_disasm_bounds, |
| 180 | (void*)(long)next_addr ); |
| 181 | } |
| 182 | } |
| 183 | } /* end follow_insn */ |
| 184 | |
| 185 | if ( insn_doesnt_return(&insn) ) { |
| 186 | /* stop disassembling */ |
| 187 | cont = 0; |
| 188 | } |
| 189 | |
| 190 | x86_oplist_free( &insn ); |
| 191 | } |
| 192 | return( count ); |
| 193 | } |
| 194 | |
| 195 | /* invariant instruction representation */ |
| 196 | size_t x86_invariant_disasm( unsigned char *buf, int buf_len, |
| 197 | x86_invariant_t *inv ){ |
| 198 | if (! buf || ! buf_len || ! inv ) { |
| 199 | return(0); |
| 200 | } |
| 201 | |
| 202 | return ia32_disasm_invariant(buf, buf_len, inv); |
| 203 | } |
| 204 | size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ) { |
| 205 | if (! buf || ! buf_len ) { |
| 206 | return(0); |
| 207 | } |
| 208 | |
| 209 | return ia32_disasm_size(buf, buf_len); |
| 210 | } |