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