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; ~AbstractDispatcher()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 GetOffset()115 uint32_t GetOffset() const { 116 return offset_; 117 } SetOffset(uint32_t new_offset)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 Size()134 uint32_t Size() const { return collection_.size(); } Collection()135 Vector& Collection() { return collection_; } Collection()136 const Vector& Collection() const { return collection_; } 137 138 // Sort the vector by copying pointers over. 139 template <typename MapType> SortByMapOrder(const MapType & map)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 AddItem(T * object)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: AddIndexedItem(T * object,uint32_t index)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. GetExistingObject(uint32_t offset)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. size()190 uint32_t size() const { return collection_.size(); } Collection()191 std::map<uint32_t, T*>& Collection() { return collection_; } 192 193 private: 194 std::map<uint32_t, T*> collection_; 195 AddItem(T * object,uint32_t offset)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 StringIds()210 CollectionVector<StringId>::Vector& StringIds() { return string_ids_.Collection(); } TypeIds()211 CollectionVector<TypeId>::Vector& TypeIds() { return type_ids_.Collection(); } ProtoIds()212 CollectionVector<ProtoId>::Vector& ProtoIds() { return proto_ids_.Collection(); } FieldIds()213 CollectionVector<FieldId>::Vector& FieldIds() { return field_ids_.Collection(); } MethodIds()214 CollectionVector<MethodId>::Vector& MethodIds() { return method_ids_.Collection(); } ClassDefs()215 CollectionVector<ClassDef>::Vector& ClassDefs() { return class_defs_.Collection(); } CallSiteIds()216 CollectionVector<CallSiteId>::Vector& CallSiteIds() { return call_site_ids_.Collection(); } MethodHandleItems()217 CollectionVector<MethodHandleItem>::Vector& MethodHandleItems() 218 { return method_handle_items_.Collection(); } StringDatas()219 CollectionVector<StringData>::Vector& StringDatas() { return string_datas_.Collection(); } TypeLists()220 CollectionVector<TypeList>::Vector& TypeLists() { return type_lists_.Collection(); } EncodedArrayItems()221 CollectionVector<EncodedArrayItem>::Vector& EncodedArrayItems() 222 { return encoded_array_items_.Collection(); } AnnotationItems()223 CollectionVector<AnnotationItem>::Vector& AnnotationItems() 224 { return annotation_items_.Collection(); } AnnotationSetItems()225 CollectionVector<AnnotationSetItem>::Vector& AnnotationSetItems() 226 { return annotation_set_items_.Collection(); } AnnotationSetRefLists()227 CollectionVector<AnnotationSetRefList>::Vector& AnnotationSetRefLists() 228 { return annotation_set_ref_lists_.Collection(); } AnnotationsDirectoryItems()229 CollectionVector<AnnotationsDirectoryItem>::Vector& AnnotationsDirectoryItems() 230 { return annotations_directory_items_.Collection(); } DebugInfoItems()231 CollectionVector<DebugInfoItem>::Vector& DebugInfoItems() 232 { return debug_info_items_.Collection(); } CodeItems()233 CollectionVector<CodeItem>::Vector& CodeItems() { return code_items_.Collection(); } ClassDatas()234 CollectionVector<ClassData>::Vector& ClassDatas() { return class_datas_.Collection(); } 235 ClassDefs()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 GetStringId(uint32_t index)268 StringId* GetStringId(uint32_t index) { 269 CHECK_LT(index, StringIdsSize()); 270 return StringIds()[index].get(); 271 } GetTypeId(uint32_t index)272 TypeId* GetTypeId(uint32_t index) { 273 CHECK_LT(index, TypeIdsSize()); 274 return TypeIds()[index].get(); 275 } GetProtoId(uint32_t index)276 ProtoId* GetProtoId(uint32_t index) { 277 CHECK_LT(index, ProtoIdsSize()); 278 return ProtoIds()[index].get(); 279 } GetFieldId(uint32_t index)280 FieldId* GetFieldId(uint32_t index) { 281 CHECK_LT(index, FieldIdsSize()); 282 return FieldIds()[index].get(); 283 } GetMethodId(uint32_t index)284 MethodId* GetMethodId(uint32_t index) { 285 CHECK_LT(index, MethodIdsSize()); 286 return MethodIds()[index].get(); 287 } GetClassDef(uint32_t index)288 ClassDef* GetClassDef(uint32_t index) { 289 CHECK_LT(index, ClassDefsSize()); 290 return ClassDefs()[index].get(); 291 } GetCallSiteId(uint32_t index)292 CallSiteId* GetCallSiteId(uint32_t index) { 293 CHECK_LT(index, CallSiteIdsSize()); 294 return CallSiteIds()[index].get(); 295 } GetMethodHandle(uint32_t index)296 MethodHandleItem* GetMethodHandle(uint32_t index) { 297 CHECK_LT(index, MethodHandleItemsSize()); 298 return MethodHandleItems()[index].get(); 299 } 300 GetStringIdOrNullPtr(uint32_t index)301 StringId* GetStringIdOrNullPtr(uint32_t index) { 302 return index == dex::kDexNoIndex ? nullptr : GetStringId(index); 303 } GetTypeIdOrNullPtr(uint16_t index)304 TypeId* GetTypeIdOrNullPtr(uint16_t index) { 305 return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index); 306 } 307 StringIdsOffset()308 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); } TypeIdsOffset()309 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); } ProtoIdsOffset()310 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); } FieldIdsOffset()311 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); } MethodIdsOffset()312 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); } ClassDefsOffset()313 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); } CallSiteIdsOffset()314 uint32_t CallSiteIdsOffset() const { return call_site_ids_.GetOffset(); } MethodHandleItemsOffset()315 uint32_t MethodHandleItemsOffset() const { return method_handle_items_.GetOffset(); } StringDatasOffset()316 uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); } TypeListsOffset()317 uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); } EncodedArrayItemsOffset()318 uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); } AnnotationItemsOffset()319 uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); } AnnotationSetItemsOffset()320 uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); } AnnotationSetRefListsOffset()321 uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); } AnnotationsDirectoryItemsOffset()322 uint32_t AnnotationsDirectoryItemsOffset() const 323 { return annotations_directory_items_.GetOffset(); } DebugInfoItemsOffset()324 uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); } CodeItemsOffset()325 uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); } ClassDatasOffset()326 uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); } MapListOffset()327 uint32_t MapListOffset() const { return map_list_offset_; } 328 SetStringIdsOffset(uint32_t new_offset)329 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); } SetTypeIdsOffset(uint32_t new_offset)330 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); } SetProtoIdsOffset(uint32_t new_offset)331 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); } SetFieldIdsOffset(uint32_t new_offset)332 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); } SetMethodIdsOffset(uint32_t new_offset)333 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); } SetClassDefsOffset(uint32_t new_offset)334 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); } SetCallSiteIdsOffset(uint32_t new_offset)335 void SetCallSiteIdsOffset(uint32_t new_offset) { call_site_ids_.SetOffset(new_offset); } SetMethodHandleItemsOffset(uint32_t new_offset)336 void SetMethodHandleItemsOffset(uint32_t new_offset) 337 { method_handle_items_.SetOffset(new_offset); } SetStringDatasOffset(uint32_t new_offset)338 void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); } SetTypeListsOffset(uint32_t new_offset)339 void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); } SetEncodedArrayItemsOffset(uint32_t new_offset)340 void SetEncodedArrayItemsOffset(uint32_t new_offset) 341 { encoded_array_items_.SetOffset(new_offset); } SetAnnotationItemsOffset(uint32_t new_offset)342 void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); } SetAnnotationSetItemsOffset(uint32_t new_offset)343 void SetAnnotationSetItemsOffset(uint32_t new_offset) 344 { annotation_set_items_.SetOffset(new_offset); } SetAnnotationSetRefListsOffset(uint32_t new_offset)345 void SetAnnotationSetRefListsOffset(uint32_t new_offset) 346 { annotation_set_ref_lists_.SetOffset(new_offset); } SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)347 void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset) 348 { annotations_directory_items_.SetOffset(new_offset); } SetDebugInfoItemsOffset(uint32_t new_offset)349 void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); } SetCodeItemsOffset(uint32_t new_offset)350 void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); } SetClassDatasOffset(uint32_t new_offset)351 void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); } SetMapListOffset(uint32_t new_offset)352 void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; } 353 StringIdsSize()354 uint32_t StringIdsSize() const { return string_ids_.Size(); } TypeIdsSize()355 uint32_t TypeIdsSize() const { return type_ids_.Size(); } ProtoIdsSize()356 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); } FieldIdsSize()357 uint32_t FieldIdsSize() const { return field_ids_.Size(); } MethodIdsSize()358 uint32_t MethodIdsSize() const { return method_ids_.Size(); } ClassDefsSize()359 uint32_t ClassDefsSize() const { return class_defs_.Size(); } CallSiteIdsSize()360 uint32_t CallSiteIdsSize() const { return call_site_ids_.Size(); } MethodHandleItemsSize()361 uint32_t MethodHandleItemsSize() const { return method_handle_items_.Size(); } StringDatasSize()362 uint32_t StringDatasSize() const { return string_datas_.Size(); } TypeListsSize()363 uint32_t TypeListsSize() const { return type_lists_.Size(); } EncodedArrayItemsSize()364 uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); } AnnotationItemsSize()365 uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); } AnnotationSetItemsSize()366 uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); } AnnotationSetRefListsSize()367 uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); } AnnotationsDirectoryItemsSize()368 uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); } DebugInfoItemsSize()369 uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); } CodeItemsSize()370 uint32_t CodeItemsSize() const { return code_items_.Size(); } ClassDatasSize()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> AddItem(CollectionMap<Type> & map,CollectionVector<Type> & vector,Type * item,uint32_t offset)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> AddIndexedItem(IndexedCollectionVector<Type> & vector,Type * item,uint32_t offset,uint32_t index)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 SetEagerlyAssignOffsets(bool eagerly_assign_offsets)402 void SetEagerlyAssignOffsets(bool eagerly_assign_offsets) { 403 eagerly_assign_offsets_ = eagerly_assign_offsets; 404 } 405 SetLinkData(std::vector<uint8_t> && link_data)406 void SetLinkData(std::vector<uint8_t>&& link_data) { 407 link_data_ = std::move(link_data); 408 } 409 LinkData()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: Item()485 Item() { } ~Item()486 virtual ~Item() { } 487 488 // Return the assigned offset. GetOffset()489 uint32_t GetOffset() const WARN_UNUSED { 490 CHECK(OffsetAssigned()); 491 return offset_; 492 } GetSize()493 uint32_t GetSize() const WARN_UNUSED { return size_; } SetOffset(uint32_t offset)494 void SetOffset(uint32_t offset) { offset_ = offset; } SetSize(uint32_t size)495 void SetSize(uint32_t size) { size_ = size; } OffsetAssigned()496 bool OffsetAssigned() const { 497 return offset_ != kOffsetUnassigned; 498 } 499 500 protected: Item(uint32_t offset,uint32_t size)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: IndexedItem()513 IndexedItem() { } ~IndexedItem()514 virtual ~IndexedItem() { } 515 GetIndex()516 uint32_t GetIndex() const { return index_; } SetIndex(uint32_t index)517 void SetIndex(uint32_t index) { index_ = index; } 518 519 protected: IndexedItem(uint32_t offset,uint32_t size,uint32_t index)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: 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,bool support_default_methods)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 } ~Header()552 ~Header() OVERRIDE { } 553 ItemSize()554 static size_t ItemSize() { return kHeaderItemSize; } 555 Magic()556 const uint8_t* Magic() const { return magic_; } Checksum()557 uint32_t Checksum() const { return checksum_; } Signature()558 const uint8_t* Signature() const { return signature_; } EndianTag()559 uint32_t EndianTag() const { return endian_tag_; } FileSize()560 uint32_t FileSize() const { return file_size_; } HeaderSize()561 uint32_t HeaderSize() const { return header_size_; } LinkSize()562 uint32_t LinkSize() const { return link_size_; } LinkOffset()563 uint32_t LinkOffset() const { return link_offset_; } DataSize()564 uint32_t DataSize() const { return data_size_; } DataOffset()565 uint32_t DataOffset() const { return data_offset_; } 566 SetChecksum(uint32_t new_checksum)567 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; } SetSignature(const uint8_t * new_signature)568 void SetSignature(const uint8_t* new_signature) { 569 memcpy(signature_, new_signature, sizeof(signature_)); 570 } SetFileSize(uint32_t new_file_size)571 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; } SetHeaderSize(uint32_t new_header_size)572 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; } SetLinkSize(uint32_t new_link_size)573 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; } SetLinkOffset(uint32_t new_link_offset)574 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; } SetDataSize(uint32_t new_data_size)575 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; } SetDataOffset(uint32_t new_data_offset)576 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; } 577 GetCollections()578 Collections& GetCollections() { return collections_; } 579 Accept(AbstractDispatcher * dispatch)580 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 581 SupportDefaultMethods()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: StringData(const char * data)606 explicit StringData(const char* data) : data_(strdup(data)) { 607 size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data); 608 } 609 Data()610 const char* Data() const { return data_.get(); } 611 Accept(AbstractDispatcher * dispatch)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: StringId(StringData * string_data)622 explicit StringId(StringData* string_data) : string_data_(string_data) { 623 size_ = kStringIdItemSize; 624 } ~StringId()625 ~StringId() OVERRIDE { } 626 ItemSize()627 static size_t ItemSize() { return kStringIdItemSize; } 628 Data()629 const char* Data() const { return string_data_->Data(); } DataItem()630 StringData* DataItem() const { return string_data_; } 631 Accept(AbstractDispatcher * dispatch)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: TypeId(StringId * string_id)642 explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; } ~TypeId()643 ~TypeId() OVERRIDE { } 644 ItemSize()645 static size_t ItemSize() { return kTypeIdItemSize; } 646 GetStringId()647 StringId* GetStringId() const { return string_id_; } 648 Accept(AbstractDispatcher * dispatch)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: TypeList(TypeIdVector * type_list)661 explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) { 662 size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t)); 663 } ~TypeList()664 ~TypeList() OVERRIDE { } 665 GetTypeList()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: ProtoId(const StringId * shorty,const TypeId * return_type,TypeList * parameters)676 ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters) 677 : shorty_(shorty), return_type_(return_type), parameters_(parameters) 678 { size_ = kProtoIdItemSize; } ~ProtoId()679 ~ProtoId() OVERRIDE { } 680 ItemSize()681 static size_t ItemSize() { return kProtoIdItemSize; } 682 Shorty()683 const StringId* Shorty() const { return shorty_; } ReturnType()684 const TypeId* ReturnType() const { return return_type_; } Parameters()685 const TypeList* Parameters() const { return parameters_; } 686 Accept(AbstractDispatcher * dispatch)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: FieldId(const TypeId * klass,const TypeId * type,const StringId * name)699 FieldId(const TypeId* klass, const TypeId* type, const StringId* name) 700 : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; } ~FieldId()701 ~FieldId() OVERRIDE { } 702 ItemSize()703 static size_t ItemSize() { return kFieldIdItemSize; } 704 Class()705 const TypeId* Class() const { return class_; } Type()706 const TypeId* Type() const { return type_; } Name()707 const StringId* Name() const { return name_; } 708 Accept(AbstractDispatcher * dispatch)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: MethodId(const TypeId * klass,const ProtoId * proto,const StringId * name)721 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name) 722 : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; } ~MethodId()723 ~MethodId() OVERRIDE { } 724 ItemSize()725 static size_t ItemSize() { return kMethodIdItemSize; } 726 Class()727 const TypeId* Class() const { return class_; } Proto()728 const ProtoId* Proto() const { return proto_; } Name()729 const StringId* Name() const { return name_; } 730 Accept(AbstractDispatcher * dispatch)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: FieldItem(uint32_t access_flags,const FieldId * field_id)743 FieldItem(uint32_t access_flags, const FieldId* field_id) 744 : access_flags_(access_flags), field_id_(field_id) { } ~FieldItem()745 ~FieldItem() OVERRIDE { } 746 GetAccessFlags()747 uint32_t GetAccessFlags() const { return access_flags_; } GetFieldId()748 const FieldId* GetFieldId() const { return field_id_; } 749 Accept(AbstractDispatcher * dispatch)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: MethodItem(uint32_t access_flags,const MethodId * method_id,CodeItem * code)763 MethodItem(uint32_t access_flags, const MethodId* method_id, CodeItem* code) 764 : access_flags_(access_flags), method_id_(method_id), code_(code) { } ~MethodItem()765 ~MethodItem() OVERRIDE { } 766 GetAccessFlags()767 uint32_t GetAccessFlags() const { return access_flags_; } GetMethodId()768 const MethodId* GetMethodId() const { return method_id_; } GetCodeItem()769 CodeItem* GetCodeItem() { return code_; } 770 Accept(AbstractDispatcher * dispatch)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: EncodedValue(uint8_t type)785 explicit EncodedValue(uint8_t type) : type_(type) { } 786 Type()787 int8_t Type() const { return type_; } 788 SetBoolean(bool z)789 void SetBoolean(bool z) { u_.bool_val_ = z; } SetByte(int8_t b)790 void SetByte(int8_t b) { u_.byte_val_ = b; } SetShort(int16_t s)791 void SetShort(int16_t s) { u_.short_val_ = s; } SetChar(uint16_t c)792 void SetChar(uint16_t c) { u_.char_val_ = c; } SetInt(int32_t i)793 void SetInt(int32_t i) { u_.int_val_ = i; } SetLong(int64_t l)794 void SetLong(int64_t l) { u_.long_val_ = l; } SetFloat(float f)795 void SetFloat(float f) { u_.float_val_ = f; } SetDouble(double d)796 void SetDouble(double d) { u_.double_val_ = d; } SetStringId(StringId * string_id)797 void SetStringId(StringId* string_id) { u_.string_val_ = string_id; } SetTypeId(TypeId * type_id)798 void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; } SetProtoId(ProtoId * proto_id)799 void SetProtoId(ProtoId* proto_id) { u_.proto_val_ = proto_id; } SetFieldId(FieldId * field_id)800 void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; } SetMethodId(MethodId * method_id)801 void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; } SetMethodHandle(MethodHandleItem * method_handle)802 void SetMethodHandle(MethodHandleItem* method_handle) { u_.method_handle_val_ = method_handle; } SetEncodedArray(EncodedArrayItem * encoded_array)803 void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); } SetEncodedAnnotation(EncodedAnnotation * encoded_annotation)804 void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation) 805 { encoded_annotation_.reset(encoded_annotation); } 806 GetBoolean()807 bool GetBoolean() const { return u_.bool_val_; } GetByte()808 int8_t GetByte() const { return u_.byte_val_; } GetShort()809 int16_t GetShort() const { return u_.short_val_; } GetChar()810 uint16_t GetChar() const { return u_.char_val_; } GetInt()811 int32_t GetInt() const { return u_.int_val_; } GetLong()812 int64_t GetLong() const { return u_.long_val_; } GetFloat()813 float GetFloat() const { return u_.float_val_; } GetDouble()814 double GetDouble() const { return u_.double_val_; } GetStringId()815 StringId* GetStringId() const { return u_.string_val_; } GetTypeId()816 TypeId* GetTypeId() const { return u_.type_val_; } GetProtoId()817 ProtoId* GetProtoId() const { return u_.proto_val_; } GetFieldId()818 FieldId* GetFieldId() const { return u_.field_val_; } GetMethodId()819 MethodId* GetMethodId() const { return u_.method_val_; } GetMethodHandle()820 MethodHandleItem* GetMethodHandle() const { return u_.method_handle_val_; } GetEncodedArray()821 EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); } GetEncodedAnnotation()822 EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); } 823 ReleaseEncodedAnnotation()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: AnnotationElement(StringId * name,EncodedValue * value)854 AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { } 855 GetName()856 StringId* GetName() const { return name_; } GetValue()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: EncodedAnnotation(TypeId * type,AnnotationElementVector * elements)870 EncodedAnnotation(TypeId* type, AnnotationElementVector* elements) 871 : type_(type), elements_(elements) { } 872 GetType()873 TypeId* GetType() const { return type_; } GetAnnotationElements()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: EncodedArrayItem(EncodedValueVector * encoded_values)885 explicit EncodedArrayItem(EncodedValueVector* encoded_values) 886 : encoded_values_(encoded_values) { } 887 GetEncodedValues()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: ClassData(FieldItemVector * static_fields,FieldItemVector * instance_fields,MethodItemVector * direct_methods,MethodItemVector * virtual_methods)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; StaticFields()908 FieldItemVector* StaticFields() { return static_fields_.get(); } InstanceFields()909 FieldItemVector* InstanceFields() { return instance_fields_.get(); } DirectMethods()910 MethodItemVector* DirectMethods() { return direct_methods_.get(); } VirtualMethods()911 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); } 912 Accept(AbstractDispatcher * dispatch)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: 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)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 ~ClassDef()943 ~ClassDef() OVERRIDE { } 944 ItemSize()945 static size_t ItemSize() { return kClassDefItemSize; } 946 ClassType()947 const TypeId* ClassType() const { return class_type_; } GetAccessFlags()948 uint32_t GetAccessFlags() const { return access_flags_; } Superclass()949 const TypeId* Superclass() const { return superclass_; } Interfaces()950 const TypeList* Interfaces() { return interfaces_; } InterfacesOffset()951 uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); } SourceFile()952 const StringId* SourceFile() const { return source_file_; } Annotations()953 AnnotationsDirectoryItem* Annotations() const { return annotations_; } GetClassData()954 ClassData* GetClassData() { return class_data_; } StaticValues()955 EncodedArrayItem* StaticValues() { return static_values_; } 956 957 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii); 958 Accept(AbstractDispatcher * dispatch)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: TypeAddrPair(const TypeId * type_id,uint32_t address)976 TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { } 977 GetTypeId()978 const TypeId* GetTypeId() const { return type_id_; } GetAddress()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: CatchHandler(bool catch_all,uint16_t list_offset,TypeAddrPairVector * handlers)992 explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers) 993 : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { } 994 HasCatchAll()995 bool HasCatchAll() const { return catch_all_; } GetListOffset()996 uint16_t GetListOffset() const { return list_offset_; } GetHandlers()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: TryItem(uint32_t start_addr,uint16_t insn_count,const CatchHandler * handlers)1011 TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers) 1012 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { } ~TryItem()1013 ~TryItem() OVERRIDE { } 1014 StartAddr()1015 uint32_t StartAddr() const { return start_addr_; } InsnCount()1016 uint16_t InsnCount() const { return insn_count_; } GetHandlers()1017 const CatchHandler* GetHandlers() const { return handlers_; } 1018 Accept(AbstractDispatcher * dispatch)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: CodeFixups(std::vector<TypeId * > type_ids,std::vector<StringId * > string_ids,std::vector<MethodId * > method_ids,std::vector<FieldId * > field_ids)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 TypeIds()1042 const std::vector<TypeId*>& TypeIds() const { return type_ids_; } StringIds()1043 const std::vector<StringId*>& StringIds() const { return string_ids_; } MethodIds()1044 const std::vector<MethodId*>& MethodIds() const { return method_ids_; } FieldIds()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: 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)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 ~CodeItem()1075 ~CodeItem() OVERRIDE { } 1076 RegistersSize()1077 uint16_t RegistersSize() const { return registers_size_; } InsSize()1078 uint16_t InsSize() const { return ins_size_; } OutsSize()1079 uint16_t OutsSize() const { return outs_size_; } TriesSize()1080 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); } DebugInfo()1081 DebugInfoItem* DebugInfo() const { return debug_info_; } InsnsSize()1082 uint32_t InsnsSize() const { return insns_size_; } Insns()1083 uint16_t* Insns() const { return insns_.get(); } Tries()1084 TryItemVector* Tries() const { return tries_.get(); } Handlers()1085 CatchHandlerVector* Handlers() const { return handlers_.get(); } 1086 SetCodeFixups(CodeFixups * fixups)1087 void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); } GetCodeFixups()1088 CodeFixups* GetCodeFixups() const { return fixups_.get(); } 1089 Accept(AbstractDispatcher * dispatch)1090 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); } 1091 Instructions()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: DebugInfoItem(uint32_t debug_info_size,uint8_t * debug_info)1113 DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info) 1114 : debug_info_size_(debug_info_size), debug_info_(debug_info) { } 1115 GetDebugInfoSize()1116 uint32_t GetDebugInfoSize() const { return debug_info_size_; } GetDebugInfo()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: AnnotationItem(uint8_t visibility,EncodedAnnotation * annotation)1128 AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation) 1129 : visibility_(visibility), annotation_(annotation) { } 1130 GetVisibility()1131 uint8_t GetVisibility() const { return visibility_; } GetAnnotation()1132 EncodedAnnotation* GetAnnotation() const { return annotation_.get(); } 1133 Accept(AbstractDispatcher * dispatch)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: AnnotationSetItem(std::vector<AnnotationItem * > * items)1145 explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) { 1146 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t); 1147 } ~AnnotationSetItem()1148 ~AnnotationSetItem() OVERRIDE { } 1149 GetItems()1150 std::vector<AnnotationItem*>* GetItems() { return items_.get(); } 1151 Accept(AbstractDispatcher * dispatch)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: AnnotationSetRefList(std::vector<AnnotationSetItem * > * items)1162 explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) { 1163 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t); 1164 } ~AnnotationSetRefList()1165 ~AnnotationSetRefList() OVERRIDE { } 1166 GetItems()1167 std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); } 1168 Accept(AbstractDispatcher * dispatch)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: FieldAnnotation(FieldId * field_id,AnnotationSetItem * annotation_set_item)1179 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item) 1180 : field_id_(field_id), annotation_set_item_(annotation_set_item) { } 1181 GetFieldId()1182 FieldId* GetFieldId() const { return field_id_; } GetAnnotationSetItem()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: MethodAnnotation(MethodId * method_id,AnnotationSetItem * annotation_set_item)1196 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item) 1197 : method_id_(method_id), annotation_set_item_(annotation_set_item) { } 1198 GetMethodId()1199 MethodId* GetMethodId() const { return method_id_; } GetAnnotationSetItem()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: ParameterAnnotation(MethodId * method_id,AnnotationSetRefList * annotations)1213 ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations) 1214 : method_id_(method_id), annotations_(annotations) { } 1215 GetMethodId()1216 MethodId* GetMethodId() const { return method_id_; } GetAnnotations()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: AnnotationsDirectoryItem(AnnotationSetItem * class_annotation,FieldAnnotationVector * field_annotations,MethodAnnotationVector * method_annotations,ParameterAnnotationVector * parameter_annotations)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 GetClassAnnotation()1239 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; } GetFieldAnnotations()1240 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); } GetMethodAnnotations()1241 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); } GetParameterAnnotations()1242 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); } 1243 Accept(AbstractDispatcher * dispatch)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: CallSiteId(EncodedArrayItem * call_site_item)1257 explicit CallSiteId(EncodedArrayItem* call_site_item) : call_site_item_(call_site_item) { 1258 size_ = kCallSiteIdItemSize; 1259 } ~CallSiteId()1260 ~CallSiteId() OVERRIDE { } 1261 ItemSize()1262 static size_t ItemSize() { return kCallSiteIdItemSize; } 1263 CallSiteItem()1264 EncodedArrayItem* CallSiteItem() const { return call_site_item_; } 1265 Accept(AbstractDispatcher * dispatch)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: MethodHandleItem(DexFile::MethodHandleType method_handle_type,IndexedItem * field_or_method_id)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 } ~MethodHandleItem()1281 ~MethodHandleItem() OVERRIDE { } 1282 ItemSize()1283 static size_t ItemSize() { return kMethodHandleItemSize; } 1284 GetMethodHandleType()1285 DexFile::MethodHandleType GetMethodHandleType() const { return method_handle_type_; } GetFieldOrMethodId()1286 IndexedItem* GetFieldOrMethodId() const { return field_or_method_id_; } 1287 Accept(AbstractDispatcher * dispatch)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: Accept(AbstractDispatcher * dispatch)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: Accept(AbstractDispatcher * dispatch)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: DexFileSectionDexFileSection1317 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