| 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 |