blob: 3a5b64480f8f3d752dd8c8130f3238562f2a4c4e [file] [log] [blame]
David Sehr7629f602016-08-07 16:01:51 -07001/*
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
Jeff Haoea7c6292016-11-14 18:10:16 -080022#include <map>
David Sehr7629f602016-08-07 16:01:51 -070023#include <vector>
24#include <stdint.h>
25
David Sehr853a8e12016-09-01 13:03:50 -070026#include "dex_file-inl.h"
Jeff Hao3ab96b42016-09-09 18:35:01 -070027#include "leb128.h"
Jeff Haoa8621002016-10-04 18:13:44 +000028#include "utf.h"
David Sehr7629f602016-08-07 16:01:51 -070029
30namespace art {
31namespace dex_ir {
32
33// Forward declarations for classes used in containers or pointed to.
Jeff Hao3ab96b42016-09-09 18:35:01 -070034class AnnotationItem;
David Sehr7629f602016-08-07 16:01:51 -070035class AnnotationsDirectoryItem;
36class AnnotationSetItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070037class AnnotationSetRefList;
David Sehr7629f602016-08-07 16:01:51 -070038class ClassData;
39class ClassDef;
40class CodeItem;
41class DebugInfoItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070042class EncodedAnnotation;
43class EncodedArrayItem;
44class EncodedValue;
David Sehr7629f602016-08-07 16:01:51 -070045class FieldId;
46class FieldItem;
47class Header;
48class MapList;
49class MapItem;
50class MethodId;
51class MethodItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070052class ParameterAnnotation;
David Sehr7629f602016-08-07 16:01:51 -070053class ProtoId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070054class StringData;
David Sehr7629f602016-08-07 16:01:51 -070055class StringId;
56class TryItem;
57class TypeId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070058class TypeList;
59
60// Item size constants.
61static constexpr size_t kHeaderItemSize = 112;
62static constexpr size_t kStringIdItemSize = 4;
63static constexpr size_t kTypeIdItemSize = 4;
64static constexpr size_t kProtoIdItemSize = 12;
65static constexpr size_t kFieldIdItemSize = 8;
66static constexpr size_t kMethodIdItemSize = 8;
67static constexpr size_t kClassDefItemSize = 32;
David Sehr7629f602016-08-07 16:01:51 -070068
69// Visitor support
70class AbstractDispatcher {
71 public:
72 AbstractDispatcher() = default;
73 virtual ~AbstractDispatcher() { }
74
75 virtual void Dispatch(Header* header) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070076 virtual void Dispatch(const StringData* string_data) = 0;
David Sehr7629f602016-08-07 16:01:51 -070077 virtual void Dispatch(const StringId* string_id) = 0;
78 virtual void Dispatch(const TypeId* type_id) = 0;
79 virtual void Dispatch(const ProtoId* proto_id) = 0;
80 virtual void Dispatch(const FieldId* field_id) = 0;
81 virtual void Dispatch(const MethodId* method_id) = 0;
82 virtual void Dispatch(ClassData* class_data) = 0;
83 virtual void Dispatch(ClassDef* class_def) = 0;
84 virtual void Dispatch(FieldItem* field_item) = 0;
85 virtual void Dispatch(MethodItem* method_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070086 virtual void Dispatch(EncodedArrayItem* array_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070087 virtual void Dispatch(CodeItem* code_item) = 0;
88 virtual void Dispatch(TryItem* try_item) = 0;
89 virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070090 virtual void Dispatch(AnnotationItem* annotation_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070091 virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070092 virtual void Dispatch(AnnotationSetRefList* annotation_set_ref_list) = 0;
David Sehr7629f602016-08-07 16:01:51 -070093 virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
94 virtual void Dispatch(MapList* map_list) = 0;
95 virtual void Dispatch(MapItem* map_item) = 0;
96
97 private:
98 DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
99};
100
101// Collections become owners of the objects added by moving them into unique pointers.
Jeff Haoea7c6292016-11-14 18:10:16 -0800102template<class T> class CollectionBase {
David Sehr7629f602016-08-07 16:01:51 -0700103 public:
Jeff Haoea7c6292016-11-14 18:10:16 -0800104 CollectionBase() = default;
105
106 uint32_t GetOffset() const { return offset_; }
107 void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
108
109 private:
110 uint32_t offset_ = 0;
111
112 DISALLOW_COPY_AND_ASSIGN(CollectionBase);
113};
114
115template<class T> class CollectionVector : public CollectionBase<T> {
116 public:
117 CollectionVector() = default;
118
Jeff Hao3ab96b42016-09-09 18:35:01 -0700119 void AddIndexedItem(T* object, uint32_t offset, uint32_t index) {
120 object->SetOffset(offset);
121 object->SetIndex(index);
122 collection_.push_back(std::unique_ptr<T>(object));
David Sehr7629f602016-08-07 16:01:51 -0700123 }
David Sehr7629f602016-08-07 16:01:51 -0700124 uint32_t Size() const { return collection_.size(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800125 std::vector<std::unique_ptr<T>>& Collection() { return collection_; }
David Sehr7629f602016-08-07 16:01:51 -0700126
127 private:
128 std::vector<std::unique_ptr<T>> collection_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700129
Jeff Haoea7c6292016-11-14 18:10:16 -0800130 DISALLOW_COPY_AND_ASSIGN(CollectionVector);
131};
132
133template<class T> class CollectionMap : public CollectionBase<T> {
134 public:
135 CollectionMap() = default;
136
Mathieu Chartiera2973d72017-02-14 17:12:20 -0800137 // Returns the existing item if it is already inserted, null otherwise.
138 T* GetExistingObject(uint32_t offset) {
139 auto it = collection_.find(offset);
140 return it != collection_.end() ? it->second.get() : nullptr;
141 }
142
Jeff Haoea7c6292016-11-14 18:10:16 -0800143 void AddItem(T* object, uint32_t offset) {
144 object->SetOffset(offset);
Mathieu Chartiera2973d72017-02-14 17:12:20 -0800145 auto it = collection_.emplace(offset, std::unique_ptr<T>(object));
146 CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " "
147 << " and address " << it.first->second.get();
Jeff Haoea7c6292016-11-14 18:10:16 -0800148 }
149 uint32_t Size() const { return collection_.size(); }
150 std::map<uint32_t, std::unique_ptr<T>>& Collection() { return collection_; }
151
152 private:
153 std::map<uint32_t, std::unique_ptr<T>> collection_;
154
155 DISALLOW_COPY_AND_ASSIGN(CollectionMap);
David Sehr7629f602016-08-07 16:01:51 -0700156};
157
Jeff Hao3ab96b42016-09-09 18:35:01 -0700158class Collections {
159 public:
160 Collections() = default;
161
162 std::vector<std::unique_ptr<StringId>>& StringIds() { return string_ids_.Collection(); }
163 std::vector<std::unique_ptr<TypeId>>& TypeIds() { return type_ids_.Collection(); }
164 std::vector<std::unique_ptr<ProtoId>>& ProtoIds() { return proto_ids_.Collection(); }
165 std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); }
166 std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); }
167 std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800168 std::map<uint32_t, std::unique_ptr<StringData>>& StringDatas()
169 { return string_datas_.Collection(); }
170 std::map<uint32_t, std::unique_ptr<TypeList>>& TypeLists() { return type_lists_.Collection(); }
171 std::map<uint32_t, std::unique_ptr<EncodedArrayItem>>& EncodedArrayItems()
Jeff Hao3ab96b42016-09-09 18:35:01 -0700172 { return encoded_array_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800173 std::map<uint32_t, std::unique_ptr<AnnotationItem>>& AnnotationItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000174 { return annotation_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800175 std::map<uint32_t, std::unique_ptr<AnnotationSetItem>>& AnnotationSetItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000176 { return annotation_set_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800177 std::map<uint32_t, std::unique_ptr<AnnotationSetRefList>>& AnnotationSetRefLists()
Jeff Haoa8621002016-10-04 18:13:44 +0000178 { return annotation_set_ref_lists_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800179 std::map<uint32_t, std::unique_ptr<AnnotationsDirectoryItem>>& AnnotationsDirectoryItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000180 { return annotations_directory_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800181 std::map<uint32_t, std::unique_ptr<DebugInfoItem>>& DebugInfoItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000182 { return debug_info_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800183 std::map<uint32_t, std::unique_ptr<CodeItem>>& CodeItems() { return code_items_.Collection(); }
184 std::map<uint32_t, std::unique_ptr<ClassData>>& ClassDatas() { return class_datas_.Collection(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700185
186 void CreateStringId(const DexFile& dex_file, uint32_t i);
187 void CreateTypeId(const DexFile& dex_file, uint32_t i);
188 void CreateProtoId(const DexFile& dex_file, uint32_t i);
189 void CreateFieldId(const DexFile& dex_file, uint32_t i);
190 void CreateMethodId(const DexFile& dex_file, uint32_t i);
191 void CreateClassDef(const DexFile& dex_file, uint32_t i);
192
Jeff Haoa8621002016-10-04 18:13:44 +0000193 TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700194 EncodedArrayItem* CreateEncodedArrayItem(const uint8_t* static_data, uint32_t offset);
195 AnnotationItem* CreateAnnotationItem(const DexFile::AnnotationItem* annotation, uint32_t offset);
196 AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
197 const DexFile::AnnotationSetItem& disk_annotations_item, uint32_t offset);
198 AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file,
199 const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset);
200 CodeItem* CreateCodeItem(
201 const DexFile& dex_file, const DexFile::CodeItem& disk_code_item, uint32_t offset);
202 ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
203
204 StringId* GetStringId(uint32_t index) { return StringIds()[index].get(); }
205 TypeId* GetTypeId(uint32_t index) { return TypeIds()[index].get(); }
206 ProtoId* GetProtoId(uint32_t index) { return ProtoIds()[index].get(); }
207 FieldId* GetFieldId(uint32_t index) { return FieldIds()[index].get(); }
208 MethodId* GetMethodId(uint32_t index) { return MethodIds()[index].get(); }
209 ClassDef* GetClassDef(uint32_t index) { return ClassDefs()[index].get(); }
210
211 StringId* GetStringIdOrNullPtr(uint32_t index) {
212 return index == DexFile::kDexNoIndex ? nullptr : GetStringId(index);
213 }
214 TypeId* GetTypeIdOrNullPtr(uint16_t index) {
215 return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index);
216 }
217
218 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
219 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
220 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
221 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
222 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
223 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
224 uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
225 uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000226 uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
227 uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
228 uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700229 uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000230 uint32_t AnnotationsDirectoryItemsOffset() const
231 { return annotations_directory_items_.GetOffset(); }
232 uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700233 uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
234 uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800235 uint32_t MapListOffset() const { return map_list_offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700236
237 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
238 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
239 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
240 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
241 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
242 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
243 void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
244 void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000245 void SetEncodedArrayItemsOffset(uint32_t new_offset)
246 { encoded_array_items_.SetOffset(new_offset); }
247 void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
248 void SetAnnotationSetItemsOffset(uint32_t new_offset)
249 { annotation_set_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700250 void SetAnnotationSetRefListsOffset(uint32_t new_offset)
251 { annotation_set_ref_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000252 void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700253 { annotations_directory_items_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000254 void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700255 void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
256 void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800257 void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700258
259 uint32_t StringIdsSize() const { return string_ids_.Size(); }
260 uint32_t TypeIdsSize() const { return type_ids_.Size(); }
261 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
262 uint32_t FieldIdsSize() const { return field_ids_.Size(); }
263 uint32_t MethodIdsSize() const { return method_ids_.Size(); }
264 uint32_t ClassDefsSize() const { return class_defs_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700265 uint32_t StringDatasSize() const { return string_datas_.Size(); }
266 uint32_t TypeListsSize() const { return type_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000267 uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
268 uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
269 uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700270 uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000271 uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
272 uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700273 uint32_t CodeItemsSize() const { return code_items_.Size(); }
274 uint32_t ClassDatasSize() const { return class_datas_.Size(); }
275
Jeff Hao3ab96b42016-09-09 18:35:01 -0700276 private:
277 EncodedValue* ReadEncodedValue(const uint8_t** data);
278 EncodedValue* ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length);
279 void ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length, EncodedValue* item);
280
281 ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
282 const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
283 MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
284
Jeff Haoea7c6292016-11-14 18:10:16 -0800285 CollectionVector<StringId> string_ids_;
286 CollectionVector<TypeId> type_ids_;
287 CollectionVector<ProtoId> proto_ids_;
288 CollectionVector<FieldId> field_ids_;
289 CollectionVector<MethodId> method_ids_;
290 CollectionVector<ClassDef> class_defs_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700291
Jeff Haoea7c6292016-11-14 18:10:16 -0800292 CollectionMap<StringData> string_datas_;
293 CollectionMap<TypeList> type_lists_;
294 CollectionMap<EncodedArrayItem> encoded_array_items_;
295 CollectionMap<AnnotationItem> annotation_items_;
296 CollectionMap<AnnotationSetItem> annotation_set_items_;
297 CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_;
298 CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_;
299 CollectionMap<DebugInfoItem> debug_info_items_;
300 CollectionMap<CodeItem> code_items_;
301 CollectionMap<ClassData> class_datas_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700302
Jeff Haoea7c6292016-11-14 18:10:16 -0800303 uint32_t map_list_offset_ = 0;
Jeff Haoa8621002016-10-04 18:13:44 +0000304
Jeff Hao3ab96b42016-09-09 18:35:01 -0700305 DISALLOW_COPY_AND_ASSIGN(Collections);
306};
307
David Sehr7629f602016-08-07 16:01:51 -0700308class Item {
309 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700310 Item() { }
David Sehr7629f602016-08-07 16:01:51 -0700311 virtual ~Item() { }
David Sehr853a8e12016-09-01 13:03:50 -0700312
David Sehr7629f602016-08-07 16:01:51 -0700313 uint32_t GetOffset() const { return offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700314 uint32_t GetSize() const { return size_; }
David Sehr7629f602016-08-07 16:01:51 -0700315 void SetOffset(uint32_t offset) { offset_ = offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700316 void SetSize(uint32_t size) { size_ = size; }
David Sehr853a8e12016-09-01 13:03:50 -0700317
David Sehr7629f602016-08-07 16:01:51 -0700318 protected:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700319 Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
320
David Sehr7629f602016-08-07 16:01:51 -0700321 uint32_t offset_ = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700322 uint32_t size_ = 0;
323};
324
325class IndexedItem : public Item {
326 public:
327 IndexedItem() { }
328 virtual ~IndexedItem() { }
329
330 uint32_t GetIndex() const { return index_; }
331 void SetIndex(uint32_t index) { index_ = index; }
332
333 protected:
334 IndexedItem(uint32_t offset, uint32_t size, uint32_t index)
335 : Item(offset, size), index_(index) { }
336
337 uint32_t index_ = 0;
David Sehr7629f602016-08-07 16:01:51 -0700338};
339
340class Header : public Item {
341 public:
David Sehr853a8e12016-09-01 13:03:50 -0700342 Header(const uint8_t* magic,
343 uint32_t checksum,
344 const uint8_t* signature,
345 uint32_t endian_tag,
346 uint32_t file_size,
347 uint32_t header_size,
348 uint32_t link_size,
349 uint32_t link_offset,
350 uint32_t data_size,
351 uint32_t data_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700352 : Item(0, kHeaderItemSize),
353 checksum_(checksum),
David Sehr853a8e12016-09-01 13:03:50 -0700354 endian_tag_(endian_tag),
355 file_size_(file_size),
356 header_size_(header_size),
357 link_size_(link_size),
358 link_offset_(link_offset),
359 data_size_(data_size),
360 data_offset_(data_offset) {
361 memcpy(magic_, magic, sizeof(magic_));
362 memcpy(signature_, signature, sizeof(signature_));
363 }
David Sehr7629f602016-08-07 16:01:51 -0700364 ~Header() OVERRIDE { }
365
Jeff Hao3ab96b42016-09-09 18:35:01 -0700366 static size_t ItemSize() { return kHeaderItemSize; }
367
David Sehr7629f602016-08-07 16:01:51 -0700368 const uint8_t* Magic() const { return magic_; }
369 uint32_t Checksum() const { return checksum_; }
370 const uint8_t* Signature() const { return signature_; }
371 uint32_t EndianTag() const { return endian_tag_; }
372 uint32_t FileSize() const { return file_size_; }
373 uint32_t HeaderSize() const { return header_size_; }
374 uint32_t LinkSize() const { return link_size_; }
375 uint32_t LinkOffset() const { return link_offset_; }
376 uint32_t DataSize() const { return data_size_; }
377 uint32_t DataOffset() const { return data_offset_; }
378
379 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
380 void SetSignature(const uint8_t* new_signature) {
381 memcpy(signature_, new_signature, sizeof(signature_));
382 }
383 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
384 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
385 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
386 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
387 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
388 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
389
Jeff Hao3ab96b42016-09-09 18:35:01 -0700390 Collections& GetCollections() { return collections_; }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700391
David Sehr7629f602016-08-07 16:01:51 -0700392 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
393
394 private:
David Sehr7629f602016-08-07 16:01:51 -0700395 uint8_t magic_[8];
396 uint32_t checksum_;
397 uint8_t signature_[DexFile::kSha1DigestSize];
398 uint32_t endian_tag_;
399 uint32_t file_size_;
400 uint32_t header_size_;
401 uint32_t link_size_;
402 uint32_t link_offset_;
403 uint32_t data_size_;
404 uint32_t data_offset_;
405
Jeff Hao3ab96b42016-09-09 18:35:01 -0700406 Collections collections_;
407
David Sehr7629f602016-08-07 16:01:51 -0700408 DISALLOW_COPY_AND_ASSIGN(Header);
409};
410
Jeff Hao3ab96b42016-09-09 18:35:01 -0700411class StringData : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700412 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700413 explicit StringData(const char* data) : data_(strdup(data)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000414 size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700415 }
David Sehr7629f602016-08-07 16:01:51 -0700416
417 const char* Data() const { return data_.get(); }
418
419 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
420
421 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000422 UniqueCPtr<const char> data_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700423
424 DISALLOW_COPY_AND_ASSIGN(StringData);
425};
426
427class StringId : public IndexedItem {
428 public:
429 explicit StringId(StringData* string_data) : string_data_(string_data) {
430 size_ = kStringIdItemSize;
431 }
432 ~StringId() OVERRIDE { }
433
434 static size_t ItemSize() { return kStringIdItemSize; }
435
436 const char* Data() const { return string_data_->Data(); }
437 StringData* DataItem() const { return string_data_; }
438
439 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
440
441 private:
442 StringData* string_data_;
443
David Sehr7629f602016-08-07 16:01:51 -0700444 DISALLOW_COPY_AND_ASSIGN(StringId);
445};
446
Jeff Hao3ab96b42016-09-09 18:35:01 -0700447class TypeId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700448 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700449 explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700450 ~TypeId() OVERRIDE { }
451
Jeff Hao3ab96b42016-09-09 18:35:01 -0700452 static size_t ItemSize() { return kTypeIdItemSize; }
453
David Sehr7629f602016-08-07 16:01:51 -0700454 StringId* GetStringId() const { return string_id_; }
455
456 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
457
458 private:
459 StringId* string_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700460
David Sehr7629f602016-08-07 16:01:51 -0700461 DISALLOW_COPY_AND_ASSIGN(TypeId);
462};
463
David Sehr853a8e12016-09-01 13:03:50 -0700464using TypeIdVector = std::vector<const TypeId*>;
465
Jeff Hao3ab96b42016-09-09 18:35:01 -0700466class TypeList : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700467 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700468 explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) {
469 size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t));
470 }
471 ~TypeList() OVERRIDE { }
472
473 const TypeIdVector* GetTypeList() const { return type_list_.get(); }
474
475 private:
476 std::unique_ptr<TypeIdVector> type_list_;
477
478 DISALLOW_COPY_AND_ASSIGN(TypeList);
479};
480
481class ProtoId : public IndexedItem {
482 public:
483 ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters)
484 : shorty_(shorty), return_type_(return_type), parameters_(parameters)
485 { size_ = kProtoIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700486 ~ProtoId() OVERRIDE { }
487
Jeff Hao3ab96b42016-09-09 18:35:01 -0700488 static size_t ItemSize() { return kProtoIdItemSize; }
489
David Sehr7629f602016-08-07 16:01:51 -0700490 const StringId* Shorty() const { return shorty_; }
491 const TypeId* ReturnType() const { return return_type_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000492 const TypeList* Parameters() const { return parameters_; }
David Sehr7629f602016-08-07 16:01:51 -0700493
494 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
495
496 private:
497 const StringId* shorty_;
498 const TypeId* return_type_;
Jeff Haoa8621002016-10-04 18:13:44 +0000499 TypeList* parameters_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700500
David Sehr7629f602016-08-07 16:01:51 -0700501 DISALLOW_COPY_AND_ASSIGN(ProtoId);
502};
503
Jeff Hao3ab96b42016-09-09 18:35:01 -0700504class FieldId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700505 public:
David Sehr853a8e12016-09-01 13:03:50 -0700506 FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700507 : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700508 ~FieldId() OVERRIDE { }
509
Jeff Hao3ab96b42016-09-09 18:35:01 -0700510 static size_t ItemSize() { return kFieldIdItemSize; }
511
David Sehr7629f602016-08-07 16:01:51 -0700512 const TypeId* Class() const { return class_; }
513 const TypeId* Type() const { return type_; }
514 const StringId* Name() const { return name_; }
515
516 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
517
518 private:
519 const TypeId* class_;
520 const TypeId* type_;
521 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700522
David Sehr7629f602016-08-07 16:01:51 -0700523 DISALLOW_COPY_AND_ASSIGN(FieldId);
524};
525
Jeff Hao3ab96b42016-09-09 18:35:01 -0700526class MethodId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700527 public:
David Sehr853a8e12016-09-01 13:03:50 -0700528 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700529 : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700530 ~MethodId() OVERRIDE { }
531
Jeff Hao3ab96b42016-09-09 18:35:01 -0700532 static size_t ItemSize() { return kMethodIdItemSize; }
533
David Sehr7629f602016-08-07 16:01:51 -0700534 const TypeId* Class() const { return class_; }
535 const ProtoId* Proto() const { return proto_; }
536 const StringId* Name() const { return name_; }
537
538 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
539
540 private:
541 const TypeId* class_;
542 const ProtoId* proto_;
543 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700544
David Sehr7629f602016-08-07 16:01:51 -0700545 DISALLOW_COPY_AND_ASSIGN(MethodId);
546};
547
548class FieldItem : public Item {
549 public:
David Sehr853a8e12016-09-01 13:03:50 -0700550 FieldItem(uint32_t access_flags, const FieldId* field_id)
551 : access_flags_(access_flags), field_id_(field_id) { }
David Sehr7629f602016-08-07 16:01:51 -0700552 ~FieldItem() OVERRIDE { }
553
554 uint32_t GetAccessFlags() const { return access_flags_; }
555 const FieldId* GetFieldId() const { return field_id_; }
556
557 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
558
559 private:
560 uint32_t access_flags_;
561 const FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700562
David Sehr7629f602016-08-07 16:01:51 -0700563 DISALLOW_COPY_AND_ASSIGN(FieldItem);
564};
565
David Sehr853a8e12016-09-01 13:03:50 -0700566using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
567
David Sehr7629f602016-08-07 16:01:51 -0700568class MethodItem : public Item {
569 public:
Jeff Haoea7c6292016-11-14 18:10:16 -0800570 MethodItem(uint32_t access_flags, const MethodId* method_id, CodeItem* code)
David Sehr853a8e12016-09-01 13:03:50 -0700571 : access_flags_(access_flags), method_id_(method_id), code_(code) { }
David Sehr7629f602016-08-07 16:01:51 -0700572 ~MethodItem() OVERRIDE { }
573
574 uint32_t GetAccessFlags() const { return access_flags_; }
575 const MethodId* GetMethodId() const { return method_id_; }
Jeff Haoea7c6292016-11-14 18:10:16 -0800576 CodeItem* GetCodeItem() { return code_; }
David Sehr7629f602016-08-07 16:01:51 -0700577
578 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
579
580 private:
581 uint32_t access_flags_;
582 const MethodId* method_id_;
Jeff Haoea7c6292016-11-14 18:10:16 -0800583 CodeItem* code_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700584
David Sehr7629f602016-08-07 16:01:51 -0700585 DISALLOW_COPY_AND_ASSIGN(MethodItem);
586};
587
David Sehr853a8e12016-09-01 13:03:50 -0700588using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
589
Jeff Hao3ab96b42016-09-09 18:35:01 -0700590class EncodedValue {
David Sehr7629f602016-08-07 16:01:51 -0700591 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700592 explicit EncodedValue(uint8_t type) : type_(type) { }
David Sehr7629f602016-08-07 16:01:51 -0700593
594 int8_t Type() const { return type_; }
David Sehr7629f602016-08-07 16:01:51 -0700595
Jeff Hao3ab96b42016-09-09 18:35:01 -0700596 void SetBoolean(bool z) { u_.bool_val_ = z; }
597 void SetByte(int8_t b) { u_.byte_val_ = b; }
598 void SetShort(int16_t s) { u_.short_val_ = s; }
599 void SetChar(uint16_t c) { u_.char_val_ = c; }
600 void SetInt(int32_t i) { u_.int_val_ = i; }
601 void SetLong(int64_t l) { u_.long_val_ = l; }
602 void SetFloat(float f) { u_.float_val_ = f; }
603 void SetDouble(double d) { u_.double_val_ = d; }
604 void SetStringId(StringId* string_id) { u_.string_val_ = string_id; }
605 void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; }
606 void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; }
607 void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; }
608 void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); }
609 void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation)
610 { encoded_annotation_.reset(encoded_annotation); }
611
612 bool GetBoolean() const { return u_.bool_val_; }
613 int8_t GetByte() const { return u_.byte_val_; }
614 int16_t GetShort() const { return u_.short_val_; }
615 uint16_t GetChar() const { return u_.char_val_; }
616 int32_t GetInt() const { return u_.int_val_; }
617 int64_t GetLong() const { return u_.long_val_; }
618 float GetFloat() const { return u_.float_val_; }
619 double GetDouble() const { return u_.double_val_; }
620 StringId* GetStringId() const { return u_.string_val_; }
621 TypeId* GetTypeId() const { return u_.type_val_; }
622 FieldId* GetFieldId() const { return u_.field_val_; }
623 MethodId* GetMethodId() const { return u_.method_val_; }
624 EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); }
625 EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); }
626
627 EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); }
David Sehr7629f602016-08-07 16:01:51 -0700628
629 private:
David Sehr7629f602016-08-07 16:01:51 -0700630 uint8_t type_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700631 union {
632 bool bool_val_;
633 int8_t byte_val_;
634 int16_t short_val_;
635 uint16_t char_val_;
636 int32_t int_val_;
637 int64_t long_val_;
638 float float_val_;
639 double double_val_;
640 StringId* string_val_;
641 TypeId* type_val_;
642 FieldId* field_val_;
643 MethodId* method_val_;
644 } u_;
645 std::unique_ptr<EncodedArrayItem> encoded_array_;
646 std::unique_ptr<EncodedAnnotation> encoded_annotation_;
647
648 DISALLOW_COPY_AND_ASSIGN(EncodedValue);
David Sehr7629f602016-08-07 16:01:51 -0700649};
650
Jeff Hao3ab96b42016-09-09 18:35:01 -0700651using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>;
652
653class AnnotationElement {
654 public:
655 AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { }
656
657 StringId* GetName() const { return name_; }
658 EncodedValue* GetValue() const { return value_.get(); }
659
660 private:
661 StringId* name_;
662 std::unique_ptr<EncodedValue> value_;
663
664 DISALLOW_COPY_AND_ASSIGN(AnnotationElement);
665};
666
667using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>;
668
669class EncodedAnnotation {
670 public:
671 EncodedAnnotation(TypeId* type, AnnotationElementVector* elements)
672 : type_(type), elements_(elements) { }
673
674 TypeId* GetType() const { return type_; }
675 AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); }
676
677 private:
678 TypeId* type_;
679 std::unique_ptr<AnnotationElementVector> elements_;
680
681 DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation);
682};
683
684class EncodedArrayItem : public Item {
685 public:
686 explicit EncodedArrayItem(EncodedValueVector* encoded_values)
687 : encoded_values_(encoded_values) { }
688
689 EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); }
690
691 private:
692 std::unique_ptr<EncodedValueVector> encoded_values_;
693
694 DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem);
695};
David Sehr853a8e12016-09-01 13:03:50 -0700696
David Sehr7629f602016-08-07 16:01:51 -0700697class ClassData : public Item {
698 public:
David Sehr853a8e12016-09-01 13:03:50 -0700699 ClassData(FieldItemVector* static_fields,
700 FieldItemVector* instance_fields,
701 MethodItemVector* direct_methods,
702 MethodItemVector* virtual_methods)
703 : static_fields_(static_fields),
704 instance_fields_(instance_fields),
705 direct_methods_(direct_methods),
706 virtual_methods_(virtual_methods) { }
707
David Sehr7629f602016-08-07 16:01:51 -0700708 ~ClassData() OVERRIDE = default;
David Sehr853a8e12016-09-01 13:03:50 -0700709 FieldItemVector* StaticFields() { return static_fields_.get(); }
710 FieldItemVector* InstanceFields() { return instance_fields_.get(); }
711 MethodItemVector* DirectMethods() { return direct_methods_.get(); }
712 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700713
714 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
715
716 private:
David Sehr853a8e12016-09-01 13:03:50 -0700717 std::unique_ptr<FieldItemVector> static_fields_;
718 std::unique_ptr<FieldItemVector> instance_fields_;
719 std::unique_ptr<MethodItemVector> direct_methods_;
720 std::unique_ptr<MethodItemVector> virtual_methods_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700721
David Sehr7629f602016-08-07 16:01:51 -0700722 DISALLOW_COPY_AND_ASSIGN(ClassData);
723};
724
Jeff Hao3ab96b42016-09-09 18:35:01 -0700725class ClassDef : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700726 public:
David Sehr853a8e12016-09-01 13:03:50 -0700727 ClassDef(const TypeId* class_type,
728 uint32_t access_flags,
729 const TypeId* superclass,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700730 TypeList* interfaces,
David Sehr853a8e12016-09-01 13:03:50 -0700731 const StringId* source_file,
732 AnnotationsDirectoryItem* annotations,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700733 EncodedArrayItem* static_values,
David Sehr853a8e12016-09-01 13:03:50 -0700734 ClassData* class_data)
735 : class_type_(class_type),
736 access_flags_(access_flags),
737 superclass_(superclass),
738 interfaces_(interfaces),
David Sehr853a8e12016-09-01 13:03:50 -0700739 source_file_(source_file),
740 annotations_(annotations),
Jeff Haoa8621002016-10-04 18:13:44 +0000741 class_data_(class_data),
742 static_values_(static_values) { size_ = kClassDefItemSize; }
David Sehr853a8e12016-09-01 13:03:50 -0700743
David Sehr7629f602016-08-07 16:01:51 -0700744 ~ClassDef() OVERRIDE { }
745
Jeff Hao3ab96b42016-09-09 18:35:01 -0700746 static size_t ItemSize() { return kClassDefItemSize; }
747
David Sehr7629f602016-08-07 16:01:51 -0700748 const TypeId* ClassType() const { return class_type_; }
749 uint32_t GetAccessFlags() const { return access_flags_; }
750 const TypeId* Superclass() const { return superclass_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700751 const TypeIdVector* Interfaces()
Roland Levillain5e8d5f02016-10-18 18:03:43 +0100752 { return interfaces_ == nullptr ? nullptr : interfaces_->GetTypeList(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700753 uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
David Sehr7629f602016-08-07 16:01:51 -0700754 const StringId* SourceFile() const { return source_file_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700755 AnnotationsDirectoryItem* Annotations() const { return annotations_; }
Nicolas Geoffrayfd1a6c22016-10-04 11:01:17 +0000756 ClassData* GetClassData() { return class_data_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000757 EncodedArrayItem* StaticValues() { return static_values_; }
David Sehr7629f602016-08-07 16:01:51 -0700758
Jeff Haoc3acfc52016-08-29 14:18:26 -0700759 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
760
David Sehr7629f602016-08-07 16:01:51 -0700761 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
762
763 private:
764 const TypeId* class_type_;
765 uint32_t access_flags_;
Jeff Haoa8621002016-10-04 18:13:44 +0000766 const TypeId* superclass_; // This can be nullptr.
767 TypeList* interfaces_; // This can be nullptr.
768 const StringId* source_file_; // This can be nullptr.
769 AnnotationsDirectoryItem* annotations_; // This can be nullptr.
770 ClassData* class_data_; // This can be nullptr.
771 EncodedArrayItem* static_values_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700772
David Sehr7629f602016-08-07 16:01:51 -0700773 DISALLOW_COPY_AND_ASSIGN(ClassDef);
774};
775
Jeff Haoa8621002016-10-04 18:13:44 +0000776class TypeAddrPair {
David Sehr853a8e12016-09-01 13:03:50 -0700777 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000778 TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
David Sehr853a8e12016-09-01 13:03:50 -0700779
780 const TypeId* GetTypeId() const { return type_id_; }
781 uint32_t GetAddress() const { return address_; }
782
783 private:
784 const TypeId* type_id_;
785 uint32_t address_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700786
Jeff Haoa8621002016-10-04 18:13:44 +0000787 DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
788};
789
790using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
791
792class CatchHandler {
793 public:
794 explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
795 : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
796
797 bool HasCatchAll() const { return catch_all_; }
798 uint16_t GetListOffset() const { return list_offset_; }
799 TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
800
801 private:
802 bool catch_all_;
803 uint16_t list_offset_;
804 std::unique_ptr<TypeAddrPairVector> handlers_;
805
David Sehr853a8e12016-09-01 13:03:50 -0700806 DISALLOW_COPY_AND_ASSIGN(CatchHandler);
807};
808
809using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
810
811class TryItem : public Item {
812 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000813 TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700814 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
815 ~TryItem() OVERRIDE { }
816
817 uint32_t StartAddr() const { return start_addr_; }
818 uint16_t InsnCount() const { return insn_count_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000819 const CatchHandler* GetHandlers() const { return handlers_; }
David Sehr853a8e12016-09-01 13:03:50 -0700820
821 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
822
823 private:
824 uint32_t start_addr_;
825 uint16_t insn_count_;
Jeff Haoa8621002016-10-04 18:13:44 +0000826 const CatchHandler* handlers_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700827
David Sehr853a8e12016-09-01 13:03:50 -0700828 DISALLOW_COPY_AND_ASSIGN(TryItem);
829};
830
831using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
832
David Sehrd1e44e22016-10-06 17:09:32 -0700833class CodeFixups {
834 public:
835 CodeFixups(std::vector<TypeId*>* type_ids,
836 std::vector<StringId*>* string_ids,
837 std::vector<MethodId*>* method_ids,
838 std::vector<FieldId*>* field_ids)
839 : type_ids_(type_ids),
840 string_ids_(string_ids),
841 method_ids_(method_ids),
842 field_ids_(field_ids) { }
843
844 std::vector<TypeId*>* TypeIds() const { return type_ids_.get(); }
845 std::vector<StringId*>* StringIds() const { return string_ids_.get(); }
846 std::vector<MethodId*>* MethodIds() const { return method_ids_.get(); }
847 std::vector<FieldId*>* FieldIds() const { return field_ids_.get(); }
848
849 private:
850 std::unique_ptr<std::vector<TypeId*>> type_ids_;
851 std::unique_ptr<std::vector<StringId*>> string_ids_;
852 std::unique_ptr<std::vector<MethodId*>> method_ids_;
853 std::unique_ptr<std::vector<FieldId*>> field_ids_;
854
855 DISALLOW_COPY_AND_ASSIGN(CodeFixups);
856};
857
David Sehr7629f602016-08-07 16:01:51 -0700858class CodeItem : public Item {
859 public:
David Sehr853a8e12016-09-01 13:03:50 -0700860 CodeItem(uint16_t registers_size,
861 uint16_t ins_size,
862 uint16_t outs_size,
863 DebugInfoItem* debug_info,
864 uint32_t insns_size,
865 uint16_t* insns,
Jeff Haoa8621002016-10-04 18:13:44 +0000866 TryItemVector* tries,
867 CatchHandlerVector* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700868 : registers_size_(registers_size),
869 ins_size_(ins_size),
870 outs_size_(outs_size),
871 debug_info_(debug_info),
872 insns_size_(insns_size),
873 insns_(insns),
Jeff Haoa8621002016-10-04 18:13:44 +0000874 tries_(tries),
875 handlers_(handlers) { }
David Sehr853a8e12016-09-01 13:03:50 -0700876
David Sehr7629f602016-08-07 16:01:51 -0700877 ~CodeItem() OVERRIDE { }
878
879 uint16_t RegistersSize() const { return registers_size_; }
880 uint16_t InsSize() const { return ins_size_; }
881 uint16_t OutsSize() const { return outs_size_; }
David Sehr853a8e12016-09-01 13:03:50 -0700882 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700883 DebugInfoItem* DebugInfo() const { return debug_info_; }
David Sehr7629f602016-08-07 16:01:51 -0700884 uint32_t InsnsSize() const { return insns_size_; }
885 uint16_t* Insns() const { return insns_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -0700886 TryItemVector* Tries() const { return tries_.get(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000887 CatchHandlerVector* Handlers() const { return handlers_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700888
David Sehrd1e44e22016-10-06 17:09:32 -0700889 void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); }
890 CodeFixups* GetCodeFixups() const { return fixups_.get(); }
891
David Sehr7629f602016-08-07 16:01:51 -0700892 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
893
894 private:
895 uint16_t registers_size_;
896 uint16_t ins_size_;
897 uint16_t outs_size_;
Jeff Haoa8621002016-10-04 18:13:44 +0000898 DebugInfoItem* debug_info_; // This can be nullptr.
David Sehr7629f602016-08-07 16:01:51 -0700899 uint32_t insns_size_;
900 std::unique_ptr<uint16_t[]> insns_;
Jeff Haoa8621002016-10-04 18:13:44 +0000901 std::unique_ptr<TryItemVector> tries_; // This can be nullptr.
902 std::unique_ptr<CatchHandlerVector> handlers_; // This can be nullptr.
David Sehrd1e44e22016-10-06 17:09:32 -0700903 std::unique_ptr<CodeFixups> fixups_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700904
David Sehr7629f602016-08-07 16:01:51 -0700905 DISALLOW_COPY_AND_ASSIGN(CodeItem);
906};
907
David Sehr7629f602016-08-07 16:01:51 -0700908struct PositionInfo {
909 PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { }
910
911 uint32_t address_;
912 uint32_t line_;
913};
914
David Sehr853a8e12016-09-01 13:03:50 -0700915using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>;
916
David Sehr7629f602016-08-07 16:01:51 -0700917struct LocalInfo {
David Sehr853a8e12016-09-01 13:03:50 -0700918 LocalInfo(const char* name,
919 const char* descriptor,
920 const char* signature,
921 uint32_t start_address,
922 uint32_t end_address,
923 uint16_t reg)
924 : name_(name),
925 descriptor_(descriptor),
926 signature_(signature),
927 start_address_(start_address),
928 end_address_(end_address),
929 reg_(reg) { }
David Sehr7629f602016-08-07 16:01:51 -0700930
931 std::string name_;
932 std::string descriptor_;
933 std::string signature_;
934 uint32_t start_address_;
935 uint32_t end_address_;
936 uint16_t reg_;
937};
938
David Sehr853a8e12016-09-01 13:03:50 -0700939using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>;
940
David Sehr7629f602016-08-07 16:01:51 -0700941class DebugInfoItem : public Item {
942 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000943 DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
944 : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
945
946 uint32_t GetDebugInfoSize() const { return debug_info_size_; }
947 uint8_t* GetDebugInfo() const { return debug_info_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700948
David Sehr853a8e12016-09-01 13:03:50 -0700949 PositionInfoVector& GetPositionInfo() { return positions_; }
950 LocalInfoVector& GetLocalInfo() { return locals_; }
David Sehr7629f602016-08-07 16:01:51 -0700951
952 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000953 uint32_t debug_info_size_;
954 std::unique_ptr<uint8_t[]> debug_info_;
955
David Sehr853a8e12016-09-01 13:03:50 -0700956 PositionInfoVector positions_;
957 LocalInfoVector locals_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700958
David Sehr7629f602016-08-07 16:01:51 -0700959 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
960};
961
Jeff Hao3ab96b42016-09-09 18:35:01 -0700962class AnnotationItem : public Item {
David Sehr853a8e12016-09-01 13:03:50 -0700963 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700964 AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation)
965 : visibility_(visibility), annotation_(annotation) { }
David Sehr853a8e12016-09-01 13:03:50 -0700966
967 uint8_t GetVisibility() const { return visibility_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700968 EncodedAnnotation* GetAnnotation() const { return annotation_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700969
970 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
971
972 private:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700973 uint8_t visibility_;
974 std::unique_ptr<EncodedAnnotation> annotation_;
975
976 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
977};
978
979class AnnotationSetItem : public Item {
980 public:
981 explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) {
982 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
983 }
984 ~AnnotationSetItem() OVERRIDE { }
985
986 std::vector<AnnotationItem*>* GetItems() { return items_.get(); }
987
988 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
989
990 private:
991 std::unique_ptr<std::vector<AnnotationItem*>> items_;
992
David Sehr7629f602016-08-07 16:01:51 -0700993 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
994};
995
Jeff Hao3ab96b42016-09-09 18:35:01 -0700996class AnnotationSetRefList : public Item {
997 public:
998 explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) {
999 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
1000 }
1001 ~AnnotationSetRefList() OVERRIDE { }
1002
1003 std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); }
1004
1005 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1006
1007 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001008 std::unique_ptr<std::vector<AnnotationSetItem*>> items_; // Elements of vector can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001009
1010 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
1011};
David Sehr853a8e12016-09-01 13:03:50 -07001012
1013class FieldAnnotation {
1014 public:
1015 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
1016 : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
1017
1018 FieldId* GetFieldId() const { return field_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001019 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001020
1021 private:
1022 FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001023 AnnotationSetItem* annotation_set_item_;
1024
David Sehr853a8e12016-09-01 13:03:50 -07001025 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
1026};
1027
1028using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
1029
1030class MethodAnnotation {
1031 public:
1032 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
1033 : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
1034
1035 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001036 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001037
1038 private:
1039 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001040 AnnotationSetItem* annotation_set_item_;
1041
David Sehr853a8e12016-09-01 13:03:50 -07001042 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
1043};
1044
1045using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
1046
1047class ParameterAnnotation {
1048 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001049 ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations)
David Sehr853a8e12016-09-01 13:03:50 -07001050 : method_id_(method_id), annotations_(annotations) { }
1051
1052 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001053 AnnotationSetRefList* GetAnnotations() { return annotations_; }
David Sehr853a8e12016-09-01 13:03:50 -07001054
1055 private:
1056 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001057 AnnotationSetRefList* annotations_;
1058
David Sehr853a8e12016-09-01 13:03:50 -07001059 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
1060};
1061
1062using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
1063
David Sehr7629f602016-08-07 16:01:51 -07001064class AnnotationsDirectoryItem : public Item {
1065 public:
David Sehr853a8e12016-09-01 13:03:50 -07001066 AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
1067 FieldAnnotationVector* field_annotations,
1068 MethodAnnotationVector* method_annotations,
1069 ParameterAnnotationVector* parameter_annotations)
1070 : class_annotation_(class_annotation),
1071 field_annotations_(field_annotations),
1072 method_annotations_(method_annotations),
1073 parameter_annotations_(parameter_annotations) { }
David Sehr7629f602016-08-07 16:01:51 -07001074
Jeff Hao3ab96b42016-09-09 18:35:01 -07001075 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; }
David Sehr853a8e12016-09-01 13:03:50 -07001076 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
1077 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
1078 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001079
1080 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1081
1082 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001083 AnnotationSetItem* class_annotation_; // This can be nullptr.
1084 std::unique_ptr<FieldAnnotationVector> field_annotations_; // This can be nullptr.
1085 std::unique_ptr<MethodAnnotationVector> method_annotations_; // This can be nullptr.
1086 std::unique_ptr<ParameterAnnotationVector> parameter_annotations_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001087
David Sehr7629f602016-08-07 16:01:51 -07001088 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
1089};
1090
1091// TODO(sehr): implement MapList.
1092class MapList : public Item {
1093 public:
1094 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1095
1096 private:
1097 DISALLOW_COPY_AND_ASSIGN(MapList);
1098};
1099
1100class MapItem : public Item {
1101 public:
1102 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1103
1104 private:
1105 DISALLOW_COPY_AND_ASSIGN(MapItem);
1106};
1107
1108} // namespace dex_ir
1109} // namespace art
1110
1111#endif // ART_DEXLAYOUT_DEX_IR_H_