1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 * Header file of an in-memory representation of DEX files. 17 */ 18 19 #include <stdint.h> 20 #include <memory> 21 #include <vector> 22 23 #include "dex_ir_builder.h" 24 25 #include "dex/class_accessor-inl.h" 26 #include "dex/code_item_accessors-inl.h" 27 #include "dex/dex_file_exception_helpers.h" 28 #include "dexlayout.h" 29 30 namespace art { 31 namespace dex_ir { 32 33 static uint64_t ReadVarWidth(const uint8_t** data, uint8_t length, bool sign_extend) { 34 uint64_t value = 0; 35 for (uint32_t i = 0; i <= length; i++) { 36 value |= static_cast<uint64_t>(*(*data)++) << (i * 8); 37 } 38 if (sign_extend) { 39 int shift = (7 - length) * 8; 40 return (static_cast<int64_t>(value) << shift) >> shift; 41 } 42 return value; 43 } 44 45 static uint32_t GetDebugInfoStreamSize(const uint8_t* debug_info_stream) { 46 const uint8_t* stream = debug_info_stream; 47 DecodeUnsignedLeb128(&stream); // line_start 48 uint32_t parameters_size = DecodeUnsignedLeb128(&stream); 49 for (uint32_t i = 0; i < parameters_size; ++i) { 50 DecodeUnsignedLeb128P1(&stream); // Parameter name. 51 } 52 53 for (;;) { 54 uint8_t opcode = *stream++; 55 switch (opcode) { 56 case DexFile::DBG_END_SEQUENCE: 57 return stream - debug_info_stream; // end of stream. 58 case DexFile::DBG_ADVANCE_PC: 59 DecodeUnsignedLeb128(&stream); // addr_diff 60 break; 61 case DexFile::DBG_ADVANCE_LINE: 62 DecodeSignedLeb128(&stream); // line_diff 63 break; 64 case DexFile::DBG_START_LOCAL: 65 DecodeUnsignedLeb128(&stream); // register_num 66 DecodeUnsignedLeb128P1(&stream); // name_idx 67 DecodeUnsignedLeb128P1(&stream); // type_idx 68 break; 69 case DexFile::DBG_START_LOCAL_EXTENDED: 70 DecodeUnsignedLeb128(&stream); // register_num 71 DecodeUnsignedLeb128P1(&stream); // name_idx 72 DecodeUnsignedLeb128P1(&stream); // type_idx 73 DecodeUnsignedLeb128P1(&stream); // sig_idx 74 break; 75 case DexFile::DBG_END_LOCAL: 76 case DexFile::DBG_RESTART_LOCAL: 77 DecodeUnsignedLeb128(&stream); // register_num 78 break; 79 case DexFile::DBG_SET_PROLOGUE_END: 80 case DexFile::DBG_SET_EPILOGUE_BEGIN: 81 break; 82 case DexFile::DBG_SET_FILE: { 83 DecodeUnsignedLeb128P1(&stream); // name_idx 84 break; 85 } 86 default: { 87 break; 88 } 89 } 90 } 91 } 92 93 template<class T> class CollectionMap : public CollectionBase { 94 public: 95 CollectionMap() = default; 96 ~CollectionMap() override { } 97 98 template <class... Args> 99 T* CreateAndAddItem(CollectionVector<T>& vector, 100 bool eagerly_assign_offsets, 101 uint32_t offset, 102 Args&&... args) { 103 T* item = vector.CreateAndAddItem(std::forward<Args>(args)...); 104 DCHECK(!GetExistingObject(offset)); 105 DCHECK(!item->OffsetAssigned()); 106 if (eagerly_assign_offsets) { 107 item->SetOffset(offset); 108 } 109 AddItem(item, offset); 110 return item; 111 } 112 113 // Returns the existing item if it is already inserted, null otherwise. 114 T* GetExistingObject(uint32_t offset) { 115 auto it = collection_.find(offset); 116 return it != collection_.end() ? it->second : nullptr; 117 } 118 119 uint32_t Size() const override { return size(); } 120 121 // Lower case for template interop with std::map. 122 uint32_t size() const { return collection_.size(); } 123 std::map<uint32_t, T*>& Collection() { return collection_; } 124 125 private: 126 std::map<uint32_t, T*> collection_; 127 128 // CollectionMaps do not own the objects they contain, therefore AddItem is supported 129 // rather than CreateAndAddItem. 130 void AddItem(T* object, uint32_t offset) { 131 auto it = collection_.emplace(offset, object); 132 CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " " 133 << " and address " << it.first->second; 134 } 135 136 DISALLOW_COPY_AND_ASSIGN(CollectionMap); 137 }; 138 139 class BuilderMaps { 140 public: 141 BuilderMaps(Header* header, bool eagerly_assign_offsets) 142 : header_(header), eagerly_assign_offsets_(eagerly_assign_offsets) { } 143 144 void CreateStringId(const DexFile& dex_file, uint32_t i); 145 void CreateTypeId(const DexFile& dex_file, uint32_t i); 146 void CreateProtoId(const DexFile& dex_file, uint32_t i); 147 void CreateFieldId(const DexFile& dex_file, uint32_t i); 148 void CreateMethodId(const DexFile& dex_file, uint32_t i); 149 void CreateClassDef(const DexFile& dex_file, uint32_t i); 150 void CreateCallSiteId(const DexFile& dex_file, uint32_t i); 151 void CreateMethodHandleItem(const DexFile& dex_file, uint32_t i); 152 153 void CreateCallSitesAndMethodHandles(const DexFile& dex_file); 154 155 TypeList* CreateTypeList(const dex::TypeList* type_list, uint32_t offset); 156 EncodedArrayItem* CreateEncodedArrayItem(const DexFile& dex_file, 157 const uint8_t* static_data, 158 uint32_t offset); 159 AnnotationItem* CreateAnnotationItem(const DexFile& dex_file, 160 const dex::AnnotationItem* annotation); 161 AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file, 162 const dex::AnnotationSetItem* disk_annotations_item, uint32_t offset); 163 AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file, 164 const dex::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset); 165 CodeItem* DedupeOrCreateCodeItem(const DexFile& dex_file, 166 const dex::CodeItem* disk_code_item, 167 uint32_t offset, 168 uint32_t dex_method_index); 169 ClassData* CreateClassData(const DexFile& dex_file, const dex::ClassDef& class_def); 170 171 void AddAnnotationsFromMapListSection(const DexFile& dex_file, 172 uint32_t start_offset, 173 uint32_t count); 174 void AddHiddenapiClassDataFromMapListSection(const DexFile& dex_file, uint32_t offset); 175 176 void CheckAndSetRemainingOffsets(const DexFile& dex_file, const Options& options); 177 178 // Sort the vectors buy map order (same order that was used in the input file). 179 void SortVectorsByMapOrder(); 180 181 private: 182 bool GetIdsFromByteCode(const CodeItem* code, 183 std::vector<TypeId*>* type_ids, 184 std::vector<StringId*>* string_ids, 185 std::vector<MethodId*>* method_ids, 186 std::vector<FieldId*>* field_ids); 187 188 bool GetIdFromInstruction(const Instruction* dec_insn, 189 std::vector<TypeId*>* type_ids, 190 std::vector<StringId*>* string_ids, 191 std::vector<MethodId*>* method_ids, 192 std::vector<FieldId*>* field_ids); 193 194 EncodedValue* ReadEncodedValue(const DexFile& dex_file, const uint8_t** data); 195 EncodedValue* ReadEncodedValue(const DexFile& dex_file, 196 const uint8_t** data, 197 uint8_t type, 198 uint8_t length); 199 void ReadEncodedValue(const DexFile& dex_file, 200 const uint8_t** data, 201 uint8_t type, 202 uint8_t length, 203 EncodedValue* item); 204 205 MethodItem GenerateMethodItem(const DexFile& dex_file, const ClassAccessor::Method& method); 206 207 ParameterAnnotation* GenerateParameterAnnotation( 208 const DexFile& dex_file, 209 MethodId* method_id, 210 const dex::AnnotationSetRefList* annotation_set_ref_list, 211 uint32_t offset); 212 213 template <typename Type, class... Args> 214 Type* CreateAndAddIndexedItem(IndexedCollectionVector<Type>& vector, 215 uint32_t offset, 216 uint32_t index, 217 Args&&... args) { 218 Type* item = vector.CreateAndAddIndexedItem(index, std::forward<Args>(args)...); 219 DCHECK(!item->OffsetAssigned()); 220 if (eagerly_assign_offsets_) { 221 item->SetOffset(offset); 222 } 223 return item; 224 } 225 226 Header* header_; 227 // If we eagerly assign offsets during IR building or later after layout. Must be false if 228 // changing the layout is enabled. 229 bool eagerly_assign_offsets_; 230 231 // Note: maps do not have ownership. 232 CollectionMap<StringData> string_datas_map_; 233 CollectionMap<TypeList> type_lists_map_; 234 CollectionMap<EncodedArrayItem> encoded_array_items_map_; 235 CollectionMap<AnnotationItem> annotation_items_map_; 236 CollectionMap<AnnotationSetItem> annotation_set_items_map_; 237 CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_map_; 238 CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_map_; 239 CollectionMap<DebugInfoItem> debug_info_items_map_; 240 // Code item maps need to check both the debug info offset and debug info offset, do not use 241 // CollectionMap. 242 // First offset is the code item offset, second is the debug info offset. 243 std::map<std::pair<uint32_t, uint32_t>, CodeItem*> code_items_map_; 244 CollectionMap<ClassData> class_datas_map_; 245 246 DISALLOW_COPY_AND_ASSIGN(BuilderMaps); 247 }; 248 249 Header* DexIrBuilder(const DexFile& dex_file, 250 bool eagerly_assign_offsets, 251 const Options& options) { 252 const DexFile::Header& disk_header = dex_file.GetHeader(); 253 Header* header = new Header(disk_header.magic_, 254 disk_header.checksum_, 255 disk_header.signature_, 256 disk_header.endian_tag_, 257 disk_header.file_size_, 258 disk_header.header_size_, 259 disk_header.link_size_, 260 disk_header.link_off_, 261 disk_header.data_size_, 262 disk_header.data_off_, 263 dex_file.SupportsDefaultMethods(), 264 dex_file.NumStringIds(), 265 dex_file.NumTypeIds(), 266 dex_file.NumProtoIds(), 267 dex_file.NumFieldIds(), 268 dex_file.NumMethodIds(), 269 dex_file.NumClassDefs()); 270 BuilderMaps builder_maps(header, eagerly_assign_offsets); 271 // Walk the rest of the header fields. 272 // StringId table. 273 header->StringIds().SetOffset(disk_header.string_ids_off_); 274 for (uint32_t i = 0; i < dex_file.NumStringIds(); ++i) { 275 builder_maps.CreateStringId(dex_file, i); 276 } 277 // TypeId table. 278 header->TypeIds().SetOffset(disk_header.type_ids_off_); 279 for (uint32_t i = 0; i < dex_file.NumTypeIds(); ++i) { 280 builder_maps.CreateTypeId(dex_file, i); 281 } 282 // ProtoId table. 283 header->ProtoIds().SetOffset(disk_header.proto_ids_off_); 284 for (uint32_t i = 0; i < dex_file.NumProtoIds(); ++i) { 285 builder_maps.CreateProtoId(dex_file, i); 286 } 287 // FieldId table. 288 header->FieldIds().SetOffset(disk_header.field_ids_off_); 289 for (uint32_t i = 0; i < dex_file.NumFieldIds(); ++i) { 290 builder_maps.CreateFieldId(dex_file, i); 291 } 292 // MethodId table. 293 header->MethodIds().SetOffset(disk_header.method_ids_off_); 294 for (uint32_t i = 0; i < dex_file.NumMethodIds(); ++i) { 295 builder_maps.CreateMethodId(dex_file, i); 296 } 297 // ClassDef table. 298 header->ClassDefs().SetOffset(disk_header.class_defs_off_); 299 for (uint32_t i = 0; i < dex_file.NumClassDefs(); ++i) { 300 if (!options.class_filter_.empty()) { 301 // If the filter is enabled (not empty), filter out classes that don't have a matching 302 // descriptor. 303 const dex::ClassDef& class_def = dex_file.GetClassDef(i); 304 const char* descriptor = dex_file.GetClassDescriptor(class_def); 305 if (options.class_filter_.find(descriptor) == options.class_filter_.end()) { 306 continue; 307 } 308 } 309 builder_maps.CreateClassDef(dex_file, i); 310 } 311 // MapItem. 312 header->SetMapListOffset(disk_header.map_off_); 313 // CallSiteIds and MethodHandleItems. 314 builder_maps.CreateCallSitesAndMethodHandles(dex_file); 315 builder_maps.CheckAndSetRemainingOffsets(dex_file, options); 316 317 // Sort the vectors by the map order (same order as the file). 318 builder_maps.SortVectorsByMapOrder(); 319 320 // Load the link data if it exists. 321 header->SetLinkData(std::vector<uint8_t>( 322 dex_file.DataBegin() + dex_file.GetHeader().link_off_, 323 dex_file.DataBegin() + dex_file.GetHeader().link_off_ + dex_file.GetHeader().link_size_)); 324 325 return header; 326 } 327 328 /* 329 * Get all the types, strings, methods, and fields referred to from bytecode. 330 */ 331 void BuilderMaps::CheckAndSetRemainingOffsets(const DexFile& dex_file, const Options& options) { 332 const DexFile::Header& disk_header = dex_file.GetHeader(); 333 // Read MapItems and validate/set remaining offsets. 334 const dex::MapList* map = dex_file.GetMapList(); 335 const uint32_t count = map->size_; 336 for (uint32_t i = 0; i < count; ++i) { 337 const dex::MapItem* item = map->list_ + i; 338 switch (item->type_) { 339 case DexFile::kDexTypeHeaderItem: 340 CHECK_EQ(item->size_, 1u); 341 CHECK_EQ(item->offset_, 0u); 342 break; 343 case DexFile::kDexTypeStringIdItem: 344 CHECK_EQ(item->size_, header_->StringIds().Size()); 345 CHECK_EQ(item->offset_, header_->StringIds().GetOffset()); 346 break; 347 case DexFile::kDexTypeTypeIdItem: 348 CHECK_EQ(item->size_, header_->TypeIds().Size()); 349 CHECK_EQ(item->offset_, header_->TypeIds().GetOffset()); 350 break; 351 case DexFile::kDexTypeProtoIdItem: 352 CHECK_EQ(item->size_, header_->ProtoIds().Size()); 353 CHECK_EQ(item->offset_, header_->ProtoIds().GetOffset()); 354 break; 355 case DexFile::kDexTypeFieldIdItem: 356 CHECK_EQ(item->size_, header_->FieldIds().Size()); 357 CHECK_EQ(item->offset_, header_->FieldIds().GetOffset()); 358 break; 359 case DexFile::kDexTypeMethodIdItem: 360 CHECK_EQ(item->size_, header_->MethodIds().Size()); 361 CHECK_EQ(item->offset_, header_->MethodIds().GetOffset()); 362 break; 363 case DexFile::kDexTypeClassDefItem: 364 if (options.class_filter_.empty()) { 365 // The filter may have removed some classes, this will get fixed up during writing. 366 CHECK_EQ(item->size_, header_->ClassDefs().Size()); 367 } 368 CHECK_EQ(item->offset_, header_->ClassDefs().GetOffset()); 369 break; 370 case DexFile::kDexTypeCallSiteIdItem: 371 CHECK_EQ(item->size_, header_->CallSiteIds().Size()); 372 CHECK_EQ(item->offset_, header_->CallSiteIds().GetOffset()); 373 break; 374 case DexFile::kDexTypeMethodHandleItem: 375 CHECK_EQ(item->size_, header_->MethodHandleItems().Size()); 376 CHECK_EQ(item->offset_, header_->MethodHandleItems().GetOffset()); 377 break; 378 case DexFile::kDexTypeMapList: 379 CHECK_EQ(item->size_, 1u); 380 CHECK_EQ(item->offset_, disk_header.map_off_); 381 break; 382 case DexFile::kDexTypeTypeList: 383 header_->TypeLists().SetOffset(item->offset_); 384 break; 385 case DexFile::kDexTypeAnnotationSetRefList: 386 header_->AnnotationSetRefLists().SetOffset(item->offset_); 387 break; 388 case DexFile::kDexTypeAnnotationSetItem: 389 header_->AnnotationSetItems().SetOffset(item->offset_); 390 break; 391 case DexFile::kDexTypeClassDataItem: 392 header_->ClassDatas().SetOffset(item->offset_); 393 break; 394 case DexFile::kDexTypeCodeItem: 395 header_->CodeItems().SetOffset(item->offset_); 396 break; 397 case DexFile::kDexTypeStringDataItem: 398 header_->StringDatas().SetOffset(item->offset_); 399 break; 400 case DexFile::kDexTypeDebugInfoItem: 401 header_->DebugInfoItems().SetOffset(item->offset_); 402 break; 403 case DexFile::kDexTypeAnnotationItem: 404 header_->AnnotationItems().SetOffset(item->offset_); 405 AddAnnotationsFromMapListSection(dex_file, item->offset_, item->size_); 406 break; 407 case DexFile::kDexTypeEncodedArrayItem: 408 header_->EncodedArrayItems().SetOffset(item->offset_); 409 break; 410 case DexFile::kDexTypeAnnotationsDirectoryItem: 411 header_->AnnotationsDirectoryItems().SetOffset(item->offset_); 412 break; 413 case DexFile::kDexTypeHiddenapiClassData: 414 header_->HiddenapiClassDatas().SetOffset(item->offset_); 415 AddHiddenapiClassDataFromMapListSection(dex_file, item->offset_); 416 break; 417 default: 418 LOG(ERROR) << "Unknown map list item type."; 419 } 420 } 421 } 422 423 void BuilderMaps::CreateStringId(const DexFile& dex_file, uint32_t i) { 424 const dex::StringId& disk_string_id = dex_file.GetStringId(dex::StringIndex(i)); 425 StringData* string_data = 426 string_datas_map_.CreateAndAddItem(header_->StringDatas(), 427 eagerly_assign_offsets_, 428 disk_string_id.string_data_off_, 429 dex_file.GetStringData(disk_string_id)); 430 CreateAndAddIndexedItem(header_->StringIds(), 431 header_->StringIds().GetOffset() + i * StringId::ItemSize(), 432 i, 433 string_data); 434 } 435 436 void BuilderMaps::CreateTypeId(const DexFile& dex_file, uint32_t i) { 437 const dex::TypeId& disk_type_id = dex_file.GetTypeId(dex::TypeIndex(i)); 438 CreateAndAddIndexedItem(header_->TypeIds(), 439 header_->TypeIds().GetOffset() + i * TypeId::ItemSize(), 440 i, 441 header_->StringIds()[disk_type_id.descriptor_idx_.index_]); 442 } 443 444 void BuilderMaps::CreateProtoId(const DexFile& dex_file, uint32_t i) { 445 const dex::ProtoId& disk_proto_id = dex_file.GetProtoId(dex::ProtoIndex(i)); 446 const dex::TypeList* type_list = dex_file.GetProtoParameters(disk_proto_id); 447 TypeList* parameter_type_list = CreateTypeList(type_list, disk_proto_id.parameters_off_); 448 449 CreateAndAddIndexedItem(header_->ProtoIds(), 450 header_->ProtoIds().GetOffset() + i * ProtoId::ItemSize(), 451 i, 452 header_->StringIds()[disk_proto_id.shorty_idx_.index_], 453 header_->TypeIds()[disk_proto_id.return_type_idx_.index_], 454 parameter_type_list); 455 } 456 457 void BuilderMaps::CreateFieldId(const DexFile& dex_file, uint32_t i) { 458 const dex::FieldId& disk_field_id = dex_file.GetFieldId(i); 459 CreateAndAddIndexedItem(header_->FieldIds(), 460 header_->FieldIds().GetOffset() + i * FieldId::ItemSize(), 461 i, 462 header_->TypeIds()[disk_field_id.class_idx_.index_], 463 header_->TypeIds()[disk_field_id.type_idx_.index_], 464 header_->StringIds()[disk_field_id.name_idx_.index_]); 465 } 466 467 void BuilderMaps::CreateMethodId(const DexFile& dex_file, uint32_t i) { 468 const dex::MethodId& disk_method_id = dex_file.GetMethodId(i); 469 CreateAndAddIndexedItem(header_->MethodIds(), 470 header_->MethodIds().GetOffset() + i * MethodId::ItemSize(), 471 i, 472 header_->TypeIds()[disk_method_id.class_idx_.index_], 473 header_->ProtoIds()[disk_method_id.proto_idx_.index_], 474 header_->StringIds()[disk_method_id.name_idx_.index_]); 475 } 476 477 void BuilderMaps::CreateClassDef(const DexFile& dex_file, uint32_t i) { 478 const dex::ClassDef& disk_class_def = dex_file.GetClassDef(i); 479 const TypeId* class_type = header_->TypeIds()[disk_class_def.class_idx_.index_]; 480 uint32_t access_flags = disk_class_def.access_flags_; 481 const TypeId* superclass = header_->GetTypeIdOrNullPtr(disk_class_def.superclass_idx_.index_); 482 483 const dex::TypeList* type_list = dex_file.GetInterfacesList(disk_class_def); 484 TypeList* interfaces_type_list = CreateTypeList(type_list, disk_class_def.interfaces_off_); 485 486 const StringId* source_file = 487 header_->GetStringIdOrNullPtr(disk_class_def.source_file_idx_.index_); 488 // Annotations. 489 AnnotationsDirectoryItem* annotations = nullptr; 490 const dex::AnnotationsDirectoryItem* disk_annotations_directory_item = 491 dex_file.GetAnnotationsDirectory(disk_class_def); 492 if (disk_annotations_directory_item != nullptr) { 493 annotations = CreateAnnotationsDirectoryItem( 494 dex_file, disk_annotations_directory_item, disk_class_def.annotations_off_); 495 } 496 // Static field initializers. 497 const uint8_t* static_data = dex_file.GetEncodedStaticFieldValuesArray(disk_class_def); 498 EncodedArrayItem* static_values = 499 CreateEncodedArrayItem(dex_file, static_data, disk_class_def.static_values_off_); 500 ClassData* class_data = CreateClassData(dex_file, disk_class_def); 501 CreateAndAddIndexedItem(header_->ClassDefs(), 502 header_->ClassDefs().GetOffset() + i * ClassDef::ItemSize(), 503 i, 504 class_type, 505 access_flags, 506 superclass, 507 interfaces_type_list, 508 source_file, 509 annotations, 510 static_values, 511 class_data); 512 } 513 514 void BuilderMaps::CreateCallSiteId(const DexFile& dex_file, uint32_t i) { 515 const dex::CallSiteIdItem& disk_call_site_id = dex_file.GetCallSiteId(i); 516 const uint8_t* disk_call_item_ptr = dex_file.DataBegin() + disk_call_site_id.data_off_; 517 EncodedArrayItem* call_site_item = 518 CreateEncodedArrayItem(dex_file, disk_call_item_ptr, disk_call_site_id.data_off_); 519 520 CreateAndAddIndexedItem(header_->CallSiteIds(), 521 header_->CallSiteIds().GetOffset() + i * CallSiteId::ItemSize(), 522 i, 523 call_site_item); 524 } 525 526 void BuilderMaps::CreateMethodHandleItem(const DexFile& dex_file, uint32_t i) { 527 const dex::MethodHandleItem& disk_method_handle = dex_file.GetMethodHandle(i); 528 uint16_t index = disk_method_handle.field_or_method_idx_; 529 DexFile::MethodHandleType type = 530 static_cast<DexFile::MethodHandleType>(disk_method_handle.method_handle_type_); 531 bool is_invoke = type == DexFile::MethodHandleType::kInvokeStatic || 532 type == DexFile::MethodHandleType::kInvokeInstance || 533 type == DexFile::MethodHandleType::kInvokeConstructor || 534 type == DexFile::MethodHandleType::kInvokeDirect || 535 type == DexFile::MethodHandleType::kInvokeInterface; 536 static_assert(DexFile::MethodHandleType::kLast == DexFile::MethodHandleType::kInvokeInterface, 537 "Unexpected method handle types."); 538 IndexedItem* field_or_method_id; 539 if (is_invoke) { 540 field_or_method_id = header_->MethodIds()[index]; 541 } else { 542 field_or_method_id = header_->FieldIds()[index]; 543 } 544 CreateAndAddIndexedItem(header_->MethodHandleItems(), 545 header_->MethodHandleItems().GetOffset() + 546 i * MethodHandleItem::ItemSize(), 547 i, 548 type, 549 field_or_method_id); 550 } 551 552 void BuilderMaps::CreateCallSitesAndMethodHandles(const DexFile& dex_file) { 553 // Iterate through the map list and set the offset of the CallSiteIds and MethodHandleItems. 554 const dex::MapList* map = dex_file.GetMapList(); 555 for (uint32_t i = 0; i < map->size_; ++i) { 556 const dex::MapItem* item = map->list_ + i; 557 switch (item->type_) { 558 case DexFile::kDexTypeCallSiteIdItem: 559 header_->CallSiteIds().SetOffset(item->offset_); 560 break; 561 case DexFile::kDexTypeMethodHandleItem: 562 header_->MethodHandleItems().SetOffset(item->offset_); 563 break; 564 default: 565 break; 566 } 567 } 568 // Populate MethodHandleItems first (CallSiteIds may depend on them). 569 for (uint32_t i = 0; i < dex_file.NumMethodHandles(); i++) { 570 CreateMethodHandleItem(dex_file, i); 571 } 572 // Populate CallSiteIds. 573 for (uint32_t i = 0; i < dex_file.NumCallSiteIds(); i++) { 574 CreateCallSiteId(dex_file, i); 575 } 576 } 577 578 TypeList* BuilderMaps::CreateTypeList(const dex::TypeList* dex_type_list, uint32_t offset) { 579 if (dex_type_list == nullptr) { 580 return nullptr; 581 } 582 TypeList* type_list = type_lists_map_.GetExistingObject(offset); 583 if (type_list == nullptr) { 584 TypeIdVector* type_vector = new TypeIdVector(); 585 uint32_t size = dex_type_list->Size(); 586 for (uint32_t index = 0; index < size; ++index) { 587 type_vector->push_back(header_->TypeIds()[ 588 dex_type_list->GetTypeItem(index).type_idx_.index_]); 589 } 590 type_list = type_lists_map_.CreateAndAddItem(header_->TypeLists(), 591 eagerly_assign_offsets_, 592 offset, 593 type_vector); 594 } 595 return type_list; 596 } 597 598 EncodedArrayItem* BuilderMaps::CreateEncodedArrayItem(const DexFile& dex_file, 599 const uint8_t* static_data, 600 uint32_t offset) { 601 if (static_data == nullptr) { 602 return nullptr; 603 } 604 EncodedArrayItem* encoded_array_item = encoded_array_items_map_.GetExistingObject(offset); 605 if (encoded_array_item == nullptr) { 606 uint32_t size = DecodeUnsignedLeb128(&static_data); 607 EncodedValueVector* values = new EncodedValueVector(); 608 for (uint32_t i = 0; i < size; ++i) { 609 values->push_back(std::unique_ptr<EncodedValue>(ReadEncodedValue(dex_file, &static_data))); 610 } 611 // TODO: Calculate the size of the encoded array. 612 encoded_array_item = encoded_array_items_map_.CreateAndAddItem(header_->EncodedArrayItems(), 613 eagerly_assign_offsets_, 614 offset, 615 values); 616 } 617 return encoded_array_item; 618 } 619 620 void BuilderMaps::AddAnnotationsFromMapListSection(const DexFile& dex_file, 621 uint32_t start_offset, 622 uint32_t count) { 623 uint32_t current_offset = start_offset; 624 for (size_t i = 0; i < count; ++i) { 625 // Annotation that we didn't process already, add it to the set. 626 const dex::AnnotationItem* annotation = dex_file.GetAnnotationItemAtOffset(current_offset); 627 AnnotationItem* annotation_item = CreateAnnotationItem(dex_file, annotation); 628 DCHECK(annotation_item != nullptr); 629 current_offset += annotation_item->GetSize(); 630 } 631 } 632 633 void BuilderMaps::AddHiddenapiClassDataFromMapListSection(const DexFile& dex_file, 634 uint32_t offset) { 635 const dex::HiddenapiClassData* hiddenapi_class_data = 636 dex_file.GetHiddenapiClassDataAtOffset(offset); 637 DCHECK(hiddenapi_class_data == dex_file.GetHiddenapiClassData()); 638 639 for (auto& class_def : header_->ClassDefs()) { 640 uint32_t index = class_def->GetIndex(); 641 ClassData* class_data = class_def->GetClassData(); 642 const uint8_t* ptr = hiddenapi_class_data->GetFlagsPointer(index); 643 644 std::unique_ptr<HiddenapiFlagsMap> flags = nullptr; 645 if (ptr != nullptr) { 646 DCHECK(class_data != nullptr); 647 flags = std::make_unique<HiddenapiFlagsMap>(); 648 for (const dex_ir::FieldItem& field : *class_data->StaticFields()) { 649 flags->emplace(&field, DecodeUnsignedLeb128(&ptr)); 650 } 651 for (const dex_ir::FieldItem& field : *class_data->InstanceFields()) { 652 flags->emplace(&field, DecodeUnsignedLeb128(&ptr)); 653 } 654 for (const dex_ir::MethodItem& method : *class_data->DirectMethods()) { 655 flags->emplace(&method, DecodeUnsignedLeb128(&ptr)); 656 } 657 for (const dex_ir::MethodItem& method : *class_data->VirtualMethods()) { 658 flags->emplace(&method, DecodeUnsignedLeb128(&ptr)); 659 } 660 } 661 662 CreateAndAddIndexedItem(header_->HiddenapiClassDatas(), 663 header_->HiddenapiClassDatas().GetOffset() + 664 hiddenapi_class_data->flags_offset_[index], 665 index, 666 class_def.get(), 667 std::move(flags)); 668 } 669 } 670 671 AnnotationItem* BuilderMaps::CreateAnnotationItem(const DexFile& dex_file, 672 const dex::AnnotationItem* annotation) { 673 const uint8_t* const start_data = reinterpret_cast<const uint8_t*>(annotation); 674 const uint32_t offset = start_data - dex_file.DataBegin(); 675 AnnotationItem* annotation_item = annotation_items_map_.GetExistingObject(offset); 676 if (annotation_item == nullptr) { 677 uint8_t visibility = annotation->visibility_; 678 const uint8_t* annotation_data = annotation->annotation_; 679 std::unique_ptr<EncodedValue> encoded_value( 680 ReadEncodedValue(dex_file, &annotation_data, DexFile::kDexAnnotationAnnotation, 0)); 681 annotation_item = 682 annotation_items_map_.CreateAndAddItem(header_->AnnotationItems(), 683 eagerly_assign_offsets_, 684 offset, 685 visibility, 686 encoded_value->ReleaseEncodedAnnotation()); 687 annotation_item->SetSize(annotation_data - start_data); 688 } 689 return annotation_item; 690 } 691 692 693 AnnotationSetItem* BuilderMaps::CreateAnnotationSetItem(const DexFile& dex_file, 694 const dex::AnnotationSetItem* disk_annotations_item, uint32_t offset) { 695 if (disk_annotations_item == nullptr || (disk_annotations_item->size_ == 0 && offset == 0)) { 696 return nullptr; 697 } 698 AnnotationSetItem* annotation_set_item = annotation_set_items_map_.GetExistingObject(offset); 699 if (annotation_set_item == nullptr) { 700 std::vector<AnnotationItem*>* items = new std::vector<AnnotationItem*>(); 701 for (uint32_t i = 0; i < disk_annotations_item->size_; ++i) { 702 const dex::AnnotationItem* annotation = 703 dex_file.GetAnnotationItem(disk_annotations_item, i); 704 if (annotation == nullptr) { 705 continue; 706 } 707 AnnotationItem* annotation_item = CreateAnnotationItem(dex_file, annotation); 708 items->push_back(annotation_item); 709 } 710 annotation_set_item = 711 annotation_set_items_map_.CreateAndAddItem(header_->AnnotationSetItems(), 712 eagerly_assign_offsets_, 713 offset, 714 items); 715 } 716 return annotation_set_item; 717 } 718 719 AnnotationsDirectoryItem* BuilderMaps::CreateAnnotationsDirectoryItem(const DexFile& dex_file, 720 const dex::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset) { 721 AnnotationsDirectoryItem* annotations_directory_item = 722 annotations_directory_items_map_.GetExistingObject(offset); 723 if (annotations_directory_item != nullptr) { 724 return annotations_directory_item; 725 } 726 const dex::AnnotationSetItem* class_set_item = 727 dex_file.GetClassAnnotationSet(disk_annotations_item); 728 AnnotationSetItem* class_annotation = nullptr; 729 if (class_set_item != nullptr) { 730 uint32_t item_offset = disk_annotations_item->class_annotations_off_; 731 class_annotation = CreateAnnotationSetItem(dex_file, class_set_item, item_offset); 732 } 733 const dex::FieldAnnotationsItem* fields = 734 dex_file.GetFieldAnnotations(disk_annotations_item); 735 FieldAnnotationVector* field_annotations = nullptr; 736 if (fields != nullptr) { 737 field_annotations = new FieldAnnotationVector(); 738 for (uint32_t i = 0; i < disk_annotations_item->fields_size_; ++i) { 739 FieldId* field_id = header_->FieldIds()[fields[i].field_idx_]; 740 const dex::AnnotationSetItem* field_set_item = 741 dex_file.GetFieldAnnotationSetItem(fields[i]); 742 uint32_t annotation_set_offset = fields[i].annotations_off_; 743 AnnotationSetItem* annotation_set_item = 744 CreateAnnotationSetItem(dex_file, field_set_item, annotation_set_offset); 745 field_annotations->push_back(std::make_unique<FieldAnnotation>( 746 field_id, annotation_set_item)); 747 } 748 } 749 const dex::MethodAnnotationsItem* methods = 750 dex_file.GetMethodAnnotations(disk_annotations_item); 751 MethodAnnotationVector* method_annotations = nullptr; 752 if (methods != nullptr) { 753 method_annotations = new MethodAnnotationVector(); 754 for (uint32_t i = 0; i < disk_annotations_item->methods_size_; ++i) { 755 MethodId* method_id = header_->MethodIds()[methods[i].method_idx_]; 756 const dex::AnnotationSetItem* method_set_item = 757 dex_file.GetMethodAnnotationSetItem(methods[i]); 758 uint32_t annotation_set_offset = methods[i].annotations_off_; 759 AnnotationSetItem* annotation_set_item = 760 CreateAnnotationSetItem(dex_file, method_set_item, annotation_set_offset); 761 method_annotations->push_back(std::make_unique<MethodAnnotation>( 762 method_id, annotation_set_item)); 763 } 764 } 765 const dex::ParameterAnnotationsItem* parameters = 766 dex_file.GetParameterAnnotations(disk_annotations_item); 767 ParameterAnnotationVector* parameter_annotations = nullptr; 768 if (parameters != nullptr) { 769 parameter_annotations = new ParameterAnnotationVector(); 770 for (uint32_t i = 0; i < disk_annotations_item->parameters_size_; ++i) { 771 MethodId* method_id = header_->MethodIds()[parameters[i].method_idx_]; 772 const dex::AnnotationSetRefList* list = 773 dex_file.GetParameterAnnotationSetRefList(¶meters[i]); 774 parameter_annotations->push_back(std::unique_ptr<ParameterAnnotation>( 775 GenerateParameterAnnotation(dex_file, method_id, list, parameters[i].annotations_off_))); 776 } 777 } 778 // TODO: Calculate the size of the annotations directory. 779 return annotations_directory_items_map_.CreateAndAddItem(header_->AnnotationsDirectoryItems(), 780 eagerly_assign_offsets_, 781 offset, 782 class_annotation, 783 field_annotations, 784 method_annotations, 785 parameter_annotations); 786 } 787 788 CodeItem* BuilderMaps::DedupeOrCreateCodeItem(const DexFile& dex_file, 789 const dex::CodeItem* disk_code_item, 790 uint32_t offset, 791 uint32_t dex_method_index) { 792 if (disk_code_item == nullptr) { 793 return nullptr; 794 } 795 CodeItemDebugInfoAccessor accessor(dex_file, disk_code_item, dex_method_index); 796 const uint32_t debug_info_offset = accessor.DebugInfoOffset(); 797 798 // Create the offsets pair and dedupe based on it. 799 std::pair<uint32_t, uint32_t> offsets_pair(offset, debug_info_offset); 800 auto existing = code_items_map_.find(offsets_pair); 801 if (existing != code_items_map_.end()) { 802 return existing->second; 803 } 804 805 const uint8_t* debug_info_stream = dex_file.GetDebugInfoStream(debug_info_offset); 806 DebugInfoItem* debug_info = nullptr; 807 if (debug_info_stream != nullptr) { 808 debug_info = debug_info_items_map_.GetExistingObject(debug_info_offset); 809 if (debug_info == nullptr) { 810 uint32_t debug_info_size = GetDebugInfoStreamSize(debug_info_stream); 811 uint8_t* debug_info_buffer = new uint8_t[debug_info_size]; 812 memcpy(debug_info_buffer, debug_info_stream, debug_info_size); 813 debug_info = debug_info_items_map_.CreateAndAddItem(header_->DebugInfoItems(), 814 eagerly_assign_offsets_, 815 debug_info_offset, 816 debug_info_size, 817 debug_info_buffer); 818 } 819 } 820 821 uint32_t insns_size = accessor.InsnsSizeInCodeUnits(); 822 uint16_t* insns = new uint16_t[insns_size]; 823 memcpy(insns, accessor.Insns(), insns_size * sizeof(uint16_t)); 824 825 TryItemVector* tries = nullptr; 826 CatchHandlerVector* handler_list = nullptr; 827 if (accessor.TriesSize() > 0) { 828 tries = new TryItemVector(); 829 handler_list = new CatchHandlerVector(); 830 for (const dex::TryItem& disk_try_item : accessor.TryItems()) { 831 uint32_t start_addr = disk_try_item.start_addr_; 832 uint16_t insn_count = disk_try_item.insn_count_; 833 uint16_t handler_off = disk_try_item.handler_off_; 834 const CatchHandler* handlers = nullptr; 835 for (std::unique_ptr<const CatchHandler>& existing_handlers : *handler_list) { 836 if (handler_off == existing_handlers->GetListOffset()) { 837 handlers = existing_handlers.get(); 838 break; 839 } 840 } 841 if (handlers == nullptr) { 842 bool catch_all = false; 843 TypeAddrPairVector* addr_pairs = new TypeAddrPairVector(); 844 for (CatchHandlerIterator it(accessor, disk_try_item); it.HasNext(); it.Next()) { 845 const dex::TypeIndex type_index = it.GetHandlerTypeIndex(); 846 const TypeId* type_id = header_->GetTypeIdOrNullPtr(type_index.index_); 847 catch_all |= type_id == nullptr; 848 addr_pairs->push_back(std::unique_ptr<const TypeAddrPair>( 849 new TypeAddrPair(type_id, it.GetHandlerAddress()))); 850 } 851 handlers = new CatchHandler(catch_all, handler_off, addr_pairs); 852 handler_list->push_back(std::unique_ptr<const CatchHandler>(handlers)); 853 } 854 TryItem* try_item = new TryItem(start_addr, insn_count, handlers); 855 tries->push_back(std::unique_ptr<const TryItem>(try_item)); 856 } 857 // Manually walk catch handlers list and add any missing handlers unreferenced by try items. 858 const uint8_t* handlers_base = accessor.GetCatchHandlerData(); 859 const uint8_t* handlers_data = handlers_base; 860 uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_data); 861 while (handlers_size > handler_list->size()) { 862 bool already_added = false; 863 uint16_t handler_off = handlers_data - handlers_base; 864 for (std::unique_ptr<const CatchHandler>& existing_handlers : *handler_list) { 865 if (handler_off == existing_handlers->GetListOffset()) { 866 already_added = true; 867 break; 868 } 869 } 870 int32_t size = DecodeSignedLeb128(&handlers_data); 871 bool has_catch_all = size <= 0; 872 if (has_catch_all) { 873 size = -size; 874 } 875 if (already_added) { 876 for (int32_t i = 0; i < size; i++) { 877 DecodeUnsignedLeb128(&handlers_data); 878 DecodeUnsignedLeb128(&handlers_data); 879 } 880 if (has_catch_all) { 881 DecodeUnsignedLeb128(&handlers_data); 882 } 883 continue; 884 } 885 TypeAddrPairVector* addr_pairs = new TypeAddrPairVector(); 886 for (int32_t i = 0; i < size; i++) { 887 const TypeId* type_id = 888 header_->GetTypeIdOrNullPtr(DecodeUnsignedLeb128(&handlers_data)); 889 uint32_t addr = DecodeUnsignedLeb128(&handlers_data); 890 addr_pairs->push_back( 891 std::unique_ptr<const TypeAddrPair>(new TypeAddrPair(type_id, addr))); 892 } 893 if (has_catch_all) { 894 uint32_t addr = DecodeUnsignedLeb128(&handlers_data); 895 addr_pairs->push_back( 896 std::unique_ptr<const TypeAddrPair>(new TypeAddrPair(nullptr, addr))); 897 } 898 const CatchHandler* handler = new CatchHandler(has_catch_all, handler_off, addr_pairs); 899 handler_list->push_back(std::unique_ptr<const CatchHandler>(handler)); 900 } 901 } 902 903 uint32_t size = dex_file.GetCodeItemSize(*disk_code_item); 904 CodeItem* code_item = header_->CodeItems().CreateAndAddItem(accessor.RegistersSize(), 905 accessor.InsSize(), 906 accessor.OutsSize(), 907 debug_info, 908 insns_size, 909 insns, 910 tries, 911 handler_list); 912 code_item->SetSize(size); 913 914 // Add the code item to the map. 915 DCHECK(!code_item->OffsetAssigned()); 916 if (eagerly_assign_offsets_) { 917 code_item->SetOffset(offset); 918 } 919 code_items_map_.emplace(offsets_pair, code_item); 920 921 // Add "fixup" references to types, strings, methods, and fields. 922 // This is temporary, as we will probably want more detailed parsing of the 923 // instructions here. 924 std::vector<TypeId*> type_ids; 925 std::vector<StringId*> string_ids; 926 std::vector<MethodId*> method_ids; 927 std::vector<FieldId*> field_ids; 928 if (GetIdsFromByteCode(code_item, 929 /*out*/ &type_ids, 930 /*out*/ &string_ids, 931 /*out*/ &method_ids, 932 /*out*/ &field_ids)) { 933 CodeFixups* fixups = new CodeFixups(std::move(type_ids), 934 std::move(string_ids), 935 std::move(method_ids), 936 std::move(field_ids)); 937 code_item->SetCodeFixups(fixups); 938 } 939 940 return code_item; 941 } 942 943 ClassData* BuilderMaps::CreateClassData(const DexFile& dex_file, 944 const dex::ClassDef& class_def) { 945 // Read the fields and methods defined by the class, resolving the circular reference from those 946 // to classes by setting class at the same time. 947 const uint32_t offset = class_def.class_data_off_; 948 ClassData* class_data = class_datas_map_.GetExistingObject(offset); 949 if (class_data == nullptr && offset != 0u) { 950 ClassAccessor accessor(dex_file, class_def); 951 // Static fields. 952 FieldItemVector* static_fields = new FieldItemVector(); 953 for (const ClassAccessor::Field& field : accessor.GetStaticFields()) { 954 FieldId* field_item = header_->FieldIds()[field.GetIndex()]; 955 uint32_t access_flags = field.GetAccessFlags(); 956 static_fields->emplace_back(access_flags, field_item); 957 } 958 FieldItemVector* instance_fields = new FieldItemVector(); 959 for (const ClassAccessor::Field& field : accessor.GetInstanceFields()) { 960 FieldId* field_item = header_->FieldIds()[field.GetIndex()]; 961 uint32_t access_flags = field.GetAccessFlags(); 962 instance_fields->emplace_back(access_flags, field_item); 963 } 964 // Direct methods. 965 MethodItemVector* direct_methods = new MethodItemVector(); 966 auto direct_methods_it = accessor.GetDirectMethods(); 967 for (auto it = direct_methods_it.begin(); it != direct_methods_it.end(); ++it) { 968 direct_methods->push_back(GenerateMethodItem(dex_file, *it)); 969 } 970 // Virtual methods. 971 MethodItemVector* virtual_methods = new MethodItemVector(); 972 auto virtual_methods_it = accessor.GetVirtualMethods(); 973 const uint8_t* last_data_ptr; 974 for (auto it = virtual_methods_it.begin(); ; ++it) { 975 if (it == virtual_methods_it.end()) { 976 last_data_ptr = it->GetDataPointer(); 977 break; 978 } 979 virtual_methods->push_back(GenerateMethodItem(dex_file, *it)); 980 } 981 class_data = class_datas_map_.CreateAndAddItem(header_->ClassDatas(), 982 eagerly_assign_offsets_, 983 offset, 984 static_fields, 985 instance_fields, 986 direct_methods, 987 virtual_methods); 988 class_data->SetSize(last_data_ptr - dex_file.GetClassData(class_def)); 989 } 990 return class_data; 991 } 992 993 void BuilderMaps::SortVectorsByMapOrder() { 994 header_->StringDatas().SortByMapOrder(string_datas_map_.Collection()); 995 header_->TypeLists().SortByMapOrder(type_lists_map_.Collection()); 996 header_->EncodedArrayItems().SortByMapOrder(encoded_array_items_map_.Collection()); 997 header_->AnnotationItems().SortByMapOrder(annotation_items_map_.Collection()); 998 header_->AnnotationSetItems().SortByMapOrder(annotation_set_items_map_.Collection()); 999 header_->AnnotationSetRefLists().SortByMapOrder(annotation_set_ref_lists_map_.Collection()); 1000 header_->AnnotationsDirectoryItems().SortByMapOrder( 1001 annotations_directory_items_map_.Collection()); 1002 header_->DebugInfoItems().SortByMapOrder(debug_info_items_map_.Collection()); 1003 header_->CodeItems().SortByMapOrder(code_items_map_); 1004 header_->ClassDatas().SortByMapOrder(class_datas_map_.Collection()); 1005 } 1006 1007 bool BuilderMaps::GetIdsFromByteCode(const CodeItem* code, 1008 std::vector<TypeId*>* type_ids, 1009 std::vector<StringId*>* string_ids, 1010 std::vector<MethodId*>* method_ids, 1011 std::vector<FieldId*>* field_ids) { 1012 bool has_id = false; 1013 IterationRange<DexInstructionIterator> instructions = code->Instructions(); 1014 SafeDexInstructionIterator it(instructions.begin(), instructions.end()); 1015 for (; !it.IsErrorState() && it < instructions.end(); ++it) { 1016 // In case the instruction goes past the end of the code item, make sure to not process it. 1017 SafeDexInstructionIterator next = it; 1018 ++next; 1019 if (next.IsErrorState()) { 1020 break; 1021 } 1022 has_id |= GetIdFromInstruction(&it.Inst(), type_ids, string_ids, method_ids, field_ids); 1023 } // for 1024 return has_id; 1025 } 1026 1027 bool BuilderMaps::GetIdFromInstruction(const Instruction* dec_insn, 1028 std::vector<TypeId*>* type_ids, 1029 std::vector<StringId*>* string_ids, 1030 std::vector<MethodId*>* method_ids, 1031 std::vector<FieldId*>* field_ids) { 1032 // Determine index and width of the string. 1033 uint32_t index = 0; 1034 switch (Instruction::FormatOf(dec_insn->Opcode())) { 1035 // SOME NOT SUPPORTED: 1036 // case Instruction::k20bc: 1037 case Instruction::k21c: 1038 case Instruction::k35c: 1039 // case Instruction::k35ms: 1040 case Instruction::k3rc: 1041 // case Instruction::k3rms: 1042 // case Instruction::k35mi: 1043 // case Instruction::k3rmi: 1044 case Instruction::k45cc: 1045 case Instruction::k4rcc: 1046 index = dec_insn->VRegB(); 1047 break; 1048 case Instruction::k31c: 1049 index = dec_insn->VRegB(); 1050 break; 1051 case Instruction::k22c: 1052 // case Instruction::k22cs: 1053 index = dec_insn->VRegC(); 1054 break; 1055 default: 1056 break; 1057 } // switch 1058 1059 // Determine index type, and add reference to the appropriate collection. 1060 switch (Instruction::IndexTypeOf(dec_insn->Opcode())) { 1061 case Instruction::kIndexTypeRef: 1062 if (index < header_->TypeIds().Size()) { 1063 type_ids->push_back(header_->TypeIds()[index]); 1064 return true; 1065 } 1066 break; 1067 case Instruction::kIndexStringRef: 1068 if (index < header_->StringIds().Size()) { 1069 string_ids->push_back(header_->StringIds()[index]); 1070 return true; 1071 } 1072 break; 1073 case Instruction::kIndexMethodRef: 1074 case Instruction::kIndexMethodAndProtoRef: 1075 if (index < header_->MethodIds().Size()) { 1076 method_ids->push_back(header_->MethodIds()[index]); 1077 return true; 1078 } 1079 break; 1080 case Instruction::kIndexFieldRef: 1081 if (index < header_->FieldIds().Size()) { 1082 field_ids->push_back(header_->FieldIds()[index]); 1083 return true; 1084 } 1085 break; 1086 case Instruction::kIndexUnknown: 1087 case Instruction::kIndexNone: 1088 case Instruction::kIndexVtableOffset: 1089 case Instruction::kIndexFieldOffset: 1090 default: 1091 break; 1092 } // switch 1093 return false; 1094 } 1095 1096 EncodedValue* BuilderMaps::ReadEncodedValue(const DexFile& dex_file, const uint8_t** data) { 1097 const uint8_t encoded_value = *(*data)++; 1098 const uint8_t type = encoded_value & 0x1f; 1099 EncodedValue* item = new EncodedValue(type); 1100 ReadEncodedValue(dex_file, data, type, encoded_value >> 5, item); 1101 return item; 1102 } 1103 1104 EncodedValue* BuilderMaps::ReadEncodedValue(const DexFile& dex_file, 1105 const uint8_t** data, 1106 uint8_t type, 1107 uint8_t length) { 1108 EncodedValue* item = new EncodedValue(type); 1109 ReadEncodedValue(dex_file, data, type, length, item); 1110 return item; 1111 } 1112 1113 void BuilderMaps::ReadEncodedValue(const DexFile& dex_file, 1114 const uint8_t** data, 1115 uint8_t type, 1116 uint8_t length, 1117 EncodedValue* item) { 1118 switch (type) { 1119 case DexFile::kDexAnnotationByte: 1120 item->SetByte(static_cast<int8_t>(ReadVarWidth(data, length, false))); 1121 break; 1122 case DexFile::kDexAnnotationShort: 1123 item->SetShort(static_cast<int16_t>(ReadVarWidth(data, length, true))); 1124 break; 1125 case DexFile::kDexAnnotationChar: 1126 item->SetChar(static_cast<uint16_t>(ReadVarWidth(data, length, false))); 1127 break; 1128 case DexFile::kDexAnnotationInt: 1129 item->SetInt(static_cast<int32_t>(ReadVarWidth(data, length, true))); 1130 break; 1131 case DexFile::kDexAnnotationLong: 1132 item->SetLong(static_cast<int64_t>(ReadVarWidth(data, length, true))); 1133 break; 1134 case DexFile::kDexAnnotationFloat: { 1135 // Fill on right. 1136 union { 1137 float f; 1138 uint32_t data; 1139 } conv; 1140 conv.data = static_cast<uint32_t>(ReadVarWidth(data, length, false)) << (3 - length) * 8; 1141 item->SetFloat(conv.f); 1142 break; 1143 } 1144 case DexFile::kDexAnnotationDouble: { 1145 // Fill on right. 1146 union { 1147 double d; 1148 uint64_t data; 1149 } conv; 1150 conv.data = ReadVarWidth(data, length, false) << (7 - length) * 8; 1151 item->SetDouble(conv.d); 1152 break; 1153 } 1154 case DexFile::kDexAnnotationMethodType: { 1155 const uint32_t proto_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); 1156 item->SetProtoId(header_->ProtoIds()[proto_index]); 1157 break; 1158 } 1159 case DexFile::kDexAnnotationMethodHandle: { 1160 const uint32_t method_handle_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); 1161 item->SetMethodHandle(header_->MethodHandleItems()[method_handle_index]); 1162 break; 1163 } 1164 case DexFile::kDexAnnotationString: { 1165 const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); 1166 item->SetStringId(header_->StringIds()[string_index]); 1167 break; 1168 } 1169 case DexFile::kDexAnnotationType: { 1170 const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); 1171 item->SetTypeId(header_->TypeIds()[string_index]); 1172 break; 1173 } 1174 case DexFile::kDexAnnotationField: 1175 case DexFile::kDexAnnotationEnum: { 1176 const uint32_t field_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); 1177 item->SetFieldId(header_->FieldIds()[field_index]); 1178 break; 1179 } 1180 case DexFile::kDexAnnotationMethod: { 1181 const uint32_t method_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); 1182 item->SetMethodId(header_->MethodIds()[method_index]); 1183 break; 1184 } 1185 case DexFile::kDexAnnotationArray: { 1186 EncodedValueVector* values = new EncodedValueVector(); 1187 const uint32_t offset = *data - dex_file.DataBegin(); 1188 const uint32_t size = DecodeUnsignedLeb128(data); 1189 // Decode all elements. 1190 for (uint32_t i = 0; i < size; i++) { 1191 values->push_back(std::unique_ptr<EncodedValue>(ReadEncodedValue(dex_file, data))); 1192 } 1193 EncodedArrayItem* array_item = new EncodedArrayItem(values); 1194 if (eagerly_assign_offsets_) { 1195 array_item->SetOffset(offset); 1196 } 1197 item->SetEncodedArray(array_item); 1198 break; 1199 } 1200 case DexFile::kDexAnnotationAnnotation: { 1201 AnnotationElementVector* elements = new AnnotationElementVector(); 1202 const uint32_t type_idx = DecodeUnsignedLeb128(data); 1203 const uint32_t size = DecodeUnsignedLeb128(data); 1204 // Decode all name=value pairs. 1205 for (uint32_t i = 0; i < size; i++) { 1206 const uint32_t name_index = DecodeUnsignedLeb128(data); 1207 elements->push_back(std::make_unique<AnnotationElement>( 1208 header_->StringIds()[name_index], 1209 ReadEncodedValue(dex_file, data))); 1210 } 1211 item->SetEncodedAnnotation(new EncodedAnnotation(header_->TypeIds()[type_idx], elements)); 1212 break; 1213 } 1214 case DexFile::kDexAnnotationNull: 1215 break; 1216 case DexFile::kDexAnnotationBoolean: 1217 item->SetBoolean(length != 0); 1218 break; 1219 default: 1220 break; 1221 } 1222 } 1223 1224 MethodItem BuilderMaps::GenerateMethodItem(const DexFile& dex_file, 1225 const ClassAccessor::Method& method) { 1226 MethodId* method_id = header_->MethodIds()[method.GetIndex()]; 1227 uint32_t access_flags = method.GetAccessFlags(); 1228 const dex::CodeItem* disk_code_item = method.GetCodeItem(); 1229 // Temporary hack to prevent incorrectly deduping code items if they have the same offset since 1230 // they may have different debug info streams. 1231 CodeItem* code_item = DedupeOrCreateCodeItem(dex_file, 1232 disk_code_item, 1233 method.GetCodeItemOffset(), 1234 method.GetIndex()); 1235 return MethodItem(access_flags, method_id, code_item); 1236 } 1237 1238 ParameterAnnotation* BuilderMaps::GenerateParameterAnnotation( 1239 const DexFile& dex_file, 1240 MethodId* method_id, 1241 const dex::AnnotationSetRefList* annotation_set_ref_list, 1242 uint32_t offset) { 1243 AnnotationSetRefList* set_ref_list = annotation_set_ref_lists_map_.GetExistingObject(offset); 1244 if (set_ref_list == nullptr) { 1245 std::vector<AnnotationSetItem*>* annotations = new std::vector<AnnotationSetItem*>(); 1246 for (uint32_t i = 0; i < annotation_set_ref_list->size_; ++i) { 1247 const dex::AnnotationSetItem* annotation_set_item = 1248 dex_file.GetSetRefItemItem(&annotation_set_ref_list->list_[i]); 1249 uint32_t set_offset = annotation_set_ref_list->list_[i].annotations_off_; 1250 annotations->push_back(CreateAnnotationSetItem(dex_file, annotation_set_item, set_offset)); 1251 } 1252 set_ref_list = 1253 annotation_set_ref_lists_map_.CreateAndAddItem(header_->AnnotationSetRefLists(), 1254 eagerly_assign_offsets_, 1255 offset, 1256 annotations); 1257 } 1258 return new ParameterAnnotation(method_id, set_ref_list); 1259 } 1260 1261 } // namespace dex_ir 1262 } // namespace art 1263