blob: 38eb0b1b4b1399c416c21bcd5c28e212b42c1153 [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
David Sehr7629f602016-08-07 16:01:51 -070022#include <vector>
23#include <stdint.h>
24
David Sehr853a8e12016-09-01 13:03:50 -070025#include "dex_file-inl.h"
Jeff Hao3ab96b42016-09-09 18:35:01 -070026#include "leb128.h"
Jeff Haoa8621002016-10-04 18:13:44 +000027#include "utf.h"
David Sehr7629f602016-08-07 16:01:51 -070028
29namespace art {
30namespace dex_ir {
31
32// Forward declarations for classes used in containers or pointed to.
Jeff Hao3ab96b42016-09-09 18:35:01 -070033class AnnotationItem;
David Sehr7629f602016-08-07 16:01:51 -070034class AnnotationsDirectoryItem;
35class AnnotationSetItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070036class AnnotationSetRefList;
David Sehr7629f602016-08-07 16:01:51 -070037class ClassData;
38class ClassDef;
39class CodeItem;
40class DebugInfoItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070041class EncodedAnnotation;
42class EncodedArrayItem;
43class EncodedValue;
David Sehr7629f602016-08-07 16:01:51 -070044class FieldId;
45class FieldItem;
46class Header;
47class MapList;
48class MapItem;
49class MethodId;
50class MethodItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070051class ParameterAnnotation;
David Sehr7629f602016-08-07 16:01:51 -070052class ProtoId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070053class StringData;
David Sehr7629f602016-08-07 16:01:51 -070054class StringId;
55class TryItem;
56class TypeId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070057class TypeList;
58
59// Item size constants.
60static constexpr size_t kHeaderItemSize = 112;
61static constexpr size_t kStringIdItemSize = 4;
62static constexpr size_t kTypeIdItemSize = 4;
63static constexpr size_t kProtoIdItemSize = 12;
64static constexpr size_t kFieldIdItemSize = 8;
65static constexpr size_t kMethodIdItemSize = 8;
66static constexpr size_t kClassDefItemSize = 32;
David Sehr7629f602016-08-07 16:01:51 -070067
68// Visitor support
69class AbstractDispatcher {
70 public:
71 AbstractDispatcher() = default;
72 virtual ~AbstractDispatcher() { }
73
74 virtual void Dispatch(Header* header) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070075 virtual void Dispatch(const StringData* string_data) = 0;
David Sehr7629f602016-08-07 16:01:51 -070076 virtual void Dispatch(const StringId* string_id) = 0;
77 virtual void Dispatch(const TypeId* type_id) = 0;
78 virtual void Dispatch(const ProtoId* proto_id) = 0;
79 virtual void Dispatch(const FieldId* field_id) = 0;
80 virtual void Dispatch(const MethodId* method_id) = 0;
81 virtual void Dispatch(ClassData* class_data) = 0;
82 virtual void Dispatch(ClassDef* class_def) = 0;
83 virtual void Dispatch(FieldItem* field_item) = 0;
84 virtual void Dispatch(MethodItem* method_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070085 virtual void Dispatch(EncodedArrayItem* array_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070086 virtual void Dispatch(CodeItem* code_item) = 0;
87 virtual void Dispatch(TryItem* try_item) = 0;
88 virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070089 virtual void Dispatch(AnnotationItem* annotation_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070090 virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070091 virtual void Dispatch(AnnotationSetRefList* annotation_set_ref_list) = 0;
David Sehr7629f602016-08-07 16:01:51 -070092 virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
93 virtual void Dispatch(MapList* map_list) = 0;
94 virtual void Dispatch(MapItem* map_item) = 0;
95
96 private:
97 DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
98};
99
100// Collections become owners of the objects added by moving them into unique pointers.
101template<class T> class CollectionWithOffset {
102 public:
103 CollectionWithOffset() = default;
104 std::vector<std::unique_ptr<T>>& Collection() { return collection_; }
105 // Read-time support methods
Jeff Hao3ab96b42016-09-09 18:35:01 -0700106 void AddItem(T* object, uint32_t offset) {
107 object->SetOffset(offset);
David Sehr7629f602016-08-07 16:01:51 -0700108 collection_.push_back(std::unique_ptr<T>(object));
Jeff Hao3ab96b42016-09-09 18:35:01 -0700109 }
110 void AddIndexedItem(T* object, uint32_t offset, uint32_t index) {
111 object->SetOffset(offset);
112 object->SetIndex(index);
113 collection_.push_back(std::unique_ptr<T>(object));
David Sehr7629f602016-08-07 16:01:51 -0700114 }
115 // Ordinary object insertion into collection.
116 void Insert(T object ATTRIBUTE_UNUSED) {
117 // TODO(sehr): add ordered insertion support.
118 UNIMPLEMENTED(FATAL) << "Insertion not ready";
119 }
120 uint32_t GetOffset() const { return offset_; }
121 void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
122 uint32_t Size() const { return collection_.size(); }
123
124 private:
125 std::vector<std::unique_ptr<T>> collection_;
126 uint32_t offset_ = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700127
David Sehr7629f602016-08-07 16:01:51 -0700128 DISALLOW_COPY_AND_ASSIGN(CollectionWithOffset);
129};
130
Jeff Hao3ab96b42016-09-09 18:35:01 -0700131class Collections {
132 public:
133 Collections() = default;
134
135 std::vector<std::unique_ptr<StringId>>& StringIds() { return string_ids_.Collection(); }
136 std::vector<std::unique_ptr<TypeId>>& TypeIds() { return type_ids_.Collection(); }
137 std::vector<std::unique_ptr<ProtoId>>& ProtoIds() { return proto_ids_.Collection(); }
138 std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); }
139 std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); }
140 std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000141 std::vector<std::unique_ptr<StringData>>& StringDatas() { return string_datas_.Collection(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700142 std::vector<std::unique_ptr<TypeList>>& TypeLists() { return type_lists_.Collection(); }
143 std::vector<std::unique_ptr<EncodedArrayItem>>& EncodedArrayItems()
144 { return encoded_array_items_.Collection(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000145 std::vector<std::unique_ptr<AnnotationItem>>& AnnotationItems()
146 { return annotation_items_.Collection(); }
147 std::vector<std::unique_ptr<AnnotationSetItem>>& AnnotationSetItems()
148 { return annotation_set_items_.Collection(); }
149 std::vector<std::unique_ptr<AnnotationSetRefList>>& AnnotationSetRefLists()
150 { return annotation_set_ref_lists_.Collection(); }
151 std::vector<std::unique_ptr<AnnotationsDirectoryItem>>& AnnotationsDirectoryItems()
152 { return annotations_directory_items_.Collection(); }
153 std::vector<std::unique_ptr<DebugInfoItem>>& DebugInfoItems()
154 { return debug_info_items_.Collection(); }
155 std::vector<std::unique_ptr<CodeItem>>& CodeItems() { return code_items_.Collection(); }
156 std::vector<std::unique_ptr<ClassData>>& ClassDatas() { return class_datas_.Collection(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700157
158 void CreateStringId(const DexFile& dex_file, uint32_t i);
159 void CreateTypeId(const DexFile& dex_file, uint32_t i);
160 void CreateProtoId(const DexFile& dex_file, uint32_t i);
161 void CreateFieldId(const DexFile& dex_file, uint32_t i);
162 void CreateMethodId(const DexFile& dex_file, uint32_t i);
163 void CreateClassDef(const DexFile& dex_file, uint32_t i);
164
Jeff Haoa8621002016-10-04 18:13:44 +0000165 TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700166 EncodedArrayItem* CreateEncodedArrayItem(const uint8_t* static_data, uint32_t offset);
167 AnnotationItem* CreateAnnotationItem(const DexFile::AnnotationItem* annotation, uint32_t offset);
168 AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
169 const DexFile::AnnotationSetItem& disk_annotations_item, uint32_t offset);
170 AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file,
171 const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset);
172 CodeItem* CreateCodeItem(
173 const DexFile& dex_file, const DexFile::CodeItem& disk_code_item, uint32_t offset);
174 ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
175
176 StringId* GetStringId(uint32_t index) { return StringIds()[index].get(); }
177 TypeId* GetTypeId(uint32_t index) { return TypeIds()[index].get(); }
178 ProtoId* GetProtoId(uint32_t index) { return ProtoIds()[index].get(); }
179 FieldId* GetFieldId(uint32_t index) { return FieldIds()[index].get(); }
180 MethodId* GetMethodId(uint32_t index) { return MethodIds()[index].get(); }
181 ClassDef* GetClassDef(uint32_t index) { return ClassDefs()[index].get(); }
182
183 StringId* GetStringIdOrNullPtr(uint32_t index) {
184 return index == DexFile::kDexNoIndex ? nullptr : GetStringId(index);
185 }
186 TypeId* GetTypeIdOrNullPtr(uint16_t index) {
187 return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index);
188 }
189
190 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
191 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
192 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
193 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
194 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
195 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
196 uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
197 uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000198 uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
199 uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
200 uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700201 uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000202 uint32_t AnnotationsDirectoryItemsOffset() const
203 { return annotations_directory_items_.GetOffset(); }
204 uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700205 uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
206 uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000207 uint32_t MapItemOffset() const { return map_item_offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700208
209 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
210 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
211 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
212 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
213 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
214 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
215 void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
216 void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000217 void SetEncodedArrayItemsOffset(uint32_t new_offset)
218 { encoded_array_items_.SetOffset(new_offset); }
219 void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
220 void SetAnnotationSetItemsOffset(uint32_t new_offset)
221 { annotation_set_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700222 void SetAnnotationSetRefListsOffset(uint32_t new_offset)
223 { annotation_set_ref_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000224 void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700225 { annotations_directory_items_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000226 void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700227 void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
228 void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000229 void SetMapItemOffset(uint32_t new_offset) { map_item_offset_ = new_offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700230
231 uint32_t StringIdsSize() const { return string_ids_.Size(); }
232 uint32_t TypeIdsSize() const { return type_ids_.Size(); }
233 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
234 uint32_t FieldIdsSize() const { return field_ids_.Size(); }
235 uint32_t MethodIdsSize() const { return method_ids_.Size(); }
236 uint32_t ClassDefsSize() const { return class_defs_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700237 uint32_t StringDatasSize() const { return string_datas_.Size(); }
238 uint32_t TypeListsSize() const { return type_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000239 uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
240 uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
241 uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700242 uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000243 uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
244 uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700245 uint32_t CodeItemsSize() const { return code_items_.Size(); }
246 uint32_t ClassDatasSize() const { return class_datas_.Size(); }
247
Jeff Hao3ab96b42016-09-09 18:35:01 -0700248 private:
249 EncodedValue* ReadEncodedValue(const uint8_t** data);
250 EncodedValue* ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length);
251 void ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length, EncodedValue* item);
252
253 ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
254 const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
255 MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
256
257 CollectionWithOffset<StringId> string_ids_;
258 CollectionWithOffset<TypeId> type_ids_;
259 CollectionWithOffset<ProtoId> proto_ids_;
260 CollectionWithOffset<FieldId> field_ids_;
261 CollectionWithOffset<MethodId> method_ids_;
262 CollectionWithOffset<ClassDef> class_defs_;
263
264 CollectionWithOffset<StringData> string_datas_;
265 CollectionWithOffset<TypeList> type_lists_;
266 CollectionWithOffset<EncodedArrayItem> encoded_array_items_;
267 CollectionWithOffset<AnnotationItem> annotation_items_;
268 CollectionWithOffset<AnnotationSetItem> annotation_set_items_;
269 CollectionWithOffset<AnnotationSetRefList> annotation_set_ref_lists_;
270 CollectionWithOffset<AnnotationsDirectoryItem> annotations_directory_items_;
271 CollectionWithOffset<DebugInfoItem> debug_info_items_;
272 CollectionWithOffset<CodeItem> code_items_;
273 CollectionWithOffset<ClassData> class_datas_;
274
Jeff Haoa8621002016-10-04 18:13:44 +0000275 uint32_t map_item_offset_ = 0;
276
Jeff Hao3ab96b42016-09-09 18:35:01 -0700277 DISALLOW_COPY_AND_ASSIGN(Collections);
278};
279
David Sehr7629f602016-08-07 16:01:51 -0700280class Item {
281 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700282 Item() { }
David Sehr7629f602016-08-07 16:01:51 -0700283 virtual ~Item() { }
David Sehr853a8e12016-09-01 13:03:50 -0700284
David Sehr7629f602016-08-07 16:01:51 -0700285 uint32_t GetOffset() const { return offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700286 uint32_t GetSize() const { return size_; }
David Sehr7629f602016-08-07 16:01:51 -0700287 void SetOffset(uint32_t offset) { offset_ = offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700288 void SetSize(uint32_t size) { size_ = size; }
David Sehr853a8e12016-09-01 13:03:50 -0700289
David Sehr7629f602016-08-07 16:01:51 -0700290 protected:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700291 Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
292
David Sehr7629f602016-08-07 16:01:51 -0700293 uint32_t offset_ = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700294 uint32_t size_ = 0;
295};
296
297class IndexedItem : public Item {
298 public:
299 IndexedItem() { }
300 virtual ~IndexedItem() { }
301
302 uint32_t GetIndex() const { return index_; }
303 void SetIndex(uint32_t index) { index_ = index; }
304
305 protected:
306 IndexedItem(uint32_t offset, uint32_t size, uint32_t index)
307 : Item(offset, size), index_(index) { }
308
309 uint32_t index_ = 0;
David Sehr7629f602016-08-07 16:01:51 -0700310};
311
312class Header : public Item {
313 public:
David Sehr853a8e12016-09-01 13:03:50 -0700314 Header(const uint8_t* magic,
315 uint32_t checksum,
316 const uint8_t* signature,
317 uint32_t endian_tag,
318 uint32_t file_size,
319 uint32_t header_size,
320 uint32_t link_size,
321 uint32_t link_offset,
322 uint32_t data_size,
323 uint32_t data_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700324 : Item(0, kHeaderItemSize),
325 checksum_(checksum),
David Sehr853a8e12016-09-01 13:03:50 -0700326 endian_tag_(endian_tag),
327 file_size_(file_size),
328 header_size_(header_size),
329 link_size_(link_size),
330 link_offset_(link_offset),
331 data_size_(data_size),
332 data_offset_(data_offset) {
333 memcpy(magic_, magic, sizeof(magic_));
334 memcpy(signature_, signature, sizeof(signature_));
335 }
David Sehr7629f602016-08-07 16:01:51 -0700336 ~Header() OVERRIDE { }
337
Jeff Hao3ab96b42016-09-09 18:35:01 -0700338 static size_t ItemSize() { return kHeaderItemSize; }
339
David Sehr7629f602016-08-07 16:01:51 -0700340 const uint8_t* Magic() const { return magic_; }
341 uint32_t Checksum() const { return checksum_; }
342 const uint8_t* Signature() const { return signature_; }
343 uint32_t EndianTag() const { return endian_tag_; }
344 uint32_t FileSize() const { return file_size_; }
345 uint32_t HeaderSize() const { return header_size_; }
346 uint32_t LinkSize() const { return link_size_; }
347 uint32_t LinkOffset() const { return link_offset_; }
348 uint32_t DataSize() const { return data_size_; }
349 uint32_t DataOffset() const { return data_offset_; }
350
351 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
352 void SetSignature(const uint8_t* new_signature) {
353 memcpy(signature_, new_signature, sizeof(signature_));
354 }
355 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
356 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
357 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
358 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
359 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
360 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
361
Jeff Hao3ab96b42016-09-09 18:35:01 -0700362 Collections& GetCollections() { return collections_; }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700363
David Sehr7629f602016-08-07 16:01:51 -0700364 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
365
366 private:
David Sehr7629f602016-08-07 16:01:51 -0700367 uint8_t magic_[8];
368 uint32_t checksum_;
369 uint8_t signature_[DexFile::kSha1DigestSize];
370 uint32_t endian_tag_;
371 uint32_t file_size_;
372 uint32_t header_size_;
373 uint32_t link_size_;
374 uint32_t link_offset_;
375 uint32_t data_size_;
376 uint32_t data_offset_;
377
Jeff Hao3ab96b42016-09-09 18:35:01 -0700378 Collections collections_;
379
David Sehr7629f602016-08-07 16:01:51 -0700380 DISALLOW_COPY_AND_ASSIGN(Header);
381};
382
Jeff Hao3ab96b42016-09-09 18:35:01 -0700383class StringData : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700384 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700385 explicit StringData(const char* data) : data_(strdup(data)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000386 size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700387 }
David Sehr7629f602016-08-07 16:01:51 -0700388
389 const char* Data() const { return data_.get(); }
390
391 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
392
393 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000394 UniqueCPtr<const char> data_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700395
396 DISALLOW_COPY_AND_ASSIGN(StringData);
397};
398
399class StringId : public IndexedItem {
400 public:
401 explicit StringId(StringData* string_data) : string_data_(string_data) {
402 size_ = kStringIdItemSize;
403 }
404 ~StringId() OVERRIDE { }
405
406 static size_t ItemSize() { return kStringIdItemSize; }
407
408 const char* Data() const { return string_data_->Data(); }
409 StringData* DataItem() const { return string_data_; }
410
411 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
412
413 private:
414 StringData* string_data_;
415
David Sehr7629f602016-08-07 16:01:51 -0700416 DISALLOW_COPY_AND_ASSIGN(StringId);
417};
418
Jeff Hao3ab96b42016-09-09 18:35:01 -0700419class TypeId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700420 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700421 explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700422 ~TypeId() OVERRIDE { }
423
Jeff Hao3ab96b42016-09-09 18:35:01 -0700424 static size_t ItemSize() { return kTypeIdItemSize; }
425
David Sehr7629f602016-08-07 16:01:51 -0700426 StringId* GetStringId() const { return string_id_; }
427
428 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
429
430 private:
431 StringId* string_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700432
David Sehr7629f602016-08-07 16:01:51 -0700433 DISALLOW_COPY_AND_ASSIGN(TypeId);
434};
435
David Sehr853a8e12016-09-01 13:03:50 -0700436using TypeIdVector = std::vector<const TypeId*>;
437
Jeff Hao3ab96b42016-09-09 18:35:01 -0700438class TypeList : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700439 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700440 explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) {
441 size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t));
442 }
443 ~TypeList() OVERRIDE { }
444
445 const TypeIdVector* GetTypeList() const { return type_list_.get(); }
446
447 private:
448 std::unique_ptr<TypeIdVector> type_list_;
449
450 DISALLOW_COPY_AND_ASSIGN(TypeList);
451};
452
453class ProtoId : public IndexedItem {
454 public:
455 ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters)
456 : shorty_(shorty), return_type_(return_type), parameters_(parameters)
457 { size_ = kProtoIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700458 ~ProtoId() OVERRIDE { }
459
Jeff Hao3ab96b42016-09-09 18:35:01 -0700460 static size_t ItemSize() { return kProtoIdItemSize; }
461
David Sehr7629f602016-08-07 16:01:51 -0700462 const StringId* Shorty() const { return shorty_; }
463 const TypeId* ReturnType() const { return return_type_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000464 const TypeList* Parameters() const { return parameters_; }
David Sehr7629f602016-08-07 16:01:51 -0700465
466 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
467
468 private:
469 const StringId* shorty_;
470 const TypeId* return_type_;
Jeff Haoa8621002016-10-04 18:13:44 +0000471 TypeList* parameters_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700472
David Sehr7629f602016-08-07 16:01:51 -0700473 DISALLOW_COPY_AND_ASSIGN(ProtoId);
474};
475
Jeff Hao3ab96b42016-09-09 18:35:01 -0700476class FieldId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700477 public:
David Sehr853a8e12016-09-01 13:03:50 -0700478 FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700479 : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700480 ~FieldId() OVERRIDE { }
481
Jeff Hao3ab96b42016-09-09 18:35:01 -0700482 static size_t ItemSize() { return kFieldIdItemSize; }
483
David Sehr7629f602016-08-07 16:01:51 -0700484 const TypeId* Class() const { return class_; }
485 const TypeId* Type() const { return type_; }
486 const StringId* Name() const { return name_; }
487
488 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
489
490 private:
491 const TypeId* class_;
492 const TypeId* type_;
493 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700494
David Sehr7629f602016-08-07 16:01:51 -0700495 DISALLOW_COPY_AND_ASSIGN(FieldId);
496};
497
Jeff Hao3ab96b42016-09-09 18:35:01 -0700498class MethodId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700499 public:
David Sehr853a8e12016-09-01 13:03:50 -0700500 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700501 : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700502 ~MethodId() OVERRIDE { }
503
Jeff Hao3ab96b42016-09-09 18:35:01 -0700504 static size_t ItemSize() { return kMethodIdItemSize; }
505
David Sehr7629f602016-08-07 16:01:51 -0700506 const TypeId* Class() const { return class_; }
507 const ProtoId* Proto() const { return proto_; }
508 const StringId* Name() const { return name_; }
509
510 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
511
512 private:
513 const TypeId* class_;
514 const ProtoId* proto_;
515 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700516
David Sehr7629f602016-08-07 16:01:51 -0700517 DISALLOW_COPY_AND_ASSIGN(MethodId);
518};
519
520class FieldItem : public Item {
521 public:
David Sehr853a8e12016-09-01 13:03:50 -0700522 FieldItem(uint32_t access_flags, const FieldId* field_id)
523 : access_flags_(access_flags), field_id_(field_id) { }
David Sehr7629f602016-08-07 16:01:51 -0700524 ~FieldItem() OVERRIDE { }
525
526 uint32_t GetAccessFlags() const { return access_flags_; }
527 const FieldId* GetFieldId() const { return field_id_; }
528
529 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
530
531 private:
532 uint32_t access_flags_;
533 const FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700534
David Sehr7629f602016-08-07 16:01:51 -0700535 DISALLOW_COPY_AND_ASSIGN(FieldItem);
536};
537
David Sehr853a8e12016-09-01 13:03:50 -0700538using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
539
David Sehr7629f602016-08-07 16:01:51 -0700540class MethodItem : public Item {
541 public:
David Sehr853a8e12016-09-01 13:03:50 -0700542 MethodItem(uint32_t access_flags, const MethodId* method_id, const CodeItem* code)
543 : access_flags_(access_flags), method_id_(method_id), code_(code) { }
David Sehr7629f602016-08-07 16:01:51 -0700544 ~MethodItem() OVERRIDE { }
545
546 uint32_t GetAccessFlags() const { return access_flags_; }
547 const MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700548 const CodeItem* GetCodeItem() const { return code_; }
David Sehr7629f602016-08-07 16:01:51 -0700549
550 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
551
552 private:
553 uint32_t access_flags_;
554 const MethodId* method_id_;
Jeff Haoa8621002016-10-04 18:13:44 +0000555 const CodeItem* code_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700556
David Sehr7629f602016-08-07 16:01:51 -0700557 DISALLOW_COPY_AND_ASSIGN(MethodItem);
558};
559
David Sehr853a8e12016-09-01 13:03:50 -0700560using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
561
Jeff Hao3ab96b42016-09-09 18:35:01 -0700562class EncodedValue {
David Sehr7629f602016-08-07 16:01:51 -0700563 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700564 explicit EncodedValue(uint8_t type) : type_(type) { }
David Sehr7629f602016-08-07 16:01:51 -0700565
566 int8_t Type() const { return type_; }
David Sehr7629f602016-08-07 16:01:51 -0700567
Jeff Hao3ab96b42016-09-09 18:35:01 -0700568 void SetBoolean(bool z) { u_.bool_val_ = z; }
569 void SetByte(int8_t b) { u_.byte_val_ = b; }
570 void SetShort(int16_t s) { u_.short_val_ = s; }
571 void SetChar(uint16_t c) { u_.char_val_ = c; }
572 void SetInt(int32_t i) { u_.int_val_ = i; }
573 void SetLong(int64_t l) { u_.long_val_ = l; }
574 void SetFloat(float f) { u_.float_val_ = f; }
575 void SetDouble(double d) { u_.double_val_ = d; }
576 void SetStringId(StringId* string_id) { u_.string_val_ = string_id; }
577 void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; }
578 void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; }
579 void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; }
580 void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); }
581 void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation)
582 { encoded_annotation_.reset(encoded_annotation); }
583
584 bool GetBoolean() const { return u_.bool_val_; }
585 int8_t GetByte() const { return u_.byte_val_; }
586 int16_t GetShort() const { return u_.short_val_; }
587 uint16_t GetChar() const { return u_.char_val_; }
588 int32_t GetInt() const { return u_.int_val_; }
589 int64_t GetLong() const { return u_.long_val_; }
590 float GetFloat() const { return u_.float_val_; }
591 double GetDouble() const { return u_.double_val_; }
592 StringId* GetStringId() const { return u_.string_val_; }
593 TypeId* GetTypeId() const { return u_.type_val_; }
594 FieldId* GetFieldId() const { return u_.field_val_; }
595 MethodId* GetMethodId() const { return u_.method_val_; }
596 EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); }
597 EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); }
598
599 EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); }
David Sehr7629f602016-08-07 16:01:51 -0700600
601 private:
David Sehr7629f602016-08-07 16:01:51 -0700602 uint8_t type_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700603 union {
604 bool bool_val_;
605 int8_t byte_val_;
606 int16_t short_val_;
607 uint16_t char_val_;
608 int32_t int_val_;
609 int64_t long_val_;
610 float float_val_;
611 double double_val_;
612 StringId* string_val_;
613 TypeId* type_val_;
614 FieldId* field_val_;
615 MethodId* method_val_;
616 } u_;
617 std::unique_ptr<EncodedArrayItem> encoded_array_;
618 std::unique_ptr<EncodedAnnotation> encoded_annotation_;
619
620 DISALLOW_COPY_AND_ASSIGN(EncodedValue);
David Sehr7629f602016-08-07 16:01:51 -0700621};
622
Jeff Hao3ab96b42016-09-09 18:35:01 -0700623using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>;
624
625class AnnotationElement {
626 public:
627 AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { }
628
629 StringId* GetName() const { return name_; }
630 EncodedValue* GetValue() const { return value_.get(); }
631
632 private:
633 StringId* name_;
634 std::unique_ptr<EncodedValue> value_;
635
636 DISALLOW_COPY_AND_ASSIGN(AnnotationElement);
637};
638
639using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>;
640
641class EncodedAnnotation {
642 public:
643 EncodedAnnotation(TypeId* type, AnnotationElementVector* elements)
644 : type_(type), elements_(elements) { }
645
646 TypeId* GetType() const { return type_; }
647 AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); }
648
649 private:
650 TypeId* type_;
651 std::unique_ptr<AnnotationElementVector> elements_;
652
653 DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation);
654};
655
656class EncodedArrayItem : public Item {
657 public:
658 explicit EncodedArrayItem(EncodedValueVector* encoded_values)
659 : encoded_values_(encoded_values) { }
660
661 EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); }
662
663 private:
664 std::unique_ptr<EncodedValueVector> encoded_values_;
665
666 DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem);
667};
David Sehr853a8e12016-09-01 13:03:50 -0700668
David Sehr7629f602016-08-07 16:01:51 -0700669class ClassData : public Item {
670 public:
David Sehr853a8e12016-09-01 13:03:50 -0700671 ClassData(FieldItemVector* static_fields,
672 FieldItemVector* instance_fields,
673 MethodItemVector* direct_methods,
674 MethodItemVector* virtual_methods)
675 : static_fields_(static_fields),
676 instance_fields_(instance_fields),
677 direct_methods_(direct_methods),
678 virtual_methods_(virtual_methods) { }
679
David Sehr7629f602016-08-07 16:01:51 -0700680 ~ClassData() OVERRIDE = default;
David Sehr853a8e12016-09-01 13:03:50 -0700681 FieldItemVector* StaticFields() { return static_fields_.get(); }
682 FieldItemVector* InstanceFields() { return instance_fields_.get(); }
683 MethodItemVector* DirectMethods() { return direct_methods_.get(); }
684 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700685
686 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
687
688 private:
David Sehr853a8e12016-09-01 13:03:50 -0700689 std::unique_ptr<FieldItemVector> static_fields_;
690 std::unique_ptr<FieldItemVector> instance_fields_;
691 std::unique_ptr<MethodItemVector> direct_methods_;
692 std::unique_ptr<MethodItemVector> virtual_methods_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700693
David Sehr7629f602016-08-07 16:01:51 -0700694 DISALLOW_COPY_AND_ASSIGN(ClassData);
695};
696
Jeff Hao3ab96b42016-09-09 18:35:01 -0700697class ClassDef : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700698 public:
David Sehr853a8e12016-09-01 13:03:50 -0700699 ClassDef(const TypeId* class_type,
700 uint32_t access_flags,
701 const TypeId* superclass,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700702 TypeList* interfaces,
David Sehr853a8e12016-09-01 13:03:50 -0700703 const StringId* source_file,
704 AnnotationsDirectoryItem* annotations,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700705 EncodedArrayItem* static_values,
David Sehr853a8e12016-09-01 13:03:50 -0700706 ClassData* class_data)
707 : class_type_(class_type),
708 access_flags_(access_flags),
709 superclass_(superclass),
710 interfaces_(interfaces),
David Sehr853a8e12016-09-01 13:03:50 -0700711 source_file_(source_file),
712 annotations_(annotations),
Jeff Haoa8621002016-10-04 18:13:44 +0000713 class_data_(class_data),
714 static_values_(static_values) { size_ = kClassDefItemSize; }
David Sehr853a8e12016-09-01 13:03:50 -0700715
David Sehr7629f602016-08-07 16:01:51 -0700716 ~ClassDef() OVERRIDE { }
717
Jeff Hao3ab96b42016-09-09 18:35:01 -0700718 static size_t ItemSize() { return kClassDefItemSize; }
719
David Sehr7629f602016-08-07 16:01:51 -0700720 const TypeId* ClassType() const { return class_type_; }
721 uint32_t GetAccessFlags() const { return access_flags_; }
722 const TypeId* Superclass() const { return superclass_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700723 const TypeIdVector* Interfaces()
724 { return interfaces_ == nullptr ? nullptr: interfaces_->GetTypeList(); }
725 uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
David Sehr7629f602016-08-07 16:01:51 -0700726 const StringId* SourceFile() const { return source_file_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700727 AnnotationsDirectoryItem* Annotations() const { return annotations_; }
Nicolas Geoffrayfd1a6c22016-10-04 11:01:17 +0000728 ClassData* GetClassData() { return class_data_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000729 EncodedArrayItem* StaticValues() { return static_values_; }
David Sehr7629f602016-08-07 16:01:51 -0700730
Jeff Haoc3acfc52016-08-29 14:18:26 -0700731 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
732
David Sehr7629f602016-08-07 16:01:51 -0700733 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
734
735 private:
736 const TypeId* class_type_;
737 uint32_t access_flags_;
Jeff Haoa8621002016-10-04 18:13:44 +0000738 const TypeId* superclass_; // This can be nullptr.
739 TypeList* interfaces_; // This can be nullptr.
740 const StringId* source_file_; // This can be nullptr.
741 AnnotationsDirectoryItem* annotations_; // This can be nullptr.
742 ClassData* class_data_; // This can be nullptr.
743 EncodedArrayItem* static_values_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700744
David Sehr7629f602016-08-07 16:01:51 -0700745 DISALLOW_COPY_AND_ASSIGN(ClassDef);
746};
747
Jeff Haoa8621002016-10-04 18:13:44 +0000748class TypeAddrPair {
David Sehr853a8e12016-09-01 13:03:50 -0700749 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000750 TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
David Sehr853a8e12016-09-01 13:03:50 -0700751
752 const TypeId* GetTypeId() const { return type_id_; }
753 uint32_t GetAddress() const { return address_; }
754
755 private:
756 const TypeId* type_id_;
757 uint32_t address_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700758
Jeff Haoa8621002016-10-04 18:13:44 +0000759 DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
760};
761
762using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
763
764class CatchHandler {
765 public:
766 explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
767 : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
768
769 bool HasCatchAll() const { return catch_all_; }
770 uint16_t GetListOffset() const { return list_offset_; }
771 TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
772
773 private:
774 bool catch_all_;
775 uint16_t list_offset_;
776 std::unique_ptr<TypeAddrPairVector> handlers_;
777
David Sehr853a8e12016-09-01 13:03:50 -0700778 DISALLOW_COPY_AND_ASSIGN(CatchHandler);
779};
780
781using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
782
783class TryItem : public Item {
784 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000785 TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700786 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
787 ~TryItem() OVERRIDE { }
788
789 uint32_t StartAddr() const { return start_addr_; }
790 uint16_t InsnCount() const { return insn_count_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000791 const CatchHandler* GetHandlers() const { return handlers_; }
David Sehr853a8e12016-09-01 13:03:50 -0700792
793 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
794
795 private:
796 uint32_t start_addr_;
797 uint16_t insn_count_;
Jeff Haoa8621002016-10-04 18:13:44 +0000798 const CatchHandler* handlers_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700799
David Sehr853a8e12016-09-01 13:03:50 -0700800 DISALLOW_COPY_AND_ASSIGN(TryItem);
801};
802
803using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
804
David Sehrd1e44e22016-10-06 17:09:32 -0700805class CodeFixups {
806 public:
807 CodeFixups(std::vector<TypeId*>* type_ids,
808 std::vector<StringId*>* string_ids,
809 std::vector<MethodId*>* method_ids,
810 std::vector<FieldId*>* field_ids)
811 : type_ids_(type_ids),
812 string_ids_(string_ids),
813 method_ids_(method_ids),
814 field_ids_(field_ids) { }
815
816 std::vector<TypeId*>* TypeIds() const { return type_ids_.get(); }
817 std::vector<StringId*>* StringIds() const { return string_ids_.get(); }
818 std::vector<MethodId*>* MethodIds() const { return method_ids_.get(); }
819 std::vector<FieldId*>* FieldIds() const { return field_ids_.get(); }
820
821 private:
822 std::unique_ptr<std::vector<TypeId*>> type_ids_;
823 std::unique_ptr<std::vector<StringId*>> string_ids_;
824 std::unique_ptr<std::vector<MethodId*>> method_ids_;
825 std::unique_ptr<std::vector<FieldId*>> field_ids_;
826
827 DISALLOW_COPY_AND_ASSIGN(CodeFixups);
828};
829
David Sehr7629f602016-08-07 16:01:51 -0700830class CodeItem : public Item {
831 public:
David Sehr853a8e12016-09-01 13:03:50 -0700832 CodeItem(uint16_t registers_size,
833 uint16_t ins_size,
834 uint16_t outs_size,
835 DebugInfoItem* debug_info,
836 uint32_t insns_size,
837 uint16_t* insns,
Jeff Haoa8621002016-10-04 18:13:44 +0000838 TryItemVector* tries,
839 CatchHandlerVector* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700840 : registers_size_(registers_size),
841 ins_size_(ins_size),
842 outs_size_(outs_size),
843 debug_info_(debug_info),
844 insns_size_(insns_size),
845 insns_(insns),
Jeff Haoa8621002016-10-04 18:13:44 +0000846 tries_(tries),
847 handlers_(handlers) { }
David Sehr853a8e12016-09-01 13:03:50 -0700848
David Sehr7629f602016-08-07 16:01:51 -0700849 ~CodeItem() OVERRIDE { }
850
851 uint16_t RegistersSize() const { return registers_size_; }
852 uint16_t InsSize() const { return ins_size_; }
853 uint16_t OutsSize() const { return outs_size_; }
David Sehr853a8e12016-09-01 13:03:50 -0700854 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700855 DebugInfoItem* DebugInfo() const { return debug_info_; }
David Sehr7629f602016-08-07 16:01:51 -0700856 uint32_t InsnsSize() const { return insns_size_; }
857 uint16_t* Insns() const { return insns_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -0700858 TryItemVector* Tries() const { return tries_.get(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000859 CatchHandlerVector* Handlers() const { return handlers_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700860
David Sehrd1e44e22016-10-06 17:09:32 -0700861 void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); }
862 CodeFixups* GetCodeFixups() const { return fixups_.get(); }
863
David Sehr7629f602016-08-07 16:01:51 -0700864 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
865
866 private:
867 uint16_t registers_size_;
868 uint16_t ins_size_;
869 uint16_t outs_size_;
Jeff Haoa8621002016-10-04 18:13:44 +0000870 DebugInfoItem* debug_info_; // This can be nullptr.
David Sehr7629f602016-08-07 16:01:51 -0700871 uint32_t insns_size_;
872 std::unique_ptr<uint16_t[]> insns_;
Jeff Haoa8621002016-10-04 18:13:44 +0000873 std::unique_ptr<TryItemVector> tries_; // This can be nullptr.
874 std::unique_ptr<CatchHandlerVector> handlers_; // This can be nullptr.
David Sehrd1e44e22016-10-06 17:09:32 -0700875 std::unique_ptr<CodeFixups> fixups_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700876
David Sehr7629f602016-08-07 16:01:51 -0700877 DISALLOW_COPY_AND_ASSIGN(CodeItem);
878};
879
David Sehr7629f602016-08-07 16:01:51 -0700880struct PositionInfo {
881 PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { }
882
883 uint32_t address_;
884 uint32_t line_;
885};
886
David Sehr853a8e12016-09-01 13:03:50 -0700887using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>;
888
David Sehr7629f602016-08-07 16:01:51 -0700889struct LocalInfo {
David Sehr853a8e12016-09-01 13:03:50 -0700890 LocalInfo(const char* name,
891 const char* descriptor,
892 const char* signature,
893 uint32_t start_address,
894 uint32_t end_address,
895 uint16_t reg)
896 : name_(name),
897 descriptor_(descriptor),
898 signature_(signature),
899 start_address_(start_address),
900 end_address_(end_address),
901 reg_(reg) { }
David Sehr7629f602016-08-07 16:01:51 -0700902
903 std::string name_;
904 std::string descriptor_;
905 std::string signature_;
906 uint32_t start_address_;
907 uint32_t end_address_;
908 uint16_t reg_;
909};
910
David Sehr853a8e12016-09-01 13:03:50 -0700911using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>;
912
David Sehr7629f602016-08-07 16:01:51 -0700913class DebugInfoItem : public Item {
914 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000915 DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
916 : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
917
918 uint32_t GetDebugInfoSize() const { return debug_info_size_; }
919 uint8_t* GetDebugInfo() const { return debug_info_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700920
David Sehr853a8e12016-09-01 13:03:50 -0700921 PositionInfoVector& GetPositionInfo() { return positions_; }
922 LocalInfoVector& GetLocalInfo() { return locals_; }
David Sehr7629f602016-08-07 16:01:51 -0700923
924 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000925 uint32_t debug_info_size_;
926 std::unique_ptr<uint8_t[]> debug_info_;
927
David Sehr853a8e12016-09-01 13:03:50 -0700928 PositionInfoVector positions_;
929 LocalInfoVector locals_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700930
David Sehr7629f602016-08-07 16:01:51 -0700931 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
932};
933
Jeff Hao3ab96b42016-09-09 18:35:01 -0700934class AnnotationItem : public Item {
David Sehr853a8e12016-09-01 13:03:50 -0700935 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700936 AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation)
937 : visibility_(visibility), annotation_(annotation) { }
David Sehr853a8e12016-09-01 13:03:50 -0700938
939 uint8_t GetVisibility() const { return visibility_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700940 EncodedAnnotation* GetAnnotation() const { return annotation_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700941
942 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
943
944 private:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700945 uint8_t visibility_;
946 std::unique_ptr<EncodedAnnotation> annotation_;
947
948 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
949};
950
951class AnnotationSetItem : public Item {
952 public:
953 explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) {
954 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
955 }
956 ~AnnotationSetItem() OVERRIDE { }
957
958 std::vector<AnnotationItem*>* GetItems() { return items_.get(); }
959
960 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
961
962 private:
963 std::unique_ptr<std::vector<AnnotationItem*>> items_;
964
David Sehr7629f602016-08-07 16:01:51 -0700965 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
966};
967
Jeff Hao3ab96b42016-09-09 18:35:01 -0700968class AnnotationSetRefList : public Item {
969 public:
970 explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) {
971 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
972 }
973 ~AnnotationSetRefList() OVERRIDE { }
974
975 std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); }
976
977 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
978
979 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000980 std::unique_ptr<std::vector<AnnotationSetItem*>> items_; // Elements of vector can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700981
982 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
983};
David Sehr853a8e12016-09-01 13:03:50 -0700984
985class FieldAnnotation {
986 public:
987 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
988 : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
989
990 FieldId* GetFieldId() const { return field_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700991 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -0700992
993 private:
994 FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700995 AnnotationSetItem* annotation_set_item_;
996
David Sehr853a8e12016-09-01 13:03:50 -0700997 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
998};
999
1000using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
1001
1002class MethodAnnotation {
1003 public:
1004 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
1005 : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
1006
1007 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001008 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001009
1010 private:
1011 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001012 AnnotationSetItem* annotation_set_item_;
1013
David Sehr853a8e12016-09-01 13:03:50 -07001014 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
1015};
1016
1017using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
1018
1019class ParameterAnnotation {
1020 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001021 ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations)
David Sehr853a8e12016-09-01 13:03:50 -07001022 : method_id_(method_id), annotations_(annotations) { }
1023
1024 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001025 AnnotationSetRefList* GetAnnotations() { return annotations_; }
David Sehr853a8e12016-09-01 13:03:50 -07001026
1027 private:
1028 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001029 AnnotationSetRefList* annotations_;
1030
David Sehr853a8e12016-09-01 13:03:50 -07001031 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
1032};
1033
1034using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
1035
David Sehr7629f602016-08-07 16:01:51 -07001036class AnnotationsDirectoryItem : public Item {
1037 public:
David Sehr853a8e12016-09-01 13:03:50 -07001038 AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
1039 FieldAnnotationVector* field_annotations,
1040 MethodAnnotationVector* method_annotations,
1041 ParameterAnnotationVector* parameter_annotations)
1042 : class_annotation_(class_annotation),
1043 field_annotations_(field_annotations),
1044 method_annotations_(method_annotations),
1045 parameter_annotations_(parameter_annotations) { }
David Sehr7629f602016-08-07 16:01:51 -07001046
Jeff Hao3ab96b42016-09-09 18:35:01 -07001047 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; }
David Sehr853a8e12016-09-01 13:03:50 -07001048 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
1049 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
1050 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001051
1052 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1053
1054 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001055 AnnotationSetItem* class_annotation_; // This can be nullptr.
1056 std::unique_ptr<FieldAnnotationVector> field_annotations_; // This can be nullptr.
1057 std::unique_ptr<MethodAnnotationVector> method_annotations_; // This can be nullptr.
1058 std::unique_ptr<ParameterAnnotationVector> parameter_annotations_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001059
David Sehr7629f602016-08-07 16:01:51 -07001060 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
1061};
1062
1063// TODO(sehr): implement MapList.
1064class MapList : public Item {
1065 public:
1066 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1067
1068 private:
1069 DISALLOW_COPY_AND_ASSIGN(MapList);
1070};
1071
1072class MapItem : public Item {
1073 public:
1074 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1075
1076 private:
1077 DISALLOW_COPY_AND_ASSIGN(MapItem);
1078};
1079
1080} // namespace dex_ir
1081} // namespace art
1082
1083#endif // ART_DEXLAYOUT_DEX_IR_H_