- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / tcmalloc / vendor / src / windows / preamble_patcher.h
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.
17  * 
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.
29  *
30  * ---
31  * Author: Joi Sigurdsson
32  * Author: Scott Francis
33  *
34  * Definition of PreamblePatcher
35  */
36
37 #ifndef GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
38 #define GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_
39
40 #include "config.h"
41 #include <windows.h>
42
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)
47
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.
57 //
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
64
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
71
72 namespace sidestep {
73
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,
86 };
87
88 #define SIDESTEP_TO_HRESULT(error)                      \
89   MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, error)
90
91 class DeleteUnsignedCharArray;
92
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.
97 //
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.
103 //
104 // To patch a function, use either of the typesafe Patch() methods.  You
105 // can unpatch a function using Unpatch().
106 //
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); }
113 // 
114 // void MyPatchInitializingFunction() {
115 //   original_func_stub = PreamblePatcher::Patch(
116 //              MyTypesafeFunc, HookMyTypesafeFunc);
117 //   if (!original_func_stub) {
118 //     // ... error handling ...
119 //   }
120 //
121 //   // ... continue - you have patched the function successfully ...
122 // }
123 // @endcode
124 //
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.
139 //
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.
145 //
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:
153
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.
157   //
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));
176   }
177
178   // Patches a named function imported from the named module using
179   // preamble patching.  Uses RawPatch() to do the actual patching
180   // work.
181   //
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.
185   //
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.
189   //
190   // @param function_name The name of the function you wish to patch.
191   //
192   // @param replacement_function Your replacement function which
193   // will be called whenever code tries to call the original function.
194   //
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.
198   //
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;
211     }
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;
217     }
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;
223     }
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));
229   }
230
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.
236   //
237   // @param target_function A pointer to the function that should be
238   // patched.
239   //
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.
244   //
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.
248   //
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.
252   //
253   // @return One of the EnSideStepError error codes; only SIDESTEP_SUCCESS
254   // indicates success.
255   //
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);
267
268   // Unpatches target_function and deletes the stub that previously could be
269   // used to call the original version of the function.
270   //
271   // DELETES the stub that is passed to the function.
272   //
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.
276   //
277   // @param replacement_function Pointer to the function target_function
278   // was patched to.
279   //
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.
284   //
285   // If your original call was
286   //    Patch(VirtualAlloc, MyVirtualAlloc, &origptr)
287   // then to undo it you would call
288   //    Unpatch(VirtualAlloc, MyVirtualAlloc, origptr);
289   //
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);
295
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.
300   //
301   // @param target_function Pointer to a function.
302   //
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);
310   }
311
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.
317   //
318   // @param target    Pointer to target function.
319   //
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);
323
324   // Frees a block allocated by AllocPreambleBlockNear.
325   //
326   // @param block     Block that was returned by AllocPreambleBlockNear.
327   static void FreePreambleBlock(unsigned char* block);
328
329  private:
330   friend class DeleteUnsignedCharArray;
331
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_;
339   };
340
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_;
348   
349   // Page granularity
350   static long granularity_;
351
352   // Page size
353   static long pagesize_;
354
355   // Determines if the patcher has been initialized.
356   static bool initialized_;
357
358   // Used to initialize static members.
359   static void Initialize();
360
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.
365   //
366   // We call VirtualProtect to make the
367   // target function writable at least for the duration of the call.
368   //
369   // @param target_function A pointer to the function that should be
370   // patched.
371   //
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.
376   //
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.
380   //
381   // @param stub_size Size in bytes of the buffer allocated for the
382   // preamble_stub
383   //
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.
387   //
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);
395
396   // A helper function used by RawPatchWithStubAndProtections -- it
397   // does everything but the VirtualProtect work.  Defined in
398   // preamble_patcher_with_stub.cc.
399   //
400   // @param target_function A pointer to the function that should be
401   // patched.
402   //
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.
407   //
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.
411   //
412   // @param stub_size Size in bytes of the buffer allocated for the
413   // preamble_stub
414   //
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.
418   //
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);
425
426
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.
431   //
432   // @param target_function Pointer to a function.
433   //
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.
437   //
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.
442   //
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);
450
451   // Helper routine that attempts to allocate a page as close (within 2GB)
452   // as possible to target.
453   //
454   // @param target    Pointer to target function.
455   //
456   // @return   Returns an address that is within 2GB of target.
457   static void* AllocPageNear(void* target);
458
459   // Helper routine that determines if a target instruction is a short
460   // conditional jump.
461   //
462   // @param target            Pointer to instruction.
463   //
464   // @param instruction_size  Size of the instruction in bytes.
465   //
466   // @return  Returns true if the instruction is a short conditional jump.
467   static bool IsShortConditionalJump(unsigned char* target,
468                                      unsigned int instruction_size);
469
470   // Helper routine that determines if a target instruction is a near
471   // conditional jump.
472   //
473   // @param target            Pointer to instruction.
474   //
475   // @param instruction_size  Size of the instruction in bytes.
476   //
477   // @return  Returns true if the instruction is a near conditional jump.
478   static bool IsNearConditionalJump(unsigned char* target,
479                                     unsigned int instruction_size);
480
481   // Helper routine that determines if a target instruction is a near
482   // relative jump.
483   //
484   // @param target            Pointer to instruction.
485   //
486   // @param instruction_size  Size of the instruction in bytes.
487   //
488   // @return  Returns true if the instruction is a near absolute jump.
489   static bool IsNearRelativeJump(unsigned char* target,
490                                  unsigned int instruction_size);
491
492   // Helper routine that determines if a target instruction is a near 
493   // absolute call.
494   //
495   // @param target            Pointer to instruction.
496   //
497   // @param instruction_size  Size of the instruction in bytes.
498   //
499   // @return  Returns true if the instruction is a near absolute call.
500   static bool IsNearAbsoluteCall(unsigned char* target,
501                                  unsigned int instruction_size);
502
503   // Helper routine that determines if a target instruction is a near 
504   // absolute call.
505   //
506   // @param target            Pointer to instruction.
507   //
508   // @param instruction_size  Size of the instruction in bytes.
509   //
510   // @return  Returns true if the instruction is a near absolute call.
511   static bool IsNearRelativeCall(unsigned char* target,
512                                  unsigned int instruction_size);
513
514   // Helper routine that determines if a target instruction is a 64-bit MOV
515   // that uses a RIP-relative displacement.
516   //
517   // @param target            Pointer to instruction.
518   //
519   // @param instruction_size  Size of the instruction in bytes.
520   //
521   // @return  Returns true if the instruction is a MOV with displacement.
522   static bool IsMovWithDisplacement(unsigned char* target,
523                                     unsigned int instruction_size);
524
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.
528   //
529   // A short conditional jump instruction is in the format:
530   // 7x xx = Jcc rel8off
531   //
532   // @param source              Pointer to instruction.
533   //
534   // @param instruction_size    Size of the instruction.
535   //
536   // @param target              Target buffer to write the new instruction.
537   //
538   // @param target_bytes        Pointer to a buffer that contains the size
539   //                            of the target instruction, in bytes.
540   //
541   // @param target_size         Size of the target buffer.
542   //
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);
549
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.
556   //
557   // We currently handle the following instructions:
558   //
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
563   //
564   // It should not be hard to update this function to support other
565   // instructions that jump to relative targets.
566   //
567   // @param source              Pointer to instruction.
568   //
569   // @param instruction_size    Size of the instruction.
570   //
571   // @param target              Target buffer to write the new instruction.
572   //
573   // @param target_bytes        Pointer to a buffer that contains the size
574   //                            of the target instruction, in bytes.
575   //
576   // @param target_size         Size of the target buffer.
577   //
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);
584   
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.
587   //
588   // 48 8B 0D XX XX XX XX = MOV rel32off
589   //
590   // @param source              Pointer to instruction.
591   //
592   // @param instruction_size    Size of the instruction.
593   //
594   // @param target              Target buffer to write the new instruction.
595   //
596   // @param target_bytes        Pointer to a buffer that contains the size
597   //                            of the target instruction, in bytes.
598   //
599   // @param target_size         Size of the target buffer.
600   //
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);
607 };
608
609 };  // namespace sidestep
610
611 #endif  // GOOGLE_PERFTOOLS_PREAMBLE_PATCHER_H_