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 = ~(kActiveBit | kBlockEndNestedBit);
135 E : return (marker.value & kMask) == kHeapHistoricBlockEndMarker;
136 E : }
137 :
138 E : bool ShadowMarkerHelper::IsNestedBlockEnd(ShadowMarkerValue marker) {
139 E : if (!IsBlockEnd(marker))
140 E : return false;
141 E : return (marker.value & kBlockEndNestedBit) == kBlockEndNestedBit;
142 E : }
143 :
144 E : bool ShadowMarkerHelper::IsHistoricLeftRedzone(ShadowMarkerValue marker) {
145 : return marker.value == kHeapHistoricLeftPaddingMarker ||
146 E : IsHistoricBlockStart(marker);
147 E : }
148 :
149 E : bool ShadowMarkerHelper::IsActiveLeftRedzone(ShadowMarkerValue marker) {
150 : return marker.value == kHeapLeftPaddingMarker ||
151 E : IsActiveBlockStart(marker);
152 E : }
153 :
154 E : bool ShadowMarkerHelper::IsLeftRedzone(ShadowMarkerValue marker) {
155 : return (marker.value & ~kActiveBit) == kHeapHistoricLeftPaddingMarker ||
156 E : IsBlockStart(marker);
157 E : }
158 :
159 E : bool ShadowMarkerHelper::IsHistoricRightRedzone(ShadowMarkerValue marker) {
160 : return marker.value == kHeapHistoricRightPaddingMarker ||
161 E : IsHistoricBlockEnd(marker);
162 E : }
163 :
164 E : bool ShadowMarkerHelper::IsActiveRightRedzone(ShadowMarkerValue marker) {
165 : return marker.value == kHeapRightPaddingMarker ||
166 E : IsActiveBlockEnd(marker);
167 E : }
168 :
169 E : bool ShadowMarkerHelper::IsRightRedzone(ShadowMarkerValue marker) {
170 : return (marker.value & ~kActiveBit) == kHeapHistoricRightPaddingMarker ||
171 E : IsBlockEnd(marker);
172 E : }
173 :
174 E : ShadowMarker ShadowMarkerHelper::ToHistoric(ShadowMarkerValue marker) {
175 E : DCHECK(IsActiveBlock(marker));
176 E : return static_cast<ShadowMarker>(marker.value & ~kActiveBit);
177 E : }
178 :
179 : ShadowMarker ShadowMarkerHelper::BuildBlockStart(
180 E : bool active, bool nested, uint8 data) {
181 E : DCHECK_EQ(0, data & ~kBlockStartDataMask);
182 E : uint8 marker = kHeapHistoricBlockStartMarker0;
183 E : if (active)
184 E : marker |= kActiveBit;
185 E : if (nested)
186 E : marker |= kBlockStartNestedBit;
187 E : marker |= data;
188 E : return static_cast<ShadowMarker>(marker);
189 E : }
190 :
191 E : ShadowMarker ShadowMarkerHelper::BuildBlockEnd(bool active, bool nested) {
192 E : uint8 marker = kHeapHistoricBlockEndMarker;
193 E : if (active)
194 E : marker |= kActiveBit;
195 E : if (nested)
196 E : marker |= kBlockEndNestedBit;
197 E : return static_cast<ShadowMarker>(marker);
198 E : }
199 :
200 : } // namespace asan
201 : } // namespace agent
|