Coverage for /Syzygy/agent/asan/memory_interceptors.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
96.7%29300.C++source

Line-by-line coverage:

   1    :  // Copyright 2014 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    :  #include "syzygy/agent/asan/memory_interceptors.h"
  15    :  
  16    :  #include "base/logging.h"
  17    :  #include "syzygy/agent/asan/asan_rtl_utils.h"
  18    :  #include "syzygy/agent/asan/shadow.h"
  19    :  
  20    :  using agent::asan::Shadow;
  21    :  
  22    :  namespace agent {
  23    :  namespace asan {
  24    :  
  25    :  // Check if the memory location is accessible and report an error on bad memory
  26    :  // accesses.
  27    :  // @param location The memory address of the access.
  28    :  // @param access_mode The mode of the access.
  29    :  // @param access_size The size of the access.
  30    :  // @param context The registers context of the access.
  31    :  void CheckMemoryAccess(void* location,
  32    :                         AccessMode access_mode,
  33    :                         size_t access_size,
  34  E :                         const AsanContext& context) {
  35  E :    if (!Shadow::IsAccessible(location))
  36  E :      ReportBadMemoryAccess(location, access_mode, access_size, context);
  37  E :  }
  38    :  
  39    :  // Check if the memory accesses done by a string instructions are valid.
  40    :  // @param dst The destination memory address of the access.
  41    :  // @param dst_access_mode The destination mode of the access.
  42    :  // @param src The source memory address of the access.
  43    :  // @param src_access_mode The source mode of the access.
  44    :  // @param length The number of memory accesses.
  45    :  // @param access_size The size of each the access in byte.
  46    :  // @param increment The increment to move dst/src after each access.
  47    :  // @param compare Flag to activate shortcut of the execution on difference.
  48    :  // @param context The registers context of the access.
  49    :  void CheckStringsMemoryAccesses(
  50    :      uint8* dst, AccessMode dst_access_mode,
  51    :      uint8* src, AccessMode src_access_mode,
  52    :      uint32 length, size_t access_size, int32 increment, bool compare,
  53  E :      const AsanContext& context) {
  54  E :    int32 offset = 0;
  55    :  
  56  E :    for (uint32 i = 0; i < length; ++i) {
  57    :      // Check next memory location at src[offset].
  58  E :      if (src_access_mode != agent::asan::ASAN_UNKNOWN_ACCESS)
  59  E :        CheckMemoryAccess(&src[offset], src_access_mode, access_size, context);
  60    :  
  61    :      // Check next memory location at dst[offset].
  62  E :      if (dst_access_mode != agent::asan::ASAN_UNKNOWN_ACCESS)
  63  E :        CheckMemoryAccess(&dst[offset], dst_access_mode, access_size, context);
  64    :  
  65    :      // For CMPS instructions, we shortcut the execution of prefix REPZ when
  66    :      // memory contents differ.
  67  E :      if (compare) {
  68  E :        uint32 src_content = 0;
  69  E :        uint32 dst_content = 0;
  70  E :        switch (access_size) {
  71    :        case 4:
  72  E :          src_content = *reinterpret_cast<uint32*>(&src[offset]);
  73  E :          dst_content = *reinterpret_cast<uint32*>(&dst[offset]);
  74  E :          break;
  75    :        case 2:
  76  E :          src_content = *reinterpret_cast<uint16*>(&src[offset]);
  77  E :          dst_content = *reinterpret_cast<uint16*>(&dst[offset]);
  78  E :          break;
  79    :        case 1:
  80  E :          src_content = *reinterpret_cast<uint8*>(&src[offset]);
  81  E :          dst_content = *reinterpret_cast<uint8*>(&dst[offset]);
  82  E :          break;
  83    :        default:
  84  i :          NOTREACHED() << "Unexpected access_size.";
  85    :          break;
  86    :        }
  87    :  
  88  E :        if (src_content != dst_content)
  89  E :          return;
  90    :      }
  91    :  
  92    :      // Increments offset of dst/src to the next memory location.
  93  E :      offset += increment;
  94  E :    }
  95  E :  }
  96    :  
  97    :  }  // namespace asan
  98    :  }  // namespace agent
  99    :  
 100    :  // Redefine some enums to make them accessible in the inlined assembly.
 101    :  // @{
 102    :  enum AccessMode {
 103    :    AsanReadAccess = agent::asan::ASAN_READ_ACCESS,
 104    :    AsanWriteAccess = agent::asan::ASAN_WRITE_ACCESS,
 105    :    AsanUnknownAccess = agent::asan::ASAN_UNKNOWN_ACCESS,
 106    :  };
 107    :  // @}
 108    :  
 109    :  // The slow path relies on the fact that the shadow memory non accessible byte
 110    :  // mask has its upper bit set to 1.
 111    :  COMPILE_ASSERT((agent::asan::kHeapNonAccessibleMarkerMask & (1 << 7)) != 0,
 112    :                 asan_shadow_mask_upper_bit_is_0);
 113    :  
 114    :  // Pull in the actual implementation of the accessor stubs.
 115    :  #include "syzygy/agent/asan/memory_interceptors_gen.cc"

Coverage information generated Thu Mar 26 16:15:41 2015.