OLD | NEW |
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "snapshot/win/pe_image_reader.h" | 15 #include "snapshot/win/pe_image_reader.h" |
16 | 16 |
17 #include <string.h> | 17 #include <string.h> |
18 | 18 |
19 #include "base/logging.h" | 19 #include "base/logging.h" |
20 #include "base/memory/scoped_ptr.h" | 20 #include "base/memory/scoped_ptr.h" |
21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
22 #include "client/crashpad_info.h" | 22 #include "client/crashpad_info.h" |
23 #include "snapshot/win/process_reader_win.h" | 23 #include "snapshot/win/process_reader_win.h" |
24 #include "util/misc/pdb_structures.h" | 24 #include "util/misc/pdb_structures.h" |
| 25 #include "util/win/process_structs.h" |
25 | 26 |
26 namespace crashpad { | 27 namespace crashpad { |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
30 std::string RangeToString(const CheckedWinAddressRange& range) { | 31 std::string RangeToString(const CheckedWinAddressRange& range) { |
31 return base::StringPrintf("[0x%llx + 0x%llx (%s)]", | 32 return base::StringPrintf("[0x%llx + 0x%llx (%s)]", |
32 range.Base(), | 33 range.Base(), |
33 range.Size(), | 34 range.Size(), |
34 range.Is64Bit() ? "64" : "32"); | 35 range.Is64Bit() ? "64" : "32"); |
(...skipping 23 matching lines...) Expand all Loading... |
58 LOG(WARNING) << "invalid module range for " << module_name << ": " | 59 LOG(WARNING) << "invalid module range for " << module_name << ": " |
59 << RangeToString(module_range_); | 60 << RangeToString(module_range_); |
60 return false; | 61 return false; |
61 } | 62 } |
62 module_name_ = module_name; | 63 module_name_ = module_name; |
63 | 64 |
64 INITIALIZATION_STATE_SET_VALID(initialized_); | 65 INITIALIZATION_STATE_SET_VALID(initialized_); |
65 return true; | 66 return true; |
66 } | 67 } |
67 | 68 |
| 69 template <class Traits> |
68 bool PEImageReader::GetCrashpadInfo( | 70 bool PEImageReader::GetCrashpadInfo( |
69 process_types::CrashpadInfo* crashpad_info) const { | 71 process_types::CrashpadInfo<Traits>* crashpad_info) const { |
70 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 72 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
71 | 73 |
| 74 // TODO(scottmg): This could be simplified as we know what we're reading based |
| 75 // on Traits. |
72 IMAGE_SECTION_HEADER section; | 76 IMAGE_SECTION_HEADER section; |
73 if (process_reader_->Is64Bit()) { | 77 if (process_reader_->Is64Bit()) { |
74 if (!GetSectionByName<IMAGE_NT_HEADERS64>("CPADinfo", §ion)) | 78 if (!GetSectionByName<IMAGE_NT_HEADERS64>("CPADinfo", §ion)) |
75 return false; | 79 return false; |
76 } else { | 80 } else { |
77 if (!GetSectionByName<IMAGE_NT_HEADERS32>("CPADinfo", §ion)) | 81 if (!GetSectionByName<IMAGE_NT_HEADERS32>("CPADinfo", §ion)) |
78 return false; | 82 return false; |
79 } | 83 } |
80 | 84 |
81 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo)) { | 85 if (section.Misc.VirtualSize < sizeof(process_types::CrashpadInfo<Traits>)) { |
82 LOG(WARNING) << "small crashpad info section size " | 86 LOG(WARNING) << "small crashpad info section size " |
83 << section.Misc.VirtualSize << ", " << module_name_; | 87 << section.Misc.VirtualSize << ", " << module_name_; |
84 return false; | 88 return false; |
85 } | 89 } |
86 | 90 |
87 WinVMAddress crashpad_info_address = Address() + section.VirtualAddress; | 91 WinVMAddress crashpad_info_address = Address() + section.VirtualAddress; |
88 CheckedWinAddressRange crashpad_info_range(process_reader_->Is64Bit(), | 92 CheckedWinAddressRange crashpad_info_range(process_reader_->Is64Bit(), |
89 crashpad_info_address, | 93 crashpad_info_address, |
90 section.Misc.VirtualSize); | 94 section.Misc.VirtualSize); |
91 if (!crashpad_info_range.IsValid()) { | 95 if (!crashpad_info_range.IsValid()) { |
92 LOG(WARNING) << "invalid range for crashpad info: " | 96 LOG(WARNING) << "invalid range for crashpad info: " |
93 << RangeToString(crashpad_info_range); | 97 << RangeToString(crashpad_info_range); |
94 return false; | 98 return false; |
95 } | 99 } |
96 | 100 |
97 if (!module_range_.ContainsRange(crashpad_info_range)) { | 101 if (!module_range_.ContainsRange(crashpad_info_range)) { |
98 LOG(WARNING) << "crashpad info does not fall inside module " | 102 LOG(WARNING) << "crashpad info does not fall inside module " |
99 << module_name_; | 103 << module_name_; |
100 return false; | 104 return false; |
101 } | 105 } |
102 | 106 |
103 // TODO(scottmg): process_types for cross-bitness. | |
104 if (!process_reader_->ReadMemory(crashpad_info_address, | 107 if (!process_reader_->ReadMemory(crashpad_info_address, |
105 sizeof(process_types::CrashpadInfo), | 108 sizeof(process_types::CrashpadInfo<Traits>), |
106 crashpad_info)) { | 109 crashpad_info)) { |
107 LOG(WARNING) << "could not read crashpad info " << module_name_; | 110 LOG(WARNING) << "could not read crashpad info " << module_name_; |
108 return false; | 111 return false; |
109 } | 112 } |
110 | 113 |
111 if (crashpad_info->signature != CrashpadInfo::kSignature || | 114 if (crashpad_info->signature != CrashpadInfo::kSignature || |
112 crashpad_info->version < 1) { | 115 crashpad_info->version < 1) { |
113 LOG(WARNING) << "unexpected crashpad info data " << module_name_; | 116 LOG(WARNING) << "unexpected crashpad info data " << module_name_; |
114 return false; | 117 return false; |
115 } | 118 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 return false; | 266 return false; |
264 } | 267 } |
265 if (!module_range_.ContainsRange(read_range)) { | 268 if (!module_range_.ContainsRange(read_range)) { |
266 LOG(WARNING) << "attempt to read outside of module " << module_name_ | 269 LOG(WARNING) << "attempt to read outside of module " << module_name_ |
267 << " at range: " << RangeToString(read_range); | 270 << " at range: " << RangeToString(read_range); |
268 return false; | 271 return false; |
269 } | 272 } |
270 return process_reader_->ReadMemory(address, size, into); | 273 return process_reader_->ReadMemory(address, size, into); |
271 } | 274 } |
272 | 275 |
| 276 // Explicit instantiations with the only 2 valid template arguments to avoid |
| 277 // putting the body of the function in the header. |
| 278 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits32>( |
| 279 process_types::CrashpadInfo<process_types::internal::Traits32>* |
| 280 crashpad_info) const; |
| 281 template bool PEImageReader::GetCrashpadInfo<process_types::internal::Traits64>( |
| 282 process_types::CrashpadInfo<process_types::internal::Traits64>* |
| 283 crashpad_info) const; |
| 284 |
273 } // namespace crashpad | 285 } // namespace crashpad |
OLD | NEW |