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 : #include "syzygy/agent/asan/shadow_marker.h"
16 :
17 : #include "base/logging.h"
18 :
19 : namespace agent {
20 : namespace asan {
21 :
22 : namespace {
23 :
24 : // Some constants related to the structure of shadow marker values.
25 : static const uint8 kActiveBit = 0x20;
26 : static const uint8 kBlockEndNestedBit = 0x01;
27 : static const uint8 kBlockStartDataMask = 0x7;
28 : static const uint8 kBlockStartNestedBit = 0x08;
29 : static const uint8 kFirstNibble = 0xF0;
30 : static const uint8 kRedzoneBit = 0x80;
31 :
32 : // ShadowMarker name generator. This maps an enumeration value to a name via
33 : // template specialization.
34 : template<size_t kIndex> struct ShadowMarkerNameGenerator {
35 : static const uintptr_t kName = 0;
36 : };
37 : #define SHADOW_MARKER_NAME_GENERATOR_MACRO(name, value) \
38 : template<> struct ShadowMarkerNameGenerator<value> { \
39 : static const char* kName; \
40 : }; \
41 : const char* ShadowMarkerNameGenerator<value>::kName = \
42 : _STRINGIZE(name);
43 : SHADOW_MARKER_GENERATOR(SHADOW_MARKER_NAME_GENERATOR_MACRO)
44 : #undef SHADOW_MARKER_NAME_GENERATOR_MACRO
45 :
46 : } // namespace
47 :
48 : // This generates an array of shadow marker names, populating valid markers
49 : // with their names as defined by the template specialization above. Invalid
50 : // markers map to NULL as defined by the base template.
51 : #define ITERATE_2(F, base) F(base) F(base + 1)
52 : #define ITERATE_4(F, base) ITERATE_2(F, base) ITERATE_2(F, base + 2)
53 : #define ITERATE_8(F, base) ITERATE_4(F, base) ITERATE_4(F, base + 4)
54 : #define ITERATE_16(F, base) ITERATE_8(F, base) ITERATE_8(F, base + 8)
55 : #define ITERATE_32(F, base) ITERATE_16(F, base) ITERATE_16(F, base + 16)
56 : #define ITERATE_64(F, base) ITERATE_32(F, base) ITERATE_32(F, base + 32)
57 : #define ITERATE_128(F, base) ITERATE_64(F, base) ITERATE_64(F, base + 64)
58 : #define ITERATE_256(F) ITERATE_128(F, 0) ITERATE_128(F, 128)
59 : #define GET_SHADOW_MARKER_STRING_PTR(index) \
60 : reinterpret_cast<const char*>(ShadowMarkerNameGenerator<index>::kName),
61 : const char* kShadowMarkerNames[256] = {
62 : ITERATE_256(GET_SHADOW_MARKER_STRING_PTR)
63 E : };
64 : #undef GET_SHADOW_MARKER_STRING_PTR
65 : #undef ITERATE_256
66 : #undef ITERATE_128
67 : #undef ITERATE_64
68 : #undef ITERATE_32
69 : #undef ITERATE_16
70 : #undef ITERATE_8
71 : #undef ITERATE_4
72 : #undef ITERATE_2
73 :
74 E : bool ShadowMarkerHelper::IsRedzone(ShadowMarkerValue marker) {
75 E : return (marker.value & kRedzoneBit) == kRedzoneBit;
76 E : }
77 :
78 E : bool ShadowMarkerHelper::IsActiveBlock(ShadowMarkerValue marker) {
79 : return marker.value == kHeapLeftPaddingMarker ||
80 : marker.value == kHeapRightPaddingMarker ||
81 : marker.value == kHeapFreedMarker ||
82 : IsActiveBlockStart(marker) ||
83 E : IsActiveBlockEnd(marker);
84 E : }
85 :
86 E : bool ShadowMarkerHelper::IsHistoricBlock(ShadowMarkerValue marker) {
87 : return marker.value == kHeapHistoricLeftPaddingMarker ||
88 : marker.value == kHeapHistoricRightPaddingMarker ||
89 : marker.value == kHeapHistoricFreedMarker ||
90 : IsHistoricBlockStart(marker) ||
91 E : IsHistoricBlockEnd(marker);
92 E : }
93 :
94 E : bool ShadowMarkerHelper::IsBlock(ShadowMarkerValue marker) {
95 E : return IsActiveBlock(marker) || IsHistoricBlock(marker);
96 E : }
97 :
98 E : bool ShadowMarkerHelper::IsActiveBlockStart(ShadowMarkerValue marker) {
99 E : return (marker.value & kFirstNibble) == kHeapBlockStartMarker0;
100 E : }
101 :
102 E : bool ShadowMarkerHelper::IsHistoricBlockStart(ShadowMarkerValue marker) {
103 E : return (marker.value & kFirstNibble) == kHeapHistoricBlockStartMarker0;
104 E : }
105 :
106 E : bool ShadowMarkerHelper::IsBlockStart(ShadowMarkerValue marker) {
107 : static const uint8 kMask = kFirstNibble ^ kActiveBit;
108 E : return (marker.value & kMask) == kHeapHistoricBlockStartMarker0;
109 E : }
110 :
111 E : bool ShadowMarkerHelper::IsNestedBlockStart(ShadowMarkerValue marker) {
112 E : if (!IsBlockStart(marker))
113 E : return false;
114 E : return (marker.value & kBlockStartNestedBit) == kBlockStartNestedBit;
115 E : }
116 :
117 E : uint8 ShadowMarkerHelper::GetBlockStartData(ShadowMarkerValue marker) {
118 E : return marker.value & kBlockStartDataMask;
119 E : }
120 :
121 E : bool ShadowMarkerHelper::IsActiveBlockEnd(ShadowMarkerValue marker) {
122 : return (marker.value & ~kBlockEndNestedBit) ==
123 E : kHeapBlockEndMarker;
124 E : }
125 :
126 E : bool ShadowMarkerHelper::IsHistoricBlockEnd(ShadowMarkerValue marker) {
127 : return (marker.value & ~kBlockEndNestedBit) ==
128 E : kHeapHistoricBlockEndMarker;
129 E : }
130 :
131 E : bool ShadowMarkerHelper::IsBlockEnd(ShadowMarkerValue marker) {
132 : // Block end markers have arbitrary values for the active bit
133 : // and the block end nested bit.
134 : static const uint8 kMask =
135 : static_cast<uint8>(~(kActiveBit | kBlockEndNestedBit));
136 E : return (marker.value & kMask) == kHeapHistoricBlockEndMarker;
137 E : }
138 :
139 E : bool ShadowMarkerHelper::IsNestedBlockEnd(ShadowMarkerValue marker) {
140 E : if (!IsBlockEnd(marker))
141 E : return false;
142 E : return (marker.value & kBlockEndNestedBit) == kBlockEndNestedBit;
143 E : }
144 :
145 E : bool ShadowMarkerHelper::IsHistoricLeftRedzone(ShadowMarkerValue marker) {
146 : return marker.value == kHeapHistoricLeftPaddingMarker ||
147 E : IsHistoricBlockStart(marker);
148 E : }
149 :
150 E : bool ShadowMarkerHelper::IsActiveLeftRedzone(ShadowMarkerValue marker) {
151 : return marker.value == kHeapLeftPaddingMarker ||
152 E : IsActiveBlockStart(marker);
153 E : }
154 :
155 E : bool ShadowMarkerHelper::IsLeftRedzone(ShadowMarkerValue marker) {
156 : return (marker.value & ~kActiveBit) == kHeapHistoricLeftPaddingMarker ||
157 E : IsBlockStart(marker);
158 E : }
159 :
160 E : bool ShadowMarkerHelper::IsHistoricRightRedzone(ShadowMarkerValue marker) {
161 : return marker.value == kHeapHistoricRightPaddingMarker ||
162 E : IsHistoricBlockEnd(marker);
163 E : }
164 :
165 E : bool ShadowMarkerHelper::IsActiveRightRedzone(ShadowMarkerValue marker) {
166 : return marker.value == kHeapRightPaddingMarker ||
167 E : IsActiveBlockEnd(marker);
168 E : }
169 :
170 E : bool ShadowMarkerHelper::IsRightRedzone(ShadowMarkerValue marker) {
171 : return (marker.value & ~kActiveBit) == kHeapHistoricRightPaddingMarker ||
172 E : IsBlockEnd(marker);
173 E : }
174 :
175 E : ShadowMarker ShadowMarkerHelper::ToHistoric(ShadowMarkerValue marker) {
176 E : DCHECK(IsActiveBlock(marker));
177 E : return static_cast<ShadowMarker>(marker.value & ~kActiveBit);
178 E : }
179 :
180 : ShadowMarker ShadowMarkerHelper::BuildBlockStart(
181 E : bool active, bool nested, uint8 data) {
182 E : DCHECK_EQ(0, data & ~kBlockStartDataMask);
183 E : uint8 marker = kHeapHistoricBlockStartMarker0;
184 E : if (active)
185 E : marker |= kActiveBit;
186 E : if (nested)
187 E : marker |= kBlockStartNestedBit;
188 E : marker |= data;
189 E : return static_cast<ShadowMarker>(marker);
190 E : }
191 :
192 E : ShadowMarker ShadowMarkerHelper::BuildBlockEnd(bool active, bool nested) {
193 E : uint8 marker = kHeapHistoricBlockEndMarker;
194 E : if (active)
195 E : marker |= kActiveBit;
196 E : if (nested)
197 E : marker |= kBlockEndNestedBit;
198 E : return static_cast<ShadowMarker>(marker);
199 E : }
200 :
201 : } // namespace asan
202 : } // namespace agent
|