From 561f81873562d407ac1c39144b30e26163e0045d Mon Sep 17 00:00:00 2001 From: "rmcilroy@chromium.org" Date: Tue, 22 Jul 2014 11:34:11 +0000 Subject: Chrome on Android now supports loading the shared library directly from the APK file. This patch makes two changes to breakpad to enable crash reporting to work correctly when the library is inside another file (an archive): - Do not filter mappings which map an executable at a non-zero offset. - If such an executable is mapped look in the ELF information for the shared object name and use that name in the minidump. Note this change doesn't care about the archive format and isn't Android specific (though loading the shared library this way is currently only done on Android). BUG=390618 R=thestig@chromium.org Review URL: https://breakpad.appspot.com/7684002 Patch from Anton Carver . git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1355 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/common/linux/memory_mapped_file.cc | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'src/common/linux/memory_mapped_file.cc') 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(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; } -- cgit v1.2.1