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 <vector> 21 22#include "dex_ir_builder.h" 23 24namespace art { 25namespace dex_ir { 26 27static void CheckAndSetRemainingOffsets(const DexFile& dex_file, Collections* collections); 28 29Header* DexIrBuilder(const DexFile& dex_file) { 30 const DexFile::Header& disk_header = dex_file.GetHeader(); 31 Header* header = new Header(disk_header.magic_, 32 disk_header.checksum_, 33 disk_header.signature_, 34 disk_header.endian_tag_, 35 disk_header.file_size_, 36 disk_header.header_size_, 37 disk_header.link_size_, 38 disk_header.link_off_, 39 disk_header.data_size_, 40 disk_header.data_off_); 41 Collections& collections = header->GetCollections(); 42 // Walk the rest of the header fields. 43 // StringId table. 44 collections.SetStringIdsOffset(disk_header.string_ids_off_); 45 for (uint32_t i = 0; i < dex_file.NumStringIds(); ++i) { 46 collections.CreateStringId(dex_file, i); 47 } 48 // TypeId table. 49 collections.SetTypeIdsOffset(disk_header.type_ids_off_); 50 for (uint32_t i = 0; i < dex_file.NumTypeIds(); ++i) { 51 collections.CreateTypeId(dex_file, i); 52 } 53 // ProtoId table. 54 collections.SetProtoIdsOffset(disk_header.proto_ids_off_); 55 for (uint32_t i = 0; i < dex_file.NumProtoIds(); ++i) { 56 collections.CreateProtoId(dex_file, i); 57 } 58 // FieldId table. 59 collections.SetFieldIdsOffset(disk_header.field_ids_off_); 60 for (uint32_t i = 0; i < dex_file.NumFieldIds(); ++i) { 61 collections.CreateFieldId(dex_file, i); 62 } 63 // MethodId table. 64 collections.SetMethodIdsOffset(disk_header.method_ids_off_); 65 for (uint32_t i = 0; i < dex_file.NumMethodIds(); ++i) { 66 collections.CreateMethodId(dex_file, i); 67 } 68 // ClassDef table. 69 collections.SetClassDefsOffset(disk_header.class_defs_off_); 70 for (uint32_t i = 0; i < dex_file.NumClassDefs(); ++i) { 71 collections.CreateClassDef(dex_file, i); 72 } 73 // MapItem. 74 collections.SetMapListOffset(disk_header.map_off_); 75 // CallSiteIds and MethodHandleItems. 76 collections.CreateCallSitesAndMethodHandles(dex_file); 77 78 CheckAndSetRemainingOffsets(dex_file, &collections); 79 80 return header; 81} 82 83static void CheckAndSetRemainingOffsets(const DexFile& dex_file, Collections* collections) { 84 const DexFile::Header& disk_header = dex_file.GetHeader(); 85 // Read MapItems and validate/set remaining offsets. 86 const DexFile::MapList* map = 87 reinterpret_cast<const DexFile::MapList*>(dex_file.Begin() + disk_header.map_off_); 88 const uint32_t count = map->size_; 89 for (uint32_t i = 0; i < count; ++i) { 90 const DexFile::MapItem* item = map->list_ + i; 91 switch (item->type_) { 92 case DexFile::kDexTypeHeaderItem: 93 CHECK_EQ(item->size_, 1u); 94 CHECK_EQ(item->offset_, 0u); 95 break; 96 case DexFile::kDexTypeStringIdItem: 97 CHECK_EQ(item->size_, collections->StringIdsSize()); 98 CHECK_EQ(item->offset_, collections->StringIdsOffset()); 99 break; 100 case DexFile::kDexTypeTypeIdItem: 101 CHECK_EQ(item->size_, collections->TypeIdsSize()); 102 CHECK_EQ(item->offset_, collections->TypeIdsOffset()); 103 break; 104 case DexFile::kDexTypeProtoIdItem: 105 CHECK_EQ(item->size_, collections->ProtoIdsSize()); 106 CHECK_EQ(item->offset_, collections->ProtoIdsOffset()); 107 break; 108 case DexFile::kDexTypeFieldIdItem: 109 CHECK_EQ(item->size_, collections->FieldIdsSize()); 110 CHECK_EQ(item->offset_, collections->FieldIdsOffset()); 111 break; 112 case DexFile::kDexTypeMethodIdItem: 113 CHECK_EQ(item->size_, collections->MethodIdsSize()); 114 CHECK_EQ(item->offset_, collections->MethodIdsOffset()); 115 break; 116 case DexFile::kDexTypeClassDefItem: 117 CHECK_EQ(item->size_, collections->ClassDefsSize()); 118 CHECK_EQ(item->offset_, collections->ClassDefsOffset()); 119 break; 120 case DexFile::kDexTypeCallSiteIdItem: 121 CHECK_EQ(item->size_, collections->CallSiteIdsSize()); 122 CHECK_EQ(item->offset_, collections->CallSiteIdsOffset()); 123 break; 124 case DexFile::kDexTypeMethodHandleItem: 125 CHECK_EQ(item->size_, collections->MethodHandleItemsSize()); 126 CHECK_EQ(item->offset_, collections->MethodHandleItemsOffset()); 127 break; 128 case DexFile::kDexTypeMapList: 129 CHECK_EQ(item->size_, 1u); 130 CHECK_EQ(item->offset_, disk_header.map_off_); 131 break; 132 case DexFile::kDexTypeTypeList: 133 collections->SetTypeListsOffset(item->offset_); 134 break; 135 case DexFile::kDexTypeAnnotationSetRefList: 136 collections->SetAnnotationSetRefListsOffset(item->offset_); 137 break; 138 case DexFile::kDexTypeAnnotationSetItem: 139 collections->SetAnnotationSetItemsOffset(item->offset_); 140 break; 141 case DexFile::kDexTypeClassDataItem: 142 collections->SetClassDatasOffset(item->offset_); 143 break; 144 case DexFile::kDexTypeCodeItem: 145 collections->SetCodeItemsOffset(item->offset_); 146 break; 147 case DexFile::kDexTypeStringDataItem: 148 collections->SetStringDatasOffset(item->offset_); 149 break; 150 case DexFile::kDexTypeDebugInfoItem: 151 collections->SetDebugInfoItemsOffset(item->offset_); 152 break; 153 case DexFile::kDexTypeAnnotationItem: 154 collections->SetAnnotationItemsOffset(item->offset_); 155 break; 156 case DexFile::kDexTypeEncodedArrayItem: 157 collections->SetEncodedArrayItemsOffset(item->offset_); 158 break; 159 case DexFile::kDexTypeAnnotationsDirectoryItem: 160 collections->SetAnnotationsDirectoryItemsOffset(item->offset_); 161 break; 162 default: 163 LOG(ERROR) << "Unknown map list item type."; 164 } 165 } 166} 167 168} // namespace dex_ir 169} // namespace art 170