blob: 183d84e15d02544d74f4235dfeaa2d4e631d034c [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Carl Shapiro1fb86202011-06-27 17:43:13 -070016
David Sehr9e734c72018-01-04 17:56:19 -080017#ifndef ART_RUNTIME_DEX_DEX_FILE_H_
18#define ART_RUNTIME_DEX_DEX_FILE_H_
Carl Shapiro1fb86202011-06-27 17:43:13 -070019
Ian Rogers700a4022014-05-19 16:49:03 -070020#include <memory>
Elliott Hughes0c424cb2011-08-26 10:16:25 -070021#include <string>
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070022#include <vector>
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070023
Andreas Gampe57943812017-12-06 21:39:13 -080024#include <android-base/logging.h>
25
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -070026#include "base/iteration_range.h"
Andreas Gampe57943812017-12-06 21:39:13 -080027#include "base/macros.h"
Ian Rogers03b6eaf2014-10-28 09:34:57 -070028#include "base/value_object.h"
Andreas Gampea5b09a62016-11-17 15:21:22 -080029#include "dex_file_types.h"
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -070030#include "dex_instruction_iterator.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070031#include "globals.h"
Jesse Wilson6bf19152011-09-29 13:12:33 -040032#include "jni.h"
Ian Rogers08f753d2012-08-24 14:35:25 -070033#include "modifiers.h"
Carl Shapiro1fb86202011-06-27 17:43:13 -070034
35namespace art {
36
Mathieu Chartier69147f12017-11-06 20:02:24 -080037class CompactDexFile;
Andreas Gampe04c6ab92017-06-08 21:49:14 -070038enum InvokeType : uint32_t;
Ian Rogers576ca0c2014-06-06 15:58:22 -070039class MemMap;
Richard Uhler07b3c232015-03-31 15:57:54 -070040class OatDexFile;
Ian Rogersd91d6d62013-09-25 20:26:14 -070041class Signature;
Mathieu Chartier69147f12017-11-06 20:02:24 -080042class StandardDexFile;
Ian Rogersfc0e94b2013-09-23 23:51:32 -070043class StringPiece;
Brian Carlstroma6cc8932012-01-04 14:44:07 -080044class ZipArchive;
45
David Sehr733bd4d2017-10-26 10:39:15 -070046// Some instances of DexFile own the storage referred to by DexFile. Clients who create
47// such management do so by subclassing Container.
48class DexFileContainer {
49 public:
50 DexFileContainer() { }
51 virtual ~DexFileContainer() { }
52 virtual int GetPermissions() = 0;
53 virtual bool IsReadOnly() = 0;
54 virtual bool EnableWrite() = 0;
55 virtual bool DisableWrite() = 0;
56
57 private:
58 DISALLOW_COPY_AND_ASSIGN(DexFileContainer);
59};
60
Mathieu Chartier7b074bf2017-09-25 16:22:36 -070061// Dex file is the API that exposes native dex files (ordinary dex files) and CompactDex.
62// Originally, the dex file format used by ART was mostly the same as APKs. The only change was
63// quickened opcodes and layout optimizations.
Mathieu Chartier79c87da2017-10-10 11:54:29 -070064// Since ART needs to support both native dex files and CompactDex files, the DexFile interface
65// provides an abstraction to facilitate this.
Brian Carlstromf615a612011-07-23 12:50:34 -070066class DexFile {
Carl Shapiro1fb86202011-06-27 17:43:13 -070067 public:
Mathieu Chartier7b074bf2017-09-25 16:22:36 -070068 // Number of bytes in the dex file magic.
69 static constexpr size_t kDexMagicSize = 4;
70 static constexpr size_t kDexVersionLen = 4;
71
Roland Levillain621b5ea2016-05-18 11:41:33 +010072 // First Dex format version enforcing class definition ordering rules.
73 static const uint32_t kClassDefinitionOrderEnforcedVersion = 37;
74
Ian Rogers13735952014-10-08 12:43:28 -070075 static constexpr size_t kSha1DigestSize = 20;
76 static constexpr uint32_t kDexEndianConstant = 0x12345678;
Carl Shapiro80d4dde2011-06-28 16:24:07 -070077
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070078 // The value of an invalid index.
Ian Rogers0571d352011-11-03 19:51:38 -070079 static const uint16_t kDexNoIndex16 = 0xFFFF;
Carl Shapiro1fb86202011-06-27 17:43:13 -070080
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070081 // Raw header_item.
82 struct Header {
Mathieu Chartierf95a75e2017-11-03 15:25:52 -070083 uint8_t magic_[8] = {};
84 uint32_t checksum_ = 0; // See also location_checksum_
85 uint8_t signature_[kSha1DigestSize] = {};
86 uint32_t file_size_ = 0; // size of entire file
87 uint32_t header_size_ = 0; // offset to start of next section
88 uint32_t endian_tag_ = 0;
89 uint32_t link_size_ = 0; // unused
90 uint32_t link_off_ = 0; // unused
91 uint32_t map_off_ = 0; // unused
92 uint32_t string_ids_size_ = 0; // number of StringIds
93 uint32_t string_ids_off_ = 0; // file offset of StringIds array
94 uint32_t type_ids_size_ = 0; // number of TypeIds, we don't support more than 65535
95 uint32_t type_ids_off_ = 0; // file offset of TypeIds array
96 uint32_t proto_ids_size_ = 0; // number of ProtoIds, we don't support more than 65535
97 uint32_t proto_ids_off_ = 0; // file offset of ProtoIds array
98 uint32_t field_ids_size_ = 0; // number of FieldIds
99 uint32_t field_ids_off_ = 0; // file offset of FieldIds array
100 uint32_t method_ids_size_ = 0; // number of MethodIds
101 uint32_t method_ids_off_ = 0; // file offset of MethodIds array
102 uint32_t class_defs_size_ = 0; // number of ClassDefs
103 uint32_t class_defs_off_ = 0; // file offset of ClassDef array
104 uint32_t data_size_ = 0; // size of data section
105 uint32_t data_off_ = 0; // file offset of data section
Elliott Hughesa21039c2012-06-21 12:09:25 -0700106
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700107 // Decode the dex magic version
108 uint32_t GetVersion() const;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700109 };
Carl Shapiro1fb86202011-06-27 17:43:13 -0700110
jeffhao10037c82012-01-23 15:06:23 -0800111 // Map item type codes.
Orion Hodson12f4ff42017-01-13 16:43:12 +0000112 enum MapItemType : uint16_t { // private
jeffhao10037c82012-01-23 15:06:23 -0800113 kDexTypeHeaderItem = 0x0000,
114 kDexTypeStringIdItem = 0x0001,
115 kDexTypeTypeIdItem = 0x0002,
116 kDexTypeProtoIdItem = 0x0003,
117 kDexTypeFieldIdItem = 0x0004,
118 kDexTypeMethodIdItem = 0x0005,
119 kDexTypeClassDefItem = 0x0006,
Orion Hodson12f4ff42017-01-13 16:43:12 +0000120 kDexTypeCallSiteIdItem = 0x0007,
121 kDexTypeMethodHandleItem = 0x0008,
jeffhao10037c82012-01-23 15:06:23 -0800122 kDexTypeMapList = 0x1000,
123 kDexTypeTypeList = 0x1001,
124 kDexTypeAnnotationSetRefList = 0x1002,
125 kDexTypeAnnotationSetItem = 0x1003,
126 kDexTypeClassDataItem = 0x2000,
127 kDexTypeCodeItem = 0x2001,
128 kDexTypeStringDataItem = 0x2002,
129 kDexTypeDebugInfoItem = 0x2003,
130 kDexTypeAnnotationItem = 0x2004,
131 kDexTypeEncodedArrayItem = 0x2005,
132 kDexTypeAnnotationsDirectoryItem = 0x2006,
133 };
134
135 struct MapItem {
136 uint16_t type_;
137 uint16_t unused_;
138 uint32_t size_;
139 uint32_t offset_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700140
jeffhao10037c82012-01-23 15:06:23 -0800141 private:
142 DISALLOW_COPY_AND_ASSIGN(MapItem);
143 };
144
145 struct MapList {
146 uint32_t size_;
147 MapItem list_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700148
jeffhao10037c82012-01-23 15:06:23 -0800149 private:
150 DISALLOW_COPY_AND_ASSIGN(MapList);
151 };
152
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700153 // Raw string_id_item.
154 struct StringId {
155 uint32_t string_data_off_; // offset in bytes from the base address
Elliott Hughesa21039c2012-06-21 12:09:25 -0700156
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700157 private:
158 DISALLOW_COPY_AND_ASSIGN(StringId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700159 };
160
161 // Raw type_id_item.
162 struct TypeId {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800163 dex::StringIndex descriptor_idx_; // index into string_ids
Elliott Hughesa21039c2012-06-21 12:09:25 -0700164
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700165 private:
166 DISALLOW_COPY_AND_ASSIGN(TypeId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700167 };
168
169 // Raw field_id_item.
170 struct FieldId {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800171 dex::TypeIndex class_idx_; // index into type_ids_ array for defining class
172 dex::TypeIndex type_idx_; // index into type_ids_ array for field type
173 dex::StringIndex name_idx_; // index into string_ids_ array for field name
Elliott Hughesa21039c2012-06-21 12:09:25 -0700174
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700175 private:
176 DISALLOW_COPY_AND_ASSIGN(FieldId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700177 };
178
Andreas Gampea5b09a62016-11-17 15:21:22 -0800179 // Raw proto_id_item.
180 struct ProtoId {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800181 dex::StringIndex shorty_idx_; // index into string_ids array for shorty descriptor
Andreas Gampea5b09a62016-11-17 15:21:22 -0800182 dex::TypeIndex return_type_idx_; // index into type_ids array for return type
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800183 uint16_t pad_; // padding = 0
184 uint32_t parameters_off_; // file offset to type_list for parameter types
Andreas Gampea5b09a62016-11-17 15:21:22 -0800185
186 private:
187 DISALLOW_COPY_AND_ASSIGN(ProtoId);
188 };
189
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700190 // Raw method_id_item.
191 struct MethodId {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800192 dex::TypeIndex class_idx_; // index into type_ids_ array for defining class
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800193 uint16_t proto_idx_; // index into proto_ids_ array for method prototype
194 dex::StringIndex name_idx_; // index into string_ids_ array for method name
Elliott Hughesa21039c2012-06-21 12:09:25 -0700195
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700196 private:
197 DISALLOW_COPY_AND_ASSIGN(MethodId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700198 };
199
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700200 // Raw class_def_item.
201 struct ClassDef {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800202 dex::TypeIndex class_idx_; // index into type_ids_ array for this class
Ian Rogers0571d352011-11-03 19:51:38 -0700203 uint16_t pad1_; // padding = 0
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700204 uint32_t access_flags_;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800205 dex::TypeIndex superclass_idx_; // index into type_ids_ array for superclass
Ian Rogers0571d352011-11-03 19:51:38 -0700206 uint16_t pad2_; // padding = 0
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700207 uint32_t interfaces_off_; // file offset to TypeList
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800208 dex::StringIndex source_file_idx_; // index into string_ids_ for source file name
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700209 uint32_t annotations_off_; // file offset to annotations_directory_item
210 uint32_t class_data_off_; // file offset to class_data_item
211 uint32_t static_values_off_; // file offset to EncodedArray
Elliott Hughesa21039c2012-06-21 12:09:25 -0700212
Andreas Gampe51829322014-08-25 15:05:04 -0700213 // Returns the valid access flags, that is, Java modifier bits relevant to the ClassDef type
214 // (class or interface). These are all in the lower 16b and do not contain runtime flags.
215 uint32_t GetJavaAccessFlags() const {
216 // Make sure that none of our runtime-only flags are set.
Andreas Gampe575e78c2014-11-03 23:41:03 -0800217 static_assert((kAccValidClassFlags & kAccJavaFlagsMask) == kAccValidClassFlags,
218 "Valid class flags not a subset of Java flags");
219 static_assert((kAccValidInterfaceFlags & kAccJavaFlagsMask) == kAccValidInterfaceFlags,
220 "Valid interface flags not a subset of Java flags");
Andreas Gampe51829322014-08-25 15:05:04 -0700221
222 if ((access_flags_ & kAccInterface) != 0) {
223 // Interface.
224 return access_flags_ & kAccValidInterfaceFlags;
225 } else {
226 // Class.
227 return access_flags_ & kAccValidClassFlags;
228 }
229 }
230
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700231 private:
232 DISALLOW_COPY_AND_ASSIGN(ClassDef);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700233 };
234
235 // Raw type_item.
236 struct TypeItem {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800237 dex::TypeIndex type_idx_; // index into type_ids section
Elliott Hughesa21039c2012-06-21 12:09:25 -0700238
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700239 private:
240 DISALLOW_COPY_AND_ASSIGN(TypeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700241 };
242
243 // Raw type_list.
244 class TypeList {
245 public:
246 uint32_t Size() const {
247 return size_;
248 }
249
250 const TypeItem& GetTypeItem(uint32_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200251 DCHECK_LT(idx, this->size_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700252 return this->list_[idx];
253 }
254
Andreas Gampe31a7a0c2014-08-29 16:07:49 -0700255 // Size in bytes of the part of the list that is common.
256 static constexpr size_t GetHeaderSize() {
257 return 4U;
258 }
259
260 // Size in bytes of the whole type list including all the stored elements.
261 static constexpr size_t GetListSize(size_t count) {
262 return GetHeaderSize() + sizeof(TypeItem) * count;
263 }
264
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700265 private:
266 uint32_t size_; // size of the list, in entries
267 TypeItem list_[1]; // elements of the list
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700268 DISALLOW_COPY_AND_ASSIGN(TypeList);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700269 };
270
Orion Hodson12f4ff42017-01-13 16:43:12 +0000271 // MethodHandle Types
272 enum class MethodHandleType : uint16_t { // private
Orion Hodsonc069a302017-01-18 09:23:12 +0000273 kStaticPut = 0x0000, // a setter for a given static field.
274 kStaticGet = 0x0001, // a getter for a given static field.
275 kInstancePut = 0x0002, // a setter for a given instance field.
276 kInstanceGet = 0x0003, // a getter for a given instance field.
277 kInvokeStatic = 0x0004, // an invoker for a given static method.
Orion Hodson12f4ff42017-01-13 16:43:12 +0000278 kInvokeInstance = 0x0005, // invoke_instance : an invoker for a given instance method. This
279 // can be any non-static method on any class (or interface) except
280 // for “<init>”.
281 kInvokeConstructor = 0x0006, // an invoker for a given constructor.
Orion Hodson631827d2017-04-10 14:53:47 +0100282 kInvokeDirect = 0x0007, // an invoker for a direct (special) method.
283 kInvokeInterface = 0x0008, // an invoker for an interface method.
284 kLast = kInvokeInterface
Orion Hodson12f4ff42017-01-13 16:43:12 +0000285 };
286
287 // raw method_handle_item
288 struct MethodHandleItem {
289 uint16_t method_handle_type_;
Orion Hodsonc069a302017-01-18 09:23:12 +0000290 uint16_t reserved1_; // Reserved for future use.
291 uint16_t field_or_method_idx_; // Field index for accessors, method index otherwise.
292 uint16_t reserved2_; // Reserved for future use.
Orion Hodson12f4ff42017-01-13 16:43:12 +0000293 private:
294 DISALLOW_COPY_AND_ASSIGN(MethodHandleItem);
295 };
296
297 // raw call_site_id_item
298 struct CallSiteIdItem {
299 uint32_t data_off_; // Offset into data section pointing to encoded array items.
300 private:
301 DISALLOW_COPY_AND_ASSIGN(CallSiteIdItem);
302 };
303
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800304 // Base code_item, compact dex and standard dex have different code item layouts.
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700305 struct CodeItem {
Mathieu Chartier6238c832018-01-04 09:55:13 -0800306 protected:
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800307 CodeItem() = default;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700308
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700309 private:
310 DISALLOW_COPY_AND_ASSIGN(CodeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700311 };
312
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700313 // Raw try_item.
314 struct TryItem {
315 uint32_t start_addr_;
316 uint16_t insn_count_;
317 uint16_t handler_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700318
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700319 private:
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800320 TryItem() = default;
321 friend class DexWriter;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700322 DISALLOW_COPY_AND_ASSIGN(TryItem);
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700323 };
324
jeffhao10037c82012-01-23 15:06:23 -0800325 // Annotation constants.
326 enum {
327 kDexVisibilityBuild = 0x00, /* annotation visibility */
328 kDexVisibilityRuntime = 0x01,
329 kDexVisibilitySystem = 0x02,
330
331 kDexAnnotationByte = 0x00,
332 kDexAnnotationShort = 0x02,
333 kDexAnnotationChar = 0x03,
334 kDexAnnotationInt = 0x04,
335 kDexAnnotationLong = 0x06,
336 kDexAnnotationFloat = 0x10,
337 kDexAnnotationDouble = 0x11,
Orion Hodson12f4ff42017-01-13 16:43:12 +0000338 kDexAnnotationMethodType = 0x15,
339 kDexAnnotationMethodHandle = 0x16,
jeffhao10037c82012-01-23 15:06:23 -0800340 kDexAnnotationString = 0x17,
341 kDexAnnotationType = 0x18,
342 kDexAnnotationField = 0x19,
343 kDexAnnotationMethod = 0x1a,
344 kDexAnnotationEnum = 0x1b,
345 kDexAnnotationArray = 0x1c,
346 kDexAnnotationAnnotation = 0x1d,
347 kDexAnnotationNull = 0x1e,
348 kDexAnnotationBoolean = 0x1f,
349
350 kDexAnnotationValueTypeMask = 0x1f, /* low 5 bits */
351 kDexAnnotationValueArgShift = 5,
352 };
353
354 struct AnnotationsDirectoryItem {
355 uint32_t class_annotations_off_;
356 uint32_t fields_size_;
357 uint32_t methods_size_;
358 uint32_t parameters_size_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700359
jeffhao10037c82012-01-23 15:06:23 -0800360 private:
361 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
362 };
363
364 struct FieldAnnotationsItem {
365 uint32_t field_idx_;
366 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700367
jeffhao10037c82012-01-23 15:06:23 -0800368 private:
369 DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem);
370 };
371
372 struct MethodAnnotationsItem {
373 uint32_t method_idx_;
374 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700375
jeffhao10037c82012-01-23 15:06:23 -0800376 private:
377 DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem);
378 };
379
380 struct ParameterAnnotationsItem {
381 uint32_t method_idx_;
382 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700383
jeffhao10037c82012-01-23 15:06:23 -0800384 private:
385 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem);
386 };
387
388 struct AnnotationSetRefItem {
389 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700390
jeffhao10037c82012-01-23 15:06:23 -0800391 private:
392 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem);
393 };
394
395 struct AnnotationSetRefList {
396 uint32_t size_;
397 AnnotationSetRefItem list_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700398
jeffhao10037c82012-01-23 15:06:23 -0800399 private:
400 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
401 };
402
403 struct AnnotationSetItem {
404 uint32_t size_;
405 uint32_t entries_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700406
jeffhao10037c82012-01-23 15:06:23 -0800407 private:
408 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
409 };
410
411 struct AnnotationItem {
412 uint8_t visibility_;
413 uint8_t annotation_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700414
jeffhao10037c82012-01-23 15:06:23 -0800415 private:
416 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
417 };
418
Jeff Hao13e748b2015-08-25 20:44:19 +0000419 enum AnnotationResultStyle { // private
420 kAllObjects,
421 kPrimitivesOrObjects,
422 kAllRaw
423 };
424
David Sehr9323e6e2016-09-13 08:58:35 -0700425 struct AnnotationValue;
426
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700427 // Closes a .dex file.
Brian Carlstromf615a612011-07-23 12:50:34 -0700428 virtual ~DexFile();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700429
Brian Carlstroma663ea52011-08-19 23:33:41 -0700430 const std::string& GetLocation() const {
431 return location_;
432 }
433
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800434 // For DexFiles directly from .dex files, this is the checksum from the DexFile::Header.
435 // For DexFiles opened from a zip files, this will be the ZipEntry CRC32 of classes.dex.
436 uint32_t GetLocationChecksum() const {
437 return location_checksum_;
438 }
439
Brian Carlstroma663ea52011-08-19 23:33:41 -0700440 const Header& GetHeader() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700441 DCHECK(header_ != nullptr) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700442 return *header_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700443 }
444
Ian Rogers0571d352011-11-03 19:51:38 -0700445 // Decode the dex magic version
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800446 uint32_t GetDexVersion() const {
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700447 return GetHeader().GetVersion();
448 }
Ian Rogersd81871c2011-10-03 13:57:23 -0700449
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800450 // Returns true if the byte string points to the magic value.
Mathieu Chartier7b074bf2017-09-25 16:22:36 -0700451 virtual bool IsMagicValid() const = 0;
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800452
453 // Returns true if the byte string after the magic is the correct value.
Mathieu Chartier7b074bf2017-09-25 16:22:36 -0700454 virtual bool IsVersionValid() const = 0;
455
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800456 // Returns true if the dex file supports default methods.
457 virtual bool SupportsDefaultMethods() const = 0;
458
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700459 // Returns the number of string identifiers in the .dex file.
460 size_t NumStringIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700461 DCHECK(header_ != nullptr) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700462 return header_->string_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700463 }
464
Ian Rogers0571d352011-11-03 19:51:38 -0700465 // Returns the StringId at the specified index.
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800466 const StringId& GetStringId(dex::StringIndex idx) const {
467 DCHECK_LT(idx.index_, NumStringIds()) << GetLocation();
468 return string_ids_[idx.index_];
Ian Rogers0571d352011-11-03 19:51:38 -0700469 }
470
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800471 dex::StringIndex GetIndexForStringId(const StringId& string_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800472 CHECK_GE(&string_id, string_ids_) << GetLocation();
473 CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800474 return dex::StringIndex(&string_id - string_ids_);
Ian Rogers0571d352011-11-03 19:51:38 -0700475 }
476
477 int32_t GetStringLength(const StringId& string_id) const;
478
Ian Rogersdfb325e2013-10-30 01:00:44 -0700479 // Returns a pointer to the UTF-8 string data referred to by the given string_id as well as the
480 // length of the string when decoded as a UTF-16 string. Note the UTF-16 length is not the same
481 // as the string length of the string data.
482 const char* GetStringDataAndUtf16Length(const StringId& string_id, uint32_t* utf16_length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700483
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100484 const char* GetStringData(const StringId& string_id) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700485
Ian Rogersdfb325e2013-10-30 01:00:44 -0700486 // Index version of GetStringDataAndUtf16Length.
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800487 const char* StringDataAndUtf16LengthByIdx(dex::StringIndex idx, uint32_t* utf16_length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700488
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800489 const char* StringDataByIdx(dex::StringIndex idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700490
Ian Rogers637c65b2013-05-31 11:46:00 -0700491 // Looks up a string id for a given modified utf8 string.
492 const StringId* FindStringId(const char* string) const;
493
Artem Udovichenkod9786b02015-10-14 16:36:55 +0300494 const TypeId* FindTypeId(const char* string) const;
495
Ian Rogers637c65b2013-05-31 11:46:00 -0700496 // Looks up a string id for a given utf16 string.
Vladimir Markoa48aef42014-12-03 17:53:53 +0000497 const StringId* FindStringId(const uint16_t* string, size_t length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700498
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700499 // Returns the number of type identifiers in the .dex file.
Ian Rogers68b56852014-08-29 20:19:11 -0700500 uint32_t NumTypeIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700501 DCHECK(header_ != nullptr) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700502 return header_->type_ids_size_;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700503 }
504
Calin Juravle08556882017-05-26 16:40:45 -0700505 bool IsTypeIndexValid(dex::TypeIndex idx) const {
506 return idx.IsValid() && idx.index_ < NumTypeIds();
507 }
508
Ian Rogers0571d352011-11-03 19:51:38 -0700509 // Returns the TypeId at the specified index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800510 const TypeId& GetTypeId(dex::TypeIndex idx) const {
511 DCHECK_LT(idx.index_, NumTypeIds()) << GetLocation();
512 return type_ids_[idx.index_];
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700513 }
514
Andreas Gampea5b09a62016-11-17 15:21:22 -0800515 dex::TypeIndex GetIndexForTypeId(const TypeId& type_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800516 CHECK_GE(&type_id, type_ids_) << GetLocation();
517 CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700518 size_t result = &type_id - type_ids_;
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800519 DCHECK_LT(result, 65536U) << GetLocation();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800520 return dex::TypeIndex(static_cast<uint16_t>(result));
Ian Rogers0571d352011-11-03 19:51:38 -0700521 }
522
523 // Get the descriptor string associated with a given type index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800524 const char* StringByTypeIdx(dex::TypeIndex idx, uint32_t* unicode_length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700525
Andreas Gampea5b09a62016-11-17 15:21:22 -0800526 const char* StringByTypeIdx(dex::TypeIndex idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700527
528 // Returns the type descriptor string of a type id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100529 const char* GetTypeDescriptor(const TypeId& type_id) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700530
531 // Looks up a type for the given string index
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800532 const TypeId* FindTypeId(dex::StringIndex string_idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700533
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700534 // Returns the number of field identifiers in the .dex file.
535 size_t NumFieldIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700536 DCHECK(header_ != nullptr) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700537 return header_->field_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700538 }
539
Ian Rogers0571d352011-11-03 19:51:38 -0700540 // Returns the FieldId at the specified index.
541 const FieldId& GetFieldId(uint32_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200542 DCHECK_LT(idx, NumFieldIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700543 return field_ids_[idx];
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700544 }
545
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800546 uint32_t GetIndexForFieldId(const FieldId& field_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800547 CHECK_GE(&field_id, field_ids_) << GetLocation();
548 CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation();
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800549 return &field_id - field_ids_;
550 }
551
552 // Looks up a field by its declaring class, name and type
553 const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass,
554 const DexFile::StringId& name,
555 const DexFile::TypeId& type) const;
556
Alex Light9c20a142016-08-23 15:05:12 -0700557 uint32_t FindCodeItemOffset(const DexFile::ClassDef& class_def,
558 uint32_t dex_method_idx) const;
559
Mathieu Chartier6238c832018-01-04 09:55:13 -0800560 virtual uint32_t GetCodeItemSize(const DexFile::CodeItem& disk_code_item) const = 0;
Bharadwaj Kalandhabhatta043c9082017-06-06 17:14:12 -0700561
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700562 // Returns the declaring class descriptor string of a field id.
563 const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const {
Brian Carlstromb9edb842011-08-28 16:31:06 -0700564 const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_);
565 return GetTypeDescriptor(type_id);
566 }
567
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700568 // Returns the class descriptor string of a field id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100569 const char* GetFieldTypeDescriptor(const FieldId& field_id) const;
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700570
Brian Carlstromb9edb842011-08-28 16:31:06 -0700571 // Returns the name of a field id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100572 const char* GetFieldName(const FieldId& field_id) const;
Brian Carlstromb9edb842011-08-28 16:31:06 -0700573
Ian Rogers0571d352011-11-03 19:51:38 -0700574 // Returns the number of method identifiers in the .dex file.
575 size_t NumMethodIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700576 DCHECK(header_ != nullptr) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700577 return header_->method_ids_size_;
578 }
579
580 // Returns the MethodId at the specified index.
581 const MethodId& GetMethodId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700582 DCHECK_LT(idx, NumMethodIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700583 return method_ids_[idx];
584 }
585
586 uint32_t GetIndexForMethodId(const MethodId& method_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800587 CHECK_GE(&method_id, method_ids_) << GetLocation();
588 CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700589 return &method_id - method_ids_;
590 }
591
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800592 // Looks up a method by its declaring class, name and proto_id
593 const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass,
594 const DexFile::StringId& name,
Ian Rogers0571d352011-11-03 19:51:38 -0700595 const DexFile::ProtoId& signature) const;
596
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700597 // Returns the declaring class descriptor string of a method id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100598 const char* GetMethodDeclaringClassDescriptor(const MethodId& method_id) const;
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700599
jeffhao98eacac2011-09-14 16:11:53 -0700600 // Returns the prototype of a method id.
Brian Carlstromaded5f72011-10-07 17:15:04 -0700601 const ProtoId& GetMethodPrototype(const MethodId& method_id) const {
602 return GetProtoId(method_id.proto_idx_);
603 }
604
Ian Rogersd91d6d62013-09-25 20:26:14 -0700605 // Returns a representation of the signature of a method id.
606 const Signature GetMethodSignature(const MethodId& method_id) const;
jeffhao98eacac2011-09-14 16:11:53 -0700607
Orion Hodsonb34bb192016-10-18 17:02:58 +0100608 // Returns a representation of the signature of a proto id.
609 const Signature GetProtoSignature(const ProtoId& proto_id) const;
610
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700611 // Returns the name of a method id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100612 const char* GetMethodName(const MethodId& method_id) const;
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700613
Calin Juravle68ad6492015-08-18 17:08:12 +0100614 // Returns the shorty of a method by its index.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100615 const char* GetMethodShorty(uint32_t idx) const;
Calin Juravle68ad6492015-08-18 17:08:12 +0100616
Ian Rogers0571d352011-11-03 19:51:38 -0700617 // Returns the shorty of a method id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100618 const char* GetMethodShorty(const MethodId& method_id) const;
619 const char* GetMethodShorty(const MethodId& method_id, uint32_t* length) const;
620
Ian Rogers0571d352011-11-03 19:51:38 -0700621 // Returns the number of class definitions in the .dex file.
Ian Rogers68b56852014-08-29 20:19:11 -0700622 uint32_t NumClassDefs() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700623 DCHECK(header_ != nullptr) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700624 return header_->class_defs_size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700625 }
626
627 // Returns the ClassDef at the specified index.
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700628 const ClassDef& GetClassDef(uint16_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200629 DCHECK_LT(idx, NumClassDefs()) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700630 return class_defs_[idx];
631 }
632
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700633 uint16_t GetIndexForClassDef(const ClassDef& class_def) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800634 CHECK_GE(&class_def, class_defs_) << GetLocation();
635 CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700636 return &class_def - class_defs_;
637 }
638
639 // Returns the class descriptor string of a class definition.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100640 const char* GetClassDescriptor(const ClassDef& class_def) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700641
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700642 // Looks up a class definition by its type index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800643 const ClassDef* FindClassDef(dex::TypeIndex type_idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700644
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700645 const TypeList* GetInterfacesList(const ClassDef& class_def) const {
646 if (class_def.interfaces_off_ == 0) {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700647 return nullptr;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700648 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700649 const uint8_t* addr = begin_ + class_def.interfaces_off_;
650 return reinterpret_cast<const TypeList*>(addr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700651 }
652
Orion Hodson12f4ff42017-01-13 16:43:12 +0000653 uint32_t NumMethodHandles() const {
654 return num_method_handles_;
655 }
656
Orion Hodsonc069a302017-01-18 09:23:12 +0000657 const MethodHandleItem& GetMethodHandle(uint32_t idx) const {
658 CHECK_LT(idx, NumMethodHandles());
659 return method_handles_[idx];
660 }
661
662 uint32_t NumCallSiteIds() const {
663 return num_call_site_ids_;
664 }
665
666 const CallSiteIdItem& GetCallSiteId(uint32_t idx) const {
667 CHECK_LT(idx, NumCallSiteIds());
668 return call_site_ids_[idx];
669 }
670
Ian Rogers0571d352011-11-03 19:51:38 -0700671 // Returns a pointer to the raw memory mapped class_data_item
Ian Rogers13735952014-10-08 12:43:28 -0700672 const uint8_t* GetClassData(const ClassDef& class_def) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700673 return (class_def.class_data_off_ == 0) ? nullptr : begin_ + class_def.class_data_off_;
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700674 }
675
Ian Rogers0571d352011-11-03 19:51:38 -0700676 //
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800677 const CodeItem* GetCodeItem(const uint32_t code_off) const {
Alex Light9139e002015-10-09 15:59:48 -0700678 DCHECK_LT(code_off, size_) << "Code item offset larger then maximum allowed offset";
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800679 if (code_off == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700680 return nullptr; // native or abstract method
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700681 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700682 const uint8_t* addr = begin_ + code_off;
683 return reinterpret_cast<const CodeItem*>(addr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700684 }
685
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100686 const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700687
688 // Returns the number of prototype identifiers in the .dex file.
689 size_t NumProtoIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700690 DCHECK(header_ != nullptr) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700691 return header_->proto_ids_size_;
692 }
693
694 // Returns the ProtoId at the specified index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800695 const ProtoId& GetProtoId(uint16_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700696 DCHECK_LT(idx, NumProtoIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700697 return proto_ids_[idx];
698 }
699
700 uint16_t GetIndexForProtoId(const ProtoId& proto_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800701 CHECK_GE(&proto_id, proto_ids_) << GetLocation();
702 CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700703 return &proto_id - proto_ids_;
704 }
705
706 // Looks up a proto id for a given return type and signature type list
Andreas Gampea5b09a62016-11-17 15:21:22 -0800707 const ProtoId* FindProtoId(dex::TypeIndex return_type_idx,
708 const dex::TypeIndex* signature_type_idxs,
709 uint32_t signature_length) const;
710 const ProtoId* FindProtoId(dex::TypeIndex return_type_idx,
711 const std::vector<dex::TypeIndex>& signature_type_idxs) const {
Vladimir Marko5c96e6b2013-11-14 15:34:17 +0000712 return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size());
713 }
Ian Rogers0571d352011-11-03 19:51:38 -0700714
715 // Given a signature place the type ids into the given vector, returns true on success
Andreas Gampea5b09a62016-11-17 15:21:22 -0800716 bool CreateTypeList(const StringPiece& signature,
717 dex::TypeIndex* return_type_idx,
718 std::vector<dex::TypeIndex>* param_type_idxs) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700719
Ian Rogersd91d6d62013-09-25 20:26:14 -0700720 // Create a Signature from the given string signature or return Signature::NoSignature if not
721 // possible.
722 const Signature CreateSignature(const StringPiece& signature) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700723
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700724 // Returns the short form method descriptor for the given prototype.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100725 const char* GetShorty(uint32_t proto_idx) const;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700726
727 const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700728 return (proto_id.parameters_off_ == 0)
729 ? nullptr
730 : reinterpret_cast<const TypeList*>(begin_ + proto_id.parameters_off_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700731 }
732
Ian Rogers13735952014-10-08 12:43:28 -0700733 const uint8_t* GetEncodedStaticFieldValuesArray(const ClassDef& class_def) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700734 return (class_def.static_values_off_ == 0) ? 0 : begin_ + class_def.static_values_off_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700735 }
736
Orion Hodson12f4ff42017-01-13 16:43:12 +0000737 const uint8_t* GetCallSiteEncodedValuesArray(const CallSiteIdItem& call_site_id) const {
738 return begin_ + call_site_id.data_off_;
739 }
740
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800741 static const TryItem* GetTryItems(const DexInstructionIterator& code_item_end, uint32_t offset);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700742
743 // Get the base of the encoded data for the given DexCode.
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800744 static const uint8_t* GetCatchHandlerData(const DexInstructionIterator& code_item_end,
745 uint32_t tries_size,
Mathieu Chartier6238c832018-01-04 09:55:13 -0800746 uint32_t offset);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700747
Ian Rogersdbbc99d2013-04-18 16:51:54 -0700748 // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800749 static int32_t FindTryItem(const TryItem* try_items, uint32_t tries_size, uint32_t address);
Ian Rogersdbbc99d2013-04-18 16:51:54 -0700750
Shih-wei Liao195487c2011-08-20 13:29:04 -0700751 // Get the pointer to the start of the debugging data
Nicolas Geoffray58cc1cb2017-11-20 13:27:29 +0000752 const uint8_t* GetDebugInfoStream(uint32_t debug_info_off) const {
David Srbecky68529422015-07-07 19:13:29 +0100753 // Check that the offset is in bounds.
754 // Note that although the specification says that 0 should be used if there
755 // is no debug information, some applications incorrectly use 0xFFFFFFFF.
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700756 return (debug_info_off == 0 || debug_info_off >= size_) ? nullptr : begin_ + debug_info_off;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700757 }
758
David Srbeckyb06e28e2015-12-10 13:15:00 +0000759 struct PositionInfo {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700760 PositionInfo() = default;
David Srbeckyb06e28e2015-12-10 13:15:00 +0000761
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700762 uint32_t address_ = 0; // In 16-bit code units.
763 uint32_t line_ = 0; // Source code line number starting at 1.
764 const char* source_file_ = nullptr; // nullptr if the file from ClassDef still applies.
765 bool prologue_end_ = false;
766 bool epilogue_begin_ = false;
David Srbeckyb06e28e2015-12-10 13:15:00 +0000767 };
768
David Srbeckyb06e28e2015-12-10 13:15:00 +0000769 struct LocalInfo {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700770 LocalInfo() = default;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700771
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700772 const char* name_ = nullptr; // E.g., list. It can be nullptr if unknown.
773 const char* descriptor_ = nullptr; // E.g., Ljava/util/LinkedList;
774 const char* signature_ = nullptr; // E.g., java.util.LinkedList<java.lang.Integer>
775 uint32_t start_address_ = 0; // PC location where the local is first defined.
776 uint32_t end_address_ = 0; // PC location where the local is no longer defined.
777 uint16_t reg_ = 0; // Dex register which stores the values.
778 bool is_live_ = false; // Is the local defined and live.
David Srbeckyb06e28e2015-12-10 13:15:00 +0000779 };
780
781 // Callback for "new locals table entry".
782 typedef void (*DexDebugNewLocalCb)(void* context, const LocalInfo& entry);
783
784 static bool LineNumForPcCb(void* context, const PositionInfo& entry);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700785
Jeff Hao13e748b2015-08-25 20:44:19 +0000786 const AnnotationsDirectoryItem* GetAnnotationsDirectory(const ClassDef& class_def) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700787 return (class_def.annotations_off_ == 0)
788 ? nullptr
789 : reinterpret_cast<const AnnotationsDirectoryItem*>(begin_ + class_def.annotations_off_);
Jeff Hao13e748b2015-08-25 20:44:19 +0000790 }
791
792 const AnnotationSetItem* GetClassAnnotationSet(const AnnotationsDirectoryItem* anno_dir) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700793 return (anno_dir->class_annotations_off_ == 0)
794 ? nullptr
795 : reinterpret_cast<const AnnotationSetItem*>(begin_ + anno_dir->class_annotations_off_);
Jeff Hao13e748b2015-08-25 20:44:19 +0000796 }
797
798 const FieldAnnotationsItem* GetFieldAnnotations(const AnnotationsDirectoryItem* anno_dir) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700799 return (anno_dir->fields_size_ == 0)
800 ? nullptr
801 : reinterpret_cast<const FieldAnnotationsItem*>(&anno_dir[1]);
Jeff Hao13e748b2015-08-25 20:44:19 +0000802 }
803
804 const MethodAnnotationsItem* GetMethodAnnotations(const AnnotationsDirectoryItem* anno_dir)
805 const {
806 if (anno_dir->methods_size_ == 0) {
807 return nullptr;
Jeff Hao13e748b2015-08-25 20:44:19 +0000808 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700809 // Skip past the header and field annotations.
810 const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
811 addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
812 return reinterpret_cast<const MethodAnnotationsItem*>(addr);
Jeff Hao13e748b2015-08-25 20:44:19 +0000813 }
814
815 const ParameterAnnotationsItem* GetParameterAnnotations(const AnnotationsDirectoryItem* anno_dir)
816 const {
817 if (anno_dir->parameters_size_ == 0) {
818 return nullptr;
Jeff Hao13e748b2015-08-25 20:44:19 +0000819 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700820 // Skip past the header, field annotations, and method annotations.
821 const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
822 addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
823 addr += anno_dir->methods_size_ * sizeof(MethodAnnotationsItem);
824 return reinterpret_cast<const ParameterAnnotationsItem*>(addr);
Jeff Hao13e748b2015-08-25 20:44:19 +0000825 }
826
827 const AnnotationSetItem* GetFieldAnnotationSetItem(const FieldAnnotationsItem& anno_item) const {
828 uint32_t offset = anno_item.annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700829 return (offset == 0)
830 ? nullptr
831 : reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000832 }
833
834 const AnnotationSetItem* GetMethodAnnotationSetItem(const MethodAnnotationsItem& anno_item)
835 const {
836 uint32_t offset = anno_item.annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700837 return (offset == 0)
838 ? nullptr
839 : reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000840 }
841
842 const AnnotationSetRefList* GetParameterAnnotationSetRefList(
843 const ParameterAnnotationsItem* anno_item) const {
844 uint32_t offset = anno_item->annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700845 return (offset == 0)
846 ? nullptr
847 : reinterpret_cast<const AnnotationSetRefList*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000848 }
849
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700850 ALWAYS_INLINE const AnnotationItem* GetAnnotationItemAtOffset(uint32_t offset) const {
851 DCHECK_LE(offset, Size());
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700852 return (offset == 0)
853 ? nullptr
854 : reinterpret_cast<const AnnotationItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000855 }
856
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700857 const AnnotationItem* GetAnnotationItem(const AnnotationSetItem* set_item, uint32_t index) const {
858 DCHECK_LE(index, set_item->size_);
859 return GetAnnotationItemAtOffset(set_item->entries_[index]);
860 }
861
Jeff Hao13e748b2015-08-25 20:44:19 +0000862 const AnnotationSetItem* GetSetRefItemItem(const AnnotationSetRefItem* anno_item) const {
863 uint32_t offset = anno_item->annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700864 return (offset == 0)
865 ? nullptr
866 : reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000867 }
868
Shih-wei Liao195487c2011-08-20 13:29:04 -0700869 // Debug info opcodes and constants
870 enum {
871 DBG_END_SEQUENCE = 0x00,
872 DBG_ADVANCE_PC = 0x01,
873 DBG_ADVANCE_LINE = 0x02,
874 DBG_START_LOCAL = 0x03,
875 DBG_START_LOCAL_EXTENDED = 0x04,
876 DBG_END_LOCAL = 0x05,
877 DBG_RESTART_LOCAL = 0x06,
878 DBG_SET_PROLOGUE_END = 0x07,
879 DBG_SET_EPILOGUE_BEGIN = 0x08,
880 DBG_SET_FILE = 0x09,
881 DBG_FIRST_SPECIAL = 0x0a,
882 DBG_LINE_BASE = -4,
883 DBG_LINE_RANGE = 15,
884 };
885
Shih-wei Liao195487c2011-08-20 13:29:04 -0700886 struct LineNumFromPcContext {
Ian Rogersca190662012-06-26 15:45:57 -0700887 LineNumFromPcContext(uint32_t address, uint32_t line_num)
888 : address_(address), line_num_(line_num) {}
Shih-wei Liao195487c2011-08-20 13:29:04 -0700889 uint32_t address_;
890 uint32_t line_num_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700891 private:
892 DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700893 };
894
Roland Levillain91d65e02016-01-19 15:59:16 +0000895 // Returns false if there is no debugging information or if it cannot be decoded.
David Sehraa6abb02017-10-12 08:25:11 -0700896 template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
897 static bool DecodeDebugLocalInfo(const uint8_t* stream,
898 const std::string& location,
899 const char* declaring_class_descriptor,
900 const std::vector<const char*>& arg_descriptors,
901 const std::string& method_name,
902 bool is_static,
903 uint16_t registers_size,
904 uint16_t ins_size,
905 uint16_t insns_size_in_code_units,
906 IndexToStringData index_to_string_data,
907 TypeIndexToStringData type_index_to_string_data,
908 NewLocalCallback new_local,
909 void* context);
910 template<typename NewLocalCallback>
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800911 bool DecodeDebugLocalInfo(uint32_t registers_size,
912 uint32_t ins_size,
913 uint32_t insns_size_in_code_units,
Nicolas Geoffray58cc1cb2017-11-20 13:27:29 +0000914 uint32_t debug_info_offset,
David Sehraa6abb02017-10-12 08:25:11 -0700915 bool is_static,
916 uint32_t method_idx,
917 NewLocalCallback new_local,
918 void* context) const;
David Srbeckyb06e28e2015-12-10 13:15:00 +0000919
Roland Levillain91d65e02016-01-19 15:59:16 +0000920 // Returns false if there is no debugging information or if it cannot be decoded.
David Sehraa6abb02017-10-12 08:25:11 -0700921 template<typename DexDebugNewPosition, typename IndexToStringData>
922 static bool DecodeDebugPositionInfo(const uint8_t* stream,
923 IndexToStringData index_to_string_data,
924 DexDebugNewPosition position_functor,
925 void* context);
926 template<typename DexDebugNewPosition>
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800927 bool DecodeDebugPositionInfo(uint32_t debug_info_offset,
David Sehraa6abb02017-10-12 08:25:11 -0700928 DexDebugNewPosition position_functor,
David Srbeckyb06e28e2015-12-10 13:15:00 +0000929 void* context) const;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700930
Ian Rogers0571d352011-11-03 19:51:38 -0700931 const char* GetSourceFile(const ClassDef& class_def) const {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800932 if (!class_def.source_file_idx_.IsValid()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700933 return nullptr;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700934 } else {
Ian Rogers0571d352011-11-03 19:51:38 -0700935 return StringDataByIdx(class_def.source_file_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700936 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700937 }
938
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800939 int GetPermissions() const;
Ian Rogers1c849e52012-06-28 14:00:33 -0700940
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200941 bool IsReadOnly() const;
942
Brian Carlstrome0948e12013-08-29 09:36:15 -0700943 bool EnableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200944
Brian Carlstrome0948e12013-08-29 09:36:15 -0700945 bool DisableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200946
Ian Rogers13735952014-10-08 12:43:28 -0700947 const uint8_t* Begin() const {
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700948 return begin_;
949 }
950
951 size_t Size() const {
952 return size_;
953 }
954
Richard Uhler07b3c232015-03-31 15:57:54 -0700955 const OatDexFile* GetOatDexFile() const {
956 return oat_dex_file_;
Andreas Gampefd9eb392014-11-06 16:52:58 -0800957 }
958
Mathieu Chartier1b868492016-11-16 16:22:37 -0800959 // Used by oat writer.
960 void SetOatDexFile(OatDexFile* oat_dex_file) const {
961 oat_dex_file_ = oat_dex_file;
962 }
963
David Sehr9323e6e2016-09-13 08:58:35 -0700964 // Utility methods for reading integral values from a buffer.
965 static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth);
966 static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right);
967 static int64_t ReadSignedLong(const uint8_t* ptr, int zwidth);
968 static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right);
969
Alex Light40528472017-03-28 09:07:36 -0700970 // Recalculates the checksum of the dex file. Does not use the current value in the header.
971 uint32_t CalculateChecksum() const;
Mathieu Chartier2c4b0842017-12-13 11:49:51 -0800972 static uint32_t CalculateChecksum(const uint8_t* begin, size_t size);
Alex Light40528472017-03-28 09:07:36 -0700973
David Sehr709b0702016-10-13 09:12:37 -0700974 // Returns a human-readable form of the method at an index.
975 std::string PrettyMethod(uint32_t method_idx, bool with_signature = true) const;
976 // Returns a human-readable form of the field at an index.
977 std::string PrettyField(uint32_t field_idx, bool with_type = true) const;
978 // Returns a human-readable form of the type at an index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800979 std::string PrettyType(dex::TypeIndex type_idx) const;
David Sehr709b0702016-10-13 09:12:37 -0700980
Mathieu Chartier69147f12017-11-06 20:02:24 -0800981 // Not virtual for performance reasons.
982 ALWAYS_INLINE bool IsCompactDexFile() const {
983 return is_compact_dex_;
Mathieu Chartier603ccab2017-10-20 14:34:28 -0700984 }
Mathieu Chartier69147f12017-11-06 20:02:24 -0800985 ALWAYS_INLINE bool IsStandardDexFile() const {
986 return !is_compact_dex_;
Mathieu Chartier603ccab2017-10-20 14:34:28 -0700987 }
Mathieu Chartier69147f12017-11-06 20:02:24 -0800988 ALWAYS_INLINE const StandardDexFile* AsStandardDexFile() const;
989 ALWAYS_INLINE const CompactDexFile* AsCompactDexFile() const;
Mathieu Chartier603ccab2017-10-20 14:34:28 -0700990
Mathieu Chartier73f21d42018-01-02 14:26:50 -0800991 bool HasAddress(const void* addr) const {
992 return Begin() <= addr && addr < Begin() + Size();
993 }
994
Mathieu Chartier7b074bf2017-09-25 16:22:36 -0700995 protected:
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800996 // First Dex format version supporting default methods.
997 static const uint32_t kDefaultMethodsVersion = 37;
998
David Sehr733ddb22016-09-19 15:02:18 -0700999 DexFile(const uint8_t* base,
1000 size_t size,
Brian Carlstrom28db0122012-10-18 16:20:41 -07001001 const std::string& location,
1002 uint32_t location_checksum,
David Sehr733bd4d2017-10-26 10:39:15 -07001003 const OatDexFile* oat_dex_file,
Mathieu Chartier69147f12017-11-06 20:02:24 -08001004 DexFileContainer* container,
1005 bool is_compact_dex);
jeffhaof6174e82012-01-31 16:14:17 -08001006
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001007 // Top-level initializer that calls other Init methods.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001008 bool Init(std::string* error_msg);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001009
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -08001010 // Returns true if the header magic and version numbers are of the expected values.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001011 bool CheckMagicAndVersion(std::string* error_msg) const;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001012
Orion Hodson12f4ff42017-01-13 16:43:12 +00001013 // Initialize section info for sections only found in map. Returns true on success.
1014 void InitializeSectionsFromMapList();
1015
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001016 // The base address of the memory mapping.
Ian Rogers13735952014-10-08 12:43:28 -07001017 const uint8_t* const begin_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001018
1019 // The size of the underlying memory allocation in bytes.
Ian Rogers62d6c772013-02-27 08:32:07 -08001020 const size_t size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001021
Elliott Hughes64bf5a32011-09-20 14:43:12 -07001022 // Typically the dex file name when available, alternatively some identifying string.
Brian Carlstroma663ea52011-08-19 23:33:41 -07001023 //
1024 // The ClassLinker will use this to match DexFiles the boot class
1025 // path to DexCache::GetLocation when loading from an image.
1026 const std::string location_;
1027
Brian Carlstrom5b332c82012-02-01 15:02:31 -08001028 const uint32_t location_checksum_;
1029
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001030 // Points to the header section.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001031 const Header* const header_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001032
1033 // Points to the base of the string identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001034 const StringId* const string_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001035
1036 // Points to the base of the type identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001037 const TypeId* const type_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001038
1039 // Points to the base of the field identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001040 const FieldId* const field_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001041
1042 // Points to the base of the method identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001043 const MethodId* const method_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001044
1045 // Points to the base of the prototype identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001046 const ProtoId* const proto_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001047
1048 // Points to the base of the class definition list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001049 const ClassDef* const class_defs_;
Ian Rogers68b56852014-08-29 20:19:11 -07001050
Orion Hodson12f4ff42017-01-13 16:43:12 +00001051 // Points to the base of the method handles list.
1052 const MethodHandleItem* method_handles_;
1053
1054 // Number of elements in the method handles list.
1055 size_t num_method_handles_;
1056
1057 // Points to the base of the call sites id list.
1058 const CallSiteIdItem* call_site_ids_;
1059
1060 // Number of elements in the call sites list.
1061 size_t num_call_site_ids_;
1062
Richard Uhler07b3c232015-03-31 15:57:54 -07001063 // If this dex file was loaded from an oat file, oat_dex_file_ contains a
1064 // pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
1065 // null.
Mathieu Chartier1b868492016-11-16 16:22:37 -08001066 mutable const OatDexFile* oat_dex_file_;
Andreas Gampee6215c02015-08-31 18:54:38 -07001067
David Sehr733bd4d2017-10-26 10:39:15 -07001068 // Manages the underlying memory allocation.
1069 std::unique_ptr<DexFileContainer> container_;
1070
Mathieu Chartier69147f12017-11-06 20:02:24 -08001071 // If the dex file is a compact dex file. If false then the dex file is a standard dex file.
1072 const bool is_compact_dex_;
1073
Mathieu Chartier79c87da2017-10-10 11:54:29 -07001074 friend class DexFileLoader;
Andreas Gampee6215c02015-08-31 18:54:38 -07001075 friend class DexFileVerifierTest;
Mathieu Chartier1b868492016-11-16 16:22:37 -08001076 friend class OatWriter;
Carl Shapiro1fb86202011-06-27 17:43:13 -07001077};
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001078
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001079std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);
Carl Shapiro1fb86202011-06-27 17:43:13 -07001080
Ian Rogers0571d352011-11-03 19:51:38 -07001081// Iterate over a dex file's ProtoId's paramters
1082class DexFileParameterIterator {
1083 public:
1084 DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id)
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001085 : dex_file_(dex_file) {
Ian Rogers0571d352011-11-03 19:51:38 -07001086 type_list_ = dex_file_.GetProtoParameters(proto_id);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001087 if (type_list_ != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -07001088 size_ = type_list_->Size();
1089 }
1090 }
1091 bool HasNext() const { return pos_ < size_; }
David Srbeckyb06e28e2015-12-10 13:15:00 +00001092 size_t Size() const { return size_; }
Ian Rogers0571d352011-11-03 19:51:38 -07001093 void Next() { ++pos_; }
Andreas Gampea5b09a62016-11-17 15:21:22 -08001094 dex::TypeIndex GetTypeIdx() {
Ian Rogers0571d352011-11-03 19:51:38 -07001095 return type_list_->GetTypeItem(pos_).type_idx_;
1096 }
1097 const char* GetDescriptor() {
Andreas Gampea5b09a62016-11-17 15:21:22 -08001098 return dex_file_.StringByTypeIdx(dex::TypeIndex(GetTypeIdx()));
Ian Rogers0571d352011-11-03 19:51:38 -07001099 }
1100 private:
1101 const DexFile& dex_file_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001102 const DexFile::TypeList* type_list_ = nullptr;
1103 uint32_t size_ = 0;
1104 uint32_t pos_ = 0;
Ian Rogers0571d352011-11-03 19:51:38 -07001105 DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
1106};
1107
Ian Rogersd91d6d62013-09-25 20:26:14 -07001108// Abstract the signature of a method.
Ian Rogers03b6eaf2014-10-28 09:34:57 -07001109class Signature : public ValueObject {
Ian Rogersd91d6d62013-09-25 20:26:14 -07001110 public:
1111 std::string ToString() const;
1112
1113 static Signature NoSignature() {
1114 return Signature();
1115 }
1116
Orion Hodson6c4921b2016-09-21 15:41:06 +01001117 bool IsVoid() const;
1118 uint32_t GetNumberOfParameters() const;
1119
Ian Rogersdfb325e2013-10-30 01:00:44 -07001120 bool operator==(const Signature& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001121 bool operator!=(const Signature& rhs) const {
1122 return !(*this == rhs);
1123 }
1124
Vladimir Markod9cffea2013-11-25 15:08:02 +00001125 bool operator==(const StringPiece& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001126
1127 private:
1128 Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
1129 }
1130
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001131 Signature() = default;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001132
1133 friend class DexFile;
1134
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001135 const DexFile* const dex_file_ = nullptr;
1136 const DexFile::ProtoId* const proto_id_ = nullptr;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001137};
1138std::ostream& operator<<(std::ostream& os, const Signature& sig);
1139
Ian Rogers0571d352011-11-03 19:51:38 -07001140// Iterate and decode class_data_item
1141class ClassDataItemIterator {
1142 public:
Ian Rogers13735952014-10-08 12:43:28 -07001143 ClassDataItemIterator(const DexFile& dex_file, const uint8_t* raw_class_data_item)
Ian Rogers0571d352011-11-03 19:51:38 -07001144 : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) {
1145 ReadClassDataHeader();
1146 if (EndOfInstanceFieldsPos() > 0) {
1147 ReadClassDataField();
1148 } else if (EndOfVirtualMethodsPos() > 0) {
1149 ReadClassDataMethod();
1150 }
1151 }
1152 uint32_t NumStaticFields() const {
1153 return header_.static_fields_size_;
1154 }
1155 uint32_t NumInstanceFields() const {
1156 return header_.instance_fields_size_;
1157 }
1158 uint32_t NumDirectMethods() const {
1159 return header_.direct_methods_size_;
1160 }
1161 uint32_t NumVirtualMethods() const {
1162 return header_.virtual_methods_size_;
1163 }
Alex Light40528472017-03-28 09:07:36 -07001164 bool IsAtMethod() const {
1165 return pos_ >= EndOfInstanceFieldsPos();
1166 }
Ian Rogers0571d352011-11-03 19:51:38 -07001167 bool HasNextStaticField() const {
1168 return pos_ < EndOfStaticFieldsPos();
1169 }
1170 bool HasNextInstanceField() const {
1171 return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos();
1172 }
1173 bool HasNextDirectMethod() const {
1174 return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos();
1175 }
1176 bool HasNextVirtualMethod() const {
1177 return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos();
1178 }
Mathieu Chartierb7c273c2017-11-10 18:07:56 -08001179 bool HasNextMethod() const {
1180 const bool result = pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfVirtualMethodsPos();
1181 DCHECK_EQ(result, HasNextDirectMethod() || HasNextVirtualMethod());
1182 return result;
1183 }
Mathieu Chartiere17cf242017-06-19 11:05:51 -07001184 void SkipStaticFields() {
1185 while (HasNextStaticField()) {
1186 Next();
1187 }
1188 }
1189 void SkipInstanceFields() {
1190 while (HasNextInstanceField()) {
1191 Next();
1192 }
1193 }
1194 void SkipAllFields() {
1195 SkipStaticFields();
1196 SkipInstanceFields();
1197 }
1198 void SkipDirectMethods() {
1199 while (HasNextDirectMethod()) {
1200 Next();
1201 }
1202 }
1203 void SkipVirtualMethods() {
1204 while (HasNextVirtualMethod()) {
1205 Next();
1206 }
1207 }
Ian Rogers0571d352011-11-03 19:51:38 -07001208 bool HasNext() const {
1209 return pos_ < EndOfVirtualMethodsPos();
1210 }
Ian Rogers637c65b2013-05-31 11:46:00 -07001211 inline void Next() {
Ian Rogers0571d352011-11-03 19:51:38 -07001212 pos_++;
1213 if (pos_ < EndOfStaticFieldsPos()) {
1214 last_idx_ = GetMemberIndex();
1215 ReadClassDataField();
1216 } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) {
1217 last_idx_ = 0; // transition to next array, reset last index
1218 ReadClassDataField();
1219 } else if (pos_ < EndOfInstanceFieldsPos()) {
1220 last_idx_ = GetMemberIndex();
1221 ReadClassDataField();
1222 } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) {
1223 last_idx_ = 0; // transition to next array, reset last index
1224 ReadClassDataMethod();
1225 } else if (pos_ < EndOfDirectMethodsPos()) {
1226 last_idx_ = GetMemberIndex();
1227 ReadClassDataMethod();
1228 } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) {
1229 last_idx_ = 0; // transition to next array, reset last index
1230 ReadClassDataMethod();
1231 } else if (pos_ < EndOfVirtualMethodsPos()) {
1232 last_idx_ = GetMemberIndex();
1233 ReadClassDataMethod();
1234 } else {
1235 DCHECK(!HasNext());
1236 }
1237 }
1238 uint32_t GetMemberIndex() const {
1239 if (pos_ < EndOfInstanceFieldsPos()) {
1240 return last_idx_ + field_.field_idx_delta_;
1241 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001242 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001243 return last_idx_ + method_.method_idx_delta_;
1244 }
1245 }
Andreas Gampe51829322014-08-25 15:05:04 -07001246 uint32_t GetRawMemberAccessFlags() const {
Ian Rogers0571d352011-11-03 19:51:38 -07001247 if (pos_ < EndOfInstanceFieldsPos()) {
1248 return field_.access_flags_;
1249 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001250 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001251 return method_.access_flags_;
1252 }
1253 }
Andreas Gampe51829322014-08-25 15:05:04 -07001254 uint32_t GetFieldAccessFlags() const {
1255 return GetRawMemberAccessFlags() & kAccValidFieldFlags;
1256 }
1257 uint32_t GetMethodAccessFlags() const {
1258 return GetRawMemberAccessFlags() & kAccValidMethodFlags;
1259 }
1260 bool MemberIsNative() const {
1261 return GetRawMemberAccessFlags() & kAccNative;
1262 }
1263 bool MemberIsFinal() const {
1264 return GetRawMemberAccessFlags() & kAccFinal;
1265 }
Andreas Gampe04c6ab92017-06-08 21:49:14 -07001266 ALWAYS_INLINE InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const;
Ian Rogers0571d352011-11-03 19:51:38 -07001267 const DexFile::CodeItem* GetMethodCodeItem() const {
1268 return dex_file_.GetCodeItem(method_.code_off_);
1269 }
1270 uint32_t GetMethodCodeItemOffset() const {
1271 return method_.code_off_;
1272 }
Andreas Gampee6215c02015-08-31 18:54:38 -07001273 const uint8_t* DataPointer() const {
1274 return ptr_pos_;
1275 }
Ian Rogers13735952014-10-08 12:43:28 -07001276 const uint8_t* EndDataPointer() const {
jeffhao10037c82012-01-23 15:06:23 -08001277 CHECK(!HasNext());
1278 return ptr_pos_;
1279 }
Elliott Hughesa21039c2012-06-21 12:09:25 -07001280
Ian Rogers0571d352011-11-03 19:51:38 -07001281 private:
1282 // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the
1283 // header for a class_data_item
1284 struct ClassDataHeader {
1285 uint32_t static_fields_size_; // the number of static fields
1286 uint32_t instance_fields_size_; // the number of instance fields
1287 uint32_t direct_methods_size_; // the number of direct methods
1288 uint32_t virtual_methods_size_; // the number of virtual methods
1289 } header_;
1290
1291 // Read and decode header from a class_data_item stream into header
1292 void ReadClassDataHeader();
1293
1294 uint32_t EndOfStaticFieldsPos() const {
1295 return header_.static_fields_size_;
1296 }
1297 uint32_t EndOfInstanceFieldsPos() const {
1298 return EndOfStaticFieldsPos() + header_.instance_fields_size_;
1299 }
1300 uint32_t EndOfDirectMethodsPos() const {
1301 return EndOfInstanceFieldsPos() + header_.direct_methods_size_;
1302 }
1303 uint32_t EndOfVirtualMethodsPos() const {
1304 return EndOfDirectMethodsPos() + header_.virtual_methods_size_;
1305 }
1306
1307 // A decoded version of the field of a class_data_item
1308 struct ClassDataField {
1309 uint32_t field_idx_delta_; // delta of index into the field_ids array for FieldId
1310 uint32_t access_flags_; // access flags for the field
1311 ClassDataField() : field_idx_delta_(0), access_flags_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001312
Ian Rogers0571d352011-11-03 19:51:38 -07001313 private:
1314 DISALLOW_COPY_AND_ASSIGN(ClassDataField);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001315 };
1316 ClassDataField field_;
Ian Rogers0571d352011-11-03 19:51:38 -07001317
1318 // Read and decode a field from a class_data_item stream into field
1319 void ReadClassDataField();
1320
1321 // A decoded version of the method of a class_data_item
1322 struct ClassDataMethod {
1323 uint32_t method_idx_delta_; // delta of index into the method_ids array for MethodId
1324 uint32_t access_flags_;
1325 uint32_t code_off_;
1326 ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001327
Ian Rogers0571d352011-11-03 19:51:38 -07001328 private:
1329 DISALLOW_COPY_AND_ASSIGN(ClassDataMethod);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001330 };
1331 ClassDataMethod method_;
Ian Rogers0571d352011-11-03 19:51:38 -07001332
1333 // Read and decode a method from a class_data_item stream into method
1334 void ReadClassDataMethod();
1335
1336 const DexFile& dex_file_;
1337 size_t pos_; // integral number of items passed
Ian Rogers13735952014-10-08 12:43:28 -07001338 const uint8_t* ptr_pos_; // pointer into stream of class_data_item
Ian Rogers0571d352011-11-03 19:51:38 -07001339 uint32_t last_idx_; // last read field or method index to apply delta to
1340 DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
1341};
1342
Orion Hodson12f4ff42017-01-13 16:43:12 +00001343class EncodedArrayValueIterator {
Ian Rogers0571d352011-11-03 19:51:38 -07001344 public:
Orion Hodson12f4ff42017-01-13 16:43:12 +00001345 EncodedArrayValueIterator(const DexFile& dex_file, const uint8_t* array_data);
Shinichiro Hamaji82863f02015-11-05 16:51:33 +09001346
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001347 bool HasNext() const { return pos_ < array_size_; }
Ian Rogers0571d352011-11-03 19:51:38 -07001348
1349 void Next();
Elliott Hughesa21039c2012-06-21 12:09:25 -07001350
Ian Rogers0571d352011-11-03 19:51:38 -07001351 enum ValueType {
Orion Hodson12f4ff42017-01-13 16:43:12 +00001352 kByte = 0x00,
1353 kShort = 0x02,
1354 kChar = 0x03,
1355 kInt = 0x04,
1356 kLong = 0x06,
1357 kFloat = 0x10,
1358 kDouble = 0x11,
1359 kMethodType = 0x15,
1360 kMethodHandle = 0x16,
1361 kString = 0x17,
1362 kType = 0x18,
1363 kField = 0x19,
1364 kMethod = 0x1a,
1365 kEnum = 0x1b,
1366 kArray = 0x1c,
1367 kAnnotation = 0x1d,
1368 kNull = 0x1e,
1369 kBoolean = 0x1f,
Ian Rogers0571d352011-11-03 19:51:38 -07001370 };
1371
Shinichiro Hamaji82863f02015-11-05 16:51:33 +09001372 ValueType GetValueType() const { return type_; }
1373 const jvalue& GetJavaValue() const { return jval_; }
1374
David Sehr9323e6e2016-09-13 08:58:35 -07001375 protected:
Ian Rogers13735952014-10-08 12:43:28 -07001376 static constexpr uint8_t kEncodedValueTypeMask = 0x1f; // 0b11111
1377 static constexpr uint8_t kEncodedValueArgShift = 5;
Ian Rogers0571d352011-11-03 19:51:38 -07001378
1379 const DexFile& dex_file_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001380 size_t array_size_; // Size of array.
1381 size_t pos_; // Current position.
Ian Rogers13735952014-10-08 12:43:28 -07001382 const uint8_t* ptr_; // Pointer into encoded data array.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001383 ValueType type_; // Type of current encoded value.
1384 jvalue jval_; // Value of current encoded value.
David Sehr9323e6e2016-09-13 08:58:35 -07001385
1386 private:
Orion Hodson12f4ff42017-01-13 16:43:12 +00001387 DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedArrayValueIterator);
1388};
1389std::ostream& operator<<(std::ostream& os, const EncodedArrayValueIterator::ValueType& code);
1390
1391class EncodedStaticFieldValueIterator : public EncodedArrayValueIterator {
1392 public:
1393 EncodedStaticFieldValueIterator(const DexFile& dex_file,
1394 const DexFile::ClassDef& class_def)
1395 : EncodedArrayValueIterator(dex_file,
1396 dex_file.GetEncodedStaticFieldValuesArray(class_def))
1397 {}
1398
1399 private:
Ian Rogers0571d352011-11-03 19:51:38 -07001400 DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
1401};
Brian Carlstrom88f36542012-10-16 23:24:21 -07001402std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code);
Ian Rogers0571d352011-11-03 19:51:38 -07001403
Orion Hodson12f4ff42017-01-13 16:43:12 +00001404class CallSiteArrayValueIterator : public EncodedArrayValueIterator {
1405 public:
1406 CallSiteArrayValueIterator(const DexFile& dex_file,
1407 const DexFile::CallSiteIdItem& call_site_id)
1408 : EncodedArrayValueIterator(dex_file,
1409 dex_file.GetCallSiteEncodedValuesArray(call_site_id))
1410 {}
1411
1412 uint32_t Size() const { return array_size_; }
1413
1414 private:
1415 DISALLOW_IMPLICIT_CONSTRUCTORS(CallSiteArrayValueIterator);
1416};
1417std::ostream& operator<<(std::ostream& os, const CallSiteArrayValueIterator::ValueType& code);
1418
Carl Shapiro1fb86202011-06-27 17:43:13 -07001419} // namespace art
1420
David Sehr9e734c72018-01-04 17:56:19 -08001421#endif // ART_RUNTIME_DEX_DEX_FILE_H_