blob: cdefb234000e4a707f8cb82158faaa37bfb5fc2e [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
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800756 static const TryItem* GetTryItems(const DexInstructionIterator& code_item_end, uint32_t offset);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800757 static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700758
759 // Get the base of the encoded data for the given DexCode.
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800760 static const uint8_t* GetCatchHandlerData(const DexInstructionIterator& code_item_end,
761 uint32_t tries_size,
762 uint32_t offset) {
Ian Rogers13735952014-10-08 12:43:28 -0700763 const uint8_t* handler_data =
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800764 reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size));
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700765 return handler_data + offset;
766 }
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800767 static const uint8_t* GetCatchHandlerData(const CodeItem& code_item, uint32_t offset) {
768 return GetCatchHandlerData(code_item.Instructions().end(), code_item.tries_size_, offset);
769 }
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700770
Ian Rogersdbbc99d2013-04-18 16:51:54 -0700771 // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800772 static int32_t FindTryItem(const TryItem* try_items, uint32_t tries_size, uint32_t address);
Ian Rogersdbbc99d2013-04-18 16:51:54 -0700773
774 // Find the handler offset associated with the given address (ie dex pc). Returns -1 if none.
775 static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700776
Shih-wei Liao195487c2011-08-20 13:29:04 -0700777 // Get the pointer to the start of the debugging data
Ian Rogers13735952014-10-08 12:43:28 -0700778 const uint8_t* GetDebugInfoStream(const CodeItem* code_item) const {
David Srbecky68529422015-07-07 19:13:29 +0100779 // Check that the offset is in bounds.
780 // Note that although the specification says that 0 should be used if there
781 // is no debug information, some applications incorrectly use 0xFFFFFFFF.
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700782 const uint32_t debug_info_off = code_item->debug_info_off_;
783 return (debug_info_off == 0 || debug_info_off >= size_) ? nullptr : begin_ + debug_info_off;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700784 }
785
David Srbeckyb06e28e2015-12-10 13:15:00 +0000786 struct PositionInfo {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700787 PositionInfo() = default;
David Srbeckyb06e28e2015-12-10 13:15:00 +0000788
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700789 uint32_t address_ = 0; // In 16-bit code units.
790 uint32_t line_ = 0; // Source code line number starting at 1.
791 const char* source_file_ = nullptr; // nullptr if the file from ClassDef still applies.
792 bool prologue_end_ = false;
793 bool epilogue_begin_ = false;
David Srbeckyb06e28e2015-12-10 13:15:00 +0000794 };
795
David Srbeckyb06e28e2015-12-10 13:15:00 +0000796 struct LocalInfo {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700797 LocalInfo() = default;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700798
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700799 const char* name_ = nullptr; // E.g., list. It can be nullptr if unknown.
800 const char* descriptor_ = nullptr; // E.g., Ljava/util/LinkedList;
801 const char* signature_ = nullptr; // E.g., java.util.LinkedList<java.lang.Integer>
802 uint32_t start_address_ = 0; // PC location where the local is first defined.
803 uint32_t end_address_ = 0; // PC location where the local is no longer defined.
804 uint16_t reg_ = 0; // Dex register which stores the values.
805 bool is_live_ = false; // Is the local defined and live.
David Srbeckyb06e28e2015-12-10 13:15:00 +0000806 };
807
808 // Callback for "new locals table entry".
809 typedef void (*DexDebugNewLocalCb)(void* context, const LocalInfo& entry);
810
811 static bool LineNumForPcCb(void* context, const PositionInfo& entry);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700812
Jeff Hao13e748b2015-08-25 20:44:19 +0000813 const AnnotationsDirectoryItem* GetAnnotationsDirectory(const ClassDef& class_def) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700814 return (class_def.annotations_off_ == 0)
815 ? nullptr
816 : reinterpret_cast<const AnnotationsDirectoryItem*>(begin_ + class_def.annotations_off_);
Jeff Hao13e748b2015-08-25 20:44:19 +0000817 }
818
819 const AnnotationSetItem* GetClassAnnotationSet(const AnnotationsDirectoryItem* anno_dir) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700820 return (anno_dir->class_annotations_off_ == 0)
821 ? nullptr
822 : reinterpret_cast<const AnnotationSetItem*>(begin_ + anno_dir->class_annotations_off_);
Jeff Hao13e748b2015-08-25 20:44:19 +0000823 }
824
825 const FieldAnnotationsItem* GetFieldAnnotations(const AnnotationsDirectoryItem* anno_dir) const {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700826 return (anno_dir->fields_size_ == 0)
827 ? nullptr
828 : reinterpret_cast<const FieldAnnotationsItem*>(&anno_dir[1]);
Jeff Hao13e748b2015-08-25 20:44:19 +0000829 }
830
831 const MethodAnnotationsItem* GetMethodAnnotations(const AnnotationsDirectoryItem* anno_dir)
832 const {
833 if (anno_dir->methods_size_ == 0) {
834 return nullptr;
Jeff Hao13e748b2015-08-25 20:44:19 +0000835 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700836 // Skip past the header and field annotations.
837 const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
838 addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
839 return reinterpret_cast<const MethodAnnotationsItem*>(addr);
Jeff Hao13e748b2015-08-25 20:44:19 +0000840 }
841
842 const ParameterAnnotationsItem* GetParameterAnnotations(const AnnotationsDirectoryItem* anno_dir)
843 const {
844 if (anno_dir->parameters_size_ == 0) {
845 return nullptr;
Jeff Hao13e748b2015-08-25 20:44:19 +0000846 }
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700847 // Skip past the header, field annotations, and method annotations.
848 const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
849 addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
850 addr += anno_dir->methods_size_ * sizeof(MethodAnnotationsItem);
851 return reinterpret_cast<const ParameterAnnotationsItem*>(addr);
Jeff Hao13e748b2015-08-25 20:44:19 +0000852 }
853
854 const AnnotationSetItem* GetFieldAnnotationSetItem(const FieldAnnotationsItem& anno_item) const {
855 uint32_t offset = anno_item.annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700856 return (offset == 0)
857 ? nullptr
858 : reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000859 }
860
861 const AnnotationSetItem* GetMethodAnnotationSetItem(const MethodAnnotationsItem& anno_item)
862 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
869 const AnnotationSetRefList* GetParameterAnnotationSetRefList(
870 const ParameterAnnotationsItem* anno_item) const {
871 uint32_t offset = anno_item->annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700872 return (offset == 0)
873 ? nullptr
874 : reinterpret_cast<const AnnotationSetRefList*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000875 }
876
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700877 ALWAYS_INLINE const AnnotationItem* GetAnnotationItemAtOffset(uint32_t offset) const {
878 DCHECK_LE(offset, Size());
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700879 return (offset == 0)
880 ? nullptr
881 : reinterpret_cast<const AnnotationItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000882 }
883
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700884 const AnnotationItem* GetAnnotationItem(const AnnotationSetItem* set_item, uint32_t index) const {
885 DCHECK_LE(index, set_item->size_);
886 return GetAnnotationItemAtOffset(set_item->entries_[index]);
887 }
888
Jeff Hao13e748b2015-08-25 20:44:19 +0000889 const AnnotationSetItem* GetSetRefItemItem(const AnnotationSetRefItem* anno_item) const {
890 uint32_t offset = anno_item->annotations_off_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -0700891 return (offset == 0)
892 ? nullptr
893 : reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
Jeff Hao13e748b2015-08-25 20:44:19 +0000894 }
895
Shih-wei Liao195487c2011-08-20 13:29:04 -0700896 // Debug info opcodes and constants
897 enum {
898 DBG_END_SEQUENCE = 0x00,
899 DBG_ADVANCE_PC = 0x01,
900 DBG_ADVANCE_LINE = 0x02,
901 DBG_START_LOCAL = 0x03,
902 DBG_START_LOCAL_EXTENDED = 0x04,
903 DBG_END_LOCAL = 0x05,
904 DBG_RESTART_LOCAL = 0x06,
905 DBG_SET_PROLOGUE_END = 0x07,
906 DBG_SET_EPILOGUE_BEGIN = 0x08,
907 DBG_SET_FILE = 0x09,
908 DBG_FIRST_SPECIAL = 0x0a,
909 DBG_LINE_BASE = -4,
910 DBG_LINE_RANGE = 15,
911 };
912
Shih-wei Liao195487c2011-08-20 13:29:04 -0700913 struct LineNumFromPcContext {
Ian Rogersca190662012-06-26 15:45:57 -0700914 LineNumFromPcContext(uint32_t address, uint32_t line_num)
915 : address_(address), line_num_(line_num) {}
Shih-wei Liao195487c2011-08-20 13:29:04 -0700916 uint32_t address_;
917 uint32_t line_num_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700918 private:
919 DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700920 };
921
Roland Levillain91d65e02016-01-19 15:59:16 +0000922 // Returns false if there is no debugging information or if it cannot be decoded.
David Sehraa6abb02017-10-12 08:25:11 -0700923 template<typename NewLocalCallback, typename IndexToStringData, typename TypeIndexToStringData>
924 static bool DecodeDebugLocalInfo(const uint8_t* stream,
925 const std::string& location,
926 const char* declaring_class_descriptor,
927 const std::vector<const char*>& arg_descriptors,
928 const std::string& method_name,
929 bool is_static,
930 uint16_t registers_size,
931 uint16_t ins_size,
932 uint16_t insns_size_in_code_units,
933 IndexToStringData index_to_string_data,
934 TypeIndexToStringData type_index_to_string_data,
935 NewLocalCallback new_local,
936 void* context);
937 template<typename NewLocalCallback>
938 bool DecodeDebugLocalInfo(const CodeItem* code_item,
939 bool is_static,
940 uint32_t method_idx,
941 NewLocalCallback new_local,
942 void* context) const;
David Srbeckyb06e28e2015-12-10 13:15:00 +0000943
Roland Levillain91d65e02016-01-19 15:59:16 +0000944 // Returns false if there is no debugging information or if it cannot be decoded.
David Sehraa6abb02017-10-12 08:25:11 -0700945 template<typename DexDebugNewPosition, typename IndexToStringData>
946 static bool DecodeDebugPositionInfo(const uint8_t* stream,
947 IndexToStringData index_to_string_data,
948 DexDebugNewPosition position_functor,
949 void* context);
950 template<typename DexDebugNewPosition>
951 bool DecodeDebugPositionInfo(const CodeItem* code_item,
952 DexDebugNewPosition position_functor,
David Srbeckyb06e28e2015-12-10 13:15:00 +0000953 void* context) const;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700954
Ian Rogers0571d352011-11-03 19:51:38 -0700955 const char* GetSourceFile(const ClassDef& class_def) const {
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800956 if (!class_def.source_file_idx_.IsValid()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700957 return nullptr;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700958 } else {
Ian Rogers0571d352011-11-03 19:51:38 -0700959 return StringDataByIdx(class_def.source_file_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700960 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700961 }
962
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800963 int GetPermissions() const;
Ian Rogers1c849e52012-06-28 14:00:33 -0700964
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200965 bool IsReadOnly() const;
966
Brian Carlstrome0948e12013-08-29 09:36:15 -0700967 bool EnableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200968
Brian Carlstrome0948e12013-08-29 09:36:15 -0700969 bool DisableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200970
Ian Rogers13735952014-10-08 12:43:28 -0700971 const uint8_t* Begin() const {
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700972 return begin_;
973 }
974
975 size_t Size() const {
976 return size_;
977 }
978
Richard Uhler07b3c232015-03-31 15:57:54 -0700979 const OatDexFile* GetOatDexFile() const {
980 return oat_dex_file_;
Andreas Gampefd9eb392014-11-06 16:52:58 -0800981 }
982
Mathieu Chartier1b868492016-11-16 16:22:37 -0800983 // Used by oat writer.
984 void SetOatDexFile(OatDexFile* oat_dex_file) const {
985 oat_dex_file_ = oat_dex_file;
986 }
987
David Sehr9323e6e2016-09-13 08:58:35 -0700988 // Utility methods for reading integral values from a buffer.
989 static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth);
990 static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right);
991 static int64_t ReadSignedLong(const uint8_t* ptr, int zwidth);
992 static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right);
993
Alex Light40528472017-03-28 09:07:36 -0700994 // Recalculates the checksum of the dex file. Does not use the current value in the header.
995 uint32_t CalculateChecksum() const;
996
David Sehr709b0702016-10-13 09:12:37 -0700997 // Returns a human-readable form of the method at an index.
998 std::string PrettyMethod(uint32_t method_idx, bool with_signature = true) const;
999 // Returns a human-readable form of the field at an index.
1000 std::string PrettyField(uint32_t field_idx, bool with_type = true) const;
1001 // Returns a human-readable form of the type at an index.
Andreas Gampea5b09a62016-11-17 15:21:22 -08001002 std::string PrettyType(dex::TypeIndex type_idx) const;
David Sehr709b0702016-10-13 09:12:37 -07001003
Mathieu Chartier69147f12017-11-06 20:02:24 -08001004 // Not virtual for performance reasons.
1005 ALWAYS_INLINE bool IsCompactDexFile() const {
1006 return is_compact_dex_;
Mathieu Chartier603ccab2017-10-20 14:34:28 -07001007 }
Mathieu Chartier69147f12017-11-06 20:02:24 -08001008 ALWAYS_INLINE bool IsStandardDexFile() const {
1009 return !is_compact_dex_;
Mathieu Chartier603ccab2017-10-20 14:34:28 -07001010 }
Mathieu Chartier69147f12017-11-06 20:02:24 -08001011 ALWAYS_INLINE const StandardDexFile* AsStandardDexFile() const;
1012 ALWAYS_INLINE const CompactDexFile* AsCompactDexFile() const;
Mathieu Chartier603ccab2017-10-20 14:34:28 -07001013
Mathieu Chartier7b074bf2017-09-25 16:22:36 -07001014 protected:
David Sehr733ddb22016-09-19 15:02:18 -07001015 DexFile(const uint8_t* base,
1016 size_t size,
Brian Carlstrom28db0122012-10-18 16:20:41 -07001017 const std::string& location,
1018 uint32_t location_checksum,
David Sehr733bd4d2017-10-26 10:39:15 -07001019 const OatDexFile* oat_dex_file,
Mathieu Chartier69147f12017-11-06 20:02:24 -08001020 DexFileContainer* container,
1021 bool is_compact_dex);
jeffhaof6174e82012-01-31 16:14:17 -08001022
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001023 // Top-level initializer that calls other Init methods.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001024 bool Init(std::string* error_msg);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001025
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -08001026 // Returns true if the header magic and version numbers are of the expected values.
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001027 bool CheckMagicAndVersion(std::string* error_msg) const;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001028
Orion Hodson12f4ff42017-01-13 16:43:12 +00001029 // Initialize section info for sections only found in map. Returns true on success.
1030 void InitializeSectionsFromMapList();
1031
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001032 // The base address of the memory mapping.
Ian Rogers13735952014-10-08 12:43:28 -07001033 const uint8_t* const begin_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001034
1035 // The size of the underlying memory allocation in bytes.
Ian Rogers62d6c772013-02-27 08:32:07 -08001036 const size_t size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001037
Elliott Hughes64bf5a32011-09-20 14:43:12 -07001038 // Typically the dex file name when available, alternatively some identifying string.
Brian Carlstroma663ea52011-08-19 23:33:41 -07001039 //
1040 // The ClassLinker will use this to match DexFiles the boot class
1041 // path to DexCache::GetLocation when loading from an image.
1042 const std::string location_;
1043
Brian Carlstrom5b332c82012-02-01 15:02:31 -08001044 const uint32_t location_checksum_;
1045
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001046 // Points to the header section.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001047 const Header* const header_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001048
1049 // Points to the base of the string identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001050 const StringId* const string_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001051
1052 // Points to the base of the type identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001053 const TypeId* const type_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001054
1055 // Points to the base of the field identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001056 const FieldId* const field_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001057
1058 // Points to the base of the method identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001059 const MethodId* const method_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001060
1061 // Points to the base of the prototype identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001062 const ProtoId* const proto_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07001063
1064 // Points to the base of the class definition list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001065 const ClassDef* const class_defs_;
Ian Rogers68b56852014-08-29 20:19:11 -07001066
Orion Hodson12f4ff42017-01-13 16:43:12 +00001067 // Points to the base of the method handles list.
1068 const MethodHandleItem* method_handles_;
1069
1070 // Number of elements in the method handles list.
1071 size_t num_method_handles_;
1072
1073 // Points to the base of the call sites id list.
1074 const CallSiteIdItem* call_site_ids_;
1075
1076 // Number of elements in the call sites list.
1077 size_t num_call_site_ids_;
1078
Richard Uhler07b3c232015-03-31 15:57:54 -07001079 // If this dex file was loaded from an oat file, oat_dex_file_ contains a
1080 // pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
1081 // null.
Mathieu Chartier1b868492016-11-16 16:22:37 -08001082 mutable const OatDexFile* oat_dex_file_;
Andreas Gampee6215c02015-08-31 18:54:38 -07001083
David Sehr733bd4d2017-10-26 10:39:15 -07001084 // Manages the underlying memory allocation.
1085 std::unique_ptr<DexFileContainer> container_;
1086
Mathieu Chartier69147f12017-11-06 20:02:24 -08001087 // If the dex file is a compact dex file. If false then the dex file is a standard dex file.
1088 const bool is_compact_dex_;
1089
Mathieu Chartier79c87da2017-10-10 11:54:29 -07001090 friend class DexFileLoader;
Andreas Gampee6215c02015-08-31 18:54:38 -07001091 friend class DexFileVerifierTest;
Mathieu Chartier1b868492016-11-16 16:22:37 -08001092 friend class OatWriter;
Carl Shapiro1fb86202011-06-27 17:43:13 -07001093};
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001094
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001095std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);
Carl Shapiro1fb86202011-06-27 17:43:13 -07001096
Ian Rogers0571d352011-11-03 19:51:38 -07001097// Iterate over a dex file's ProtoId's paramters
1098class DexFileParameterIterator {
1099 public:
1100 DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id)
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001101 : dex_file_(dex_file) {
Ian Rogers0571d352011-11-03 19:51:38 -07001102 type_list_ = dex_file_.GetProtoParameters(proto_id);
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001103 if (type_list_ != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -07001104 size_ = type_list_->Size();
1105 }
1106 }
1107 bool HasNext() const { return pos_ < size_; }
David Srbeckyb06e28e2015-12-10 13:15:00 +00001108 size_t Size() const { return size_; }
Ian Rogers0571d352011-11-03 19:51:38 -07001109 void Next() { ++pos_; }
Andreas Gampea5b09a62016-11-17 15:21:22 -08001110 dex::TypeIndex GetTypeIdx() {
Ian Rogers0571d352011-11-03 19:51:38 -07001111 return type_list_->GetTypeItem(pos_).type_idx_;
1112 }
1113 const char* GetDescriptor() {
Andreas Gampea5b09a62016-11-17 15:21:22 -08001114 return dex_file_.StringByTypeIdx(dex::TypeIndex(GetTypeIdx()));
Ian Rogers0571d352011-11-03 19:51:38 -07001115 }
1116 private:
1117 const DexFile& dex_file_;
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001118 const DexFile::TypeList* type_list_ = nullptr;
1119 uint32_t size_ = 0;
1120 uint32_t pos_ = 0;
Ian Rogers0571d352011-11-03 19:51:38 -07001121 DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
1122};
1123
Ian Rogersd91d6d62013-09-25 20:26:14 -07001124// Abstract the signature of a method.
Ian Rogers03b6eaf2014-10-28 09:34:57 -07001125class Signature : public ValueObject {
Ian Rogersd91d6d62013-09-25 20:26:14 -07001126 public:
1127 std::string ToString() const;
1128
1129 static Signature NoSignature() {
1130 return Signature();
1131 }
1132
Orion Hodson6c4921b2016-09-21 15:41:06 +01001133 bool IsVoid() const;
1134 uint32_t GetNumberOfParameters() const;
1135
Ian Rogersdfb325e2013-10-30 01:00:44 -07001136 bool operator==(const Signature& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001137 bool operator!=(const Signature& rhs) const {
1138 return !(*this == rhs);
1139 }
1140
Vladimir Markod9cffea2013-11-25 15:08:02 +00001141 bool operator==(const StringPiece& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001142
1143 private:
1144 Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
1145 }
1146
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001147 Signature() = default;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001148
1149 friend class DexFile;
1150
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001151 const DexFile* const dex_file_ = nullptr;
1152 const DexFile::ProtoId* const proto_id_ = nullptr;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001153};
1154std::ostream& operator<<(std::ostream& os, const Signature& sig);
1155
Ian Rogers0571d352011-11-03 19:51:38 -07001156// Iterate and decode class_data_item
1157class ClassDataItemIterator {
1158 public:
Ian Rogers13735952014-10-08 12:43:28 -07001159 ClassDataItemIterator(const DexFile& dex_file, const uint8_t* raw_class_data_item)
Ian Rogers0571d352011-11-03 19:51:38 -07001160 : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) {
1161 ReadClassDataHeader();
1162 if (EndOfInstanceFieldsPos() > 0) {
1163 ReadClassDataField();
1164 } else if (EndOfVirtualMethodsPos() > 0) {
1165 ReadClassDataMethod();
1166 }
1167 }
1168 uint32_t NumStaticFields() const {
1169 return header_.static_fields_size_;
1170 }
1171 uint32_t NumInstanceFields() const {
1172 return header_.instance_fields_size_;
1173 }
1174 uint32_t NumDirectMethods() const {
1175 return header_.direct_methods_size_;
1176 }
1177 uint32_t NumVirtualMethods() const {
1178 return header_.virtual_methods_size_;
1179 }
Alex Light40528472017-03-28 09:07:36 -07001180 bool IsAtMethod() const {
1181 return pos_ >= EndOfInstanceFieldsPos();
1182 }
Ian Rogers0571d352011-11-03 19:51:38 -07001183 bool HasNextStaticField() const {
1184 return pos_ < EndOfStaticFieldsPos();
1185 }
1186 bool HasNextInstanceField() const {
1187 return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos();
1188 }
1189 bool HasNextDirectMethod() const {
1190 return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos();
1191 }
1192 bool HasNextVirtualMethod() const {
1193 return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos();
1194 }
Mathieu Chartierb7c273c2017-11-10 18:07:56 -08001195 bool HasNextMethod() const {
1196 const bool result = pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfVirtualMethodsPos();
1197 DCHECK_EQ(result, HasNextDirectMethod() || HasNextVirtualMethod());
1198 return result;
1199 }
Mathieu Chartiere17cf242017-06-19 11:05:51 -07001200 void SkipStaticFields() {
1201 while (HasNextStaticField()) {
1202 Next();
1203 }
1204 }
1205 void SkipInstanceFields() {
1206 while (HasNextInstanceField()) {
1207 Next();
1208 }
1209 }
1210 void SkipAllFields() {
1211 SkipStaticFields();
1212 SkipInstanceFields();
1213 }
1214 void SkipDirectMethods() {
1215 while (HasNextDirectMethod()) {
1216 Next();
1217 }
1218 }
1219 void SkipVirtualMethods() {
1220 while (HasNextVirtualMethod()) {
1221 Next();
1222 }
1223 }
Ian Rogers0571d352011-11-03 19:51:38 -07001224 bool HasNext() const {
1225 return pos_ < EndOfVirtualMethodsPos();
1226 }
Ian Rogers637c65b2013-05-31 11:46:00 -07001227 inline void Next() {
Ian Rogers0571d352011-11-03 19:51:38 -07001228 pos_++;
1229 if (pos_ < EndOfStaticFieldsPos()) {
1230 last_idx_ = GetMemberIndex();
1231 ReadClassDataField();
1232 } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) {
1233 last_idx_ = 0; // transition to next array, reset last index
1234 ReadClassDataField();
1235 } else if (pos_ < EndOfInstanceFieldsPos()) {
1236 last_idx_ = GetMemberIndex();
1237 ReadClassDataField();
1238 } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) {
1239 last_idx_ = 0; // transition to next array, reset last index
1240 ReadClassDataMethod();
1241 } else if (pos_ < EndOfDirectMethodsPos()) {
1242 last_idx_ = GetMemberIndex();
1243 ReadClassDataMethod();
1244 } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) {
1245 last_idx_ = 0; // transition to next array, reset last index
1246 ReadClassDataMethod();
1247 } else if (pos_ < EndOfVirtualMethodsPos()) {
1248 last_idx_ = GetMemberIndex();
1249 ReadClassDataMethod();
1250 } else {
1251 DCHECK(!HasNext());
1252 }
1253 }
1254 uint32_t GetMemberIndex() const {
1255 if (pos_ < EndOfInstanceFieldsPos()) {
1256 return last_idx_ + field_.field_idx_delta_;
1257 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001258 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001259 return last_idx_ + method_.method_idx_delta_;
1260 }
1261 }
Andreas Gampe51829322014-08-25 15:05:04 -07001262 uint32_t GetRawMemberAccessFlags() const {
Ian Rogers0571d352011-11-03 19:51:38 -07001263 if (pos_ < EndOfInstanceFieldsPos()) {
1264 return field_.access_flags_;
1265 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001266 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001267 return method_.access_flags_;
1268 }
1269 }
Andreas Gampe51829322014-08-25 15:05:04 -07001270 uint32_t GetFieldAccessFlags() const {
1271 return GetRawMemberAccessFlags() & kAccValidFieldFlags;
1272 }
1273 uint32_t GetMethodAccessFlags() const {
1274 return GetRawMemberAccessFlags() & kAccValidMethodFlags;
1275 }
1276 bool MemberIsNative() const {
1277 return GetRawMemberAccessFlags() & kAccNative;
1278 }
1279 bool MemberIsFinal() const {
1280 return GetRawMemberAccessFlags() & kAccFinal;
1281 }
Andreas Gampe04c6ab92017-06-08 21:49:14 -07001282 ALWAYS_INLINE InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const;
Ian Rogers0571d352011-11-03 19:51:38 -07001283 const DexFile::CodeItem* GetMethodCodeItem() const {
1284 return dex_file_.GetCodeItem(method_.code_off_);
1285 }
1286 uint32_t GetMethodCodeItemOffset() const {
1287 return method_.code_off_;
1288 }
Andreas Gampee6215c02015-08-31 18:54:38 -07001289 const uint8_t* DataPointer() const {
1290 return ptr_pos_;
1291 }
Ian Rogers13735952014-10-08 12:43:28 -07001292 const uint8_t* EndDataPointer() const {
jeffhao10037c82012-01-23 15:06:23 -08001293 CHECK(!HasNext());
1294 return ptr_pos_;
1295 }
Elliott Hughesa21039c2012-06-21 12:09:25 -07001296
Ian Rogers0571d352011-11-03 19:51:38 -07001297 private:
1298 // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the
1299 // header for a class_data_item
1300 struct ClassDataHeader {
1301 uint32_t static_fields_size_; // the number of static fields
1302 uint32_t instance_fields_size_; // the number of instance fields
1303 uint32_t direct_methods_size_; // the number of direct methods
1304 uint32_t virtual_methods_size_; // the number of virtual methods
1305 } header_;
1306
1307 // Read and decode header from a class_data_item stream into header
1308 void ReadClassDataHeader();
1309
1310 uint32_t EndOfStaticFieldsPos() const {
1311 return header_.static_fields_size_;
1312 }
1313 uint32_t EndOfInstanceFieldsPos() const {
1314 return EndOfStaticFieldsPos() + header_.instance_fields_size_;
1315 }
1316 uint32_t EndOfDirectMethodsPos() const {
1317 return EndOfInstanceFieldsPos() + header_.direct_methods_size_;
1318 }
1319 uint32_t EndOfVirtualMethodsPos() const {
1320 return EndOfDirectMethodsPos() + header_.virtual_methods_size_;
1321 }
1322
1323 // A decoded version of the field of a class_data_item
1324 struct ClassDataField {
1325 uint32_t field_idx_delta_; // delta of index into the field_ids array for FieldId
1326 uint32_t access_flags_; // access flags for the field
1327 ClassDataField() : field_idx_delta_(0), access_flags_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001328
Ian Rogers0571d352011-11-03 19:51:38 -07001329 private:
1330 DISALLOW_COPY_AND_ASSIGN(ClassDataField);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001331 };
1332 ClassDataField field_;
Ian Rogers0571d352011-11-03 19:51:38 -07001333
1334 // Read and decode a field from a class_data_item stream into field
1335 void ReadClassDataField();
1336
1337 // A decoded version of the method of a class_data_item
1338 struct ClassDataMethod {
1339 uint32_t method_idx_delta_; // delta of index into the method_ids array for MethodId
1340 uint32_t access_flags_;
1341 uint32_t code_off_;
1342 ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001343
Ian Rogers0571d352011-11-03 19:51:38 -07001344 private:
1345 DISALLOW_COPY_AND_ASSIGN(ClassDataMethod);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001346 };
1347 ClassDataMethod method_;
Ian Rogers0571d352011-11-03 19:51:38 -07001348
1349 // Read and decode a method from a class_data_item stream into method
1350 void ReadClassDataMethod();
1351
1352 const DexFile& dex_file_;
1353 size_t pos_; // integral number of items passed
Ian Rogers13735952014-10-08 12:43:28 -07001354 const uint8_t* ptr_pos_; // pointer into stream of class_data_item
Ian Rogers0571d352011-11-03 19:51:38 -07001355 uint32_t last_idx_; // last read field or method index to apply delta to
1356 DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
1357};
1358
Orion Hodson12f4ff42017-01-13 16:43:12 +00001359class EncodedArrayValueIterator {
Ian Rogers0571d352011-11-03 19:51:38 -07001360 public:
Orion Hodson12f4ff42017-01-13 16:43:12 +00001361 EncodedArrayValueIterator(const DexFile& dex_file, const uint8_t* array_data);
Shinichiro Hamaji82863f02015-11-05 16:51:33 +09001362
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001363 bool HasNext() const { return pos_ < array_size_; }
Ian Rogers0571d352011-11-03 19:51:38 -07001364
1365 void Next();
Elliott Hughesa21039c2012-06-21 12:09:25 -07001366
Ian Rogers0571d352011-11-03 19:51:38 -07001367 enum ValueType {
Orion Hodson12f4ff42017-01-13 16:43:12 +00001368 kByte = 0x00,
1369 kShort = 0x02,
1370 kChar = 0x03,
1371 kInt = 0x04,
1372 kLong = 0x06,
1373 kFloat = 0x10,
1374 kDouble = 0x11,
1375 kMethodType = 0x15,
1376 kMethodHandle = 0x16,
1377 kString = 0x17,
1378 kType = 0x18,
1379 kField = 0x19,
1380 kMethod = 0x1a,
1381 kEnum = 0x1b,
1382 kArray = 0x1c,
1383 kAnnotation = 0x1d,
1384 kNull = 0x1e,
1385 kBoolean = 0x1f,
Ian Rogers0571d352011-11-03 19:51:38 -07001386 };
1387
Shinichiro Hamaji82863f02015-11-05 16:51:33 +09001388 ValueType GetValueType() const { return type_; }
1389 const jvalue& GetJavaValue() const { return jval_; }
1390
David Sehr9323e6e2016-09-13 08:58:35 -07001391 protected:
Ian Rogers13735952014-10-08 12:43:28 -07001392 static constexpr uint8_t kEncodedValueTypeMask = 0x1f; // 0b11111
1393 static constexpr uint8_t kEncodedValueArgShift = 5;
Ian Rogers0571d352011-11-03 19:51:38 -07001394
1395 const DexFile& dex_file_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001396 size_t array_size_; // Size of array.
1397 size_t pos_; // Current position.
Ian Rogers13735952014-10-08 12:43:28 -07001398 const uint8_t* ptr_; // Pointer into encoded data array.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001399 ValueType type_; // Type of current encoded value.
1400 jvalue jval_; // Value of current encoded value.
David Sehr9323e6e2016-09-13 08:58:35 -07001401
1402 private:
Orion Hodson12f4ff42017-01-13 16:43:12 +00001403 DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedArrayValueIterator);
1404};
1405std::ostream& operator<<(std::ostream& os, const EncodedArrayValueIterator::ValueType& code);
1406
1407class EncodedStaticFieldValueIterator : public EncodedArrayValueIterator {
1408 public:
1409 EncodedStaticFieldValueIterator(const DexFile& dex_file,
1410 const DexFile::ClassDef& class_def)
1411 : EncodedArrayValueIterator(dex_file,
1412 dex_file.GetEncodedStaticFieldValuesArray(class_def))
1413 {}
1414
1415 private:
Ian Rogers0571d352011-11-03 19:51:38 -07001416 DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
1417};
Brian Carlstrom88f36542012-10-16 23:24:21 -07001418std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code);
Ian Rogers0571d352011-11-03 19:51:38 -07001419
Orion Hodson12f4ff42017-01-13 16:43:12 +00001420class CallSiteArrayValueIterator : public EncodedArrayValueIterator {
1421 public:
1422 CallSiteArrayValueIterator(const DexFile& dex_file,
1423 const DexFile::CallSiteIdItem& call_site_id)
1424 : EncodedArrayValueIterator(dex_file,
1425 dex_file.GetCallSiteEncodedValuesArray(call_site_id))
1426 {}
1427
1428 uint32_t Size() const { return array_size_; }
1429
1430 private:
1431 DISALLOW_IMPLICIT_CONSTRUCTORS(CallSiteArrayValueIterator);
1432};
1433std::ostream& operator<<(std::ostream& os, const CallSiteArrayValueIterator::ValueType& code);
1434
Ian Rogers0571d352011-11-03 19:51:38 -07001435class CatchHandlerIterator {
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001436 public:
1437 CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address);
Logan Chien736df022012-04-27 16:25:57 +08001438
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001439 CatchHandlerIterator(const DexFile::CodeItem& code_item,
1440 const DexFile::TryItem& try_item);
Logan Chien736df022012-04-27 16:25:57 +08001441
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001442 explicit CatchHandlerIterator(const uint8_t* handler_data) {
1443 Init(handler_data);
1444 }
Ian Rogers0571d352011-11-03 19:51:38 -07001445
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001446 dex::TypeIndex GetHandlerTypeIndex() const {
1447 return handler_.type_idx_;
1448 }
1449 uint32_t GetHandlerAddress() const {
1450 return handler_.address_;
1451 }
1452 void Next();
1453 bool HasNext() const {
1454 return remaining_count_ != -1 || catch_all_;
1455 }
1456 // End of this set of catch blocks, convenience method to locate next set of catch blocks
1457 const uint8_t* EndDataPointer() const {
1458 CHECK(!HasNext());
1459 return current_data_;
1460 }
Elliott Hughesa21039c2012-06-21 12:09:25 -07001461
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001462 private:
1463 void Init(const DexFile::CodeItem& code_item, int32_t offset);
1464 void Init(const uint8_t* handler_data);
Ian Rogers0571d352011-11-03 19:51:38 -07001465
Mathieu Chartier73d7b2d2017-10-09 16:41:33 -07001466 struct CatchHandlerItem {
1467 dex::TypeIndex type_idx_; // type index of the caught exception type
1468 uint32_t address_; // handler address
1469 } handler_;
1470 const uint8_t* current_data_; // the current handler in dex file.
1471 int32_t remaining_count_; // number of handlers not read.
1472 bool catch_all_; // is there a handler that will catch all exceptions in case
1473 // that all typed handler does not match.
Ian Rogers0571d352011-11-03 19:51:38 -07001474};
1475
Carl Shapiro1fb86202011-06-27 17:43:13 -07001476} // namespace art
1477
Brian Carlstromfc0e3212013-07-17 14:40:12 -07001478#endif // ART_RUNTIME_DEX_FILE_H_