Index: runtime/vm/code_patcher.cc |
diff --git a/runtime/vm/code_patcher.cc b/runtime/vm/code_patcher.cc |
index 6fda035f4047783368cc8dffa9e299c6d09d6b20..8fa4785a686081f05935a747cbe5b5d679b5bc3c 100644 |
--- a/runtime/vm/code_patcher.cc |
+++ b/runtime/vm/code_patcher.cc |
@@ -6,9 +6,30 @@ |
#include "vm/cpu.h" |
#include "vm/instructions.h" |
#include "vm/object.h" |
+#include "vm/virtual_memory.h" |
namespace dart { |
+WritableInstructionsScope::WritableInstructionsScope(uword address, |
+ intptr_t size) |
+ : address_(address), size_(size) { |
+ bool status = |
+ VirtualMemory::Protect(reinterpret_cast<void*>(address), |
+ size, |
+ VirtualMemory::kReadWriteExecute); |
+ ASSERT(status); |
+} |
+ |
+ |
+WritableInstructionsScope::~WritableInstructionsScope() { |
+ bool status = |
+ VirtualMemory::Protect(reinterpret_cast<void*>(address_), |
+ size_, |
+ VirtualMemory::kReadExecute); |
+ ASSERT(status); |
+} |
+ |
+ |
static void SwapCode(intptr_t num_bytes, char* code, char* buffer) { |
uword code_address = reinterpret_cast<uword>(code); |
for (intptr_t i = 0; i < num_bytes; i++) { |
@@ -36,10 +57,15 @@ void CodePatcher::PatchEntry(const Code& code) { |
JumpPattern jmp_patch(patch_buffer, code); |
ASSERT(jmp_patch.IsValid()); |
const uword jump_target = jmp_patch.TargetAddress(); |
- SwapCode(jmp_patch.pattern_length_in_bytes(), |
- reinterpret_cast<char*>(patch_addr), |
- reinterpret_cast<char*>(patch_buffer)); |
- jmp_entry.SetTargetAddress(jump_target); |
+ intptr_t length = jmp_patch.pattern_length_in_bytes(); |
+ { |
+ WritableInstructionsScope writable_code(patch_addr, length); |
+ WritableInstructionsScope writable_buffer(patch_buffer, length); |
+ SwapCode(jmp_patch.pattern_length_in_bytes(), |
+ reinterpret_cast<char*>(patch_addr), |
+ reinterpret_cast<char*>(patch_buffer)); |
+ jmp_entry.SetTargetAddress(jump_target); |
+ } |
} |
@@ -57,11 +83,16 @@ void CodePatcher::RestoreEntry(const Code& code) { |
// 'patch_buffer' contains original entry code. |
JumpPattern jmp_patch(patch_buffer, code); |
ASSERT(!jmp_patch.IsValid()); |
- SwapCode(jmp_patch.pattern_length_in_bytes(), |
- reinterpret_cast<char*>(patch_addr), |
- reinterpret_cast<char*>(patch_buffer)); |
- ASSERT(jmp_patch.IsValid()); |
- jmp_patch.SetTargetAddress(jump_target); |
+ intptr_t length = jmp_patch.pattern_length_in_bytes(); |
+ { |
+ WritableInstructionsScope writable_code(patch_addr, length); |
+ WritableInstructionsScope writable_buffer(patch_buffer, length); |
+ SwapCode(jmp_patch.pattern_length_in_bytes(), |
+ reinterpret_cast<char*>(patch_addr), |
+ reinterpret_cast<char*>(patch_buffer)); |
+ ASSERT(jmp_patch.IsValid()); |
+ jmp_patch.SetTargetAddress(jump_target); |
+ } |
} |