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