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