diff options
author | benchan@chromium.org <benchan@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2011-12-16 16:42:59 +0000 |
---|---|---|
committer | benchan@chromium.org <benchan@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2011-12-16 16:42:59 +0000 |
commit | f044345c23c0324942b7375e7a09558267651523 (patch) | |
tree | 55a0847ef9681e390bad9c97458c352cc1da75ed /src/common/linux/memory_mapped_file.cc | |
parent | Fix ContextDeathTest.X86BadFlags unit test on Mac OS X. (diff) | |
download | breakpad-f044345c23c0324942b7375e7a09558267651523.tar.xz |
Refactor code in preparation of merging with the fork in Chromium OS.
This patch is part of a bigger patch that helps merging the breakpad code
with the modified version in Chromium OS.
Specifically, this patch makes the following changes:
1. Add a MemoryRange class for encapsulating and checking read access
to a contiguous range of memory.
2. Add a MemoryMappedFile class for mapping a file into memory for
read-only access.
3. Refactor other source code to use MemoryMappedFile.
BUG=455
TEST=Tested the following:
1. Build on 32-bit and 64-bit Linux with gcc 4.4.3 and gcc 4.6.
2. Build on Mac OS X 10.6.8 with gcc 4.2 and clang 3.0 (with latest gmock).
3. All unit tests pass.
4. Run minidump-2-core to covnert a minidump file to a core file.
Review URL: http://breakpad.appspot.com/332001
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@895 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/linux/memory_mapped_file.cc')
-rw-r--r-- | src/common/linux/memory_mapped_file.cc | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/common/linux/memory_mapped_file.cc b/src/common/linux/memory_mapped_file.cc new file mode 100644 index 00000000..6f450bd3 --- /dev/null +++ b/src/common/linux/memory_mapped_file.cc @@ -0,0 +1,102 @@ +// Copyright (c) 2011, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// memory_mapped_file.cc: Implement google_breakpad::MemoryMappedFile. +// See memory_mapped_file.h for details. + +#include "common/linux/memory_mapped_file.h" + +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "common/memory_range.h" +#include "third_party/lss/linux_syscall_support.h" + +namespace google_breakpad { + +MemoryMappedFile::MemoryMappedFile() {} + +MemoryMappedFile::MemoryMappedFile(const char* path) { + Map(path); +} + +MemoryMappedFile::~MemoryMappedFile() { + Unmap(); +} + +bool MemoryMappedFile::Map(const char* path) { + Unmap(); + + int fd = sys_open(path, O_RDONLY, 0); + if (fd == -1) { + return false; + } + +#if defined(__x86_64__) + struct kernel_stat st; + if (sys_fstat(fd, &st) == -1 || st.st_size < 0) { +#else + struct kernel_stat64 st; + if (sys_fstat64(fd, &st) == -1 || st.st_size < 0) { +#endif + sys_close(fd); + return false; + } + + // If the file size is zero, simply use an empty MemoryRange and return + // true. Don't bother to call mmap() even though mmap() can handle an + // empty file on some platforms. + if (st.st_size == 0) { + sys_close(fd); + return true; + } + +#if defined(__x86_64__) + void* data = sys_mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); +#else + void* data = sys_mmap2(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); +#endif + sys_close(fd); + if (data == MAP_FAILED) { + return false; + } + + content_.Set(data, st.st_size); + return true; +} + +void MemoryMappedFile::Unmap() { + if (content_.data()) { + sys_munmap(const_cast<u_int8_t*>(content_.data()), content_.length()); + content_.Set(NULL, 0); + } +} + +} // namespace google_breakpad |