blob: 67890d68855cb810a086da788d2f046f78240d25 [file] [log] [blame]
[email protected]c3088cb2013-02-24 21:55:451// 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
dcheng9dfa1232015-12-15 05:11:177#include <utility>
8
[email protected]06b66502013-02-27 03:01:139#include "base/files/file_path.h"
[email protected]c3088cb2013-02-24 21:55:4510#include "base/logging.h"
[email protected]3fa9ff82014-07-28 17:57:4011#include "base/sys_info.h"
avi543540e2015-12-24 05:15:3212#include "build/build_config.h"
[email protected]c3088cb2013-02-24 21:55:4513
14namespace base {
15
agrievefd2d44ab2015-06-19 04:33:0316const MemoryMappedFile::Region MemoryMappedFile::Region::kWholeFile = {0, 0};
[email protected]3fa9ff82014-07-28 17:57:4017
18bool MemoryMappedFile::Region::operator==(
19 const MemoryMappedFile::Region& other) const {
20 return other.offset == offset && other.size == size;
21}
22
agrieve0f9183132015-06-03 13:41:5323bool MemoryMappedFile::Region::operator!=(
24 const MemoryMappedFile::Region& other) const {
25 return other.offset != offset || other.size != size;
26}
27
[email protected]c3088cb2013-02-24 21:55:4528MemoryMappedFile::~MemoryMappedFile() {
29 CloseHandles();
30}
31
mkosiba3c766cc2015-01-09 13:10:2232#if !defined(OS_NACL)
bcwhitef0dfab02016-05-19 21:18:3333bool MemoryMappedFile::Initialize(const FilePath& file_name, Access access) {
[email protected]c3088cb2013-02-24 21:55:4534 if (IsValid())
35 return false;
36
bcwhitef0dfab02016-05-19 21:18:3337 uint32_t flags = 0;
38 switch (access) {
39 case READ_ONLY:
40 flags = File::FLAG_OPEN | File::FLAG_READ;
41 break;
42 case READ_WRITE:
43 flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE;
44 break;
45 case READ_WRITE_EXTEND:
46 // Can't open with "extend" because no maximum size is known.
47 NOTREACHED();
48 }
49 file_.Initialize(file_name, flags);
[email protected]58ba3ea2014-01-03 22:14:1550
51 if (!file_.IsValid()) {
52 DLOG(ERROR) << "Couldn't open " << file_name.AsUTF8Unsafe();
53 return false;
54 }
55
bcwhitef0dfab02016-05-19 21:18:3356 if (!MapFileRegionToMemory(Region::kWholeFile, access)) {
[email protected]c3088cb2013-02-24 21:55:4557 CloseHandles();
58 return false;
59 }
60
61 return true;
62}
63
bcwhitef0dfab02016-05-19 21:18:3364bool MemoryMappedFile::Initialize(File file, Access access) {
65 DCHECK_NE(READ_WRITE_EXTEND, access);
66 return Initialize(std::move(file), Region::kWholeFile, access);
[email protected]3fa9ff82014-07-28 17:57:4067}
68
bcwhitef0dfab02016-05-19 21:18:3369bool MemoryMappedFile::Initialize(File file,
70 const Region& region,
71 Access access) {
72 switch (access) {
73 case READ_WRITE_EXTEND:
74 // Ensure that the extended size is within limits of File.
75 if (region.size > std::numeric_limits<int64_t>::max() - region.offset) {
76 DLOG(ERROR) << "Region bounds exceed maximum for base::File.";
77 return false;
78 }
79 // Fall through.
80 case READ_ONLY:
81 case READ_WRITE:
82 // Ensure that the region values are valid.
83 if (region.offset < 0 || region.size < 0) {
84 DLOG(ERROR) << "Region bounds are not valid.";
85 return false;
86 }
87 break;
88 }
89
[email protected]c3088cb2013-02-24 21:55:4590 if (IsValid())
91 return false;
92
agrieve0f9183132015-06-03 13:41:5393 if (region != Region::kWholeFile) {
94 DCHECK_GE(region.offset, 0);
95 DCHECK_GT(region.size, 0);
96 }
97
dcheng9dfa1232015-12-15 05:11:1798 file_ = std::move(file);
[email protected]c3088cb2013-02-24 21:55:4599
bcwhitef0dfab02016-05-19 21:18:33100 if (!MapFileRegionToMemory(region, access)) {
[email protected]c3088cb2013-02-24 21:55:45101 CloseHandles();
102 return false;
103 }
104
105 return true;
106}
107
108bool MemoryMappedFile::IsValid() const {
109 return data_ != NULL;
110}
111
[email protected]3fa9ff82014-07-28 17:57:40112// static
avid0181f32015-12-10 19:41:47113void MemoryMappedFile::CalculateVMAlignedBoundaries(int64_t start,
114 int64_t size,
115 int64_t* aligned_start,
116 int64_t* aligned_size,
117 int32_t* offset) {
[email protected]3fa9ff82014-07-28 17:57:40118 // Sadly, on Windows, the mmap alignment is not just equal to the page size.
avid0181f32015-12-10 19:41:47119 const int64_t mask =
120 static_cast<int64_t>(SysInfo::VMAllocationGranularity()) - 1;
121 DCHECK_LT(mask, std::numeric_limits<int32_t>::max());
[email protected]3fa9ff82014-07-28 17:57:40122 *offset = start & mask;
123 *aligned_start = start & ~mask;
124 *aligned_size = (size + *offset + mask) & ~mask;
125}
mkosiba3c766cc2015-01-09 13:10:22126#endif
[email protected]3fa9ff82014-07-28 17:57:40127
[email protected]c3088cb2013-02-24 21:55:45128} // namespace base