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...) 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 #include <link.h> |
42 #include <linux/limits.h> | 43 #include <linux/limits.h> |
43 #include <stdint.h> | 44 #include <stdint.h> |
44 #include <sys/types.h> | 45 #include <sys/types.h> |
45 #include <sys/user.h> | 46 #include <sys/user.h> |
46 | 47 |
47 #include "client/linux/dump_writer_common/mapping_info.h" | 48 #include "client/linux/dump_writer_common/mapping_info.h" |
48 #include "client/linux/dump_writer_common/thread_info.h" | 49 #include "client/linux/dump_writer_common/thread_info.h" |
49 #include "common/memory.h" | 50 #include "common/memory.h" |
50 #include "google_breakpad/common/minidump_format.h" | 51 #include "google_breakpad/common/minidump_format.h" |
51 | 52 |
(...skipping 14 matching lines...) Loading... |
66 // is the name we use for it when writing it to the minidump. | 67 // is the name we use for it when writing it to the minidump. |
67 // This should always be less than NAME_MAX! | 68 // This should always be less than NAME_MAX! |
68 const char kLinuxGateLibraryName[] = "linux-gate.so"; | 69 const char kLinuxGateLibraryName[] = "linux-gate.so"; |
69 | 70 |
70 class LinuxDumper { | 71 class LinuxDumper { |
71 public: | 72 public: |
72 explicit LinuxDumper(pid_t pid); | 73 explicit LinuxDumper(pid_t pid); |
73 | 74 |
74 virtual ~LinuxDumper(); | 75 virtual ~LinuxDumper(); |
75 | 76 |
76 // Parse the data for |threads| and |mappings|. | 77 // Parse the data for |threads| and |mappings|. LateInit() should be |
| 78 // called after all other caller's initialization is complete, and in |
| 79 // particular after it has called ThreadsSuspend(), so that ptrace is |
| 80 // available. |
77 virtual bool Init(); | 81 virtual bool Init(); |
| 82 virtual bool LateInit(); |
78 | 83 |
79 // Return true if the dumper performs a post-mortem dump. | 84 // Return true if the dumper performs a post-mortem dump. |
80 virtual bool IsPostMortem() const = 0; | 85 virtual bool IsPostMortem() const = 0; |
81 | 86 |
82 // Suspend/resume all threads in the given process. | 87 // Suspend/resume all threads in the given process. |
83 virtual bool ThreadsSuspend() = 0; | 88 virtual bool ThreadsSuspend() = 0; |
84 virtual bool ThreadsResume() = 0; | 89 virtual bool ThreadsResume() = 0; |
85 | 90 |
86 // Read information about the |index|-th thread of |threads_|. | 91 // Read information about the |index|-th thread of |threads_|. |
87 // Returns true on success. One must have called |ThreadsSuspend| first. | 92 // Returns true on success. One must have called |ThreadsSuspend| first. |
(...skipping 54 matching lines...) Loading... |
142 char* file_name, | 147 char* file_name, |
143 size_t file_name_size); | 148 size_t file_name_size); |
144 | 149 |
145 protected: | 150 protected: |
146 bool ReadAuxv(); | 151 bool ReadAuxv(); |
147 | 152 |
148 virtual bool EnumerateMappings(); | 153 virtual bool EnumerateMappings(); |
149 | 154 |
150 virtual bool EnumerateThreads() = 0; | 155 virtual bool EnumerateThreads() = 0; |
151 | 156 |
| 157 #if defined(__ANDROID__) |
| 158 // Android M and later support packed ELF relocations in shared libraries. |
| 159 // Packing relocations changes the vaddr of the LOAD segments, such that |
| 160 // the effective load bias is no longer the same as the start address of |
| 161 // the memory mapping containing the executable parts of the library. The |
| 162 // packing is applied to the stripped library run on the target, but not to |
| 163 // any other library, and in particular not to the library used to generate |
| 164 // breakpad symbols. As a result, we need to adjust the start_addr value for |
| 165 // any mapping that results from a shared library that contains Android |
| 166 // packed relocations, so that it properly represents the effective library |
| 167 // load bias. The following functions support this adjustment. |
| 168 |
| 169 // Check that a given mapping at |start_addr| is for an ELF shared library. |
| 170 // If it is, place the ELF header in |ehdr| and return true. |
| 171 virtual bool GetLoadedElfHeader(uintptr_t start_addr, ElfW(Ehdr)* ehdr); |
| 172 |
| 173 // For the ELF file mapped at |start_addr|, find the min vaddr of all |
| 174 // program header LOAD segments, the vaddr for the DYNAMIC segment, and |
| 175 // a count of DYNAMIC entries. Return values in |min_vaddr_ptr|, |
| 176 // |dyn_vaddr_ptr|, and |dyn_count_ptr|. |
| 177 virtual void ParseLoadedElfProgramHeaders(ElfW(Ehdr)* ehdr, |
| 178 uintptr_t start_addr, |
| 179 uintptr_t* min_vaddr_ptr, |
| 180 uintptr_t* dyn_vaddr_ptr, |
| 181 size_t* dyn_count_ptr); |
| 182 |
| 183 // Search the DYNAMIC tags for the ELF file with the given |load_bias|, and |
| 184 // return true if the tags indicate that the file contains Android packed |
| 185 // relocations. |
| 186 virtual bool HasAndroidPackedRelocations(uintptr_t load_bias, |
| 187 uintptr_t dyn_vaddr, |
| 188 size_t dyn_count); |
| 189 |
| 190 // If the ELF file mapped at |start_addr| contained Android packed |
| 191 // relocations, return the load bias that the system linker (or Chromium |
| 192 // crazy linker) will have used. If the file did not contain Android |
| 193 // packed relocations, returns |start_addr|, indicating that no adjustment |
| 194 // is necessary. |
| 195 virtual uintptr_t GetEffectiveLoadBias(ElfW(Ehdr)* ehdr, |
| 196 uintptr_t start_addr); |
| 197 |
| 198 // Called from LateInit(). Iterates mappings_ and rewrites the start_addr |
| 199 // field of any that represent ELF shared libraries with Android packed |
| 200 // relocations, so that start_addr is the load_bias that the system linker |
| 201 // (or Chromium crazy linker) used. This value matches the addresses produced |
| 202 // when the non-relocation-packed library is used for breakpad symbol |
| 203 // generation. |
| 204 virtual bool LatePostprocessMappings(); |
| 205 #endif // __ANDROID__ |
| 206 |
152 // For the case where a running program has been deleted, it'll show up in | 207 // For the case where a running program has been deleted, it'll show up in |
153 // /proc/pid/maps as "/path/to/program (deleted)". If this is the case, then | 208 // /proc/pid/maps as "/path/to/program (deleted)". If this is the case, then |
154 // see if '/path/to/program (deleted)' matches /proc/pid/exe and return | 209 // see if '/path/to/program (deleted)' matches /proc/pid/exe and return |
155 // /proc/pid/exe in |path| so ELF identifier generation works correctly. This | 210 // /proc/pid/exe in |path| so ELF identifier generation works correctly. This |
156 // also checks to see if '/path/to/program (deleted)' exists, so it does not | 211 // also checks to see if '/path/to/program (deleted)' exists, so it does not |
157 // get fooled by a poorly named binary. | 212 // get fooled by a poorly named binary. |
158 // For programs that don't end with ' (deleted)', this is a no-op. | 213 // For programs that don't end with ' (deleted)', this is a no-op. |
159 // This assumes |path| is a buffer with length NAME_MAX. | 214 // This assumes |path| is a buffer with length NAME_MAX. |
160 // Returns true if |path| is modified. | 215 // Returns true if |path| is modified. |
161 bool HandleDeletedFileInMapping(char* path) const; | 216 bool HandleDeletedFileInMapping(char* path) const; |
(...skipping 18 matching lines...) Loading... |
180 // Info from /proc/<pid>/maps. | 235 // Info from /proc/<pid>/maps. |
181 wasteful_vector<MappingInfo*> mappings_; | 236 wasteful_vector<MappingInfo*> mappings_; |
182 | 237 |
183 // Info from /proc/<pid>/auxv | 238 // Info from /proc/<pid>/auxv |
184 wasteful_vector<elf_aux_val_t> auxv_; | 239 wasteful_vector<elf_aux_val_t> auxv_; |
185 }; | 240 }; |
186 | 241 |
187 } // namespace google_breakpad | 242 } // namespace google_breakpad |
188 | 243 |
189 #endif // CLIENT_LINUX_HANDLER_LINUX_DUMPER_H_ | 244 #endif // CLIENT_LINUX_HANDLER_LINUX_DUMPER_H_ |
OLD | NEW |