diff options
author | Alex Vakulenko <avakulenko@google.com> | 2016-01-25 12:28:19 -0800 |
---|---|---|
committer | Alex Vakulenko <avakulenko@google.com> | 2016-01-25 12:54:42 -0800 |
commit | 1ac3a5e3e15a0a3db48c4cb13736ce38033831fe (patch) | |
tree | 024c351584392fb462e4352e4cafeec57e033b0f /base/files | |
parent | 24854748fba09df2a29f0d08d558c3acea70e7a1 (diff) | |
download | libchrome-1ac3a5e3e15a0a3db48c4cb13736ce38033831fe.tar.gz |
libchrome: Add files needed by some veyron variants on Chrome OS
These files are needed for Chrome IPC. These will be compiled on
Chrome OS, so no impact on AOSP.
BUG: 26772882
TEST: make -j32 for dragonboard
./build_packages on CrOS for various boards.
Change-Id: Ibca0a04692a59f245cab2d5c9707cff109ca144f
Diffstat (limited to 'base/files')
-rw-r--r-- | base/files/memory_mapped_file.cc | 95 | ||||
-rw-r--r-- | base/files/memory_mapped_file_posix.cc | 91 |
2 files changed, 186 insertions, 0 deletions
diff --git a/base/files/memory_mapped_file.cc b/base/files/memory_mapped_file.cc new file mode 100644 index 0000000000..0fd9d6796b --- /dev/null +++ b/base/files/memory_mapped_file.cc @@ -0,0 +1,95 @@ +// Copyright 2013 The Chromium 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 "base/files/memory_mapped_file.h" + +#include <utility> + +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/sys_info.h" +#include "build/build_config.h" + +namespace base { + +const MemoryMappedFile::Region MemoryMappedFile::Region::kWholeFile = {0, 0}; + +bool MemoryMappedFile::Region::operator==( + const MemoryMappedFile::Region& other) const { + return other.offset == offset && other.size == size; +} + +bool MemoryMappedFile::Region::operator!=( + const MemoryMappedFile::Region& other) const { + return other.offset != offset || other.size != size; +} + +MemoryMappedFile::~MemoryMappedFile() { + CloseHandles(); +} + +#if !defined(OS_NACL) +bool MemoryMappedFile::Initialize(const FilePath& file_name) { + if (IsValid()) + return false; + + file_.Initialize(file_name, File::FLAG_OPEN | File::FLAG_READ); + + if (!file_.IsValid()) { + DLOG(ERROR) << "Couldn't open " << file_name.AsUTF8Unsafe(); + return false; + } + + if (!MapFileRegionToMemory(Region::kWholeFile)) { + CloseHandles(); + return false; + } + + return true; +} + +bool MemoryMappedFile::Initialize(File file) { + return Initialize(std::move(file), Region::kWholeFile); +} + +bool MemoryMappedFile::Initialize(File file, const Region& region) { + if (IsValid()) + return false; + + if (region != Region::kWholeFile) { + DCHECK_GE(region.offset, 0); + DCHECK_GT(region.size, 0); + } + + file_ = std::move(file); + + if (!MapFileRegionToMemory(region)) { + CloseHandles(); + return false; + } + + return true; +} + +bool MemoryMappedFile::IsValid() const { + return data_ != NULL; +} + +// static +void MemoryMappedFile::CalculateVMAlignedBoundaries(int64_t start, + int64_t size, + int64_t* aligned_start, + int64_t* aligned_size, + int32_t* offset) { + // Sadly, on Windows, the mmap alignment is not just equal to the page size. + const int64_t mask = + static_cast<int64_t>(SysInfo::VMAllocationGranularity()) - 1; + DCHECK_LT(mask, std::numeric_limits<int32_t>::max()); + *offset = start & mask; + *aligned_start = start & ~mask; + *aligned_size = (size + *offset + mask) & ~mask; +} +#endif + +} // namespace base diff --git a/base/files/memory_mapped_file_posix.cc b/base/files/memory_mapped_file_posix.cc new file mode 100644 index 0000000000..1067fdc9ac --- /dev/null +++ b/base/files/memory_mapped_file_posix.cc @@ -0,0 +1,91 @@ +// Copyright 2013 The Chromium 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 "base/files/memory_mapped_file.h" + +#include <stddef.h> +#include <stdint.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "base/logging.h" +#include "base/threading/thread_restrictions.h" +#include "build/build_config.h" + +namespace base { + +MemoryMappedFile::MemoryMappedFile() : data_(NULL), length_(0) { +} + +#if !defined(OS_NACL) +bool MemoryMappedFile::MapFileRegionToMemory( + const MemoryMappedFile::Region& region) { + ThreadRestrictions::AssertIOAllowed(); + + off_t map_start = 0; + size_t map_size = 0; + int32_t data_offset = 0; + + if (region == MemoryMappedFile::Region::kWholeFile) { + int64_t file_len = file_.GetLength(); + if (file_len == -1) { + DPLOG(ERROR) << "fstat " << file_.GetPlatformFile(); + return false; + } + map_size = static_cast<size_t>(file_len); + length_ = map_size; + } else { + // The region can be arbitrarily aligned. mmap, instead, requires both the + // start and size to be page-aligned. Hence, we map here the page-aligned + // outer region [|aligned_start|, |aligned_start| + |size|] which contains + // |region| and then add up the |data_offset| displacement. + int64_t aligned_start = 0; + int64_t aligned_size = 0; + CalculateVMAlignedBoundaries(region.offset, + region.size, + &aligned_start, + &aligned_size, + &data_offset); + + // Ensure that the casts in the mmap call below are sane. + if (aligned_start < 0 || aligned_size < 0 || + aligned_start > std::numeric_limits<off_t>::max() || + static_cast<uint64_t>(aligned_size) > + std::numeric_limits<size_t>::max() || + static_cast<uint64_t>(region.size) > + std::numeric_limits<size_t>::max()) { + DLOG(ERROR) << "Region bounds are not valid for mmap"; + return false; + } + + map_start = static_cast<off_t>(aligned_start); + map_size = static_cast<size_t>(aligned_size); + length_ = static_cast<size_t>(region.size); + } + + data_ = static_cast<uint8_t*>(mmap(NULL, map_size, PROT_READ, MAP_SHARED, + file_.GetPlatformFile(), map_start)); + if (data_ == MAP_FAILED) { + DPLOG(ERROR) << "mmap " << file_.GetPlatformFile(); + return false; + } + + data_ += data_offset; + return true; +} +#endif + +void MemoryMappedFile::CloseHandles() { + ThreadRestrictions::AssertIOAllowed(); + + if (data_ != NULL) + munmap(data_, length_); + file_.Close(); + + data_ = NULL; + length_ = 0; +} + +} // namespace base |