Coverage for /Syzygy/agent/asan/shadow_impl.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
98.1%53540.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    :  // Contains the implementation details of the templated functions of Asan's
  16    :  // shadow memory. See 'shadow.h' for more information. This file is not
  17    :  // meant to be included directly, but is brought in by shadow.h.
  18    :  #ifndef SYZYGY_AGENT_ASAN_SHADOW_IMPL_H_
  19    :  #define SYZYGY_AGENT_ASAN_SHADOW_IMPL_H_
  20    :  
  21    :  template <typename type>
  22    :  bool Shadow::GetNullTerminatedArraySize(const void* addr,
  23    :                                          size_t max_size,
  24  E :                                          size_t* size) const {
  25  E :    DCHECK_NE(reinterpret_cast<const void*>(NULL), addr);
  26  E :    DCHECK_NE(reinterpret_cast<size_t*>(NULL), size);
  27    :  
  28  E :    uintptr_t index = reinterpret_cast<uintptr_t>(addr);
  29  E :    const type* addr_value = reinterpret_cast<const type*>(addr);
  30  E :    index >>= 3;
  31  E :    *size = 0;
  32    :  
  33  E :    if (index > length_)
  34  i :      return false;
  35    :  
  36    :    // Scan the input array 8 bytes at a time until we've found a NULL value or
  37    :    // we've reached the end of an accessible memory block.
  38    :    // TODO(sebmarchand): Look into doing this more efficiently.
  39  E :    while (true) {
  40  E :      uint8_t shadow = shadow_[index++];
  41  E :      if (ShadowMarkerHelper::IsRedzone(shadow))
  42  E :        return false;
  43    :  
  44  E :      uint8_t max_index = shadow ? shadow : kShadowRatio;
  45  E :      DCHECK_EQ(0U, max_index % sizeof(type));
  46  E :      max_index /= sizeof(type);
  47  E :      while (max_index-- > 0) {
  48  E :        (*size) += sizeof(type);
  49  E :        if (*size == max_size || *addr_value == 0)
  50  E :          return true;
  51  E :        addr_value++;
  52  E :      }
  53    :  
  54  E :      if (shadow != 0)
  55  E :        return false;
  56  E :    }
  57  E :  }
  58    :  
  59    :  namespace internal {
  60    :  
  61    :  template <typename AccessType>
  62  E :  const AccessType* AlignDown(const uint8_t* ptr) {
  63  E :    DCHECK(::common::IsPowerOfTwo(sizeof(AccessType)));
  64  E :    return reinterpret_cast<const AccessType*>(reinterpret_cast<uintptr_t>(ptr) &
  65    :                                               ~(sizeof(AccessType) - 1));
  66  E :  }
  67    :  
  68    :  template <typename AccessType>
  69  E :  const AccessType* AlignUp(const uint8_t* ptr) {
  70  E :    DCHECK(::common::IsPowerOfTwo(sizeof(AccessType)));
  71    :  
  72  E :    return reinterpret_cast<const AccessType*>(
  73    :        reinterpret_cast<uintptr_t>(ptr + sizeof(AccessType) - 1) &
  74    :        ~(sizeof(AccessType) - 1));
  75  E :  }
  76    :  
  77    :  // Returns true iff every byte in the range [@p start, @p end) is zero.
  78    :  // This function reads sizeof(AccessType) bytes at a time from memory at
  79    :  // natural alignment for AccessType. Note this may under- and over-read the
  80    :  // provided buffer by sizeof(AccessType)-1 bytes, but will never cross
  81    :  // sizeof(AccessType) boundary. The implementation is intended to allow the
  82    :  // compiler to inline it to the usage.
  83    :  // @param start the first byte to test.
  84    :  // @param end the byte after the last byte to test.
  85    :  // @returns true iff every byte from @p *start to @p *(end - 1) is zero.
  86    :  // @note this function is templatized to allow easily performance testing
  87    :  //     it with different AccessType parameters.
  88    :  template <typename AccessType>
  89  E :  bool IsZeroBufferImpl(const uint8_t* start_in, const uint8_t* end_in) {
  90  E :    if (start_in == end_in)
  91  E :      return true;
  92    :  
  93    :    // Round the start address downwards, and the end address upwards.
  94  E :    const AccessType* start = AlignDown<AccessType>(start_in);
  95  E :    const AccessType* end = AlignUp<AccessType>(end_in);
  96    :  
  97    :    // Assuming start_in != end_in the alignment should leave us at least one
  98    :    // element to check.
  99  E :    DCHECK_NE(start, end);
 100  E :    AccessType val = *start;
 101    :  
 102    :    // Mask out the bytes read due to starting alignment.
 103  E :    const AccessType kMask = static_cast<AccessType>(-1LL);
 104  E :    val &= kMask << ((start_in - reinterpret_cast<const uint8_t*>(start)) * 8);
 105  E :    ++start;
 106  E :    while (start != end) {
 107  E :      if (val != 0U)
 108  E :        return false;
 109  E :      val = *start++;
 110  E :    }
 111    :  
 112    :    // Mask out the bytes read due to end alignment.
 113  E :    val &= kMask >> ((reinterpret_cast<const uint8_t*>(end) - end_in) * 8);
 114  E :    if (val != 0U)
 115  E :      return false;
 116    :  
 117  E :    return true;
 118  E :  }
 119    :  
 120    :  }  // namespace internal
 121    :  
 122    :  #endif  // SYZYGY_AGENT_ASAN_SHADOW_IMPL_H_

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