blob: 5692eb2b39cda7b5d46cfc027b3f69fe94f5bf47 [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;
Jeff Hao5daee902017-04-27 18:00:38 -070038class CallSiteId;
David Sehr7629f602016-08-07 16:01:51 -070039class ClassData;
40class ClassDef;
41class CodeItem;
42class DebugInfoItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070043class EncodedAnnotation;
44class EncodedArrayItem;
45class EncodedValue;
David Sehr7629f602016-08-07 16:01:51 -070046class FieldId;
47class FieldItem;
48class Header;
49class MapList;
50class MapItem;
Jeff Hao5daee902017-04-27 18:00:38 -070051class MethodHandleItem;
David Sehr7629f602016-08-07 16:01:51 -070052class MethodId;
53class MethodItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070054class ParameterAnnotation;
David Sehr7629f602016-08-07 16:01:51 -070055class ProtoId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070056class StringData;
David Sehr7629f602016-08-07 16:01:51 -070057class StringId;
58class TryItem;
59class TypeId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070060class TypeList;
61
62// Item size constants.
63static constexpr size_t kHeaderItemSize = 112;
64static constexpr size_t kStringIdItemSize = 4;
65static constexpr size_t kTypeIdItemSize = 4;
66static constexpr size_t kProtoIdItemSize = 12;
67static constexpr size_t kFieldIdItemSize = 8;
68static constexpr size_t kMethodIdItemSize = 8;
69static constexpr size_t kClassDefItemSize = 32;
Jeff Hao5daee902017-04-27 18:00:38 -070070static constexpr size_t kCallSiteIdItemSize = 4;
71static constexpr size_t kMethodHandleItemSize = 8;
David Sehr7629f602016-08-07 16:01:51 -070072
73// Visitor support
74class AbstractDispatcher {
75 public:
76 AbstractDispatcher() = default;
77 virtual ~AbstractDispatcher() { }
78
79 virtual void Dispatch(Header* header) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070080 virtual void Dispatch(const StringData* string_data) = 0;
David Sehr7629f602016-08-07 16:01:51 -070081 virtual void Dispatch(const StringId* string_id) = 0;
82 virtual void Dispatch(const TypeId* type_id) = 0;
83 virtual void Dispatch(const ProtoId* proto_id) = 0;
84 virtual void Dispatch(const FieldId* field_id) = 0;
85 virtual void Dispatch(const MethodId* method_id) = 0;
Jeff Hao5daee902017-04-27 18:00:38 -070086 virtual void Dispatch(const CallSiteId* call_site_id) = 0;
87 virtual void Dispatch(const MethodHandleItem* method_handle_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070088 virtual void Dispatch(ClassData* class_data) = 0;
89 virtual void Dispatch(ClassDef* class_def) = 0;
90 virtual void Dispatch(FieldItem* field_item) = 0;
91 virtual void Dispatch(MethodItem* method_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070092 virtual void Dispatch(EncodedArrayItem* array_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070093 virtual void Dispatch(CodeItem* code_item) = 0;
94 virtual void Dispatch(TryItem* try_item) = 0;
95 virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070096 virtual void Dispatch(AnnotationItem* annotation_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070097 virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070098 virtual void Dispatch(AnnotationSetRefList* annotation_set_ref_list) = 0;
David Sehr7629f602016-08-07 16:01:51 -070099 virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
100 virtual void Dispatch(MapList* map_list) = 0;
101 virtual void Dispatch(MapItem* map_item) = 0;
102
103 private:
104 DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
105};
106
107// Collections become owners of the objects added by moving them into unique pointers.
Jeff Haoea7c6292016-11-14 18:10:16 -0800108template<class T> class CollectionBase {
David Sehr7629f602016-08-07 16:01:51 -0700109 public:
Jeff Haoea7c6292016-11-14 18:10:16 -0800110 CollectionBase() = default;
111
112 uint32_t GetOffset() const { return offset_; }
113 void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
114
115 private:
116 uint32_t offset_ = 0;
117
118 DISALLOW_COPY_AND_ASSIGN(CollectionBase);
119};
120
121template<class T> class CollectionVector : public CollectionBase<T> {
122 public:
123 CollectionVector() = default;
124
Jeff Hao3ab96b42016-09-09 18:35:01 -0700125 void AddIndexedItem(T* object, uint32_t offset, uint32_t index) {
126 object->SetOffset(offset);
127 object->SetIndex(index);
128 collection_.push_back(std::unique_ptr<T>(object));
David Sehr7629f602016-08-07 16:01:51 -0700129 }
David Sehr7629f602016-08-07 16:01:51 -0700130 uint32_t Size() const { return collection_.size(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800131 std::vector<std::unique_ptr<T>>& Collection() { return collection_; }
David Sehr7629f602016-08-07 16:01:51 -0700132
133 private:
134 std::vector<std::unique_ptr<T>> collection_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700135
Jeff Haoea7c6292016-11-14 18:10:16 -0800136 DISALLOW_COPY_AND_ASSIGN(CollectionVector);
137};
138
139template<class T> class CollectionMap : public CollectionBase<T> {
140 public:
141 CollectionMap() = default;
142
Mathieu Chartiera2973d72017-02-14 17:12:20 -0800143 // Returns the existing item if it is already inserted, null otherwise.
144 T* GetExistingObject(uint32_t offset) {
145 auto it = collection_.find(offset);
146 return it != collection_.end() ? it->second.get() : nullptr;
147 }
148
Jeff Haoea7c6292016-11-14 18:10:16 -0800149 void AddItem(T* object, uint32_t offset) {
150 object->SetOffset(offset);
Mathieu Chartiera2973d72017-02-14 17:12:20 -0800151 auto it = collection_.emplace(offset, std::unique_ptr<T>(object));
152 CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " "
153 << " and address " << it.first->second.get();
Jeff Haoea7c6292016-11-14 18:10:16 -0800154 }
155 uint32_t Size() const { return collection_.size(); }
156 std::map<uint32_t, std::unique_ptr<T>>& Collection() { return collection_; }
157
158 private:
159 std::map<uint32_t, std::unique_ptr<T>> collection_;
160
161 DISALLOW_COPY_AND_ASSIGN(CollectionMap);
David Sehr7629f602016-08-07 16:01:51 -0700162};
163
Jeff Hao3ab96b42016-09-09 18:35:01 -0700164class Collections {
165 public:
166 Collections() = default;
167
168 std::vector<std::unique_ptr<StringId>>& StringIds() { return string_ids_.Collection(); }
169 std::vector<std::unique_ptr<TypeId>>& TypeIds() { return type_ids_.Collection(); }
170 std::vector<std::unique_ptr<ProtoId>>& ProtoIds() { return proto_ids_.Collection(); }
171 std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); }
172 std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); }
173 std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); }
Jeff Hao5daee902017-04-27 18:00:38 -0700174 std::vector<std::unique_ptr<CallSiteId>>& CallSiteIds() { return call_site_ids_.Collection(); }
175 std::vector<std::unique_ptr<MethodHandleItem>>& MethodHandleItems()
176 { return method_handle_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800177 std::map<uint32_t, std::unique_ptr<StringData>>& StringDatas()
178 { return string_datas_.Collection(); }
179 std::map<uint32_t, std::unique_ptr<TypeList>>& TypeLists() { return type_lists_.Collection(); }
180 std::map<uint32_t, std::unique_ptr<EncodedArrayItem>>& EncodedArrayItems()
Jeff Hao3ab96b42016-09-09 18:35:01 -0700181 { return encoded_array_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800182 std::map<uint32_t, std::unique_ptr<AnnotationItem>>& AnnotationItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000183 { return annotation_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800184 std::map<uint32_t, std::unique_ptr<AnnotationSetItem>>& AnnotationSetItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000185 { return annotation_set_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800186 std::map<uint32_t, std::unique_ptr<AnnotationSetRefList>>& AnnotationSetRefLists()
Jeff Haoa8621002016-10-04 18:13:44 +0000187 { return annotation_set_ref_lists_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800188 std::map<uint32_t, std::unique_ptr<AnnotationsDirectoryItem>>& AnnotationsDirectoryItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000189 { return annotations_directory_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800190 std::map<uint32_t, std::unique_ptr<DebugInfoItem>>& DebugInfoItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000191 { return debug_info_items_.Collection(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800192 std::map<uint32_t, std::unique_ptr<CodeItem>>& CodeItems() { return code_items_.Collection(); }
193 std::map<uint32_t, std::unique_ptr<ClassData>>& ClassDatas() { return class_datas_.Collection(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700194
195 void CreateStringId(const DexFile& dex_file, uint32_t i);
196 void CreateTypeId(const DexFile& dex_file, uint32_t i);
197 void CreateProtoId(const DexFile& dex_file, uint32_t i);
198 void CreateFieldId(const DexFile& dex_file, uint32_t i);
199 void CreateMethodId(const DexFile& dex_file, uint32_t i);
200 void CreateClassDef(const DexFile& dex_file, uint32_t i);
Jeff Hao5daee902017-04-27 18:00:38 -0700201 void CreateCallSiteId(const DexFile& dex_file, uint32_t i);
202 void CreateMethodHandleItem(const DexFile& dex_file, uint32_t i);
203
204 void CreateCallSitesAndMethodHandles(const DexFile& dex_file);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700205
Jeff Haoa8621002016-10-04 18:13:44 +0000206 TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700207 EncodedArrayItem* CreateEncodedArrayItem(const uint8_t* static_data, uint32_t offset);
208 AnnotationItem* CreateAnnotationItem(const DexFile::AnnotationItem* annotation, uint32_t offset);
209 AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
Jeff Haobe9b44b2017-02-16 13:34:38 -0800210 const DexFile::AnnotationSetItem* disk_annotations_item, uint32_t offset);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700211 AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file,
212 const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset);
213 CodeItem* CreateCodeItem(
214 const DexFile& dex_file, const DexFile::CodeItem& disk_code_item, uint32_t offset);
215 ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
216
217 StringId* GetStringId(uint32_t index) { return StringIds()[index].get(); }
218 TypeId* GetTypeId(uint32_t index) { return TypeIds()[index].get(); }
219 ProtoId* GetProtoId(uint32_t index) { return ProtoIds()[index].get(); }
220 FieldId* GetFieldId(uint32_t index) { return FieldIds()[index].get(); }
221 MethodId* GetMethodId(uint32_t index) { return MethodIds()[index].get(); }
222 ClassDef* GetClassDef(uint32_t index) { return ClassDefs()[index].get(); }
Jeff Hao5daee902017-04-27 18:00:38 -0700223 CallSiteId* GetCallSiteId(uint32_t index) { return CallSiteIds()[index].get(); }
224 MethodHandleItem* GetMethodHandle(uint32_t index) { return MethodHandleItems()[index].get(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700225
226 StringId* GetStringIdOrNullPtr(uint32_t index) {
227 return index == DexFile::kDexNoIndex ? nullptr : GetStringId(index);
228 }
229 TypeId* GetTypeIdOrNullPtr(uint16_t index) {
230 return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index);
231 }
232
233 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
234 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
235 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
236 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
237 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
238 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
Jeff Hao5daee902017-04-27 18:00:38 -0700239 uint32_t CallSiteIdsOffset() const { return call_site_ids_.GetOffset(); }
240 uint32_t MethodHandleItemsOffset() const { return method_handle_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700241 uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
242 uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000243 uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
244 uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
245 uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700246 uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000247 uint32_t AnnotationsDirectoryItemsOffset() const
248 { return annotations_directory_items_.GetOffset(); }
249 uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700250 uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
251 uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800252 uint32_t MapListOffset() const { return map_list_offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700253
254 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
255 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
256 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
257 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
258 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
259 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
Jeff Hao5daee902017-04-27 18:00:38 -0700260 void SetCallSiteIdsOffset(uint32_t new_offset) { call_site_ids_.SetOffset(new_offset); }
261 void SetMethodHandleItemsOffset(uint32_t new_offset)
262 { method_handle_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700263 void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
264 void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000265 void SetEncodedArrayItemsOffset(uint32_t new_offset)
266 { encoded_array_items_.SetOffset(new_offset); }
267 void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
268 void SetAnnotationSetItemsOffset(uint32_t new_offset)
269 { annotation_set_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700270 void SetAnnotationSetRefListsOffset(uint32_t new_offset)
271 { annotation_set_ref_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000272 void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700273 { annotations_directory_items_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000274 void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700275 void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
276 void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800277 void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700278
279 uint32_t StringIdsSize() const { return string_ids_.Size(); }
280 uint32_t TypeIdsSize() const { return type_ids_.Size(); }
281 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
282 uint32_t FieldIdsSize() const { return field_ids_.Size(); }
283 uint32_t MethodIdsSize() const { return method_ids_.Size(); }
284 uint32_t ClassDefsSize() const { return class_defs_.Size(); }
Jeff Hao5daee902017-04-27 18:00:38 -0700285 uint32_t CallSiteIdsSize() const { return call_site_ids_.Size(); }
286 uint32_t MethodHandleItemsSize() const { return method_handle_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700287 uint32_t StringDatasSize() const { return string_datas_.Size(); }
288 uint32_t TypeListsSize() const { return type_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000289 uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
290 uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
291 uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700292 uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000293 uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
294 uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700295 uint32_t CodeItemsSize() const { return code_items_.Size(); }
296 uint32_t ClassDatasSize() const { return class_datas_.Size(); }
297
Jeff Hao3ab96b42016-09-09 18:35:01 -0700298 private:
299 EncodedValue* ReadEncodedValue(const uint8_t** data);
300 EncodedValue* ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length);
301 void ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length, EncodedValue* item);
302
303 ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
304 const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
305 MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
306
Jeff Haoea7c6292016-11-14 18:10:16 -0800307 CollectionVector<StringId> string_ids_;
308 CollectionVector<TypeId> type_ids_;
309 CollectionVector<ProtoId> proto_ids_;
310 CollectionVector<FieldId> field_ids_;
311 CollectionVector<MethodId> method_ids_;
312 CollectionVector<ClassDef> class_defs_;
Jeff Hao5daee902017-04-27 18:00:38 -0700313 CollectionVector<CallSiteId> call_site_ids_;
314 CollectionVector<MethodHandleItem> method_handle_items_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700315
Jeff Haoea7c6292016-11-14 18:10:16 -0800316 CollectionMap<StringData> string_datas_;
317 CollectionMap<TypeList> type_lists_;
318 CollectionMap<EncodedArrayItem> encoded_array_items_;
319 CollectionMap<AnnotationItem> annotation_items_;
320 CollectionMap<AnnotationSetItem> annotation_set_items_;
321 CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_;
322 CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_;
323 CollectionMap<DebugInfoItem> debug_info_items_;
324 CollectionMap<CodeItem> code_items_;
325 CollectionMap<ClassData> class_datas_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700326
Jeff Haoea7c6292016-11-14 18:10:16 -0800327 uint32_t map_list_offset_ = 0;
Jeff Haoa8621002016-10-04 18:13:44 +0000328
Jeff Hao3ab96b42016-09-09 18:35:01 -0700329 DISALLOW_COPY_AND_ASSIGN(Collections);
330};
331
David Sehr7629f602016-08-07 16:01:51 -0700332class Item {
333 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700334 Item() { }
David Sehr7629f602016-08-07 16:01:51 -0700335 virtual ~Item() { }
David Sehr853a8e12016-09-01 13:03:50 -0700336
David Sehr7629f602016-08-07 16:01:51 -0700337 uint32_t GetOffset() const { return offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700338 uint32_t GetSize() const { return size_; }
David Sehr7629f602016-08-07 16:01:51 -0700339 void SetOffset(uint32_t offset) { offset_ = offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700340 void SetSize(uint32_t size) { size_ = size; }
David Sehr853a8e12016-09-01 13:03:50 -0700341
David Sehr7629f602016-08-07 16:01:51 -0700342 protected:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700343 Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
344
David Sehr7629f602016-08-07 16:01:51 -0700345 uint32_t offset_ = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700346 uint32_t size_ = 0;
347};
348
349class IndexedItem : public Item {
350 public:
351 IndexedItem() { }
352 virtual ~IndexedItem() { }
353
354 uint32_t GetIndex() const { return index_; }
355 void SetIndex(uint32_t index) { index_ = index; }
356
357 protected:
358 IndexedItem(uint32_t offset, uint32_t size, uint32_t index)
359 : Item(offset, size), index_(index) { }
360
361 uint32_t index_ = 0;
David Sehr7629f602016-08-07 16:01:51 -0700362};
363
364class Header : public Item {
365 public:
David Sehr853a8e12016-09-01 13:03:50 -0700366 Header(const uint8_t* magic,
367 uint32_t checksum,
368 const uint8_t* signature,
369 uint32_t endian_tag,
370 uint32_t file_size,
371 uint32_t header_size,
372 uint32_t link_size,
373 uint32_t link_offset,
374 uint32_t data_size,
375 uint32_t data_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700376 : Item(0, kHeaderItemSize),
377 checksum_(checksum),
David Sehr853a8e12016-09-01 13:03:50 -0700378 endian_tag_(endian_tag),
379 file_size_(file_size),
380 header_size_(header_size),
381 link_size_(link_size),
382 link_offset_(link_offset),
383 data_size_(data_size),
384 data_offset_(data_offset) {
385 memcpy(magic_, magic, sizeof(magic_));
386 memcpy(signature_, signature, sizeof(signature_));
387 }
David Sehr7629f602016-08-07 16:01:51 -0700388 ~Header() OVERRIDE { }
389
Jeff Hao3ab96b42016-09-09 18:35:01 -0700390 static size_t ItemSize() { return kHeaderItemSize; }
391
David Sehr7629f602016-08-07 16:01:51 -0700392 const uint8_t* Magic() const { return magic_; }
393 uint32_t Checksum() const { return checksum_; }
394 const uint8_t* Signature() const { return signature_; }
395 uint32_t EndianTag() const { return endian_tag_; }
396 uint32_t FileSize() const { return file_size_; }
397 uint32_t HeaderSize() const { return header_size_; }
398 uint32_t LinkSize() const { return link_size_; }
399 uint32_t LinkOffset() const { return link_offset_; }
400 uint32_t DataSize() const { return data_size_; }
401 uint32_t DataOffset() const { return data_offset_; }
402
403 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
404 void SetSignature(const uint8_t* new_signature) {
405 memcpy(signature_, new_signature, sizeof(signature_));
406 }
407 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
408 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
409 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
410 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
411 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
412 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
413
Jeff Hao3ab96b42016-09-09 18:35:01 -0700414 Collections& GetCollections() { return collections_; }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700415
David Sehr7629f602016-08-07 16:01:51 -0700416 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
417
418 private:
David Sehr7629f602016-08-07 16:01:51 -0700419 uint8_t magic_[8];
420 uint32_t checksum_;
421 uint8_t signature_[DexFile::kSha1DigestSize];
422 uint32_t endian_tag_;
423 uint32_t file_size_;
424 uint32_t header_size_;
425 uint32_t link_size_;
426 uint32_t link_offset_;
427 uint32_t data_size_;
428 uint32_t data_offset_;
429
Jeff Hao3ab96b42016-09-09 18:35:01 -0700430 Collections collections_;
431
David Sehr7629f602016-08-07 16:01:51 -0700432 DISALLOW_COPY_AND_ASSIGN(Header);
433};
434
Jeff Hao3ab96b42016-09-09 18:35:01 -0700435class StringData : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700436 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700437 explicit StringData(const char* data) : data_(strdup(data)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000438 size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700439 }
David Sehr7629f602016-08-07 16:01:51 -0700440
441 const char* Data() const { return data_.get(); }
442
443 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
444
445 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000446 UniqueCPtr<const char> data_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700447
448 DISALLOW_COPY_AND_ASSIGN(StringData);
449};
450
451class StringId : public IndexedItem {
452 public:
453 explicit StringId(StringData* string_data) : string_data_(string_data) {
454 size_ = kStringIdItemSize;
455 }
456 ~StringId() OVERRIDE { }
457
458 static size_t ItemSize() { return kStringIdItemSize; }
459
460 const char* Data() const { return string_data_->Data(); }
461 StringData* DataItem() const { return string_data_; }
462
463 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
464
465 private:
466 StringData* string_data_;
467
David Sehr7629f602016-08-07 16:01:51 -0700468 DISALLOW_COPY_AND_ASSIGN(StringId);
469};
470
Jeff Hao3ab96b42016-09-09 18:35:01 -0700471class TypeId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700472 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700473 explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700474 ~TypeId() OVERRIDE { }
475
Jeff Hao3ab96b42016-09-09 18:35:01 -0700476 static size_t ItemSize() { return kTypeIdItemSize; }
477
David Sehr7629f602016-08-07 16:01:51 -0700478 StringId* GetStringId() const { return string_id_; }
479
480 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
481
482 private:
483 StringId* string_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700484
David Sehr7629f602016-08-07 16:01:51 -0700485 DISALLOW_COPY_AND_ASSIGN(TypeId);
486};
487
David Sehr853a8e12016-09-01 13:03:50 -0700488using TypeIdVector = std::vector<const TypeId*>;
489
Jeff Hao3ab96b42016-09-09 18:35:01 -0700490class TypeList : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700491 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700492 explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) {
493 size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t));
494 }
495 ~TypeList() OVERRIDE { }
496
497 const TypeIdVector* GetTypeList() const { return type_list_.get(); }
498
499 private:
500 std::unique_ptr<TypeIdVector> type_list_;
501
502 DISALLOW_COPY_AND_ASSIGN(TypeList);
503};
504
505class ProtoId : public IndexedItem {
506 public:
507 ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters)
508 : shorty_(shorty), return_type_(return_type), parameters_(parameters)
509 { size_ = kProtoIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700510 ~ProtoId() OVERRIDE { }
511
Jeff Hao3ab96b42016-09-09 18:35:01 -0700512 static size_t ItemSize() { return kProtoIdItemSize; }
513
David Sehr7629f602016-08-07 16:01:51 -0700514 const StringId* Shorty() const { return shorty_; }
515 const TypeId* ReturnType() const { return return_type_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000516 const TypeList* Parameters() const { return parameters_; }
David Sehr7629f602016-08-07 16:01:51 -0700517
518 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
519
520 private:
521 const StringId* shorty_;
522 const TypeId* return_type_;
Jeff Haoa8621002016-10-04 18:13:44 +0000523 TypeList* parameters_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700524
David Sehr7629f602016-08-07 16:01:51 -0700525 DISALLOW_COPY_AND_ASSIGN(ProtoId);
526};
527
Jeff Hao3ab96b42016-09-09 18:35:01 -0700528class FieldId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700529 public:
David Sehr853a8e12016-09-01 13:03:50 -0700530 FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700531 : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700532 ~FieldId() OVERRIDE { }
533
Jeff Hao3ab96b42016-09-09 18:35:01 -0700534 static size_t ItemSize() { return kFieldIdItemSize; }
535
David Sehr7629f602016-08-07 16:01:51 -0700536 const TypeId* Class() const { return class_; }
537 const TypeId* Type() const { return type_; }
538 const StringId* Name() const { return name_; }
539
540 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
541
542 private:
543 const TypeId* class_;
544 const TypeId* type_;
545 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700546
David Sehr7629f602016-08-07 16:01:51 -0700547 DISALLOW_COPY_AND_ASSIGN(FieldId);
548};
549
Jeff Hao3ab96b42016-09-09 18:35:01 -0700550class MethodId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700551 public:
David Sehr853a8e12016-09-01 13:03:50 -0700552 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700553 : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700554 ~MethodId() OVERRIDE { }
555
Jeff Hao3ab96b42016-09-09 18:35:01 -0700556 static size_t ItemSize() { return kMethodIdItemSize; }
557
David Sehr7629f602016-08-07 16:01:51 -0700558 const TypeId* Class() const { return class_; }
559 const ProtoId* Proto() const { return proto_; }
560 const StringId* Name() const { return name_; }
561
562 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
563
564 private:
565 const TypeId* class_;
566 const ProtoId* proto_;
567 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700568
David Sehr7629f602016-08-07 16:01:51 -0700569 DISALLOW_COPY_AND_ASSIGN(MethodId);
570};
571
572class FieldItem : public Item {
573 public:
David Sehr853a8e12016-09-01 13:03:50 -0700574 FieldItem(uint32_t access_flags, const FieldId* field_id)
575 : access_flags_(access_flags), field_id_(field_id) { }
David Sehr7629f602016-08-07 16:01:51 -0700576 ~FieldItem() OVERRIDE { }
577
578 uint32_t GetAccessFlags() const { return access_flags_; }
579 const FieldId* GetFieldId() const { return field_id_; }
580
581 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
582
583 private:
584 uint32_t access_flags_;
585 const FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700586
David Sehr7629f602016-08-07 16:01:51 -0700587 DISALLOW_COPY_AND_ASSIGN(FieldItem);
588};
589
David Sehr853a8e12016-09-01 13:03:50 -0700590using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
591
David Sehr7629f602016-08-07 16:01:51 -0700592class MethodItem : public Item {
593 public:
Jeff Haoea7c6292016-11-14 18:10:16 -0800594 MethodItem(uint32_t access_flags, const MethodId* method_id, CodeItem* code)
David Sehr853a8e12016-09-01 13:03:50 -0700595 : access_flags_(access_flags), method_id_(method_id), code_(code) { }
David Sehr7629f602016-08-07 16:01:51 -0700596 ~MethodItem() OVERRIDE { }
597
598 uint32_t GetAccessFlags() const { return access_flags_; }
599 const MethodId* GetMethodId() const { return method_id_; }
Jeff Haoea7c6292016-11-14 18:10:16 -0800600 CodeItem* GetCodeItem() { return code_; }
David Sehr7629f602016-08-07 16:01:51 -0700601
602 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
603
604 private:
605 uint32_t access_flags_;
606 const MethodId* method_id_;
Jeff Haoea7c6292016-11-14 18:10:16 -0800607 CodeItem* code_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700608
David Sehr7629f602016-08-07 16:01:51 -0700609 DISALLOW_COPY_AND_ASSIGN(MethodItem);
610};
611
David Sehr853a8e12016-09-01 13:03:50 -0700612using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
613
Jeff Hao3ab96b42016-09-09 18:35:01 -0700614class EncodedValue {
David Sehr7629f602016-08-07 16:01:51 -0700615 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700616 explicit EncodedValue(uint8_t type) : type_(type) { }
David Sehr7629f602016-08-07 16:01:51 -0700617
618 int8_t Type() const { return type_; }
David Sehr7629f602016-08-07 16:01:51 -0700619
Jeff Hao3ab96b42016-09-09 18:35:01 -0700620 void SetBoolean(bool z) { u_.bool_val_ = z; }
621 void SetByte(int8_t b) { u_.byte_val_ = b; }
622 void SetShort(int16_t s) { u_.short_val_ = s; }
623 void SetChar(uint16_t c) { u_.char_val_ = c; }
624 void SetInt(int32_t i) { u_.int_val_ = i; }
625 void SetLong(int64_t l) { u_.long_val_ = l; }
626 void SetFloat(float f) { u_.float_val_ = f; }
627 void SetDouble(double d) { u_.double_val_ = d; }
628 void SetStringId(StringId* string_id) { u_.string_val_ = string_id; }
629 void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; }
Jeff Hao5daee902017-04-27 18:00:38 -0700630 void SetProtoId(ProtoId* proto_id) { u_.proto_val_ = proto_id; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700631 void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; }
632 void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; }
Jeff Hao5daee902017-04-27 18:00:38 -0700633 void SetMethodHandle(MethodHandleItem* method_handle) { u_.method_handle_val_ = method_handle; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700634 void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); }
635 void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation)
636 { encoded_annotation_.reset(encoded_annotation); }
637
638 bool GetBoolean() const { return u_.bool_val_; }
639 int8_t GetByte() const { return u_.byte_val_; }
640 int16_t GetShort() const { return u_.short_val_; }
641 uint16_t GetChar() const { return u_.char_val_; }
642 int32_t GetInt() const { return u_.int_val_; }
643 int64_t GetLong() const { return u_.long_val_; }
644 float GetFloat() const { return u_.float_val_; }
645 double GetDouble() const { return u_.double_val_; }
646 StringId* GetStringId() const { return u_.string_val_; }
647 TypeId* GetTypeId() const { return u_.type_val_; }
Jeff Hao5daee902017-04-27 18:00:38 -0700648 ProtoId* GetProtoId() const { return u_.proto_val_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700649 FieldId* GetFieldId() const { return u_.field_val_; }
650 MethodId* GetMethodId() const { return u_.method_val_; }
Jeff Hao5daee902017-04-27 18:00:38 -0700651 MethodHandleItem* GetMethodHandle() const { return u_.method_handle_val_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700652 EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); }
653 EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); }
654
655 EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); }
David Sehr7629f602016-08-07 16:01:51 -0700656
657 private:
David Sehr7629f602016-08-07 16:01:51 -0700658 uint8_t type_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700659 union {
660 bool bool_val_;
661 int8_t byte_val_;
662 int16_t short_val_;
663 uint16_t char_val_;
664 int32_t int_val_;
665 int64_t long_val_;
666 float float_val_;
667 double double_val_;
668 StringId* string_val_;
669 TypeId* type_val_;
Jeff Hao5daee902017-04-27 18:00:38 -0700670 ProtoId* proto_val_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700671 FieldId* field_val_;
672 MethodId* method_val_;
Jeff Hao5daee902017-04-27 18:00:38 -0700673 MethodHandleItem* method_handle_val_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700674 } u_;
675 std::unique_ptr<EncodedArrayItem> encoded_array_;
676 std::unique_ptr<EncodedAnnotation> encoded_annotation_;
677
678 DISALLOW_COPY_AND_ASSIGN(EncodedValue);
David Sehr7629f602016-08-07 16:01:51 -0700679};
680
Jeff Hao3ab96b42016-09-09 18:35:01 -0700681using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>;
682
683class AnnotationElement {
684 public:
685 AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { }
686
687 StringId* GetName() const { return name_; }
688 EncodedValue* GetValue() const { return value_.get(); }
689
690 private:
691 StringId* name_;
692 std::unique_ptr<EncodedValue> value_;
693
694 DISALLOW_COPY_AND_ASSIGN(AnnotationElement);
695};
696
697using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>;
698
699class EncodedAnnotation {
700 public:
701 EncodedAnnotation(TypeId* type, AnnotationElementVector* elements)
702 : type_(type), elements_(elements) { }
703
704 TypeId* GetType() const { return type_; }
705 AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); }
706
707 private:
708 TypeId* type_;
709 std::unique_ptr<AnnotationElementVector> elements_;
710
711 DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation);
712};
713
714class EncodedArrayItem : public Item {
715 public:
716 explicit EncodedArrayItem(EncodedValueVector* encoded_values)
717 : encoded_values_(encoded_values) { }
718
719 EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); }
720
721 private:
722 std::unique_ptr<EncodedValueVector> encoded_values_;
723
724 DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem);
725};
David Sehr853a8e12016-09-01 13:03:50 -0700726
David Sehr7629f602016-08-07 16:01:51 -0700727class ClassData : public Item {
728 public:
David Sehr853a8e12016-09-01 13:03:50 -0700729 ClassData(FieldItemVector* static_fields,
730 FieldItemVector* instance_fields,
731 MethodItemVector* direct_methods,
732 MethodItemVector* virtual_methods)
733 : static_fields_(static_fields),
734 instance_fields_(instance_fields),
735 direct_methods_(direct_methods),
736 virtual_methods_(virtual_methods) { }
737
David Sehr7629f602016-08-07 16:01:51 -0700738 ~ClassData() OVERRIDE = default;
David Sehr853a8e12016-09-01 13:03:50 -0700739 FieldItemVector* StaticFields() { return static_fields_.get(); }
740 FieldItemVector* InstanceFields() { return instance_fields_.get(); }
741 MethodItemVector* DirectMethods() { return direct_methods_.get(); }
742 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700743
744 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
745
746 private:
David Sehr853a8e12016-09-01 13:03:50 -0700747 std::unique_ptr<FieldItemVector> static_fields_;
748 std::unique_ptr<FieldItemVector> instance_fields_;
749 std::unique_ptr<MethodItemVector> direct_methods_;
750 std::unique_ptr<MethodItemVector> virtual_methods_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700751
David Sehr7629f602016-08-07 16:01:51 -0700752 DISALLOW_COPY_AND_ASSIGN(ClassData);
753};
754
Jeff Hao3ab96b42016-09-09 18:35:01 -0700755class ClassDef : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700756 public:
David Sehr853a8e12016-09-01 13:03:50 -0700757 ClassDef(const TypeId* class_type,
758 uint32_t access_flags,
759 const TypeId* superclass,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700760 TypeList* interfaces,
David Sehr853a8e12016-09-01 13:03:50 -0700761 const StringId* source_file,
762 AnnotationsDirectoryItem* annotations,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700763 EncodedArrayItem* static_values,
David Sehr853a8e12016-09-01 13:03:50 -0700764 ClassData* class_data)
765 : class_type_(class_type),
766 access_flags_(access_flags),
767 superclass_(superclass),
768 interfaces_(interfaces),
David Sehr853a8e12016-09-01 13:03:50 -0700769 source_file_(source_file),
770 annotations_(annotations),
Jeff Haoa8621002016-10-04 18:13:44 +0000771 class_data_(class_data),
772 static_values_(static_values) { size_ = kClassDefItemSize; }
David Sehr853a8e12016-09-01 13:03:50 -0700773
David Sehr7629f602016-08-07 16:01:51 -0700774 ~ClassDef() OVERRIDE { }
775
Jeff Hao3ab96b42016-09-09 18:35:01 -0700776 static size_t ItemSize() { return kClassDefItemSize; }
777
David Sehr7629f602016-08-07 16:01:51 -0700778 const TypeId* ClassType() const { return class_type_; }
779 uint32_t GetAccessFlags() const { return access_flags_; }
780 const TypeId* Superclass() const { return superclass_; }
Jeff Haocc829592017-03-14 16:13:39 -0700781 const TypeList* Interfaces() { return interfaces_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700782 uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
David Sehr7629f602016-08-07 16:01:51 -0700783 const StringId* SourceFile() const { return source_file_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700784 AnnotationsDirectoryItem* Annotations() const { return annotations_; }
Nicolas Geoffrayfd1a6c22016-10-04 11:01:17 +0000785 ClassData* GetClassData() { return class_data_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000786 EncodedArrayItem* StaticValues() { return static_values_; }
David Sehr7629f602016-08-07 16:01:51 -0700787
Jeff Haoc3acfc52016-08-29 14:18:26 -0700788 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
789
David Sehr7629f602016-08-07 16:01:51 -0700790 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
791
792 private:
793 const TypeId* class_type_;
794 uint32_t access_flags_;
Jeff Haoa8621002016-10-04 18:13:44 +0000795 const TypeId* superclass_; // This can be nullptr.
796 TypeList* interfaces_; // This can be nullptr.
797 const StringId* source_file_; // This can be nullptr.
798 AnnotationsDirectoryItem* annotations_; // This can be nullptr.
799 ClassData* class_data_; // This can be nullptr.
800 EncodedArrayItem* static_values_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700801
David Sehr7629f602016-08-07 16:01:51 -0700802 DISALLOW_COPY_AND_ASSIGN(ClassDef);
803};
804
Jeff Haoa8621002016-10-04 18:13:44 +0000805class TypeAddrPair {
David Sehr853a8e12016-09-01 13:03:50 -0700806 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000807 TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
David Sehr853a8e12016-09-01 13:03:50 -0700808
809 const TypeId* GetTypeId() const { return type_id_; }
810 uint32_t GetAddress() const { return address_; }
811
812 private:
Jeff Haocc829592017-03-14 16:13:39 -0700813 const TypeId* type_id_; // This can be nullptr.
David Sehr853a8e12016-09-01 13:03:50 -0700814 uint32_t address_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700815
Jeff Haoa8621002016-10-04 18:13:44 +0000816 DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
817};
818
819using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
820
821class CatchHandler {
822 public:
823 explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
824 : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
825
826 bool HasCatchAll() const { return catch_all_; }
827 uint16_t GetListOffset() const { return list_offset_; }
828 TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
829
830 private:
831 bool catch_all_;
832 uint16_t list_offset_;
833 std::unique_ptr<TypeAddrPairVector> handlers_;
834
David Sehr853a8e12016-09-01 13:03:50 -0700835 DISALLOW_COPY_AND_ASSIGN(CatchHandler);
836};
837
838using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
839
840class TryItem : public Item {
841 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000842 TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700843 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
844 ~TryItem() OVERRIDE { }
845
846 uint32_t StartAddr() const { return start_addr_; }
847 uint16_t InsnCount() const { return insn_count_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000848 const CatchHandler* GetHandlers() const { return handlers_; }
David Sehr853a8e12016-09-01 13:03:50 -0700849
850 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
851
852 private:
853 uint32_t start_addr_;
854 uint16_t insn_count_;
Jeff Haoa8621002016-10-04 18:13:44 +0000855 const CatchHandler* handlers_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700856
David Sehr853a8e12016-09-01 13:03:50 -0700857 DISALLOW_COPY_AND_ASSIGN(TryItem);
858};
859
860using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
861
David Sehrd1e44e22016-10-06 17:09:32 -0700862class CodeFixups {
863 public:
864 CodeFixups(std::vector<TypeId*>* type_ids,
865 std::vector<StringId*>* string_ids,
866 std::vector<MethodId*>* method_ids,
867 std::vector<FieldId*>* field_ids)
868 : type_ids_(type_ids),
869 string_ids_(string_ids),
870 method_ids_(method_ids),
871 field_ids_(field_ids) { }
872
873 std::vector<TypeId*>* TypeIds() const { return type_ids_.get(); }
874 std::vector<StringId*>* StringIds() const { return string_ids_.get(); }
875 std::vector<MethodId*>* MethodIds() const { return method_ids_.get(); }
876 std::vector<FieldId*>* FieldIds() const { return field_ids_.get(); }
877
878 private:
879 std::unique_ptr<std::vector<TypeId*>> type_ids_;
880 std::unique_ptr<std::vector<StringId*>> string_ids_;
881 std::unique_ptr<std::vector<MethodId*>> method_ids_;
882 std::unique_ptr<std::vector<FieldId*>> field_ids_;
883
884 DISALLOW_COPY_AND_ASSIGN(CodeFixups);
885};
886
David Sehr7629f602016-08-07 16:01:51 -0700887class CodeItem : public Item {
888 public:
David Sehr853a8e12016-09-01 13:03:50 -0700889 CodeItem(uint16_t registers_size,
890 uint16_t ins_size,
891 uint16_t outs_size,
892 DebugInfoItem* debug_info,
893 uint32_t insns_size,
894 uint16_t* insns,
Jeff Haoa8621002016-10-04 18:13:44 +0000895 TryItemVector* tries,
896 CatchHandlerVector* handlers)
David Sehr853a8e12016-09-01 13:03:50 -0700897 : registers_size_(registers_size),
898 ins_size_(ins_size),
899 outs_size_(outs_size),
900 debug_info_(debug_info),
901 insns_size_(insns_size),
902 insns_(insns),
Jeff Haoa8621002016-10-04 18:13:44 +0000903 tries_(tries),
904 handlers_(handlers) { }
David Sehr853a8e12016-09-01 13:03:50 -0700905
David Sehr7629f602016-08-07 16:01:51 -0700906 ~CodeItem() OVERRIDE { }
907
908 uint16_t RegistersSize() const { return registers_size_; }
909 uint16_t InsSize() const { return ins_size_; }
910 uint16_t OutsSize() const { return outs_size_; }
David Sehr853a8e12016-09-01 13:03:50 -0700911 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700912 DebugInfoItem* DebugInfo() const { return debug_info_; }
David Sehr7629f602016-08-07 16:01:51 -0700913 uint32_t InsnsSize() const { return insns_size_; }
914 uint16_t* Insns() const { return insns_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -0700915 TryItemVector* Tries() const { return tries_.get(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000916 CatchHandlerVector* Handlers() const { return handlers_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700917
David Sehrd1e44e22016-10-06 17:09:32 -0700918 void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); }
919 CodeFixups* GetCodeFixups() const { return fixups_.get(); }
920
David Sehr7629f602016-08-07 16:01:51 -0700921 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
922
923 private:
924 uint16_t registers_size_;
925 uint16_t ins_size_;
926 uint16_t outs_size_;
Jeff Haoa8621002016-10-04 18:13:44 +0000927 DebugInfoItem* debug_info_; // This can be nullptr.
David Sehr7629f602016-08-07 16:01:51 -0700928 uint32_t insns_size_;
929 std::unique_ptr<uint16_t[]> insns_;
Jeff Haoa8621002016-10-04 18:13:44 +0000930 std::unique_ptr<TryItemVector> tries_; // This can be nullptr.
931 std::unique_ptr<CatchHandlerVector> handlers_; // This can be nullptr.
David Sehrd1e44e22016-10-06 17:09:32 -0700932 std::unique_ptr<CodeFixups> fixups_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700933
David Sehr7629f602016-08-07 16:01:51 -0700934 DISALLOW_COPY_AND_ASSIGN(CodeItem);
935};
936
David Sehr7629f602016-08-07 16:01:51 -0700937struct PositionInfo {
938 PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { }
939
940 uint32_t address_;
941 uint32_t line_;
942};
943
David Sehr853a8e12016-09-01 13:03:50 -0700944using PositionInfoVector = std::vector<std::unique_ptr<PositionInfo>>;
945
David Sehr7629f602016-08-07 16:01:51 -0700946struct LocalInfo {
David Sehr853a8e12016-09-01 13:03:50 -0700947 LocalInfo(const char* name,
948 const char* descriptor,
949 const char* signature,
950 uint32_t start_address,
951 uint32_t end_address,
952 uint16_t reg)
953 : name_(name),
954 descriptor_(descriptor),
955 signature_(signature),
956 start_address_(start_address),
957 end_address_(end_address),
958 reg_(reg) { }
David Sehr7629f602016-08-07 16:01:51 -0700959
960 std::string name_;
961 std::string descriptor_;
962 std::string signature_;
963 uint32_t start_address_;
964 uint32_t end_address_;
965 uint16_t reg_;
966};
967
David Sehr853a8e12016-09-01 13:03:50 -0700968using LocalInfoVector = std::vector<std::unique_ptr<LocalInfo>>;
969
David Sehr7629f602016-08-07 16:01:51 -0700970class DebugInfoItem : public Item {
971 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000972 DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
973 : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
974
975 uint32_t GetDebugInfoSize() const { return debug_info_size_; }
976 uint8_t* GetDebugInfo() const { return debug_info_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700977
David Sehr853a8e12016-09-01 13:03:50 -0700978 PositionInfoVector& GetPositionInfo() { return positions_; }
979 LocalInfoVector& GetLocalInfo() { return locals_; }
David Sehr7629f602016-08-07 16:01:51 -0700980
981 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000982 uint32_t debug_info_size_;
983 std::unique_ptr<uint8_t[]> debug_info_;
984
David Sehr853a8e12016-09-01 13:03:50 -0700985 PositionInfoVector positions_;
986 LocalInfoVector locals_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700987
David Sehr7629f602016-08-07 16:01:51 -0700988 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
989};
990
Jeff Hao3ab96b42016-09-09 18:35:01 -0700991class AnnotationItem : public Item {
David Sehr853a8e12016-09-01 13:03:50 -0700992 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700993 AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation)
994 : visibility_(visibility), annotation_(annotation) { }
David Sehr853a8e12016-09-01 13:03:50 -0700995
996 uint8_t GetVisibility() const { return visibility_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700997 EncodedAnnotation* GetAnnotation() const { return annotation_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700998
999 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1000
1001 private:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001002 uint8_t visibility_;
1003 std::unique_ptr<EncodedAnnotation> annotation_;
1004
1005 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
1006};
1007
1008class AnnotationSetItem : public Item {
1009 public:
1010 explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) {
1011 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
1012 }
1013 ~AnnotationSetItem() OVERRIDE { }
1014
1015 std::vector<AnnotationItem*>* GetItems() { return items_.get(); }
1016
1017 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1018
1019 private:
1020 std::unique_ptr<std::vector<AnnotationItem*>> items_;
1021
David Sehr7629f602016-08-07 16:01:51 -07001022 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
1023};
1024
Jeff Hao3ab96b42016-09-09 18:35:01 -07001025class AnnotationSetRefList : public Item {
1026 public:
1027 explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) {
1028 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
1029 }
1030 ~AnnotationSetRefList() OVERRIDE { }
1031
1032 std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); }
1033
1034 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1035
1036 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001037 std::unique_ptr<std::vector<AnnotationSetItem*>> items_; // Elements of vector can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001038
1039 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
1040};
David Sehr853a8e12016-09-01 13:03:50 -07001041
1042class FieldAnnotation {
1043 public:
1044 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
1045 : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
1046
1047 FieldId* GetFieldId() const { return field_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001048 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001049
1050 private:
1051 FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001052 AnnotationSetItem* annotation_set_item_;
1053
David Sehr853a8e12016-09-01 13:03:50 -07001054 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
1055};
1056
1057using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
1058
1059class MethodAnnotation {
1060 public:
1061 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
1062 : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
1063
1064 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001065 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001066
1067 private:
1068 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001069 AnnotationSetItem* annotation_set_item_;
1070
David Sehr853a8e12016-09-01 13:03:50 -07001071 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
1072};
1073
1074using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
1075
1076class ParameterAnnotation {
1077 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001078 ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations)
David Sehr853a8e12016-09-01 13:03:50 -07001079 : method_id_(method_id), annotations_(annotations) { }
1080
1081 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001082 AnnotationSetRefList* GetAnnotations() { return annotations_; }
David Sehr853a8e12016-09-01 13:03:50 -07001083
1084 private:
1085 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001086 AnnotationSetRefList* annotations_;
1087
David Sehr853a8e12016-09-01 13:03:50 -07001088 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
1089};
1090
1091using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
1092
David Sehr7629f602016-08-07 16:01:51 -07001093class AnnotationsDirectoryItem : public Item {
1094 public:
David Sehr853a8e12016-09-01 13:03:50 -07001095 AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
1096 FieldAnnotationVector* field_annotations,
1097 MethodAnnotationVector* method_annotations,
1098 ParameterAnnotationVector* parameter_annotations)
1099 : class_annotation_(class_annotation),
1100 field_annotations_(field_annotations),
1101 method_annotations_(method_annotations),
1102 parameter_annotations_(parameter_annotations) { }
David Sehr7629f602016-08-07 16:01:51 -07001103
Jeff Hao3ab96b42016-09-09 18:35:01 -07001104 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; }
David Sehr853a8e12016-09-01 13:03:50 -07001105 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
1106 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
1107 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001108
1109 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1110
1111 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001112 AnnotationSetItem* class_annotation_; // This can be nullptr.
1113 std::unique_ptr<FieldAnnotationVector> field_annotations_; // This can be nullptr.
1114 std::unique_ptr<MethodAnnotationVector> method_annotations_; // This can be nullptr.
1115 std::unique_ptr<ParameterAnnotationVector> parameter_annotations_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001116
David Sehr7629f602016-08-07 16:01:51 -07001117 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
1118};
1119
Jeff Hao5daee902017-04-27 18:00:38 -07001120class CallSiteId : public IndexedItem {
1121 public:
1122 explicit CallSiteId(EncodedArrayItem* call_site_item) : call_site_item_(call_site_item) {
1123 size_ = kCallSiteIdItemSize;
1124 }
1125 ~CallSiteId() OVERRIDE { }
1126
1127 static size_t ItemSize() { return kCallSiteIdItemSize; }
1128
1129 EncodedArrayItem* CallSiteItem() const { return call_site_item_; }
1130
1131 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
1132
1133 private:
1134 EncodedArrayItem* call_site_item_;
1135
1136 DISALLOW_COPY_AND_ASSIGN(CallSiteId);
1137};
1138
1139class MethodHandleItem : public IndexedItem {
1140 public:
1141 MethodHandleItem(DexFile::MethodHandleType method_handle_type, IndexedItem* field_or_method_id)
1142 : method_handle_type_(method_handle_type),
1143 field_or_method_id_(field_or_method_id) {
1144 size_ = kMethodHandleItemSize;
1145 }
1146 ~MethodHandleItem() OVERRIDE { }
1147
1148 static size_t ItemSize() { return kMethodHandleItemSize; }
1149
1150 DexFile::MethodHandleType GetMethodHandleType() const { return method_handle_type_; }
1151 IndexedItem* GetFieldOrMethodId() const { return field_or_method_id_; }
1152
1153 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
1154
1155 private:
1156 DexFile::MethodHandleType method_handle_type_;
1157 IndexedItem* field_or_method_id_;
1158
1159 DISALLOW_COPY_AND_ASSIGN(MethodHandleItem);
1160};
1161
David Sehr7629f602016-08-07 16:01:51 -07001162// TODO(sehr): implement MapList.
1163class MapList : public Item {
1164 public:
1165 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1166
1167 private:
1168 DISALLOW_COPY_AND_ASSIGN(MapList);
1169};
1170
1171class MapItem : public Item {
1172 public:
1173 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1174
1175 private:
1176 DISALLOW_COPY_AND_ASSIGN(MapItem);
1177};
1178
David Sehr9037a3a2017-03-30 17:50:24 -07001179// Interface for building a vector of file sections for use by other clients.
1180struct DexFileSection {
1181 public:
1182 DexFileSection(const std::string& name, uint16_t type, uint32_t size, uint32_t offset)
1183 : name(name), type(type), size(size), offset(offset) { }
1184 std::string name;
1185 // The type (DexFile::MapItemType).
1186 uint16_t type;
1187 // The size (in elements, not bytes).
1188 uint32_t size;
1189 // The byte offset from the start of the file.
1190 uint32_t offset;
1191};
1192
1193enum class SortDirection {
1194 kSortAscending,
1195 kSortDescending
1196};
1197
1198std::vector<DexFileSection> GetSortedDexFileSections(dex_ir::Header* header,
1199 SortDirection direction);
1200
David Sehr7629f602016-08-07 16:01:51 -07001201} // namespace dex_ir
1202} // namespace art
1203
1204#endif // ART_DEXLAYOUT_DEX_IR_H_