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  E :    AddressImpl() : value_(0) {
  51  E :    }
  52  E :    explicit AddressImpl(uint32 value) : value_(value) {
  53  E :    }
  54  E :    AddressImpl(const AddressImpl<type>& other)  // NOLINT
  55    :        : value_(other.value_) {
  56  E :    }
  57    :  
  58  E :    bool operator<(const AddressImpl<type>& other) const {
  59  E :      return value_ < other.value_;
  60  E :    }
  61  E :    bool operator<=(const AddressImpl<type>& other) const {
  62  E :      return value_ <= other.value_;
  63  E :    }
  64  E :    bool operator>(const AddressImpl<type>& other) const {
  65  E :      return value_ > other.value_;
  66  E :    }
  67  E :    bool operator>=(const AddressImpl<type>& other) const {
  68  E :      return value_ >= other.value_;
  69  E :    }
  70    :  
  71  E :    bool operator==(const AddressImpl<type>& other) const {
  72  E :      return value_ == other.value_;
  73  E :    }
  74  E :    bool operator!=(const AddressImpl<type>& other) const {
  75  E :      return value_ != other.value_;
  76  E :    }
  77    :  
  78  E :    void operator=(const AddressImpl<type>& other) {
  79  E :      value_ = other.value_;
  80  E :    }
  81  E :    void operator+=(int32 offset) {
  82  E :      value_ += offset;
  83  E :    }
  84  E :    void operator-=(int32 offset) {
  85  E :      value_ -= offset;
  86  E :    }
  87    :  
  88  E :    AddressImpl<type> operator+(size_t offset) const {
  89  E :      return AddressImpl<type>(value() + offset);
  90  E :    }
  91    :  
  92  E :    AddressImpl<type> operator-(size_t offset) const {
  93  E :      return AddressImpl<type>(value() - offset);
  94  E :    }
  95    :  
  96  E :    int32 operator-(const AddressImpl<type>& other) const {
  97  E :      return value_ - other.value_;
  98  E :    }
  99    :  
 100  E :    uint32 value() const { return value_; }
 101  E :    void set_value(uint32 value) {
 102  E :      value_ = value;
 103  E :    }
 104    :  
 105  E :    AddressImpl<type> AlignUp(size_t alignment) const {
 106  E :      DCHECK(alignment > 0);
 107    :      // Round up to nearest multiple of alignment.
 108  E :      uint32 value = ((value_ + alignment - 1) / alignment) * alignment;
 109  E :      return AddressImpl<type>(value);
 110  E :    }
 111    :  
 112  E :    bool IsAligned(size_t alignment) const {
 113  E :      DCHECK(alignment > 0);
 114  E :      return (value_ % alignment) == 0;
 115  E :    }
 116    :  
 117    :    // Determines the address alignment by counting the trailing zeros. If the
 118    :    // value of the address is 0 then we return the maximum alignment for a 32-bit
 119    :    // address (0x80000000).
 120  E :    uint32 GetAlignment() const {
 121  E :      uint32 value_copy = value_;
 122  E :      uint8 trailing_zeros = 0;
 123    :  
 124    :      // Sets the trailing zeros to one and set the other bits to zero.
 125    :      // This is inspired from the code on this page:
 126    :      // http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear
 127  E :      value_copy = (value_copy ^ (value_copy - 1)) >> 1;
 128    :  
 129  E :      for (; value_copy > 0; trailing_zeros++)
 130  E :        value_copy >>= 1;
 131    :  
 132  E :      return (1 << trailing_zeros);
 133  E :    }
 134    :  
 135    :    // For serialization.
 136  E :    bool Save(OutArchive *out_archive) const {
 137  E :      return out_archive->Save(value_);
 138  E :    }
 139  E :    bool Load(InArchive *in_archive) {
 140  E :      return in_archive->Load(&value_);
 141  E :    }
 142    :  
 143    :   private:
 144    :    uint32 value_;
 145    :  };
 146    :  
 147    :  // These types represent the different addressing formats used in PE images.
 148    :  
 149    :  // A virtual address relative to the image base, often termed
 150    :  // RVA in documentation and in data structure comments.
 151    :  typedef AddressImpl<kRelativeAddressType> RelativeAddress;
 152    :  // An absolute address.
 153    :  typedef AddressImpl<kAbsoluteAddressType> AbsoluteAddress;
 154    :  // A file offset within an image file.
 155    :  typedef AddressImpl<kFileOffsetAddressType> FileOffsetAddress;
 156    :  
 157    :  std::ostream& operator<<(std::ostream& str, RelativeAddress addr);
 158    :  std::ostream& operator<<(std::ostream& str, AbsoluteAddress addr);
 159    :  std::ostream& operator<<(std::ostream& str, FileOffsetAddress addr);
 160    :  
 161    :  }  // namespace core
 162    :  
 163    :  #endif  // SYZYGY_CORE_ADDRESS_H_

Coverage information generated Tue Jun 25 13:56:24 2013.