1 // Copyright 2013 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 "base/files/memory_mapped_file.h"
6
7 #include <utility>
8
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/sys_info.h"
12 #include "build/build_config.h"
13
14 namespace base {
15
16 const MemoryMappedFile::Region MemoryMappedFile::Region::kWholeFile = {0, 0};
17
operator ==(const MemoryMappedFile::Region & other) const18 bool MemoryMappedFile::Region::operator==(
19 const MemoryMappedFile::Region& other) const {
20 return other.offset == offset && other.size == size;
21 }
22
operator !=(const MemoryMappedFile::Region & other) const23 bool MemoryMappedFile::Region::operator!=(
24 const MemoryMappedFile::Region& other) const {
25 return other.offset != offset || other.size != size;
26 }
27
~MemoryMappedFile()28 MemoryMappedFile::~MemoryMappedFile() {
29 CloseHandles();
30 }
31
32 #if !defined(OS_NACL)
Initialize(const FilePath & file_name)33 bool MemoryMappedFile::Initialize(const FilePath& file_name) {
34 if (IsValid())
35 return false;
36
37 file_.Initialize(file_name, File::FLAG_OPEN | File::FLAG_READ);
38
39 if (!file_.IsValid()) {
40 DLOG(ERROR) << "Couldn't open " << file_name.AsUTF8Unsafe();
41 return false;
42 }
43
44 if (!MapFileRegionToMemory(Region::kWholeFile)) {
45 CloseHandles();
46 return false;
47 }
48
49 return true;
50 }
51
Initialize(File file)52 bool MemoryMappedFile::Initialize(File file) {
53 return Initialize(std::move(file), Region::kWholeFile);
54 }
55
Initialize(File file,const Region & region)56 bool MemoryMappedFile::Initialize(File file, const Region& region) {
57 if (IsValid())
58 return false;
59
60 if (region != Region::kWholeFile) {
61 DCHECK_GE(region.offset, 0);
62 DCHECK_GT(region.size, 0);
63 }
64
65 file_ = std::move(file);
66
67 if (!MapFileRegionToMemory(region)) {
68 CloseHandles();
69 return false;
70 }
71
72 return true;
73 }
74
IsValid() const75 bool MemoryMappedFile::IsValid() const {
76 return data_ != NULL;
77 }
78
79 // static
CalculateVMAlignedBoundaries(int64_t start,int64_t size,int64_t * aligned_start,int64_t * aligned_size,int32_t * offset)80 void MemoryMappedFile::CalculateVMAlignedBoundaries(int64_t start,
81 int64_t size,
82 int64_t* aligned_start,
83 int64_t* aligned_size,
84 int32_t* offset) {
85 // Sadly, on Windows, the mmap alignment is not just equal to the page size.
86 const int64_t mask =
87 static_cast<int64_t>(SysInfo::VMAllocationGranularity()) - 1;
88 DCHECK_LT(mask, std::numeric_limits<int32_t>::max());
89 *offset = start & mask;
90 *aligned_start = start & ~mask;
91 *aligned_size = (size + *offset + mask) & ~mask;
92 }
93 #endif
94
95 } // namespace base
96