Coverage for /Syzygy/core/address.h

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

Line-by-line coverage:

   1    :  // Copyright 2011 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    :  #ifndef SYZYGY_CORE_ADDRESS_H_
  16    :  #define SYZYGY_CORE_ADDRESS_H_
  17    :  
  18    :  #include <iosfwd>
  19    :  #include "base/basictypes.h"
  20    :  #include "base/logging.h"
  21    :  #include "syzygy/core/serialization.h"
  22    :  
  23    :  namespace core {
  24    :  
  25    :  enum AddressType {
  26    :    kRelativeAddressType,
  27    :    kAbsoluteAddressType,
  28    :    kFileOffsetAddressType,
  29    :  };
  30    :  
  31    :  // This class implements an address in a PE image file.
  32    :  // Addresses are of three varieties:
  33    :  // - Relative addresses are relative to the base of the image, and thus do not
  34    :  //   change when the image is relocated. Bulk of the addresses in the PE image
  35    :  //   format itself are of this variety, and that's where relative addresses
  36    :  //   crop up most frequently.
  37    :  // - Absolute addresses are as the name indicates absolute, and those change
  38    :  //   when an image is relocated. Absolute addresses mostly occur in initialized
  39    :  //   data, and for each absolute datum in an image file, there will be a
  40    :  //   relocation entry calling out its location in the image.
  41    :  // - File offset addresses occur only in the debug data directory that I'm
  42    :  //   aware of, where the debug data is referred to both by a relative address
  43    :  //   and (presumably for convenience) by a file offset address.
  44    :  // This class is a lightweight wrapper for an integer, which can be freely
  45    :  // copied. The different address types are deliberately assignment
  46    :  // incompatible, which helps to avoid confusion when handling different
  47    :  // types of addresses in implementation.
  48    :  template <AddressType type> class AddressImpl {
  49    :   public:
  50    :    static const AddressImpl kInvalidAddress;
  51    :  
  52  E :    AddressImpl() : value_(0) {
  53  E :    }
  54  E :    explicit AddressImpl(uint32 value) : value_(value) {
  55  E :    }
  56  E :    AddressImpl(const AddressImpl<type>& other)  // NOLINT
  57    :        : value_(other.value_) {
  58  E :    }
  59    :  
  60  E :    bool operator<(const AddressImpl<type>& other) const {
  61  E :      return value_ < other.value_;
  62  E :    }
  63  E :    bool operator<=(const AddressImpl<type>& other) const {
  64  E :      return value_ <= other.value_;
  65  E :    }
  66  E :    bool operator>(const AddressImpl<type>& other) const {
  67  E :      return value_ > other.value_;
  68  E :    }
  69  E :    bool operator>=(const AddressImpl<type>& other) const {
  70  E :      return value_ >= other.value_;
  71  E :    }
  72    :  
  73  E :    bool operator==(const AddressImpl<type>& other) const {
  74  E :      return value_ == other.value_;
  75  E :    }
  76  E :    bool operator!=(const AddressImpl<type>& other) const {
  77  E :      return value_ != other.value_;
  78  E :    }
  79    :  
  80  E :    void operator=(const AddressImpl<type>& other) {
  81  E :      value_ = other.value_;
  82  E :    }
  83  E :    void operator+=(int32 offset) {
  84  E :      value_ += offset;
  85  E :    }
  86  E :    void operator-=(int32 offset) {
  87  E :      value_ -= offset;
  88  E :    }
  89    :  
  90  E :    AddressImpl<type> operator+(size_t offset) const {
  91  E :      return AddressImpl<type>(value() + offset);
  92  E :    }
  93    :  
  94  E :    AddressImpl<type> operator-(size_t offset) const {
  95  E :      return AddressImpl<type>(value() - offset);
  96  E :    }
  97    :  
  98  E :    int32 operator-(const AddressImpl<type>& other) const {
  99  E :      return value_ - other.value_;
 100  E :    }
 101    :  
 102  E :    uint32 value() const { return value_; }
 103  E :    void set_value(uint32 value) {
 104  E :      value_ = value;
 105  E :    }
 106    :  
 107  E :    AddressImpl<type> AlignUp(size_t alignment) const {
 108  E :      DCHECK_NE(0U, alignment);
 109    :      // Round up to nearest multiple of alignment.
 110  E :      uint32 value = ((value_ + alignment - 1) / alignment) * alignment;
 111  E :      return AddressImpl<type>(value);
 112  E :    }
 113    :  
 114  E :    bool IsAligned(size_t alignment) const {
 115  E :      DCHECK_NE(0U, alignment);
 116  E :      return (value_ % alignment) == 0;
 117  E :    }
 118    :  
 119    :    // Determines the address alignment by counting the trailing zeros. If the
 120    :    // value of the address is 0 then we return the maximum alignment for a 32-bit
 121    :    // address (0x80000000).
 122  E :    uint32 GetAlignment() const {
 123  E :      uint32 value_copy = value_;
 124  E :      uint8 trailing_zeros = 0;
 125    :  
 126    :      // Sets the trailing zeros to one and set the other bits to zero.
 127    :      // This is inspired from the code on this page:
 128    :      // http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear
 129  E :      value_copy = (value_copy ^ (value_copy - 1)) >> 1;
 130    :  
 131  E :      for (; value_copy > 0; trailing_zeros++)
 132  E :        value_copy >>= 1;
 133    :  
 134  E :      return (1 << trailing_zeros);
 135  E :    }
 136    :  
 137    :    // For serialization.
 138  E :    bool Save(OutArchive *out_archive) const {
 139  E :      return out_archive->Save(value_);
 140  E :    }
 141  E :    bool Load(InArchive *in_archive) {
 142  E :      return in_archive->Load(&value_);
 143  E :    }
 144    :  
 145    :   private:
 146    :    uint32 value_;
 147    :  };
 148    :  
 149    :  // These types represent the different addressing formats used in PE images.
 150    :  
 151    :  // A virtual address relative to the image base, often termed
 152    :  // RVA in documentation and in data structure comments.
 153    :  typedef AddressImpl<kRelativeAddressType> RelativeAddress;
 154    :  // An absolute address.
 155    :  typedef AddressImpl<kAbsoluteAddressType> AbsoluteAddress;
 156    :  // A file offset within an image file.
 157    :  typedef AddressImpl<kFileOffsetAddressType> FileOffsetAddress;
 158    :  
 159    :  std::ostream& operator<<(std::ostream& str, RelativeAddress addr);
 160    :  std::ostream& operator<<(std::ostream& str, AbsoluteAddress addr);
 161    :  std::ostream& operator<<(std::ostream& str, FileOffsetAddress addr);
 162    :  
 163    :  }  // namespace core
 164    :  
 165    :  #endif  // SYZYGY_CORE_ADDRESS_H_

Coverage information generated Wed Dec 11 11:34:16 2013.