| // 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 |