diff options
Diffstat (limited to 'dexlayout/dex_ir_builder.cc')
-rw-r--r-- | dexlayout/dex_ir_builder.cc | 1263 |
1 files changed, 0 insertions, 1263 deletions
diff --git a/dexlayout/dex_ir_builder.cc b/dexlayout/dex_ir_builder.cc deleted file mode 100644 index 5636e2c1f5..0000000000 --- a/dexlayout/dex_ir_builder.cc +++ /dev/null @@ -1,1263 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Header file of an in-memory representation of DEX files. - */ - -#include <stdint.h> -#include <memory> -#include <vector> - -#include "dex_ir_builder.h" - -#include "dex/class_accessor-inl.h" -#include "dex/code_item_accessors-inl.h" -#include "dex/dex_file_exception_helpers.h" -#include "dex/dex_instruction-inl.h" -#include "dexlayout.h" - -namespace art { -namespace dex_ir { - -static uint64_t ReadVarWidth(const uint8_t** data, uint8_t length, bool sign_extend) { - uint64_t value = 0; - for (uint32_t i = 0; i <= length; i++) { - value |= static_cast<uint64_t>(*(*data)++) << (i * 8); - } - if (sign_extend) { - int shift = (7 - length) * 8; - return (static_cast<int64_t>(value) << shift) >> shift; - } - return value; -} - -static uint32_t GetDebugInfoStreamSize(const uint8_t* debug_info_stream) { - const uint8_t* stream = debug_info_stream; - DecodeUnsignedLeb128(&stream); // line_start - uint32_t parameters_size = DecodeUnsignedLeb128(&stream); - for (uint32_t i = 0; i < parameters_size; ++i) { - DecodeUnsignedLeb128P1(&stream); // Parameter name. - } - - for (;;) { - uint8_t opcode = *stream++; - switch (opcode) { - case DexFile::DBG_END_SEQUENCE: - return stream - debug_info_stream; // end of stream. - case DexFile::DBG_ADVANCE_PC: - DecodeUnsignedLeb128(&stream); // addr_diff - break; - case DexFile::DBG_ADVANCE_LINE: - DecodeSignedLeb128(&stream); // line_diff - break; - case DexFile::DBG_START_LOCAL: - DecodeUnsignedLeb128(&stream); // register_num - DecodeUnsignedLeb128P1(&stream); // name_idx - DecodeUnsignedLeb128P1(&stream); // type_idx - break; - case DexFile::DBG_START_LOCAL_EXTENDED: - DecodeUnsignedLeb128(&stream); // register_num - DecodeUnsignedLeb128P1(&stream); // name_idx - DecodeUnsignedLeb128P1(&stream); // type_idx - DecodeUnsignedLeb128P1(&stream); // sig_idx - break; - case DexFile::DBG_END_LOCAL: - case DexFile::DBG_RESTART_LOCAL: - DecodeUnsignedLeb128(&stream); // register_num - break; - case DexFile::DBG_SET_PROLOGUE_END: - case DexFile::DBG_SET_EPILOGUE_BEGIN: - break; - case DexFile::DBG_SET_FILE: { - DecodeUnsignedLeb128P1(&stream); // name_idx - break; - } - default: { - break; - } - } - } -} - -template<class T> class CollectionMap : public CollectionBase { - public: - CollectionMap() = default; - ~CollectionMap() override { } - - template <class... Args> - T* CreateAndAddItem(CollectionVector<T>& vector, - bool eagerly_assign_offsets, - uint32_t offset, - Args&&... args) { - T* item = vector.CreateAndAddItem(std::forward<Args>(args)...); - DCHECK(!GetExistingObject(offset)); - DCHECK(!item->OffsetAssigned()); - if (eagerly_assign_offsets) { - item->SetOffset(offset); - } - AddItem(item, offset); - return item; - } - - // Returns the existing item if it is already inserted, null otherwise. - T* GetExistingObject(uint32_t offset) { - auto it = collection_.find(offset); - return it != collection_.end() ? it->second : nullptr; - } - - uint32_t Size() const override { return size(); } - - // Lower case for template interop with std::map. - uint32_t size() const { return collection_.size(); } - std::map<uint32_t, T*>& Collection() { return collection_; } - - private: - std::map<uint32_t, T*> collection_; - - // CollectionMaps do not own the objects they contain, therefore AddItem is supported - // rather than CreateAndAddItem. - void AddItem(T* object, uint32_t offset) { - auto it = collection_.emplace(offset, object); - CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " " - << " and address " << it.first->second; - } - - DISALLOW_COPY_AND_ASSIGN(CollectionMap); -}; - -class BuilderMaps { - public: - BuilderMaps(Header* header, bool eagerly_assign_offsets) - : header_(header), eagerly_assign_offsets_(eagerly_assign_offsets) { } - - void CreateStringId(const DexFile& dex_file, uint32_t i); - void CreateTypeId(const DexFile& dex_file, uint32_t i); - void CreateProtoId(const DexFile& dex_file, uint32_t i); - void CreateFieldId(const DexFile& dex_file, uint32_t i); - void CreateMethodId(const DexFile& dex_file, uint32_t i); - void CreateClassDef(const DexFile& dex_file, uint32_t i); - void CreateCallSiteId(const DexFile& dex_file, uint32_t i); - void CreateMethodHandleItem(const DexFile& dex_file, uint32_t i); - - void CreateCallSitesAndMethodHandles(const DexFile& dex_file); - - TypeList* CreateTypeList(const dex::TypeList* type_list, uint32_t offset); - EncodedArrayItem* CreateEncodedArrayItem(const DexFile& dex_file, - const uint8_t* static_data, - uint32_t offset); - AnnotationItem* CreateAnnotationItem(const DexFile& dex_file, - const dex::AnnotationItem* annotation); - AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file, - const dex::AnnotationSetItem* disk_annotations_item, uint32_t offset); - AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file, - const dex::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset); - CodeItem* DedupeOrCreateCodeItem(const DexFile& dex_file, - const dex::CodeItem* disk_code_item, - uint32_t offset, - uint32_t dex_method_index); - ClassData* CreateClassData(const DexFile& dex_file, const dex::ClassDef& class_def); - - void AddAnnotationsFromMapListSection(const DexFile& dex_file, - uint32_t start_offset, - uint32_t count); - void AddHiddenapiClassDataFromMapListSection(const DexFile& dex_file, uint32_t offset); - - void CheckAndSetRemainingOffsets(const DexFile& dex_file, const Options& options); - - // Sort the vectors buy map order (same order that was used in the input file). - void SortVectorsByMapOrder(); - - private: - bool GetIdsFromByteCode(const CodeItem* code, - std::vector<TypeId*>* type_ids, - std::vector<StringId*>* string_ids, - std::vector<MethodId*>* method_ids, - std::vector<FieldId*>* field_ids); - - bool GetIdFromInstruction(const Instruction* dec_insn, - std::vector<TypeId*>* type_ids, - std::vector<StringId*>* string_ids, - std::vector<MethodId*>* method_ids, - std::vector<FieldId*>* field_ids); - - EncodedValue* ReadEncodedValue(const DexFile& dex_file, const uint8_t** data); - EncodedValue* ReadEncodedValue(const DexFile& dex_file, - const uint8_t** data, - uint8_t type, - uint8_t length); - void ReadEncodedValue(const DexFile& dex_file, - const uint8_t** data, - uint8_t type, - uint8_t length, - EncodedValue* item); - - MethodItem GenerateMethodItem(const DexFile& dex_file, const ClassAccessor::Method& method); - - ParameterAnnotation* GenerateParameterAnnotation( - const DexFile& dex_file, - MethodId* method_id, - const dex::AnnotationSetRefList* annotation_set_ref_list, - uint32_t offset); - - template <typename Type, class... Args> - Type* CreateAndAddIndexedItem(IndexedCollectionVector<Type>& vector, - uint32_t offset, - uint32_t index, - Args&&... args) { - Type* item = vector.CreateAndAddIndexedItem(index, std::forward<Args>(args)...); - DCHECK(!item->OffsetAssigned()); - if (eagerly_assign_offsets_) { - item->SetOffset(offset); - } - return item; - } - - Header* header_; - // If we eagerly assign offsets during IR building or later after layout. Must be false if - // changing the layout is enabled. - bool eagerly_assign_offsets_; - - // Note: maps do not have ownership. - CollectionMap<StringData> string_datas_map_; - CollectionMap<TypeList> type_lists_map_; - CollectionMap<EncodedArrayItem> encoded_array_items_map_; - CollectionMap<AnnotationItem> annotation_items_map_; - CollectionMap<AnnotationSetItem> annotation_set_items_map_; - CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_map_; - CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_map_; - CollectionMap<DebugInfoItem> debug_info_items_map_; - // Code item maps need to check both the debug info offset and debug info offset, do not use - // CollectionMap. - // First offset is the code item offset, second is the debug info offset. - std::map<std::pair<uint32_t, uint32_t>, CodeItem*> code_items_map_; - CollectionMap<ClassData> class_datas_map_; - - DISALLOW_COPY_AND_ASSIGN(BuilderMaps); -}; - -Header* DexIrBuilder(const DexFile& dex_file, - bool eagerly_assign_offsets, - const Options& options) { - const DexFile::Header& disk_header = dex_file.GetHeader(); - Header* header = new Header(disk_header.magic_, - disk_header.checksum_, - disk_header.signature_, - disk_header.endian_tag_, - disk_header.file_size_, - disk_header.header_size_, - disk_header.link_size_, - disk_header.link_off_, - disk_header.data_size_, - disk_header.data_off_, - dex_file.SupportsDefaultMethods(), - dex_file.NumStringIds(), - dex_file.NumTypeIds(), - dex_file.NumProtoIds(), - dex_file.NumFieldIds(), - dex_file.NumMethodIds(), - dex_file.NumClassDefs()); - BuilderMaps builder_maps(header, eagerly_assign_offsets); - // Walk the rest of the header fields. - // StringId table. - header->StringIds().SetOffset(disk_header.string_ids_off_); - for (uint32_t i = 0; i < dex_file.NumStringIds(); ++i) { - builder_maps.CreateStringId(dex_file, i); - } - // TypeId table. - header->TypeIds().SetOffset(disk_header.type_ids_off_); - for (uint32_t i = 0; i < dex_file.NumTypeIds(); ++i) { - builder_maps.CreateTypeId(dex_file, i); - } - // ProtoId table. - header->ProtoIds().SetOffset(disk_header.proto_ids_off_); - for (uint32_t i = 0; i < dex_file.NumProtoIds(); ++i) { - builder_maps.CreateProtoId(dex_file, i); - } - // FieldId table. - header->FieldIds().SetOffset(disk_header.field_ids_off_); - for (uint32_t i = 0; i < dex_file.NumFieldIds(); ++i) { - builder_maps.CreateFieldId(dex_file, i); - } - // MethodId table. - header->MethodIds().SetOffset(disk_header.method_ids_off_); - for (uint32_t i = 0; i < dex_file.NumMethodIds(); ++i) { - builder_maps.CreateMethodId(dex_file, i); - } - // ClassDef table. - header->ClassDefs().SetOffset(disk_header.class_defs_off_); - for (uint32_t i = 0; i < dex_file.NumClassDefs(); ++i) { - if (!options.class_filter_.empty()) { - // If the filter is enabled (not empty), filter out classes that don't have a matching - // descriptor. - const dex::ClassDef& class_def = dex_file.GetClassDef(i); - const char* descriptor = dex_file.GetClassDescriptor(class_def); - if (options.class_filter_.find(descriptor) == options.class_filter_.end()) { - continue; - } - } - builder_maps.CreateClassDef(dex_file, i); - } - // MapItem. - header->SetMapListOffset(disk_header.map_off_); - // CallSiteIds and MethodHandleItems. - builder_maps.CreateCallSitesAndMethodHandles(dex_file); - builder_maps.CheckAndSetRemainingOffsets(dex_file, options); - - // Sort the vectors by the map order (same order as the file). - builder_maps.SortVectorsByMapOrder(); - - // Load the link data if it exists. - header->SetLinkData(std::vector<uint8_t>( - dex_file.DataBegin() + dex_file.GetHeader().link_off_, - dex_file.DataBegin() + dex_file.GetHeader().link_off_ + dex_file.GetHeader().link_size_)); - - return header; -} - -/* - * Get all the types, strings, methods, and fields referred to from bytecode. - */ -void BuilderMaps::CheckAndSetRemainingOffsets(const DexFile& dex_file, const Options& options) { - const DexFile::Header& disk_header = dex_file.GetHeader(); - // Read MapItems and validate/set remaining offsets. - const dex::MapList* map = dex_file.GetMapList(); - const uint32_t count = map->size_; - for (uint32_t i = 0; i < count; ++i) { - const dex::MapItem* item = map->list_ + i; - switch (item->type_) { - case DexFile::kDexTypeHeaderItem: - CHECK_EQ(item->size_, 1u); - CHECK_EQ(item->offset_, 0u); - break; - case DexFile::kDexTypeStringIdItem: - CHECK_EQ(item->size_, header_->StringIds().Size()); - CHECK_EQ(item->offset_, header_->StringIds().GetOffset()); - break; - case DexFile::kDexTypeTypeIdItem: - CHECK_EQ(item->size_, header_->TypeIds().Size()); - CHECK_EQ(item->offset_, header_->TypeIds().GetOffset()); - break; - case DexFile::kDexTypeProtoIdItem: - CHECK_EQ(item->size_, header_->ProtoIds().Size()); - CHECK_EQ(item->offset_, header_->ProtoIds().GetOffset()); - break; - case DexFile::kDexTypeFieldIdItem: - CHECK_EQ(item->size_, header_->FieldIds().Size()); - CHECK_EQ(item->offset_, header_->FieldIds().GetOffset()); - break; - case DexFile::kDexTypeMethodIdItem: - CHECK_EQ(item->size_, header_->MethodIds().Size()); - CHECK_EQ(item->offset_, header_->MethodIds().GetOffset()); - break; - case DexFile::kDexTypeClassDefItem: - if (options.class_filter_.empty()) { - // The filter may have removed some classes, this will get fixed up during writing. - CHECK_EQ(item->size_, header_->ClassDefs().Size()); - } - CHECK_EQ(item->offset_, header_->ClassDefs().GetOffset()); - break; - case DexFile::kDexTypeCallSiteIdItem: - CHECK_EQ(item->size_, header_->CallSiteIds().Size()); - CHECK_EQ(item->offset_, header_->CallSiteIds().GetOffset()); - break; - case DexFile::kDexTypeMethodHandleItem: - CHECK_EQ(item->size_, header_->MethodHandleItems().Size()); - CHECK_EQ(item->offset_, header_->MethodHandleItems().GetOffset()); - break; - case DexFile::kDexTypeMapList: - CHECK_EQ(item->size_, 1u); - CHECK_EQ(item->offset_, disk_header.map_off_); - break; - case DexFile::kDexTypeTypeList: - header_->TypeLists().SetOffset(item->offset_); - break; - case DexFile::kDexTypeAnnotationSetRefList: - header_->AnnotationSetRefLists().SetOffset(item->offset_); - break; - case DexFile::kDexTypeAnnotationSetItem: - header_->AnnotationSetItems().SetOffset(item->offset_); - break; - case DexFile::kDexTypeClassDataItem: - header_->ClassDatas().SetOffset(item->offset_); - break; - case DexFile::kDexTypeCodeItem: - header_->CodeItems().SetOffset(item->offset_); - break; - case DexFile::kDexTypeStringDataItem: - header_->StringDatas().SetOffset(item->offset_); - break; - case DexFile::kDexTypeDebugInfoItem: - header_->DebugInfoItems().SetOffset(item->offset_); - break; - case DexFile::kDexTypeAnnotationItem: - header_->AnnotationItems().SetOffset(item->offset_); - AddAnnotationsFromMapListSection(dex_file, item->offset_, item->size_); - break; - case DexFile::kDexTypeEncodedArrayItem: - header_->EncodedArrayItems().SetOffset(item->offset_); - break; - case DexFile::kDexTypeAnnotationsDirectoryItem: - header_->AnnotationsDirectoryItems().SetOffset(item->offset_); - break; - case DexFile::kDexTypeHiddenapiClassData: - header_->HiddenapiClassDatas().SetOffset(item->offset_); - AddHiddenapiClassDataFromMapListSection(dex_file, item->offset_); - break; - default: - LOG(ERROR) << "Unknown map list item type."; - } - } -} - -void BuilderMaps::CreateStringId(const DexFile& dex_file, uint32_t i) { - const dex::StringId& disk_string_id = dex_file.GetStringId(dex::StringIndex(i)); - StringData* string_data = - string_datas_map_.CreateAndAddItem(header_->StringDatas(), - eagerly_assign_offsets_, - disk_string_id.string_data_off_, - dex_file.GetStringData(disk_string_id)); - CreateAndAddIndexedItem(header_->StringIds(), - header_->StringIds().GetOffset() + i * StringId::ItemSize(), - i, - string_data); -} - -void BuilderMaps::CreateTypeId(const DexFile& dex_file, uint32_t i) { - const dex::TypeId& disk_type_id = dex_file.GetTypeId(dex::TypeIndex(i)); - CreateAndAddIndexedItem(header_->TypeIds(), - header_->TypeIds().GetOffset() + i * TypeId::ItemSize(), - i, - header_->StringIds()[disk_type_id.descriptor_idx_.index_]); -} - -void BuilderMaps::CreateProtoId(const DexFile& dex_file, uint32_t i) { - const dex::ProtoId& disk_proto_id = dex_file.GetProtoId(dex::ProtoIndex(i)); - const dex::TypeList* type_list = dex_file.GetProtoParameters(disk_proto_id); - TypeList* parameter_type_list = CreateTypeList(type_list, disk_proto_id.parameters_off_); - - CreateAndAddIndexedItem(header_->ProtoIds(), - header_->ProtoIds().GetOffset() + i * ProtoId::ItemSize(), - i, - header_->StringIds()[disk_proto_id.shorty_idx_.index_], - header_->TypeIds()[disk_proto_id.return_type_idx_.index_], - parameter_type_list); -} - -void BuilderMaps::CreateFieldId(const DexFile& dex_file, uint32_t i) { - const dex::FieldId& disk_field_id = dex_file.GetFieldId(i); - CreateAndAddIndexedItem(header_->FieldIds(), - header_->FieldIds().GetOffset() + i * FieldId::ItemSize(), - i, - header_->TypeIds()[disk_field_id.class_idx_.index_], - header_->TypeIds()[disk_field_id.type_idx_.index_], - header_->StringIds()[disk_field_id.name_idx_.index_]); -} - -void BuilderMaps::CreateMethodId(const DexFile& dex_file, uint32_t i) { - const dex::MethodId& disk_method_id = dex_file.GetMethodId(i); - CreateAndAddIndexedItem(header_->MethodIds(), - header_->MethodIds().GetOffset() + i * MethodId::ItemSize(), - i, - header_->TypeIds()[disk_method_id.class_idx_.index_], - header_->ProtoIds()[disk_method_id.proto_idx_.index_], - header_->StringIds()[disk_method_id.name_idx_.index_]); -} - -void BuilderMaps::CreateClassDef(const DexFile& dex_file, uint32_t i) { - const dex::ClassDef& disk_class_def = dex_file.GetClassDef(i); - const TypeId* class_type = header_->TypeIds()[disk_class_def.class_idx_.index_]; - uint32_t access_flags = disk_class_def.access_flags_; - const TypeId* superclass = header_->GetTypeIdOrNullPtr(disk_class_def.superclass_idx_.index_); - - const dex::TypeList* type_list = dex_file.GetInterfacesList(disk_class_def); - TypeList* interfaces_type_list = CreateTypeList(type_list, disk_class_def.interfaces_off_); - - const StringId* source_file = - header_->GetStringIdOrNullPtr(disk_class_def.source_file_idx_.index_); - // Annotations. - AnnotationsDirectoryItem* annotations = nullptr; - const dex::AnnotationsDirectoryItem* disk_annotations_directory_item = - dex_file.GetAnnotationsDirectory(disk_class_def); - if (disk_annotations_directory_item != nullptr) { - annotations = CreateAnnotationsDirectoryItem( - dex_file, disk_annotations_directory_item, disk_class_def.annotations_off_); - } - // Static field initializers. - const uint8_t* static_data = dex_file.GetEncodedStaticFieldValuesArray(disk_class_def); - EncodedArrayItem* static_values = - CreateEncodedArrayItem(dex_file, static_data, disk_class_def.static_values_off_); - ClassData* class_data = CreateClassData(dex_file, disk_class_def); - CreateAndAddIndexedItem(header_->ClassDefs(), - header_->ClassDefs().GetOffset() + i * ClassDef::ItemSize(), - i, - class_type, - access_flags, - superclass, - interfaces_type_list, - source_file, - annotations, - static_values, - class_data); -} - -void BuilderMaps::CreateCallSiteId(const DexFile& dex_file, uint32_t i) { - const dex::CallSiteIdItem& disk_call_site_id = dex_file.GetCallSiteId(i); - const uint8_t* disk_call_item_ptr = dex_file.DataBegin() + disk_call_site_id.data_off_; - EncodedArrayItem* call_site_item = - CreateEncodedArrayItem(dex_file, disk_call_item_ptr, disk_call_site_id.data_off_); - - CreateAndAddIndexedItem(header_->CallSiteIds(), - header_->CallSiteIds().GetOffset() + i * CallSiteId::ItemSize(), - i, - call_site_item); -} - -void BuilderMaps::CreateMethodHandleItem(const DexFile& dex_file, uint32_t i) { - const dex::MethodHandleItem& disk_method_handle = dex_file.GetMethodHandle(i); - uint16_t index = disk_method_handle.field_or_method_idx_; - DexFile::MethodHandleType type = - static_cast<DexFile::MethodHandleType>(disk_method_handle.method_handle_type_); - bool is_invoke = type == DexFile::MethodHandleType::kInvokeStatic || - type == DexFile::MethodHandleType::kInvokeInstance || - type == DexFile::MethodHandleType::kInvokeConstructor || - type == DexFile::MethodHandleType::kInvokeDirect || - type == DexFile::MethodHandleType::kInvokeInterface; - static_assert(DexFile::MethodHandleType::kLast == DexFile::MethodHandleType::kInvokeInterface, - "Unexpected method handle types."); - IndexedItem* field_or_method_id; - if (is_invoke) { - field_or_method_id = header_->MethodIds()[index]; - } else { - field_or_method_id = header_->FieldIds()[index]; - } - CreateAndAddIndexedItem(header_->MethodHandleItems(), - header_->MethodHandleItems().GetOffset() + - i * MethodHandleItem::ItemSize(), - i, - type, - field_or_method_id); -} - -void BuilderMaps::CreateCallSitesAndMethodHandles(const DexFile& dex_file) { - // Iterate through the map list and set the offset of the CallSiteIds and MethodHandleItems. - const dex::MapList* map = dex_file.GetMapList(); - for (uint32_t i = 0; i < map->size_; ++i) { - const dex::MapItem* item = map->list_ + i; - switch (item->type_) { - case DexFile::kDexTypeCallSiteIdItem: - header_->CallSiteIds().SetOffset(item->offset_); - break; - case DexFile::kDexTypeMethodHandleItem: - header_->MethodHandleItems().SetOffset(item->offset_); - break; - default: - break; - } - } - // Populate MethodHandleItems first (CallSiteIds may depend on them). - for (uint32_t i = 0; i < dex_file.NumMethodHandles(); i++) { - CreateMethodHandleItem(dex_file, i); - } - // Populate CallSiteIds. - for (uint32_t i = 0; i < dex_file.NumCallSiteIds(); i++) { - CreateCallSiteId(dex_file, i); - } -} - -TypeList* BuilderMaps::CreateTypeList(const dex::TypeList* dex_type_list, uint32_t offset) { - if (dex_type_list == nullptr) { - return nullptr; - } - TypeList* type_list = type_lists_map_.GetExistingObject(offset); - if (type_list == nullptr) { - TypeIdVector* type_vector = new TypeIdVector(); - uint32_t size = dex_type_list->Size(); - for (uint32_t index = 0; index < size; ++index) { - type_vector->push_back(header_->TypeIds()[ - dex_type_list->GetTypeItem(index).type_idx_.index_]); - } - type_list = type_lists_map_.CreateAndAddItem(header_->TypeLists(), - eagerly_assign_offsets_, - offset, - type_vector); - } - return type_list; -} - -EncodedArrayItem* BuilderMaps::CreateEncodedArrayItem(const DexFile& dex_file, - const uint8_t* static_data, - uint32_t offset) { - if (static_data == nullptr) { - return nullptr; - } - EncodedArrayItem* encoded_array_item = encoded_array_items_map_.GetExistingObject(offset); - if (encoded_array_item == nullptr) { - uint32_t size = DecodeUnsignedLeb128(&static_data); - EncodedValueVector* values = new EncodedValueVector(); - for (uint32_t i = 0; i < size; ++i) { - values->push_back(std::unique_ptr<EncodedValue>(ReadEncodedValue(dex_file, &static_data))); - } - // TODO: Calculate the size of the encoded array. - encoded_array_item = encoded_array_items_map_.CreateAndAddItem(header_->EncodedArrayItems(), - eagerly_assign_offsets_, - offset, - values); - } - return encoded_array_item; -} - -void BuilderMaps::AddAnnotationsFromMapListSection(const DexFile& dex_file, - uint32_t start_offset, - uint32_t count) { - uint32_t current_offset = start_offset; - for (size_t i = 0; i < count; ++i) { - // Annotation that we didn't process already, add it to the set. - const dex::AnnotationItem* annotation = dex_file.GetAnnotationItemAtOffset(current_offset); - AnnotationItem* annotation_item = CreateAnnotationItem(dex_file, annotation); - DCHECK(annotation_item != nullptr); - current_offset += annotation_item->GetSize(); - } -} - -void BuilderMaps::AddHiddenapiClassDataFromMapListSection(const DexFile& dex_file, - uint32_t offset) { - const dex::HiddenapiClassData* hiddenapi_class_data = - dex_file.GetHiddenapiClassDataAtOffset(offset); - DCHECK(hiddenapi_class_data == dex_file.GetHiddenapiClassData()); - - for (auto& class_def : header_->ClassDefs()) { - uint32_t index = class_def->GetIndex(); - ClassData* class_data = class_def->GetClassData(); - const uint8_t* ptr = hiddenapi_class_data->GetFlagsPointer(index); - - std::unique_ptr<HiddenapiFlagsMap> flags = nullptr; - if (ptr != nullptr) { - DCHECK(class_data != nullptr); - flags = std::make_unique<HiddenapiFlagsMap>(); - for (const dex_ir::FieldItem& field : *class_data->StaticFields()) { - flags->emplace(&field, DecodeUnsignedLeb128(&ptr)); - } - for (const dex_ir::FieldItem& field : *class_data->InstanceFields()) { - flags->emplace(&field, DecodeUnsignedLeb128(&ptr)); - } - for (const dex_ir::MethodItem& method : *class_data->DirectMethods()) { - flags->emplace(&method, DecodeUnsignedLeb128(&ptr)); - } - for (const dex_ir::MethodItem& method : *class_data->VirtualMethods()) { - flags->emplace(&method, DecodeUnsignedLeb128(&ptr)); - } - } - - CreateAndAddIndexedItem(header_->HiddenapiClassDatas(), - header_->HiddenapiClassDatas().GetOffset() + - hiddenapi_class_data->flags_offset_[index], - index, - class_def.get(), - std::move(flags)); - } -} - -AnnotationItem* BuilderMaps::CreateAnnotationItem(const DexFile& dex_file, - const dex::AnnotationItem* annotation) { - const uint8_t* const start_data = reinterpret_cast<const uint8_t*>(annotation); - const uint32_t offset = start_data - dex_file.DataBegin(); - AnnotationItem* annotation_item = annotation_items_map_.GetExistingObject(offset); - if (annotation_item == nullptr) { - uint8_t visibility = annotation->visibility_; - const uint8_t* annotation_data = annotation->annotation_; - std::unique_ptr<EncodedValue> encoded_value( - ReadEncodedValue(dex_file, &annotation_data, DexFile::kDexAnnotationAnnotation, 0)); - annotation_item = - annotation_items_map_.CreateAndAddItem(header_->AnnotationItems(), - eagerly_assign_offsets_, - offset, - visibility, - encoded_value->ReleaseEncodedAnnotation()); - annotation_item->SetSize(annotation_data - start_data); - } - return annotation_item; -} - - -AnnotationSetItem* BuilderMaps::CreateAnnotationSetItem(const DexFile& dex_file, - const dex::AnnotationSetItem* disk_annotations_item, uint32_t offset) { - if (disk_annotations_item == nullptr || (disk_annotations_item->size_ == 0 && offset == 0)) { - return nullptr; - } - AnnotationSetItem* annotation_set_item = annotation_set_items_map_.GetExistingObject(offset); - if (annotation_set_item == nullptr) { - std::vector<AnnotationItem*>* items = new std::vector<AnnotationItem*>(); - for (uint32_t i = 0; i < disk_annotations_item->size_; ++i) { - const dex::AnnotationItem* annotation = - dex_file.GetAnnotationItem(disk_annotations_item, i); - if (annotation == nullptr) { - continue; - } - AnnotationItem* annotation_item = CreateAnnotationItem(dex_file, annotation); - items->push_back(annotation_item); - } - annotation_set_item = - annotation_set_items_map_.CreateAndAddItem(header_->AnnotationSetItems(), - eagerly_assign_offsets_, - offset, - items); - } - return annotation_set_item; -} - -AnnotationsDirectoryItem* BuilderMaps::CreateAnnotationsDirectoryItem(const DexFile& dex_file, - const dex::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset) { - AnnotationsDirectoryItem* annotations_directory_item = - annotations_directory_items_map_.GetExistingObject(offset); - if (annotations_directory_item != nullptr) { - return annotations_directory_item; - } - const dex::AnnotationSetItem* class_set_item = - dex_file.GetClassAnnotationSet(disk_annotations_item); - AnnotationSetItem* class_annotation = nullptr; - if (class_set_item != nullptr) { - uint32_t item_offset = disk_annotations_item->class_annotations_off_; - class_annotation = CreateAnnotationSetItem(dex_file, class_set_item, item_offset); - } - const dex::FieldAnnotationsItem* fields = - dex_file.GetFieldAnnotations(disk_annotations_item); - FieldAnnotationVector* field_annotations = nullptr; - if (fields != nullptr) { - field_annotations = new FieldAnnotationVector(); - for (uint32_t i = 0; i < disk_annotations_item->fields_size_; ++i) { - FieldId* field_id = header_->FieldIds()[fields[i].field_idx_]; - const dex::AnnotationSetItem* field_set_item = - dex_file.GetFieldAnnotationSetItem(fields[i]); - uint32_t annotation_set_offset = fields[i].annotations_off_; - AnnotationSetItem* annotation_set_item = - CreateAnnotationSetItem(dex_file, field_set_item, annotation_set_offset); - field_annotations->push_back(std::make_unique<FieldAnnotation>( - field_id, annotation_set_item)); - } - } - const dex::MethodAnnotationsItem* methods = - dex_file.GetMethodAnnotations(disk_annotations_item); - MethodAnnotationVector* method_annotations = nullptr; - if (methods != nullptr) { - method_annotations = new MethodAnnotationVector(); - for (uint32_t i = 0; i < disk_annotations_item->methods_size_; ++i) { - MethodId* method_id = header_->MethodIds()[methods[i].method_idx_]; - const dex::AnnotationSetItem* method_set_item = - dex_file.GetMethodAnnotationSetItem(methods[i]); - uint32_t annotation_set_offset = methods[i].annotations_off_; - AnnotationSetItem* annotation_set_item = - CreateAnnotationSetItem(dex_file, method_set_item, annotation_set_offset); - method_annotations->push_back(std::make_unique<MethodAnnotation>( - method_id, annotation_set_item)); - } - } - const dex::ParameterAnnotationsItem* parameters = - dex_file.GetParameterAnnotations(disk_annotations_item); - ParameterAnnotationVector* parameter_annotations = nullptr; - if (parameters != nullptr) { - parameter_annotations = new ParameterAnnotationVector(); - for (uint32_t i = 0; i < disk_annotations_item->parameters_size_; ++i) { - MethodId* method_id = header_->MethodIds()[parameters[i].method_idx_]; - const dex::AnnotationSetRefList* list = - dex_file.GetParameterAnnotationSetRefList(¶meters[i]); - parameter_annotations->push_back(std::unique_ptr<ParameterAnnotation>( - GenerateParameterAnnotation(dex_file, method_id, list, parameters[i].annotations_off_))); - } - } - // TODO: Calculate the size of the annotations directory. - return annotations_directory_items_map_.CreateAndAddItem(header_->AnnotationsDirectoryItems(), - eagerly_assign_offsets_, - offset, - class_annotation, - field_annotations, - method_annotations, - parameter_annotations); -} - -CodeItem* BuilderMaps::DedupeOrCreateCodeItem(const DexFile& dex_file, - const dex::CodeItem* disk_code_item, - uint32_t offset, - uint32_t dex_method_index) { - if (disk_code_item == nullptr) { - return nullptr; - } - CodeItemDebugInfoAccessor accessor(dex_file, disk_code_item, dex_method_index); - const uint32_t debug_info_offset = accessor.DebugInfoOffset(); - - // Create the offsets pair and dedupe based on it. - std::pair<uint32_t, uint32_t> offsets_pair(offset, debug_info_offset); - auto existing = code_items_map_.find(offsets_pair); - if (existing != code_items_map_.end()) { - return existing->second; - } - - const uint8_t* debug_info_stream = dex_file.GetDebugInfoStream(debug_info_offset); - DebugInfoItem* debug_info = nullptr; - if (debug_info_stream != nullptr) { - debug_info = debug_info_items_map_.GetExistingObject(debug_info_offset); - if (debug_info == nullptr) { - uint32_t debug_info_size = GetDebugInfoStreamSize(debug_info_stream); - uint8_t* debug_info_buffer = new uint8_t[debug_info_size]; - memcpy(debug_info_buffer, debug_info_stream, debug_info_size); - debug_info = debug_info_items_map_.CreateAndAddItem(header_->DebugInfoItems(), - eagerly_assign_offsets_, - debug_info_offset, - debug_info_size, - debug_info_buffer); - } - } - - uint32_t insns_size = accessor.InsnsSizeInCodeUnits(); - uint16_t* insns = new uint16_t[insns_size]; - memcpy(insns, accessor.Insns(), insns_size * sizeof(uint16_t)); - - TryItemVector* tries = nullptr; - CatchHandlerVector* handler_list = nullptr; - if (accessor.TriesSize() > 0) { - tries = new TryItemVector(); - handler_list = new CatchHandlerVector(); - for (const dex::TryItem& disk_try_item : accessor.TryItems()) { - uint32_t start_addr = disk_try_item.start_addr_; - uint16_t insn_count = disk_try_item.insn_count_; - uint16_t handler_off = disk_try_item.handler_off_; - const CatchHandler* handlers = nullptr; - for (std::unique_ptr<const CatchHandler>& existing_handlers : *handler_list) { - if (handler_off == existing_handlers->GetListOffset()) { - handlers = existing_handlers.get(); - break; - } - } - if (handlers == nullptr) { - bool catch_all = false; - TypeAddrPairVector* addr_pairs = new TypeAddrPairVector(); - for (CatchHandlerIterator it(accessor, disk_try_item); it.HasNext(); it.Next()) { - const dex::TypeIndex type_index = it.GetHandlerTypeIndex(); - const TypeId* type_id = header_->GetTypeIdOrNullPtr(type_index.index_); - catch_all |= type_id == nullptr; - addr_pairs->push_back(std::unique_ptr<const TypeAddrPair>( - new TypeAddrPair(type_id, it.GetHandlerAddress()))); - } - handlers = new CatchHandler(catch_all, handler_off, addr_pairs); - handler_list->push_back(std::unique_ptr<const CatchHandler>(handlers)); - } - TryItem* try_item = new TryItem(start_addr, insn_count, handlers); - tries->push_back(std::unique_ptr<const TryItem>(try_item)); - } - // Manually walk catch handlers list and add any missing handlers unreferenced by try items. - const uint8_t* handlers_base = accessor.GetCatchHandlerData(); - const uint8_t* handlers_data = handlers_base; - uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_data); - while (handlers_size > handler_list->size()) { - bool already_added = false; - uint16_t handler_off = handlers_data - handlers_base; - for (std::unique_ptr<const CatchHandler>& existing_handlers : *handler_list) { - if (handler_off == existing_handlers->GetListOffset()) { - already_added = true; - break; - } - } - int32_t size = DecodeSignedLeb128(&handlers_data); - bool has_catch_all = size <= 0; - if (has_catch_all) { - size = -size; - } - if (already_added) { - for (int32_t i = 0; i < size; i++) { - DecodeUnsignedLeb128(&handlers_data); - DecodeUnsignedLeb128(&handlers_data); - } - if (has_catch_all) { - DecodeUnsignedLeb128(&handlers_data); - } - continue; - } - TypeAddrPairVector* addr_pairs = new TypeAddrPairVector(); - for (int32_t i = 0; i < size; i++) { - const TypeId* type_id = - header_->GetTypeIdOrNullPtr(DecodeUnsignedLeb128(&handlers_data)); - uint32_t addr = DecodeUnsignedLeb128(&handlers_data); - addr_pairs->push_back( - std::unique_ptr<const TypeAddrPair>(new TypeAddrPair(type_id, addr))); - } - if (has_catch_all) { - uint32_t addr = DecodeUnsignedLeb128(&handlers_data); - addr_pairs->push_back( - std::unique_ptr<const TypeAddrPair>(new TypeAddrPair(nullptr, addr))); - } - const CatchHandler* handler = new CatchHandler(has_catch_all, handler_off, addr_pairs); - handler_list->push_back(std::unique_ptr<const CatchHandler>(handler)); - } - } - - uint32_t size = dex_file.GetCodeItemSize(*disk_code_item); - CodeItem* code_item = header_->CodeItems().CreateAndAddItem(accessor.RegistersSize(), - accessor.InsSize(), - accessor.OutsSize(), - debug_info, - insns_size, - insns, - tries, - handler_list); - code_item->SetSize(size); - - // Add the code item to the map. - DCHECK(!code_item->OffsetAssigned()); - if (eagerly_assign_offsets_) { - code_item->SetOffset(offset); - } - code_items_map_.emplace(offsets_pair, code_item); - - // Add "fixup" references to types, strings, methods, and fields. - // This is temporary, as we will probably want more detailed parsing of the - // instructions here. - std::vector<TypeId*> type_ids; - std::vector<StringId*> string_ids; - std::vector<MethodId*> method_ids; - std::vector<FieldId*> field_ids; - if (GetIdsFromByteCode(code_item, - /*out*/ &type_ids, - /*out*/ &string_ids, - /*out*/ &method_ids, - /*out*/ &field_ids)) { - CodeFixups* fixups = new CodeFixups(std::move(type_ids), - std::move(string_ids), - std::move(method_ids), - std::move(field_ids)); - code_item->SetCodeFixups(fixups); - } - - return code_item; -} - -ClassData* BuilderMaps::CreateClassData(const DexFile& dex_file, - const dex::ClassDef& class_def) { - // Read the fields and methods defined by the class, resolving the circular reference from those - // to classes by setting class at the same time. - const uint32_t offset = class_def.class_data_off_; - ClassData* class_data = class_datas_map_.GetExistingObject(offset); - if (class_data == nullptr && offset != 0u) { - ClassAccessor accessor(dex_file, class_def); - // Static fields. - FieldItemVector* static_fields = new FieldItemVector(); - for (const ClassAccessor::Field& field : accessor.GetStaticFields()) { - FieldId* field_item = header_->FieldIds()[field.GetIndex()]; - uint32_t access_flags = field.GetAccessFlags(); - static_fields->emplace_back(access_flags, field_item); - } - FieldItemVector* instance_fields = new FieldItemVector(); - for (const ClassAccessor::Field& field : accessor.GetInstanceFields()) { - FieldId* field_item = header_->FieldIds()[field.GetIndex()]; - uint32_t access_flags = field.GetAccessFlags(); - instance_fields->emplace_back(access_flags, field_item); - } - // Direct methods. - MethodItemVector* direct_methods = new MethodItemVector(); - auto direct_methods_it = accessor.GetDirectMethods(); - for (auto it = direct_methods_it.begin(); it != direct_methods_it.end(); ++it) { - direct_methods->push_back(GenerateMethodItem(dex_file, *it)); - } - // Virtual methods. - MethodItemVector* virtual_methods = new MethodItemVector(); - auto virtual_methods_it = accessor.GetVirtualMethods(); - const uint8_t* last_data_ptr; - for (auto it = virtual_methods_it.begin(); ; ++it) { - if (it == virtual_methods_it.end()) { - last_data_ptr = it->GetDataPointer(); - break; - } - virtual_methods->push_back(GenerateMethodItem(dex_file, *it)); - } - class_data = class_datas_map_.CreateAndAddItem(header_->ClassDatas(), - eagerly_assign_offsets_, - offset, - static_fields, - instance_fields, - direct_methods, - virtual_methods); - class_data->SetSize(last_data_ptr - dex_file.GetClassData(class_def)); - } - return class_data; -} - -void BuilderMaps::SortVectorsByMapOrder() { - header_->StringDatas().SortByMapOrder(string_datas_map_.Collection()); - header_->TypeLists().SortByMapOrder(type_lists_map_.Collection()); - header_->EncodedArrayItems().SortByMapOrder(encoded_array_items_map_.Collection()); - header_->AnnotationItems().SortByMapOrder(annotation_items_map_.Collection()); - header_->AnnotationSetItems().SortByMapOrder(annotation_set_items_map_.Collection()); - header_->AnnotationSetRefLists().SortByMapOrder(annotation_set_ref_lists_map_.Collection()); - header_->AnnotationsDirectoryItems().SortByMapOrder( - annotations_directory_items_map_.Collection()); - header_->DebugInfoItems().SortByMapOrder(debug_info_items_map_.Collection()); - header_->CodeItems().SortByMapOrder(code_items_map_); - header_->ClassDatas().SortByMapOrder(class_datas_map_.Collection()); -} - -bool BuilderMaps::GetIdsFromByteCode(const CodeItem* code, - std::vector<TypeId*>* type_ids, - std::vector<StringId*>* string_ids, - std::vector<MethodId*>* method_ids, - std::vector<FieldId*>* field_ids) { - bool has_id = false; - IterationRange<DexInstructionIterator> instructions = code->Instructions(); - SafeDexInstructionIterator it(instructions.begin(), instructions.end()); - for (; !it.IsErrorState() && it < instructions.end(); ++it) { - // In case the instruction goes past the end of the code item, make sure to not process it. - SafeDexInstructionIterator next = it; - ++next; - if (next.IsErrorState()) { - break; - } - has_id |= GetIdFromInstruction(&it.Inst(), type_ids, string_ids, method_ids, field_ids); - } // for - return has_id; -} - -bool BuilderMaps::GetIdFromInstruction(const Instruction* dec_insn, - std::vector<TypeId*>* type_ids, - std::vector<StringId*>* string_ids, - std::vector<MethodId*>* method_ids, - std::vector<FieldId*>* field_ids) { - // Determine index and width of the string. - uint32_t index = 0; - switch (Instruction::FormatOf(dec_insn->Opcode())) { - // SOME NOT SUPPORTED: - // case Instruction::k20bc: - case Instruction::k21c: - case Instruction::k35c: - // case Instruction::k35ms: - case Instruction::k3rc: - // case Instruction::k3rms: - // case Instruction::k35mi: - // case Instruction::k3rmi: - case Instruction::k45cc: - case Instruction::k4rcc: - index = dec_insn->VRegB(); - break; - case Instruction::k31c: - index = dec_insn->VRegB(); - break; - case Instruction::k22c: - // case Instruction::k22cs: - index = dec_insn->VRegC(); - break; - default: - break; - } // switch - - // Determine index type, and add reference to the appropriate collection. - switch (Instruction::IndexTypeOf(dec_insn->Opcode())) { - case Instruction::kIndexTypeRef: - if (index < header_->TypeIds().Size()) { - type_ids->push_back(header_->TypeIds()[index]); - return true; - } - break; - case Instruction::kIndexStringRef: - if (index < header_->StringIds().Size()) { - string_ids->push_back(header_->StringIds()[index]); - return true; - } - break; - case Instruction::kIndexMethodRef: - case Instruction::kIndexMethodAndProtoRef: - if (index < header_->MethodIds().Size()) { - method_ids->push_back(header_->MethodIds()[index]); - return true; - } - break; - case Instruction::kIndexFieldRef: - if (index < header_->FieldIds().Size()) { - field_ids->push_back(header_->FieldIds()[index]); - return true; - } - break; - case Instruction::kIndexUnknown: - case Instruction::kIndexNone: - case Instruction::kIndexVtableOffset: - case Instruction::kIndexFieldOffset: - default: - break; - } // switch - return false; -} - -EncodedValue* BuilderMaps::ReadEncodedValue(const DexFile& dex_file, const uint8_t** data) { - const uint8_t encoded_value = *(*data)++; - const uint8_t type = encoded_value & 0x1f; - EncodedValue* item = new EncodedValue(type); - ReadEncodedValue(dex_file, data, type, encoded_value >> 5, item); - return item; -} - -EncodedValue* BuilderMaps::ReadEncodedValue(const DexFile& dex_file, - const uint8_t** data, - uint8_t type, - uint8_t length) { - EncodedValue* item = new EncodedValue(type); - ReadEncodedValue(dex_file, data, type, length, item); - return item; -} - -void BuilderMaps::ReadEncodedValue(const DexFile& dex_file, - const uint8_t** data, - uint8_t type, - uint8_t length, - EncodedValue* item) { - switch (type) { - case DexFile::kDexAnnotationByte: - item->SetByte(static_cast<int8_t>(ReadVarWidth(data, length, false))); - break; - case DexFile::kDexAnnotationShort: - item->SetShort(static_cast<int16_t>(ReadVarWidth(data, length, true))); - break; - case DexFile::kDexAnnotationChar: - item->SetChar(static_cast<uint16_t>(ReadVarWidth(data, length, false))); - break; - case DexFile::kDexAnnotationInt: - item->SetInt(static_cast<int32_t>(ReadVarWidth(data, length, true))); - break; - case DexFile::kDexAnnotationLong: - item->SetLong(static_cast<int64_t>(ReadVarWidth(data, length, true))); - break; - case DexFile::kDexAnnotationFloat: { - // Fill on right. - union { - float f; - uint32_t data; - } conv; - conv.data = static_cast<uint32_t>(ReadVarWidth(data, length, false)) << (3 - length) * 8; - item->SetFloat(conv.f); - break; - } - case DexFile::kDexAnnotationDouble: { - // Fill on right. - union { - double d; - uint64_t data; - } conv; - conv.data = ReadVarWidth(data, length, false) << (7 - length) * 8; - item->SetDouble(conv.d); - break; - } - case DexFile::kDexAnnotationMethodType: { - const uint32_t proto_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); - item->SetProtoId(header_->ProtoIds()[proto_index]); - break; - } - case DexFile::kDexAnnotationMethodHandle: { - const uint32_t method_handle_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); - item->SetMethodHandle(header_->MethodHandleItems()[method_handle_index]); - break; - } - case DexFile::kDexAnnotationString: { - const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); - item->SetStringId(header_->StringIds()[string_index]); - break; - } - case DexFile::kDexAnnotationType: { - const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); - item->SetTypeId(header_->TypeIds()[string_index]); - break; - } - case DexFile::kDexAnnotationField: - case DexFile::kDexAnnotationEnum: { - const uint32_t field_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); - item->SetFieldId(header_->FieldIds()[field_index]); - break; - } - case DexFile::kDexAnnotationMethod: { - const uint32_t method_index = static_cast<uint32_t>(ReadVarWidth(data, length, false)); - item->SetMethodId(header_->MethodIds()[method_index]); - break; - } - case DexFile::kDexAnnotationArray: { - EncodedValueVector* values = new EncodedValueVector(); - const uint32_t offset = *data - dex_file.DataBegin(); - const uint32_t size = DecodeUnsignedLeb128(data); - // Decode all elements. - for (uint32_t i = 0; i < size; i++) { - values->push_back(std::unique_ptr<EncodedValue>(ReadEncodedValue(dex_file, data))); - } - EncodedArrayItem* array_item = new EncodedArrayItem(values); - if (eagerly_assign_offsets_) { - array_item->SetOffset(offset); - } - item->SetEncodedArray(array_item); - break; - } - case DexFile::kDexAnnotationAnnotation: { - AnnotationElementVector* elements = new AnnotationElementVector(); - const uint32_t type_idx = DecodeUnsignedLeb128(data); - const uint32_t size = DecodeUnsignedLeb128(data); - // Decode all name=value pairs. - for (uint32_t i = 0; i < size; i++) { - const uint32_t name_index = DecodeUnsignedLeb128(data); - elements->push_back(std::make_unique<AnnotationElement>( - header_->StringIds()[name_index], - ReadEncodedValue(dex_file, data))); - } - item->SetEncodedAnnotation(new EncodedAnnotation(header_->TypeIds()[type_idx], elements)); - break; - } - case DexFile::kDexAnnotationNull: - break; - case DexFile::kDexAnnotationBoolean: - item->SetBoolean(length != 0); - break; - default: - break; - } -} - -MethodItem BuilderMaps::GenerateMethodItem(const DexFile& dex_file, - const ClassAccessor::Method& method) { - MethodId* method_id = header_->MethodIds()[method.GetIndex()]; - uint32_t access_flags = method.GetAccessFlags(); - const dex::CodeItem* disk_code_item = method.GetCodeItem(); - // Temporary hack to prevent incorrectly deduping code items if they have the same offset since - // they may have different debug info streams. - CodeItem* code_item = DedupeOrCreateCodeItem(dex_file, - disk_code_item, - method.GetCodeItemOffset(), - method.GetIndex()); - return MethodItem(access_flags, method_id, code_item); -} - -ParameterAnnotation* BuilderMaps::GenerateParameterAnnotation( - const DexFile& dex_file, - MethodId* method_id, - const dex::AnnotationSetRefList* annotation_set_ref_list, - uint32_t offset) { - AnnotationSetRefList* set_ref_list = annotation_set_ref_lists_map_.GetExistingObject(offset); - if (set_ref_list == nullptr) { - std::vector<AnnotationSetItem*>* annotations = new std::vector<AnnotationSetItem*>(); - for (uint32_t i = 0; i < annotation_set_ref_list->size_; ++i) { - const dex::AnnotationSetItem* annotation_set_item = - dex_file.GetSetRefItemItem(&annotation_set_ref_list->list_[i]); - uint32_t set_offset = annotation_set_ref_list->list_[i].annotations_off_; - annotations->push_back(CreateAnnotationSetItem(dex_file, annotation_set_item, set_offset)); - } - set_ref_list = - annotation_set_ref_lists_map_.CreateAndAddItem(header_->AnnotationSetRefLists(), - eagerly_assign_offsets_, - offset, - annotations); - } - return new ParameterAnnotation(method_id, set_ref_list); -} - -} // namespace dex_ir -} // namespace art |