blob: a2d1190d035ffc8214756bee31e1bf675f8aa043 [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
137 void AddItem(T* object, uint32_t offset) {
138 object->SetOffset(offset);
139 collection_.emplace(offset, std::unique_ptr<T>(object));
140 }
141 uint32_t Size() const { return collection_.size(); }
142 std::map<uint32_t, std::unique_ptr<T>>& Collection() { return collection_; }
143
144 private:
145 std::map<uint32_t, std::unique_ptr<T>> collection_;
146
147 DISALLOW_COPY_AND_ASSIGN(CollectionMap);
David Sehr7629f602016-08-07 16:01:51 -0700148};
149
Jeff Hao3ab96b42016-09-09 18:35:01 -0700150class Collections {
151 public:
152 Collections() = default;
153
154 std::vector<std::unique_ptr<StringId>>& StringIds() { return string_ids_.Collection(); }
155 std::vector<std::unique_ptr<TypeId>>& TypeIds() { return type_ids_.Collection(); }
156 std::vector<std::unique_ptr<ProtoId>>& ProtoIds() { return proto_ids_.Collection(); }
157 std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); }
158 std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); }
159 std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800160 std::map<uint32_t, std::unique_ptr<StringData>>& StringDatas()
161 { return string_datas_.Collection(); }
162 std::map<uint32_t, std::unique_ptr<TypeList>>& TypeLists() { return type_lists_.Collection(); }
163 std::map<uint32_t, std::unique_ptr<EncodedArrayItem>>& EncodedArrayItems()
Jeff Hao3ab96b42016-09-09 18:35:01 -0700164 { return encoded_array_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800165 std::map<uint32_t, std::unique_ptr<AnnotationItem>>& AnnotationItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000166 { return annotation_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800167 std::map<uint32_t, std::unique_ptr<AnnotationSetItem>>& AnnotationSetItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000168 { return annotation_set_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800169 std::map<uint32_t, std::unique_ptr<AnnotationSetRefList>>& AnnotationSetRefLists()
Jeff Haoa8621002016-10-04 18:13:44 +0000170 { return annotation_set_ref_lists_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800171 std::map<uint32_t, std::unique_ptr<AnnotationsDirectoryItem>>& AnnotationsDirectoryItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000172 { return annotations_directory_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800173 std::map<uint32_t, std::unique_ptr<DebugInfoItem>>& DebugInfoItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000174 { return debug_info_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800175 std::map<uint32_t, std::unique_ptr<CodeItem>>& CodeItems() { return code_items_.Collection(); }
176 std::map<uint32_t, std::unique_ptr<ClassData>>& ClassDatas() { return class_datas_.Collection(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700177
178 void CreateStringId(const DexFile& dex_file, uint32_t i);
179 void CreateTypeId(const DexFile& dex_file, uint32_t i);
180 void CreateProtoId(const DexFile& dex_file, uint32_t i);
181 void CreateFieldId(const DexFile& dex_file, uint32_t i);
182 void CreateMethodId(const DexFile& dex_file, uint32_t i);
183 void CreateClassDef(const DexFile& dex_file, uint32_t i);
184
Jeff Haoa8621002016-10-04 18:13:44 +0000185 TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700186 EncodedArrayItem* CreateEncodedArrayItem(const uint8_t* static_data, uint32_t offset);
187 AnnotationItem* CreateAnnotationItem(const DexFile::AnnotationItem* annotation, uint32_t offset);
188 AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
189 const DexFile::AnnotationSetItem& disk_annotations_item, uint32_t offset);
190 AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file,
191 const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset);
192 CodeItem* CreateCodeItem(
193 const DexFile& dex_file, const DexFile::CodeItem& disk_code_item, uint32_t offset);
194 ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
195
196 StringId* GetStringId(uint32_t index) { return StringIds()[index].get(); }
197 TypeId* GetTypeId(uint32_t index) { return TypeIds()[index].get(); }
198 ProtoId* GetProtoId(uint32_t index) { return ProtoIds()[index].get(); }
199 FieldId* GetFieldId(uint32_t index) { return FieldIds()[index].get(); }
200 MethodId* GetMethodId(uint32_t index) { return MethodIds()[index].get(); }
201 ClassDef* GetClassDef(uint32_t index) { return ClassDefs()[index].get(); }
202
203 StringId* GetStringIdOrNullPtr(uint32_t index) {
204 return index == DexFile::kDexNoIndex ? nullptr : GetStringId(index);
205 }
206 TypeId* GetTypeIdOrNullPtr(uint16_t index) {
207 return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index);
208 }
209
210 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
211 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
212 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
213 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
214 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
215 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
216 uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
217 uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000218 uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
219 uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
220 uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700221 uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000222 uint32_t AnnotationsDirectoryItemsOffset() const
223 { return annotations_directory_items_.GetOffset(); }
224 uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700225 uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
226 uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800227 uint32_t MapListOffset() const { return map_list_offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700228
229 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
230 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
231 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
232 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
233 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
234 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
235 void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
236 void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000237 void SetEncodedArrayItemsOffset(uint32_t new_offset)
238 { encoded_array_items_.SetOffset(new_offset); }
239 void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
240 void SetAnnotationSetItemsOffset(uint32_t new_offset)
241 { annotation_set_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700242 void SetAnnotationSetRefListsOffset(uint32_t new_offset)
243 { annotation_set_ref_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000244 void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700245 { annotations_directory_items_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000246 void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700247 void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
248 void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800249 void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700250
251 uint32_t StringIdsSize() const { return string_ids_.Size(); }
252 uint32_t TypeIdsSize() const { return type_ids_.Size(); }
253 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
254 uint32_t FieldIdsSize() const { return field_ids_.Size(); }
255 uint32_t MethodIdsSize() const { return method_ids_.Size(); }
256 uint32_t ClassDefsSize() const { return class_defs_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700257 uint32_t StringDatasSize() const { return string_datas_.Size(); }
258 uint32_t TypeListsSize() const { return type_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000259 uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
260 uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
261 uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700262 uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000263 uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
264 uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700265 uint32_t CodeItemsSize() const { return code_items_.Size(); }
266 uint32_t ClassDatasSize() const { return class_datas_.Size(); }
267
Jeff Hao3ab96b42016-09-09 18:35:01 -0700268 private:
269 EncodedValue* ReadEncodedValue(const uint8_t** data);
270 EncodedValue* ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length);
271 void ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length, EncodedValue* item);
272
273 ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
274 const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
275 MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
276
Jeff Haoea7c6292016-11-14 18:10:16 -0800277 CollectionVector<StringId> string_ids_;
278 CollectionVector<TypeId> type_ids_;
279 CollectionVector<ProtoId> proto_ids_;
280 CollectionVector<FieldId> field_ids_;
281 CollectionVector<MethodId> method_ids_;
282 CollectionVector<ClassDef> class_defs_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700283
Jeff Haoea7c6292016-11-14 18:10:16 -0800284 CollectionMap<StringData> string_datas_;
285 CollectionMap<TypeList> type_lists_;
286 CollectionMap<EncodedArrayItem> encoded_array_items_;
287 CollectionMap<AnnotationItem> annotation_items_;
288 CollectionMap<AnnotationSetItem> annotation_set_items_;
289 CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_;
290 CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_;
291 CollectionMap<DebugInfoItem> debug_info_items_;
292 CollectionMap<CodeItem> code_items_;
293 CollectionMap<ClassData> class_datas_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700294
Jeff Haoea7c6292016-11-14 18:10:16 -0800295 uint32_t map_list_offset_ = 0;
Jeff Haoa8621002016-10-04 18:13:44 +0000296
Jeff Hao3ab96b42016-09-09 18:35:01 -0700297 DISALLOW_COPY_AND_ASSIGN(Collections);
298};
299
David Sehr7629f602016-08-07 16:01:51 -0700300class Item {
301 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700302 Item() { }
David Sehr7629f602016-08-07 16:01:51 -0700303 virtual ~Item() { }
David Sehr853a8e12016-09-01 13:03:50 -0700304
David Sehr7629f602016-08-07 16:01:51 -0700305 uint32_t GetOffset() const { return offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700306 uint32_t GetSize() const { return size_; }
David Sehr7629f602016-08-07 16:01:51 -0700307 void SetOffset(uint32_t offset) { offset_ = offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700308 void SetSize(uint32_t size) { size_ = size; }
David Sehr853a8e12016-09-01 13:03:50 -0700309
David Sehr7629f602016-08-07 16:01:51 -0700310 protected:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700311 Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
312
David Sehr7629f602016-08-07 16:01:51 -0700313 uint32_t offset_ = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700314 uint32_t size_ = 0;
315};
316
317class IndexedItem : public Item {
318 public:
319 IndexedItem() { }
320 virtual ~IndexedItem() { }
321
322 uint32_t GetIndex() const { return index_; }
323 void SetIndex(uint32_t index) { index_ = index; }
324
325 protected:
326 IndexedItem(uint32_t offset, uint32_t size, uint32_t index)
327 : Item(offset, size), index_(index) { }
328
329 uint32_t index_ = 0;
David Sehr7629f602016-08-07 16:01:51 -0700330};
331
332class Header : public Item {
333 public:
David Sehr853a8e12016-09-01 13:03:50 -0700334 Header(const uint8_t* magic,
335 uint32_t checksum,
336 const uint8_t* signature,
337 uint32_t endian_tag,
338 uint32_t file_size,
339 uint32_t header_size,
340 uint32_t link_size,
341 uint32_t link_offset,
342 uint32_t data_size,
343 uint32_t data_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700344 : Item(0, kHeaderItemSize),
345 checksum_(checksum),
David Sehr853a8e12016-09-01 13:03:50 -0700346 endian_tag_(endian_tag),
347 file_size_(file_size),
348 header_size_(header_size),
349 link_size_(link_size),
350 link_offset_(link_offset),
351 data_size_(data_size),
352 data_offset_(data_offset) {
353 memcpy(magic_, magic, sizeof(magic_));
354 memcpy(signature_, signature, sizeof(signature_));
355 }
David Sehr7629f602016-08-07 16:01:51 -0700356 ~Header() OVERRIDE { }
357
Jeff Hao3ab96b42016-09-09 18:35:01 -0700358 static size_t ItemSize() { return kHeaderItemSize; }
359
David Sehr7629f602016-08-07 16:01:51 -0700360 const uint8_t* Magic() const { return magic_; }
361 uint32_t Checksum() const { return checksum_; }
362 const uint8_t* Signature() const { return signature_; }
363 uint32_t EndianTag() const { return endian_tag_; }
364 uint32_t FileSize() const { return file_size_; }
365 uint32_t HeaderSize() const { return header_size_; }
366 uint32_t LinkSize() const { return link_size_; }
367 uint32_t LinkOffset() const { return link_offset_; }
368 uint32_t DataSize() const { return data_size_; }
369 uint32_t DataOffset() const { return data_offset_; }
370
371 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
372 void SetSignature(const uint8_t* new_signature) {
373 memcpy(signature_, new_signature, sizeof(signature_));
374 }
375 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
376 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
377 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
378 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
379 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
380 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
381
Jeff Hao3ab96b42016-09-09 18:35:01 -0700382 Collections& GetCollections() { return collections_; }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700383
David Sehr7629f602016-08-07 16:01:51 -0700384 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
385
386 private:
David Sehr7629f602016-08-07 16:01:51 -0700387 uint8_t magic_[8];
388 uint32_t checksum_;
389 uint8_t signature_[DexFile::kSha1DigestSize];
390 uint32_t endian_tag_;
391 uint32_t file_size_;
392 uint32_t header_size_;
393 uint32_t link_size_;
394 uint32_t link_offset_;
395 uint32_t data_size_;
396 uint32_t data_offset_;
397
Jeff Hao3ab96b42016-09-09 18:35:01 -0700398 Collections collections_;
399
David Sehr7629f602016-08-07 16:01:51 -0700400 DISALLOW_COPY_AND_ASSIGN(Header);
401};
402
Jeff Hao3ab96b42016-09-09 18:35:01 -0700403class StringData : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700404 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700405 explicit StringData(const char* data) : data_(strdup(data)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000406 size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700407 }
David Sehr7629f602016-08-07 16:01:51 -0700408
409 const char* Data() const { return data_.get(); }
410
411 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
412
413 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000414 UniqueCPtr<const char> data_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700415
416 DISALLOW_COPY_AND_ASSIGN(StringData);
417};
418
419class StringId : public IndexedItem {
420 public:
421 explicit StringId(StringData* string_data) : string_data_(string_data) {
422 size_ = kStringIdItemSize;
423 }
424 ~StringId() OVERRIDE { }
425
426 static size_t ItemSize() { return kStringIdItemSize; }
427
428 const char* Data() const { return string_data_->Data(); }
429 StringData* DataItem() const { return string_data_; }
430
431 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
432
433 private:
434 StringData* string_data_;
435
David Sehr7629f602016-08-07 16:01:51 -0700436 DISALLOW_COPY_AND_ASSIGN(StringId);
437};
438
Jeff Hao3ab96b42016-09-09 18:35:01 -0700439class TypeId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700440 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700441 explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700442 ~TypeId() OVERRIDE { }
443
Jeff Hao3ab96b42016-09-09 18:35:01 -0700444 static size_t ItemSize() { return kTypeIdItemSize; }
445
David Sehr7629f602016-08-07 16:01:51 -0700446 StringId* GetStringId() const { return string_id_; }
447
448 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
449
450 private:
451 StringId* string_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700452
David Sehr7629f602016-08-07 16:01:51 -0700453 DISALLOW_COPY_AND_ASSIGN(TypeId);
454};
455
David Sehr853a8e12016-09-01 13:03:50 -0700456using TypeIdVector = std::vector<const TypeId*>;
457
Jeff Hao3ab96b42016-09-09 18:35:01 -0700458class TypeList : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700459 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700460 explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) {
461 size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t));
462 }
463 ~TypeList() OVERRIDE { }
464
465 const TypeIdVector* GetTypeList() const { return type_list_.get(); }
466
467 private:
468 std::unique_ptr<TypeIdVector> type_list_;
469
470 DISALLOW_COPY_AND_ASSIGN(TypeList);
471};
472
473class ProtoId : public IndexedItem {
474 public:
475 ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters)
476 : shorty_(shorty), return_type_(return_type), parameters_(parameters)
477 { size_ = kProtoIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700478 ~ProtoId() OVERRIDE { }
479
Jeff Hao3ab96b42016-09-09 18:35:01 -0700480 static size_t ItemSize() { return kProtoIdItemSize; }
481
David Sehr7629f602016-08-07 16:01:51 -0700482 const StringId* Shorty() const { return shorty_; }
483 const TypeId* ReturnType() const { return return_type_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000484 const TypeList* Parameters() const { return parameters_; }
David Sehr7629f602016-08-07 16:01:51 -0700485
486 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
487
488 private:
489 const StringId* shorty_;
490 const TypeId* return_type_;
Jeff Haoa8621002016-10-04 18:13:44 +0000491 TypeList* parameters_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700492
David Sehr7629f602016-08-07 16:01:51 -0700493 DISALLOW_COPY_AND_ASSIGN(ProtoId);
494};
495
Jeff Hao3ab96b42016-09-09 18:35:01 -0700496class FieldId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700497 public:
David Sehr853a8e12016-09-01 13:03:50 -0700498 FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700499 : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700500 ~FieldId() OVERRIDE { }
501
Jeff Hao3ab96b42016-09-09 18:35:01 -0700502 static size_t ItemSize() { return kFieldIdItemSize; }
503
David Sehr7629f602016-08-07 16:01:51 -0700504 const TypeId* Class() const { return class_; }
505 const TypeId* Type() const { return type_; }
506 const StringId* Name() const { return name_; }
507
508 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
509
510 private:
511 const TypeId* class_;
512 const TypeId* type_;
513 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700514
David Sehr7629f602016-08-07 16:01:51 -0700515 DISALLOW_COPY_AND_ASSIGN(FieldId);
516};
517
Jeff Hao3ab96b42016-09-09 18:35:01 -0700518class MethodId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700519 public:
David Sehr853a8e12016-09-01 13:03:50 -0700520 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700521 : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700522 ~MethodId() OVERRIDE { }
523
Jeff Hao3ab96b42016-09-09 18:35:01 -0700524 static size_t ItemSize() { return kMethodIdItemSize; }
525
David Sehr7629f602016-08-07 16:01:51 -0700526 const TypeId* Class() const { return class_; }
527 const ProtoId* Proto() const { return proto_; }
528 const StringId* Name() const { return name_; }
529
530 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
531
532 private:
533 const TypeId* class_;
534 const ProtoId* proto_;
535 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700536
David Sehr7629f602016-08-07 16:01:51 -0700537 DISALLOW_COPY_AND_ASSIGN(MethodId);
538};
539
540class FieldItem : public Item {
541 public:
David Sehr853a8e12016-09-01 13:03:50 -0700542 FieldItem(uint32_t access_flags, const FieldId* field_id)
543 : access_flags_(access_flags), field_id_(field_id) { }
David Sehr7629f602016-08-07 16:01:51 -0700544 ~FieldItem() OVERRIDE { }
545
546 uint32_t GetAccessFlags() const { return access_flags_; }
547 const FieldId* GetFieldId() const { return field_id_; }
548
549 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
550
551 private:
552 uint32_t access_flags_;
553 const FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700554
David Sehr7629f602016-08-07 16:01:51 -0700555 DISALLOW_COPY_AND_ASSIGN(FieldItem);
556};
557
David Sehr853a8e12016-09-01 13:03:50 -0700558using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
559
David Sehr7629f602016-08-07 16:01:51 -0700560class MethodItem : public Item {
561 public:
Jeff Haoea7c6292016-11-14 18:10:16 -0800562 MethodItem(uint32_t access_flags, const MethodId* method_id, CodeItem* code)
David Sehr853a8e12016-09-01 13:03:50 -0700563 : access_flags_(access_flags), method_id_(method_id), code_(code) { }
David Sehr7629f602016-08-07 16:01:51 -0700564 ~MethodItem() OVERRIDE { }
565
566 uint32_t GetAccessFlags() const { return access_flags_; }
567 const MethodId* GetMethodId() const { return method_id_; }
Jeff Haoea7c6292016-11-14 18:10:16 -0800568 CodeItem* GetCodeItem() { return code_; }
David Sehr7629f602016-08-07 16:01:51 -0700569
570 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
571
572 private:
573 uint32_t access_flags_;
574 const MethodId* method_id_;
Jeff Haoea7c6292016-11-14 18:10:16 -0800575 CodeItem* code_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700576
David Sehr7629f602016-08-07 16:01:51 -0700577 DISALLOW_COPY_AND_ASSIGN(MethodItem);
578};
579
David Sehr853a8e12016-09-01 13:03:50 -0700580using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
581
Jeff Hao3ab96b42016-09-09 18:35:01 -0700582class EncodedValue {
David Sehr7629f602016-08-07 16:01:51 -0700583 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700584 explicit EncodedValue(uint8_t type) : type_(type) { }
David Sehr7629f602016-08-07 16:01:51 -0700585
586 int8_t Type() const { return type_; }
David Sehr7629f602016-08-07 16:01:51 -0700587
Jeff Hao3ab96b42016-09-09 18:35:01 -0700588 void SetBoolean(bool z) { u_.bool_val_ = z; }
589 void SetByte(int8_t b) { u_.byte_val_ = b; }
590 void SetShort(int16_t s) { u_.short_val_ = s; }
591 void SetChar(uint16_t c) { u_.char_val_ = c; }
592 void SetInt(int32_t i) { u_.int_val_ = i; }
593 void SetLong(int64_t l) { u_.long_val_ = l; }
594 void SetFloat(float f) { u_.float_val_ = f; }
595 void SetDouble(double d) { u_.double_val_ = d; }
596 void SetStringId(StringId* string_id) { u_.string_val_ = string_id; }
597 void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; }
598 void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; }
599 void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; }
600 void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); }
601 void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation)
602 { encoded_annotation_.reset(encoded_annotation); }
603
604 bool GetBoolean() const { return u_.bool_val_; }
605 int8_t GetByte() const { return u_.byte_val_; }
606 int16_t GetShort() const { return u_.short_val_; }
607 uint16_t GetChar() const { return u_.char_val_; }
608 int32_t GetInt() const { return u_.int_val_; }
609 int64_t GetLong() const { return u_.long_val_; }
610 float GetFloat() const { return u_.float_val_; }
611 double GetDouble() const { return u_.double_val_; }
612 StringId* GetStringId() const { return u_.string_val_; }
613 TypeId* GetTypeId() const { return u_.type_val_; }
614 FieldId* GetFieldId() const { return u_.field_val_; }
615 MethodId* GetMethodId() const { return u_.method_val_; }
616 EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); }
617 EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); }
618
619 EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); }
David Sehr7629f602016-08-07 16:01:51 -0700620
621 private:
David Sehr7629f602016-08-07 16:01:51 -0700622 uint8_t type_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700623 union {
624 bool bool_val_;
625 int8_t byte_val_;
626 int16_t short_val_;
627 uint16_t char_val_;
628 int32_t int_val_;
629 int64_t long_val_;
630 float float_val_;
631 double double_val_;
632 StringId* string_val_;
633 TypeId* type_val_;
634 FieldId* field_val_;
635 MethodId* method_val_;
636 } u_;
637 std::unique_ptr<EncodedArrayItem> encoded_array_;
638 std::unique_ptr<EncodedAnnotation> encoded_annotation_;
639
640 DISALLOW_COPY_AND_ASSIGN(EncodedValue);
David Sehr7629f602016-08-07 16:01:51 -0700641};
642
Jeff Hao3ab96b42016-09-09 18:35:01 -0700643using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>;
644
645class AnnotationElement {
646 public:
647 AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { }
648
649 StringId* GetName() const { return name_; }
650 EncodedValue* GetValue() const { return value_.get(); }
651
652 private:
653 StringId* name_;
654 std::unique_ptr<EncodedValue> value_;
655
656 DISALLOW_COPY_AND_ASSIGN(AnnotationElement);
657};
658
659using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>;
660
661class EncodedAnnotation {
662 public:
663 EncodedAnnotation(TypeId* type, AnnotationElementVector* elements)
664 : type_(type), elements_(elements) { }
665
666 TypeId* GetType() const { return type_; }
667 AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); }
668
669 private:
670 TypeId* type_;
671 std::unique_ptr<AnnotationElementVector> elements_;
672
673 DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation);
674};
675
676class EncodedArrayItem : public Item {
677 public:
678 explicit EncodedArrayItem(EncodedValueVector* encoded_values)
679 : encoded_values_(encoded_values) { }
680
681 EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); }
682
683 private:
684 std::unique_ptr<EncodedValueVector> encoded_values_;
685
686 DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem);
687};
David Sehr853a8e12016-09-01 13:03:50 -0700688
David Sehr7629f602016-08-07 16:01:51 -0700689class ClassData : public Item {
690 public:
David Sehr853a8e12016-09-01 13:03:50 -0700691 ClassData(FieldItemVector* static_fields,
692 FieldItemVector* instance_fields,
693 MethodItemVector* direct_methods,
694 MethodItemVector* virtual_methods)
695 : static_fields_(static_fields),
696 instance_fields_(instance_fields),
697 direct_methods_(direct_methods),
698 virtual_methods_(virtual_methods) { }
699
David Sehr7629f602016-08-07 16:01:51 -0700700 ~ClassData() OVERRIDE = default;
David Sehr853a8e12016-09-01 13:03:50 -0700701 FieldItemVector* StaticFields() { return static_fields_.get(); }
702 FieldItemVector* InstanceFields() { return instance_fields_.get(); }
703 MethodItemVector* DirectMethods() { return direct_methods_.get(); }
704 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700705
706 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
707
708 private:
David Sehr853a8e12016-09-01 13:03:50 -0700709 std::unique_ptr<FieldItemVector> static_fields_;
710 std::unique_ptr<FieldItemVector> instance_fields_;
711 std::unique_ptr<MethodItemVector> direct_methods_;
712 std::unique_ptr<MethodItemVector> virtual_methods_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700713
David Sehr7629f602016-08-07 16:01:51 -0700714 DISALLOW_COPY_AND_ASSIGN(ClassData);
715};
716
Jeff Hao3ab96b42016-09-09 18:35:01 -0700717class ClassDef : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700718 public:
David Sehr853a8e12016-09-01 13:03:50 -0700719 ClassDef(const TypeId* class_type,
720 uint32_t access_flags,
721 const TypeId* superclass,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700722 TypeList* interfaces,
David Sehr853a8e12016-09-01 13:03:50 -0700723 const StringId* source_file,
724 AnnotationsDirectoryItem* annotations,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700725 EncodedArrayItem* static_values,
David Sehr853a8e12016-09-01 13:03:50 -0700726 ClassData* class_data)
727 : class_type_(class_type),
728 access_flags_(access_flags),
729 superclass_(superclass),
730 interfaces_(interfaces),
David Sehr853a8e12016-09-01 13:03:50 -0700731 source_file_(source_file),
732 annotations_(annotations),
Jeff Haoa8621002016-10-04 18:13:44 +0000733 class_data_(class_data),
734 static_values_(static_values) { size_ = kClassDefItemSize; }
David Sehr853a8e12016-09-01 13:03:50 -0700735
David Sehr7629f602016-08-07 16:01:51 -0700736 ~ClassDef() OVERRIDE { }
737
Jeff Hao3ab96b42016-09-09 18:35:01 -0700738 static size_t ItemSize() { return kClassDefItemSize; }
739
David Sehr7629f602016-08-07 16:01:51 -0700740 const TypeId* ClassType() const { return class_type_; }
741 uint32_t GetAccessFlags() const { return access_flags_; }
742 const TypeId* Superclass() const { return superclass_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700743 const TypeIdVector* Interfaces()
744 { return interfaces_ == nullptr ? nullptr: interfaces_->GetTypeList(); }
745 uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
David Sehr7629f602016-08-07 16:01:51 -0700746 const StringId* SourceFile() const { return source_file_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700747 AnnotationsDirectoryItem* Annotations() const { return annotations_; }
Nicolas Geoffrayfd1a6c22016-10-04 11:01:17 +0000748 ClassData* GetClassData() { return class_data_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000749 EncodedArrayItem* StaticValues() { return static_values_; }
David Sehr7629f602016-08-07 16:01:51 -0700750
Jeff Haoc3acfc52016-08-29 14:18:26 -0700751 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
752
David Sehr7629f602016-08-07 16:01:51 -0700753 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
754
755 private:
756 const TypeId* class_type_;
757 uint32_t access_flags_;
Jeff Haoa8621002016-10-04 18:13:44 +0000758 const TypeId* superclass_; // This can be nullptr.
759 TypeList* interfaces_; // This can be nullptr.
760 const StringId* source_file_; // This can be nullptr.
761 AnnotationsDirectoryItem* annotations_; // This can be nullptr.
762 ClassData* class_data_; // This can be nullptr.
763 EncodedArrayItem* static_values_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700764
David Sehr7629f602016-08-07 16:01:51 -0700765 DISALLOW_COPY_AND_ASSIGN(ClassDef);
766};
767
Jeff Haoa8621002016-10-04 18:13:44 +0000768class TypeAddrPair {
David Sehr853a8e12016-09-01 13:03:50 -0700769 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000770 TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
David Sehr853a8e12016-09-01 13:03:50 -0700771
772 const TypeId* GetTypeId() const { return type_id_; }
773 uint32_t GetAddress() const { return address_; }
774
775 private:
776 const TypeId* type_id_;
777 uint32_t address_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700778
Jeff Haoa8621002016-10-04 18:13:44 +0000779 DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
780};
781
782using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
783
784class CatchHandler {
785 public:
786 explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
787 : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
788
789 bool HasCatchAll() const { return catch_all_; }
790 uint16_t GetListOffset() const { return list_offset_; }
791 TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
792
793 private:
794 bool catch_all_;
795 uint16_t list_offset_;
796 std::unique_ptr<TypeAddrPairVector> handlers_;
797
David Sehr853a8e12016-09-01 13:03:50 -0700798 DISALLOW_COPY_AND_ASSIGN(CatchHandler);
799};
800
801using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
802
803class TryItem : public Item {
804 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000805 TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700806 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
807 ~TryItem() OVERRIDE { }
808
809 uint32_t StartAddr() const { return start_addr_; }
810 uint16_t InsnCount() const { return insn_count_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000811 const CatchHandler* GetHandlers() const { return handlers_; }
David Sehr853a8e12016-09-01 13:03:50 -0700812
813 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
814
815 private:
816 uint32_t start_addr_;
817 uint16_t insn_count_;
Jeff Haoa8621002016-10-04 18:13:44 +0000818 const CatchHandler* handlers_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700819
David Sehr853a8e12016-09-01 13:03:50 -0700820 DISALLOW_COPY_AND_ASSIGN(TryItem);
821};
822
823using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
824
David Sehrd1e44e22016-10-06 17:09:32 -0700825class CodeFixups {
826 public:
827 CodeFixups(std::vector<TypeId*>* type_ids,
828 std::vector<StringId*>* string_ids,
829 std::vector<MethodId*>* method_ids,
830 std::vector<FieldId*>* field_ids)
831 : type_ids_(type_ids),
832 string_ids_(string_ids),
833 method_ids_(method_ids),
834 field_ids_(field_ids) { }
835
836 std::vector<TypeId*>* TypeIds() const { return type_ids_.get(); }
837 std::vector<StringId*>* StringIds() const { return string_ids_.get(); }
838 std::vector<MethodId*>* MethodIds() const { return method_ids_.get(); }
839 std::vector<FieldId*>* FieldIds() const { return field_ids_.get(); }
840
841 private:
842 std::unique_ptr<std::vector<TypeId*>> type_ids_;
843 std::unique_ptr<std::vector<StringId*>> string_ids_;
844 std::unique_ptr<std::vector<MethodId*>> method_ids_;
845 std::unique_ptr<std::vector<FieldId*>> field_ids_;
846
847 DISALLOW_COPY_AND_ASSIGN(CodeFixups);
848};
849
David Sehr7629f602016-08-07 16:01:51 -0700850class CodeItem : public Item {
851 public:
David Sehr853a8e12016-09-01 13:03:50 -0700852 CodeItem(uint16_t registers_size,
853 uint16_t ins_size,
854 uint16_t outs_size,
855 DebugInfoItem* debug_info,
856 uint32_t insns_size,
857 uint16_t* insns,
Jeff Haoa8621002016-10-04 18:13:44 +0000858 TryItemVector* tries,
859 CatchHandlerVector* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700860 : registers_size_(registers_size),
861 ins_size_(ins_size),
862 outs_size_(outs_size),
863 debug_info_(debug_info),
864 insns_size_(insns_size),
865 insns_(insns),
Jeff Haoa8621002016-10-04 18:13:44 +0000866 tries_(tries),
867 handlers_(handlers) { }
David Sehr853a8e12016-09-01 13:03:50 -0700868
David Sehr7629f602016-08-07 16:01:51 -0700869 ~CodeItem() OVERRIDE { }
870
871 uint16_t RegistersSize() const { return registers_size_; }
872 uint16_t InsSize() const { return ins_size_; }
873 uint16_t OutsSize() const { return outs_size_; }
David Sehr853a8e12016-09-01 13:03:50 -0700874 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700875 DebugInfoItem* DebugInfo() const { return debug_info_; }
David Sehr7629f602016-08-07 16:01:51 -0700876 uint32_t InsnsSize() const { return insns_size_; }
877 uint16_t* Insns() const { return insns_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -0700878 TryItemVector* Tries() const { return tries_.get(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000879 CatchHandlerVector* Handlers() const { return handlers_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700880
David Sehrd1e44e22016-10-06 17:09:32 -0700881 void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); }
882 CodeFixups* GetCodeFixups() const { return fixups_.get(); }
883
David Sehr7629f602016-08-07 16:01:51 -0700884 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
885
886 private:
887 uint16_t registers_size_;
888 uint16_t ins_size_;
889 uint16_t outs_size_;
Jeff Haoa8621002016-10-04 18:13:44 +0000890 DebugInfoItem* debug_info_; // This can be nullptr.
David Sehr7629f602016-08-07 16:01:51 -0700891 uint32_t insns_size_;
892 std::unique_ptr<uint16_t[]> insns_;
Jeff Haoa8621002016-10-04 18:13:44 +0000893 std::unique_ptr<TryItemVector> tries_; // This can be nullptr.
894 std::unique_ptr<CatchHandlerVector> handlers_; // This can be nullptr.
David Sehrd1e44e22016-10-06 17:09:32 -0700895 std::unique_ptr<CodeFixups> fixups_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700896
David Sehr7629f602016-08-07 16:01:51 -0700897 DISALLOW_COPY_AND_ASSIGN(CodeItem);
898};
899
David Sehr7629f602016-08-07 16:01:51 -0700900struct PositionInfo {
901 PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { }
902
903 uint32_t address_;
904 uint32_t line_;
905};
906
David Sehr853a8e12016-09-01 13:03:50 -0700907using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>;
908
David Sehr7629f602016-08-07 16:01:51 -0700909struct LocalInfo {
David Sehr853a8e12016-09-01 13:03:50 -0700910 LocalInfo(const char* name,
911 const char* descriptor,
912 const char* signature,
913 uint32_t start_address,
914 uint32_t end_address,
915 uint16_t reg)
916 : name_(name),
917 descriptor_(descriptor),
918 signature_(signature),
919 start_address_(start_address),
920 end_address_(end_address),
921 reg_(reg) { }
David Sehr7629f602016-08-07 16:01:51 -0700922
923 std::string name_;
924 std::string descriptor_;
925 std::string signature_;
926 uint32_t start_address_;
927 uint32_t end_address_;
928 uint16_t reg_;
929};
930
David Sehr853a8e12016-09-01 13:03:50 -0700931using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>;
932
David Sehr7629f602016-08-07 16:01:51 -0700933class DebugInfoItem : public Item {
934 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000935 DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
936 : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
937
938 uint32_t GetDebugInfoSize() const { return debug_info_size_; }
939 uint8_t* GetDebugInfo() const { return debug_info_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700940
David Sehr853a8e12016-09-01 13:03:50 -0700941 PositionInfoVector& GetPositionInfo() { return positions_; }
942 LocalInfoVector& GetLocalInfo() { return locals_; }
David Sehr7629f602016-08-07 16:01:51 -0700943
944 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000945 uint32_t debug_info_size_;
946 std::unique_ptr<uint8_t[]> debug_info_;
947
David Sehr853a8e12016-09-01 13:03:50 -0700948 PositionInfoVector positions_;
949 LocalInfoVector locals_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700950
David Sehr7629f602016-08-07 16:01:51 -0700951 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
952};
953
Jeff Hao3ab96b42016-09-09 18:35:01 -0700954class AnnotationItem : public Item {
David Sehr853a8e12016-09-01 13:03:50 -0700955 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700956 AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation)
957 : visibility_(visibility), annotation_(annotation) { }
David Sehr853a8e12016-09-01 13:03:50 -0700958
959 uint8_t GetVisibility() const { return visibility_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700960 EncodedAnnotation* GetAnnotation() const { return annotation_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700961
962 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
963
964 private:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700965 uint8_t visibility_;
966 std::unique_ptr<EncodedAnnotation> annotation_;
967
968 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
969};
970
971class AnnotationSetItem : public Item {
972 public:
973 explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) {
974 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
975 }
976 ~AnnotationSetItem() OVERRIDE { }
977
978 std::vector<AnnotationItem*>* GetItems() { return items_.get(); }
979
980 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
981
982 private:
983 std::unique_ptr<std::vector<AnnotationItem*>> items_;
984
David Sehr7629f602016-08-07 16:01:51 -0700985 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
986};
987
Jeff Hao3ab96b42016-09-09 18:35:01 -0700988class AnnotationSetRefList : public Item {
989 public:
990 explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) {
991 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
992 }
993 ~AnnotationSetRefList() OVERRIDE { }
994
995 std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); }
996
997 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
998
999 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001000 std::unique_ptr<std::vector<AnnotationSetItem*>> items_; // Elements of vector can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001001
1002 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
1003};
David Sehr853a8e12016-09-01 13:03:50 -07001004
1005class FieldAnnotation {
1006 public:
1007 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
1008 : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
1009
1010 FieldId* GetFieldId() const { return field_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001011 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001012
1013 private:
1014 FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001015 AnnotationSetItem* annotation_set_item_;
1016
David Sehr853a8e12016-09-01 13:03:50 -07001017 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
1018};
1019
1020using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
1021
1022class MethodAnnotation {
1023 public:
1024 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
1025 : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
1026
1027 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001028 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001029
1030 private:
1031 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001032 AnnotationSetItem* annotation_set_item_;
1033
David Sehr853a8e12016-09-01 13:03:50 -07001034 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
1035};
1036
1037using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
1038
1039class ParameterAnnotation {
1040 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001041 ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations)
David Sehr853a8e12016-09-01 13:03:50 -07001042 : method_id_(method_id), annotations_(annotations) { }
1043
1044 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001045 AnnotationSetRefList* GetAnnotations() { return annotations_; }
David Sehr853a8e12016-09-01 13:03:50 -07001046
1047 private:
1048 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001049 AnnotationSetRefList* annotations_;
1050
David Sehr853a8e12016-09-01 13:03:50 -07001051 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
1052};
1053
1054using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
1055
David Sehr7629f602016-08-07 16:01:51 -07001056class AnnotationsDirectoryItem : public Item {
1057 public:
David Sehr853a8e12016-09-01 13:03:50 -07001058 AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
1059 FieldAnnotationVector* field_annotations,
1060 MethodAnnotationVector* method_annotations,
1061 ParameterAnnotationVector* parameter_annotations)
1062 : class_annotation_(class_annotation),
1063 field_annotations_(field_annotations),
1064 method_annotations_(method_annotations),
1065 parameter_annotations_(parameter_annotations) { }
David Sehr7629f602016-08-07 16:01:51 -07001066
Jeff Hao3ab96b42016-09-09 18:35:01 -07001067 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; }
David Sehr853a8e12016-09-01 13:03:50 -07001068 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
1069 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
1070 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001071
1072 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1073
1074 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001075 AnnotationSetItem* class_annotation_; // This can be nullptr.
1076 std::unique_ptr<FieldAnnotationVector> field_annotations_; // This can be nullptr.
1077 std::unique_ptr<MethodAnnotationVector> method_annotations_; // This can be nullptr.
1078 std::unique_ptr<ParameterAnnotationVector> parameter_annotations_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001079
David Sehr7629f602016-08-07 16:01:51 -07001080 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
1081};
1082
1083// TODO(sehr): implement MapList.
1084class MapList : public Item {
1085 public:
1086 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1087
1088 private:
1089 DISALLOW_COPY_AND_ASSIGN(MapList);
1090};
1091
1092class MapItem : public Item {
1093 public:
1094 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1095
1096 private:
1097 DISALLOW_COPY_AND_ASSIGN(MapItem);
1098};
1099
1100} // namespace dex_ir
1101} // namespace art
1102
1103#endif // ART_DEXLAYOUT_DEX_IR_H_