blob: c53e39b346036a499110870782217378851d1507 [file] [log] [blame] [edit]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shared-memory.h"
#include <lib/zx/vmar.h>
#include <zircon/errors.h>
namespace fuzzing {
// These are the flags that the shared memory should be mapped with.
static const zx_vm_option_t kSharedVmOptions =
ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_MAP_RANGE | ZX_VM_REQUIRE_NON_RESIZABLE;
SharedMemory::SharedMemory() : addr_(0), len_(0) {}
SharedMemory::SharedMemory(SharedMemory &&other)
: vmo_(std::move(other.vmo_)), addr_(other.addr_), len_(other.len_) {
other.addr_ = 0;
other.len_ = 0;
}
SharedMemory::~SharedMemory() { Reset(); }
zx_status_t SharedMemory::Create(size_t len) {
if (len == 0) {
return ZX_ERR_INVALID_ARGS;
}
zx::vmo vmo;
zx_status_t status = zx::vmo::create(len, 0, &vmo);
if (status != ZX_OK) {
return status;
}
return Link(vmo, len);
}
zx_status_t SharedMemory::Share(zx::vmo *out) {
if (!out) {
return ZX_ERR_INVALID_ARGS;
}
return vmo_.duplicate(ZX_RIGHT_SAME_RIGHTS, out);
}
zx_status_t SharedMemory::Link(const zx::vmo &vmo, size_t len) {
if (len == 0) {
return ZX_ERR_INVALID_ARGS;
}
Reset();
size_t size;
zx_status_t status = vmo.get_size(&size);
if (status != ZX_OK) {
return status;
}
if (size < len) {
return ZX_ERR_BUFFER_TOO_SMALL;
}
zx::vmo tmp;
status = vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &tmp);
if (status != ZX_OK) {
return status;
}
zx_vaddr_t addr;
status = zx::vmar::root_self()->map(kSharedVmOptions, 0, tmp, 0, size, &addr);
if (status != ZX_OK) {
return status;
}
vmo_ = std::move(tmp);
addr_ = addr;
len_ = len;
return ZX_OK;
}
void SharedMemory::Reset() {
if (addr_ != 0) {
zx::vmar::root_self()->unmap(addr_, len_);
vmo_.reset();
addr_ = 0;
len_ = 0;
}
}
} // namespace fuzzing