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/heaps/win_heap.h"
16 :
17 : namespace agent {
18 : namespace asan {
19 : namespace heaps {
20 :
21 E : WinHeap::WinHeap() : heap_(NULL), own_heap_(true), heap_lock_held_(false) {
22 E : heap_ = ::HeapCreate(0, 0, 0);
23 E : DCHECK_NE(static_cast<HANDLE>(NULL), heap_);
24 E : }
25 :
26 : WinHeap::WinHeap(HANDLE heap)
27 E : : heap_(heap), own_heap_(false), heap_lock_held_(false) {
28 E : }
29 :
30 E : WinHeap::~WinHeap() {
31 E : if (!own_heap_)
32 E : return;
33 E : DCHECK_NE(static_cast<HANDLE>(NULL), heap_);
34 E : ::HeapDestroy(heap_);
35 E : }
36 :
37 E : HeapType WinHeap::GetHeapType() const {
38 E : return kWinHeap;
39 E : }
40 :
41 E : uint32 WinHeap::GetHeapFeatures() const {
42 E : return kHeapSupportsGetAllocationSize;
43 E : }
44 :
45 E : void* WinHeap::Allocate(size_t bytes) {
46 E : DCHECK_NE(static_cast<HANDLE>(NULL), heap_);
47 E : void* alloc = ::HeapAlloc(heap_, 0, bytes);
48 E : return alloc;
49 E : }
50 :
51 E : bool WinHeap::Free(void* alloc) {
52 E : DCHECK_NE(static_cast<HANDLE>(NULL), heap_);
53 :
54 : // According to the MSDN documentation about HeapFree the return value needs
55 : // to be cast to BOOLEAN in order to support Windows XP:
56 : // Prior to Windows Vista, HeapFree has a bug: only the low byte of the
57 : // return value is correctly indicative of the result. This is because
58 : // the implementation returns type BOOLEAN (BYTE) despite the prototype
59 : // declaring it as returning BOOL (int).
60 : //
61 : // If you care about the return value of HeapFree, and you need to support
62 : // XP and 2003, cast the return value to BOOLEAN before checking it.
63 E : if (static_cast<BOOLEAN>(::HeapFree(heap_, 0, alloc)) != TRUE)
64 i : return false;
65 E : return true;
66 E : }
67 :
68 E : bool WinHeap::IsAllocated(const void* alloc) {
69 E : return false;
70 E : }
71 :
72 E : size_t WinHeap::GetAllocationSize(const void* alloc) {
73 E : return ::HeapSize(heap_, 0, alloc);
74 E : }
75 :
76 E : void WinHeap::Lock() {
77 E : DCHECK_NE(static_cast<HANDLE>(NULL), heap_);
78 E : lock_.Acquire();
79 E : if (lock_.recursion() == 1) {
80 E : DCHECK(!heap_lock_held_);
81 E : if (::HeapLock(heap_) == TRUE)
82 E : heap_lock_held_ = true;
83 : }
84 E : }
85 :
86 E : void WinHeap::Unlock() {
87 E : DCHECK_NE(static_cast<HANDLE>(NULL), heap_);
88 E : lock_.AssertAcquired();
89 E : if (lock_.recursion() == 1 && heap_lock_held_) {
90 E : ::HeapUnlock(heap_);
91 E : heap_lock_held_ = false;
92 : }
93 E : lock_.Release();
94 E : }
95 :
96 E : bool WinHeap::TryLock() {
97 E : return lock_.Try();
98 E : }
99 :
100 : } // namespace heaps
101 : } // namespace asan
102 : } // namespace agent
|