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