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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
99.2%1321330.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    :  #include "syzygy/agent/asan/asan_shadow.h"
  15    :  
  16    :  #include "base/logging.h"
  17    :  #include "base/stringprintf.h"
  18    :  
  19    :  namespace agent {
  20    :  namespace asan {
  21    :  
  22    :  uint8 Shadow::shadow_[kShadowSize];
  23    :  
  24  E :  void Shadow::SetUp() {
  25    :    // Poison the shadow memory.
  26  E :    Poison(shadow_, kShadowSize, kAsanMemoryByte);
  27    :    // Poison the first 64k of the memory as they're not addressable.
  28  E :    Poison(0, 0x10000, kInvalidAddress);
  29  E :  }
  30    :  
  31  E :  void Shadow::TearDown() {
  32    :    // Unpoison the shadow memory.
  33  E :    Unpoison(shadow_, kShadowSize);
  34    :    // Unpoison the first 64k of the memory.
  35  E :    Unpoison(0, 0x10000);
  36  E :  }
  37    :  
  38  E :  void Shadow::Reset() {
  39  E :    memset(shadow_, 0, kShadowSize);
  40  E :  }
  41    :  
  42  E :  void Shadow::Poison(const void* addr, size_t size, ShadowMarker shadow_val) {
  43  E :    uintptr_t index = reinterpret_cast<uintptr_t>(addr);
  44  E :    uintptr_t start = index & 0x7;
  45  E :    DCHECK_EQ(0U, (index + size) & 0x7);
  46    :  
  47  E :    index >>= 3;
  48  E :    if (start)
  49  E :      shadow_[index++] = start;
  50    :  
  51  E :    size >>= 3;
  52  E :    DCHECK_GT(arraysize(shadow_), index + size);
  53  E :    memset(shadow_ + index, shadow_val, size);
  54  E :  }
  55    :  
  56  E :  void Shadow::Unpoison(const void* addr, size_t size) {
  57  E :    uintptr_t index = reinterpret_cast<uintptr_t>(addr);
  58  E :    DCHECK_EQ(0U, index & 0x7);
  59    :  
  60  E :    uint8 remainder = size & 0x7;
  61  E :    index >>= 3;
  62  E :    size >>= 3;
  63  E :    DCHECK_GT(arraysize(shadow_), index + size);
  64  E :    memset(shadow_ + index, kHeapAddressableByte, size);
  65    :  
  66  E :    if (remainder != 0)
  67  E :      shadow_[index + size] = remainder;
  68  E :  }
  69    :  
  70  E :  void Shadow::MarkAsFreed(const void* addr, size_t size) {
  71  E :    uintptr_t index = reinterpret_cast<uintptr_t>(addr);
  72  E :    uintptr_t start = index & 0x7;
  73    :  
  74  E :    index >>= 3;
  75  E :    if (start)
  76  i :      shadow_[index++] = kHeapFreedByte;
  77    :  
  78  E :    size_t size_shadow = size >> 3;
  79  E :    DCHECK_GT(arraysize(shadow_), index + size_shadow);
  80  E :    memset(shadow_ + index, kHeapFreedByte, size_shadow);
  81  E :    if ((size & 0x7) != 0)
  82  E :      shadow_[index + size_shadow] = kHeapFreedByte;
  83  E :  }
  84    :  
  85  E :  bool Shadow::IsAccessible(const void* addr) {
  86  E :    uintptr_t index = reinterpret_cast<uintptr_t>(addr);
  87  E :    uintptr_t start = index & 0x7;
  88    :  
  89  E :    index >>= 3;
  90    :  
  91  E :    DCHECK_GT(arraysize(shadow_), index);
  92  E :    uint8 shadow = shadow_[index];
  93  E :    if (shadow == 0)
  94  E :      return true;
  95    :  
  96  E :    if ((shadow & kHeapNonAccessibleByteMask) != 0)
  97  E :      return false;
  98    :  
  99  E :    return start < shadow;
 100  E :  }
 101    :  
 102  E :  Shadow::ShadowMarker Shadow::GetShadowMarkerForAddress(const void* addr) {
 103  E :    uintptr_t index = reinterpret_cast<uintptr_t>(addr);
 104  E :    index >>= 3;
 105    :  
 106  E :    DCHECK_GT(arraysize(shadow_), index);
 107  E :    return static_cast<ShadowMarker>(shadow_[index]);
 108  E :  }
 109    :  
 110    :  void Shadow::CloneShadowRange(const void* src_pointer,
 111    :                                void* dst_pointer,
 112  E :                                size_t size) {
 113  E :    DCHECK_EQ(0U, size & 0x7);
 114    :  
 115  E :    uintptr_t src_index = reinterpret_cast<uintptr_t>(src_pointer);
 116  E :    DCHECK_EQ(0U, src_index & 0x7);
 117  E :    src_index >>= 3;
 118    :  
 119  E :    uintptr_t dst_index = reinterpret_cast<uintptr_t>(dst_pointer);
 120  E :    DCHECK_EQ(0U, dst_index & 0x7);
 121  E :    dst_index >>= 3;
 122    :  
 123  E :    size_t size_shadow = size >> 3;
 124    :  
 125  E :    memcpy(shadow_ + dst_index, shadow_ + src_index, size_shadow);
 126  E :  }
 127    :  
 128    :  void Shadow::AppendShadowByteText(const char *prefix,
 129    :                                    uintptr_t index,
 130    :                                    std::string* output,
 131  E :                                    size_t bug_index) {
 132    :    base::StringAppendF(
 133  E :        output, "%s0x%08x:", prefix, reinterpret_cast<void*>(index << 3));
 134  E :    char separator = ' ';
 135  E :    for (uint32 i = 0; i < 8; i++) {
 136  E :      if (index + i == bug_index)
 137  E :        separator = '[';
 138  E :      uint8 shadow_value = shadow_[index + i];
 139    :      base::StringAppendF(
 140  E :          output, "%c%x%x", separator, shadow_value >> 4, shadow_value & 15);
 141  E :      if (separator == '[')
 142  E :        separator = ']';
 143  E :      else if (separator == ']')
 144  E :        separator = ' ';
 145  E :    }
 146  E :    if (separator == ']')
 147  E :      base::StringAppendF(output, "]");
 148  E :    base::StringAppendF(output, "\n");
 149  E :  }
 150    :  
 151  E :  void Shadow::AppendShadowArrayText(const void* addr, std::string* output) {
 152  E :    uintptr_t index = reinterpret_cast<uintptr_t>(addr);
 153  E :    index >>= 3;
 154  E :    size_t index_start = index;
 155  E :    index_start &= ~0x7;
 156  E :    for (int i = -4; i <= 4; i++) {
 157  E :      const char * const prefix = (i == 0) ? "=>" : "  ";
 158  E :      AppendShadowByteText(prefix, (index_start + i * 8), output, index);
 159  E :    }
 160  E :  }
 161    :  
 162  E :  void Shadow::AppendShadowMemoryText(const void* addr, std::string* output) {
 163  E :    base::StringAppendF(output, "Shadow bytes around the buggy address:\n");
 164  E :    AppendShadowArrayText(addr, output);
 165    :    base::StringAppendF(output,
 166  E :        "Shadow byte legend (one shadow byte represents 8 application bytes):\n");
 167    :    base::StringAppendF(output, "  Addressable:           %x%x\n",
 168  E :        kHeapAddressableByte >> 4, kHeapAddressableByte & 15);
 169    :    base::StringAppendF(output,
 170  E :      "  Partially addressable: 01 02 03 04 05 06 07\n");
 171    :    base::StringAppendF(output, "  Heap left redzone:     %x%x\n",
 172  E :        kHeapLeftRedzone >> 4, kHeapLeftRedzone & 15);
 173    :    base::StringAppendF(output, "  Heap righ redzone:     %x%x\n",
 174  E :        kHeapRightRedzone >> 4, kHeapRightRedzone & 15);
 175    :    base::StringAppendF(output, "  Freed Heap region:     %x%x\n",
 176  E :        kHeapFreedByte >> 4, kHeapFreedByte & 15);
 177  E :  }
 178    :  
 179    :  bool Shadow::GetNullTerminatedArraySize(const void* addr,
 180    :                                          size_t* size,
 181  E :                                          size_t max_size) {
 182  E :    DCHECK(addr != NULL);
 183  E :    DCHECK(size != NULL);
 184    :  
 185  E :    uintptr_t index = reinterpret_cast<uintptr_t>(addr);
 186  E :    const uint8* addr_value = reinterpret_cast<const uint8*>(addr);
 187  E :    index >>= 3;
 188  E :    *size = 0;
 189    :  
 190    :    // Scan the input array 8 bytes at a time until we've found a NULL value or
 191    :    // we've reached the end of an accessible memory block.
 192    :    // TODO(sebmarchand): Look into doing this more efficiently.
 193  E :    while (true) {
 194  E :      uint8 shadow = shadow_[index++];
 195  E :      if ((shadow & kHeapNonAccessibleByteMask) != 0)
 196  E :        return false;
 197    :  
 198  E :      uint8 max_index = shadow ? shadow : 8;
 199  E :      while (max_index-- > 0) {
 200  E :        (*size)++;
 201  E :        if (*size == max_size || *addr_value == 0)
 202  E :          return true;
 203  E :        addr_value++;
 204  E :      }
 205    :  
 206  E :      if (shadow != 0)
 207  E :        return false;
 208  E :    }
 209  E :  }
 210    :  
 211    :  }  // namespace asan
 212    :  }  // namespace agent

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