Coverage for /Syzygy/block_graph/typed_block.h

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

Line-by-line coverage:

   1    :  // Copyright 2012 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    :  // Declares TypedBlock and ConstTypedBlock. These are thin wrappers to
  16    :  // BlockGraph::Block objects which allow the data within a block to be
  17    :  // interpreted as an object of a given type.
  18    :  //
  19    :  // Example use is as follows:
  20    :  //
  21    :  //   BlockGraph::Block* dos_header_block = ...;
  22    :  //   TypedBlock<IMAGE_DOS_HEADER> dos_header;
  23    :  //   DCHECK(dos_header.Init(0, dos_header_block));
  24    :  //
  25    :  //   // Reference the fields of the object as if we had a pointer to the object.
  26    :  //   if (dos_header->e_magic == ...) ...
  27    :  //
  28    :  //   // Dereference pointers in the object using 'Dereference'. This takes care
  29    :  //   // of finding, validating and following references within the block graph.
  30    :  //   TypedBlock<IMAGE_NT_HEADERS> nt_headers;
  31    :  //   DCHECK(dos_header.Dereference(dos_header->e_lfanew, &nt_headers));
  32    :  //
  33    :  // For full details of the API, refer to internal::TypedBlockImpl, defined in
  34    :  // syzygy/block_graph/typed_block_internal.h
  35    :  
  36    :  #ifndef SYZYGY_BLOCK_GRAPH_TYPED_BLOCK_H_
  37    :  #define SYZYGY_BLOCK_GRAPH_TYPED_BLOCK_H_
  38    :  
  39    :  #include "syzygy/block_graph/block_graph.h"
  40    :  
  41    :  namespace block_graph {
  42    :  
  43    :  namespace internal {
  44    :  
  45    :  typedef BlockGraph::Block* BlockPtr;
  46    :  typedef const BlockGraph::Block* ConstBlockPtr;
  47    :  
  48    :  // Forward declare.
  49    :  template <typename T, typename BlockPtr, typename ChildType>
  50    :  class TypedBlockImpl;
  51    :  
  52    :  }  // namespace internal
  53    :  
  54    :  // Used for interpreting a non-const BlockGraph::Block's data as a mutable
  55    :  // object of type T. Augments TypedBlockImpl with routine's for modifying
  56    :  // references.
  57    :  template <typename T> class TypedBlock
  58    :      : public internal::TypedBlockImpl<T,
  59    :                                        internal::BlockPtr,
  60    :                                        TypedBlock<T>> {
  61    :   public:
  62    :    typedef BlockGraph::Block Block;
  63    :    typedef BlockGraph::Offset Offset;
  64    :    typedef BlockGraph::Reference Reference;
  65    :    typedef BlockGraph::ReferenceType ReferenceType;
  66    :    typedef BlockGraph::Size Size;
  67    :    typedef T ObjectType;
  68    :  
  69    :    template <typename T2> struct Rebind {
  70    :      typedef TypedBlock<typename T2> Type;
  71    :    };
  72    :  
  73  E :    TypedBlock() : TypedBlockImpl() { }
  74    :  
  75    :    // Accesses the block encapsulated by this typed block.
  76    :    //
  77    :    // @returns a non-const pointer to the encapsulated block.
  78  E :    internal::BlockPtr block() { return block_; }
  79    :  
  80    :    // Accesses the block encapsulated by this typed block.
  81    :    //
  82    :    // @returns a const pointer to the encapsulated block.
  83  E :    internal::ConstBlockPtr block() const { return block_; }
  84    :  
  85    :    // Removes the reference at the given offset. Will clear a reference of any
  86    :    // size and type.
  87    :    //
  88    :    // @param offset the offset of the reference to clear.
  89  E :    void RemoveReferenceAt(Offset offset) {
  90  E :      RemoveReferenceImpl(offset, 0);
  91  E :    }
  92    :  
  93    :    // Removes the reference at the given offset, but only if it has the given
  94    :    // size. Returns false if there exists a reference at the offset but with a
  95    :    // different size, true otherwise.
  96    :    //
  97    :    // @param offset the offset of the reference to clear.
  98    :    // @param size the size of the reference to clear.
  99    :    // @returns true on success, false otherwise.
 100  E :    bool RemoveReferenceAt(Offset offset, size_t size) {
 101  E :      return RemoveReferenceImpl(offset, size);
 102  E :    }
 103    :  
 104    :    // Removes the reference corresponding to the given value. Succeeds if there
 105    :    // is no reference at the offset, or if the existing reference has the same
 106    :    // size as the value.
 107    :    //
 108    :    // @tparam TIn the type of @p value.
 109    :    // @param value the value in this block encapsulating the reference to erase.
 110    :    template <typename TIn>
 111  E :    bool RemoveReference(const TIn& value) {
 112  E :      return RemoveReferenceImpl(OffsetOf(value), sizeof(TIn));
 113  E :    }
 114    :  
 115    :    // Builds a reference with the given type, offset and size to the given
 116    :    // block and offset.
 117    :    //
 118    :    // @param reference_type the type of reference to create.
 119    :    // @param reference_offset the offset of the reference to construct.
 120    :    // @param reference_size the size of the reference to construct.
 121    :    // @param referenced_block the block to be referenced.
 122    :    // @param referenced_offset the offset into the block to be directly
 123    :    //     referenced.
 124    :    // @param referenced_base the offset into the block of the item that is
 125    :    //     actually being referenced.
 126    :    // @returns true iff this inserts a new reference.
 127    :    bool SetReference(ReferenceType reference_type,
 128    :                      Offset reference_offset,
 129    :                      size_t reference_size,
 130    :                      Block* referenced_block,
 131    :                      Offset referenced_offset,
 132    :                      Offset referenced_base);
 133    :  
 134    :    // Sets a reference from one value to a given block/offset. The size of the
 135    :    // reference will be sizeof(TFrom).
 136    :    //
 137    :    // @tparam TFrom the type of @p value_from.
 138    :    // @param reference_type the type of reference to create.
 139    :    // @param value_from the value which will hold the created reference.
 140    :    // @param block_to the block to be referenced.
 141    :    // @param offset_to the offset of @p block_to to be referenced directly.
 142    :    // @param base_to the offset of @p block_to to be actually referenced.
 143    :    template <typename TFrom>
 144  E :    bool SetReference(ReferenceType reference_type,
 145    :                      const TFrom& value_from,
 146    :                      Block* block_to,
 147    :                      Offset offset_to,
 148    :                      Offset base_to) {
 149  E :      DCHECK(block_to != NULL);
 150    :      return SetReference(reference_type, OffsetOf(value_from), sizeof(TFrom),
 151  E :          block_to, offset_to, base_to);
 152  E :    }
 153    :  
 154    :    // Sets a direct reference (where base = offset) from one value to another
 155    :    // typed block. The size of the reference will be sizeof(TFrom).
 156    :    //
 157    :    // @tparam TFrom the type of @p value_from.
 158    :    // @tparam T2 the type encapsulated by @p typed_block_to.
 159    :    // @param reference_type the type of reference to create.
 160    :    // @param value_from the value which will hold the created reference.
 161    :    // @param typed_block_to the typed block that will be referenced. The
 162    :    //     reference will be constructed to the beginning of the object
 163    :    //     encapsulated by the typed block.
 164    :    // @returns true iff this inserts a new reference.
 165    :    template <typename TFrom, typename T2>
 166  E :    bool SetReference(ReferenceType reference_type,
 167    :                      const TFrom& value_from,
 168    :                      const TypedBlock<T2>& typed_block_to) {
 169    :      return SetReference(reference_type, OffsetOf(value_from), sizeof(TFrom),
 170    :          const_cast<Block*>(typed_block_to.block()), typed_block_to.offset(),
 171  E :                             typed_block_to.offset());
 172  E :    }
 173    :  
 174    :    // Sets a direct reference (where base = offset) from one value to another.
 175    :    // The size of the reference will be sizeof(TFrom). The offset and base are
 176    :    // inferred from the position of @p value_to in @p typed_block_to.
 177    :    //
 178    :    // @tparam TFrom the type of @p value_from.
 179    :    // @tparam T2 the type encapsulated by @p typed_block_to.
 180    :    // @tparam TTo the type of value_to.
 181    :    // @param reference_type the type of reference to create.
 182    :    // @param value_from the value which will hold the created reference.
 183    :    // @param typed_block_to the typed block that will be referenced.
 184    :    // @param value_to the value within @p typed_block_to that will be referenced.
 185    :    // @returns true iff this inserts a new reference.
 186    :    template <typename TFrom, typename T2, typename TTo>
 187  E :    bool SetReference(ReferenceType reference_type,
 188    :                      const TFrom& value_from,
 189    :                      const TypedBlock<T2>& typed_block_to,
 190    :                      const TTo& value_to) {
 191  E :      Offset offset_to = typed_block_to.OffsetOf(value_to);
 192    :      return SetReference(reference_type, OffsetOf(value_from), sizeof(TFrom),
 193  E :          const_cast<Block*>(typed_block_to.block()), offset_to, offset_to);
 194  E :    }
 195    :  
 196    :   private:
 197    :    // Clears the reference at the given @p offset, but only if it has the given
 198    :    // @p size. If @p size = 0, then a reference of any size will be cleared.
 199    :    // Returns true on success, false otherwise.
 200    :    //
 201    :    // @param offset the offset of the reference to erase.
 202    :    // @param size the size of the reference to erase, 0 if it doesn't matter.
 203    :    bool RemoveReferenceImpl(Offset offset, size_t size);
 204    :  
 205    :    DISALLOW_COPY_AND_ASSIGN(TypedBlock);
 206    :  };
 207    :  
 208    :  // Used for interpreting a const BlockGraph::Block's data as a constant object
 209    :  // of type T.
 210    :  template <typename T> class ConstTypedBlock
 211    :      : public internal::TypedBlockImpl<const T,
 212    :                                        internal::ConstBlockPtr,
 213    :                                        ConstTypedBlock<T>> {
 214    :   public:
 215    :    typedef T ObjectType;
 216    :  
 217    :    template <typename T2> struct Rebind {
 218    :      typedef ConstTypedBlock<T2> Type;
 219    :    };
 220    :  
 221  E :    ConstTypedBlock() : TypedBlockImpl() { }
 222    :  
 223    :    // Accesses the block encapsulated by this typed block.
 224    :    //
 225    :    // @returns a const pointer to the encapsulated block.
 226  E :    internal::ConstBlockPtr block() const { return block_; }
 227    :  
 228    :   private:
 229    :    DISALLOW_COPY_AND_ASSIGN(ConstTypedBlock);
 230    :  };
 231    :  
 232    :  template <typename T>
 233    :  bool TypedBlock<T>::SetReference(ReferenceType reference_type,
 234    :                                   Offset reference_offset,
 235    :                                   Size reference_size,
 236    :                                   Block* referenced_block,
 237    :                                   Offset referenced_offset,
 238  E :                                   Offset referenced_base) {
 239  E :    DCHECK(referenced_block != NULL);
 240    :    BlockGraph::Reference reference(reference_type, reference_size,
 241    :                                    referenced_block, referenced_offset,
 242  E :                                    referenced_base);
 243  E :    return block_->SetReference(reference_offset, reference);
 244  E :  }
 245    :  
 246    :  template <typename T>
 247  E :  bool TypedBlock<T>::RemoveReferenceImpl(Offset offset, size_t size) {
 248  E :    if (size != 0) {
 249  E :      Reference reference;
 250  E :      if (block_->GetReference(offset, &reference)) {
 251  E :        if (reference.size() != size)
 252  E :          return false;
 253    :      }
 254    :    }
 255  E :    block_->RemoveReference(offset);
 256  E :    return true;
 257  E :  }
 258    :  
 259    :  }  // namespace block_graph
 260    :  
 261    :  // This brings in the implementation.
 262    :  #include "syzygy/block_graph/typed_block_internal.h"
 263    :  
 264    :  #endif  // SYZYGY_BLOCK_GRAPH_TYPED_BLOCK_H_

Coverage information generated Thu Jan 14 17:40:38 2016.