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 : // Implementations of the Asan heap interceptors. These functions are
16 : // instrumented and log detailed function call information to the call-trace
17 : // service.
18 :
19 : #include <windows.h>
20 :
21 : #include "base/hash.h"
22 : #include "syzygy/agent/memprof/memprof.h"
23 :
24 : // A wrapper to EMIT_DETAILED_FUNCTION_CALL that provides the MemoryProfiler
25 : // FunctionCallLogger instance.
26 : #define EMIT_DETAILED_HEAP_FUNCTION_CALL(...) \
27 m : DCHECK_NE(static_cast<agent::memprof::MemoryProfiler*>(nullptr), \
28 m : agent::memprof::memory_profiler.get()); \
29 m : EMIT_DETAILED_FUNCTION_CALL( \
30 m : &agent::memprof::memory_profiler->function_call_logger(), \
31 m : agent::memprof::memory_profiler->GetOrAllocateThreadState()-> \
32 m : segment(), \
33 m : __VA_ARGS__);
34 :
35 m : extern "C" {
36 :
37 m : HANDLE WINAPI asan_GetProcessHeap() {
38 : // This function doesn't need to be logged, but does need to be implemented
39 : // for compatibility with old ASAN implementations.
40 m : return ::GetProcessHeap();
41 m : }
42 :
43 m : HANDLE WINAPI asan_HeapCreate(DWORD options,
44 m : SIZE_T initial_size,
45 m : SIZE_T maximum_size) {
46 m : HANDLE ret = ::HeapCreate(options, initial_size, maximum_size);
47 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(options, initial_size, maximum_size, ret);
48 m : return ret;
49 m : }
50 :
51 m : BOOL WINAPI asan_HeapDestroy(HANDLE heap) {
52 m : BOOL ret = ::HeapDestroy(heap);
53 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, ret);
54 m : return ret;
55 m : }
56 :
57 m : LPVOID WINAPI asan_HeapAlloc(HANDLE heap,
58 m : DWORD flags,
59 m : SIZE_T bytes) {
60 m : LPVOID ret = ::HeapAlloc(heap, flags, bytes);
61 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, bytes, ret);
62 m : return ret;
63 m : }
64 :
65 m : LPVOID WINAPI asan_HeapReAlloc(HANDLE heap,
66 m : DWORD flags,
67 m : LPVOID mem,
68 m : SIZE_T bytes) {
69 m : LPVOID ret = ::HeapReAlloc(heap, flags, mem, bytes);
70 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, mem, bytes, ret);
71 m : return ret;
72 m : }
73 :
74 m : BOOL WINAPI asan_HeapFree(HANDLE heap,
75 m : DWORD flags,
76 m : LPVOID mem) {
77 : // Calculate a hash value of the contents if necessary.
78 m : uint32 hash = 0;
79 m : if (mem != nullptr &&
80 m : agent::memprof::memory_profiler->parameters().hash_contents_at_free) {
81 m : size_t size = ::HeapSize(heap, 0, mem);
82 m : hash = base::SuperFastHash(reinterpret_cast<const char*>(mem), size);
83 m : }
84 :
85 m : BOOL ret = ::HeapFree(heap, flags, mem);
86 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, mem, ret, hash);
87 m : return ret;
88 m : }
89 :
90 m : SIZE_T WINAPI asan_HeapSize(HANDLE heap,
91 m : DWORD flags,
92 m : LPCVOID mem) {
93 m : SIZE_T ret = ::HeapSize(heap, flags, mem);
94 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, mem, ret);
95 m : return ret;
96 m : }
97 :
98 m : BOOL WINAPI asan_HeapValidate(HANDLE heap,
99 m : DWORD flags,
100 m : LPCVOID mem) {
101 m : BOOL ret = ::HeapValidate(heap, flags, mem);
102 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, mem, ret);
103 m : return ret;
104 m : }
105 :
106 m : SIZE_T WINAPI asan_HeapCompact(HANDLE heap,
107 m : DWORD flags) {
108 m : SIZE_T ret = ::HeapCompact(heap, flags);
109 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, ret);
110 m : return ret;
111 m : }
112 :
113 m : BOOL WINAPI asan_HeapLock(HANDLE heap) {
114 m : BOOL ret = ::HeapLock(heap);
115 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, ret);
116 m : return ret;
117 m : }
118 :
119 m : BOOL WINAPI asan_HeapUnlock(HANDLE heap) {
120 m : BOOL ret = ::HeapUnlock(heap);
121 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, ret);
122 m : return ret;
123 m : }
124 :
125 m : BOOL WINAPI asan_HeapWalk(HANDLE heap,
126 m : LPPROCESS_HEAP_ENTRY entry) {
127 m : BOOL ret = ::HeapWalk(heap, entry);
128 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, entry, ret);
129 m : return ret;
130 m : }
131 :
132 m : BOOL WINAPI asan_HeapSetInformation(
133 m : HANDLE heap, HEAP_INFORMATION_CLASS info_class,
134 m : PVOID info, SIZE_T info_length) {
135 m : BOOL ret = ::HeapSetInformation(heap, info_class, info, info_length);
136 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, info_class, info, info_length, ret);
137 m : return ret;
138 m : }
139 :
140 m : BOOL WINAPI asan_HeapQueryInformation(
141 m : HANDLE heap, HEAP_INFORMATION_CLASS info_class,
142 m : PVOID info, SIZE_T info_length, PSIZE_T return_length) {
143 m : BOOL ret = ::HeapQueryInformation(
144 m : heap, info_class, info, info_length, return_length);
145 m : EMIT_DETAILED_HEAP_FUNCTION_CALL(
146 m : heap, info_class, info, info_length, return_length, ret);
147 m : return ret;
148 m : }
149 :
150 m : } // extern "C"
|