aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux/memory_mapped_file.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/linux/memory_mapped_file.cc')
-rw-r--r--src/common/linux/memory_mapped_file.cc28
1 files changed, 18 insertions, 10 deletions
diff --git a/src/common/linux/memory_mapped_file.cc b/src/common/linux/memory_mapped_file.cc
index 0f0fcb2b..064326bb 100644
--- a/src/common/linux/memory_mapped_file.cc
+++ b/src/common/linux/memory_mapped_file.cc
@@ -46,15 +46,15 @@ namespace google_breakpad {
MemoryMappedFile::MemoryMappedFile() {}
-MemoryMappedFile::MemoryMappedFile(const char* path) {
- Map(path);
+MemoryMappedFile::MemoryMappedFile(const char* path, size_t offset) {
+ Map(path, offset);
}
MemoryMappedFile::~MemoryMappedFile() {
Unmap();
}
-bool MemoryMappedFile::Map(const char* path) {
+bool MemoryMappedFile::Map(const char* path, size_t offset) {
Unmap();
int fd = sys_open(path, O_RDONLY, 0);
@@ -73,25 +73,33 @@ bool MemoryMappedFile::Map(const char* path) {
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) {
+ // Strangely file size can be negative, but we check above that it is not.
+ size_t file_len = static_cast<size_t>(st.st_size);
+ // If the file does not extend beyond the offset, 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 (offset >= file_len) {
sys_close(fd);
return true;
}
#if defined(__x86_64__) || defined(__aarch64__)
- void* data = sys_mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ void* data = sys_mmap(NULL, file_len, PROT_READ, MAP_PRIVATE, fd, offset);
#else
- void* data = sys_mmap2(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if ((offset & 4095) != 0) {
+ // Not page aligned.
+ sys_close(fd);
+ return false;
+ }
+ void* data = sys_mmap2(
+ NULL, file_len, PROT_READ, MAP_PRIVATE, fd, offset >> 12);
#endif
sys_close(fd);
if (data == MAP_FAILED) {
return false;
}
- content_.Set(data, st.st_size);
+ content_.Set(data, file_len - offset);
return true;
}