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 interface that all heap implementations must implement.
16 : // This is a vastly simplified interface as the instrumentation layer
17 : // provides more advanced features (validation, iteration, etc).
18 : //
19 : // This also declares the interface for an instrumented heap. An instrumented
20 : // heap has explicit knowledge of the fact that it is laying out blocks
21 : // with redzones, as due to heap implementation details it may need to grow
22 : // the redzones of the block being allocated.
23 :
24 : #ifndef SYZYGY_AGENT_ASAN_HEAP_H_
25 : #define SYZYGY_AGENT_ASAN_HEAP_H_
26 :
27 : #include "syzygy/agent/asan/block.h"
28 :
29 : namespace agent {
30 : namespace asan {
31 :
32 : // An enumeration of known heap types. New heaps should be added strictly
33 : // to the end of this list.
34 : enum HeapType {
35 : // A catch-all heap type for test fixtures, etc.
36 : kUnknownHeapType,
37 : kWinHeap,
38 : kReserved, // Was kCtMalloc.
39 : kLargeBlockHeap,
40 : kZebraBlockHeap,
41 :
42 : // This must be last.
43 : kHeapTypeMax,
44 : };
45 :
46 : extern const char* kHeapTypes[kHeapTypeMax];
47 :
48 : // An extremely simple heap interface. More advanced heap features are
49 : // provided by the instrumentation layer which is overlaid on top of a
50 : // raw heap. This is the API for a heap that performs actual memory
51 : // management of simple contiguous chunks of memory. Instrumented heaps
52 : // (for allocating Blocks, with redzones, etc) are allocated and laid out
53 : // by BlockHeap implementations.
54 : class HeapInterface {
55 : public:
56 : // A bitset of features supported by this heap.
57 : enum HeapFeatures {
58 : // If this is set then the heap reports reserved memory via the
59 : // MemoryNotifierInterface. This implies that allocations will come
60 : // from regions of memory that have been previously redzoned, and
61 : // guides the heap manager in maintaining consistent shadow memory.
62 : //
63 : // If this flag is set then the heap should also support the
64 : // kHeapSupportsGetAllocationSize feature in order to be able to redzone the
65 : // unguarded allocations when they get freed.
66 : kHeapReportsReservations = 1 << 0,
67 :
68 : // If this bit is set then the heap is able to determine if a given
69 : // address is part of an active allocation owned by the heap, via the
70 : // 'IsAllocated' function.
71 : kHeapSupportsIsAllocated = 1 << 1,
72 :
73 : // If this bit is set then the heap supports returning allocation sizes.
74 : kHeapSupportsGetAllocationSize = 1 << 2,
75 :
76 : // If this bit is set then the results returned by GetAllocationSize are
77 : // approximate, and reflect the size of the block of memory returned for
78 : // the allocation, not the actual initially requested amount. Can only be
79 : // set in conjunction with kHeapSupportsGetAllocationSize.
80 : kHeapGetAllocationSizeIsUpperBound = 1 << 3,
81 : };
82 :
83 : // The return value of GetAllocationSize if the heap does not support it.
84 : static const size_t kUnknownSize = ~0U;
85 :
86 : // Virtual destructor.
87 E : virtual ~HeapInterface() { }
88 :
89 : // Reports the of this heap.
90 : // @returns the type of this heap.
91 : virtual HeapType GetHeapType() const = 0;
92 :
93 : // @returns the heap features.
94 : virtual uint32 GetHeapFeatures() const = 0;
95 :
96 : // Allocates memory from the heap. It is valid to request an allocation
97 : // of size zero, in which case any return address is valid. If @p bytes
98 : // is non-zero and the request fails this should return NULL. The allocation
99 : // must have an alignment of at least kShadowRatio.
100 : // @param bytes The size of the requested allocation, in bytes.
101 : // @returns a valid pointer on success, or NULL on failure.
102 : virtual void* Allocate(size_t bytes) = 0;
103 :
104 : // Frees an allocation, returning the memory to the underlying heap. It is
105 : // invalid to attempt to free memory not previously allocated by this heap,
106 : // or double free previously freed memory.
107 : // @param alloc The address of the allocation.
108 : // @returns true on success, false otherwise.
109 : virtual bool Free(void* alloc) = 0;
110 :
111 : // Determines if the heap owns the given allocation.
112 : // @param alloc An address.
113 : // @returns true if @p alloc is an address previously returned by a call
114 : // to 'Allocate', and not yet returned via 'Free'.
115 : // @note This will always return false unless the heap has the
116 : // kHeapSupportsIsAllocated feature.
117 : virtual bool IsAllocated(const void* alloc) = 0;
118 :
119 : // Returns the size of the given allocation.
120 : // @param alloc An address previously returned by Allocate.
121 : // @returns the size of the allocation.
122 : // @note This will always return kUnknownSize unless the heap has the
123 : // kHeapSupportsGetAllocationSize feature.
124 : virtual size_t GetAllocationSize(const void* alloc) = 0;
125 :
126 : // Locks the heap. All other calls to the heap will be blocked until
127 : // a corresponding call to Unlock.
128 : virtual void Lock() = 0;
129 :
130 : // Unlocks the heap.
131 : virtual void Unlock() = 0;
132 :
133 : // Tries to lock this heap.
134 : // @returns true if the lock was acquired, false otherwise.
135 : virtual bool TryLock() = 0;
136 : };
137 :
138 : // Declares the interface that a block-allocating heap must implement. The API
139 : // reflects the fact that the heap implementation is aware that it is
140 : // allocating Block objects with redzones, and allows for the implementation to
141 : // potentially grow the redzones of the requested block. This is an extension
142 : // of HeapInterface.
143 : class BlockHeapInterface : public HeapInterface {
144 : public:
145 : // Virtual destructor.
146 E : virtual ~BlockHeapInterface() { }
147 :
148 : // Allocates a block from the heap. If this heap is unable to satisfy the
149 : // allocation then it can simply return NULL and not initialize the block
150 : // layout.
151 : // @param size The size of the body of the allocation. Can be 0.
152 : // @param min_left_redzone_size The minimum size of the left redzone.
153 : // @param min_right_redzone_size The minimum size of the right redzone.
154 : // @param layout The layout structure to be populated.
155 : // @returns a pointer to the allocation upon success, otherwise NULL.
156 : virtual void* AllocateBlock(size_t size,
157 : size_t min_left_redzone_size,
158 : size_t min_right_redzone_size,
159 : BlockLayout* layout) = 0;
160 :
161 : // Frees the block at the given address.
162 : // @returns true on success, false otherwise.
163 : virtual bool FreeBlock(const BlockInfo& block_info) = 0;
164 : };
165 :
166 : } // namespace asan
167 : } // namespace agent
168 :
169 : #endif // SYZYGY_AGENT_ASAN_HEAP_H_
|