OLD | NEW |
1 // Copyright 2015 Google Inc. All Rights Reserved. | 1 // Copyright 2015 Google Inc. 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, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 | 98 |
99 *type = matching_types[0]; | 99 *type = matching_types[0]; |
100 return true; | 100 return true; |
101 } | 101 } |
102 | 102 |
103 } // namespace | 103 } // namespace |
104 | 104 |
105 StackFrameDataAnalyzer::StackFrameDataAnalyzer( | 105 StackFrameDataAnalyzer::StackFrameDataAnalyzer( |
106 StackFrameRecordPtr frame_record, | 106 StackFrameRecordPtr frame_record, |
107 scoped_refptr<TypeNameIndex> typename_index, | 107 scoped_refptr<TypeNameIndex> typename_index, |
| 108 ModuleId module_id, |
108 ProcessState* process_state) | 109 ProcessState* process_state) |
109 : frame_record_(frame_record), | 110 : frame_record_(frame_record), |
110 typename_index_(typename_index), | 111 typename_index_(typename_index), |
| 112 module_id_(module_id), |
111 process_state_(process_state) { | 113 process_state_(process_state) { |
112 DCHECK(frame_record.get()); | 114 DCHECK(frame_record.get()); |
113 DCHECK(typename_index.get()); | 115 DCHECK(typename_index.get()); |
114 DCHECK(process_state); | 116 DCHECK(process_state); |
115 } | 117 } |
116 | 118 |
117 bool StackFrameDataAnalyzer::Analyze(IDiaSymbol* data) { | 119 bool StackFrameDataAnalyzer::Analyze(IDiaSymbol* data) { |
118 DCHECK(data); | 120 DCHECK(data); |
119 DCHECK(pe::IsSymTag(data, SymTagData)); | 121 DCHECK(pe::IsSymTag(data, SymTagData)); |
120 | 122 |
(...skipping 17 matching lines...) Expand all Loading... |
138 case DataIsConstant: | 140 case DataIsConstant: |
139 // TODO(manzagop): look into these. | 141 // TODO(manzagop): look into these. |
140 return true; // Ignore these for now. | 142 return true; // Ignore these for now. |
141 } | 143 } |
142 | 144 |
143 // Get the data's information: name, type name and address range. | 145 // Get the data's information: name, type name and address range. |
144 base::string16 data_name; | 146 base::string16 data_name; |
145 if (!pe::GetSymName(data, &data_name)) | 147 if (!pe::GetSymName(data, &data_name)) |
146 return false; | 148 return false; |
147 | 149 |
148 base::string16 type_name; | 150 // Get the data's type from the type_repository. |
149 if (!GetTypeName(data, &type_name)) | 151 TypePtr type; |
| 152 if (!GetDataType(typename_index_.get(), data, &type)) |
150 return false; | 153 return false; |
| 154 if (type.get() == nullptr) |
| 155 return true; // The type was not found. |
151 | 156 |
152 AddressRange range; | 157 AddressRange range; |
153 if (!GetAddressRange(data, &range)) | 158 if (!GetAddressRange(data, type, &range)) |
154 return false; | 159 return false; |
155 // Note: successfully returning an invalid address range means the location | 160 // Note: successfully returning an invalid address range means the location |
156 // type is not yet supported. | 161 // type is not yet supported. |
157 // TODO(manzagop): fully support location types and remove this. | 162 // TODO(manzagop): fully support location types and remove this. |
158 if (!range.IsValid()) | 163 if (!range.IsValid()) |
159 return true; | 164 return true; |
160 | 165 |
161 // Add the typed block to the process state's typed block layer. | 166 // Add the typed block to the process state's typed block layer. |
162 // TODO(manzagop): handle CV qualifiers. | 167 // TODO(manzagop): handle CV qualifiers. |
163 // TODO(manzagop): avoid duplicating types we already know about. | 168 // TODO(manzagop): avoid duplicating types we already know about. |
164 return AddTypedBlockRecord(range, data_name, type_name, process_state_); | 169 return AddTypedBlockRecord(range, data_name, module_id_, type->type_id(), |
| 170 process_state_); |
165 } | 171 } |
166 | 172 |
167 bool StackFrameDataAnalyzer::GetAddressRange(IDiaSymbol* data, | 173 bool StackFrameDataAnalyzer::GetAddressRange(IDiaSymbol* data, |
| 174 TypePtr type, |
168 AddressRange* range) { | 175 AddressRange* range) { |
169 DCHECK(data); DCHECK(range); | 176 DCHECK(data); DCHECK(range); |
170 | 177 |
171 LocationType location_type = LocIsNull; | 178 LocationType location_type = LocIsNull; |
172 if (!pe::GetLocationType(data, &location_type)) | 179 if (!pe::GetLocationType(data, &location_type)) |
173 return false; | 180 return false; |
174 | 181 |
175 switch (location_type) { | 182 switch (location_type) { |
176 case LocIsRegRel: | 183 case LocIsRegRel: |
177 return GetAddressRangeRegRel(data, range); | 184 return GetAddressRangeRegRel(data, type, range); |
178 case LocIsStatic: | 185 case LocIsStatic: |
179 case LocIsTLS: | 186 case LocIsTLS: |
180 case LocIsThisRel: | 187 case LocIsThisRel: |
181 case LocIsEnregistered: | 188 case LocIsEnregistered: |
182 case LocIsBitField: | 189 case LocIsBitField: |
183 case LocIsSlot: | 190 case LocIsSlot: |
184 case LocIsIlRel: | 191 case LocIsIlRel: |
185 case LocInMetaData: | 192 case LocInMetaData: |
186 case LocIsConstant: | 193 case LocIsConstant: |
187 VLOG(1) << "Unhandled location type: " << location_type; | 194 VLOG(1) << "Unhandled location type: " << location_type; |
188 // TODO(manzagop): implement. | 195 // TODO(manzagop): implement. |
189 AddressRange address_range; | 196 AddressRange address_range; |
190 *range = address_range; | 197 *range = address_range; |
191 return true; | 198 return true; |
192 } | 199 } |
193 | 200 |
194 return false; | 201 return false; |
195 } | 202 } |
196 | 203 |
197 bool StackFrameDataAnalyzer::GetAddressRangeRegRel(IDiaSymbol* data, | 204 bool StackFrameDataAnalyzer::GetAddressRangeRegRel(IDiaSymbol* data, |
| 205 TypePtr type, |
198 AddressRange* range) { | 206 AddressRange* range) { |
199 DCHECK(data); DCHECK(range); | 207 DCHECK(data); DCHECK(range); |
200 DCHECK(IsLocType(data, LocIsRegRel)); | 208 DCHECK(IsLocType(data, LocIsRegRel)); |
201 | 209 |
202 AddressRange address_range; | 210 AddressRange address_range; |
203 *range = address_range; | 211 *range = address_range; |
204 | 212 |
205 // Register-relative: determine location. | 213 // Register-relative: determine location. |
206 uint32_t register_id = 0U; | 214 uint32_t register_id = 0U; |
207 if (!pe::GetRegisterId(data, ®ister_id)) | 215 if (!pe::GetRegisterId(data, ®ister_id)) |
208 return false; | 216 return false; |
209 ptrdiff_t register_offset = 0; | 217 ptrdiff_t register_offset = 0; |
210 if (!pe::GetSymOffset(data, ®ister_offset)) | 218 if (!pe::GetSymOffset(data, ®ister_offset)) |
211 return false; | 219 return false; |
212 | 220 |
213 // Get the data's type from the type_repository. | |
214 TypePtr type; | |
215 if (!GetDataType(typename_index_.get(), data, &type)) | |
216 return false; | |
217 if (type.get() == nullptr) | |
218 return true; // The type was not found. | |
219 | |
220 // Figure out the data's range. | 221 // Figure out the data's range. |
221 uint32_t register_value = 0U; | 222 uint32_t register_value = 0U; |
222 if (!GetRegRelLocationRegisterValue(frame_record_, register_id, | 223 if (!GetRegRelLocationRegisterValue(frame_record_, register_id, |
223 ®ister_value)) { | 224 ®ister_value)) { |
224 LOG(ERROR) << base::StringPrintf( | 225 LOG(ERROR) << base::StringPrintf( |
225 "Failed to retrieve register value (%d). Skipping data.", register_id); | 226 "Failed to retrieve register value (%d). Skipping data.", register_id); |
226 return true; | 227 return true; |
227 } | 228 } |
228 | 229 |
229 // TODO(manzagop): check validity of operation. | 230 // TODO(manzagop): check validity of operation. |
230 Address data_va = register_value + register_offset; | 231 Address data_va = register_value + register_offset; |
231 address_range.set_start(data_va); | 232 address_range.set_start(data_va); |
232 address_range.set_size(type->size()); | 233 address_range.set_size(type->size()); |
233 if (!address_range.IsValid()) | 234 if (!address_range.IsValid()) |
234 return false; | 235 return false; |
235 | 236 |
236 *range = address_range; | 237 *range = address_range; |
237 return true; | 238 return true; |
238 } | 239 } |
239 | 240 |
240 } // namespace refinery | 241 } // namespace refinery |
OLD | NEW |