SharedMemoryPlatform_android.cpp (4053B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* This source code was derived from Chromium code, and as such is also subject 8 * to the [Chromium license](ipc/chromium/src/LICENSE). */ 9 10 #include "SharedMemoryPlatform.h" 11 12 #include <errno.h> 13 #include <fcntl.h> 14 #include <sys/mman.h> 15 #include <sys/stat.h> 16 #include <unistd.h> 17 18 #include <android/sharedmem.h> 19 20 #ifdef MOZ_VALGRIND 21 # include <valgrind/valgrind.h> 22 #endif 23 24 #include "mozilla/Maybe.h" 25 #include "mozilla/UniquePtrExtensions.h" 26 #include "prenv.h" 27 28 namespace mozilla::ipc::shared_memory { 29 30 // Right now we do nothing different for freezable shared memory on Android. 31 static Maybe<PlatformHandle> CreateImpl(size_t aSize, bool aFreezable) { 32 MOZ_ASSERT(aSize > 0); 33 34 int fd = ASharedMemory_create(nullptr, aSize); 35 if (fd < 0) { 36 MOZ_LOG_FMT(gSharedMemoryLog, LogLevel::Warning, "failed to open shm: {}", 37 strerror(errno)); 38 return Nothing(); 39 } 40 41 return Some(fd); 42 } 43 44 bool AppendPosixShmPrefix(std::string* str, pid_t pid) { return false; } 45 bool UsingPosixShm() { return false; } 46 47 bool Platform::Create(MutableHandle& aHandle, size_t aSize) { 48 if (auto ph = CreateImpl(aSize, false)) { 49 aHandle.mHandle = std::move(*ph); 50 aHandle.SetSize(aSize); 51 return true; 52 } 53 return false; 54 } 55 56 bool Platform::CreateFreezable(FreezableHandle& aHandle, size_t aSize) { 57 if (auto ph = CreateImpl(aSize, true)) { 58 aHandle.mHandle = std::move(*ph); 59 aHandle.SetSize(aSize); 60 return true; 61 } 62 return false; 63 } 64 65 PlatformHandle Platform::CloneHandle(const PlatformHandle& aHandle) { 66 const int new_fd = dup(aHandle.get()); 67 if (new_fd < 0) { 68 MOZ_LOG_FMT(gSharedMemoryLog, LogLevel::Warning, 69 "failed to duplicate file descriptor: {}", strerror(errno)); 70 return nullptr; 71 } 72 return mozilla::UniqueFileHandle(new_fd); 73 } 74 75 bool Platform::Freeze(FreezableHandle& aHandle) { 76 if (ASharedMemory_setProt(aHandle.mHandle.get(), PROT_READ) != 0) { 77 MOZ_LOG_FMT(gSharedMemoryLog, LogLevel::Warning, 78 "failed to set sharedmem read-only: {}", strerror(errno)); 79 return false; 80 } 81 return true; 82 } 83 84 Maybe<void*> Platform::Map(const HandleBase& aHandle, uint64_t aOffset, 85 size_t aSize, void* aFixedAddress, bool aReadOnly) { 86 // Don't use MAP_FIXED when a fixed_address was specified, since that can 87 // replace pages that are alread mapped at that address. 88 void* mem = 89 mmap(aFixedAddress, aSize, PROT_READ | (aReadOnly ? 0 : PROT_WRITE), 90 MAP_SHARED, aHandle.mHandle.get(), aOffset); 91 92 if (mem == MAP_FAILED) { 93 MOZ_LOG_FMT(gSharedMemoryLog, LogLevel::Warning, "call to mmap failed: {}", 94 strerror(errno)); 95 return Nothing(); 96 } 97 98 if (aFixedAddress && mem != aFixedAddress) { 99 DebugOnly<bool> munmap_succeeded = munmap(mem, aSize) == 0; 100 MOZ_ASSERT(munmap_succeeded, "call to munmap failed"); 101 return Nothing(); 102 } 103 104 return Some(mem); 105 } 106 107 void Platform::Unmap(void* aMemory, size_t aSize) { munmap(aMemory, aSize); } 108 109 bool Platform::Protect(char* aAddr, size_t aSize, Access aAccess) { 110 int flags = PROT_NONE; 111 if (aAccess & AccessRead) flags |= PROT_READ; 112 if (aAccess & AccessWrite) flags |= PROT_WRITE; 113 114 return 0 == mprotect(aAddr, aSize, flags); 115 } 116 117 void* Platform::FindFreeAddressSpace(size_t aSize) { 118 void* memory = mmap(nullptr, aSize, PROT_NONE, 119 MAP_ANONYMOUS | MAP_NORESERVE | MAP_PRIVATE, -1, 0); 120 if (memory == MAP_FAILED) { 121 return nullptr; 122 } 123 munmap(memory, aSize); 124 return memory; 125 } 126 127 size_t Platform::PageSize() { return sysconf(_SC_PAGESIZE); } 128 129 size_t Platform::AllocationGranularity() { return PageSize(); } 130 131 bool Platform::IsSafeToMap(const PlatformHandle&) { return true; } 132 133 } // namespace mozilla::ipc::shared_memory