OLD | NEW |
1 // Copyright (c) 2010, Google Inc. | 1 // Copyright (c) 2010, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 21 matching lines...) Expand all Loading... |
32 // was originally a complete implementation using the ptrace API, but | 32 // was originally a complete implementation using the ptrace API, but |
33 // has been refactored to allow derived implementations supporting both | 33 // has been refactored to allow derived implementations supporting both |
34 // ptrace and core dump. A portion of the original implementation is now | 34 // ptrace and core dump. A portion of the original implementation is now |
35 // in google_breakpad::LinuxPtraceDumper (see linux_ptrace_dumper.h for | 35 // in google_breakpad::LinuxPtraceDumper (see linux_ptrace_dumper.h for |
36 // details). | 36 // details). |
37 | 37 |
38 #ifndef CLIENT_LINUX_MINIDUMP_WRITER_LINUX_DUMPER_H_ | 38 #ifndef CLIENT_LINUX_MINIDUMP_WRITER_LINUX_DUMPER_H_ |
39 #define CLIENT_LINUX_MINIDUMP_WRITER_LINUX_DUMPER_H_ | 39 #define CLIENT_LINUX_MINIDUMP_WRITER_LINUX_DUMPER_H_ |
40 | 40 |
41 #include <elf.h> | 41 #include <elf.h> |
| 42 #if defined(__ANDROID__) |
| 43 #include <link.h> |
| 44 #endif |
42 #include <linux/limits.h> | 45 #include <linux/limits.h> |
43 #include <stdint.h> | 46 #include <stdint.h> |
44 #include <sys/types.h> | 47 #include <sys/types.h> |
45 #include <sys/user.h> | 48 #include <sys/user.h> |
46 | 49 |
47 #include "client/linux/dump_writer_common/mapping_info.h" | 50 #include "client/linux/dump_writer_common/mapping_info.h" |
48 #include "client/linux/dump_writer_common/thread_info.h" | 51 #include "client/linux/dump_writer_common/thread_info.h" |
49 #include "common/memory.h" | 52 #include "common/memory.h" |
50 #include "google_breakpad/common/minidump_format.h" | 53 #include "google_breakpad/common/minidump_format.h" |
51 | 54 |
(...skipping 17 matching lines...) Expand all Loading... |
69 | 72 |
70 class LinuxDumper { | 73 class LinuxDumper { |
71 public: | 74 public: |
72 explicit LinuxDumper(pid_t pid); | 75 explicit LinuxDumper(pid_t pid); |
73 | 76 |
74 virtual ~LinuxDumper(); | 77 virtual ~LinuxDumper(); |
75 | 78 |
76 // Parse the data for |threads| and |mappings|. | 79 // Parse the data for |threads| and |mappings|. |
77 virtual bool Init(); | 80 virtual bool Init(); |
78 | 81 |
| 82 // Take any actions that could not be taken in Init(). LateInit() is |
| 83 // called after all other caller's initialization is complete, and in |
| 84 // particular after it has called ThreadsSuspend(), so that ptrace is |
| 85 // available. |
| 86 virtual bool LateInit(); |
| 87 |
79 // Return true if the dumper performs a post-mortem dump. | 88 // Return true if the dumper performs a post-mortem dump. |
80 virtual bool IsPostMortem() const = 0; | 89 virtual bool IsPostMortem() const = 0; |
81 | 90 |
82 // Suspend/resume all threads in the given process. | 91 // Suspend/resume all threads in the given process. |
83 virtual bool ThreadsSuspend() = 0; | 92 virtual bool ThreadsSuspend() = 0; |
84 virtual bool ThreadsResume() = 0; | 93 virtual bool ThreadsResume() = 0; |
85 | 94 |
86 // Read information about the |index|-th thread of |threads_|. | 95 // Read information about the |index|-th thread of |threads_|. |
87 // Returns true on success. One must have called |ThreadsSuspend| first. | 96 // Returns true on success. One must have called |ThreadsSuspend| first. |
88 virtual bool GetThreadInfoByIndex(size_t index, ThreadInfo* info) = 0; | 97 virtual bool GetThreadInfoByIndex(size_t index, ThreadInfo* info) = 0; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 mutable PageAllocator allocator_; | 184 mutable PageAllocator allocator_; |
176 | 185 |
177 // IDs of all the threads. | 186 // IDs of all the threads. |
178 wasteful_vector<pid_t> threads_; | 187 wasteful_vector<pid_t> threads_; |
179 | 188 |
180 // Info from /proc/<pid>/maps. | 189 // Info from /proc/<pid>/maps. |
181 wasteful_vector<MappingInfo*> mappings_; | 190 wasteful_vector<MappingInfo*> mappings_; |
182 | 191 |
183 // Info from /proc/<pid>/auxv | 192 // Info from /proc/<pid>/auxv |
184 wasteful_vector<elf_aux_val_t> auxv_; | 193 wasteful_vector<elf_aux_val_t> auxv_; |
| 194 |
| 195 #if defined(__ANDROID__) |
| 196 private: |
| 197 // Android M and later support packed ELF relocations in shared libraries. |
| 198 // Packing relocations changes the vaddr of the LOAD segments, such that |
| 199 // the effective load bias is no longer the same as the start address of |
| 200 // the memory mapping containing the executable parts of the library. The |
| 201 // packing is applied to the stripped library run on the target, but not to |
| 202 // any other library, and in particular not to the library used to generate |
| 203 // breakpad symbols. As a result, we need to adjust the |start_addr| for |
| 204 // any mapping that results from a shared library that contains Android |
| 205 // packed relocations, so that it properly represents the effective library |
| 206 // load bias. The following functions support this adjustment. |
| 207 |
| 208 // Check that a given mapping at |start_addr| is for an ELF shared library. |
| 209 // If it is, place the ELF header in |ehdr| and return true. |
| 210 // The first LOAD segment in an ELF shared library has offset zero, so the |
| 211 // ELF file header is at the start of this map entry, and in already mapped |
| 212 // memory. |
| 213 bool GetLoadedElfHeader(uintptr_t start_addr, ElfW(Ehdr)* ehdr); |
| 214 |
| 215 // For the ELF file mapped at |start_addr|, iterate ELF program headers to |
| 216 // find the min vaddr of all program header LOAD segments, the vaddr for |
| 217 // the DYNAMIC segment, and a count of DYNAMIC entries. Return values in |
| 218 // |min_vaddr_ptr|, |dyn_vaddr_ptr|, and |dyn_count_ptr|. |
| 219 // The program header table is also in already mapped memory. |
| 220 void ParseLoadedElfProgramHeaders(ElfW(Ehdr)* ehdr, |
| 221 uintptr_t start_addr, |
| 222 uintptr_t* min_vaddr_ptr, |
| 223 uintptr_t* dyn_vaddr_ptr, |
| 224 size_t* dyn_count_ptr); |
| 225 |
| 226 // Search the DYNAMIC tags for the ELF file with the given |load_bias|, and |
| 227 // return true if the tags indicate that the file contains Android packed |
| 228 // relocations. Dynamic tags are found at |dyn_vaddr| past the |load_bias|. |
| 229 bool HasAndroidPackedRelocations(uintptr_t load_bias, |
| 230 uintptr_t dyn_vaddr, |
| 231 size_t dyn_count); |
| 232 |
| 233 // If the ELF file mapped at |start_addr| contained Android packed |
| 234 // relocations, return the load bias that the system linker (or Chromium |
| 235 // crazy linker) will have used. If the file did not contain Android |
| 236 // packed relocations, returns |start_addr|, indicating that no adjustment |
| 237 // is necessary. |
| 238 // The effective load bias is |start_addr| adjusted downwards by the |
| 239 // min vaddr in the library LOAD segments. |
| 240 uintptr_t GetEffectiveLoadBias(ElfW(Ehdr)* ehdr, uintptr_t start_addr); |
| 241 |
| 242 // Called from LateInit(). Iterates |mappings_| and rewrites the |start_addr| |
| 243 // field of any that represent ELF shared libraries with Android packed |
| 244 // relocations, so that |start_addr| is the load bias that the system linker |
| 245 // (or Chromium crazy linker) used. This value matches the addresses produced |
| 246 // when the non-relocation-packed library is used for breakpad symbol |
| 247 // generation. |
| 248 void LatePostprocessMappings(); |
| 249 #endif // __ANDROID__ |
185 }; | 250 }; |
186 | 251 |
187 } // namespace google_breakpad | 252 } // namespace google_breakpad |
188 | 253 |
189 #endif // CLIENT_LINUX_HANDLER_LINUX_DUMPER_H_ | 254 #endif // CLIENT_LINUX_HANDLER_LINUX_DUMPER_H_ |
OLD | NEW |