• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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