blob: fadf967c313e4a3839b2bb7501697c3eefa0d921 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "reference_drivers/memfd_memory.h"
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <utility>
#include "third_party/abseil-cpp/absl/base/macros.h"
namespace ipcz::reference_drivers {
MemfdMemory::Mapping::Mapping() = default;
MemfdMemory::Mapping::Mapping(void* base_address, size_t size)
: base_address_(base_address), size_(size) {}
MemfdMemory::Mapping::Mapping(Mapping&& other)
: base_address_(std::exchange(other.base_address_, nullptr)),
size_(std::exchange(other.size_, 0)) {}
MemfdMemory::Mapping& MemfdMemory::Mapping::operator=(Mapping&& other) {
Reset();
base_address_ = std::exchange(other.base_address_, nullptr);
size_ = std::exchange(other.size_, 0);
return *this;
}
MemfdMemory::Mapping::~Mapping() {
Reset();
}
void MemfdMemory::Mapping::Reset() {
if (base_address_) {
munmap(base_address_, size_);
base_address_ = nullptr;
size_ = 0;
}
}
MemfdMemory::MemfdMemory() = default;
MemfdMemory::MemfdMemory(FileDescriptor fd, size_t size)
: fd_(std::move(fd)), size_(size) {}
MemfdMemory::MemfdMemory(size_t size) {
int fd = memfd_create("/ipcz/mem", MFD_ALLOW_SEALING);
ABSL_ASSERT(fd >= 0);
int result = ftruncate(fd, size);
ABSL_ASSERT(result == 0);
result = fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK);
ABSL_ASSERT(result == 0);
fd_ = FileDescriptor(fd);
size_ = size;
}
MemfdMemory::MemfdMemory(MemfdMemory&&) = default;
MemfdMemory& MemfdMemory::operator=(MemfdMemory&&) = default;
MemfdMemory::~MemfdMemory() = default;
MemfdMemory MemfdMemory::Clone() {
ABSL_ASSERT(is_valid());
return MemfdMemory(fd_.Clone(), size_);
}
MemfdMemory::Mapping MemfdMemory::Map() {
ABSL_ASSERT(is_valid());
void* addr =
mmap(nullptr, size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_.get(), 0);
ABSL_ASSERT(addr && addr != MAP_FAILED);
return Mapping(addr, size_);
}
} // namespace ipcz::reference_drivers