Commit f9a768ed authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

MemoryMappedFile: Implement read-only mode

This way d8 can use a read-only mapping for its input file. Otherwise,
it would require write access for reading the sources.

Bug: v8:8997
Change-Id: I8e117f0a3d9c125ffd1dc1682d5af04b3f6287c2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1530804
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60331}
parent 3cda21de
......@@ -444,15 +444,21 @@ class PosixMemoryMappedFile final : public OS::MemoryMappedFile {
// static
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name,
FileMode mode) {
if (FILE* file = fopen(name, "r+")) {
if (fseek(file, 0, SEEK_END) == 0) {
long size = ftell(file); // NOLINT(runtime/int)
if (size == 0) return new PosixMemoryMappedFile(file, nullptr, 0);
if (size > 0) {
int prot = PROT_READ;
int flags = MAP_PRIVATE;
if (mode == FileMode::kReadWrite) {
prot |= PROT_WRITE;
flags = MAP_SHARED;
}
void* const memory =
mmap(OS::GetRandomMmapAddr(), size, PROT_READ | PROT_WRITE,
MAP_SHARED, fileno(file), 0);
mmap(OS::GetRandomMmapAddr(), size, prot, flags, fileno(file), 0);
if (memory != MAP_FAILED) {
return new PosixMemoryMappedFile(file, memory, size);
}
......@@ -463,7 +469,6 @@ OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
return nullptr;
}
// static
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name,
size_t size, void* initial) {
......
......@@ -973,27 +973,34 @@ class Win32MemoryMappedFile final : public OS::MemoryMappedFile {
// static
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name,
FileMode mode) {
// Open a physical file.
HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_EXISTING, 0, nullptr);
DWORD access = GENERIC_READ;
if (mode == FileMode::kReadWrite) {
access |= GENERIC_WRITE;
}
HANDLE file = CreateFileA(name, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr, OPEN_EXISTING, 0, nullptr);
if (file == INVALID_HANDLE_VALUE) return nullptr;
DWORD size = GetFileSize(file, nullptr);
if (size == 0) return new Win32MemoryMappedFile(file, nullptr, nullptr, 0);
DWORD protection =
(mode == FileMode::kReadOnly) ? PAGE_READONLY : PAGE_READWRITE;
// Create a file mapping for the physical file.
HANDLE file_mapping =
CreateFileMapping(file, nullptr, PAGE_READWRITE, 0, size, nullptr);
CreateFileMapping(file, nullptr, protection, 0, size, nullptr);
if (file_mapping == nullptr) return nullptr;
// Map a view of the file into memory.
void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
DWORD view_access =
(mode == FileMode::kReadOnly) ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS;
void* memory = MapViewOfFile(file_mapping, view_access, 0, 0, size);
return new Win32MemoryMappedFile(file, file_mapping, memory, size);
}
// static
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name,
size_t size, void* initial) {
......
......@@ -188,11 +188,14 @@ class V8_BASE_EXPORT OS {
class V8_BASE_EXPORT MemoryMappedFile {
public:
enum class FileMode { kReadOnly, kReadWrite };
virtual ~MemoryMappedFile() = default;
virtual void* memory() const = 0;
virtual size_t size() const = 0;
static MemoryMappedFile* open(const char* name);
static MemoryMappedFile* open(const char* name,
FileMode mode = FileMode::kReadWrite);
static MemoryMappedFile* create(const char* name, size_t size,
void* initial);
};
......
......@@ -2254,7 +2254,8 @@ void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) {
// Reads a file into a v8 string.
Local<String> Shell::ReadFile(Isolate* isolate, const char* name) {
std::unique_ptr<base::OS::MemoryMappedFile> file(
base::OS::MemoryMappedFile::open(name));
base::OS::MemoryMappedFile::open(
name, base::OS::MemoryMappedFile::FileMode::kReadOnly));
if (!file) return Local<String>();
int size = static_cast<int>(file->size());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment