| 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);
|
| + }
|
| }
|
|
|
|
|
|
|