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