1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_COOKIE_H_
6 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_COOKIE_H_
7
8 #include "base/allocator/buildflags.h"
9 #include "base/allocator/partition_allocator/partition_alloc_check.h"
10 #include "base/compiler_specific.h"
11
12 namespace base {
13 namespace internal {
14
15 // Handles alignment up to XMM instructions on Intel.
16 static constexpr size_t kCookieSize = 16;
17
18 // Cookies are enabled for debug builds.
19 #if DCHECK_IS_ON()
20
21 static constexpr unsigned char kCookieValue[kCookieSize] = {
22 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xD0, 0x0D,
23 0x13, 0x37, 0xF0, 0x05, 0xBA, 0x11, 0xAB, 0x1E};
24
PartitionCookieCheckValue(void * ptr)25 ALWAYS_INLINE void PartitionCookieCheckValue(void* ptr) {
26 unsigned char* cookie_ptr = reinterpret_cast<unsigned char*>(ptr);
27 for (size_t i = 0; i < kCookieSize; ++i, ++cookie_ptr)
28 PA_DCHECK(*cookie_ptr == kCookieValue[i]);
29 }
30
PartitionCookieSizeAdjustAdd(size_t size)31 ALWAYS_INLINE size_t PartitionCookieSizeAdjustAdd(size_t size) {
32 // Add space for cookies, checking for integer overflow. TODO(palmer):
33 // Investigate the performance and code size implications of using
34 // CheckedNumeric throughout PA.
35 PA_DCHECK(size + (2 * kCookieSize) > size);
36 size += 2 * kCookieSize;
37 return size;
38 }
39
PartitionCookieSizeAdjustSubtract(size_t size)40 ALWAYS_INLINE size_t PartitionCookieSizeAdjustSubtract(size_t size) {
41 // Remove space for cookies.
42 PA_DCHECK(size >= 2 * kCookieSize);
43 size -= 2 * kCookieSize;
44 return size;
45 }
46
PartitionCookiePointerAdjustSubtract(void * ptr)47 ALWAYS_INLINE void* PartitionCookiePointerAdjustSubtract(void* ptr) {
48 // The value given to the application is actually just after the cookie.
49 ptr = static_cast<char*>(ptr) - kCookieSize;
50 return ptr;
51 }
52
PartitionCookiePointerAdjustAdd(void * ptr)53 ALWAYS_INLINE void* PartitionCookiePointerAdjustAdd(void* ptr) {
54 // The value given to the application is actually just after the cookie.
55 ptr = static_cast<char*>(ptr) + kCookieSize;
56 return ptr;
57 }
58
PartitionCookieWriteValue(void * ptr)59 ALWAYS_INLINE void PartitionCookieWriteValue(void* ptr) {
60 unsigned char* cookie_ptr = reinterpret_cast<unsigned char*>(ptr);
61 for (size_t i = 0; i < kCookieSize; ++i, ++cookie_ptr)
62 *cookie_ptr = kCookieValue[i];
63 }
64
65 #else
66
PartitionCookieCheckValue(void * ptr)67 ALWAYS_INLINE void PartitionCookieCheckValue(void* ptr) {}
68
PartitionCookieSizeAdjustAdd(size_t size)69 ALWAYS_INLINE size_t PartitionCookieSizeAdjustAdd(size_t size) {
70 return size;
71 }
72
PartitionCookieSizeAdjustSubtract(size_t size)73 ALWAYS_INLINE size_t PartitionCookieSizeAdjustSubtract(size_t size) {
74 return size;
75 }
76
PartitionCookiePointerAdjustSubtract(void * ptr)77 ALWAYS_INLINE void* PartitionCookiePointerAdjustSubtract(void* ptr) {
78 return ptr;
79 }
80
PartitionCookiePointerAdjustAdd(void * ptr)81 ALWAYS_INLINE void* PartitionCookiePointerAdjustAdd(void* ptr) {
82 return ptr;
83 }
84
PartitionCookieWriteValue(void * ptr)85 ALWAYS_INLINE void PartitionCookieWriteValue(void* ptr) {}
86 #endif // DCHECK_IS_ON()
87
88 } // namespace internal
89 } // namespace base
90
91 #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_COOKIE_H_
92