Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: client/linux/minidump_writer/linux_dumper.h

Issue 1189823002: Update breakpad for Android packed relocations. (Closed) Base URL: https://chromium.googlesource.com/external/google-breakpad/src.git@master
Patch Set: Update for more review comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « client/linux/microdump_writer/microdump_writer.cc ('k') | client/linux/minidump_writer/linux_dumper.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « client/linux/microdump_writer/microdump_writer.cc ('k') | client/linux/minidump_writer/linux_dumper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698