OLD | NEW |
1 // Copyright 2014 Google Inc. All Rights Reserved. | 1 // Copyright 2014 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 // Various constants for identifying the beginnings of regions of memory. | 105 // Various constants for identifying the beginnings of regions of memory. |
106 static const uint16_t kBlockHeaderMagic = 0xCA80; | 106 static const uint16_t kBlockHeaderMagic = 0xCA80; |
107 | 107 |
108 // Various constants used for filling regions of memory. | 108 // Various constants used for filling regions of memory. |
109 static const uint8_t kBlockHeaderPaddingByte = 0x1C; | 109 static const uint8_t kBlockHeaderPaddingByte = 0x1C; |
110 static const uint8_t kBlockTrailerPaddingByte = 0xC3; | 110 static const uint8_t kBlockTrailerPaddingByte = 0xC3; |
111 static const uint8_t kBlockFloodFillByte = 0xFD; | 111 static const uint8_t kBlockFloodFillByte = 0xFD; |
112 | 112 |
113 // The number of bits in the checksum field. This is parameterized so that | 113 // The number of bits in the checksum field. This is parameterized so that |
114 // it can be referred to by the checksumming code. | 114 // it can be referred to by the checksumming code. |
115 static const size_t kBlockHeaderChecksumBits = 13; | 115 static const size_t kBlockHeaderChecksumBits = 14; |
116 | 116 |
117 // The state of an Asan block. These are in the order that reflects the typical | 117 // The state of an Asan block. These are in the order that reflects the typical |
118 // lifespan of an allocation. | 118 // lifespan of an allocation. |
119 enum BlockState { | 119 enum BlockState { |
120 // The block is allocated and valid for reading/writing. | 120 // The block is allocated and valid for reading/writing. |
121 ALLOCATED_BLOCK, | 121 ALLOCATED_BLOCK, |
122 // The block has been quarantined, and not valid for reading/writing. | 122 // The block has been quarantined, and not valid for reading/writing. |
123 // While in the quarantine it is still allocated as far as the underlying | 123 // While in the quarantine it is still allocated as far as the underlying |
124 // heap is concerned, and won't be reclaimed. | 124 // heap is concerned, and won't be reclaimed. |
125 QUARANTINED_BLOCK, | 125 QUARANTINED_BLOCK, |
(...skipping 13 matching lines...) Expand all Loading... |
139 // overwrites are far more common than underwrites critical information should | 139 // overwrites are far more common than underwrites critical information should |
140 // be stored here. | 140 // be stored here. |
141 #pragma pack(push, 1) | 141 #pragma pack(push, 1) |
142 struct BlockHeader { | 142 struct BlockHeader { |
143 struct { | 143 struct { |
144 // A magic constant that identifies the block header in memory. | 144 // A magic constant that identifies the block header in memory. |
145 unsigned magic : 16; | 145 unsigned magic : 16; |
146 // The checksum of the entire block. The semantics of this vary with the | 146 // The checksum of the entire block. The semantics of this vary with the |
147 // block state. | 147 // block state. |
148 unsigned checksum : kBlockHeaderChecksumBits; | 148 unsigned checksum : kBlockHeaderChecksumBits; |
149 // If this bit is set then the block is a nested block. | 149 // This is implicitly a BlockState value. |
150 unsigned is_nested : 1; | 150 unsigned state : 2; |
151 // If this bit is positive then header padding is present. The size of the | 151 // If this bit is positive then header padding is present. The size of the |
152 // header padding is encoded in the padding itself. | 152 // header padding is encoded in the padding itself. |
153 unsigned has_header_padding : 1; | 153 unsigned has_header_padding : 1; |
154 // If this bit is positive then trailer padding in excess of | 154 // If this bit is positive then trailer padding in excess of |
155 // kShadowRatio/2 is present, and the size of the trailer padding itself | 155 // kShadowRatio/2 is present, and the size of the trailer padding itself |
156 // will be encoded in these bytes. Otherwise it is implicit as | 156 // will be encoded in these bytes. Otherwise it is implicit as |
157 // (kShadowRatio / 2) - (body_size % (kShadowRatio / 2)). | 157 // (kShadowRatio / 2) - (body_size % (kShadowRatio / 2)). |
158 unsigned has_excess_trailer_padding : 1; | 158 unsigned has_excess_trailer_padding : 1; |
159 // This is implicitly a BlockState value. | |
160 unsigned state : 2; | |
161 // The size of the body of the allocation, in bytes. | 159 // The size of the body of the allocation, in bytes. |
162 unsigned body_size : 30; | 160 unsigned body_size : 30; |
163 }; | 161 }; |
164 // TODO(loskutov): replace pointers with something more compact. | 162 // TODO(loskutov): replace pointers with something more compact. |
165 // The allocation stack of this block. | 163 // The allocation stack of this block. |
166 const common::StackCapture* alloc_stack; | 164 const common::StackCapture* alloc_stack; |
167 // The free stack of this block (NULL if not yet quarantined/freed). | 165 // The free stack of this block (NULL if not yet quarantined/freed). |
168 const common::StackCapture* free_stack; | 166 const common::StackCapture* free_stack; |
169 }; | 167 }; |
170 #pragma pack(pop) | 168 #pragma pack(pop) |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 // strict subset of the entire block, depending on how it was allocated. | 278 // strict subset of the entire block, depending on how it was allocated. |
281 // These pages will have protections toggled as the block changes state. | 279 // These pages will have protections toggled as the block changes state. |
282 // These must stay contiguous. | 280 // These must stay contiguous. |
283 uint8_t* block_pages; | 281 uint8_t* block_pages; |
284 uint32_t block_pages_size; | 282 uint32_t block_pages_size; |
285 uint8_t* left_redzone_pages; | 283 uint8_t* left_redzone_pages; |
286 uint32_t left_redzone_pages_size; | 284 uint32_t left_redzone_pages_size; |
287 uint8_t* right_redzone_pages; | 285 uint8_t* right_redzone_pages; |
288 uint32_t right_redzone_pages_size; | 286 uint32_t right_redzone_pages_size; |
289 | 287 |
290 // Indicates if the block is nested. | |
291 bool is_nested; | |
292 | |
293 // Convenience accessors to various parts of the block. All access should be | 288 // Convenience accessors to various parts of the block. All access should be |
294 // gated through these as they provide strong bounds checking in debug | 289 // gated through these as they provide strong bounds checking in debug |
295 // builds. | 290 // builds. |
296 // @name | 291 // @name |
297 // @{ | 292 // @{ |
298 uint8_t* RawBlock() const { return reinterpret_cast<uint8_t*>(header); } | 293 uint8_t* RawBlock() const { return reinterpret_cast<uint8_t*>(header); } |
299 uint8_t& RawBlock(uint32_t index) const { | 294 uint8_t& RawBlock(uint32_t index) const { |
300 DCHECK_GT(block_size, index); | 295 DCHECK_GT(block_size, index); |
301 return RawBlock()[index]; | 296 return RawBlock()[index]; |
302 } | 297 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 // Given a fresh allocation and a block layout, lays out and initializes the | 363 // Given a fresh allocation and a block layout, lays out and initializes the |
369 // given block. Initializes everything except for the allocation stack and the | 364 // given block. Initializes everything except for the allocation stack and the |
370 // checksum. Initializes the block to the ALLOCATED_BLOCK state, setting | 365 // checksum. Initializes the block to the ALLOCATED_BLOCK state, setting |
371 // |alloc_ticks| and |alloc_tid|. Sets |alloc_stack| to NULL; the caller should | 366 // |alloc_ticks| and |alloc_tid|. Sets |alloc_stack| to NULL; the caller should |
372 // set this stack upon return so as to minimize the number of useless frames on | 367 // set this stack upon return so as to minimize the number of useless frames on |
373 // the stack. Does not set the checksum. | 368 // the stack. Does not set the checksum. |
374 // @param layout The layout to be respected. | 369 // @param layout The layout to be respected. |
375 // @param allocation The allocation to be filled in. This must be of | 370 // @param allocation The allocation to be filled in. This must be of |
376 // |layout.block_size| in size, and be aligned with | 371 // |layout.block_size| in size, and be aligned with |
377 // |layout.block_alignment|. | 372 // |layout.block_alignment|. |
378 // @param is_nested Indicates if the block is nested. | |
379 // @param block_info Will be filled in with pointers to the various portions | 373 // @param block_info Will be filled in with pointers to the various portions |
380 // of the block. May be NULL. | 374 // of the block. May be NULL. |
381 // @note The pages containing the block must be writable and readable. | 375 // @note The pages containing the block must be writable and readable. |
382 void BlockInitialize(const BlockLayout& layout, | 376 void BlockInitialize(const BlockLayout& layout, |
383 void* allocation, | 377 void* allocation, |
384 bool is_nested, | |
385 BlockInfo* block_info); | 378 BlockInfo* block_info); |
386 | 379 |
387 // Converts between the two BlockInfo formats. This will work as long as the | 380 // Converts between the two BlockInfo formats. This will work as long as the |
388 // input is valid; garbage in implies garbage out. | 381 // input is valid; garbage in implies garbage out. |
389 // @param compact The populated compact block info. | 382 // @param compact The populated compact block info. |
390 // @param expanded The full expanded block info. | 383 // @param expanded The full expanded block info. |
391 void ConvertBlockInfo(const CompactBlockInfo& compact, BlockInfo* expanded); | 384 void ConvertBlockInfo(const CompactBlockInfo& compact, BlockInfo* expanded); |
392 void ConvertBlockInfo(const BlockInfo& expanded, CompactBlockInfo* compact); | 385 void ConvertBlockInfo(const BlockInfo& expanded, CompactBlockInfo* compact); |
393 | 386 |
394 // Given a pointer to a block examines memory and extracts the block layout. | 387 // Given a pointer to a block examines memory and extracts the block layout. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 typedef base::Callback<void(EXCEPTION_POINTERS*)> OnExceptionCallback; | 517 typedef base::Callback<void(EXCEPTION_POINTERS*)> OnExceptionCallback; |
525 void SetOnExceptionCallback(OnExceptionCallback callback); | 518 void SetOnExceptionCallback(OnExceptionCallback callback); |
526 void ClearOnExceptionCallback(); | 519 void ClearOnExceptionCallback(); |
527 | 520 |
528 } // namespace asan | 521 } // namespace asan |
529 } // namespace agent | 522 } // namespace agent |
530 | 523 |
531 #include "syzygy/agent/asan/block_impl.h" | 524 #include "syzygy/agent/asan/block_impl.h" |
532 | 525 |
533 #endif // SYZYGY_AGENT_ASAN_BLOCK_H_ | 526 #endif // SYZYGY_AGENT_ASAN_BLOCK_H_ |
OLD | NEW |