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