blob: c1602530196306f84d3521073b2c203b954b97ed [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>
Ian Rogers68b56852014-08-29 20:19:11 -070022#include <unordered_map>
Brian Carlstrom74eb46a2011-08-02 20:10:14 -070023#include <vector>
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070024
Elliott Hughes07ed66b2012-12-12 18:34:25 -080025#include "base/logging.h"
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070026#include "base/mutex.h" // For Locks::mutator_lock_.
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070027#include "globals.h"
Ian Rogers08f753d2012-08-24 14:35:25 -070028#include "invoke_type.h"
Jesse Wilson6bf19152011-09-29 13:12:33 -040029#include "jni.h"
Ian Rogers08f753d2012-08-24 14:35:25 -070030#include "modifiers.h"
Ian Rogers68b56852014-08-29 20:19:11 -070031#include "utf.h"
Carl Shapiro1fb86202011-06-27 17:43:13 -070032
33namespace art {
34
Brian Carlstrome8104522013-10-15 21:56:36 -070035// TODO: remove dependencies on mirror classes, primarily by moving
36// EncodedStaticFieldValueIterator to its own file.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080037namespace mirror {
Brian Carlstromea46f952013-07-30 01:26:50 -070038 class ArtField;
39 class ArtMethod;
40 class ClassLoader;
41 class DexCache;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080042} // namespace mirror
43class ClassLinker;
Ian Rogers576ca0c2014-06-06 15:58:22 -070044class MemMap;
Ian Rogersd91d6d62013-09-25 20:26:14 -070045class Signature;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070046template<class T> class Handle;
Ian Rogersfc0e94b2013-09-23 23:51:32 -070047class StringPiece;
Brian Carlstroma6cc8932012-01-04 14:44:07 -080048class ZipArchive;
49
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070050// TODO: move all of the macro functionality into the DexCache class.
Brian Carlstromf615a612011-07-23 12:50:34 -070051class DexFile {
Carl Shapiro1fb86202011-06-27 17:43:13 -070052 public:
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070053 static const byte kDexMagic[];
54 static const byte kDexMagicVersion[];
55 static const size_t kSha1DigestSize = 20;
jeffhao10037c82012-01-23 15:06:23 -080056 static const uint32_t kDexEndianConstant = 0x12345678;
Carl Shapiro80d4dde2011-06-28 16:24:07 -070057
Brian Carlstromb7bbba42011-10-13 14:58:47 -070058 // name of the DexFile entry within a zip archive
59 static const char* kClassesDex;
60
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070061 // The value of an invalid index.
62 static const uint32_t kDexNoIndex = 0xFFFFFFFF;
63
Ian Rogers0571d352011-11-03 19:51:38 -070064 // The value of an invalid index.
65 static const uint16_t kDexNoIndex16 = 0xFFFF;
Carl Shapiro1fb86202011-06-27 17:43:13 -070066
Andreas Gampe833a4852014-05-21 18:46:59 -070067 // The separator charactor in MultiDex locations.
68 static constexpr char kMultiDexSeparator = ':';
69
70 // A string version of the previous. This is a define so that we can merge string literals in the
71 // preprocessor.
72 #define kMultiDexSeparatorString ":"
73
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070074 // Raw header_item.
75 struct Header {
76 uint8_t magic_[8];
Brian Carlstrom7934ac22013-07-26 10:54:15 -070077 uint32_t checksum_; // See also location_checksum_
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070078 uint8_t signature_[kSha1DigestSize];
jeffhaof6174e82012-01-31 16:14:17 -080079 uint32_t file_size_; // size of entire file
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070080 uint32_t header_size_; // offset to start of next section
81 uint32_t endian_tag_;
Ian Rogers0571d352011-11-03 19:51:38 -070082 uint32_t link_size_; // unused
83 uint32_t link_off_; // unused
84 uint32_t map_off_; // unused
85 uint32_t string_ids_size_; // number of StringIds
86 uint32_t string_ids_off_; // file offset of StringIds array
87 uint32_t type_ids_size_; // number of TypeIds, we don't support more than 65535
88 uint32_t type_ids_off_; // file offset of TypeIds array
89 uint32_t proto_ids_size_; // number of ProtoIds, we don't support more than 65535
90 uint32_t proto_ids_off_; // file offset of ProtoIds array
91 uint32_t field_ids_size_; // number of FieldIds
92 uint32_t field_ids_off_; // file offset of FieldIds array
93 uint32_t method_ids_size_; // number of MethodIds
94 uint32_t method_ids_off_; // file offset of MethodIds array
95 uint32_t class_defs_size_; // number of ClassDefs
96 uint32_t class_defs_off_; // file offset of ClassDef array
97 uint32_t data_size_; // unused
98 uint32_t data_off_; // unused
Elliott Hughesa21039c2012-06-21 12:09:25 -070099
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700100 private:
101 DISALLOW_COPY_AND_ASSIGN(Header);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700102 };
Carl Shapiro1fb86202011-06-27 17:43:13 -0700103
jeffhao10037c82012-01-23 15:06:23 -0800104 // Map item type codes.
105 enum {
106 kDexTypeHeaderItem = 0x0000,
107 kDexTypeStringIdItem = 0x0001,
108 kDexTypeTypeIdItem = 0x0002,
109 kDexTypeProtoIdItem = 0x0003,
110 kDexTypeFieldIdItem = 0x0004,
111 kDexTypeMethodIdItem = 0x0005,
112 kDexTypeClassDefItem = 0x0006,
113 kDexTypeMapList = 0x1000,
114 kDexTypeTypeList = 0x1001,
115 kDexTypeAnnotationSetRefList = 0x1002,
116 kDexTypeAnnotationSetItem = 0x1003,
117 kDexTypeClassDataItem = 0x2000,
118 kDexTypeCodeItem = 0x2001,
119 kDexTypeStringDataItem = 0x2002,
120 kDexTypeDebugInfoItem = 0x2003,
121 kDexTypeAnnotationItem = 0x2004,
122 kDexTypeEncodedArrayItem = 0x2005,
123 kDexTypeAnnotationsDirectoryItem = 0x2006,
124 };
125
126 struct MapItem {
127 uint16_t type_;
128 uint16_t unused_;
129 uint32_t size_;
130 uint32_t offset_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700131
jeffhao10037c82012-01-23 15:06:23 -0800132 private:
133 DISALLOW_COPY_AND_ASSIGN(MapItem);
134 };
135
136 struct MapList {
137 uint32_t size_;
138 MapItem list_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700139
jeffhao10037c82012-01-23 15:06:23 -0800140 private:
141 DISALLOW_COPY_AND_ASSIGN(MapList);
142 };
143
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700144 // Raw string_id_item.
145 struct StringId {
146 uint32_t string_data_off_; // offset in bytes from the base address
Elliott Hughesa21039c2012-06-21 12:09:25 -0700147
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700148 private:
149 DISALLOW_COPY_AND_ASSIGN(StringId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700150 };
151
152 // Raw type_id_item.
153 struct TypeId {
154 uint32_t descriptor_idx_; // index into string_ids
Elliott Hughesa21039c2012-06-21 12:09:25 -0700155
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700156 private:
157 DISALLOW_COPY_AND_ASSIGN(TypeId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700158 };
159
160 // Raw field_id_item.
161 struct FieldId {
Ian Rogers0571d352011-11-03 19:51:38 -0700162 uint16_t class_idx_; // index into type_ids_ array for defining class
163 uint16_t type_idx_; // index into type_ids_ array for field type
164 uint32_t name_idx_; // index into string_ids_ array for field name
Elliott Hughesa21039c2012-06-21 12:09:25 -0700165
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700166 private:
167 DISALLOW_COPY_AND_ASSIGN(FieldId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700168 };
169
170 // Raw method_id_item.
171 struct MethodId {
Ian Rogers0571d352011-11-03 19:51:38 -0700172 uint16_t class_idx_; // index into type_ids_ array for defining class
173 uint16_t proto_idx_; // index into proto_ids_ array for method prototype
174 uint32_t name_idx_; // index into string_ids_ array for method name
Elliott Hughesa21039c2012-06-21 12:09:25 -0700175
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700176 private:
177 DISALLOW_COPY_AND_ASSIGN(MethodId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700178 };
179
180 // Raw proto_id_item.
181 struct ProtoId {
Ian Rogers0571d352011-11-03 19:51:38 -0700182 uint32_t shorty_idx_; // index into string_ids array for shorty descriptor
183 uint16_t return_type_idx_; // index into type_ids array for return type
184 uint16_t pad_; // padding = 0
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700185 uint32_t parameters_off_; // file offset to type_list for parameter types
Elliott Hughesa21039c2012-06-21 12:09:25 -0700186
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700187 private:
188 DISALLOW_COPY_AND_ASSIGN(ProtoId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700189 };
190
191 // Raw class_def_item.
192 struct ClassDef {
Ian Rogers0571d352011-11-03 19:51:38 -0700193 uint16_t class_idx_; // index into type_ids_ array for this class
194 uint16_t pad1_; // padding = 0
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700195 uint32_t access_flags_;
Ian Rogers0571d352011-11-03 19:51:38 -0700196 uint16_t superclass_idx_; // index into type_ids_ array for superclass
197 uint16_t pad2_; // padding = 0
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700198 uint32_t interfaces_off_; // file offset to TypeList
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700199 uint32_t source_file_idx_; // index into string_ids_ for source file name
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700200 uint32_t annotations_off_; // file offset to annotations_directory_item
201 uint32_t class_data_off_; // file offset to class_data_item
202 uint32_t static_values_off_; // file offset to EncodedArray
Elliott Hughesa21039c2012-06-21 12:09:25 -0700203
Andreas Gampe51829322014-08-25 15:05:04 -0700204 // Returns the valid access flags, that is, Java modifier bits relevant to the ClassDef type
205 // (class or interface). These are all in the lower 16b and do not contain runtime flags.
206 uint32_t GetJavaAccessFlags() const {
207 // Make sure that none of our runtime-only flags are set.
208 COMPILE_ASSERT((kAccValidClassFlags & kAccJavaFlagsMask) == kAccValidClassFlags,
209 valid_class_flags_not_subset_of_java_flags);
210 COMPILE_ASSERT((kAccValidInterfaceFlags & kAccJavaFlagsMask) == kAccValidInterfaceFlags,
211 valid_interface_flags_not_subset_of_java_flags);
212
213 if ((access_flags_ & kAccInterface) != 0) {
214 // Interface.
215 return access_flags_ & kAccValidInterfaceFlags;
216 } else {
217 // Class.
218 return access_flags_ & kAccValidClassFlags;
219 }
220 }
221
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700222 private:
223 DISALLOW_COPY_AND_ASSIGN(ClassDef);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700224 };
225
226 // Raw type_item.
227 struct TypeItem {
228 uint16_t type_idx_; // index into type_ids section
Elliott Hughesa21039c2012-06-21 12:09:25 -0700229
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700230 private:
231 DISALLOW_COPY_AND_ASSIGN(TypeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700232 };
233
234 // Raw type_list.
235 class TypeList {
236 public:
237 uint32_t Size() const {
238 return size_;
239 }
240
241 const TypeItem& GetTypeItem(uint32_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200242 DCHECK_LT(idx, this->size_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700243 return this->list_[idx];
244 }
245
Andreas Gampe31a7a0c2014-08-29 16:07:49 -0700246 // Size in bytes of the part of the list that is common.
247 static constexpr size_t GetHeaderSize() {
248 return 4U;
249 }
250
251 // Size in bytes of the whole type list including all the stored elements.
252 static constexpr size_t GetListSize(size_t count) {
253 return GetHeaderSize() + sizeof(TypeItem) * count;
254 }
255
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700256 private:
257 uint32_t size_; // size of the list, in entries
258 TypeItem list_[1]; // elements of the list
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700259 DISALLOW_COPY_AND_ASSIGN(TypeList);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700260 };
261
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700262 // Raw code_item.
263 struct CodeItem {
264 uint16_t registers_size_;
265 uint16_t ins_size_;
266 uint16_t outs_size_;
267 uint16_t tries_size_;
268 uint32_t debug_info_off_; // file offset to debug info stream
Ian Rogersd81871c2011-10-03 13:57:23 -0700269 uint32_t insns_size_in_code_units_; // size of the insns array, in 2 byte code units
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700270 uint16_t insns_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700271
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700272 private:
273 DISALLOW_COPY_AND_ASSIGN(CodeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700274 };
275
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700276 // Raw try_item.
277 struct TryItem {
278 uint32_t start_addr_;
279 uint16_t insn_count_;
280 uint16_t handler_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700281
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700282 private:
283 DISALLOW_COPY_AND_ASSIGN(TryItem);
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700284 };
285
jeffhao10037c82012-01-23 15:06:23 -0800286 // Annotation constants.
287 enum {
288 kDexVisibilityBuild = 0x00, /* annotation visibility */
289 kDexVisibilityRuntime = 0x01,
290 kDexVisibilitySystem = 0x02,
291
292 kDexAnnotationByte = 0x00,
293 kDexAnnotationShort = 0x02,
294 kDexAnnotationChar = 0x03,
295 kDexAnnotationInt = 0x04,
296 kDexAnnotationLong = 0x06,
297 kDexAnnotationFloat = 0x10,
298 kDexAnnotationDouble = 0x11,
299 kDexAnnotationString = 0x17,
300 kDexAnnotationType = 0x18,
301 kDexAnnotationField = 0x19,
302 kDexAnnotationMethod = 0x1a,
303 kDexAnnotationEnum = 0x1b,
304 kDexAnnotationArray = 0x1c,
305 kDexAnnotationAnnotation = 0x1d,
306 kDexAnnotationNull = 0x1e,
307 kDexAnnotationBoolean = 0x1f,
308
309 kDexAnnotationValueTypeMask = 0x1f, /* low 5 bits */
310 kDexAnnotationValueArgShift = 5,
311 };
312
313 struct AnnotationsDirectoryItem {
314 uint32_t class_annotations_off_;
315 uint32_t fields_size_;
316 uint32_t methods_size_;
317 uint32_t parameters_size_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700318
jeffhao10037c82012-01-23 15:06:23 -0800319 private:
320 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
321 };
322
323 struct FieldAnnotationsItem {
324 uint32_t field_idx_;
325 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700326
jeffhao10037c82012-01-23 15:06:23 -0800327 private:
328 DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem);
329 };
330
331 struct MethodAnnotationsItem {
332 uint32_t method_idx_;
333 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700334
jeffhao10037c82012-01-23 15:06:23 -0800335 private:
336 DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem);
337 };
338
339 struct ParameterAnnotationsItem {
340 uint32_t method_idx_;
341 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700342
jeffhao10037c82012-01-23 15:06:23 -0800343 private:
344 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem);
345 };
346
347 struct AnnotationSetRefItem {
348 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700349
jeffhao10037c82012-01-23 15:06:23 -0800350 private:
351 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem);
352 };
353
354 struct AnnotationSetRefList {
355 uint32_t size_;
356 AnnotationSetRefItem list_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700357
jeffhao10037c82012-01-23 15:06:23 -0800358 private:
359 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
360 };
361
362 struct AnnotationSetItem {
363 uint32_t size_;
364 uint32_t entries_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700365
jeffhao10037c82012-01-23 15:06:23 -0800366 private:
367 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
368 };
369
370 struct AnnotationItem {
371 uint8_t visibility_;
372 uint8_t annotation_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700373
jeffhao10037c82012-01-23 15:06:23 -0800374 private:
375 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
376 };
377
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800378 // Returns the checksum of a file for comparison with GetLocationChecksum().
379 // For .dex files, this is the header checksum.
380 // For zip files, this is the classes.dex zip entry CRC32 checksum.
381 // Return true if the checksum could be found, false otherwise.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700382 static bool GetChecksum(const char* filename, uint32_t* checksum, std::string* error_msg);
Brian Carlstrom78128a62011-09-15 17:21:19 -0700383
Andreas Gampe833a4852014-05-21 18:46:59 -0700384 // Opens .dex files found in the container, guessing the container format based on file extension.
385 static bool Open(const char* filename, const char* location, std::string* error_msg,
386 std::vector<const DexFile*>* dex_files);
jeffhao262bf462011-10-20 18:36:32 -0700387
Brian Carlstrom89521892011-12-07 22:05:07 -0800388 // Opens .dex file, backed by existing memory
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800389 static const DexFile* Open(const uint8_t* base, size_t size,
Brian Carlstrom28db0122012-10-18 16:20:41 -0700390 const std::string& location,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700391 uint32_t location_checksum,
392 std::string* error_msg) {
393 return OpenMemory(base, size, location, location_checksum, NULL, error_msg);
Brian Carlstrom89521892011-12-07 22:05:07 -0800394 }
395
Andreas Gampe833a4852014-05-21 18:46:59 -0700396 // Open all classesXXX.dex files from a zip archive.
397 static bool OpenFromZip(const ZipArchive& zip_archive, const std::string& location,
398 std::string* error_msg, std::vector<const DexFile*>* dex_files);
Brian Carlstroma6cc8932012-01-04 14:44:07 -0800399
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700400 // Closes a .dex file.
Brian Carlstromf615a612011-07-23 12:50:34 -0700401 virtual ~DexFile();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700402
Brian Carlstroma663ea52011-08-19 23:33:41 -0700403 const std::string& GetLocation() const {
404 return location_;
405 }
406
Andreas Gampecb8f9e82014-07-24 15:35:50 -0700407 // For normal dex files, location and base location coincide. If a dex file is part of a multidex
408 // archive, the base location is the name of the originating jar/apk, stripped of any internal
409 // classes*.dex path.
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100410 static std::string GetBaseLocation(const char* location) {
411 const char* pos = strrchr(location, kMultiDexSeparator);
412 if (pos == nullptr) {
413 return location;
Andreas Gampecb8f9e82014-07-24 15:35:50 -0700414 } else {
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100415 return std::string(location, pos - location);
416 }
417 }
418
419 std::string GetBaseLocation() const {
420 size_t pos = location_.rfind(kMultiDexSeparator);
421 if (pos == std::string::npos) {
Andreas Gampecb8f9e82014-07-24 15:35:50 -0700422 return location_;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100423 } else {
424 return location_.substr(0, pos);
Andreas Gampecb8f9e82014-07-24 15:35:50 -0700425 }
426 }
427
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800428 // For DexFiles directly from .dex files, this is the checksum from the DexFile::Header.
429 // For DexFiles opened from a zip files, this will be the ZipEntry CRC32 of classes.dex.
430 uint32_t GetLocationChecksum() const {
431 return location_checksum_;
432 }
433
Brian Carlstroma663ea52011-08-19 23:33:41 -0700434 const Header& GetHeader() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700435 DCHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700436 return *header_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700437 }
438
Ian Rogers0571d352011-11-03 19:51:38 -0700439 // Decode the dex magic version
Ian Rogersd81871c2011-10-03 13:57:23 -0700440 uint32_t GetVersion() const;
441
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800442 // Returns true if the byte string points to the magic value.
443 static bool IsMagicValid(const byte* magic);
444
445 // Returns true if the byte string after the magic is the correct value.
446 static bool IsVersionValid(const byte* magic);
447
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700448 // Returns the number of string identifiers in the .dex file.
449 size_t NumStringIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700450 DCHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700451 return header_->string_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700452 }
453
Ian Rogers0571d352011-11-03 19:51:38 -0700454 // Returns the StringId at the specified index.
455 const StringId& GetStringId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700456 DCHECK_LT(idx, NumStringIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700457 return string_ids_[idx];
458 }
459
460 uint32_t GetIndexForStringId(const StringId& string_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800461 CHECK_GE(&string_id, string_ids_) << GetLocation();
462 CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700463 return &string_id - string_ids_;
464 }
465
466 int32_t GetStringLength(const StringId& string_id) const;
467
Ian Rogersdfb325e2013-10-30 01:00:44 -0700468 // Returns a pointer to the UTF-8 string data referred to by the given string_id as well as the
469 // length of the string when decoded as a UTF-16 string. Note the UTF-16 length is not the same
470 // as the string length of the string data.
471 const char* GetStringDataAndUtf16Length(const StringId& string_id, uint32_t* utf16_length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700472
473 const char* GetStringData(const StringId& string_id) const {
Ian Rogersdfb325e2013-10-30 01:00:44 -0700474 uint32_t ignored;
475 return GetStringDataAndUtf16Length(string_id, &ignored);
Ian Rogers0571d352011-11-03 19:51:38 -0700476 }
477
Ian Rogersdfb325e2013-10-30 01:00:44 -0700478 // Index version of GetStringDataAndUtf16Length.
479 const char* StringDataAndUtf16LengthByIdx(uint32_t idx, uint32_t* utf16_length) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700480 if (idx == kDexNoIndex) {
Ian Rogersdfb325e2013-10-30 01:00:44 -0700481 *utf16_length = 0;
Ian Rogers0571d352011-11-03 19:51:38 -0700482 return NULL;
483 }
484 const StringId& string_id = GetStringId(idx);
Ian Rogersdfb325e2013-10-30 01:00:44 -0700485 return GetStringDataAndUtf16Length(string_id, utf16_length);
Ian Rogers0571d352011-11-03 19:51:38 -0700486 }
487
488 const char* StringDataByIdx(uint32_t idx) const {
Elliott Hughes45651fd2012-02-21 15:48:20 -0800489 uint32_t unicode_length;
Ian Rogersdfb325e2013-10-30 01:00:44 -0700490 return StringDataAndUtf16LengthByIdx(idx, &unicode_length);
Ian Rogers0571d352011-11-03 19:51:38 -0700491 }
492
Ian Rogers637c65b2013-05-31 11:46:00 -0700493 // Looks up a string id for a given modified utf8 string.
494 const StringId* FindStringId(const char* string) const;
495
496 // Looks up a string id for a given utf16 string.
497 const StringId* FindStringId(const uint16_t* string) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700498
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700499 // Returns the number of type identifiers in the .dex file.
Ian Rogers68b56852014-08-29 20:19:11 -0700500 uint32_t NumTypeIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700501 DCHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700502 return header_->type_ids_size_;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700503 }
504
Ian Rogers0571d352011-11-03 19:51:38 -0700505 // Returns the TypeId at the specified index.
506 const TypeId& GetTypeId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700507 DCHECK_LT(idx, NumTypeIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700508 return type_ids_[idx];
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700509 }
510
Ian Rogers0571d352011-11-03 19:51:38 -0700511 uint16_t GetIndexForTypeId(const TypeId& type_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800512 CHECK_GE(&type_id, type_ids_) << GetLocation();
513 CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700514 size_t result = &type_id - type_ids_;
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800515 DCHECK_LT(result, 65536U) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700516 return static_cast<uint16_t>(result);
517 }
518
519 // Get the descriptor string associated with a given type index.
Elliott Hughes45651fd2012-02-21 15:48:20 -0800520 const char* StringByTypeIdx(uint32_t idx, uint32_t* unicode_length) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700521 const TypeId& type_id = GetTypeId(idx);
Ian Rogersdfb325e2013-10-30 01:00:44 -0700522 return StringDataAndUtf16LengthByIdx(type_id.descriptor_idx_, unicode_length);
Ian Rogers0571d352011-11-03 19:51:38 -0700523 }
524
525 const char* StringByTypeIdx(uint32_t idx) const {
526 const TypeId& type_id = GetTypeId(idx);
527 return StringDataByIdx(type_id.descriptor_idx_);
528 }
529
530 // Returns the type descriptor string of a type id.
531 const char* GetTypeDescriptor(const TypeId& type_id) const {
532 return StringDataByIdx(type_id.descriptor_idx_);
533 }
534
535 // Looks up a type for the given string index
536 const TypeId* FindTypeId(uint32_t string_idx) const;
537
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700538 // Returns the number of field identifiers in the .dex file.
539 size_t NumFieldIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700540 DCHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700541 return header_->field_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700542 }
543
Ian Rogers0571d352011-11-03 19:51:38 -0700544 // Returns the FieldId at the specified index.
545 const FieldId& GetFieldId(uint32_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200546 DCHECK_LT(idx, NumFieldIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700547 return field_ids_[idx];
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700548 }
549
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800550 uint32_t GetIndexForFieldId(const FieldId& field_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800551 CHECK_GE(&field_id, field_ids_) << GetLocation();
552 CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation();
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800553 return &field_id - field_ids_;
554 }
555
556 // Looks up a field by its declaring class, name and type
557 const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass,
558 const DexFile::StringId& name,
559 const DexFile::TypeId& type) const;
560
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700561 // Returns the declaring class descriptor string of a field id.
562 const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const {
Brian Carlstromb9edb842011-08-28 16:31:06 -0700563 const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_);
564 return GetTypeDescriptor(type_id);
565 }
566
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700567 // Returns the class descriptor string of a field id.
568 const char* GetFieldTypeDescriptor(const FieldId& field_id) const {
569 const DexFile::TypeId& type_id = GetTypeId(field_id.type_idx_);
570 return GetTypeDescriptor(type_id);
571 }
572
Brian Carlstromb9edb842011-08-28 16:31:06 -0700573 // Returns the name of a field id.
574 const char* GetFieldName(const FieldId& field_id) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700575 return StringDataByIdx(field_id.name_idx_);
Brian Carlstromb9edb842011-08-28 16:31:06 -0700576 }
577
Ian Rogers0571d352011-11-03 19:51:38 -0700578 // Returns the number of method identifiers in the .dex file.
579 size_t NumMethodIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700580 DCHECK(header_ != NULL) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700581 return header_->method_ids_size_;
582 }
583
584 // Returns the MethodId at the specified index.
585 const MethodId& GetMethodId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700586 DCHECK_LT(idx, NumMethodIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700587 return method_ids_[idx];
588 }
589
590 uint32_t GetIndexForMethodId(const MethodId& method_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800591 CHECK_GE(&method_id, method_ids_) << GetLocation();
592 CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700593 return &method_id - method_ids_;
594 }
595
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800596 // Looks up a method by its declaring class, name and proto_id
597 const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass,
598 const DexFile::StringId& name,
Ian Rogers0571d352011-11-03 19:51:38 -0700599 const DexFile::ProtoId& signature) const;
600
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700601 // Returns the declaring class descriptor string of a method id.
602 const char* GetMethodDeclaringClassDescriptor(const MethodId& method_id) const {
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700603 const DexFile::TypeId& type_id = GetTypeId(method_id.class_idx_);
604 return GetTypeDescriptor(type_id);
605 }
606
jeffhao98eacac2011-09-14 16:11:53 -0700607 // Returns the prototype of a method id.
Brian Carlstromaded5f72011-10-07 17:15:04 -0700608 const ProtoId& GetMethodPrototype(const MethodId& method_id) const {
609 return GetProtoId(method_id.proto_idx_);
610 }
611
Ian Rogersd91d6d62013-09-25 20:26:14 -0700612 // Returns a representation of the signature of a method id.
613 const Signature GetMethodSignature(const MethodId& method_id) const;
jeffhao98eacac2011-09-14 16:11:53 -0700614
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700615 // Returns the name of a method id.
616 const char* GetMethodName(const MethodId& method_id) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700617 return StringDataByIdx(method_id.name_idx_);
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700618 }
619
Ian Rogers0571d352011-11-03 19:51:38 -0700620 // Returns the shorty of a method id.
621 const char* GetMethodShorty(const MethodId& method_id) const {
622 return StringDataByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700623 }
Elliott Hughes45651fd2012-02-21 15:48:20 -0800624 const char* GetMethodShorty(const MethodId& method_id, uint32_t* length) const {
Ian Rogerscf5077a2013-10-31 12:37:54 -0700625 // Using the UTF16 length is safe here as shorties are guaranteed to be ASCII characters.
Ian Rogersdfb325e2013-10-30 01:00:44 -0700626 return StringDataAndUtf16LengthByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_, length);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800627 }
Ian Rogers0571d352011-11-03 19:51:38 -0700628 // Returns the number of class definitions in the .dex file.
Ian Rogers68b56852014-08-29 20:19:11 -0700629 uint32_t NumClassDefs() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700630 DCHECK(header_ != NULL) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700631 return header_->class_defs_size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700632 }
633
634 // Returns the ClassDef at the specified index.
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700635 const ClassDef& GetClassDef(uint16_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200636 DCHECK_LT(idx, NumClassDefs()) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700637 return class_defs_[idx];
638 }
639
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700640 uint16_t GetIndexForClassDef(const ClassDef& class_def) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800641 CHECK_GE(&class_def, class_defs_) << GetLocation();
642 CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700643 return &class_def - class_defs_;
644 }
645
646 // Returns the class descriptor string of a class definition.
647 const char* GetClassDescriptor(const ClassDef& class_def) const {
648 return StringByTypeIdx(class_def.class_idx_);
649 }
650
651 // Looks up a class definition by its class descriptor.
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700652 const ClassDef* FindClassDef(const char* descriptor) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700653
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700654 // Looks up a class definition by its type index.
655 const ClassDef* FindClassDef(uint16_t type_idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700656
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700657 const TypeList* GetInterfacesList(const ClassDef& class_def) const {
658 if (class_def.interfaces_off_ == 0) {
659 return NULL;
660 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800661 const byte* addr = begin_ + class_def.interfaces_off_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700662 return reinterpret_cast<const TypeList*>(addr);
663 }
664 }
665
Ian Rogers0571d352011-11-03 19:51:38 -0700666 // Returns a pointer to the raw memory mapped class_data_item
667 const byte* GetClassData(const ClassDef& class_def) const {
668 if (class_def.class_data_off_ == 0) {
669 return NULL;
670 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800671 return begin_ + class_def.class_data_off_;
Ian Rogers0571d352011-11-03 19:51:38 -0700672 }
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700673 }
674
Ian Rogers0571d352011-11-03 19:51:38 -0700675 //
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800676 const CodeItem* GetCodeItem(const uint32_t code_off) const {
677 if (code_off == 0) {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700678 return NULL; // native or abstract method
679 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800680 const byte* addr = begin_ + code_off;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700681 return reinterpret_cast<const CodeItem*>(addr);
682 }
683 }
684
Ian Rogers0571d352011-11-03 19:51:38 -0700685 const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const {
686 return StringByTypeIdx(proto_id.return_type_idx_);
687 }
688
689 // Returns the number of prototype identifiers in the .dex file.
690 size_t NumProtoIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700691 DCHECK(header_ != NULL) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700692 return header_->proto_ids_size_;
693 }
694
695 // Returns the ProtoId at the specified index.
696 const ProtoId& GetProtoId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700697 DCHECK_LT(idx, NumProtoIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700698 return proto_ids_[idx];
699 }
700
701 uint16_t GetIndexForProtoId(const ProtoId& proto_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800702 CHECK_GE(&proto_id, proto_ids_) << GetLocation();
703 CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700704 return &proto_id - proto_ids_;
705 }
706
707 // Looks up a proto id for a given return type and signature type list
Ian Rogersd91d6d62013-09-25 20:26:14 -0700708 const ProtoId* FindProtoId(uint16_t return_type_idx,
Vladimir Marko5c96e6b2013-11-14 15:34:17 +0000709 const uint16_t* signature_type_idxs, uint32_t signature_length) const;
710 const ProtoId* FindProtoId(uint16_t return_type_idx,
711 const std::vector<uint16_t>& signature_type_idxs) const {
712 return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size());
713 }
Ian Rogers0571d352011-11-03 19:51:38 -0700714
715 // Given a signature place the type ids into the given vector, returns true on success
Ian Rogersd91d6d62013-09-25 20:26:14 -0700716 bool CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx,
717 std::vector<uint16_t>* param_type_idxs) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700718
Ian Rogersd91d6d62013-09-25 20:26:14 -0700719 // Create a Signature from the given string signature or return Signature::NoSignature if not
720 // possible.
721 const Signature CreateSignature(const StringPiece& signature) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700722
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700723 // Returns the short form method descriptor for the given prototype.
724 const char* GetShorty(uint32_t proto_idx) const {
725 const ProtoId& proto_id = GetProtoId(proto_idx);
Ian Rogers0571d352011-11-03 19:51:38 -0700726 return StringDataByIdx(proto_id.shorty_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700727 }
728
729 const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
730 if (proto_id.parameters_off_ == 0) {
731 return NULL;
732 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800733 const byte* addr = begin_ + proto_id.parameters_off_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700734 return reinterpret_cast<const TypeList*>(addr);
735 }
736 }
737
Ian Rogers0571d352011-11-03 19:51:38 -0700738 const byte* GetEncodedStaticFieldValuesArray(const ClassDef& class_def) const {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700739 if (class_def.static_values_off_ == 0) {
740 return 0;
741 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800742 return begin_ + class_def.static_values_off_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700743 }
744 }
745
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800746 static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700747
748 // Get the base of the encoded data for the given DexCode.
Ian Rogers0571d352011-11-03 19:51:38 -0700749 static const byte* GetCatchHandlerData(const CodeItem& code_item, uint32_t offset) {
750 const byte* handler_data =
751 reinterpret_cast<const byte*>(GetTryItems(code_item, code_item.tries_size_));
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700752 return handler_data + offset;
753 }
754
Ian Rogersdbbc99d2013-04-18 16:51:54 -0700755 // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
756 static int32_t FindTryItem(const CodeItem &code_item, uint32_t address);
757
758 // Find the handler offset associated with the given address (ie dex pc). Returns -1 if none.
759 static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700760
Shih-wei Liao195487c2011-08-20 13:29:04 -0700761 // Get the pointer to the start of the debugging data
Ian Rogers0571d352011-11-03 19:51:38 -0700762 const byte* GetDebugInfoStream(const CodeItem* code_item) const {
Shih-wei Liao195487c2011-08-20 13:29:04 -0700763 if (code_item->debug_info_off_ == 0) {
764 return NULL;
765 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800766 return begin_ + code_item->debug_info_off_;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700767 }
768 }
769
770 // Callback for "new position table entry".
771 // Returning true causes the decoder to stop early.
Elliott Hughes2435a572012-02-17 16:07:41 -0800772 typedef bool (*DexDebugNewPositionCb)(void* context, uint32_t address, uint32_t line_num);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700773
774 // Callback for "new locals table entry". "signature" is an empty string
775 // if no signature is available for an entry.
Elliott Hughes2435a572012-02-17 16:07:41 -0800776 typedef void (*DexDebugNewLocalCb)(void* context, uint16_t reg,
Elliott Hughes24edeb52012-06-18 15:29:46 -0700777 uint32_t start_address,
778 uint32_t end_address,
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700779 const char* name,
780 const char* descriptor,
781 const char* signature);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700782
Elliott Hughes2435a572012-02-17 16:07:41 -0800783 static bool LineNumForPcCb(void* context, uint32_t address, uint32_t line_num);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700784
785 // Debug info opcodes and constants
786 enum {
787 DBG_END_SEQUENCE = 0x00,
788 DBG_ADVANCE_PC = 0x01,
789 DBG_ADVANCE_LINE = 0x02,
790 DBG_START_LOCAL = 0x03,
791 DBG_START_LOCAL_EXTENDED = 0x04,
792 DBG_END_LOCAL = 0x05,
793 DBG_RESTART_LOCAL = 0x06,
794 DBG_SET_PROLOGUE_END = 0x07,
795 DBG_SET_EPILOGUE_BEGIN = 0x08,
796 DBG_SET_FILE = 0x09,
797 DBG_FIRST_SPECIAL = 0x0a,
798 DBG_LINE_BASE = -4,
799 DBG_LINE_RANGE = 15,
800 };
801
802 struct LocalInfo {
Ian Rogersca190662012-06-26 15:45:57 -0700803 LocalInfo()
804 : name_(NULL), descriptor_(NULL), signature_(NULL), start_address_(0), is_live_(false) {}
Shih-wei Liao195487c2011-08-20 13:29:04 -0700805
Ian Rogers0571d352011-11-03 19:51:38 -0700806 const char* name_; // E.g., list
807 const char* descriptor_; // E.g., Ljava/util/LinkedList;
808 const char* signature_; // E.g., java.util.LinkedList<java.lang.Integer>
809 uint16_t start_address_; // PC location where the local is first defined.
810 bool is_live_; // Is the local defined and live.
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700811
812 private:
813 DISALLOW_COPY_AND_ASSIGN(LocalInfo);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700814 };
815
816 struct LineNumFromPcContext {
Ian Rogersca190662012-06-26 15:45:57 -0700817 LineNumFromPcContext(uint32_t address, uint32_t line_num)
818 : address_(address), line_num_(line_num) {}
Shih-wei Liao195487c2011-08-20 13:29:04 -0700819 uint32_t address_;
820 uint32_t line_num_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700821 private:
822 DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700823 };
824
Elliott Hughes2435a572012-02-17 16:07:41 -0800825 void InvokeLocalCbIfLive(void* context, int reg, uint32_t end_address,
Brian Carlstrom78128a62011-09-15 17:21:19 -0700826 LocalInfo* local_in_reg, DexDebugNewLocalCb local_cb) const {
Shih-wei Liao195487c2011-08-20 13:29:04 -0700827 if (local_cb != NULL && local_in_reg[reg].is_live_) {
Elliott Hughes2435a572012-02-17 16:07:41 -0800828 local_cb(context, reg, local_in_reg[reg].start_address_, end_address,
Elliott Hughesdbb40792011-11-18 17:05:22 -0800829 local_in_reg[reg].name_, local_in_reg[reg].descriptor_,
830 local_in_reg[reg].signature_ != NULL ? local_in_reg[reg].signature_ : "");
Shih-wei Liao195487c2011-08-20 13:29:04 -0700831 }
832 }
833
834 // Determine the source file line number based on the program counter.
835 // "pc" is an offset, in 16-bit units, from the start of the method's code.
836 //
837 // Returns -1 if no match was found (possibly because the source files were
838 // compiled without "-g", so no line number information is present).
839 // Returns -2 for native methods (as expected in exception traces).
840 //
841 // This is used by runtime; therefore use art::Method not art::DexFile::Method.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800842 int32_t GetLineNumFromPC(mirror::ArtMethod* method, uint32_t rel_pc) const
Ian Rogersb726dcb2012-09-05 08:57:23 -0700843 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700844
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800845 void DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
Elliott Hughes2435a572012-02-17 16:07:41 -0800846 DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
847 void* context) const;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700848
Ian Rogers0571d352011-11-03 19:51:38 -0700849 const char* GetSourceFile(const ClassDef& class_def) const {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700850 if (class_def.source_file_idx_ == 0xffffffff) {
851 return NULL;
852 } else {
Ian Rogers0571d352011-11-03 19:51:38 -0700853 return StringDataByIdx(class_def.source_file_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700854 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700855 }
856
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800857 int GetPermissions() const;
Ian Rogers1c849e52012-06-28 14:00:33 -0700858
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200859 bool IsReadOnly() const;
860
Brian Carlstrome0948e12013-08-29 09:36:15 -0700861 bool EnableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200862
Brian Carlstrome0948e12013-08-29 09:36:15 -0700863 bool DisableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200864
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700865 const byte* Begin() const {
866 return begin_;
867 }
868
869 size_t Size() const {
870 return size_;
871 }
872
Calin Juravle4e1d5792014-07-15 23:56:47 +0100873 static std::string GetMultiDexClassesDexName(size_t number, const char* dex_location);
874
875 // Returns the canonical form of the given dex location.
876 //
877 // There are different flavors of "dex locations" as follows:
878 // the file name of a dex file:
879 // The actual file path that the dex file has on disk.
880 // dex_location:
881 // This acts as a key for the class linker to know which dex file to load.
882 // It may correspond to either an old odex file or a particular dex file
883 // inside an oat file. In the first case it will also match the file name
884 // of the dex file. In the second case (oat) it will include the file name
885 // and possibly some multidex annotation to uniquely identify it.
886 // canonical_dex_location:
887 // the dex_location where it's file name part has been made canonical.
888 static std::string GetDexCanonicalLocation(const char* dex_location);
889
Carl Shapiro1fb86202011-06-27 17:43:13 -0700890 private:
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700891 // Opens a .dex file
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700892 static const DexFile* OpenFile(int fd, const char* location, bool verify, std::string* error_msg);
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700893
Andreas Gampe833a4852014-05-21 18:46:59 -0700894 // Opens dex files from within a .jar, .zip, or .apk file
895 static bool OpenZip(int fd, const std::string& location, std::string* error_msg,
896 std::vector<const DexFile*>* dex_files);
897
898 enum class ZipOpenErrorCode { // private
899 kNoError,
900 kEntryNotFound,
901 kExtractToMemoryError,
902 kDexFileError,
903 kMakeReadOnlyError,
904 kVerifyError
905 };
906
907 // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-nullptr
908 // return.
909 static const DexFile* Open(const ZipArchive& zip_archive, const char* entry_name,
910 const std::string& location, std::string* error_msg,
911 ZipOpenErrorCode* error_code);
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700912
Brian Carlstrom89521892011-12-07 22:05:07 -0800913 // Opens a .dex file at the given address backed by a MemMap
914 static const DexFile* OpenMemory(const std::string& location,
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800915 uint32_t location_checksum,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700916 MemMap* mem_map,
917 std::string* error_msg);
Brian Carlstrom89521892011-12-07 22:05:07 -0800918
919 // Opens a .dex file at the given address, optionally backed by a MemMap
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700920 static const DexFile* OpenMemory(const byte* dex_file,
jeffhaof6174e82012-01-31 16:14:17 -0800921 size_t size,
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700922 const std::string& location,
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800923 uint32_t location_checksum,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700924 MemMap* mem_map,
925 std::string* error_msg);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700926
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800927 DexFile(const byte* base, size_t size,
Brian Carlstrom28db0122012-10-18 16:20:41 -0700928 const std::string& location,
929 uint32_t location_checksum,
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800930 MemMap* mem_map);
jeffhaof6174e82012-01-31 16:14:17 -0800931
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700932 // Top-level initializer that calls other Init methods.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700933 bool Init(std::string* error_msg);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700934
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800935 // Returns true if the header magic and version numbers are of the expected values.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700936 bool CheckMagicAndVersion(std::string* error_msg) const;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700937
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800938 void DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx,
Elliott Hughes2435a572012-02-17 16:07:41 -0800939 DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
940 void* context, const byte* stream, LocalInfo* local_in_reg) const;
Elliott Hughes03181a82011-11-17 17:22:21 -0800941
Andreas Gampe833a4852014-05-21 18:46:59 -0700942 // Check whether a location denotes a multidex dex file. This is a very simple check: returns
943 // whether the string contains the separator character.
944 static bool IsMultiDexLocation(const char* location);
945
Andreas Gampe833a4852014-05-21 18:46:59 -0700946
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700947 // The base address of the memory mapping.
Ian Rogers62d6c772013-02-27 08:32:07 -0800948 const byte* const begin_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700949
950 // The size of the underlying memory allocation in bytes.
Ian Rogers62d6c772013-02-27 08:32:07 -0800951 const size_t size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700952
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700953 // Typically the dex file name when available, alternatively some identifying string.
Brian Carlstroma663ea52011-08-19 23:33:41 -0700954 //
955 // The ClassLinker will use this to match DexFiles the boot class
956 // path to DexCache::GetLocation when loading from an image.
957 const std::string location_;
958
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800959 const uint32_t location_checksum_;
960
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700961 // Manages the underlying memory allocation.
Ian Rogers700a4022014-05-19 16:49:03 -0700962 std::unique_ptr<MemMap> mem_map_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700963
964 // Points to the header section.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800965 const Header* const header_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700966
967 // Points to the base of the string identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800968 const StringId* const string_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700969
970 // Points to the base of the type identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800971 const TypeId* const type_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700972
973 // Points to the base of the field identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800974 const FieldId* const field_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700975
976 // Points to the base of the method identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800977 const MethodId* const method_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700978
979 // Points to the base of the prototype identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800980 const ProtoId* const proto_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700981
982 // Points to the base of the class definition list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800983 const ClassDef* const class_defs_;
Ian Rogers68b56852014-08-29 20:19:11 -0700984
985 // Number of misses finding a class def from a descriptor.
986 mutable Atomic<uint32_t> find_class_def_misses_;
987
988 struct UTF16HashCmp {
989 // Hash function.
990 size_t operator()(const char* key) const {
991 return ComputeUtf8Hash(key);
992 }
993 // std::equal function.
994 bool operator()(const char* a, const char* b) const {
995 return CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(a, b) == 0;
996 }
997 };
998 typedef std::unordered_map<const char*, const ClassDef*, UTF16HashCmp, UTF16HashCmp> Index;
999 mutable Atomic<Index*> class_def_index_;
Carl Shapiro1fb86202011-06-27 17:43:13 -07001000};
Brian Carlstrom0d6adac2014-02-05 17:39:16 -08001001std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);
Carl Shapiro1fb86202011-06-27 17:43:13 -07001002
Ian Rogers0571d352011-11-03 19:51:38 -07001003// Iterate over a dex file's ProtoId's paramters
1004class DexFileParameterIterator {
1005 public:
1006 DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id)
1007 : dex_file_(dex_file), size_(0), pos_(0) {
1008 type_list_ = dex_file_.GetProtoParameters(proto_id);
1009 if (type_list_ != NULL) {
1010 size_ = type_list_->Size();
1011 }
1012 }
1013 bool HasNext() const { return pos_ < size_; }
1014 void Next() { ++pos_; }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -08001015 uint16_t GetTypeIdx() {
Ian Rogers0571d352011-11-03 19:51:38 -07001016 return type_list_->GetTypeItem(pos_).type_idx_;
1017 }
1018 const char* GetDescriptor() {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -08001019 return dex_file_.StringByTypeIdx(GetTypeIdx());
Ian Rogers0571d352011-11-03 19:51:38 -07001020 }
1021 private:
1022 const DexFile& dex_file_;
1023 const DexFile::TypeList* type_list_;
1024 uint32_t size_;
1025 uint32_t pos_;
1026 DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
1027};
1028
Ian Rogersd91d6d62013-09-25 20:26:14 -07001029// Abstract the signature of a method.
1030class Signature {
1031 public:
1032 std::string ToString() const;
1033
1034 static Signature NoSignature() {
1035 return Signature();
1036 }
1037
Ian Rogersdfb325e2013-10-30 01:00:44 -07001038 bool operator==(const Signature& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001039 bool operator!=(const Signature& rhs) const {
1040 return !(*this == rhs);
1041 }
1042
Vladimir Markod9cffea2013-11-25 15:08:02 +00001043 bool operator==(const StringPiece& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001044
1045 private:
1046 Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
1047 }
1048
1049 Signature() : dex_file_(nullptr), proto_id_(nullptr) {
1050 }
1051
1052 friend class DexFile;
1053
1054 const DexFile* const dex_file_;
1055 const DexFile::ProtoId* const proto_id_;
1056};
1057std::ostream& operator<<(std::ostream& os, const Signature& sig);
1058
Ian Rogers0571d352011-11-03 19:51:38 -07001059// Iterate and decode class_data_item
1060class ClassDataItemIterator {
1061 public:
1062 ClassDataItemIterator(const DexFile& dex_file, const byte* raw_class_data_item)
1063 : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) {
1064 ReadClassDataHeader();
1065 if (EndOfInstanceFieldsPos() > 0) {
1066 ReadClassDataField();
1067 } else if (EndOfVirtualMethodsPos() > 0) {
1068 ReadClassDataMethod();
1069 }
1070 }
1071 uint32_t NumStaticFields() const {
1072 return header_.static_fields_size_;
1073 }
1074 uint32_t NumInstanceFields() const {
1075 return header_.instance_fields_size_;
1076 }
1077 uint32_t NumDirectMethods() const {
1078 return header_.direct_methods_size_;
1079 }
1080 uint32_t NumVirtualMethods() const {
1081 return header_.virtual_methods_size_;
1082 }
1083 bool HasNextStaticField() const {
1084 return pos_ < EndOfStaticFieldsPos();
1085 }
1086 bool HasNextInstanceField() const {
1087 return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos();
1088 }
1089 bool HasNextDirectMethod() const {
1090 return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos();
1091 }
1092 bool HasNextVirtualMethod() const {
1093 return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos();
1094 }
1095 bool HasNext() const {
1096 return pos_ < EndOfVirtualMethodsPos();
1097 }
Ian Rogers637c65b2013-05-31 11:46:00 -07001098 inline void Next() {
Ian Rogers0571d352011-11-03 19:51:38 -07001099 pos_++;
1100 if (pos_ < EndOfStaticFieldsPos()) {
1101 last_idx_ = GetMemberIndex();
1102 ReadClassDataField();
1103 } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) {
1104 last_idx_ = 0; // transition to next array, reset last index
1105 ReadClassDataField();
1106 } else if (pos_ < EndOfInstanceFieldsPos()) {
1107 last_idx_ = GetMemberIndex();
1108 ReadClassDataField();
1109 } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) {
1110 last_idx_ = 0; // transition to next array, reset last index
1111 ReadClassDataMethod();
1112 } else if (pos_ < EndOfDirectMethodsPos()) {
1113 last_idx_ = GetMemberIndex();
1114 ReadClassDataMethod();
1115 } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) {
1116 last_idx_ = 0; // transition to next array, reset last index
1117 ReadClassDataMethod();
1118 } else if (pos_ < EndOfVirtualMethodsPos()) {
1119 last_idx_ = GetMemberIndex();
1120 ReadClassDataMethod();
1121 } else {
1122 DCHECK(!HasNext());
1123 }
1124 }
1125 uint32_t GetMemberIndex() const {
1126 if (pos_ < EndOfInstanceFieldsPos()) {
1127 return last_idx_ + field_.field_idx_delta_;
1128 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001129 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001130 return last_idx_ + method_.method_idx_delta_;
1131 }
1132 }
Andreas Gampe51829322014-08-25 15:05:04 -07001133 uint32_t GetRawMemberAccessFlags() const {
Ian Rogers0571d352011-11-03 19:51:38 -07001134 if (pos_ < EndOfInstanceFieldsPos()) {
1135 return field_.access_flags_;
1136 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001137 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001138 return method_.access_flags_;
1139 }
1140 }
Andreas Gampe51829322014-08-25 15:05:04 -07001141 uint32_t GetFieldAccessFlags() const {
1142 return GetRawMemberAccessFlags() & kAccValidFieldFlags;
1143 }
1144 uint32_t GetMethodAccessFlags() const {
1145 return GetRawMemberAccessFlags() & kAccValidMethodFlags;
1146 }
1147 bool MemberIsNative() const {
1148 return GetRawMemberAccessFlags() & kAccNative;
1149 }
1150 bool MemberIsFinal() const {
1151 return GetRawMemberAccessFlags() & kAccFinal;
1152 }
Ian Rogers08f753d2012-08-24 14:35:25 -07001153 InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const {
1154 if (HasNextDirectMethod()) {
Andreas Gampe51829322014-08-25 15:05:04 -07001155 if ((GetRawMemberAccessFlags() & kAccStatic) != 0) {
Ian Rogers08f753d2012-08-24 14:35:25 -07001156 return kStatic;
1157 } else {
1158 return kDirect;
1159 }
1160 } else {
Andreas Gampe51829322014-08-25 15:05:04 -07001161 DCHECK_EQ(GetRawMemberAccessFlags() & kAccStatic, 0U);
Ian Rogers08f753d2012-08-24 14:35:25 -07001162 if ((class_def.access_flags_ & kAccInterface) != 0) {
1163 return kInterface;
Andreas Gampe51829322014-08-25 15:05:04 -07001164 } else if ((GetRawMemberAccessFlags() & kAccConstructor) != 0) {
Ian Rogers08f753d2012-08-24 14:35:25 -07001165 return kSuper;
1166 } else {
1167 return kVirtual;
1168 }
1169 }
1170 }
Ian Rogers0571d352011-11-03 19:51:38 -07001171 const DexFile::CodeItem* GetMethodCodeItem() const {
1172 return dex_file_.GetCodeItem(method_.code_off_);
1173 }
1174 uint32_t GetMethodCodeItemOffset() const {
1175 return method_.code_off_;
1176 }
jeffhao10037c82012-01-23 15:06:23 -08001177 const byte* EndDataPointer() const {
1178 CHECK(!HasNext());
1179 return ptr_pos_;
1180 }
Elliott Hughesa21039c2012-06-21 12:09:25 -07001181
Ian Rogers0571d352011-11-03 19:51:38 -07001182 private:
1183 // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the
1184 // header for a class_data_item
1185 struct ClassDataHeader {
1186 uint32_t static_fields_size_; // the number of static fields
1187 uint32_t instance_fields_size_; // the number of instance fields
1188 uint32_t direct_methods_size_; // the number of direct methods
1189 uint32_t virtual_methods_size_; // the number of virtual methods
1190 } header_;
1191
1192 // Read and decode header from a class_data_item stream into header
1193 void ReadClassDataHeader();
1194
1195 uint32_t EndOfStaticFieldsPos() const {
1196 return header_.static_fields_size_;
1197 }
1198 uint32_t EndOfInstanceFieldsPos() const {
1199 return EndOfStaticFieldsPos() + header_.instance_fields_size_;
1200 }
1201 uint32_t EndOfDirectMethodsPos() const {
1202 return EndOfInstanceFieldsPos() + header_.direct_methods_size_;
1203 }
1204 uint32_t EndOfVirtualMethodsPos() const {
1205 return EndOfDirectMethodsPos() + header_.virtual_methods_size_;
1206 }
1207
1208 // A decoded version of the field of a class_data_item
1209 struct ClassDataField {
1210 uint32_t field_idx_delta_; // delta of index into the field_ids array for FieldId
1211 uint32_t access_flags_; // access flags for the field
1212 ClassDataField() : field_idx_delta_(0), access_flags_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001213
Ian Rogers0571d352011-11-03 19:51:38 -07001214 private:
1215 DISALLOW_COPY_AND_ASSIGN(ClassDataField);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001216 };
1217 ClassDataField field_;
Ian Rogers0571d352011-11-03 19:51:38 -07001218
1219 // Read and decode a field from a class_data_item stream into field
1220 void ReadClassDataField();
1221
1222 // A decoded version of the method of a class_data_item
1223 struct ClassDataMethod {
1224 uint32_t method_idx_delta_; // delta of index into the method_ids array for MethodId
1225 uint32_t access_flags_;
1226 uint32_t code_off_;
1227 ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001228
Ian Rogers0571d352011-11-03 19:51:38 -07001229 private:
1230 DISALLOW_COPY_AND_ASSIGN(ClassDataMethod);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001231 };
1232 ClassDataMethod method_;
Ian Rogers0571d352011-11-03 19:51:38 -07001233
1234 // Read and decode a method from a class_data_item stream into method
1235 void ReadClassDataMethod();
1236
1237 const DexFile& dex_file_;
1238 size_t pos_; // integral number of items passed
1239 const byte* ptr_pos_; // pointer into stream of class_data_item
1240 uint32_t last_idx_; // last read field or method index to apply delta to
1241 DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
1242};
1243
Ian Rogers0571d352011-11-03 19:51:38 -07001244class EncodedStaticFieldValueIterator {
1245 public:
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001246 EncodedStaticFieldValueIterator(const DexFile& dex_file, Handle<mirror::DexCache>* dex_cache,
1247 Handle<mirror::ClassLoader>* class_loader,
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001248 ClassLinker* linker, const DexFile::ClassDef& class_def)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001249 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers0571d352011-11-03 19:51:38 -07001250
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001251 template<bool kTransactionActive>
Hiroshi Yamauchi67ef46a2014-08-21 15:59:43 -07001252 void ReadValueToField(Handle<mirror::ArtField> field) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers0571d352011-11-03 19:51:38 -07001253
1254 bool HasNext() { return pos_ < array_size_; }
1255
1256 void Next();
Elliott Hughesa21039c2012-06-21 12:09:25 -07001257
Ian Rogers0571d352011-11-03 19:51:38 -07001258 enum ValueType {
1259 kByte = 0x00,
1260 kShort = 0x02,
1261 kChar = 0x03,
1262 kInt = 0x04,
1263 kLong = 0x06,
1264 kFloat = 0x10,
1265 kDouble = 0x11,
1266 kString = 0x17,
1267 kType = 0x18,
1268 kField = 0x19,
1269 kMethod = 0x1a,
1270 kEnum = 0x1b,
1271 kArray = 0x1c,
1272 kAnnotation = 0x1d,
1273 kNull = 0x1e,
1274 kBoolean = 0x1f
1275 };
1276
Brian Carlstrom88f36542012-10-16 23:24:21 -07001277 private:
Ian Rogers0571d352011-11-03 19:51:38 -07001278 static const byte kEncodedValueTypeMask = 0x1f; // 0b11111
1279 static const byte kEncodedValueArgShift = 5;
1280
1281 const DexFile& dex_file_;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001282 Handle<mirror::DexCache>* const dex_cache_; // Dex cache to resolve literal objects.
1283 Handle<mirror::ClassLoader>* const class_loader_; // ClassLoader to resolve types.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001284 ClassLinker* linker_; // Linker to resolve literal objects.
1285 size_t array_size_; // Size of array.
1286 size_t pos_; // Current position.
1287 const byte* ptr_; // Pointer into encoded data array.
1288 ValueType type_; // Type of current encoded value.
1289 jvalue jval_; // Value of current encoded value.
Ian Rogers0571d352011-11-03 19:51:38 -07001290 DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
1291};
Brian Carlstrom88f36542012-10-16 23:24:21 -07001292std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code);
Ian Rogers0571d352011-11-03 19:51:38 -07001293
1294class CatchHandlerIterator {
1295 public:
1296 CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address);
Logan Chien736df022012-04-27 16:25:57 +08001297
1298 CatchHandlerIterator(const DexFile::CodeItem& code_item,
1299 const DexFile::TryItem& try_item);
1300
Ian Rogers0571d352011-11-03 19:51:38 -07001301 explicit CatchHandlerIterator(const byte* handler_data) {
1302 Init(handler_data);
1303 }
1304
1305 uint16_t GetHandlerTypeIndex() const {
1306 return handler_.type_idx_;
1307 }
1308 uint32_t GetHandlerAddress() const {
1309 return handler_.address_;
1310 }
1311 void Next();
1312 bool HasNext() const {
1313 return remaining_count_ != -1 || catch_all_;
1314 }
1315 // End of this set of catch blocks, convenience method to locate next set of catch blocks
1316 const byte* EndDataPointer() const {
1317 CHECK(!HasNext());
1318 return current_data_;
1319 }
Elliott Hughesa21039c2012-06-21 12:09:25 -07001320
Ian Rogers0571d352011-11-03 19:51:38 -07001321 private:
Logan Chien736df022012-04-27 16:25:57 +08001322 void Init(const DexFile::CodeItem& code_item, int32_t offset);
Ian Rogers0571d352011-11-03 19:51:38 -07001323 void Init(const byte* handler_data);
1324
1325 struct CatchHandlerItem {
1326 uint16_t type_idx_; // type index of the caught exception type
1327 uint32_t address_; // handler address
1328 } handler_;
1329 const byte *current_data_; // the current handler in dex file.
1330 int32_t remaining_count_; // number of handlers not read.
1331 bool catch_all_; // is there a handler that will catch all exceptions in case
1332 // that all typed handler does not match.
1333};
1334
Carl Shapiro1fb86202011-06-27 17:43:13 -07001335} // namespace art
1336
Brian Carlstromfc0e3212013-07-17 14:40:12 -07001337#endif // ART_RUNTIME_DEX_FILE_H_