Coverage for /Syzygy/assm/register_internal.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%18180.C++source

Line-by-line coverage:

   1    :  // Copyright 2013 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // This file declares the internal implementation details for classes that are
  16    :  // used to represent general purpose X86 registers. They are intended to be used
  17    :  // with the X86 assembly utilities declared in assembler.h, and are of no real
  18    :  // use on their own.
  19    :  //
  20    :  // The design of the register class has been crafted to allow easy extension
  21    :  // for X86-64 registers if the time comes.
  22    :  //
  23    :  // For converting between Syzygy registers and Distorm RegisterType refer to the
  24    :  // utilities in disassembler_util.
  25    :  
  26    :  #ifndef SYZYGY_ASSM_REGISTER_INTERNAL_H_
  27    :  #define SYZYGY_ASSM_REGISTER_INTERNAL_H_
  28    :  
  29    :  #include "base/logging.h"
  30    :  
  31    :  namespace assm {
  32    :  
  33    :  // An enum of known registers. The enums guarantee unique values for each
  34    :  // register at each precision. These are not intended to be used directly, but
  35    :  // can be used for iterating over known registers in static analysis, for
  36    :  // example.
  37    :  //
  38    :  // This enum has been constructed such that the lower 3-bits represents the
  39    :  // code associated with the register, which is used in ModR/M and SIB bytes.
  40    :  enum RegisterId {
  41    :    kRegisterNone = -1,
  42    :  
  43    :    // 8-bit registers.
  44    :    kRegisterAl = 0,
  45    :    kRegisterCl = 1,
  46    :    kRegisterDl = 2,
  47    :    kRegisterBl = 3,
  48    :    kRegisterAh = 4,
  49    :    kRegisterCh = 5,
  50    :    kRegisterDh = 6,
  51    :    kRegisterBh = 7,
  52    :  
  53    :    // 16-bit registers.
  54    :    kRegisterAx = 8,
  55    :    kRegisterCx = 9,
  56    :    kRegisterDx = 10,
  57    :    kRegisterBx = 11,
  58    :    kRegisterSp = 12,
  59    :    kRegisterBp = 13,
  60    :    kRegisterSi = 14,
  61    :    kRegisterDi = 15,
  62    :  
  63    :    // 32-bit registers.
  64    :    kRegisterEax = 16,
  65    :    kRegisterEcx = 17,
  66    :    kRegisterEdx = 18,
  67    :    kRegisterEbx = 19,
  68    :    kRegisterEsp = 20,
  69    :    kRegisterEbp = 21,
  70    :    kRegisterEsi = 22,
  71    :    kRegisterEdi = 23,
  72    :  
  73    :    // Ranges for various register types. These come at the end so that
  74    :    // preferentially the debugger will show proper register IDs for overloaded
  75    :    // enum values.
  76    :    kRegisterMin = 0,
  77    :    kRegister8Min = 0,
  78    :    kRegister8Max = 8,
  79    :    kRegister16Min = 8,
  80    :    kRegister16Max = 16,
  81    :    kRegister32Min = 16,
  82    :    kRegister32Max = 24,
  83    :    kRegisterMax = 24
  84    :  };
  85    :  
  86    :  // We use another enum for register code simply for type safety. This makes it
  87    :  // so that we can't accidentally use a RegisterId or a uint8_t as a
  88    :  // RegisterCode.
  89    :  enum RegisterCode {
  90    :    kRegisterCode000 = 0,
  91    :    kRegisterCode001 = 1,
  92    :    kRegisterCode010 = 2,
  93    :    kRegisterCode011 = 3,
  94    :    kRegisterCode100 = 4,
  95    :    kRegisterCode101 = 5,
  96    :    kRegisterCode110 = 6,
  97    :    kRegisterCode111 = 7
  98    :  };
  99    :  
 100    :  // Register sizes. The values double as the actual number of bits.
 101    :  enum RegisterSize {
 102    :    kSizeNone = 0,
 103    :    kSize8Bit = 8,
 104    :    kSize16Bit = 16,
 105    :    kSize32Bit = 32,
 106    :  };
 107    :  
 108    :  // The base class of all registers.
 109    :  class Register {
 110    :   public:
 111    :    // @returns the unique ID of this register.
 112  E :    RegisterId id() const { return id_; }
 113    :  
 114    :    // @returns the size of this register.
 115  E :    RegisterSize size() const { return size_; }
 116    :  
 117    :    // @returns the code associated with this register.
 118    :    // @note This is not unique, with multiple registers of different precisions
 119    :    //     having the same code.
 120  E :    RegisterCode code() const { return Code(id_); }
 121    :  
 122    :    // Utility function for getting the code associated with the given register
 123    :    // ID.
 124  E :    static const RegisterCode Code(RegisterId id) {
 125  E :      return RegisterCode(id & 0x7);
 126  E :    }
 127    :  
 128    :    // Utility function for getting the register with the given ID.
 129    :    static const Register& Get(RegisterId id);
 130    :  
 131    :    // @name Comparison operators.
 132    :    // @{
 133  E :    bool operator==(const Register& reg) const {
 134  E :      return id_ == reg.id_ && size_ == reg.size_;
 135  E :    }
 136  E :    bool operator!=(const Register& reg) const {
 137  E :      return !operator==(reg);
 138  E :    }
 139    :    // @}
 140    :  
 141    :   protected:
 142  E :    Register(RegisterId id, RegisterSize size) : id_(id), size_(size) {
 143  E :      DCHECK_NE(kRegisterNone, id);
 144  E :      DCHECK_NE(kSizeNone, size);
 145  E :    }
 146    :  
 147    :   private:
 148    :    RegisterId id_;
 149    :    RegisterSize size_;
 150    :  };
 151    :  
 152    :  // A templated implementation class for register objects. This is parameterized
 153    :  // based on the register sizes so that registers of different sizes have
 154    :  // different types.
 155    :  // @tparam register_size The size of the register, in bits.
 156    :  template<RegisterSize register_size>
 157    :  class RegisterImpl : public Register {
 158    :   protected:
 159    :    // This class acts as registry factory in the .cc file.
 160    :    friend class RegisterBuilder;
 161    :  
 162    :    // Constructor. This is protected so that clients don't try to manually
 163    :    // construct register objects, but instead use the provided static register
 164    :    // objects.
 165  E :    explicit RegisterImpl(RegisterId id) : Register(id, register_size) {
 166  E :    }
 167    :  };
 168    :  
 169    :  // We declare different types for registers so that assembler functions can be
 170    :  // type checked. Functions that can seamlessly handle registers of various sizes
 171    :  // can simply accept object of type Register, and query them directly for size
 172    :  // information.
 173    :  typedef RegisterImpl<kSize8Bit> Register8;
 174    :  typedef RegisterImpl<kSize16Bit> Register16;
 175    :  typedef RegisterImpl<kSize32Bit> Register32;
 176    :  
 177    :  }  // namespace assm
 178    :  
 179    :  #endif  // SYZYGY_ASSM_REGISTER_INTERNAL_H_

Coverage information generated Fri Jul 29 11:00:21 2016.