Revert of Roll src/third_party/WebKit e0eac24:489c548 (svn 193311:193320) (patchset...
[chromium-blink-merge.git] / third_party / tcmalloc / chromium / src / windows / preamble_patcher.h
blob4fdb7d001655a02953ea8f0f821a5c5ab2f7794e
1 /* Copyright (c) 2007, Google Inc.
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * ---
31 * Author: Joi Sigurdsson
32 * Author: Scott Francis
34 * Definition of PreamblePatcher
37 #ifndef GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
38 #define GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
40 #include "config.h"
41 #include <windows.h>
43 // compatibility shim
44 #include "base/logging.h"
45 #define SIDESTEP_ASSERT(cond) RAW_DCHECK(cond, #cond)
46 #define SIDESTEP_LOG(msg) RAW_VLOG(1, msg)
48 // Maximum size of the preamble stub. We overwrite at least the first 5
49 // bytes of the function. Considering the worst case scenario, we need 4
50 // bytes + the max instruction size + 5 more bytes for our jump back to
51 // the original code. With that in mind, 32 is a good number :)
52 #ifdef _M_X64
53 // In 64-bit mode we may need more room. In 64-bit mode all jumps must be
54 // within +/-2GB of RIP. Because of this limitation we may need to use a
55 // trampoline to jump to the replacement function if it is further than 2GB
56 // away from the target. The trampoline is 14 bytes.
58 // So 4 bytes + max instruction size (17 bytes) + 5 bytes to jump back to the
59 // original code + trampoline size. 64 bytes is a nice number :-)
60 #define MAX_PREAMBLE_STUB_SIZE (64)
61 #else
62 #define MAX_PREAMBLE_STUB_SIZE (32)
63 #endif
65 // Determines if this is a 64-bit binary.
66 #ifdef _M_X64
67 static const bool kIs64BitBinary = true;
68 #else
69 static const bool kIs64BitBinary = false;
70 #endif
72 namespace sidestep {
74 // Possible results of patching/unpatching
75 enum SideStepError {
76 SIDESTEP_SUCCESS = 0,
77 SIDESTEP_INVALID_PARAMETER,
78 SIDESTEP_INSUFFICIENT_BUFFER,
79 SIDESTEP_JUMP_INSTRUCTION,
80 SIDESTEP_FUNCTION_TOO_SMALL,
81 SIDESTEP_UNSUPPORTED_INSTRUCTION,
82 SIDESTEP_NO_SUCH_MODULE,
83 SIDESTEP_NO_SUCH_FUNCTION,
84 SIDESTEP_ACCESS_DENIED,
85 SIDESTEP_UNEXPECTED,
88 #define SIDESTEP_TO_HRESULT(error) \
89 MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, error)
91 class DeleteUnsignedCharArray;
93 // Implements a patching mechanism that overwrites the first few bytes of
94 // a function preamble with a jump to our hook function, which is then
95 // able to call the original function via a specially-made preamble-stub
96 // that imitates the action of the original preamble.
98 // NOTE: This patching mechanism should currently only be used for
99 // non-production code, e.g. unit tests, because it is not threadsafe.
100 // See the TODO in preamble_patcher_with_stub.cc for instructions on what
101 // we need to do before using it in production code; it's fairly simple
102 // but unnecessary for now since we only intend to use it in unit tests.
104 // To patch a function, use either of the typesafe Patch() methods. You
105 // can unpatch a function using Unpatch().
107 // Typical usage goes something like this:
108 // @code
109 // typedef int (*MyTypesafeFuncPtr)(int x);
110 // MyTypesafeFuncPtr original_func_stub;
111 // int MyTypesafeFunc(int x) { return x + 1; }
112 // int HookMyTypesafeFunc(int x) { return 1 + original_func_stub(x); }
114 // void MyPatchInitializingFunction() {
115 // original_func_stub = PreamblePatcher::Patch(
116 // MyTypesafeFunc, HookMyTypesafeFunc);
117 // if (!original_func_stub) {
118 // // ... error handling ...
119 // }
121 // // ... continue - you have patched the function successfully ...
122 // }
123 // @endcode
125 // Note that there are a number of ways that this method of patching can
126 // fail. The most common are:
127 // - If there is a jump (jxx) instruction in the first 5 bytes of
128 // the function being patched, we cannot patch it because in the
129 // current implementation we do not know how to rewrite relative
130 // jumps after relocating them to the preamble-stub. Note that
131 // if you really really need to patch a function like this, it
132 // would be possible to add this functionality (but at some cost).
133 // - If there is a return (ret) instruction in the first 5 bytes
134 // we cannot patch the function because it may not be long enough
135 // for the jmp instruction we use to inject our patch.
136 // - If there is another thread currently executing within the bytes
137 // that are copied to the preamble stub, it will crash in an undefined
138 // way.
140 // If you get any other error than the above, you're either pointing the
141 // patcher at an invalid instruction (e.g. into the middle of a multi-
142 // byte instruction, or not at memory containing executable instructions)
143 // or, there may be a bug in the disassembler we use to find
144 // instruction boundaries.
146 // NOTE: In optimized builds, when you have very trivial functions that
147 // the compiler can reason do not have side effects, the compiler may
148 // reuse the result of calling the function with a given parameter, which
149 // may mean if you patch the function in between your patch will never get
150 // invoked. See preamble_patcher_test.cc for an example.
151 class PERFTOOLS_DLL_DECL PreamblePatcher {
152 public:
154 // This is a typesafe version of RawPatch(), identical in all other
155 // ways than it takes a template parameter indicating the type of the
156 // function being patched.
158 // @param T The type of the function you are patching. Usually
159 // you will establish this type using a typedef, as in the following
160 // example:
161 // @code
162 // typedef BOOL (WINAPI *MessageBoxPtr)(HWND, LPCTSTR, LPCTSTR, UINT);
163 // MessageBoxPtr original = NULL;
164 // PreamblePatcher::Patch(MessageBox, Hook_MessageBox, &original);
165 // @endcode
166 template <class T>
167 static SideStepError Patch(T target_function,
168 T replacement_function,
169 T* original_function_stub) {
170 // NOTE: casting from a function to a pointer is contra the C++
171 // spec. It's not safe on IA64, but is on i386. We use
172 // a C-style cast here to emphasize this is not legal C++.
173 return RawPatch((void*)(target_function),
174 (void*)(replacement_function),
175 (void**)(original_function_stub));
178 // Patches a named function imported from the named module using
179 // preamble patching. Uses RawPatch() to do the actual patching
180 // work.
182 // @param T The type of the function you are patching. Must
183 // exactly match the function you specify using module_name and
184 // function_name.
186 // @param module_name The name of the module from which the function
187 // is being imported. Note that the patch will fail if this module
188 // has not already been loaded into the current process.
190 // @param function_name The name of the function you wish to patch.
192 // @param replacement_function Your replacement function which
193 // will be called whenever code tries to call the original function.
195 // @param original_function_stub Pointer to memory that should receive a
196 // pointer that can be used (e.g. in the replacement function) to call the
197 // original function, or NULL to indicate failure.
199 // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
200 // indicates success.
201 template <class T>
202 static SideStepError Patch(LPCTSTR module_name,
203 LPCSTR function_name,
204 T replacement_function,
205 T* original_function_stub) {
206 SIDESTEP_ASSERT(module_name && function_name);
207 if (!module_name || !function_name) {
208 SIDESTEP_ASSERT(false &&
209 "You must specify a module name and function name.");
210 return SIDESTEP_INVALID_PARAMETER;
212 HMODULE module = ::GetModuleHandle(module_name);
213 SIDESTEP_ASSERT(module != NULL);
214 if (!module) {
215 SIDESTEP_ASSERT(false && "Invalid module name.");
216 return SIDESTEP_NO_SUCH_MODULE;
218 FARPROC existing_function = ::GetProcAddress(module, function_name);
219 if (!existing_function) {
220 SIDESTEP_ASSERT(
221 false && "Did not find any function with that name in the module.");
222 return SIDESTEP_NO_SUCH_FUNCTION;
224 // NOTE: casting from a function to a pointer is contra the C++
225 // spec. It's not safe on IA64, but is on i386. We use
226 // a C-style cast here to emphasize this is not legal C++.
227 return RawPatch((void*)existing_function, (void*)replacement_function,
228 (void**)(original_function_stub));
231 // Patches a function by overwriting its first few bytes with
232 // a jump to a different function. This is the "worker" function
233 // for each of the typesafe Patch() functions. In most cases,
234 // it is preferable to use the Patch() functions rather than
235 // this one as they do more checking at compile time.
237 // @param target_function A pointer to the function that should be
238 // patched.
240 // @param replacement_function A pointer to the function that should
241 // replace the target function. The replacement function must have
242 // exactly the same calling convention and parameters as the original
243 // function.
245 // @param original_function_stub Pointer to memory that should receive a
246 // pointer that can be used (e.g. in the replacement function) to call the
247 // original function, or NULL to indicate failure.
249 // @param original_function_stub Pointer to memory that should receive a
250 // pointer that can be used (e.g. in the replacement function) to call the
251 // original function, or NULL to indicate failure.
253 // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
254 // indicates success.
256 // @note The preamble-stub (the memory pointed to by
257 // *original_function_stub) is allocated on the heap, and (in
258 // production binaries) never destroyed, resulting in a memory leak. This
259 // will be the case until we implement safe unpatching of a method.
260 // However, it is quite difficult to unpatch a method (because other
261 // threads in the process may be using it) so we are leaving it for now.
262 // See however UnsafeUnpatch, which can be used for binaries where you
263 // know only one thread is running, e.g. unit tests.
264 static SideStepError RawPatch(void* target_function,
265 void* replacement_function,
266 void** original_function_stub);
268 // Unpatches target_function and deletes the stub that previously could be
269 // used to call the original version of the function.
271 // DELETES the stub that is passed to the function.
273 // @param target_function Pointer to the target function which was
274 // previously patched, i.e. a pointer which value should match the value
275 // of the symbol prior to patching it.
277 // @param replacement_function Pointer to the function target_function
278 // was patched to.
280 // @param original_function_stub Pointer to the stub returned when
281 // patching, that could be used to call the original version of the
282 // patched function. This function will also delete the stub, which after
283 // unpatching is useless.
285 // If your original call was
286 // Patch(VirtualAlloc, MyVirtualAlloc, &origptr)
287 // then to undo it you would call
288 // Unpatch(VirtualAlloc, MyVirtualAlloc, origptr);
290 // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
291 // indicates success.
292 static SideStepError Unpatch(void* target_function,
293 void* replacement_function,
294 void* original_function_stub);
296 // A helper routine when patching, which follows jmp instructions at
297 // function addresses, to get to the "actual" function contents.
298 // This allows us to identify two functions that are at different
299 // addresses but actually resolve to the same code.
301 // @param target_function Pointer to a function.
303 // @return Either target_function (the input parameter), or if
304 // target_function's body consists entirely of a JMP instruction,
305 // the address it JMPs to (or more precisely, the address at the end
306 // of a chain of JMPs).
307 template <class T>
308 static T ResolveTarget(T target_function) {
309 return (T)ResolveTargetImpl((unsigned char*)target_function, NULL);
312 // Allocates a block of memory of size MAX_PREAMBLE_STUB_SIZE that is as
313 // close (within 2GB) as possible to target. This is done to ensure that
314 // we can perform a relative jump from target to a trampoline if the
315 // replacement function is > +-2GB from target. This means that we only need
316 // to patch 5 bytes in the target function.
318 // @param target Pointer to target function.
320 // @return Returns a block of memory of size MAX_PREAMBLE_STUB_SIZE that can
321 // be used to store a function preamble block.
322 static unsigned char* AllocPreambleBlockNear(void* target);
324 // Frees a block allocated by AllocPreambleBlockNear.
326 // @param block Block that was returned by AllocPreambleBlockNear.
327 static void FreePreambleBlock(unsigned char* block);
329 private:
330 friend class DeleteUnsignedCharArray;
332 // Used to store data allocated for preamble stubs
333 struct PreamblePage {
334 unsigned int magic_;
335 PreamblePage* next_;
336 // This member points to a linked list of free blocks within the page
337 // or NULL if at the end
338 void* free_;
341 // In 64-bit mode, the replacement function must be within 2GB of the original
342 // target in order to only require 5 bytes for the function patch. To meet
343 // this requirement we're creating an allocator within this class to
344 // allocate blocks that are within 2GB of a given target. This member is the
345 // head of a linked list of pages used to allocate blocks that are within
346 // 2GB of the target.
347 static PreamblePage* preamble_pages_;
349 // Page granularity
350 static long granularity_;
352 // Page size
353 static long pagesize_;
355 // Determines if the patcher has been initialized.
356 static bool initialized_;
358 // Used to initialize static members.
359 static void Initialize();
361 // Patches a function by overwriting its first few bytes with
362 // a jump to a different function. This is similar to the RawPatch
363 // function except that it uses the stub allocated by the caller
364 // instead of allocating it.
366 // We call VirtualProtect to make the
367 // target function writable at least for the duration of the call.
369 // @param target_function A pointer to the function that should be
370 // patched.
372 // @param replacement_function A pointer to the function that should
373 // replace the target function. The replacement function must have
374 // exactly the same calling convention and parameters as the original
375 // function.
377 // @param preamble_stub A pointer to a buffer where the preamble stub
378 // should be copied. The size of the buffer should be sufficient to
379 // hold the preamble bytes.
381 // @param stub_size Size in bytes of the buffer allocated for the
382 // preamble_stub
384 // @param bytes_needed Pointer to a variable that receives the minimum
385 // number of bytes required for the stub. Can be set to NULL if you're
386 // not interested.
388 // @return An error code indicating the result of patching.
389 static SideStepError RawPatchWithStubAndProtections(
390 void* target_function,
391 void* replacement_function,
392 unsigned char* preamble_stub,
393 unsigned long stub_size,
394 unsigned long* bytes_needed);
396 // A helper function used by RawPatchWithStubAndProtections -- it
397 // does everything but the VirtualProtect work. Defined in
398 // preamble_patcher_with_stub.cc.
400 // @param target_function A pointer to the function that should be
401 // patched.
403 // @param replacement_function A pointer to the function that should
404 // replace the target function. The replacement function must have
405 // exactly the same calling convention and parameters as the original
406 // function.
408 // @param preamble_stub A pointer to a buffer where the preamble stub
409 // should be copied. The size of the buffer should be sufficient to
410 // hold the preamble bytes.
412 // @param stub_size Size in bytes of the buffer allocated for the
413 // preamble_stub
415 // @param bytes_needed Pointer to a variable that receives the minimum
416 // number of bytes required for the stub. Can be set to NULL if you're
417 // not interested.
419 // @return An error code indicating the result of patching.
420 static SideStepError RawPatchWithStub(void* target_function,
421 void* replacement_function,
422 unsigned char* preamble_stub,
423 unsigned long stub_size,
424 unsigned long* bytes_needed);
427 // A helper routine when patching, which follows jmp instructions at
428 // function addresses, to get to the "actual" function contents.
429 // This allows us to identify two functions that are at different
430 // addresses but actually resolve to the same code.
432 // @param target_function Pointer to a function.
434 // @param stop_before If, when following JMP instructions from
435 // target_function, we get to the address stop, we return
436 // immediately, the address that jumps to stop_before.
438 // @param stop_before_trampoline When following JMP instructions from
439 // target_function, stop before a trampoline is detected. See comment in
440 // PreamblePatcher::RawPatchWithStub for more information. This parameter
441 // has no effect in 32-bit mode.
443 // @return Either target_function (the input parameter), or if
444 // target_function's body consists entirely of a JMP instruction,
445 // the address it JMPs to (or more precisely, the address at the end
446 // of a chain of JMPs).
447 static void* ResolveTargetImpl(unsigned char* target_function,
448 unsigned char* stop_before,
449 bool stop_before_trampoline = false);
451 // Helper routine that attempts to allocate a page as close (within 2GB)
452 // as possible to target.
454 // @param target Pointer to target function.
456 // @return Returns an address that is within 2GB of target.
457 static void* AllocPageNear(void* target);
459 // Helper routine that determines if a target instruction is a short
460 // conditional jump.
462 // @param target Pointer to instruction.
464 // @param instruction_size Size of the instruction in bytes.
466 // @return Returns true if the instruction is a short conditional jump.
467 static bool IsShortConditionalJump(unsigned char* target,
468 unsigned int instruction_size);
470 // Helper routine that determines if a target instruction is a near
471 // conditional jump.
473 // @param target Pointer to instruction.
475 // @param instruction_size Size of the instruction in bytes.
477 // @return Returns true if the instruction is a near conditional jump.
478 static bool IsNearConditionalJump(unsigned char* target,
479 unsigned int instruction_size);
481 // Helper routine that determines if a target instruction is a near
482 // relative jump.
484 // @param target Pointer to instruction.
486 // @param instruction_size Size of the instruction in bytes.
488 // @return Returns true if the instruction is a near absolute jump.
489 static bool IsNearRelativeJump(unsigned char* target,
490 unsigned int instruction_size);
492 // Helper routine that determines if a target instruction is a near
493 // absolute call.
495 // @param target Pointer to instruction.
497 // @param instruction_size Size of the instruction in bytes.
499 // @return Returns true if the instruction is a near absolute call.
500 static bool IsNearAbsoluteCall(unsigned char* target,
501 unsigned int instruction_size);
503 // Helper routine that determines if a target instruction is a near
504 // absolute call.
506 // @param target Pointer to instruction.
508 // @param instruction_size Size of the instruction in bytes.
510 // @return Returns true if the instruction is a near absolute call.
511 static bool IsNearRelativeCall(unsigned char* target,
512 unsigned int instruction_size);
514 // Helper routine that determines if a target instruction is a 64-bit MOV
515 // that uses a RIP-relative displacement.
517 // @param target Pointer to instruction.
519 // @param instruction_size Size of the instruction in bytes.
521 // @return Returns true if the instruction is a MOV with displacement.
522 static bool IsMovWithDisplacement(unsigned char* target,
523 unsigned int instruction_size);
525 // Helper routine that converts a short conditional jump instruction
526 // to a near conditional jump in a target buffer. Note that the target
527 // buffer must be within 2GB of the source for the near jump to work.
529 // A short conditional jump instruction is in the format:
530 // 7x xx = Jcc rel8off
532 // @param source Pointer to instruction.
534 // @param instruction_size Size of the instruction.
536 // @param target Target buffer to write the new instruction.
538 // @param target_bytes Pointer to a buffer that contains the size
539 // of the target instruction, in bytes.
541 // @param target_size Size of the target buffer.
543 // @return Returns SIDESTEP_SUCCESS if successful, otherwise an error.
544 static SideStepError PatchShortConditionalJump(unsigned char* source,
545 unsigned int instruction_size,
546 unsigned char* target,
547 unsigned int* target_bytes,
548 unsigned int target_size);
550 // Helper routine that converts an instruction that will convert various
551 // jump-like instructions to corresponding instructions in the target buffer.
552 // What this routine does is fix up the relative offsets contained in jump
553 // instructions to point back to the original target routine. Like with
554 // PatchShortConditionalJump, the target buffer must be within 2GB of the
555 // source.
557 // We currently handle the following instructions:
559 // E9 xx xx xx xx = JMP rel32off
560 // 0F 8x xx xx xx xx = Jcc rel32off
561 // FF /2 xx xx xx xx = CALL reg/mem32/mem64
562 // E8 xx xx xx xx = CALL rel32off
564 // It should not be hard to update this function to support other
565 // instructions that jump to relative targets.
567 // @param source Pointer to instruction.
569 // @param instruction_size Size of the instruction.
571 // @param target Target buffer to write the new instruction.
573 // @param target_bytes Pointer to a buffer that contains the size
574 // of the target instruction, in bytes.
576 // @param target_size Size of the target buffer.
578 // @return Returns SIDESTEP_SUCCESS if successful, otherwise an error.
579 static SideStepError PatchNearJumpOrCall(unsigned char* source,
580 unsigned int instruction_size,
581 unsigned char* target,
582 unsigned int* target_bytes,
583 unsigned int target_size);
585 // Helper routine that patches a 64-bit MOV instruction with a RIP-relative
586 // displacement. The target buffer must be within 2GB of the source.
588 // 48 8B 0D XX XX XX XX = MOV rel32off
590 // @param source Pointer to instruction.
592 // @param instruction_size Size of the instruction.
594 // @param target Target buffer to write the new instruction.
596 // @param target_bytes Pointer to a buffer that contains the size
597 // of the target instruction, in bytes.
599 // @param target_size Size of the target buffer.
601 // @return Returns SIDESTEP_SUCCESS if successful, otherwise an error.
602 static SideStepError PatchMovWithDisplacement(unsigned char* source,
603 unsigned int instruction_size,
604 unsigned char* target,
605 unsigned int* target_bytes,
606 unsigned int target_size);
609 }; // namespace sidestep
611 #endif // GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_