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