1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4// Class for patching compiled code.
5
6#ifndef RUNTIME_VM_CODE_PATCHER_H_
7#define RUNTIME_VM_CODE_PATCHER_H_
8
9#include "vm/allocation.h"
10#include "vm/native_entry.h"
11
12namespace dart {
13
14// Forward declaration.
15class Code;
16class ICData;
17
18#if defined(TARGET_ARCH_IA32)
19// Stack-allocated class to create a scope where the specified region
20// [address, address + size] has write access enabled. This is used
21// when patching generated code. Access is reset to read-execute in
22// the destructor of this scope.
23// Dual mapping of instructions pages is not supported on these target arch.
24class WritableInstructionsScope : public ValueObject {
25 public:
26 WritableInstructionsScope(uword address, intptr_t size);
27 ~WritableInstructionsScope();
28
29 private:
30 const uword address_;
31 const intptr_t size_;
32};
33#endif // defined(TARGET_ARCH_IA32)
34
35class CodePatcher : public AllStatic {
36 public:
37 // Dart static calls have a distinct, machine-dependent code pattern.
38
39 // Patch static call before return_address in given code to the new target.
40 static void PatchStaticCallAt(uword return_address,
41 const Code& code,
42 const Code& new_target);
43
44 // Return the target address of the static call before return_address
45 // in given code.
46 static CodePtr GetStaticCallTargetAt(uword return_address, const Code& code);
47
48 // Get instance call information. Returns the call target and sets the output
49 // parameter data if non-NULL.
50 static CodePtr GetInstanceCallAt(uword return_address,
51 const Code& caller_code,
52 Object* data);
53
54 // Change the state of an instance call by patching the corresponding object
55 // pool entries (non-IA32) or instructions (IA32).
56 static void PatchInstanceCallAt(uword return_address,
57 const Code& caller_code,
58 const Object& data,
59 const Code& target);
60 static void PatchInstanceCallAtWithMutatorsStopped(Thread* thread,
61 uword return_address,
62 const Code& caller_code,
63 const Object& data,
64 const Code& target);
65
66 // Return target of an unoptimized static call and its ICData object
67 // (calls target via a stub).
68 static FunctionPtr GetUnoptimizedStaticCallAt(uword return_address,
69 const Code& code,
70 ICData* ic_data);
71
72 static void InsertDeoptimizationCallAt(uword start);
73
74 static void PatchPoolPointerCallAt(uword return_address,
75 const Code& code,
76 const Code& new_target);
77
78 static void PatchSwitchableCallAt(uword return_address,
79 const Code& caller_code,
80 const Object& data,
81 const Code& target);
82 static void PatchSwitchableCallAtWithMutatorsStopped(Thread* thread,
83 uword return_address,
84 const Code& caller_code,
85 const Object& data,
86 const Code& target);
87 static ObjectPtr GetSwitchableCallDataAt(uword return_address,
88 const Code& caller_code);
89 static CodePtr GetSwitchableCallTargetAt(uword return_address,
90 const Code& caller_code);
91
92 static CodePtr GetNativeCallAt(uword return_address,
93 const Code& caller_code,
94 NativeFunction* target);
95
96 static void PatchNativeCallAt(uword return_address,
97 const Code& caller_code,
98 NativeFunction target,
99 const Code& trampoline);
100
101 static intptr_t GetSubtypeTestCachePoolIndex(uword return_address);
102};
103
104// Beginning from [end - size] we compare [size] bytes with [pattern]. All
105// [0..255] values in [pattern] have to match, negative values are skipped.
106//
107// Example pattern: `[0x3d, 0x8b, -1, -1]`.
108bool MatchesPattern(uword end, const int16_t* pattern, intptr_t size);
109
110class KBCPatcher : public AllStatic {
111 public:
112 static NativeFunctionWrapper GetNativeCallAt(uword return_address,
113 const Bytecode& bytecode,
114 NativeFunction* function);
115
116 static void PatchNativeCallAt(uword return_address,
117 const Bytecode& bytecode,
118 NativeFunction function,
119 NativeFunctionWrapper trampoline);
120};
121
122} // namespace dart
123
124#endif // RUNTIME_VM_CODE_PATCHER_H_
125