blob: 2c6a430020b359b6c3db7d2ed9179f723c48c4da [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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_DEX_FILE_H_
18#define ART_RUNTIME_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
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -070024#include "base/iteration_range.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080025#include "base/logging.h"
Ian Rogers03b6eaf2014-10-28 09:34:57 -070026#include "base/value_object.h"
Andreas Gampea5b09a62016-11-17 15:21:22 -080027#include "dex_file_types.h"
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -070028#include "dex_instruction_iterator.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070029#include "globals.h"
Jesse Wilson6bf19152011-09-29 13:12:33 -040030#include "jni.h"
Ian Rogers08f753d2012-08-24 14:35:25 -070031#include "modifiers.h"
Carl Shapiro1fb86202011-06-27 17:43:13 -070032
33namespace art {
34
Mathieu Chartier69147f12017-11-06 20:02:24 -080035class CompactDexFile;
Andreas Gampe04c6ab92017-06-08 21:49:14 -070036enum InvokeType : uint32_t;
Ian Rogers576ca0c2014-06-06 15:58:22 -070037class MemMap;
Richard Uhler07b3c232015-03-31 15:57:54 -070038class OatDexFile;
Ian Rogersd91d6d62013-09-25 20:26:14 -070039class Signature;
Mathieu Chartier69147f12017-11-06 20:02:24 -080040class StandardDexFile;
Ian Rogersfc0e94b2013-09-23 23:51:32 -070041class StringPiece;
Brian Carlstroma6cc8932012-01-04 14:44:07 -080042class ZipArchive;
43
David Sehr733bd4d2017-10-26 10:39:15 -070044// Some instances of DexFile own the storage referred to by DexFile. Clients who create
45// such management do so by subclassing Container.
46class DexFileContainer {
47 public:
48 DexFileContainer() { }
49 virtual ~DexFileContainer() { }
50 virtual int GetPermissions() = 0;
51 virtual bool IsReadOnly() = 0;
52 virtual bool EnableWrite() = 0;
53 virtual bool DisableWrite() = 0;
54
55 private:
56 DISALLOW_COPY_AND_ASSIGN(DexFileContainer);
57};
58
Mathieu Chartier7b074bf2017-09-25 16:22:36 -070059// Dex file is the API that exposes native dex files (ordinary dex files) and CompactDex.
60// Originally, the dex file format used by ART was mostly the same as APKs. The only change was
61// quickened opcodes and layout optimizations.
Mathieu Chartier79c87da2017-10-10 11:54:29 -070062// Since ART needs to support both native dex files and CompactDex files, the DexFile interface
63// provides an abstraction to facilitate this.
Brian Carlstromf615a612011-07-23 12:50:34 -070064class DexFile {
Carl Shapiro1fb86202011-06-27 17:43:13 -070065 public:
Mathieu Chartier7b074bf2017-09-25 16:22:36 -070066 // Number of bytes in the dex file magic.
67 static constexpr size_t kDexMagicSize = 4;
68 static constexpr size_t kDexVersionLen = 4;
69
Roland Levillain621b5ea2016-05-18 11:41:33 +010070 // First Dex format version supporting default methods.
Alex Lightb55f1ac2016-04-12 15:50:55 -070071 static const uint32_t kDefaultMethodsVersion = 37;
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
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700304 // Raw code_item.
305 struct CodeItem {
Mathieu Chartier0021feb2017-11-07 00:08:52 -0800306 IterationRange<DexInstructionIterator> Instructions(uint32_t start_dex_pc = 0u) const {
307 DCHECK_LE(start_dex_pc, insns_size_in_code_units_);
308 return { DexInstructionIterator(insns_, start_dex_pc),
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700309 DexInstructionIterator(insns_, insns_size_in_code_units_) };
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -0700310 }
311
312 const Instruction& InstructionAt(uint32_t dex_pc) const {
313 return *Instruction::At(insns_ + dex_pc);
314 }
315
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700316 uint16_t registers_size_; // the number of registers used by this code
317 // (locals + parameters)
318 uint16_t ins_size_; // the number of words of incoming arguments to the method
319 // that this code is for
320 uint16_t outs_size_; // the number of words of outgoing argument space required
321 // by this code for method invocation
322 uint16_t tries_size_; // the number of try_items for this instance. If non-zero,
323 // then these appear as the tries array just after the
324 // insns in this instance.
325 uint32_t debug_info_off_; // file offset to debug info stream
Ian Rogersd81871c2011-10-03 13:57:23 -0700326 uint32_t insns_size_in_code_units_; // size of the insns array, in 2 byte code units
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700327 uint16_t insns_[1]; // actual array of bytecode.
Elliott Hughesa21039c2012-06-21 12:09:25 -0700328
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700329 private:
330 DISALLOW_COPY_AND_ASSIGN(CodeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700331 };
332
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700333 // Raw try_item.
334 struct TryItem {
335 uint32_t start_addr_;
336 uint16_t insn_count_;
337 uint16_t handler_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700338
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700339 private:
340 DISALLOW_COPY_AND_ASSIGN(TryItem);
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700341 };
342
jeffhao10037c82012-01-23 15:06:23 -0800343 // Annotation constants.
344 enum {
345 kDexVisibilityBuild = 0x00, /* annotation visibility */
346 kDexVisibilityRuntime = 0x01,
347 kDexVisibilitySystem = 0x02,
348
349 kDexAnnotationByte = 0x00,
350 kDexAnnotationShort = 0x02,
351 kDexAnnotationChar = 0x03,
352 kDexAnnotationInt = 0x04,
353 kDexAnnotationLong = 0x06,
354 kDexAnnotationFloat = 0x10,
355 kDexAnnotationDouble = 0x11,
Orion Hodson12f4ff42017-01-13 16:43:12 +0000356 kDexAnnotationMethodType = 0x15,
357 kDexAnnotationMethodHandle = 0x16,
jeffhao10037c82012-01-23 15:06:23 -0800358 kDexAnnotationString = 0x17,
359 kDexAnnotationType = 0x18,
360 kDexAnnotationField = 0x19,
361 kDexAnnotationMethod = 0x1a,
362 kDexAnnotationEnum = 0x1b,
363 kDexAnnotationArray = 0x1c,
364 kDexAnnotationAnnotation = 0x1d,
365 kDexAnnotationNull = 0x1e,
366 kDexAnnotationBoolean = 0x1f,
367
368 kDexAnnotationValueTypeMask = 0x1f, /* low 5 bits */
369 kDexAnnotationValueArgShift = 5,
370 };
371
372 struct AnnotationsDirectoryItem {
373 uint32_t class_annotations_off_;
374 uint32_t fields_size_;
375 uint32_t methods_size_;
376 uint32_t parameters_size_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700377
jeffhao10037c82012-01-23 15:06:23 -0800378 private:
379 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
380 };
381
382 struct FieldAnnotationsItem {
383 uint32_t field_idx_;
384 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700385
jeffhao10037c82012-01-23 15:06:23 -0800386 private:
387 DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem);
388 };
389
390 struct MethodAnnotationsItem {
391 uint32_t method_idx_;
392 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700393
jeffhao10037c82012-01-23 15:06:23 -0800394 private:
395 DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem);
396 };
397
398 struct ParameterAnnotationsItem {
399 uint32_t method_idx_;
400 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700401
jeffhao10037c82012-01-23 15:06:23 -0800402 private:
403 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem);
404 };
405
406 struct AnnotationSetRefItem {
407 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700408
jeffhao10037c82012-01-23 15:06:23 -0800409 private:
410 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem);
411 };
412
413 struct AnnotationSetRefList {
414 uint32_t size_;
415 AnnotationSetRefItem list_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700416
jeffhao10037c82012-01-23 15:06:23 -0800417 private:
418 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
419 };
420
421 struct AnnotationSetItem {
422 uint32_t size_;
423 uint32_t entries_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700424
jeffhao10037c82012-01-23 15:06:23 -0800425 private:
426 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
427 };
428
429 struct AnnotationItem {
430 uint8_t visibility_;
431 uint8_t annotation_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700432
jeffhao10037c82012-01-23 15:06:23 -0800433 private:
434 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
435 };
436
Jeff Hao13e748b2015-08-25 20:44:19 +0000437 enum AnnotationResultStyle { // private
438 kAllObjects,
439 kPrimitivesOrObjects,
440 kAllRaw
441 };
442
David Sehr9323e6e2016-09-13 08:58:35 -0700443 struct AnnotationValue;
444
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700445 // Closes a .dex file.
Brian Carlstromf615a612011-07-23 12:50:34 -0700446 virtual ~DexFile();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700447
Brian Carlstroma663ea52011-08-19 23:33:41 -0700448 const std::string& GetLocation() const {
449 return location_;
450 }
451
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800452 // For DexFiles directly from .dex files, this is the checksum from the DexFile::Header.
453 // For DexFiles opened from a zip files, this will be the ZipEntry CRC32 of classes.dex.
454 uint32_t GetLocationChecksum() const {
455 return location_checksum_;
456 }
457
Brian Carlstroma663ea52011-08-19 23:33:41 -0700458 const Header& GetHeader() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700459 DCHECK(header_ != nullptr) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700460 return *header_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700461 }
462
Ian Rogers0571d352011-11-03 19:51:38 -0700463 // Decode the dex magic version
Andreas Gampe76ed99d2016-03-28 18:31:29 -0700464 uint32_t GetVersion() const {
465 return GetHeader().GetVersion();
466 }
Ian Rogersd81871c2011-10-03 13:57:23 -0700467
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800468 // Returns true if the byte string points to the magic value.
Mathieu Chartier7b074bf2017-09-25 16:22:36 -0700469 virtual bool IsMagicValid() const = 0;
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800470
471 // Returns true if the byte string after the magic is the correct value.
Mathieu Chartier7b074bf2017-09-25 16:22:36 -0700472 virtual bool IsVersionValid() const = 0;
473
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700474 // Returns the number of string identifiers in the .dex file.
475 size_t NumStringIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700476 DCHECK(header_ != nullptr) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700477 return header_->string_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700478 }
479
Ian Rogers0571d352011-11-03 19:51:38 -0700480 // Returns the StringId at the specified index.
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800481 const StringId& GetStringId(dex::StringIndex idx) const {
482 DCHECK_LT(idx.index_, NumStringIds()) << GetLocation();
483 return string_ids_[idx.index_];
Ian Rogers0571d352011-11-03 19:51:38 -0700484 }
485
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800486 dex::StringIndex GetIndexForStringId(const StringId& string_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800487 CHECK_GE(&string_id, string_ids_) << GetLocation();
488 CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800489 return dex::StringIndex(&string_id - string_ids_);
Ian Rogers0571d352011-11-03 19:51:38 -0700490 }
491
492 int32_t GetStringLength(const StringId& string_id) const;
493
Ian Rogersdfb325e2013-10-30 01:00:44 -0700494 // Returns a pointer to the UTF-8 string data referred to by the given string_id as well as the
495 // length of the string when decoded as a UTF-16 string. Note the UTF-16 length is not the same
496 // as the string length of the string data.
497 const char* GetStringDataAndUtf16Length(const StringId& string_id, uint32_t* utf16_length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700498
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100499 const char* GetStringData(const StringId& string_id) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700500
Ian Rogersdfb325e2013-10-30 01:00:44 -0700501 // Index version of GetStringDataAndUtf16Length.
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800502 const char* StringDataAndUtf16LengthByIdx(dex::StringIndex idx, uint32_t* utf16_length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700503
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800504 const char* StringDataByIdx(dex::StringIndex idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700505
Ian Rogers637c65b2013-05-31 11:46:00 -0700506 // Looks up a string id for a given modified utf8 string.
507 const StringId* FindStringId(const char* string) const;
508
Artem Udovichenkod9786b02015-10-14 16:36:55 +0300509 const TypeId* FindTypeId(const char* string) const;
510
Ian Rogers637c65b2013-05-31 11:46:00 -0700511 // Looks up a string id for a given utf16 string.
Vladimir Markoa48aef42014-12-03 17:53:53 +0000512 const StringId* FindStringId(const uint16_t* string, size_t length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700513
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700514 // Returns the number of type identifiers in the .dex file.
Ian Rogers68b56852014-08-29 20:19:11 -0700515 uint32_t NumTypeIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700516 DCHECK(header_ != nullptr) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700517 return header_->type_ids_size_;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700518 }
519
Calin Juravle08556882017-05-26 16:40:45 -0700520 bool IsTypeIndexValid(dex::TypeIndex idx) const {
521 return idx.IsValid() && idx.index_ < NumTypeIds();
522 }
523
Ian Rogers0571d352011-11-03 19:51:38 -0700524 // Returns the TypeId at the specified index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800525 const TypeId& GetTypeId(dex::TypeIndex idx) const {
526 DCHECK_LT(idx.index_, NumTypeIds()) << GetLocation();
527 return type_ids_[idx.index_];
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700528 }
529
Andreas Gampea5b09a62016-11-17 15:21:22 -0800530 dex::TypeIndex GetIndexForTypeId(const TypeId& type_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800531 CHECK_GE(&type_id, type_ids_) << GetLocation();
532 CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700533 size_t result = &type_id - type_ids_;
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800534 DCHECK_LT(result, 65536U) << GetLocation();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800535 return dex::TypeIndex(static_cast<uint16_t>(result));
Ian Rogers0571d352011-11-03 19:51:38 -0700536 }
537
538 // Get the descriptor string associated with a given type index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800539 const char* StringByTypeIdx(dex::TypeIndex idx, uint32_t* unicode_length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700540
Andreas Gampea5b09a62016-11-17 15:21:22 -0800541 const char* StringByTypeIdx(dex::TypeIndex idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700542
543 // Returns the type descriptor string of a type id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100544 const char* GetTypeDescriptor(const TypeId& type_id) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700545
546 // Looks up a type for the given string index
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800547 const TypeId* FindTypeId(dex::StringIndex string_idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700548
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700549 // Returns the number of field identifiers in the .dex file.
550 size_t NumFieldIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700551 DCHECK(header_ != nullptr) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700552 return header_->field_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700553 }
554
Ian Rogers0571d352011-11-03 19:51:38 -0700555 // Returns the FieldId at the specified index.
556 const FieldId& GetFieldId(uint32_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200557 DCHECK_LT(idx, NumFieldIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700558 return field_ids_[idx];
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700559 }
560
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800561 uint32_t GetIndexForFieldId(const FieldId& field_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800562 CHECK_GE(&field_id, field_ids_) << GetLocation();
563 CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation();
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800564 return &field_id - field_ids_;
565 }
566
567 // Looks up a field by its declaring class, name and type
568 const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass,
569 const DexFile::StringId& name,
570 const DexFile::TypeId& type) const;
571
Alex Light9c20a142016-08-23 15:05:12 -0700572 uint32_t FindCodeItemOffset(const DexFile::ClassDef& class_def,
573 uint32_t dex_method_idx) const;
574
Bharadwaj Kalandhabhatta043c9082017-06-06 17:14:12 -0700575 static uint32_t GetCodeItemSize(const DexFile::CodeItem& disk_code_item);
576
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700577 // Returns the declaring class descriptor string of a field id.
578 const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const {
Brian Carlstromb9edb842011-08-28 16:31:06 -0700579 const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_);
580 return GetTypeDescriptor(type_id);
581 }
582
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700583 // Returns the class descriptor string of a field id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100584 const char* GetFieldTypeDescriptor(const FieldId& field_id) const;
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700585
Brian Carlstromb9edb842011-08-28 16:31:06 -0700586 // Returns the name of a field id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100587 const char* GetFieldName(const FieldId& field_id) const;
Brian Carlstromb9edb842011-08-28 16:31:06 -0700588
Ian Rogers0571d352011-11-03 19:51:38 -0700589 // Returns the number of method identifiers in the .dex file.
590 size_t NumMethodIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700591 DCHECK(header_ != nullptr) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700592 return header_->method_ids_size_;
593 }
594
595 // Returns the MethodId at the specified index.
596 const MethodId& GetMethodId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700597 DCHECK_LT(idx, NumMethodIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700598 return method_ids_[idx];
599 }
600
601 uint32_t GetIndexForMethodId(const MethodId& method_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800602 CHECK_GE(&method_id, method_ids_) << GetLocation();
603 CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700604 return &method_id - method_ids_;
605 }
606
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800607 // Looks up a method by its declaring class, name and proto_id
608 const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass,
609 const DexFile::StringId& name,
Ian Rogers0571d352011-11-03 19:51:38 -0700610 const DexFile::ProtoId& signature) const;
611
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700612 // Returns the declaring class descriptor string of a method id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100613 const char* GetMethodDeclaringClassDescriptor(const MethodId& method_id) const;
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700614
jeffhao98eacac2011-09-14 16:11:53 -0700615 // Returns the prototype of a method id.
Brian Carlstromaded5f72011-10-07 17:15:04 -0700616 const ProtoId& GetMethodPrototype(const MethodId& method_id) const {
617 return GetProtoId(method_id.proto_idx_);
618 }
619
Ian Rogersd91d6d62013-09-25 20:26:14 -0700620 // Returns a representation of the signature of a method id.
621 const Signature GetMethodSignature(const MethodId& method_id) const;
jeffhao98eacac2011-09-14 16:11:53 -0700622
Orion Hodsonb34bb192016-10-18 17:02:58 +0100623 // Returns a representation of the signature of a proto id.
624 const Signature GetProtoSignature(const ProtoId& proto_id) const;
625
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700626 // Returns the name of a method id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100627 const char* GetMethodName(const MethodId& method_id) const;
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700628
Calin Juravle68ad6492015-08-18 17:08:12 +0100629 // Returns the shorty of a method by its index.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100630 const char* GetMethodShorty(uint32_t idx) const;
Calin Juravle68ad6492015-08-18 17:08:12 +0100631
Ian Rogers0571d352011-11-03 19:51:38 -0700632 // Returns the shorty of a method id.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100633 const char* GetMethodShorty(const MethodId& method_id) const;
634 const char* GetMethodShorty(const MethodId& method_id, uint32_t* length) const;
635
Ian Rogers0571d352011-11-03 19:51:38 -0700636 // Returns the number of class definitions in the .dex file.
Ian Rogers68b56852014-08-29 20:19:11 -0700637 uint32_t NumClassDefs() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700638 DCHECK(header_ != nullptr) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700639 return header_->class_defs_size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700640 }
641
642 // Returns the ClassDef at the specified index.
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700643 const ClassDef& GetClassDef(uint16_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200644 DCHECK_LT(idx, NumClassDefs()) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700645 return class_defs_[idx];
646 }
647
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700648 uint16_t GetIndexForClassDef(const ClassDef& class_def) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800649 CHECK_GE(&class_def, class_defs_) << GetLocation();
650 CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700651 return &class_def - class_defs_;
652 }
653
654 // Returns the class descriptor string of a class definition.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100655 const char* GetClassDescriptor(const ClassDef& class_def) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700656
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700657 // Looks up a class definition by its type index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800658 const ClassDef* FindClassDef(dex::TypeIndex type_idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700659
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700660 const TypeList* GetInterfacesList(const ClassDef& class_def) const {
661 if (class_def.interfaces_off_ == 0) {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700662 return nullptr;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700663 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700664 const uint8_t* addr = begin_ + class_def.interfaces_off_;
665 return reinterpret_cast<const TypeList*>(addr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700666 }
667
Orion Hodson12f4ff42017-01-13 16:43:12 +0000668 uint32_t NumMethodHandles() const {
669 return num_method_handles_;
670 }
671
Orion Hodsonc069a302017-01-18 09:23:12 +0000672 const MethodHandleItem& GetMethodHandle(uint32_t idx) const {
673 CHECK_LT(idx, NumMethodHandles());
674 return method_handles_[idx];
675 }
676
677 uint32_t NumCallSiteIds() const {
678 return num_call_site_ids_;
679 }
680
681 const CallSiteIdItem& GetCallSiteId(uint32_t idx) const {
682 CHECK_LT(idx, NumCallSiteIds());
683 return call_site_ids_[idx];
684 }
685
Ian Rogers0571d352011-11-03 19:51:38 -0700686 // Returns a pointer to the raw memory mapped class_data_item
Ian Rogers13735952014-10-08 12:43:28 -0700687 const uint8_t* GetClassData(const ClassDef& class_def) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700688 return (class_def.class_data_off_ == 0) ? nullptr : begin_ + class_def.class_data_off_;
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700689 }
690
Ian Rogers0571d352011-11-03 19:51:38 -0700691 //
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800692 const CodeItem* GetCodeItem(const uint32_t code_off) const {
Alex Light9139e002015-10-09 15:59:48 -0700693 DCHECK_LT(code_off, size_) << "Code item offset larger then maximum allowed offset";
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800694 if (code_off == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700695 return nullptr; // native or abstract method
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700696 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700697 const uint8_t* addr = begin_ + code_off;
698 return reinterpret_cast<const CodeItem*>(addr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700699 }
700
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100701 const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700702
703 // Returns the number of prototype identifiers in the .dex file.
704 size_t NumProtoIds() const {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700705 DCHECK(header_ != nullptr) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700706 return header_->proto_ids_size_;
707 }
708
709 // Returns the ProtoId at the specified index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800710 const ProtoId& GetProtoId(uint16_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700711 DCHECK_LT(idx, NumProtoIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700712 return proto_ids_[idx];
713 }
714
715 uint16_t GetIndexForProtoId(const ProtoId& proto_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800716 CHECK_GE(&proto_id, proto_ids_) << GetLocation();
717 CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700718 return &proto_id - proto_ids_;
719 }
720
721 // Looks up a proto id for a given return type and signature type list
Andreas Gampea5b09a62016-11-17 15:21:22 -0800722 const ProtoId* FindProtoId(dex::TypeIndex return_type_idx,
723 const dex::TypeIndex* signature_type_idxs,
724 uint32_t signature_length) const;
725 const ProtoId* FindProtoId(dex::TypeIndex return_type_idx,
726 const std::vector<dex::TypeIndex>& signature_type_idxs) const {
Vladimir Marko5c96e6b2013-11-14 15:34:17 +0000727 return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size());
728 }
Ian Rogers0571d352011-11-03 19:51:38 -0700729
730 // Given a signature place the type ids into the given vector, returns true on success
Andreas Gampea5b09a62016-11-17 15:21:22 -0800731 bool CreateTypeList(const StringPiece& signature,
732 dex::TypeIndex* return_type_idx,
733 std::vector<dex::TypeIndex>* param_type_idxs) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700734
Ian Rogersd91d6d62013-09-25 20:26:14 -0700735 // Create a Signature from the given string signature or return Signature::NoSignature if not
736 // possible.
737 const Signature CreateSignature(const StringPiece& signature) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700738
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700739 // Returns the short form method descriptor for the given prototype.
Vladimir Marko5c6a5872016-06-27 13:50:16 +0100740 const char* GetShorty(uint32_t proto_idx) const;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700741
742 const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700743 return (proto_id.parameters_off_ == 0)
744 ? nullptr
745 : reinterpret_cast<const TypeList*>(begin_ + proto_id.parameters_off_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700746 }
747
Ian Rogers13735952014-10-08 12:43:28 -0700748 const uint8_t* GetEncodedStaticFieldValuesArray(const ClassDef& class_def) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700749 return (class_def.static_values_off_ == 0) ? 0 : begin_ + class_def.static_values_off_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700750 }
751
Orion Hodson12f4ff42017-01-13 16:43:12 +0000752 const uint8_t* GetCallSiteEncodedValuesArray(const CallSiteIdItem& call_site_id) const {
753 return begin_ + call_site_id.data_off_;
754 }
755
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800756 static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700757
758 // Get the base of the encoded data for the given DexCode.
Ian Rogers13735952014-10-08 12:43:28 -0700759 static const uint8_t* GetCatchHandlerData(const CodeItem& code_item, uint32_t offset) {
760 const uint8_t* handler_data =
761 reinterpret_cast<const uint8_t*>(GetTryItems(code_item, code_item.tries_size_));
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700762 return handler_data + offset;
763 }
764
Ian Rogersdbbc99d2013-04-18 16:51:54 -0700765 // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
766 static int32_t FindTryItem(const CodeItem &code_item, uint32_t address);
767
768 // Find the handler offset associated with the given address (ie dex pc). Returns -1 if none.
769 static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700770
Shih-wei Liao195487c2011-08-20 13:29:04 -0700771 // Get the pointer to the start of the debugging data
Ian Rogers13735952014-10-08 12:43:28 -0700772 const uint8_t* GetDebugInfoStream(const CodeItem* code_item) const {
David Srbecky68529422015-07-07 19:13:29 +0100773 // Check that the offset is in bounds.
774 // Note that although the specification says that 0 should be used if there
775 // is no debug information, some applications incorrectly use 0xFFFFFFFF.
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700776 const uint32_t debug_info_off = code_item->debug_info_off_;
777 return (debug_info_off == 0 || debug_info_off >= size_) ? nullptr : begin_ + debug_info_off;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700778 }
779
David Srbeckyb06e28e2015-12-10 13:15:00 +0000780 struct PositionInfo {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700781 PositionInfo() = default;
David Srbeckyb06e28e2015-12-10 13:15:00 +0000782
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700783 uint32_t address_ = 0; // In 16-bit code units.
784 uint32_t line_ = 0; // Source code line number starting at 1.
785 const char* source_file_ = nullptr; // nullptr if the file from ClassDef still applies.
786 bool prologue_end_ = false;
787 bool epilogue_begin_ = false;
David Srbeckyb06e28e2015-12-10 13:15:00 +0000788 };
789
David Srbeckyb06e28e2015-12-10 13:15:00 +0000790 struct LocalInfo {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700791 LocalInfo() = default;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700792
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700793 const char* name_ = nullptr; // E.g., list. It can be nullptr if unknown.
794 const char* descriptor_ = nullptr; // E.g., Ljava/util/LinkedList;
795 const char* signature_ = nullptr; // E.g., java.util.LinkedList<java.lang.Integer>
796 uint32_t start_address_ = 0; // PC location where the local is first defined.
797 uint32_t end_address_ = 0; // PC location where the local is no longer defined.
798 uint16_t reg_ = 0; // Dex register which stores the values.
799 bool is_live_ = false; // Is the local defined and live.
David Srbeckyb06e28e2015-12-10 13:15:00 +0000800 };
801
802 // Callback for "new locals table entry".
803 typedef void (*DexDebugNewLocalCb)(void* context, const LocalInfo& entry);
804
805 static bool LineNumForPcCb(void* context, const PositionInfo& entry);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700806
Jeff Hao13e748b2015-08-25 20:44:19 +0000807 const AnnotationsDirectoryItem* GetAnnotationsDirectory(const ClassDef& class_def) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700808 return (class_def.annotations_off_ == 0)
809 ? nullptr
810 : reinterpret_cast<const AnnotationsDirectoryItem*>(begin_ + class_def.annotations_off_);
Jeff Hao13e748b2015-08-25 20:44:19 +0000811 }
812
813 const AnnotationSetItem* GetClassAnnotationSet(const AnnotationsDirectoryItem* anno_dir) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700814 return (anno_dir->class_annotations_off_ == 0)
815 ? nullptr
816 : reinterpret_cast<const AnnotationSetItem*>(begin_ + anno_dir->class_annotations_off_);
Jeff Hao13e748b2015-08-25 20:44:19 +0000817 }
818
819 const FieldAnnotationsItem* GetFieldAnnotations(const AnnotationsDirectoryItem* anno_dir) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700820 return (anno_dir->fields_size_ == 0)
821 ? nullptr
822 : reinterpret_cast<const FieldAnnotationsItem*>(&anno_dir[1]);
Jeff Hao13e748b2015-08-25 20:44:19 +0000823 }
824
825 const MethodAnnotationsItem* GetMethodAnnotations(const AnnotationsDirectoryItem* anno_dir)
826 const {
827 if (anno_dir->methods_size_ == 0) {
828 return nullptr;
Jeff Hao13e748b2015-08-25 20:44:19 +0000829 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700830 // Skip past the header and field annotations.
831 const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
832 addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
833 return reinterpret_cast<const MethodAnnotationsItem*>(addr);
Jeff Hao13e748b2015-08-25 20:44:19 +0000834 }
835
836 const ParameterAnnotationsItem* GetParameterAnnotations(const AnnotationsDirectoryItem* anno_dir)
837 const {
838 if (anno_dir->parameters_size_ == 0) {
839 return nullptr;
Jeff Hao13e748b2015-08-25 20:44:19 +0000840 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700841 // Skip past the header, field annotations, and method annotations.
842 const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
843 addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
844 addr += anno_dir->methods_size_ * sizeof(MethodAnnotationsItem);
845 return reinterpret_cast<const ParameterAnnotationsItem*>(addr);
Jeff Hao13e748b2015-08-25 20:44:19 +0000846 }
847
848 const AnnotationSetItem* GetFieldAnnotationSetItem(const FieldAnnotationsItem& anno_item) const {
849 uint32_t offset = anno_item.annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700850 return (offset == 0)
851 ? nullptr
852 : reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000853 }
854
855 const AnnotationSetItem* GetMethodAnnotationSetItem(const MethodAnnotationsItem& anno_item)
856 const {
857 uint32_t offset = anno_item.annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700858 return (offset == 0)
859 ? nullptr
860 : reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000861 }
862
863 const AnnotationSetRefList* GetParameterAnnotationSetRefList(
864 const ParameterAnnotationsItem* anno_item) const {
865 uint32_t offset = anno_item->annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700866 return (offset == 0)
867 ? nullptr
868 : reinterpret_cast<const AnnotationSetRefList*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000869 }
870
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700871 ALWAYS_INLINE const AnnotationItem* GetAnnotationItemAtOffset(uint32_t offset) const {
872 DCHECK_LE(offset, Size());
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700873 return (offset == 0)
874 ? nullptr
875 : reinterpret_cast<const AnnotationItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000876 }
877
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700878 const AnnotationItem* GetAnnotationItem(const AnnotationSetItem* set_item, uint32_t index) const {
879 DCHECK_LE(index, set_item->size_);
880 return GetAnnotationItemAtOffset(set_item->entries_[index]);
881 }
882
Jeff Hao13e748b2015-08-25 20:44:19 +0000883 const AnnotationSetItem* GetSetRefItemItem(const AnnotationSetRefItem* anno_item) const {
884 uint32_t offset = anno_item->annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700885 return (offset == 0)
886 ? nullptr
887 : reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000888 }
889
Shih-wei Liao195487c2011-08-20 13:29:04 -0700890 // Debug info opcodes and constants
891 enum {
892 DBG_END_SEQUENCE = 0x00,
893 DBG_ADVANCE_PC = 0x01,
894 DBG_ADVANCE_LINE = 0x02,
895 DBG_START_LOCAL = 0x03,
896 DBG_START_LOCAL_EXTENDED = 0x04,
897 DBG_END_LOCAL = 0x05,
898 DBG_RESTART_LOCAL = 0x06,
899 DBG_SET_PROLOGUE_END = 0x07,
900 DBG_SET_EPILOGUE_BEGIN = 0x08,
901 DBG_SET_FILE = 0x09,
902 DBG_FIRST_SPECIAL = 0x0a,
903 DBG_LINE_BASE = -4,
904 DBG_LINE_RANGE = 15,
905 };
906
Shih-wei Liao195487c2011-08-20 13:29:04 -0700907 struct LineNumFromPcContext {
Ian Rogersca190662012-06-26 15:45:57 -0700908 LineNumFromPcContext(uint32_t address, uint32_t line_num)
909 : address_(address), line_num_(line_num) {}
Shih-wei Liao195487c2011-08-20 13:29:04 -0700910 uint32_t address_;
911 uint32_t line_num_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700912 private:
913 DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700914 };
915
Roland Levillain91d65e02016-01-19 15:59:16 +0000916 // Returns false if there is no debugging information or if it cannot be decoded.
David Sehraa6abb02017-10-12 08:25:11 -0700917 template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
918 static bool DecodeDebugLocalInfo(const uint8_t* stream,
919 const std::string& location,
920 const char* declaring_class_descriptor,
921 const std::vector<const char*>& arg_descriptors,
922 const std::string& method_name,
923 bool is_static,
924 uint16_t registers_size,
925 uint16_t ins_size,
926 uint16_t insns_size_in_code_units,
927 IndexToStringData index_to_string_data,
928 TypeIndexToStringData type_index_to_string_data,
929 NewLocalCallback new_local,
930 void* context);
931 template<typename NewLocalCallback>
932 bool DecodeDebugLocalInfo(const CodeItem* code_item,
933 bool is_static,
934 uint32_t method_idx,
935 NewLocalCallback new_local,
936 void* context) const;
David Srbeckyb06e28e2015-12-10 13:15:00 +0000937
Roland Levillain91d65e02016-01-19 15:59:16 +0000938 // Returns false if there is no debugging information or if it cannot be decoded.
David Sehraa6abb02017-10-12 08:25:11 -0700939 template<typename DexDebugNewPosition, typename IndexToStringData>
940 static bool DecodeDebugPositionInfo(const uint8_t* stream,
941 IndexToStringData index_to_string_data,
942 DexDebugNewPosition position_functor,
943 void* context);
944 template<typename DexDebugNewPosition>
945 bool DecodeDebugPositionInfo(const CodeItem* code_item,
946 DexDebugNewPosition position_functor,
David Srbeckyb06e28e2015-12-10 13:15:00 +0000947 void* context) const;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700948
Ian Rogers0571d352011-11-03 19:51:38 -0700949 const char* GetSourceFile(const ClassDef& class_def) const {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800950 if (!class_def.source_file_idx_.IsValid()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700951 return nullptr;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700952 } else {
Ian Rogers0571d352011-11-03 19:51:38 -0700953 return StringDataByIdx(class_def.source_file_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700954 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700955 }
956
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800957 int GetPermissions() const;
Ian Rogers1c849e52012-06-28 14:00:33 -0700958
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200959 bool IsReadOnly() const;
960
Brian Carlstrome0948e12013-08-29 09:36:15 -0700961 bool EnableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200962
Brian Carlstrome0948e12013-08-29 09:36:15 -0700963 bool DisableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200964
Ian Rogers13735952014-10-08 12:43:28 -0700965 const uint8_t* Begin() const {
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700966 return begin_;
967 }
968
969 size_t Size() const {
970 return size_;
971 }
972
Richard Uhler07b3c232015-03-31 15:57:54 -0700973 const OatDexFile* GetOatDexFile() const {
974 return oat_dex_file_;
Andreas Gampefd9eb392014-11-06 16:52:58 -0800975 }
976
Mathieu Chartier1b868492016-11-16 16:22:37 -0800977 // Used by oat writer.
978 void SetOatDexFile(OatDexFile* oat_dex_file) const {
979 oat_dex_file_ = oat_dex_file;
980 }
981
David Sehr9323e6e2016-09-13 08:58:35 -0700982 // Utility methods for reading integral values from a buffer.
983 static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth);
984 static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right);
985 static int64_t ReadSignedLong(const uint8_t* ptr, int zwidth);
986 static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right);
987
Alex Light40528472017-03-28 09:07:36 -0700988 // Recalculates the checksum of the dex file. Does not use the current value in the header.
989 uint32_t CalculateChecksum() const;
990
David Sehr709b0702016-10-13 09:12:37 -0700991 // Returns a human-readable form of the method at an index.
992 std::string PrettyMethod(uint32_t method_idx, bool with_signature = true) const;
993 // Returns a human-readable form of the field at an index.
994 std::string PrettyField(uint32_t field_idx, bool with_type = true) const;
995 // Returns a human-readable form of the type at an index.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800996 std::string PrettyType(dex::TypeIndex type_idx) const;
David Sehr709b0702016-10-13 09:12:37 -0700997
Mathieu Chartier69147f12017-11-06 20:02:24 -0800998 // Not virtual for performance reasons.
999 ALWAYS_INLINE bool IsCompactDexFile() const {
1000 return is_compact_dex_;
Mathieu Chartier603ccab2017-10-20 14:34:28 -07001001 }
Mathieu Chartier69147f12017-11-06 20:02:24 -08001002 ALWAYS_INLINE bool IsStandardDexFile() const {
1003 return !is_compact_dex_;
Mathieu Chartier603ccab2017-10-20 14:34:28 -07001004 }
Mathieu Chartier69147f12017-11-06 20:02:24 -08001005 ALWAYS_INLINE const StandardDexFile* AsStandardDexFile() const;
1006 ALWAYS_INLINE const CompactDexFile* AsCompactDexFile() const;
Mathieu Chartier603ccab2017-10-20 14:34:28 -07001007
Mathieu Chartier7b074bf2017-09-25 16:22:36 -07001008 protected:
David Sehr733ddb22016-09-19 15:02:18 -07001009 DexFile(const uint8_t* base,
1010 size_t size,
Brian Carlstrom28db0122012-10-18 16:20:41 -07001011 const std::string& location,
1012 uint32_t location_checksum,
David Sehr733bd4d2017-10-26 10:39:15 -07001013 const OatDexFile* oat_dex_file,
Mathieu Chartier69147f12017-11-06 20:02:24 -08001014 DexFileContainer* container,
1015 bool is_compact_dex);
jeffhaof6174e82012-01-31 16:14:17 -08001016
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001017 // Top-level initializer that calls other Init methods.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001018 bool Init(std::string* error_msg);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001019
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -08001020 // Returns true if the header magic and version numbers are of the expected values.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001021 bool CheckMagicAndVersion(std::string* error_msg) const;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001022
Orion Hodson12f4ff42017-01-13 16:43:12 +00001023 // Initialize section info for sections only found in map. Returns true on success.
1024 void InitializeSectionsFromMapList();
1025
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001026 // The base address of the memory mapping.
Ian Rogers13735952014-10-08 12:43:28 -07001027 const uint8_t* const begin_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001028
1029 // The size of the underlying memory allocation in bytes.
Ian Rogers62d6c772013-02-27 08:32:07 -08001030 const size_t size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001031
Elliott Hughes64bf5a32011-09-20 14:43:12 -07001032 // Typically the dex file name when available, alternatively some identifying string.
Brian Carlstroma663ea52011-08-19 23:33:41 -07001033 //
1034 // The ClassLinker will use this to match DexFiles the boot class
1035 // path to DexCache::GetLocation when loading from an image.
1036 const std::string location_;
1037
Brian Carlstrom5b332c82012-02-01 15:02:31 -08001038 const uint32_t location_checksum_;
1039
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001040 // Points to the header section.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001041 const Header* const header_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001042
1043 // Points to the base of the string identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001044 const StringId* const string_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001045
1046 // Points to the base of the type identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001047 const TypeId* const type_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001048
1049 // Points to the base of the field identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001050 const FieldId* const field_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001051
1052 // Points to the base of the method identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001053 const MethodId* const method_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001054
1055 // Points to the base of the prototype identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001056 const ProtoId* const proto_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001057
1058 // Points to the base of the class definition list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001059 const ClassDef* const class_defs_;
Ian Rogers68b56852014-08-29 20:19:11 -07001060
Orion Hodson12f4ff42017-01-13 16:43:12 +00001061 // Points to the base of the method handles list.
1062 const MethodHandleItem* method_handles_;
1063
1064 // Number of elements in the method handles list.
1065 size_t num_method_handles_;
1066
1067 // Points to the base of the call sites id list.
1068 const CallSiteIdItem* call_site_ids_;
1069
1070 // Number of elements in the call sites list.
1071 size_t num_call_site_ids_;
1072
Richard Uhler07b3c232015-03-31 15:57:54 -07001073 // If this dex file was loaded from an oat file, oat_dex_file_ contains a
1074 // pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
1075 // null.
Mathieu Chartier1b868492016-11-16 16:22:37 -08001076 mutable const OatDexFile* oat_dex_file_;
Andreas Gampee6215c02015-08-31 18:54:38 -07001077
David Sehr733bd4d2017-10-26 10:39:15 -07001078 // Manages the underlying memory allocation.
1079 std::unique_ptr<DexFileContainer> container_;
1080
Mathieu Chartier69147f12017-11-06 20:02:24 -08001081 // If the dex file is a compact dex file. If false then the dex file is a standard dex file.
1082 const bool is_compact_dex_;
1083
Mathieu Chartier79c87da2017-10-10 11:54:29 -07001084 friend class DexFileLoader;
Andreas Gampee6215c02015-08-31 18:54:38 -07001085 friend class DexFileVerifierTest;
Mathieu Chartier1b868492016-11-16 16:22:37 -08001086 friend class OatWriter;
Carl Shapiro1fb86202011-06-27 17:43:13 -07001087};
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001088
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001089std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);
Carl Shapiro1fb86202011-06-27 17:43:13 -07001090
Ian Rogers0571d352011-11-03 19:51:38 -07001091// Iterate over a dex file's ProtoId's paramters
1092class DexFileParameterIterator {
1093 public:
1094 DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id)
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001095 : dex_file_(dex_file) {
Ian Rogers0571d352011-11-03 19:51:38 -07001096 type_list_ = dex_file_.GetProtoParameters(proto_id);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001097 if (type_list_ != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -07001098 size_ = type_list_->Size();
1099 }
1100 }
1101 bool HasNext() const { return pos_ < size_; }
David Srbeckyb06e28e2015-12-10 13:15:00 +00001102 size_t Size() const { return size_; }
Ian Rogers0571d352011-11-03 19:51:38 -07001103 void Next() { ++pos_; }
Andreas Gampea5b09a62016-11-17 15:21:22 -08001104 dex::TypeIndex GetTypeIdx() {
Ian Rogers0571d352011-11-03 19:51:38 -07001105 return type_list_->GetTypeItem(pos_).type_idx_;
1106 }
1107 const char* GetDescriptor() {
Andreas Gampea5b09a62016-11-17 15:21:22 -08001108 return dex_file_.StringByTypeIdx(dex::TypeIndex(GetTypeIdx()));
Ian Rogers0571d352011-11-03 19:51:38 -07001109 }
1110 private:
1111 const DexFile& dex_file_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001112 const DexFile::TypeList* type_list_ = nullptr;
1113 uint32_t size_ = 0;
1114 uint32_t pos_ = 0;
Ian Rogers0571d352011-11-03 19:51:38 -07001115 DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
1116};
1117
Ian Rogersd91d6d62013-09-25 20:26:14 -07001118// Abstract the signature of a method.
Ian Rogers03b6eaf2014-10-28 09:34:57 -07001119class Signature : public ValueObject {
Ian Rogersd91d6d62013-09-25 20:26:14 -07001120 public:
1121 std::string ToString() const;
1122
1123 static Signature NoSignature() {
1124 return Signature();
1125 }
1126
Orion Hodson6c4921b2016-09-21 15:41:06 +01001127 bool IsVoid() const;
1128 uint32_t GetNumberOfParameters() const;
1129
Ian Rogersdfb325e2013-10-30 01:00:44 -07001130 bool operator==(const Signature& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001131 bool operator!=(const Signature& rhs) const {
1132 return !(*this == rhs);
1133 }
1134
Vladimir Markod9cffea2013-11-25 15:08:02 +00001135 bool operator==(const StringPiece& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001136
1137 private:
1138 Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
1139 }
1140
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001141 Signature() = default;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001142
1143 friend class DexFile;
1144
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001145 const DexFile* const dex_file_ = nullptr;
1146 const DexFile::ProtoId* const proto_id_ = nullptr;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001147};
1148std::ostream& operator<<(std::ostream& os, const Signature& sig);
1149
Ian Rogers0571d352011-11-03 19:51:38 -07001150// Iterate and decode class_data_item
1151class ClassDataItemIterator {
1152 public:
Ian Rogers13735952014-10-08 12:43:28 -07001153 ClassDataItemIterator(const DexFile& dex_file, const uint8_t* raw_class_data_item)
Ian Rogers0571d352011-11-03 19:51:38 -07001154 : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) {
1155 ReadClassDataHeader();
1156 if (EndOfInstanceFieldsPos() > 0) {
1157 ReadClassDataField();
1158 } else if (EndOfVirtualMethodsPos() > 0) {
1159 ReadClassDataMethod();
1160 }
1161 }
1162 uint32_t NumStaticFields() const {
1163 return header_.static_fields_size_;
1164 }
1165 uint32_t NumInstanceFields() const {
1166 return header_.instance_fields_size_;
1167 }
1168 uint32_t NumDirectMethods() const {
1169 return header_.direct_methods_size_;
1170 }
1171 uint32_t NumVirtualMethods() const {
1172 return header_.virtual_methods_size_;
1173 }
Alex Light40528472017-03-28 09:07:36 -07001174 bool IsAtMethod() const {
1175 return pos_ >= EndOfInstanceFieldsPos();
1176 }
Ian Rogers0571d352011-11-03 19:51:38 -07001177 bool HasNextStaticField() const {
1178 return pos_ < EndOfStaticFieldsPos();
1179 }
1180 bool HasNextInstanceField() const {
1181 return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos();
1182 }
1183 bool HasNextDirectMethod() const {
1184 return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos();
1185 }
1186 bool HasNextVirtualMethod() const {
1187 return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos();
1188 }
Mathieu Chartierb7c273c2017-11-10 18:07:56 -08001189 bool HasNextMethod() const {
1190 const bool result = pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfVirtualMethodsPos();
1191 DCHECK_EQ(result, HasNextDirectMethod() || HasNextVirtualMethod());
1192 return result;
1193 }
Mathieu Chartiere17cf242017-06-19 11:05:51 -07001194 void SkipStaticFields() {
1195 while (HasNextStaticField()) {
1196 Next();
1197 }
1198 }
1199 void SkipInstanceFields() {
1200 while (HasNextInstanceField()) {
1201 Next();
1202 }
1203 }
1204 void SkipAllFields() {
1205 SkipStaticFields();
1206 SkipInstanceFields();
1207 }
1208 void SkipDirectMethods() {
1209 while (HasNextDirectMethod()) {
1210 Next();
1211 }
1212 }
1213 void SkipVirtualMethods() {
1214 while (HasNextVirtualMethod()) {
1215 Next();
1216 }
1217 }
Ian Rogers0571d352011-11-03 19:51:38 -07001218 bool HasNext() const {
1219 return pos_ < EndOfVirtualMethodsPos();
1220 }
Ian Rogers637c65b2013-05-31 11:46:00 -07001221 inline void Next() {
Ian Rogers0571d352011-11-03 19:51:38 -07001222 pos_++;
1223 if (pos_ < EndOfStaticFieldsPos()) {
1224 last_idx_ = GetMemberIndex();
1225 ReadClassDataField();
1226 } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) {
1227 last_idx_ = 0; // transition to next array, reset last index
1228 ReadClassDataField();
1229 } else if (pos_ < EndOfInstanceFieldsPos()) {
1230 last_idx_ = GetMemberIndex();
1231 ReadClassDataField();
1232 } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) {
1233 last_idx_ = 0; // transition to next array, reset last index
1234 ReadClassDataMethod();
1235 } else if (pos_ < EndOfDirectMethodsPos()) {
1236 last_idx_ = GetMemberIndex();
1237 ReadClassDataMethod();
1238 } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) {
1239 last_idx_ = 0; // transition to next array, reset last index
1240 ReadClassDataMethod();
1241 } else if (pos_ < EndOfVirtualMethodsPos()) {
1242 last_idx_ = GetMemberIndex();
1243 ReadClassDataMethod();
1244 } else {
1245 DCHECK(!HasNext());
1246 }
1247 }
1248 uint32_t GetMemberIndex() const {
1249 if (pos_ < EndOfInstanceFieldsPos()) {
1250 return last_idx_ + field_.field_idx_delta_;
1251 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001252 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001253 return last_idx_ + method_.method_idx_delta_;
1254 }
1255 }
Andreas Gampe51829322014-08-25 15:05:04 -07001256 uint32_t GetRawMemberAccessFlags() const {
Ian Rogers0571d352011-11-03 19:51:38 -07001257 if (pos_ < EndOfInstanceFieldsPos()) {
1258 return field_.access_flags_;
1259 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001260 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001261 return method_.access_flags_;
1262 }
1263 }
Andreas Gampe51829322014-08-25 15:05:04 -07001264 uint32_t GetFieldAccessFlags() const {
1265 return GetRawMemberAccessFlags() & kAccValidFieldFlags;
1266 }
1267 uint32_t GetMethodAccessFlags() const {
1268 return GetRawMemberAccessFlags() & kAccValidMethodFlags;
1269 }
1270 bool MemberIsNative() const {
1271 return GetRawMemberAccessFlags() & kAccNative;
1272 }
1273 bool MemberIsFinal() const {
1274 return GetRawMemberAccessFlags() & kAccFinal;
1275 }
Andreas Gampe04c6ab92017-06-08 21:49:14 -07001276 ALWAYS_INLINE InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const;
Ian Rogers0571d352011-11-03 19:51:38 -07001277 const DexFile::CodeItem* GetMethodCodeItem() const {
1278 return dex_file_.GetCodeItem(method_.code_off_);
1279 }
1280 uint32_t GetMethodCodeItemOffset() const {
1281 return method_.code_off_;
1282 }
Andreas Gampee6215c02015-08-31 18:54:38 -07001283 const uint8_t* DataPointer() const {
1284 return ptr_pos_;
1285 }
Ian Rogers13735952014-10-08 12:43:28 -07001286 const uint8_t* EndDataPointer() const {
jeffhao10037c82012-01-23 15:06:23 -08001287 CHECK(!HasNext());
1288 return ptr_pos_;
1289 }
Elliott Hughesa21039c2012-06-21 12:09:25 -07001290
Ian Rogers0571d352011-11-03 19:51:38 -07001291 private:
1292 // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the
1293 // header for a class_data_item
1294 struct ClassDataHeader {
1295 uint32_t static_fields_size_; // the number of static fields
1296 uint32_t instance_fields_size_; // the number of instance fields
1297 uint32_t direct_methods_size_; // the number of direct methods
1298 uint32_t virtual_methods_size_; // the number of virtual methods
1299 } header_;
1300
1301 // Read and decode header from a class_data_item stream into header
1302 void ReadClassDataHeader();
1303
1304 uint32_t EndOfStaticFieldsPos() const {
1305 return header_.static_fields_size_;
1306 }
1307 uint32_t EndOfInstanceFieldsPos() const {
1308 return EndOfStaticFieldsPos() + header_.instance_fields_size_;
1309 }
1310 uint32_t EndOfDirectMethodsPos() const {
1311 return EndOfInstanceFieldsPos() + header_.direct_methods_size_;
1312 }
1313 uint32_t EndOfVirtualMethodsPos() const {
1314 return EndOfDirectMethodsPos() + header_.virtual_methods_size_;
1315 }
1316
1317 // A decoded version of the field of a class_data_item
1318 struct ClassDataField {
1319 uint32_t field_idx_delta_; // delta of index into the field_ids array for FieldId
1320 uint32_t access_flags_; // access flags for the field
1321 ClassDataField() : field_idx_delta_(0), access_flags_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001322
Ian Rogers0571d352011-11-03 19:51:38 -07001323 private:
1324 DISALLOW_COPY_AND_ASSIGN(ClassDataField);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001325 };
1326 ClassDataField field_;
Ian Rogers0571d352011-11-03 19:51:38 -07001327
1328 // Read and decode a field from a class_data_item stream into field
1329 void ReadClassDataField();
1330
1331 // A decoded version of the method of a class_data_item
1332 struct ClassDataMethod {
1333 uint32_t method_idx_delta_; // delta of index into the method_ids array for MethodId
1334 uint32_t access_flags_;
1335 uint32_t code_off_;
1336 ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001337
Ian Rogers0571d352011-11-03 19:51:38 -07001338 private:
1339 DISALLOW_COPY_AND_ASSIGN(ClassDataMethod);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001340 };
1341 ClassDataMethod method_;
Ian Rogers0571d352011-11-03 19:51:38 -07001342
1343 // Read and decode a method from a class_data_item stream into method
1344 void ReadClassDataMethod();
1345
1346 const DexFile& dex_file_;
1347 size_t pos_; // integral number of items passed
Ian Rogers13735952014-10-08 12:43:28 -07001348 const uint8_t* ptr_pos_; // pointer into stream of class_data_item
Ian Rogers0571d352011-11-03 19:51:38 -07001349 uint32_t last_idx_; // last read field or method index to apply delta to
1350 DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
1351};
1352
Orion Hodson12f4ff42017-01-13 16:43:12 +00001353class EncodedArrayValueIterator {
Ian Rogers0571d352011-11-03 19:51:38 -07001354 public:
Orion Hodson12f4ff42017-01-13 16:43:12 +00001355 EncodedArrayValueIterator(const DexFile& dex_file, const uint8_t* array_data);
Shinichiro Hamaji82863f02015-11-05 16:51:33 +09001356
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001357 bool HasNext() const { return pos_ < array_size_; }
Ian Rogers0571d352011-11-03 19:51:38 -07001358
1359 void Next();
Elliott Hughesa21039c2012-06-21 12:09:25 -07001360
Ian Rogers0571d352011-11-03 19:51:38 -07001361 enum ValueType {
Orion Hodson12f4ff42017-01-13 16:43:12 +00001362 kByte = 0x00,
1363 kShort = 0x02,
1364 kChar = 0x03,
1365 kInt = 0x04,
1366 kLong = 0x06,
1367 kFloat = 0x10,
1368 kDouble = 0x11,
1369 kMethodType = 0x15,
1370 kMethodHandle = 0x16,
1371 kString = 0x17,
1372 kType = 0x18,
1373 kField = 0x19,
1374 kMethod = 0x1a,
1375 kEnum = 0x1b,
1376 kArray = 0x1c,
1377 kAnnotation = 0x1d,
1378 kNull = 0x1e,
1379 kBoolean = 0x1f,
Ian Rogers0571d352011-11-03 19:51:38 -07001380 };
1381
Shinichiro Hamaji82863f02015-11-05 16:51:33 +09001382 ValueType GetValueType() const { return type_; }
1383 const jvalue& GetJavaValue() const { return jval_; }
1384
David Sehr9323e6e2016-09-13 08:58:35 -07001385 protected:
Ian Rogers13735952014-10-08 12:43:28 -07001386 static constexpr uint8_t kEncodedValueTypeMask = 0x1f; // 0b11111
1387 static constexpr uint8_t kEncodedValueArgShift = 5;
Ian Rogers0571d352011-11-03 19:51:38 -07001388
1389 const DexFile& dex_file_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001390 size_t array_size_; // Size of array.
1391 size_t pos_; // Current position.
Ian Rogers13735952014-10-08 12:43:28 -07001392 const uint8_t* ptr_; // Pointer into encoded data array.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001393 ValueType type_; // Type of current encoded value.
1394 jvalue jval_; // Value of current encoded value.
David Sehr9323e6e2016-09-13 08:58:35 -07001395
1396 private:
Orion Hodson12f4ff42017-01-13 16:43:12 +00001397 DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedArrayValueIterator);
1398};
1399std::ostream& operator<<(std::ostream& os, const EncodedArrayValueIterator::ValueType& code);
1400
1401class EncodedStaticFieldValueIterator : public EncodedArrayValueIterator {
1402 public:
1403 EncodedStaticFieldValueIterator(const DexFile& dex_file,
1404 const DexFile::ClassDef& class_def)
1405 : EncodedArrayValueIterator(dex_file,
1406 dex_file.GetEncodedStaticFieldValuesArray(class_def))
1407 {}
1408
1409 private:
Ian Rogers0571d352011-11-03 19:51:38 -07001410 DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
1411};
Brian Carlstrom88f36542012-10-16 23:24:21 -07001412std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code);
Ian Rogers0571d352011-11-03 19:51:38 -07001413
Orion Hodson12f4ff42017-01-13 16:43:12 +00001414class CallSiteArrayValueIterator : public EncodedArrayValueIterator {
1415 public:
1416 CallSiteArrayValueIterator(const DexFile& dex_file,
1417 const DexFile::CallSiteIdItem& call_site_id)
1418 : EncodedArrayValueIterator(dex_file,
1419 dex_file.GetCallSiteEncodedValuesArray(call_site_id))
1420 {}
1421
1422 uint32_t Size() const { return array_size_; }
1423
1424 private:
1425 DISALLOW_IMPLICIT_CONSTRUCTORS(CallSiteArrayValueIterator);
1426};
1427std::ostream& operator<<(std::ostream& os, const CallSiteArrayValueIterator::ValueType& code);
1428
Ian Rogers0571d352011-11-03 19:51:38 -07001429class CatchHandlerIterator {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001430 public:
1431 CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address);
Logan Chien736df022012-04-27 16:25:57 +08001432
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001433 CatchHandlerIterator(const DexFile::CodeItem& code_item,
1434 const DexFile::TryItem& try_item);
Logan Chien736df022012-04-27 16:25:57 +08001435
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001436 explicit CatchHandlerIterator(const uint8_t* handler_data) {
1437 Init(handler_data);
1438 }
Ian Rogers0571d352011-11-03 19:51:38 -07001439
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001440 dex::TypeIndex GetHandlerTypeIndex() const {
1441 return handler_.type_idx_;
1442 }
1443 uint32_t GetHandlerAddress() const {
1444 return handler_.address_;
1445 }
1446 void Next();
1447 bool HasNext() const {
1448 return remaining_count_ != -1 || catch_all_;
1449 }
1450 // End of this set of catch blocks, convenience method to locate next set of catch blocks
1451 const uint8_t* EndDataPointer() const {
1452 CHECK(!HasNext());
1453 return current_data_;
1454 }
Elliott Hughesa21039c2012-06-21 12:09:25 -07001455
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001456 private:
1457 void Init(const DexFile::CodeItem& code_item, int32_t offset);
1458 void Init(const uint8_t* handler_data);
Ian Rogers0571d352011-11-03 19:51:38 -07001459
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001460 struct CatchHandlerItem {
1461 dex::TypeIndex type_idx_; // type index of the caught exception type
1462 uint32_t address_; // handler address
1463 } handler_;
1464 const uint8_t* current_data_; // the current handler in dex file.
1465 int32_t remaining_count_; // number of handlers not read.
1466 bool catch_all_; // is there a handler that will catch all exceptions in case
1467 // that all typed handler does not match.
Ian Rogers0571d352011-11-03 19:51:38 -07001468};
1469
Carl Shapiro1fb86202011-06-27 17:43:13 -07001470} // namespace art
1471
Brian Carlstromfc0e3212013-07-17 14:40:12 -07001472#endif // ART_RUNTIME_DEX_FILE_H_