From c9c33d9db3c84646232ff23e51a4069dd5e92044 Mon Sep 17 00:00:00 2001 From: Ryan Macnak Date: Wed, 19 Oct 2016 16:36:01 -0700 Subject: [PATCH] Implement File::Map on Windows. R=zra@google.com Review URL: https://codereview.chromium.org/2430473002 . --- runtime/bin/file_win.cc | 40 +++++++++++++++++++++++++++++++++++++--- runtime/bin/main.cc | 26 ++++++++++++++++---------- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc index 28788430ea6..d1e771948cf 100644 --- a/runtime/bin/file_win.cc +++ b/runtime/bin/file_win.cc @@ -74,9 +74,43 @@ bool File::IsClosed() { } -void* File::Map(MapType type, int64_t position, int64_t length) { - UNIMPLEMENTED(); - return NULL; +void* File::Map(File::MapType type, int64_t position, int64_t length) { + DWORD prot_alloc; + DWORD prot_final; + switch (type) { + case File::kReadOnly: + prot_alloc = PAGE_READWRITE; + prot_final = PAGE_READONLY; + break; + case File::kReadExecute: + prot_alloc = PAGE_EXECUTE_READWRITE; + prot_final = PAGE_EXECUTE_READ; + break; + default: + return NULL; + } + + void* addr = VirtualAlloc(NULL, length, MEM_COMMIT | MEM_RESERVE, prot_alloc); + if (addr == NULL) { + Log::PrintErr("VirtualAlloc failed %d\n", GetLastError()); + return NULL; + } + + SetPosition(position); + if (!ReadFully(addr, length)) { + Log::PrintErr("ReadFully failed %d\n", GetLastError()); + VirtualFree(addr, 0, MEM_RELEASE); + return NULL; + } + + DWORD old_prot; + bool result = VirtualProtect(addr, length, prot_final, &old_prot); + if (!result) { + Log::PrintErr("VirtualProtect failed %d\n", GetLastError()); + VirtualFree(addr, 0, MEM_RELEASE); + return NULL; + } + return addr; } diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc index d95a6073a25..f233837dfbb 100644 --- a/runtime/bin/main.cc +++ b/runtime/bin/main.cc @@ -1241,7 +1241,8 @@ static bool ReadAppSnapshotBlobs(const char* script_name, file->Map(File::kReadOnly, vmisolate_position, instructions_position - vmisolate_position); if (read_only_buffer == NULL) { - ErrorExit(kErrorExitCode, "Failed to memory map snapshot\n"); + Log::PrintErr("Failed to memory map snapshot\n"); + Platform::Exit(kErrorExitCode); } *vmisolate_buffer = reinterpret_cast(read_only_buffer) @@ -1261,7 +1262,8 @@ static bool ReadAppSnapshotBlobs(const char* script_name, *instructions_buffer = reinterpret_cast( file->Map(File::kReadExecute, instructions_position, header[4])); if (*instructions_buffer == NULL) { - ErrorExit(kErrorExitCode, "Failed to memory map snapshot2\n"); + Log::PrintErr("Failed to memory map snapshot\n"); + Platform::Exit(kErrorExitCode); } } @@ -1283,29 +1285,33 @@ static bool ReadAppSnapshotDynamicLibrary(const char* script_name, *vmisolate_buffer = reinterpret_cast( Extensions::ResolveSymbol(library, kPrecompiledVMIsolateSymbolName)); if (*vmisolate_buffer == NULL) { - ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n", - kPrecompiledVMIsolateSymbolName); + Log::PrintErr("Failed to resolve symbol '%s'\n", + kPrecompiledVMIsolateSymbolName); + Platform::Exit(kErrorExitCode); } *isolate_buffer = reinterpret_cast( Extensions::ResolveSymbol(library, kPrecompiledIsolateSymbolName)); if (*isolate_buffer == NULL) { - ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n", - kPrecompiledIsolateSymbolName); + Log::PrintErr("Failed to resolve symbol '%s'\n", + kPrecompiledIsolateSymbolName); + Platform::Exit(kErrorExitCode); } *instructions_buffer = reinterpret_cast( Extensions::ResolveSymbol(library, kPrecompiledInstructionsSymbolName)); if (*instructions_buffer == NULL) { - ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n", - kPrecompiledInstructionsSymbolName); + Log::PrintErr("Failed to resolve symbol '%s'\n", + kPrecompiledInstructionsSymbolName); + Platform::Exit(kErrorExitCode); } *rodata_buffer = reinterpret_cast( Extensions::ResolveSymbol(library, kPrecompiledDataSymbolName)); if (*rodata_buffer == NULL) { - ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n", - kPrecompiledDataSymbolName); + Log::PrintErr("Failed to resolve symbol '%s'\n", + kPrecompiledDataSymbolName); + Platform::Exit(kErrorExitCode); } return true;