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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%660.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    :  //
  15    :  // Declares the ShadowMarker enumeration, and a utility class for querying the
  16    :  // component parts of a shadow byte.
  17    :  
  18    :  #ifndef SYZYGY_AGENT_ASAN_SHADOW_MARKER_H_
  19    :  #define SYZYGY_AGENT_ASAN_SHADOW_MARKER_H_
  20    :  
  21    :  #include "base/basictypes.h"
  22    :  
  23    :  namespace agent {
  24    :  namespace asan {
  25    :  
  26    :  // Defines the various distinct values that are used to mark shadow memory. At
  27    :  // the highest level this is split into 2 classes: accessible memory (leading
  28    :  // bit is 0), and inaccessible, or redzoned, memory (leading bit is 1). The
  29    :  // fast path Asan error checking code relies on the fact that the leading bit
  30    :  // is 1 for redzoned memory.
  31    :  //
  32    :  // The redzoned memory is broken into various distinct types. A lot of the
  33    :  // codespace of this enum is dedicated to describing blocks, with sufficient
  34    :  // detail to reconstruct the layout of the block from an inspection of shadow
  35    :  // memory alone.
  36    :  //
  37    :  // All block markers have 'historic' variants which are used for marking old
  38    :  // blocks that have since fallen out of the quarantine. This serves as a
  39    :  // persistent record of the block that *used* to be located at a specific spot
  40    :  // in memory, at least until the owning heap reuses the memory.
  41    :  //
  42    :  // Since the code space is quite convoluted (it has strictly been added to, and
  43    :  // was initially a clone of Asan's far simpler marker types) a helper class
  44    :  // (ShadowMarkerHelper) has been defined for making queries about marker
  45    :  // properties.
  46    :  //
  47    :  // NOTE: If this grows any more complex then it would be relatively simple to
  48    :  //     define a 32-bit 'ShadowMarkerProperties' struct, and simply map each
  49    :  //     marker type to its properties. The properties could then be trivially
  50    :  //     inspected via masks.
  51    :  #define SHADOW_MARKER_GENERATOR(F)  \
  52    :      /* ADDRESSABLE BYTES. */  \
  53    :      /* This is either a range of bytes that we know nothing about, or is */  \
  54    :      /* an allocated byte that is explicitly accessible. */  \
  55    :      F(kHeapAddressableMarker, 0x00)  \
  56    :      /* Values 0x01 through 0x07 indicate that a range of bytes is */  \
  57    :      /* partially accessible, and partially inaccessible. */  \
  58    :      F(kHeapPartiallyAddressableByte1, 0x01)  \
  59    :      F(kHeapPartiallyAddressableByte2, 0x02)  \
  60    :      F(kHeapPartiallyAddressableByte3, 0x03)  \
  61    :      F(kHeapPartiallyAddressableByte4, 0x04)  \
  62    :      F(kHeapPartiallyAddressableByte5, 0x05)  \
  63    :      F(kHeapPartiallyAddressableByte6, 0x06)  \
  64    :      F(kHeapPartiallyAddressableByte7, 0x07)  \
  65    :      /* NON-ADDRESSABLE BYTES. */  \
  66    :      /* These are 'historic' block start bytes. They are equivalent to */  \
  67    :      /* other block markers, but mark blocks that have since fallen out of */  \
  68    :      /* the quarantine. They are kept around to provide extra data, but */  \
  69    :      /* through memory reuse may end up being incomplete. The values are */  \
  70    :      /* the same as 'active' block markers, but with the 'active' bit */  \
  71    :      /* (0x20) disabled. Thus any marker starting with 0xc0 is a historic */  \
  72    :      /* block start marker. */  \
  73    :      F(kHeapHistoricBlockStartMarker0, 0xC0)  \
  74    :      F(kHeapHistoricBlockStartMarker1, 0xC1)  \
  75    :      F(kHeapHistoricBlockStartMarker2, 0xC2)  \
  76    :      F(kHeapHistoricBlockStartMarker3, 0xC3)  \
  77    :      F(kHeapHistoricBlockStartMarker4, 0xC4)  \
  78    :      F(kHeapHistoricBlockStartMarker5, 0xC5)  \
  79    :      F(kHeapHistoricBlockStartMarker6, 0xC6)  \
  80    :      F(kHeapHistoricBlockStartMarker7, 0xC7)  \
  81    :      /* Nested block start bytes have the bit 0x80 set. */  \
  82    :      F(kHeapHistoricNestedBlockStartMarker0, 0xC8)  \
  83    :      F(kHeapHistoricNestedBlockStartMarker1, 0xC9)  \
  84    :      F(kHeapHistoricNestedBlockStartMarker2, 0xCA)  \
  85    :      F(kHeapHistoricNestedBlockStartMarker3, 0xCB)  \
  86    :      F(kHeapHistoricNestedBlockStartMarker4, 0xCC)  \
  87    :      F(kHeapHistoricNestedBlockStartMarker5, 0xCD)  \
  88    :      F(kHeapHistoricNestedBlockStartMarker6, 0xCE)  \
  89    :      F(kHeapHistoricNestedBlockStartMarker7, 0xCF)  \
  90    :      /* These are 'historic' markers associated with block left/right */  \
  91    :      /* redzones and freed data. They consist of the same values as the */  \
  92    :      /* active markers, minus the active block bit. */  \
  93    :      F(kHeapHistoricBlockEndMarker, 0xD4)  \
  94    :      F(kHeapHistoricNestedBlockEndMarker, 0xD5)  \
  95    :      F(kHeapHistoricLeftPaddingMarker, 0xDA)  \
  96    :      F(kHeapHistoricRightPaddingMarker, 0xDB)  \
  97    :      F(kHeapHistoricFreedMarker, 0xDD)  \
  98    :      /* Any marker starting with 0xe0 marks the beginning of a block. The */  \
  99    :      /* trailing 4 bits of the marker are used to encode additional */  \
 100    :      /* metadata about the block itself. This is necessary to allow */  \
 101    :      /* full introspection of blocks via the shadow. All 'active' block */  \
 102    :      /* start bytes have the bit 0x20 set. */  \
 103    :      F(kHeapBlockStartMarker0, 0xE0)  \
 104    :      F(kHeapBlockStartMarker1, 0xE1)  \
 105    :      F(kHeapBlockStartMarker2, 0xE2)  \
 106    :      F(kHeapBlockStartMarker3, 0xE3)  \
 107    :      F(kHeapBlockStartMarker4, 0xE4)  \
 108    :      F(kHeapBlockStartMarker5, 0xE5)  \
 109    :      F(kHeapBlockStartMarker6, 0xE6)  \
 110    :      F(kHeapBlockStartMarker7, 0xE7)  \
 111    :      /* Nested block start bytes have the bit 0x80 set. */  \
 112    :      F(kHeapNestedBlockStartMarker0, 0xE8)  \
 113    :      F(kHeapNestedBlockStartMarker1, 0xE9)  \
 114    :      F(kHeapNestedBlockStartMarker2, 0xEA)  \
 115    :      F(kHeapNestedBlockStartMarker3, 0xEB)  \
 116    :      F(kHeapNestedBlockStartMarker4, 0xEC)  \
 117    :      F(kHeapNestedBlockStartMarker5, 0xED)  \
 118    :      F(kHeapNestedBlockStartMarker6, 0xEE)  \
 119    :      F(kHeapNestedBlockStartMarker7, 0xEF)  \
 120    :      /* The data in this block maps to internal memory structures. */  \
 121    :      F(kAsanMemoryMarker, 0xF1)  \
 122    :      /* The address covered by this byte are simply invalid and unable to */  \
 123    :      /* be accessed by user code. */  \
 124    :      F(kInvalidAddressMarker, 0xF2)  \
 125    :      /* The bytes are part of a block that has been allocated by the */  \
 126    :      /* instrumented code, but subsequently redzoned via the runtime API. */  \
 127    :      F(kUserRedzoneMarker, 0xF3)  \
 128    :      /* This marker marks the end of a block in memory, and is part of a */  \
 129    :      /* right redzone. */  \
 130    :      F(kHeapBlockEndMarker, 0xF4)  \
 131    :      F(kHeapNestedBlockEndMarker, 0xF5)  \
 132    :      /* The bytes are part of a left redzone (block header padding). */  \
 133    :      /* This is the same value as used by Asan itself. */  \
 134    :      F(kHeapLeftPaddingMarker, 0xFA)  \
 135    :      /* The bytes are part of a right redzone (block trailer and padding). */  \
 136    :      /* This is the same value as used by Asan itself. */  \
 137    :      F(kHeapRightPaddingMarker, 0xFB)  \
 138    :      /* These bytes are part of memory that is destined to be used by the */  \
 139    :      /* heap, has been reserved from the OS, but not yet handed out to */  \
 140    :      /* the code under test. */  \
 141    :      F(kAsanReservedMarker, 0xFC)  \
 142    :      /* The bytes are part of the body of a block that has been allocated */  \
 143    :      /* and subsequently freed by instrumented code. */  \
 144    :      /* This is the same value as used by Asan itself. */  \
 145    :      F(kHeapFreedMarker, 0xFD)
 146    :  
 147    :  // Any non-accessible marker will have these bits set.
 148    :  static const uint8 kHeapNonAccessibleMarkerMask = 0x80;
 149    :  
 150    :  // Generate the enum using the generator. This keeps it such that we only need
 151    :  // to maintain a single list.
 152    :  #define SHADOW_MARKER_ENUM_FUNCTION(x, y)  x = y,
 153    :  enum ShadowMarker {
 154    :    SHADOW_MARKER_GENERATOR(SHADOW_MARKER_ENUM_FUNCTION)
 155    :  };
 156    :  #undef SHADOW_MARKER_ENUM_FUNCTION
 157    :  
 158    :  // Maps from a shadow marker ID to its name. Invalid enumeration values are
 159    :  // mapped to a NULL string.
 160    :  extern const char* kShadowMarkerNames[256];
 161    :  
 162    :  // A convenience class that automatically accepts either a uint8 or a
 163    :  // ShadowMarker enum.
 164    :  struct ShadowMarkerValue {
 165    :    // These are deliberately left as implicit typecasts.
 166  E :    ShadowMarkerValue(ShadowMarker marker) : value(marker) {  // NOLINT
 167  E :    }
 168  E :    ShadowMarkerValue(uint8 marker)  // NOLINT
 169    :        : value(static_cast<ShadowMarker>(marker)) {
 170  E :    }
 171  E :    ShadowMarkerValue(const ShadowMarkerValue& rhs)  // NOLINT
 172    :        : value(rhs.value) {
 173  E :    }
 174    :    ShadowMarker value;
 175    :  };
 176    :  
 177    :  // A simple helper for querying and building ShadowMarker values.
 178    :  struct ShadowMarkerHelper {
 179    :    // @name For querying shadow markers.
 180    :    // @{
 181    :  
 182    :    // @param marker The shadow marker to query.
 183    :    // @returns true if the marker is a redzone (inaccessible) marker, false
 184    :    //     otherwise.
 185    :    static bool IsRedzone(ShadowMarkerValue marker);
 186    :  
 187    :    // @param marker The shadow marker to query.
 188    :    // @returns true if the marker describes an active block.
 189    :    static bool IsActiveBlock(ShadowMarkerValue marker);
 190    :  
 191    :    // @param marker The shadow marker to query.
 192    :    // @returns true if the marker describes a historic block.
 193    :    static bool IsHistoricBlock(ShadowMarkerValue marker);
 194    :  
 195    :    // @param marker The shadow marker to query.
 196    :    // @returns true if the marker describes memory pertaining to a block,
 197    :    //     historic or otherwise.
 198    :    static bool IsBlock(ShadowMarkerValue marker);
 199    :  
 200    :    // @param marker The shadow marker to query.
 201    :    // @returns true if the marker describes an active block start marker.
 202    :    static bool IsActiveBlockStart(ShadowMarkerValue marker);
 203    :  
 204    :    // @param marker The shadow marker to query.
 205    :    // @returns true if the marker describes a historic block start marker.
 206    :    static bool IsHistoricBlockStart(ShadowMarkerValue marker);
 207    :  
 208    :    // @param marker The shadow marker to query.
 209    :    // @returns true if the marker describes a block header marker, historic or
 210    :    //     active.
 211    :    static bool IsBlockStart(ShadowMarkerValue marker);
 212    :  
 213    :    // @param marker The shadow marker to query.
 214    :    // @returns true if the markers describes a nested block start marker,
 215    :    //     historic or active.
 216    :    static bool IsNestedBlockStart(ShadowMarkerValue marker);
 217    :  
 218    :    // @param marker The shadow marker to query.
 219    :    // @returns the extra data encoded in a block start marker.
 220    :    // @note This should only be called for block start markers.
 221    :    static uint8 GetBlockStartData(ShadowMarkerValue marker);
 222    :  
 223    :    // @param marker The shadow marker to query.
 224    :    // @returns true if the marker describes an active block start marker.
 225    :    static bool IsActiveBlockEnd(ShadowMarkerValue marker);
 226    :  
 227    :    // @param marker The shadow marker to query.
 228    :    // @returns true if the marker describes a historic block start marker.
 229    :    static bool IsHistoricBlockEnd(ShadowMarkerValue marker);
 230    :  
 231    :    // @param marker The shadow marker to query.
 232    :    // @returns true if the marker describes a block header marker, historic or
 233    :    //     active.
 234    :    static bool IsBlockEnd(ShadowMarkerValue marker);
 235    :  
 236    :    // @param marker The shadow marker to query.
 237    :    // @returns true if the markers describes a nested block end marker,
 238    :    //     historic or active.
 239    :    static bool IsNestedBlockEnd(ShadowMarkerValue marker);
 240    :  
 241    :    // @param marker The shadow marker to query.
 242    :    // @returns true if the marker describes a historic left redzone.
 243    :    //     Note that block start markers are part of a left redzone.
 244    :    static bool IsHistoricLeftRedzone(ShadowMarkerValue marker);
 245    :  
 246    :    // @param marker The shadow marker to query.
 247    :    // @returns true if the marker describes an active left redzone.
 248    :    //     Note that block start markers are part of a left redzone.
 249    :    static bool IsActiveLeftRedzone(ShadowMarkerValue marker);
 250    :  
 251    :    // @param marker The shadow marker to query.
 252    :    // @returns true if the marker describes a left redzone, historic or active.
 253    :    //     Note that block start markers are part of a left redzone.
 254    :    static bool IsLeftRedzone(ShadowMarkerValue marker);
 255    :  
 256    :    // @param marker The shadow marker to query.
 257    :    // @returns true if the marker describes a historic right redzone.
 258    :    //     Note that block end markers are part of a right redzone.
 259    :    static bool IsHistoricRightRedzone(ShadowMarkerValue marker);
 260    :  
 261    :    // @param marker The shadow marker to query.
 262    :    // @returns true if the marker describes an active right redzone.
 263    :    //     Note that block end markers are part of a right redzone.
 264    :    static bool IsActiveRightRedzone(ShadowMarkerValue marker);
 265    :  
 266    :    // @param marker The shadow marker to query.
 267    :    // @returns true if the marker describes a right redzone, historic or active.
 268    :    //     Note that block end markers are part of a left redzone.
 269    :    static bool IsRightRedzone(ShadowMarkerValue marker);
 270    :  
 271    :    // @}
 272    :  
 273    :    // @name For modifying shadow markers.
 274    :    // @{
 275    :  
 276    :    // @param marker The shadow marker to modify.
 277    :    // @returns the historic version of the input marker.
 278    :    // @note The input marker must be an active block marker that has an
 279    :    //     equivalent historic type.
 280    :     static ShadowMarker ToHistoric(ShadowMarkerValue marker);
 281    :  
 282    :    // @}
 283    :  
 284    :    // @name For building shadow markers.
 285    :    // @{
 286    :  
 287    :    // Builds a block start marker.
 288    :    // @param active True if the block is active, false if its historic.
 289    :    // @param nested True if the block is nested, false otherwise.
 290    :    // @param data The data to be appended to the marker. This can only consist
 291    :    //     of 3 bits of data.
 292    :    // @returns the generated block start marker.
 293    :    static ShadowMarker BuildBlockStart(bool active, bool nested, uint8 data);
 294    :  
 295    :    // Builds a block end marker.
 296    :    // @param active True if the block is active, false if its historic.
 297    :    // @param nested True if the block is nested, false otherwise.
 298    :    // @returns the generated block end marker.
 299    :    static ShadowMarker BuildBlockEnd(bool active, bool nested);
 300    :  
 301    :    // @}
 302    :  };
 303    :  
 304    :  }  // namespace asan
 305    :  }  // namespace agent
 306    :  
 307    :  #endif  // SYZYGY_AGENT_ASAN_SHADOW_MARKER_H_

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