Home | History | Annotate | Download | only in dexlayout
      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(&parameters[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