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/internal_heap.h"
16 :
17 : #include "gtest/gtest.h"
18 : #include "syzygy/agent/asan/unittest_util.h"
19 : #include "syzygy/agent/asan/heaps/large_block_heap.h"
20 : #include "syzygy/agent/asan/heaps/win_heap.h"
21 :
22 : namespace agent {
23 : namespace asan {
24 : namespace heaps {
25 :
26 : namespace {
27 :
28 : using testing::_;
29 : using testing::Return;
30 :
31 : } // namespace
32 :
33 E : TEST(InternalHeapTest, GetHeapTypeIsValid) {
34 E : memory_notifiers::NullMemoryNotifier mock_notifier;
35 E : WinHeap win_heap;
36 E : InternalHeap h(&mock_notifier, &win_heap);
37 E : EXPECT_EQ(win_heap.GetHeapType(), h.GetHeapType());
38 E : }
39 :
40 E : TEST(InternalHeapTest, EndToEnd) {
41 E : memory_notifiers::NullMemoryNotifier mock_notifier;
42 E : WinHeap win_heap;
43 E : InternalHeap h(&mock_notifier, &win_heap);
44 :
45 : // Allocate and free a zero-sized allocation. This should succeed
46 : // by definition.
47 E : void* alloc = h.Allocate(0);
48 E : EXPECT_TRUE(h.Free(alloc));
49 :
50 : // Make a bunch of different sized allocations.
51 E : std::set<void*> allocs;
52 E : for (size_t i = 1; i < 1024 * 1024; i <<= 1) {
53 E : void* alloc = h.Allocate(i);
54 E : allocs.insert(alloc);
55 E : }
56 :
57 : // Now free them.
58 E : std::set<void*>::const_iterator it = allocs.begin();
59 E : for (; it != allocs.end(); ++it)
60 E : EXPECT_TRUE(h.Free(*it));
61 E : }
62 :
63 E : TEST(InternalHeapTest, GetAllocationSize) {
64 E : memory_notifiers::NullMemoryNotifier mock_notifier;
65 E : testing::DummyHeap heap;
66 E : InternalHeap h(&mock_notifier, &heap);
67 :
68 E : void* alloc = h.Allocate(67);
69 E : ASSERT_TRUE(alloc != NULL);
70 E : EXPECT_EQ(::common::AlignUp(67u, kShadowRatio), h.GetAllocationSize(alloc));
71 E : }
72 :
73 E : TEST(InternalHeapTest, NotificationsWorkWithNonNotifyingHeap) {
74 E : testing::MockMemoryNotifier mock_notifier;
75 E : WinHeap win_heap;
76 E : InternalHeap h(&mock_notifier, &win_heap);
77 :
78 E : EXPECT_CALL(mock_notifier, NotifyInternalUse(_, 16)).Times(1);
79 E : EXPECT_CALL(mock_notifier, NotifyReturnedToOS(_, 16)).Times(1);
80 E : void* alloc = h.Allocate(8);
81 E : h.Free(alloc);
82 E : }
83 :
84 E : TEST(InternalHeapTest, NotificationsWorkWithNotifyingHeap) {
85 E : memory_notifiers::NullMemoryNotifier null_notifier;
86 E : testing::MockMemoryNotifier mock_notifier;
87 E : WinHeap win_heap;
88 E : LargeBlockHeap large_block_heap(&null_notifier, &win_heap);
89 E : InternalHeap h(&mock_notifier, &large_block_heap);
90 :
91 E : EXPECT_CALL(mock_notifier, NotifyInternalUse(_, 16)).Times(1);
92 E : EXPECT_CALL(mock_notifier, NotifyFutureHeapUse(_, 16)).Times(1);
93 E : void* alloc = h.Allocate(8);
94 E : h.Free(alloc);
95 E : }
96 :
97 E : TEST(InternalHeapTest, HeaderIsAllocated) {
98 E : memory_notifiers::NullMemoryNotifier null_notifier;
99 E : testing::MockHeap mock_heap;
100 E : uint8 dummy_allocation[16] = {};
101 :
102 E : EXPECT_CALL(mock_heap, GetHeapFeatures()).Times(1).WillOnce(Return(0));
103 E : InternalHeap h(&null_notifier, &mock_heap);
104 :
105 E : void* header = dummy_allocation;
106 E : void* expected_alloc = dummy_allocation + sizeof(uint32);
107 :
108 E : EXPECT_CALL(mock_heap, Allocate(16)).Times(1).WillOnce(Return(header));
109 E : void* alloc = h.Allocate(8);
110 E : EXPECT_EQ(expected_alloc, alloc);
111 E : EXPECT_EQ(16, *reinterpret_cast<uint32*>(dummy_allocation));
112 :
113 E : EXPECT_CALL(mock_heap, Free(header)).Times(1).WillOnce(Return(true));
114 E : EXPECT_TRUE(h.Free(alloc));
115 E : }
116 :
117 E : TEST(InternalHeapTest, Lock) {
118 E : memory_notifiers::NullMemoryNotifier mock_notifier;
119 E : testing::DummyHeap heap;
120 E : InternalHeap h(&mock_notifier, &heap);
121 :
122 E : h.Lock();
123 E : EXPECT_TRUE(h.TryLock());
124 E : h.Unlock();
125 E : h.Unlock();
126 E : }
127 :
128 : } // namespace heaps
129 : } // namespace asan
130 : } // namespace agent
|