Index: client/linux/minidump_writer/linux_dumper.h |
diff --git a/client/linux/minidump_writer/linux_dumper.h b/client/linux/minidump_writer/linux_dumper.h |
index 87dfadb4fda85b88c964007af58dfc1be1f94d06..6a3a100f32376e125490a64376c7318a76c4486f 100644 |
--- a/client/linux/minidump_writer/linux_dumper.h |
+++ b/client/linux/minidump_writer/linux_dumper.h |
@@ -39,6 +39,9 @@ |
#define CLIENT_LINUX_MINIDUMP_WRITER_LINUX_DUMPER_H_ |
#include <elf.h> |
+#if defined(__ANDROID__) |
+#include <link.h> |
+#endif |
#include <linux/limits.h> |
#include <stdint.h> |
#include <sys/types.h> |
@@ -76,6 +79,12 @@ class LinuxDumper { |
// Parse the data for |threads| and |mappings|. |
virtual bool Init(); |
+ // Take any actions that could not be taken in Init(). LateInit() is |
+ // called after all other caller's initialization is complete, and in |
+ // particular after it has called ThreadsSuspend(), so that ptrace is |
+ // available. |
+ virtual bool LateInit(); |
+ |
// Return true if the dumper performs a post-mortem dump. |
virtual bool IsPostMortem() const = 0; |
@@ -182,6 +191,62 @@ class LinuxDumper { |
// Info from /proc/<pid>/auxv |
wasteful_vector<elf_aux_val_t> auxv_; |
+ |
+#if defined(__ANDROID__) |
+ private: |
+ // Android M and later support packed ELF relocations in shared libraries. |
+ // Packing relocations changes the vaddr of the LOAD segments, such that |
+ // the effective load bias is no longer the same as the start address of |
+ // the memory mapping containing the executable parts of the library. The |
+ // packing is applied to the stripped library run on the target, but not to |
+ // any other library, and in particular not to the library used to generate |
+ // breakpad symbols. As a result, we need to adjust the |start_addr| for |
+ // any mapping that results from a shared library that contains Android |
+ // packed relocations, so that it properly represents the effective library |
+ // load bias. The following functions support this adjustment. |
+ |
+ // Check that a given mapping at |start_addr| is for an ELF shared library. |
+ // If it is, place the ELF header in |ehdr| and return true. |
+ // The first LOAD segment in an ELF shared library has offset zero, so the |
+ // ELF file header is at the start of this map entry, and in already mapped |
+ // memory. |
+ bool GetLoadedElfHeader(uintptr_t start_addr, ElfW(Ehdr)* ehdr); |
+ |
+ // For the ELF file mapped at |start_addr|, iterate ELF program headers to |
+ // find the min vaddr of all program header LOAD segments, the vaddr for |
+ // the DYNAMIC segment, and a count of DYNAMIC entries. Return values in |
+ // |min_vaddr_ptr|, |dyn_vaddr_ptr|, and |dyn_count_ptr|. |
+ // The program header table is also in already mapped memory. |
+ void ParseLoadedElfProgramHeaders(ElfW(Ehdr)* ehdr, |
+ uintptr_t start_addr, |
+ uintptr_t* min_vaddr_ptr, |
+ uintptr_t* dyn_vaddr_ptr, |
+ size_t* dyn_count_ptr); |
+ |
+ // Search the DYNAMIC tags for the ELF file with the given |load_bias|, and |
+ // return true if the tags indicate that the file contains Android packed |
+ // relocations. Dynamic tags are found at |dyn_vaddr| past the |load_bias|. |
+ bool HasAndroidPackedRelocations(uintptr_t load_bias, |
+ uintptr_t dyn_vaddr, |
+ size_t dyn_count); |
+ |
+ // If the ELF file mapped at |start_addr| contained Android packed |
+ // relocations, return the load bias that the system linker (or Chromium |
+ // crazy linker) will have used. If the file did not contain Android |
+ // packed relocations, returns |start_addr|, indicating that no adjustment |
+ // is necessary. |
+ // The effective load bias is |start_addr| adjusted downwards by the |
+ // min vaddr in the library LOAD segments. |
+ uintptr_t GetEffectiveLoadBias(ElfW(Ehdr)* ehdr, uintptr_t start_addr); |
+ |
+ // Called from LateInit(). Iterates |mappings_| and rewrites the |start_addr| |
+ // field of any that represent ELF shared libraries with Android packed |
+ // relocations, so that |start_addr| is the load bias that the system linker |
+ // (or Chromium crazy linker) used. This value matches the addresses produced |
+ // when the non-relocation-packed library is used for breakpad symbol |
+ // generation. |
+ void LatePostprocessMappings(); |
+#endif // __ANDROID__ |
}; |
} // namespace google_breakpad |