1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,127 @@ 1.4 +// All rights reserved. 1.5 +// 1.6 +// Redistribution and use in source and binary forms, with or without 1.7 +// modification, are permitted provided that the following conditions are 1.8 +// met: 1.9 +// 1.10 +// * Redistributions of source code must retain the above copyright 1.11 +// notice, this list of conditions and the following disclaimer. 1.12 +// * Redistributions in binary form must reproduce the above 1.13 +// copyright notice, this list of conditions and the following disclaimer 1.14 +// in the documentation and/or other materials provided with the 1.15 +// distribution. 1.16 +// * Neither the name of Google Inc. nor the names of its 1.17 +// contributors may be used to endorse or promote products derived from 1.18 +// this software without specific prior written permission. 1.19 +// 1.20 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.21 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.22 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.23 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.24 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.25 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.26 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.27 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.28 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.29 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.30 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.31 + 1.32 +// disassembler_x86.h: Basic x86 bytecode disassembler 1.33 +// 1.34 +// Provides a simple disassembler which wraps libdisasm. This allows simple 1.35 +// tests to be run against bytecode to test for various properties. 1.36 +// 1.37 +// Author: Cris Neckar 1.38 + 1.39 +#ifndef GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ 1.40 +#define GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ 1.41 + 1.42 +#include <stddef.h> 1.43 +#include <sys/types.h> 1.44 + 1.45 +#include "google_breakpad/common/breakpad_types.h" 1.46 + 1.47 +namespace libdis { 1.48 +#include "third_party/libdisasm/libdis.h" 1.49 +} 1.50 + 1.51 +namespace google_breakpad { 1.52 + 1.53 +enum { 1.54 + DISX86_NONE = 0x0, 1.55 + DISX86_BAD_BRANCH_TARGET = 0x1, 1.56 + DISX86_BAD_ARGUMENT_PASSED = 0x2, 1.57 + DISX86_BAD_WRITE = 0x4, 1.58 + DISX86_BAD_BLOCK_WRITE = 0x8, 1.59 + DISX86_BAD_READ = 0x10, 1.60 + DISX86_BAD_BLOCK_READ = 0x20, 1.61 + DISX86_BAD_COMPARISON = 0x40 1.62 +}; 1.63 + 1.64 +class DisassemblerX86 { 1.65 + public: 1.66 + // TODO(cdn): Modify this class to take a MemoryRegion instead of just 1.67 + // a raw buffer. This will make it easier to use this on arbitrary 1.68 + // minidumps without first copying out the code segment. 1.69 + DisassemblerX86(const uint8_t *bytecode, uint32_t, uint32_t); 1.70 + ~DisassemblerX86(); 1.71 + 1.72 + // This walks to the next instruction in the memory region and 1.73 + // sets flags based on the type of instruction and previous state 1.74 + // including any registers marked as bad through setBadRead() 1.75 + // or setBadWrite(). This method can be called in a loop to 1.76 + // disassemble until the end of a region. 1.77 + uint32_t NextInstruction(); 1.78 + 1.79 + // Indicates whether the current disassembled instruction was valid. 1.80 + bool currentInstructionValid() { return instr_valid_; } 1.81 + 1.82 + // Returns the current instruction as defined in libdis.h, 1.83 + // or NULL if the current instruction is not valid. 1.84 + const libdis::x86_insn_t* currentInstruction() { 1.85 + return instr_valid_ ? ¤t_instr_ : NULL; 1.86 + } 1.87 + 1.88 + // Returns the type of the current instruction as defined in libdis.h. 1.89 + libdis::x86_insn_group currentInstructionGroup() { 1.90 + return current_instr_.group; 1.91 + } 1.92 + 1.93 + // Indicates whether a return instruction has been encountered. 1.94 + bool endOfBlock() { return end_of_block_; } 1.95 + 1.96 + // The flags set so far for the disassembly. 1.97 + uint16_t flags() { return flags_; } 1.98 + 1.99 + // This sets an indicator that the register used to determine 1.100 + // src or dest for the current instruction is tainted. These can 1.101 + // be used after examining the current instruction to indicate, 1.102 + // for example that a bad read or write occurred and the pointer 1.103 + // stored in the register is currently invalid. 1.104 + bool setBadRead(); 1.105 + bool setBadWrite(); 1.106 + 1.107 + protected: 1.108 + const uint8_t *bytecode_; 1.109 + uint32_t size_; 1.110 + uint32_t virtual_address_; 1.111 + uint32_t current_byte_offset_; 1.112 + uint32_t current_inst_offset_; 1.113 + 1.114 + bool instr_valid_; 1.115 + libdis::x86_insn_t current_instr_; 1.116 + 1.117 + // TODO(cdn): Maybe also track an expression's index register. 1.118 + // ex: mov eax, [ebx + ecx]; ebx is base, ecx is index. 1.119 + bool register_valid_; 1.120 + libdis::x86_reg_t bad_register_; 1.121 + 1.122 + bool pushed_bad_value_; 1.123 + bool end_of_block_; 1.124 + 1.125 + uint16_t flags_; 1.126 +}; 1.127 + 1.128 +} // namespace google_breakpad 1.129 + 1.130 +#endif // GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_