12b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// copyright notice, this list of conditions and the following disclaimer
22b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// in the documentation and/or other materials provided with the
32b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// distribution.
42b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org//     * Neither the name of Google Inc. nor the names of its
52b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// contributors may be used to endorse or promote products derived from
62b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// this software without specific prior written permission.
72b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org//
82b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
92b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// disassembler_x86.cc: simple x86 disassembler.
212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org//
222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// Provides single step disassembly of x86 bytecode and flags instructions
232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// that utilize known bad register values.
242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org//
252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org// Author: Cris Neckar
262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "processor/disassembler_x86.h"
282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <string.h>
302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <unistd.h>
312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgnamespace google_breakpad {
332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
346162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comDisassemblerX86::DisassemblerX86(const uint8_t *bytecode,
356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com                                 uint32_t size,
366162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com                                 uint32_t virtual_address) :
372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     bytecode_(bytecode),
382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     size_(size),
392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     virtual_address_(virtual_address),
402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     current_byte_offset_(0),
412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     current_inst_offset_(0),
422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     instr_valid_(false),
432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     register_valid_(false),
442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     pushed_bad_value_(false),
452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     end_of_block_(false),
462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                     flags_(0) {
472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  libdis::x86_init(libdis::opt_none, NULL, NULL);
482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org}
492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgDisassemblerX86::~DisassemblerX86() {
519a51ba04705be56f59e27e510958d6356153fdb9benchan@chromium.org  if (instr_valid_)
529a51ba04705be56f59e27e510958d6356153fdb9benchan@chromium.org    libdis::x86_oplist_free(&current_instr_);
539a51ba04705be56f59e27e510958d6356153fdb9benchan@chromium.org
542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  libdis::x86_cleanup();
552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org}
562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
576162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.comuint32_t DisassemblerX86::NextInstruction() {
582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (instr_valid_)
592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    libdis::x86_oplist_free(&current_instr_);
602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (current_byte_offset_ >= size_) {
622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    instr_valid_ = false;
632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    return 0;
642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  }
656162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com  uint32_t instr_size = 0;
662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  instr_size = libdis::x86_disasm((unsigned char *)bytecode_, size_,
672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                          virtual_address_, current_byte_offset_,
682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                          &current_instr_);
692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (instr_size == 0) {
702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    instr_valid_ = false;
712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    return 0;
722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  }
732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  current_byte_offset_ += instr_size;
752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  current_inst_offset_++;
762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  instr_valid_ = libdis::x86_insn_is_valid(&current_instr_);
772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (!instr_valid_)
782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    return 0;
792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (current_instr_.type == libdis::insn_return)
812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    end_of_block_ = true;
822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  libdis::x86_op_t *src = libdis::x86_get_src_operand(&current_instr_);
832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  libdis::x86_op_t *dest = libdis::x86_get_dest_operand(&current_instr_);
842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (register_valid_) {
862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    switch (current_instr_.group) {
872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      // Flag branches based off of bad registers and calls that occur
882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      // after pushing bad values.
892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_controlflow:
902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        switch (current_instr_.type) {
912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          case libdis::insn_jmp:
922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          case libdis::insn_jcc:
932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          case libdis::insn_call:
942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          case libdis::insn_callcc:
952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            if (dest) {
962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org              switch (dest->type) {
972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                case libdis::op_expression:
982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                  if (dest->data.expression.base.id == bad_register_.id)
992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                    flags_ |= DISX86_BAD_BRANCH_TARGET;
1002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                  break;
1012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                case libdis::op_register:
1022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                  if (dest->data.reg.id == bad_register_.id)
1032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                    flags_ |= DISX86_BAD_BRANCH_TARGET;
1042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                  break;
1052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                default:
1062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                  if (pushed_bad_value_ &&
1072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                      (current_instr_.type == libdis::insn_call ||
1082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                      current_instr_.type == libdis::insn_callcc))
1092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                    flags_ |= DISX86_BAD_ARGUMENT_PASSED;
1102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                  break;
1112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org              }
1122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            }
1132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            break;
114361f24eac7fb452a795709479fc48fd59b04bc1fSiyangXie@gmail.com          default:
115361f24eac7fb452a795709479fc48fd59b04bc1fSiyangXie@gmail.com            break;
1162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        }
1172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
1182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      // Flag block data operations that use bad registers for src or dest.
1202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_string:
1212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if (dest && dest->type == libdis::op_expression &&
1222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            dest->data.expression.base.id == bad_register_.id)
1232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          flags_ |= DISX86_BAD_BLOCK_WRITE;
1242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if (src && src->type == libdis::op_expression &&
1252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            src->data.expression.base.id == bad_register_.id)
1262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          flags_ |= DISX86_BAD_BLOCK_READ;
1272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
1282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      // Flag comparisons based on bad data.
1302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_comparison:
1312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if ((dest && dest->type == libdis::op_expression &&
1322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            dest->data.expression.base.id == bad_register_.id) ||
1332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            (src && src->type == libdis::op_expression &&
1342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            src->data.expression.base.id == bad_register_.id) ||
1352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            (dest && dest->type == libdis::op_register &&
1362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            dest->data.reg.id == bad_register_.id) ||
1372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            (src && src->type == libdis::op_register &&
1382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            src->data.reg.id == bad_register_.id))
1392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          flags_ |= DISX86_BAD_COMPARISON;
1402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
1412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      // Flag any other instruction which derefs a bad register for
1432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      // src or dest.
1442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      default:
1452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if (dest && dest->type == libdis::op_expression &&
1462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            dest->data.expression.base.id == bad_register_.id)
1472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          flags_ |= DISX86_BAD_WRITE;
1482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if (src && src->type == libdis::op_expression &&
1492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            src->data.expression.base.id == bad_register_.id)
1502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          flags_ |= DISX86_BAD_READ;
1512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
1522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    }
1532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  }
1542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  // When a register is marked as tainted check if it is pushed.
1562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  // TODO(cdn): may also want to check for MOVs into EBP offsets.
1572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (register_valid_ && dest && current_instr_.type == libdis::insn_push) {
1582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    switch (dest->type) {
1592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::op_expression:
1602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if (dest->data.expression.base.id == bad_register_.id ||
1612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            dest->data.expression.index.id == bad_register_.id)
1622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          pushed_bad_value_ = true;
1632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
1642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::op_register:
1652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if (dest->data.reg.id == bad_register_.id)
1662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          pushed_bad_value_ = true;
1672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
168361f24eac7fb452a795709479fc48fd59b04bc1fSiyangXie@gmail.com      default:
169361f24eac7fb452a795709479fc48fd59b04bc1fSiyangXie@gmail.com        break;
1702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    }
1712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  }
1722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  // Check if a tainted register value is clobbered.
1742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  // For conditional MOVs and XCHGs assume that
1752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  // there is a hit.
1762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (register_valid_) {
1772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    switch (current_instr_.type) {
1782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_xor:
1792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if (src && src->type == libdis::op_register &&
18094074a84d0907f7151b7f274606fcbcf1a248fd5cdn@chromium.org            dest && dest->type == libdis::op_register &&
1812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            src->data.reg.id == bad_register_.id &&
1822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            src->data.reg.id == dest->data.reg.id)
1832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          register_valid_ = false;
1842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
1852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_pop:
1862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_mov:
1872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_movcc:
1882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if (dest && dest->type == libdis::op_register &&
1892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            dest->data.reg.id == bad_register_.id)
1902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          register_valid_ = false;
1912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
1922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_popregs:
1932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        register_valid_ = false;
1942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
1952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_xchg:
1962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org      case libdis::insn_xchgcc:
1972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        if (dest && dest->type == libdis::op_register &&
19894074a84d0907f7151b7f274606fcbcf1a248fd5cdn@chromium.org            src && src->type == libdis::op_register) {
1992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          if (dest->data.reg.id == bad_register_.id)
2002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            memcpy(&bad_register_, &src->data.reg, sizeof(libdis::x86_reg_t));
2012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org          else if (src->data.reg.id == bad_register_.id)
2022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org            memcpy(&bad_register_, &dest->data.reg, sizeof(libdis::x86_reg_t));
2032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        }
2042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        break;
205361f24eac7fb452a795709479fc48fd59b04bc1fSiyangXie@gmail.com      default:
206361f24eac7fb452a795709479fc48fd59b04bc1fSiyangXie@gmail.com        break;
2072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    }
2082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  }
2092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  return instr_size;
2112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org}
2122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgbool DisassemblerX86::setBadRead() {
2142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (!instr_valid_)
2152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    return false;
2162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  libdis::x86_op_t *operand = libdis::x86_get_src_operand(&current_instr_);
218fb7fdb9426ac53d17b7ba034264aa4ee4a50b19ecdn@chromium.org  if (!operand || operand->type != libdis::op_expression)
2192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    return false;
2202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  memcpy(&bad_register_, &operand->data.expression.base,
2222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org         sizeof(libdis::x86_reg_t));
2232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  register_valid_ = true;
2242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  return true;
2252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org}
2262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgbool DisassemblerX86::setBadWrite() {
2282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  if (!instr_valid_)
2292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    return false;
2302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  libdis::x86_op_t *operand = libdis::x86_get_dest_operand(&current_instr_);
232fb7fdb9426ac53d17b7ba034264aa4ee4a50b19ecdn@chromium.org  if (!operand || operand->type != libdis::op_expression)
2332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    return false;
2342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  memcpy(&bad_register_, &operand->data.expression.base,
2362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org         sizeof(libdis::x86_reg_t));
2372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  register_valid_ = true;
2382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org  return true;
2392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org}
2402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org}  // namespace google_breakpad
242