• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "mojo/core/platform_shared_memory_mapping.h"
6 
7 #include <utility>
8 
9 #include "base/logging.h"
10 #include "base/memory/read_only_shared_memory_region.h"
11 #include "base/memory/unsafe_shared_memory_region.h"
12 #include "base/memory/writable_shared_memory_region.h"
13 #include "base/sys_info.h"
14 #include "build/build_config.h"
15 
16 #if defined(OS_NACL)
17 // For getpagesize() on NaCl.
18 #include <unistd.h>
19 #endif
20 
21 namespace mojo {
22 namespace core {
23 
24 namespace {
25 
GetPageSize()26 size_t GetPageSize() {
27 #if defined(OS_NACL)
28   // base::SysInfo isn't available under NaCl.
29   return getpagesize();
30 #else
31   return base::SysInfo::VMAllocationGranularity();
32 #endif
33 }
34 
35 }  // namespace
36 
PlatformSharedMemoryMapping(base::subtle::PlatformSharedMemoryRegion * region,size_t offset,size_t length)37 PlatformSharedMemoryMapping::PlatformSharedMemoryMapping(
38     base::subtle::PlatformSharedMemoryRegion* region,
39     size_t offset,
40     size_t length)
41     : type_(region->GetMode() ==
42                     base::subtle::PlatformSharedMemoryRegion::Mode::kReadOnly
43                 ? Type::kReadOnly
44                 : Type::kWritable),
45       offset_(offset),
46       length_(length) {
47   // Mojo shared buffers can be mapped at any offset, but //base shared memory
48   // regions must be mapped at a page boundary. We calculate the nearest whole
49   // page offset and map from there.
50   size_t offset_rounding = offset_ % GetPageSize();
51   off_t real_offset = static_cast<off_t>(offset_ - offset_rounding);
52   size_t real_length = length_ + offset_rounding;
53   void* mapped_memory = nullptr;
54   if (type_ == Type::kReadOnly) {
55     auto read_only_region =
56         base::ReadOnlySharedMemoryRegion::Deserialize(std::move(*region));
57     auto read_only_mapping = read_only_region.MapAt(real_offset, real_length);
58     mapped_memory = const_cast<void*>(read_only_mapping.memory());
59     mapping_ = std::make_unique<base::ReadOnlySharedMemoryMapping>(
60         std::move(read_only_mapping));
61     *region = base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
62         std::move(read_only_region));
63   } else if (region->GetMode() ==
64              base::subtle::PlatformSharedMemoryRegion::Mode::kUnsafe) {
65     auto unsafe_region =
66         base::UnsafeSharedMemoryRegion::Deserialize(std::move(*region));
67     auto writable_mapping = unsafe_region.MapAt(real_offset, real_length);
68     mapped_memory = writable_mapping.memory();
69     mapping_ = std::make_unique<base::WritableSharedMemoryMapping>(
70         std::move(writable_mapping));
71     *region = base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
72         std::move(unsafe_region));
73   } else {
74     DCHECK_EQ(region->GetMode(),
75               base::subtle::PlatformSharedMemoryRegion::Mode::kWritable);
76     auto writable_region =
77         base::WritableSharedMemoryRegion::Deserialize(std::move(*region));
78     auto writable_mapping = writable_region.MapAt(real_offset, real_length);
79     mapped_memory = writable_mapping.memory();
80     mapping_ = std::make_unique<base::WritableSharedMemoryMapping>(
81         std::move(writable_mapping));
82     *region = base::WritableSharedMemoryRegion::TakeHandleForSerialization(
83         std::move(writable_region));
84   }
85 
86   base_ = static_cast<char*>(mapped_memory) + offset_rounding;
87 }
88 
89 PlatformSharedMemoryMapping::~PlatformSharedMemoryMapping() = default;
90 
IsValid() const91 bool PlatformSharedMemoryMapping::IsValid() const {
92   return mapping_ && mapping_->IsValid();
93 }
94 
GetBase() const95 void* PlatformSharedMemoryMapping::GetBase() const {
96   return base_;
97 }
98 
GetLength() const99 size_t PlatformSharedMemoryMapping::GetLength() const {
100   return length_;
101 }
102 
103 }  // namespace core
104 }  // namespace mojo
105