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 #ifndef ART_DEXLAYOUT_DEX_IR_H_ 20 #define ART_DEXLAYOUT_DEX_IR_H_ 21 22 #include <map> 23 #include <vector> 24 #include <stdint.h> 25 26 #include "dex_file-inl.h" 27 #include "leb128.h" 28 #include "utf.h" 29 30 namespace art { 31 namespace dex_ir { 32 33 // Forward declarations for classes used in containers or pointed to. 34 class AnnotationItem; 35 class AnnotationsDirectoryItem; 36 class AnnotationSetItem; 37 class AnnotationSetRefList; 38 class CallSiteId; 39 class ClassData; 40 class ClassDef; 41 class CodeItem; 42 class DebugInfoItem; 43 class EncodedAnnotation; 44 class EncodedArrayItem; 45 class EncodedValue; 46 class FieldId; 47 class FieldItem; 48 class Header; 49 class MapList; 50 class MapItem; 51 class MethodHandleItem; 52 class MethodId; 53 class MethodItem; 54 class ParameterAnnotation; 55 class ProtoId; 56 class StringData; 57 class StringId; 58 class TryItem; 59 class TypeId; 60 class TypeList; 61 62 // Item size constants. 63 static constexpr size_t kHeaderItemSize = 112; 64 static constexpr size_t kStringIdItemSize = 4; 65 static constexpr size_t kTypeIdItemSize = 4; 66 static constexpr size_t kProtoIdItemSize = 12; 67 static constexpr size_t kFieldIdItemSize = 8; 68 static constexpr size_t kMethodIdItemSize = 8; 69 static constexpr size_t kClassDefItemSize = 32; 70 static constexpr size_t kCallSiteIdItemSize = 4; 71 static constexpr size_t kMethodHandleItemSize = 8; 72 73 // Visitor support 74 class AbstractDispatcher { 75 public: 76 AbstractDispatcher() = default; ~AbstractDispatcher()77 virtual ~AbstractDispatcher() { } 78 79 virtual void Dispatch(Header* header) = 0; 80 virtual void Dispatch(const StringData* string_data) = 0; 81 virtual void Dispatch(const StringId* string_id) = 0; 82 virtual void Dispatch(const TypeId* type_id) = 0; 83 virtual void Dispatch(const ProtoId* proto_id) = 0; 84 virtual void Dispatch(const FieldId* field_id) = 0; 85 virtual void Dispatch(const MethodId* method_id) = 0; 86 virtual void Dispatch(const CallSiteId* call_site_id) = 0; 87 virtual void Dispatch(const MethodHandleItem* method_handle_item) = 0; 88 virtual void Dispatch(ClassData* class_data) = 0; 89 virtual void Dispatch(ClassDef* class_def) = 0; 90 virtual void Dispatch(FieldItem* field_item) = 0; 91 virtual void Dispatch(MethodItem* method_item) = 0; 92 virtual void Dispatch(EncodedArrayItem* array_item) = 0; 93 virtual void Dispatch(CodeItem* code_item) = 0; 94 virtual void Dispatch(TryItem* try_item) = 0; 95 virtual void Dispatch(DebugInfoItem* debug_info_item) = 0; 96 virtual void Dispatch(AnnotationItem* annotation_item) = 0; 97 virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0; 98 virtual void Dispatch(AnnotationSetRefList* annotation_set_ref_list) = 0; 99 virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0; 100 virtual void Dispatch(MapList* map_list) = 0; 101 virtual void Dispatch(MapItem* map_item) = 0; 102 103 private: 104 DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher); 105 }; 106 107 // Collections become owners of the objects added by moving them into unique pointers. 108 template<class T> class CollectionBase { 109 public: 110 CollectionBase() = default; 111 GetOffset()112 uint32_t GetOffset() const { return offset_; } SetOffset(uint32_t new_offset)113 void SetOffset(uint32_t new_offset) { offset_ = new_offset; } 114 115 private: 116 uint32_t offset_ = 0; 117 118 DISALLOW_COPY_AND_ASSIGN(CollectionBase); 119 }; 120 121 template<class T> class CollectionVector : public CollectionBase<T> { 122 public: 123 CollectionVector() = default; 124 AddIndexedItem(T * object,uint32_t offset,uint32_t index)125 void AddIndexedItem(T* object, uint32_t offset, uint32_t index) { 126 object->SetOffset(offset); 127 object->SetIndex(index); 128 collection_.push_back(std::unique_ptr<T>(object)); 129 } Size()130 uint32_t Size() const { return collection_.size(); } Collection()131 std::vector<std::unique_ptr<T>>& Collection() { return collection_; } 132 133 private: 134 std::vector<std::unique_ptr<T>> collection_; 135 136 DISALLOW_COPY_AND_ASSIGN(CollectionVector); 137 }; 138 139 template<class T> class CollectionMap : public CollectionBase<T> { 140 public: 141 CollectionMap() = default; 142 143 // Returns the existing item if it is already inserted, null otherwise. GetExistingObject(uint32_t offset)144 T* GetExistingObject(uint32_t offset) { 145 auto it = collection_.find(offset); 146 return it != collection_.end() ? it->second.get() : nullptr; 147 } 148 AddItem(T * object,uint32_t offset)149 void AddItem(T* object, uint32_t offset) { 150 object->SetOffset(offset); 151 auto it = collection_.emplace(offset, std::unique_ptr<T>(object)); 152 CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " " 153 << " and address " << it.first->second.get(); 154 } Size()155 uint32_t Size() const { return collection_.size(); } Collection()156 std::map<uint32_t, std::unique_ptr<T>>& Collection() { return collection_; } 157 158 private: 159 std::map<uint32_t, std::unique_ptr<T>> collection_; 160 161 DISALLOW_COPY_AND_ASSIGN(CollectionMap); 162 }; 163 164 class Collections { 165 public: 166 Collections() = default; 167 StringIds()168 std::vector<std::unique_ptr<StringId>>& StringIds() { return string_ids_.Collection(); } TypeIds()169 std::vector<std::unique_ptr<TypeId>>& TypeIds() { return type_ids_.Collection(); } ProtoIds()170 std::vector<std::unique_ptr<ProtoId>>& ProtoIds() { return proto_ids_.Collection(); } FieldIds()171 std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); } MethodIds()172 std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); } ClassDefs()173 std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); } CallSiteIds()174 std::vector<std::unique_ptr<CallSiteId>>& CallSiteIds() { return call_site_ids_.Collection(); } MethodHandleItems()175 std::vector<std::unique_ptr<MethodHandleItem>>& MethodHandleItems() 176 { return method_handle_items_.Collection(); } StringDatas()177 std::map<uint32_t, std::unique_ptr<StringData>>& StringDatas() 178 { return string_datas_.Collection(); } TypeLists()179 std::map<uint32_t, std::unique_ptr<TypeList>>& TypeLists() { return type_lists_.Collection(); } EncodedArrayItems()180 std::map<uint32_t, std::unique_ptr<EncodedArrayItem>>& EncodedArrayItems() 181 { return encoded_array_items_.Collection(); } AnnotationItems()182 std::map<uint32_t, std::unique_ptr<AnnotationItem>>& AnnotationItems() 183 { return annotation_items_.Collection(); } AnnotationSetItems()184 std::map<uint32_t, std::unique_ptr<AnnotationSetItem>>& AnnotationSetItems() 185 { return annotation_set_items_.Collection(); } AnnotationSetRefLists()186 std::map<uint32_t, std::unique_ptr<AnnotationSetRefList>>& AnnotationSetRefLists() 187 { return annotation_set_ref_lists_.Collection(); } AnnotationsDirectoryItems()188 std::map<uint32_t, std::unique_ptr<AnnotationsDirectoryItem>>& AnnotationsDirectoryItems() 189 { return annotations_directory_items_.Collection(); } DebugInfoItems()190 std::map<uint32_t, std::unique_ptr<DebugInfoItem>>& DebugInfoItems() 191 { return debug_info_items_.Collection(); } CodeItems()192 std::map<uint32_t, std::unique_ptr<CodeItem>>& CodeItems() { return code_items_.Collection(); } ClassDatas()193 std::map<uint32_t, std::unique_ptr<ClassData>>& ClassDatas() { return class_datas_.Collection(); } 194 195 void CreateStringId(const DexFile& dex_file, uint32_t i); 196 void CreateTypeId(const DexFile& dex_file, uint32_t i); 197 void CreateProtoId(const DexFile& dex_file, uint32_t i); 198 void CreateFieldId(const DexFile& dex_file, uint32_t i); 199 void CreateMethodId(const DexFile& dex_file, uint32_t i); 200 void CreateClassDef(const DexFile& dex_file, uint32_t i); 201 void CreateCallSiteId(const DexFile& dex_file, uint32_t i); 202 void CreateMethodHandleItem(const DexFile& dex_file, uint32_t i); 203 204 void CreateCallSitesAndMethodHandles(const DexFile& dex_file); 205 206 TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset); 207 EncodedArrayItem* CreateEncodedArrayItem(const uint8_t* static_data, uint32_t offset); 208 AnnotationItem* CreateAnnotationItem(const DexFile::AnnotationItem* annotation, uint32_t offset); 209 AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file, 210 const DexFile::AnnotationSetItem* disk_annotations_item, uint32_t offset); 211 AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file, 212 const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset); 213 CodeItem* CreateCodeItem( 214 const DexFile& dex_file, const DexFile::CodeItem& disk_code_item, uint32_t offset); 215 ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset); 216 GetStringId(uint32_t index)217 StringId* GetStringId(uint32_t index) { 218 CHECK_LT(index, StringIdsSize()); 219 return StringIds()[index].get(); 220 } GetTypeId(uint32_t index)221 TypeId* GetTypeId(uint32_t index) { 222 CHECK_LT(index, TypeIdsSize()); 223 return TypeIds()[index].get(); 224 } GetProtoId(uint32_t index)225 ProtoId* GetProtoId(uint32_t index) { 226 CHECK_LT(index, ProtoIdsSize()); 227 return ProtoIds()[index].get(); 228 } GetFieldId(uint32_t index)229 FieldId* GetFieldId(uint32_t index) { 230 CHECK_LT(index, FieldIdsSize()); 231 return FieldIds()[index].get(); 232 } GetMethodId(uint32_t index)233 MethodId* GetMethodId(uint32_t index) { 234 CHECK_LT(index, MethodIdsSize()); 235 return MethodIds()[index].get(); 236 } GetClassDef(uint32_t index)237 ClassDef* GetClassDef(uint32_t index) { 238 CHECK_LT(index, ClassDefsSize()); 239 return ClassDefs()[index].get(); 240 } GetCallSiteId(uint32_t index)241 CallSiteId* GetCallSiteId(uint32_t index) { 242 CHECK_LT(index, CallSiteIdsSize()); 243 return CallSiteIds()[index].get(); 244 } GetMethodHandle(uint32_t index)245 MethodHandleItem* GetMethodHandle(uint32_t index) { 246 CHECK_LT(index, MethodHandleItemsSize()); 247 return MethodHandleItems()[index].get(); 248 } 249 GetStringIdOrNullPtr(uint32_t index)250 StringId* GetStringIdOrNullPtr(uint32_t index) { 251 return index == DexFile::kDexNoIndex ? nullptr : GetStringId(index); 252 } GetTypeIdOrNullPtr(uint16_t index)253 TypeId* GetTypeIdOrNullPtr(uint16_t index) { 254 return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index); 255 } 256 StringIdsOffset()257 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); } TypeIdsOffset()258 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); } ProtoIdsOffset()259 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); } FieldIdsOffset()260 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); } MethodIdsOffset()261 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); } ClassDefsOffset()262 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); } CallSiteIdsOffset()263 uint32_t CallSiteIdsOffset() const { return call_site_ids_.GetOffset(); } MethodHandleItemsOffset()264 uint32_t MethodHandleItemsOffset() const { return method_handle_items_.GetOffset(); } StringDatasOffset()265 uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); } TypeListsOffset()266 uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); } EncodedArrayItemsOffset()267 uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); } AnnotationItemsOffset()268 uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); } AnnotationSetItemsOffset()269 uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); } AnnotationSetRefListsOffset()270 uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); } AnnotationsDirectoryItemsOffset()271 uint32_t AnnotationsDirectoryItemsOffset() const 272 { return annotations_directory_items_.GetOffset(); } DebugInfoItemsOffset()273 uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); } CodeItemsOffset()274 uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); } ClassDatasOffset()275 uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); } MapListOffset()276 uint32_t MapListOffset() const { return map_list_offset_; } 277 SetStringIdsOffset(uint32_t new_offset)278 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); } SetTypeIdsOffset(uint32_t new_offset)279 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); } SetProtoIdsOffset(uint32_t new_offset)280 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); } SetFieldIdsOffset(uint32_t new_offset)281 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); } SetMethodIdsOffset(uint32_t new_offset)282 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); } SetClassDefsOffset(uint32_t new_offset)283 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); } SetCallSiteIdsOffset(uint32_t new_offset)284 void SetCallSiteIdsOffset(uint32_t new_offset) { call_site_ids_.SetOffset(new_offset); } SetMethodHandleItemsOffset(uint32_t new_offset)285 void SetMethodHandleItemsOffset(uint32_t new_offset) 286 { method_handle_items_.SetOffset(new_offset); } SetStringDatasOffset(uint32_t new_offset)287 void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); } SetTypeListsOffset(uint32_t new_offset)288 void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); } SetEncodedArrayItemsOffset(uint32_t new_offset)289 void SetEncodedArrayItemsOffset(uint32_t new_offset) 290 { encoded_array_items_.SetOffset(new_offset); } SetAnnotationItemsOffset(uint32_t new_offset)291 void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); } SetAnnotationSetItemsOffset(uint32_t new_offset)292 void SetAnnotationSetItemsOffset(uint32_t new_offset) 293 { annotation_set_items_.SetOffset(new_offset); } SetAnnotationSetRefListsOffset(uint32_t new_offset)294 void SetAnnotationSetRefListsOffset(uint32_t new_offset) 295 { annotation_set_ref_lists_.SetOffset(new_offset); } SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)296 void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset) 297 { annotations_directory_items_.SetOffset(new_offset); } SetDebugInfoItemsOffset(uint32_t new_offset)298 void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); } SetCodeItemsOffset(uint32_t new_offset)299 void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); } SetClassDatasOffset(uint32_t new_offset)300 void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); } SetMapListOffset(uint32_t new_offset)301 void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; } 302 StringIdsSize()303 uint32_t StringIdsSize() const { return string_ids_.Size(); } TypeIdsSize()304 uint32_t TypeIdsSize() const { return type_ids_.Size(); } ProtoIdsSize()305 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); } FieldIdsSize()306 uint32_t FieldIdsSize() const { return field_ids_.Size(); } MethodIdsSize()307 uint32_t MethodIdsSize() const { return method_ids_.Size(); } ClassDefsSize()308 uint32_t ClassDefsSize() const { return class_defs_.Size(); } CallSiteIdsSize()309 uint32_t CallSiteIdsSize() const { return call_site_ids_.Size(); } MethodHandleItemsSize()310 uint32_t MethodHandleItemsSize() const { return method_handle_items_.Size(); } StringDatasSize()311 uint32_t StringDatasSize() const { return string_datas_.Size(); } TypeListsSize()312 uint32_t TypeListsSize() const { return type_lists_.Size(); } EncodedArrayItemsSize()313 uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); } AnnotationItemsSize()314 uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); } AnnotationSetItemsSize()315 uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); } AnnotationSetRefListsSize()316 uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); } AnnotationsDirectoryItemsSize()317 uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); } DebugInfoItemsSize()318 uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); } CodeItemsSize()319 uint32_t CodeItemsSize() const { return code_items_.Size(); } ClassDatasSize()320 uint32_t ClassDatasSize() const { return class_datas_.Size(); } 321 322 private: 323 EncodedValue* ReadEncodedValue(const uint8_t** data); 324 EncodedValue* ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length); 325 void ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length, EncodedValue* item); 326 327 ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id, 328 const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset); 329 MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii); 330 331 CollectionVector<StringId> string_ids_; 332 CollectionVector<TypeId> type_ids_; 333 CollectionVector<ProtoId> proto_ids_; 334 CollectionVector<FieldId> field_ids_; 335 CollectionVector<MethodId> method_ids_; 336 CollectionVector<ClassDef> class_defs_; 337 CollectionVector<CallSiteId> call_site_ids_; 338 CollectionVector<MethodHandleItem> method_handle_items_; 339 340 CollectionMap<StringData> string_datas_; 341 CollectionMap<TypeList> type_lists_; 342 CollectionMap<EncodedArrayItem> encoded_array_items_; 343 CollectionMap<AnnotationItem> annotation_items_; 344 CollectionMap<AnnotationSetItem> annotation_set_items_; 345 CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_; 346 CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_; 347 CollectionMap<DebugInfoItem> debug_info_items_; 348 CollectionMap<CodeItem> code_items_; 349 CollectionMap<ClassData> class_datas_; 350 351 uint32_t map_list_offset_ = 0; 352 353 DISALLOW_COPY_AND_ASSIGN(Collections); 354 }; 355 356 class Item { 357 public: Item()358 Item() { } ~Item()359 virtual ~Item() { } 360 GetOffset()361 uint32_t GetOffset() const { return offset_; } GetSize()362 uint32_t GetSize() const { return size_; } SetOffset(uint32_t offset)363 void SetOffset(uint32_t offset) { offset_ = offset; } SetSize(uint32_t size)364 void SetSize(uint32_t size) { size_ = size; } 365 366 protected: Item(uint32_t offset,uint32_t size)367 Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { } 368 369 uint32_t offset_ = 0; 370 uint32_t size_ = 0; 371 }; 372 373 class IndexedItem : public Item { 374 public: IndexedItem()375 IndexedItem() { } ~IndexedItem()376 virtual ~IndexedItem() { } 377 GetIndex()378 uint32_t GetIndex() const { return index_; } SetIndex(uint32_t index)379 void SetIndex(uint32_t index) { index_ = index; } 380 381 protected: IndexedItem(uint32_t offset,uint32_t size,uint32_t index)382 IndexedItem(uint32_t offset, uint32_t size, uint32_t index) 383 : Item(offset, size), index_(index) { } 384 385 uint32_t index_ = 0; 386 }; 387 388 class Header : public Item { 389 public: Header(const uint8_t * magic,uint32_t checksum,const uint8_t * signature,uint32_t endian_tag,uint32_t file_size,uint32_t header_size,uint32_t link_size,uint32_t link_offset,uint32_t data_size,uint32_t data_offset)390 Header(const uint8_t* magic, 391 uint32_t checksum, 392 const uint8_t* signature, 393 uint32_t endian_tag, 394 uint32_t file_size, 395 uint32_t header_size, 396 uint32_t link_size, 397 uint32_t link_offset, 398 uint32_t data_size, 399 uint32_t data_offset) 400 : Item(0, kHeaderItemSize), 401 checksum_(checksum), 402 endian_tag_(endian_tag), 403 file_size_(file_size), 404 header_size_(header_size), 405 link_size_(link_size), 406 link_offset_(link_offset), 407 data_size_(data_size), 408 data_offset_(data_offset) { 409 memcpy(magic_, magic, sizeof(magic_)); 410 memcpy(signature_, signature, sizeof(signature_)); 411 } ~Header()412 ~Header() OVERRIDE { } 413 ItemSize()414 static size_t ItemSize() { return kHeaderItemSize; } 415 Magic()416 const uint8_t* Magic() const { return magic_; } Checksum()417 uint32_t Checksum() const { return checksum_; } Signature()418 const uint8_t* Signature() const { return signature_; } EndianTag()419 uint32_t EndianTag() const { return endian_tag_; } FileSize()420 uint32_t FileSize() const { return file_size_; } HeaderSize()421 uint32_t HeaderSize() const { return header_size_; } LinkSize()422 uint32_t LinkSize() const { return link_size_; } LinkOffset()423 uint32_t LinkOffset() const { return link_offset_; } DataSize()424 uint32_t DataSize() const { return data_size_; } DataOffset()425 uint32_t DataOffset() const { return data_offset_; } 426 SetChecksum(uint32_t new_checksum)427 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; } SetSignature(const uint8_t * new_signature)428 void SetSignature(const uint8_t* new_signature) { 429 memcpy(signature_, new_signature, sizeof(signature_)); 430 } SetFileSize(uint32_t new_file_size)431 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; } SetHeaderSize(uint32_t new_header_size)432 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; } SetLinkSize(uint32_t new_link_size)433 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; } SetLinkOffset(uint32_t new_link_offset)434 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; } SetDataSize(uint32_t new_data_size)435 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; } SetDataOffset(uint32_t new_data_offset)436 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; } 437 GetCollections()438 Collections& GetCollections() { return collections_; } 439 Accept(AbstractDispatcher * dispatch)440 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 441 442 private: 443 uint8_t magic_[8]; 444 uint32_t checksum_; 445 uint8_t signature_[DexFile::kSha1DigestSize]; 446 uint32_t endian_tag_; 447 uint32_t file_size_; 448 uint32_t header_size_; 449 uint32_t link_size_; 450 uint32_t link_offset_; 451 uint32_t data_size_; 452 uint32_t data_offset_; 453 454 Collections collections_; 455 456 DISALLOW_COPY_AND_ASSIGN(Header); 457 }; 458 459 class StringData : public Item { 460 public: StringData(const char * data)461 explicit StringData(const char* data) : data_(strdup(data)) { 462 size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data); 463 } 464 Data()465 const char* Data() const { return data_.get(); } 466 Accept(AbstractDispatcher * dispatch)467 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); } 468 469 private: 470 UniqueCPtr<const char> data_; 471 472 DISALLOW_COPY_AND_ASSIGN(StringData); 473 }; 474 475 class StringId : public IndexedItem { 476 public: StringId(StringData * string_data)477 explicit StringId(StringData* string_data) : string_data_(string_data) { 478 size_ = kStringIdItemSize; 479 } ~StringId()480 ~StringId() OVERRIDE { } 481 ItemSize()482 static size_t ItemSize() { return kStringIdItemSize; } 483 Data()484 const char* Data() const { return string_data_->Data(); } DataItem()485 StringData* DataItem() const { return string_data_; } 486 Accept(AbstractDispatcher * dispatch)487 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); } 488 489 private: 490 StringData* string_data_; 491 492 DISALLOW_COPY_AND_ASSIGN(StringId); 493 }; 494 495 class TypeId : public IndexedItem { 496 public: TypeId(StringId * string_id)497 explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; } ~TypeId()498 ~TypeId() OVERRIDE { } 499 ItemSize()500 static size_t ItemSize() { return kTypeIdItemSize; } 501 GetStringId()502 StringId* GetStringId() const { return string_id_; } 503 Accept(AbstractDispatcher * dispatch)504 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); } 505 506 private: 507 StringId* string_id_; 508 509 DISALLOW_COPY_AND_ASSIGN(TypeId); 510 }; 511 512 using TypeIdVector = std::vector<const TypeId*>; 513 514 class TypeList : public Item { 515 public: TypeList(TypeIdVector * type_list)516 explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) { 517 size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t)); 518 } ~TypeList()519 ~TypeList() OVERRIDE { } 520 GetTypeList()521 const TypeIdVector* GetTypeList() const { return type_list_.get(); } 522 523 private: 524 std::unique_ptr<TypeIdVector> type_list_; 525 526 DISALLOW_COPY_AND_ASSIGN(TypeList); 527 }; 528 529 class ProtoId : public IndexedItem { 530 public: ProtoId(const StringId * shorty,const TypeId * return_type,TypeList * parameters)531 ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters) 532 : shorty_(shorty), return_type_(return_type), parameters_(parameters) 533 { size_ = kProtoIdItemSize; } ~ProtoId()534 ~ProtoId() OVERRIDE { } 535 ItemSize()536 static size_t ItemSize() { return kProtoIdItemSize; } 537 Shorty()538 const StringId* Shorty() const { return shorty_; } ReturnType()539 const TypeId* ReturnType() const { return return_type_; } Parameters()540 const TypeList* Parameters() const { return parameters_; } 541 Accept(AbstractDispatcher * dispatch)542 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); } 543 544 private: 545 const StringId* shorty_; 546 const TypeId* return_type_; 547 TypeList* parameters_; // This can be nullptr. 548 549 DISALLOW_COPY_AND_ASSIGN(ProtoId); 550 }; 551 552 class FieldId : public IndexedItem { 553 public: FieldId(const TypeId * klass,const TypeId * type,const StringId * name)554 FieldId(const TypeId* klass, const TypeId* type, const StringId* name) 555 : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; } ~FieldId()556 ~FieldId() OVERRIDE { } 557 ItemSize()558 static size_t ItemSize() { return kFieldIdItemSize; } 559 Class()560 const TypeId* Class() const { return class_; } Type()561 const TypeId* Type() const { return type_; } Name()562 const StringId* Name() const { return name_; } 563 Accept(AbstractDispatcher * dispatch)564 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); } 565 566 private: 567 const TypeId* class_; 568 const TypeId* type_; 569 const StringId* name_; 570 571 DISALLOW_COPY_AND_ASSIGN(FieldId); 572 }; 573 574 class MethodId : public IndexedItem { 575 public: MethodId(const TypeId * klass,const ProtoId * proto,const StringId * name)576 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name) 577 : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; } ~MethodId()578 ~MethodId() OVERRIDE { } 579 ItemSize()580 static size_t ItemSize() { return kMethodIdItemSize; } 581 Class()582 const TypeId* Class() const { return class_; } Proto()583 const ProtoId* Proto() const { return proto_; } Name()584 const StringId* Name() const { return name_; } 585 Accept(AbstractDispatcher * dispatch)586 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); } 587 588 private: 589 const TypeId* class_; 590 const ProtoId* proto_; 591 const StringId* name_; 592 593 DISALLOW_COPY_AND_ASSIGN(MethodId); 594 }; 595 596 class FieldItem : public Item { 597 public: FieldItem(uint32_t access_flags,const FieldId * field_id)598 FieldItem(uint32_t access_flags, const FieldId* field_id) 599 : access_flags_(access_flags), field_id_(field_id) { } ~FieldItem()600 ~FieldItem() OVERRIDE { } 601 GetAccessFlags()602 uint32_t GetAccessFlags() const { return access_flags_; } GetFieldId()603 const FieldId* GetFieldId() const { return field_id_; } 604 Accept(AbstractDispatcher * dispatch)605 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 606 607 private: 608 uint32_t access_flags_; 609 const FieldId* field_id_; 610 611 DISALLOW_COPY_AND_ASSIGN(FieldItem); 612 }; 613 614 using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>; 615 616 class MethodItem : public Item { 617 public: MethodItem(uint32_t access_flags,const MethodId * method_id,CodeItem * code)618 MethodItem(uint32_t access_flags, const MethodId* method_id, CodeItem* code) 619 : access_flags_(access_flags), method_id_(method_id), code_(code) { } ~MethodItem()620 ~MethodItem() OVERRIDE { } 621 GetAccessFlags()622 uint32_t GetAccessFlags() const { return access_flags_; } GetMethodId()623 const MethodId* GetMethodId() const { return method_id_; } GetCodeItem()624 CodeItem* GetCodeItem() { return code_; } 625 Accept(AbstractDispatcher * dispatch)626 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 627 628 private: 629 uint32_t access_flags_; 630 const MethodId* method_id_; 631 CodeItem* code_; // This can be nullptr. 632 633 DISALLOW_COPY_AND_ASSIGN(MethodItem); 634 }; 635 636 using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>; 637 638 class EncodedValue { 639 public: EncodedValue(uint8_t type)640 explicit EncodedValue(uint8_t type) : type_(type) { } 641 Type()642 int8_t Type() const { return type_; } 643 SetBoolean(bool z)644 void SetBoolean(bool z) { u_.bool_val_ = z; } SetByte(int8_t b)645 void SetByte(int8_t b) { u_.byte_val_ = b; } SetShort(int16_t s)646 void SetShort(int16_t s) { u_.short_val_ = s; } SetChar(uint16_t c)647 void SetChar(uint16_t c) { u_.char_val_ = c; } SetInt(int32_t i)648 void SetInt(int32_t i) { u_.int_val_ = i; } SetLong(int64_t l)649 void SetLong(int64_t l) { u_.long_val_ = l; } SetFloat(float f)650 void SetFloat(float f) { u_.float_val_ = f; } SetDouble(double d)651 void SetDouble(double d) { u_.double_val_ = d; } SetStringId(StringId * string_id)652 void SetStringId(StringId* string_id) { u_.string_val_ = string_id; } SetTypeId(TypeId * type_id)653 void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; } SetProtoId(ProtoId * proto_id)654 void SetProtoId(ProtoId* proto_id) { u_.proto_val_ = proto_id; } SetFieldId(FieldId * field_id)655 void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; } SetMethodId(MethodId * method_id)656 void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; } SetMethodHandle(MethodHandleItem * method_handle)657 void SetMethodHandle(MethodHandleItem* method_handle) { u_.method_handle_val_ = method_handle; } SetEncodedArray(EncodedArrayItem * encoded_array)658 void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); } SetEncodedAnnotation(EncodedAnnotation * encoded_annotation)659 void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation) 660 { encoded_annotation_.reset(encoded_annotation); } 661 GetBoolean()662 bool GetBoolean() const { return u_.bool_val_; } GetByte()663 int8_t GetByte() const { return u_.byte_val_; } GetShort()664 int16_t GetShort() const { return u_.short_val_; } GetChar()665 uint16_t GetChar() const { return u_.char_val_; } GetInt()666 int32_t GetInt() const { return u_.int_val_; } GetLong()667 int64_t GetLong() const { return u_.long_val_; } GetFloat()668 float GetFloat() const { return u_.float_val_; } GetDouble()669 double GetDouble() const { return u_.double_val_; } GetStringId()670 StringId* GetStringId() const { return u_.string_val_; } GetTypeId()671 TypeId* GetTypeId() const { return u_.type_val_; } GetProtoId()672 ProtoId* GetProtoId() const { return u_.proto_val_; } GetFieldId()673 FieldId* GetFieldId() const { return u_.field_val_; } GetMethodId()674 MethodId* GetMethodId() const { return u_.method_val_; } GetMethodHandle()675 MethodHandleItem* GetMethodHandle() const { return u_.method_handle_val_; } GetEncodedArray()676 EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); } GetEncodedAnnotation()677 EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); } 678 ReleaseEncodedAnnotation()679 EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); } 680 681 private: 682 uint8_t type_; 683 union { 684 bool bool_val_; 685 int8_t byte_val_; 686 int16_t short_val_; 687 uint16_t char_val_; 688 int32_t int_val_; 689 int64_t long_val_; 690 float float_val_; 691 double double_val_; 692 StringId* string_val_; 693 TypeId* type_val_; 694 ProtoId* proto_val_; 695 FieldId* field_val_; 696 MethodId* method_val_; 697 MethodHandleItem* method_handle_val_; 698 } u_; 699 std::unique_ptr<EncodedArrayItem> encoded_array_; 700 std::unique_ptr<EncodedAnnotation> encoded_annotation_; 701 702 DISALLOW_COPY_AND_ASSIGN(EncodedValue); 703 }; 704 705 using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>; 706 707 class AnnotationElement { 708 public: AnnotationElement(StringId * name,EncodedValue * value)709 AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { } 710 GetName()711 StringId* GetName() const { return name_; } GetValue()712 EncodedValue* GetValue() const { return value_.get(); } 713 714 private: 715 StringId* name_; 716 std::unique_ptr<EncodedValue> value_; 717 718 DISALLOW_COPY_AND_ASSIGN(AnnotationElement); 719 }; 720 721 using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>; 722 723 class EncodedAnnotation { 724 public: EncodedAnnotation(TypeId * type,AnnotationElementVector * elements)725 EncodedAnnotation(TypeId* type, AnnotationElementVector* elements) 726 : type_(type), elements_(elements) { } 727 GetType()728 TypeId* GetType() const { return type_; } GetAnnotationElements()729 AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); } 730 731 private: 732 TypeId* type_; 733 std::unique_ptr<AnnotationElementVector> elements_; 734 735 DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation); 736 }; 737 738 class EncodedArrayItem : public Item { 739 public: EncodedArrayItem(EncodedValueVector * encoded_values)740 explicit EncodedArrayItem(EncodedValueVector* encoded_values) 741 : encoded_values_(encoded_values) { } 742 GetEncodedValues()743 EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); } 744 745 private: 746 std::unique_ptr<EncodedValueVector> encoded_values_; 747 748 DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem); 749 }; 750 751 class ClassData : public Item { 752 public: ClassData(FieldItemVector * static_fields,FieldItemVector * instance_fields,MethodItemVector * direct_methods,MethodItemVector * virtual_methods)753 ClassData(FieldItemVector* static_fields, 754 FieldItemVector* instance_fields, 755 MethodItemVector* direct_methods, 756 MethodItemVector* virtual_methods) 757 : static_fields_(static_fields), 758 instance_fields_(instance_fields), 759 direct_methods_(direct_methods), 760 virtual_methods_(virtual_methods) { } 761 762 ~ClassData() OVERRIDE = default; StaticFields()763 FieldItemVector* StaticFields() { return static_fields_.get(); } InstanceFields()764 FieldItemVector* InstanceFields() { return instance_fields_.get(); } DirectMethods()765 MethodItemVector* DirectMethods() { return direct_methods_.get(); } VirtualMethods()766 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); } 767 Accept(AbstractDispatcher * dispatch)768 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 769 770 private: 771 std::unique_ptr<FieldItemVector> static_fields_; 772 std::unique_ptr<FieldItemVector> instance_fields_; 773 std::unique_ptr<MethodItemVector> direct_methods_; 774 std::unique_ptr<MethodItemVector> virtual_methods_; 775 776 DISALLOW_COPY_AND_ASSIGN(ClassData); 777 }; 778 779 class ClassDef : public IndexedItem { 780 public: ClassDef(const TypeId * class_type,uint32_t access_flags,const TypeId * superclass,TypeList * interfaces,const StringId * source_file,AnnotationsDirectoryItem * annotations,EncodedArrayItem * static_values,ClassData * class_data)781 ClassDef(const TypeId* class_type, 782 uint32_t access_flags, 783 const TypeId* superclass, 784 TypeList* interfaces, 785 const StringId* source_file, 786 AnnotationsDirectoryItem* annotations, 787 EncodedArrayItem* static_values, 788 ClassData* class_data) 789 : class_type_(class_type), 790 access_flags_(access_flags), 791 superclass_(superclass), 792 interfaces_(interfaces), 793 source_file_(source_file), 794 annotations_(annotations), 795 class_data_(class_data), 796 static_values_(static_values) { size_ = kClassDefItemSize; } 797 ~ClassDef()798 ~ClassDef() OVERRIDE { } 799 ItemSize()800 static size_t ItemSize() { return kClassDefItemSize; } 801 ClassType()802 const TypeId* ClassType() const { return class_type_; } GetAccessFlags()803 uint32_t GetAccessFlags() const { return access_flags_; } Superclass()804 const TypeId* Superclass() const { return superclass_; } Interfaces()805 const TypeList* Interfaces() { return interfaces_; } InterfacesOffset()806 uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); } SourceFile()807 const StringId* SourceFile() const { return source_file_; } Annotations()808 AnnotationsDirectoryItem* Annotations() const { return annotations_; } GetClassData()809 ClassData* GetClassData() { return class_data_; } StaticValues()810 EncodedArrayItem* StaticValues() { return static_values_; } 811 812 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii); 813 Accept(AbstractDispatcher * dispatch)814 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 815 816 private: 817 const TypeId* class_type_; 818 uint32_t access_flags_; 819 const TypeId* superclass_; // This can be nullptr. 820 TypeList* interfaces_; // This can be nullptr. 821 const StringId* source_file_; // This can be nullptr. 822 AnnotationsDirectoryItem* annotations_; // This can be nullptr. 823 ClassData* class_data_; // This can be nullptr. 824 EncodedArrayItem* static_values_; // This can be nullptr. 825 826 DISALLOW_COPY_AND_ASSIGN(ClassDef); 827 }; 828 829 class TypeAddrPair { 830 public: TypeAddrPair(const TypeId * type_id,uint32_t address)831 TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { } 832 GetTypeId()833 const TypeId* GetTypeId() const { return type_id_; } GetAddress()834 uint32_t GetAddress() const { return address_; } 835 836 private: 837 const TypeId* type_id_; // This can be nullptr. 838 uint32_t address_; 839 840 DISALLOW_COPY_AND_ASSIGN(TypeAddrPair); 841 }; 842 843 using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>; 844 845 class CatchHandler { 846 public: CatchHandler(bool catch_all,uint16_t list_offset,TypeAddrPairVector * handlers)847 explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers) 848 : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { } 849 HasCatchAll()850 bool HasCatchAll() const { return catch_all_; } GetListOffset()851 uint16_t GetListOffset() const { return list_offset_; } GetHandlers()852 TypeAddrPairVector* GetHandlers() const { return handlers_.get(); } 853 854 private: 855 bool catch_all_; 856 uint16_t list_offset_; 857 std::unique_ptr<TypeAddrPairVector> handlers_; 858 859 DISALLOW_COPY_AND_ASSIGN(CatchHandler); 860 }; 861 862 using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>; 863 864 class TryItem : public Item { 865 public: TryItem(uint32_t start_addr,uint16_t insn_count,const CatchHandler * handlers)866 TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers) 867 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { } ~TryItem()868 ~TryItem() OVERRIDE { } 869 StartAddr()870 uint32_t StartAddr() const { return start_addr_; } InsnCount()871 uint16_t InsnCount() const { return insn_count_; } GetHandlers()872 const CatchHandler* GetHandlers() const { return handlers_; } 873 Accept(AbstractDispatcher * dispatch)874 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 875 876 private: 877 uint32_t start_addr_; 878 uint16_t insn_count_; 879 const CatchHandler* handlers_; 880 881 DISALLOW_COPY_AND_ASSIGN(TryItem); 882 }; 883 884 using TryItemVector = std::vector<std::unique_ptr<const TryItem>>; 885 886 class CodeFixups { 887 public: CodeFixups(std::vector<TypeId * > * type_ids,std::vector<StringId * > * string_ids,std::vector<MethodId * > * method_ids,std::vector<FieldId * > * field_ids)888 CodeFixups(std::vector<TypeId*>* type_ids, 889 std::vector<StringId*>* string_ids, 890 std::vector<MethodId*>* method_ids, 891 std::vector<FieldId*>* field_ids) 892 : type_ids_(type_ids), 893 string_ids_(string_ids), 894 method_ids_(method_ids), 895 field_ids_(field_ids) { } 896 TypeIds()897 std::vector<TypeId*>* TypeIds() const { return type_ids_.get(); } StringIds()898 std::vector<StringId*>* StringIds() const { return string_ids_.get(); } MethodIds()899 std::vector<MethodId*>* MethodIds() const { return method_ids_.get(); } FieldIds()900 std::vector<FieldId*>* FieldIds() const { return field_ids_.get(); } 901 902 private: 903 std::unique_ptr<std::vector<TypeId*>> type_ids_; 904 std::unique_ptr<std::vector<StringId*>> string_ids_; 905 std::unique_ptr<std::vector<MethodId*>> method_ids_; 906 std::unique_ptr<std::vector<FieldId*>> field_ids_; 907 908 DISALLOW_COPY_AND_ASSIGN(CodeFixups); 909 }; 910 911 class CodeItem : public Item { 912 public: CodeItem(uint16_t registers_size,uint16_t ins_size,uint16_t outs_size,DebugInfoItem * debug_info,uint32_t insns_size,uint16_t * insns,TryItemVector * tries,CatchHandlerVector * handlers)913 CodeItem(uint16_t registers_size, 914 uint16_t ins_size, 915 uint16_t outs_size, 916 DebugInfoItem* debug_info, 917 uint32_t insns_size, 918 uint16_t* insns, 919 TryItemVector* tries, 920 CatchHandlerVector* handlers) 921 : registers_size_(registers_size), 922 ins_size_(ins_size), 923 outs_size_(outs_size), 924 debug_info_(debug_info), 925 insns_size_(insns_size), 926 insns_(insns), 927 tries_(tries), 928 handlers_(handlers) { } 929 ~CodeItem()930 ~CodeItem() OVERRIDE { } 931 RegistersSize()932 uint16_t RegistersSize() const { return registers_size_; } InsSize()933 uint16_t InsSize() const { return ins_size_; } OutsSize()934 uint16_t OutsSize() const { return outs_size_; } TriesSize()935 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); } DebugInfo()936 DebugInfoItem* DebugInfo() const { return debug_info_; } InsnsSize()937 uint32_t InsnsSize() const { return insns_size_; } Insns()938 uint16_t* Insns() const { return insns_.get(); } Tries()939 TryItemVector* Tries() const { return tries_.get(); } Handlers()940 CatchHandlerVector* Handlers() const { return handlers_.get(); } 941 SetCodeFixups(CodeFixups * fixups)942 void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); } GetCodeFixups()943 CodeFixups* GetCodeFixups() const { return fixups_.get(); } 944 Accept(AbstractDispatcher * dispatch)945 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 946 947 private: 948 uint16_t registers_size_; 949 uint16_t ins_size_; 950 uint16_t outs_size_; 951 DebugInfoItem* debug_info_; // This can be nullptr. 952 uint32_t insns_size_; 953 std::unique_ptr<uint16_t[]> insns_; 954 std::unique_ptr<TryItemVector> tries_; // This can be nullptr. 955 std::unique_ptr<CatchHandlerVector> handlers_; // This can be nullptr. 956 std::unique_ptr<CodeFixups> fixups_; // This can be nullptr. 957 958 DISALLOW_COPY_AND_ASSIGN(CodeItem); 959 }; 960 961 struct PositionInfo { PositionInfoPositionInfo962 PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { } 963 964 uint32_t address_; 965 uint32_t line_; 966 }; 967 968 using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>; 969 970 struct LocalInfo { LocalInfoLocalInfo971 LocalInfo(const char* name, 972 const char* descriptor, 973 const char* signature, 974 uint32_t start_address, 975 uint32_t end_address, 976 uint16_t reg) 977 : name_(name), 978 descriptor_(descriptor), 979 signature_(signature), 980 start_address_(start_address), 981 end_address_(end_address), 982 reg_(reg) { } 983 984 std::string name_; 985 std::string descriptor_; 986 std::string signature_; 987 uint32_t start_address_; 988 uint32_t end_address_; 989 uint16_t reg_; 990 }; 991 992 using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>; 993 994 class DebugInfoItem : public Item { 995 public: DebugInfoItem(uint32_t debug_info_size,uint8_t * debug_info)996 DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info) 997 : debug_info_size_(debug_info_size), debug_info_(debug_info) { } 998 GetDebugInfoSize()999 uint32_t GetDebugInfoSize() const { return debug_info_size_; } GetDebugInfo()1000 uint8_t* GetDebugInfo() const { return debug_info_.get(); } 1001 GetPositionInfo()1002 PositionInfoVector& GetPositionInfo() { return positions_; } GetLocalInfo()1003 LocalInfoVector& GetLocalInfo() { return locals_; } 1004 1005 private: 1006 uint32_t debug_info_size_; 1007 std::unique_ptr<uint8_t[]> debug_info_; 1008 1009 PositionInfoVector positions_; 1010 LocalInfoVector locals_; 1011 1012 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem); 1013 }; 1014 1015 class AnnotationItem : public Item { 1016 public: AnnotationItem(uint8_t visibility,EncodedAnnotation * annotation)1017 AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation) 1018 : visibility_(visibility), annotation_(annotation) { } 1019 GetVisibility()1020 uint8_t GetVisibility() const { return visibility_; } GetAnnotation()1021 EncodedAnnotation* GetAnnotation() const { return annotation_.get(); } 1022 Accept(AbstractDispatcher * dispatch)1023 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 1024 1025 private: 1026 uint8_t visibility_; 1027 std::unique_ptr<EncodedAnnotation> annotation_; 1028 1029 DISALLOW_COPY_AND_ASSIGN(AnnotationItem); 1030 }; 1031 1032 class AnnotationSetItem : public Item { 1033 public: AnnotationSetItem(std::vector<AnnotationItem * > * items)1034 explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) { 1035 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t); 1036 } ~AnnotationSetItem()1037 ~AnnotationSetItem() OVERRIDE { } 1038 GetItems()1039 std::vector<AnnotationItem*>* GetItems() { return items_.get(); } 1040 Accept(AbstractDispatcher * dispatch)1041 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 1042 1043 private: 1044 std::unique_ptr<std::vector<AnnotationItem*>> items_; 1045 1046 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem); 1047 }; 1048 1049 class AnnotationSetRefList : public Item { 1050 public: AnnotationSetRefList(std::vector<AnnotationSetItem * > * items)1051 explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) { 1052 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t); 1053 } ~AnnotationSetRefList()1054 ~AnnotationSetRefList() OVERRIDE { } 1055 GetItems()1056 std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); } 1057 Accept(AbstractDispatcher * dispatch)1058 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 1059 1060 private: 1061 std::unique_ptr<std::vector<AnnotationSetItem*>> items_; // Elements of vector can be nullptr. 1062 1063 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList); 1064 }; 1065 1066 class FieldAnnotation { 1067 public: FieldAnnotation(FieldId * field_id,AnnotationSetItem * annotation_set_item)1068 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item) 1069 : field_id_(field_id), annotation_set_item_(annotation_set_item) { } 1070 GetFieldId()1071 FieldId* GetFieldId() const { return field_id_; } GetAnnotationSetItem()1072 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; } 1073 1074 private: 1075 FieldId* field_id_; 1076 AnnotationSetItem* annotation_set_item_; 1077 1078 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation); 1079 }; 1080 1081 using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>; 1082 1083 class MethodAnnotation { 1084 public: MethodAnnotation(MethodId * method_id,AnnotationSetItem * annotation_set_item)1085 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item) 1086 : method_id_(method_id), annotation_set_item_(annotation_set_item) { } 1087 GetMethodId()1088 MethodId* GetMethodId() const { return method_id_; } GetAnnotationSetItem()1089 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; } 1090 1091 private: 1092 MethodId* method_id_; 1093 AnnotationSetItem* annotation_set_item_; 1094 1095 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation); 1096 }; 1097 1098 using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>; 1099 1100 class ParameterAnnotation { 1101 public: ParameterAnnotation(MethodId * method_id,AnnotationSetRefList * annotations)1102 ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations) 1103 : method_id_(method_id), annotations_(annotations) { } 1104 GetMethodId()1105 MethodId* GetMethodId() const { return method_id_; } GetAnnotations()1106 AnnotationSetRefList* GetAnnotations() { return annotations_; } 1107 1108 private: 1109 MethodId* method_id_; 1110 AnnotationSetRefList* annotations_; 1111 1112 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation); 1113 }; 1114 1115 using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>; 1116 1117 class AnnotationsDirectoryItem : public Item { 1118 public: AnnotationsDirectoryItem(AnnotationSetItem * class_annotation,FieldAnnotationVector * field_annotations,MethodAnnotationVector * method_annotations,ParameterAnnotationVector * parameter_annotations)1119 AnnotationsDirectoryItem(AnnotationSetItem* class_annotation, 1120 FieldAnnotationVector* field_annotations, 1121 MethodAnnotationVector* method_annotations, 1122 ParameterAnnotationVector* parameter_annotations) 1123 : class_annotation_(class_annotation), 1124 field_annotations_(field_annotations), 1125 method_annotations_(method_annotations), 1126 parameter_annotations_(parameter_annotations) { } 1127 GetClassAnnotation()1128 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; } GetFieldAnnotations()1129 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); } GetMethodAnnotations()1130 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); } GetParameterAnnotations()1131 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); } 1132 Accept(AbstractDispatcher * dispatch)1133 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 1134 1135 private: 1136 AnnotationSetItem* class_annotation_; // This can be nullptr. 1137 std::unique_ptr<FieldAnnotationVector> field_annotations_; // This can be nullptr. 1138 std::unique_ptr<MethodAnnotationVector> method_annotations_; // This can be nullptr. 1139 std::unique_ptr<ParameterAnnotationVector> parameter_annotations_; // This can be nullptr. 1140 1141 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem); 1142 }; 1143 1144 class CallSiteId : public IndexedItem { 1145 public: CallSiteId(EncodedArrayItem * call_site_item)1146 explicit CallSiteId(EncodedArrayItem* call_site_item) : call_site_item_(call_site_item) { 1147 size_ = kCallSiteIdItemSize; 1148 } ~CallSiteId()1149 ~CallSiteId() OVERRIDE { } 1150 ItemSize()1151 static size_t ItemSize() { return kCallSiteIdItemSize; } 1152 CallSiteItem()1153 EncodedArrayItem* CallSiteItem() const { return call_site_item_; } 1154 Accept(AbstractDispatcher * dispatch)1155 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); } 1156 1157 private: 1158 EncodedArrayItem* call_site_item_; 1159 1160 DISALLOW_COPY_AND_ASSIGN(CallSiteId); 1161 }; 1162 1163 class MethodHandleItem : public IndexedItem { 1164 public: MethodHandleItem(DexFile::MethodHandleType method_handle_type,IndexedItem * field_or_method_id)1165 MethodHandleItem(DexFile::MethodHandleType method_handle_type, IndexedItem* field_or_method_id) 1166 : method_handle_type_(method_handle_type), 1167 field_or_method_id_(field_or_method_id) { 1168 size_ = kMethodHandleItemSize; 1169 } ~MethodHandleItem()1170 ~MethodHandleItem() OVERRIDE { } 1171 ItemSize()1172 static size_t ItemSize() { return kMethodHandleItemSize; } 1173 GetMethodHandleType()1174 DexFile::MethodHandleType GetMethodHandleType() const { return method_handle_type_; } GetFieldOrMethodId()1175 IndexedItem* GetFieldOrMethodId() const { return field_or_method_id_; } 1176 Accept(AbstractDispatcher * dispatch)1177 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); } 1178 1179 private: 1180 DexFile::MethodHandleType method_handle_type_; 1181 IndexedItem* field_or_method_id_; 1182 1183 DISALLOW_COPY_AND_ASSIGN(MethodHandleItem); 1184 }; 1185 1186 // TODO(sehr): implement MapList. 1187 class MapList : public Item { 1188 public: Accept(AbstractDispatcher * dispatch)1189 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 1190 1191 private: 1192 DISALLOW_COPY_AND_ASSIGN(MapList); 1193 }; 1194 1195 class MapItem : public Item { 1196 public: Accept(AbstractDispatcher * dispatch)1197 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 1198 1199 private: 1200 DISALLOW_COPY_AND_ASSIGN(MapItem); 1201 }; 1202 1203 // Interface for building a vector of file sections for use by other clients. 1204 struct DexFileSection { 1205 public: DexFileSectionDexFileSection1206 DexFileSection(const std::string& name, uint16_t type, uint32_t size, uint32_t offset) 1207 : name(name), type(type), size(size), offset(offset) { } 1208 std::string name; 1209 // The type (DexFile::MapItemType). 1210 uint16_t type; 1211 // The size (in elements, not bytes). 1212 uint32_t size; 1213 // The byte offset from the start of the file. 1214 uint32_t offset; 1215 }; 1216 1217 enum class SortDirection { 1218 kSortAscending, 1219 kSortDescending 1220 }; 1221 1222 std::vector<DexFileSection> GetSortedDexFileSections(dex_ir::Header* header, 1223 SortDirection direction); 1224 1225 } // namespace dex_ir 1226 } // namespace art 1227 1228 #endif // ART_DEXLAYOUT_DEX_IR_H_ 1229