blob: dd7d732ab5506e02173cc9928c9d8b7d9b146712 [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
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700204 private:
205 DISALLOW_COPY_AND_ASSIGN(ClassDef);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700206 };
207
208 // Raw type_item.
209 struct TypeItem {
210 uint16_t type_idx_; // index into type_ids section
Elliott Hughesa21039c2012-06-21 12:09:25 -0700211
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700212 private:
213 DISALLOW_COPY_AND_ASSIGN(TypeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700214 };
215
216 // Raw type_list.
217 class TypeList {
218 public:
219 uint32_t Size() const {
220 return size_;
221 }
222
223 const TypeItem& GetTypeItem(uint32_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200224 DCHECK_LT(idx, this->size_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700225 return this->list_[idx];
226 }
227
228 private:
229 uint32_t size_; // size of the list, in entries
230 TypeItem list_[1]; // elements of the list
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700231 DISALLOW_COPY_AND_ASSIGN(TypeList);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700232 };
233
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700234 // Raw code_item.
235 struct CodeItem {
236 uint16_t registers_size_;
237 uint16_t ins_size_;
238 uint16_t outs_size_;
239 uint16_t tries_size_;
240 uint32_t debug_info_off_; // file offset to debug info stream
Ian Rogersd81871c2011-10-03 13:57:23 -0700241 uint32_t insns_size_in_code_units_; // size of the insns array, in 2 byte code units
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700242 uint16_t insns_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700243
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700244 private:
245 DISALLOW_COPY_AND_ASSIGN(CodeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700246 };
247
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700248 // Raw try_item.
249 struct TryItem {
250 uint32_t start_addr_;
251 uint16_t insn_count_;
252 uint16_t handler_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700253
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700254 private:
255 DISALLOW_COPY_AND_ASSIGN(TryItem);
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700256 };
257
jeffhao10037c82012-01-23 15:06:23 -0800258 // Annotation constants.
259 enum {
260 kDexVisibilityBuild = 0x00, /* annotation visibility */
261 kDexVisibilityRuntime = 0x01,
262 kDexVisibilitySystem = 0x02,
263
264 kDexAnnotationByte = 0x00,
265 kDexAnnotationShort = 0x02,
266 kDexAnnotationChar = 0x03,
267 kDexAnnotationInt = 0x04,
268 kDexAnnotationLong = 0x06,
269 kDexAnnotationFloat = 0x10,
270 kDexAnnotationDouble = 0x11,
271 kDexAnnotationString = 0x17,
272 kDexAnnotationType = 0x18,
273 kDexAnnotationField = 0x19,
274 kDexAnnotationMethod = 0x1a,
275 kDexAnnotationEnum = 0x1b,
276 kDexAnnotationArray = 0x1c,
277 kDexAnnotationAnnotation = 0x1d,
278 kDexAnnotationNull = 0x1e,
279 kDexAnnotationBoolean = 0x1f,
280
281 kDexAnnotationValueTypeMask = 0x1f, /* low 5 bits */
282 kDexAnnotationValueArgShift = 5,
283 };
284
285 struct AnnotationsDirectoryItem {
286 uint32_t class_annotations_off_;
287 uint32_t fields_size_;
288 uint32_t methods_size_;
289 uint32_t parameters_size_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700290
jeffhao10037c82012-01-23 15:06:23 -0800291 private:
292 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
293 };
294
295 struct FieldAnnotationsItem {
296 uint32_t field_idx_;
297 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700298
jeffhao10037c82012-01-23 15:06:23 -0800299 private:
300 DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem);
301 };
302
303 struct MethodAnnotationsItem {
304 uint32_t method_idx_;
305 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700306
jeffhao10037c82012-01-23 15:06:23 -0800307 private:
308 DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem);
309 };
310
311 struct ParameterAnnotationsItem {
312 uint32_t method_idx_;
313 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700314
jeffhao10037c82012-01-23 15:06:23 -0800315 private:
316 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem);
317 };
318
319 struct AnnotationSetRefItem {
320 uint32_t annotations_off_;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700321
jeffhao10037c82012-01-23 15:06:23 -0800322 private:
323 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem);
324 };
325
326 struct AnnotationSetRefList {
327 uint32_t size_;
328 AnnotationSetRefItem list_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700329
jeffhao10037c82012-01-23 15:06:23 -0800330 private:
331 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
332 };
333
334 struct AnnotationSetItem {
335 uint32_t size_;
336 uint32_t entries_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700337
jeffhao10037c82012-01-23 15:06:23 -0800338 private:
339 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
340 };
341
342 struct AnnotationItem {
343 uint8_t visibility_;
344 uint8_t annotation_[1];
Elliott Hughesa21039c2012-06-21 12:09:25 -0700345
jeffhao10037c82012-01-23 15:06:23 -0800346 private:
347 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
348 };
349
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800350 // Returns the checksum of a file for comparison with GetLocationChecksum().
351 // For .dex files, this is the header checksum.
352 // For zip files, this is the classes.dex zip entry CRC32 checksum.
353 // Return true if the checksum could be found, false otherwise.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700354 static bool GetChecksum(const char* filename, uint32_t* checksum, std::string* error_msg);
Brian Carlstrom78128a62011-09-15 17:21:19 -0700355
Andreas Gampe833a4852014-05-21 18:46:59 -0700356 // Opens .dex files found in the container, guessing the container format based on file extension.
357 static bool Open(const char* filename, const char* location, std::string* error_msg,
358 std::vector<const DexFile*>* dex_files);
jeffhao262bf462011-10-20 18:36:32 -0700359
Brian Carlstrom89521892011-12-07 22:05:07 -0800360 // Opens .dex file, backed by existing memory
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800361 static const DexFile* Open(const uint8_t* base, size_t size,
Brian Carlstrom28db0122012-10-18 16:20:41 -0700362 const std::string& location,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700363 uint32_t location_checksum,
364 std::string* error_msg) {
365 return OpenMemory(base, size, location, location_checksum, NULL, error_msg);
Brian Carlstrom89521892011-12-07 22:05:07 -0800366 }
367
Andreas Gampe833a4852014-05-21 18:46:59 -0700368 // Open all classesXXX.dex files from a zip archive.
369 static bool OpenFromZip(const ZipArchive& zip_archive, const std::string& location,
370 std::string* error_msg, std::vector<const DexFile*>* dex_files);
Brian Carlstroma6cc8932012-01-04 14:44:07 -0800371
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700372 // Closes a .dex file.
Brian Carlstromf615a612011-07-23 12:50:34 -0700373 virtual ~DexFile();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700374
Brian Carlstroma663ea52011-08-19 23:33:41 -0700375 const std::string& GetLocation() const {
376 return location_;
377 }
378
Andreas Gampecb8f9e82014-07-24 15:35:50 -0700379 // For normal dex files, location and base location coincide. If a dex file is part of a multidex
380 // archive, the base location is the name of the originating jar/apk, stripped of any internal
381 // classes*.dex path.
382 const std::string GetBaseLocation() const {
383 if (IsMultiDexLocation(location_.c_str())) {
384 std::pair<const char*, const char*> pair = SplitMultiDexLocation(location_.c_str());
385 std::string res(pair.first);
386 delete[] pair.first;
387 return res;
388 } else {
389 return location_;
390 }
391 }
392
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800393 // For DexFiles directly from .dex files, this is the checksum from the DexFile::Header.
394 // For DexFiles opened from a zip files, this will be the ZipEntry CRC32 of classes.dex.
395 uint32_t GetLocationChecksum() const {
396 return location_checksum_;
397 }
398
Brian Carlstroma663ea52011-08-19 23:33:41 -0700399 const Header& GetHeader() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700400 DCHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700401 return *header_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700402 }
403
Ian Rogers0571d352011-11-03 19:51:38 -0700404 // Decode the dex magic version
Ian Rogersd81871c2011-10-03 13:57:23 -0700405 uint32_t GetVersion() const;
406
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800407 // Returns true if the byte string points to the magic value.
408 static bool IsMagicValid(const byte* magic);
409
410 // Returns true if the byte string after the magic is the correct value.
411 static bool IsVersionValid(const byte* magic);
412
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700413 // Returns the number of string identifiers in the .dex file.
414 size_t NumStringIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700415 DCHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700416 return header_->string_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700417 }
418
Ian Rogers0571d352011-11-03 19:51:38 -0700419 // Returns the StringId at the specified index.
420 const StringId& GetStringId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700421 DCHECK_LT(idx, NumStringIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700422 return string_ids_[idx];
423 }
424
425 uint32_t GetIndexForStringId(const StringId& string_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800426 CHECK_GE(&string_id, string_ids_) << GetLocation();
427 CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700428 return &string_id - string_ids_;
429 }
430
431 int32_t GetStringLength(const StringId& string_id) const;
432
Ian Rogersdfb325e2013-10-30 01:00:44 -0700433 // Returns a pointer to the UTF-8 string data referred to by the given string_id as well as the
434 // length of the string when decoded as a UTF-16 string. Note the UTF-16 length is not the same
435 // as the string length of the string data.
436 const char* GetStringDataAndUtf16Length(const StringId& string_id, uint32_t* utf16_length) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700437
438 const char* GetStringData(const StringId& string_id) const {
Ian Rogersdfb325e2013-10-30 01:00:44 -0700439 uint32_t ignored;
440 return GetStringDataAndUtf16Length(string_id, &ignored);
Ian Rogers0571d352011-11-03 19:51:38 -0700441 }
442
Ian Rogersdfb325e2013-10-30 01:00:44 -0700443 // Index version of GetStringDataAndUtf16Length.
444 const char* StringDataAndUtf16LengthByIdx(uint32_t idx, uint32_t* utf16_length) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700445 if (idx == kDexNoIndex) {
Ian Rogersdfb325e2013-10-30 01:00:44 -0700446 *utf16_length = 0;
Ian Rogers0571d352011-11-03 19:51:38 -0700447 return NULL;
448 }
449 const StringId& string_id = GetStringId(idx);
Ian Rogersdfb325e2013-10-30 01:00:44 -0700450 return GetStringDataAndUtf16Length(string_id, utf16_length);
Ian Rogers0571d352011-11-03 19:51:38 -0700451 }
452
453 const char* StringDataByIdx(uint32_t idx) const {
Elliott Hughes45651fd2012-02-21 15:48:20 -0800454 uint32_t unicode_length;
Ian Rogersdfb325e2013-10-30 01:00:44 -0700455 return StringDataAndUtf16LengthByIdx(idx, &unicode_length);
Ian Rogers0571d352011-11-03 19:51:38 -0700456 }
457
Ian Rogers637c65b2013-05-31 11:46:00 -0700458 // Looks up a string id for a given modified utf8 string.
459 const StringId* FindStringId(const char* string) const;
460
461 // Looks up a string id for a given utf16 string.
462 const StringId* FindStringId(const uint16_t* string) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700463
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700464 // Returns the number of type identifiers in the .dex file.
Ian Rogers68b56852014-08-29 20:19:11 -0700465 uint32_t NumTypeIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700466 DCHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700467 return header_->type_ids_size_;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700468 }
469
Ian Rogers0571d352011-11-03 19:51:38 -0700470 // Returns the TypeId at the specified index.
471 const TypeId& GetTypeId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700472 DCHECK_LT(idx, NumTypeIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700473 return type_ids_[idx];
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700474 }
475
Ian Rogers0571d352011-11-03 19:51:38 -0700476 uint16_t GetIndexForTypeId(const TypeId& type_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800477 CHECK_GE(&type_id, type_ids_) << GetLocation();
478 CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700479 size_t result = &type_id - type_ids_;
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800480 DCHECK_LT(result, 65536U) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700481 return static_cast<uint16_t>(result);
482 }
483
484 // Get the descriptor string associated with a given type index.
Elliott Hughes45651fd2012-02-21 15:48:20 -0800485 const char* StringByTypeIdx(uint32_t idx, uint32_t* unicode_length) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700486 const TypeId& type_id = GetTypeId(idx);
Ian Rogersdfb325e2013-10-30 01:00:44 -0700487 return StringDataAndUtf16LengthByIdx(type_id.descriptor_idx_, unicode_length);
Ian Rogers0571d352011-11-03 19:51:38 -0700488 }
489
490 const char* StringByTypeIdx(uint32_t idx) const {
491 const TypeId& type_id = GetTypeId(idx);
492 return StringDataByIdx(type_id.descriptor_idx_);
493 }
494
495 // Returns the type descriptor string of a type id.
496 const char* GetTypeDescriptor(const TypeId& type_id) const {
497 return StringDataByIdx(type_id.descriptor_idx_);
498 }
499
500 // Looks up a type for the given string index
501 const TypeId* FindTypeId(uint32_t string_idx) const;
502
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700503 // Returns the number of field identifiers in the .dex file.
504 size_t NumFieldIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700505 DCHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700506 return header_->field_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700507 }
508
Ian Rogers0571d352011-11-03 19:51:38 -0700509 // Returns the FieldId at the specified index.
510 const FieldId& GetFieldId(uint32_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200511 DCHECK_LT(idx, NumFieldIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700512 return field_ids_[idx];
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700513 }
514
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800515 uint32_t GetIndexForFieldId(const FieldId& field_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800516 CHECK_GE(&field_id, field_ids_) << GetLocation();
517 CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation();
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800518 return &field_id - field_ids_;
519 }
520
521 // Looks up a field by its declaring class, name and type
522 const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass,
523 const DexFile::StringId& name,
524 const DexFile::TypeId& type) const;
525
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700526 // Returns the declaring class descriptor string of a field id.
527 const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const {
Brian Carlstromb9edb842011-08-28 16:31:06 -0700528 const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_);
529 return GetTypeDescriptor(type_id);
530 }
531
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700532 // Returns the class descriptor string of a field id.
533 const char* GetFieldTypeDescriptor(const FieldId& field_id) const {
534 const DexFile::TypeId& type_id = GetTypeId(field_id.type_idx_);
535 return GetTypeDescriptor(type_id);
536 }
537
Brian Carlstromb9edb842011-08-28 16:31:06 -0700538 // Returns the name of a field id.
539 const char* GetFieldName(const FieldId& field_id) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700540 return StringDataByIdx(field_id.name_idx_);
Brian Carlstromb9edb842011-08-28 16:31:06 -0700541 }
542
Ian Rogers0571d352011-11-03 19:51:38 -0700543 // Returns the number of method identifiers in the .dex file.
544 size_t NumMethodIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700545 DCHECK(header_ != NULL) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700546 return header_->method_ids_size_;
547 }
548
549 // Returns the MethodId at the specified index.
550 const MethodId& GetMethodId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700551 DCHECK_LT(idx, NumMethodIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700552 return method_ids_[idx];
553 }
554
555 uint32_t GetIndexForMethodId(const MethodId& method_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800556 CHECK_GE(&method_id, method_ids_) << GetLocation();
557 CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700558 return &method_id - method_ids_;
559 }
560
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800561 // Looks up a method by its declaring class, name and proto_id
562 const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass,
563 const DexFile::StringId& name,
Ian Rogers0571d352011-11-03 19:51:38 -0700564 const DexFile::ProtoId& signature) const;
565
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700566 // Returns the declaring class descriptor string of a method id.
567 const char* GetMethodDeclaringClassDescriptor(const MethodId& method_id) const {
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700568 const DexFile::TypeId& type_id = GetTypeId(method_id.class_idx_);
569 return GetTypeDescriptor(type_id);
570 }
571
jeffhao98eacac2011-09-14 16:11:53 -0700572 // Returns the prototype of a method id.
Brian Carlstromaded5f72011-10-07 17:15:04 -0700573 const ProtoId& GetMethodPrototype(const MethodId& method_id) const {
574 return GetProtoId(method_id.proto_idx_);
575 }
576
Ian Rogersd91d6d62013-09-25 20:26:14 -0700577 // Returns a representation of the signature of a method id.
578 const Signature GetMethodSignature(const MethodId& method_id) const;
jeffhao98eacac2011-09-14 16:11:53 -0700579
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700580 // Returns the name of a method id.
581 const char* GetMethodName(const MethodId& method_id) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700582 return StringDataByIdx(method_id.name_idx_);
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700583 }
584
Ian Rogers0571d352011-11-03 19:51:38 -0700585 // Returns the shorty of a method id.
586 const char* GetMethodShorty(const MethodId& method_id) const {
587 return StringDataByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700588 }
Elliott Hughes45651fd2012-02-21 15:48:20 -0800589 const char* GetMethodShorty(const MethodId& method_id, uint32_t* length) const {
Ian Rogerscf5077a2013-10-31 12:37:54 -0700590 // Using the UTF16 length is safe here as shorties are guaranteed to be ASCII characters.
Ian Rogersdfb325e2013-10-30 01:00:44 -0700591 return StringDataAndUtf16LengthByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_, length);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800592 }
Ian Rogers0571d352011-11-03 19:51:38 -0700593 // Returns the number of class definitions in the .dex file.
Ian Rogers68b56852014-08-29 20:19:11 -0700594 uint32_t NumClassDefs() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700595 DCHECK(header_ != NULL) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700596 return header_->class_defs_size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700597 }
598
599 // Returns the ClassDef at the specified index.
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700600 const ClassDef& GetClassDef(uint16_t idx) const {
Sebastien Hertzb24bd992013-08-02 15:19:09 +0200601 DCHECK_LT(idx, NumClassDefs()) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700602 return class_defs_[idx];
603 }
604
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700605 uint16_t GetIndexForClassDef(const ClassDef& class_def) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800606 CHECK_GE(&class_def, class_defs_) << GetLocation();
607 CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700608 return &class_def - class_defs_;
609 }
610
611 // Returns the class descriptor string of a class definition.
612 const char* GetClassDescriptor(const ClassDef& class_def) const {
613 return StringByTypeIdx(class_def.class_idx_);
614 }
615
616 // Looks up a class definition by its class descriptor.
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700617 const ClassDef* FindClassDef(const char* descriptor) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700618
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700619 // Looks up a class definition by its type index.
620 const ClassDef* FindClassDef(uint16_t type_idx) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700621
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700622 const TypeList* GetInterfacesList(const ClassDef& class_def) const {
623 if (class_def.interfaces_off_ == 0) {
624 return NULL;
625 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800626 const byte* addr = begin_ + class_def.interfaces_off_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700627 return reinterpret_cast<const TypeList*>(addr);
628 }
629 }
630
Ian Rogers0571d352011-11-03 19:51:38 -0700631 // Returns a pointer to the raw memory mapped class_data_item
632 const byte* GetClassData(const ClassDef& class_def) const {
633 if (class_def.class_data_off_ == 0) {
634 return NULL;
635 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800636 return begin_ + class_def.class_data_off_;
Ian Rogers0571d352011-11-03 19:51:38 -0700637 }
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700638 }
639
Ian Rogers0571d352011-11-03 19:51:38 -0700640 //
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800641 const CodeItem* GetCodeItem(const uint32_t code_off) const {
642 if (code_off == 0) {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700643 return NULL; // native or abstract method
644 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800645 const byte* addr = begin_ + code_off;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700646 return reinterpret_cast<const CodeItem*>(addr);
647 }
648 }
649
Ian Rogers0571d352011-11-03 19:51:38 -0700650 const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const {
651 return StringByTypeIdx(proto_id.return_type_idx_);
652 }
653
654 // Returns the number of prototype identifiers in the .dex file.
655 size_t NumProtoIds() const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700656 DCHECK(header_ != NULL) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700657 return header_->proto_ids_size_;
658 }
659
660 // Returns the ProtoId at the specified index.
661 const ProtoId& GetProtoId(uint32_t idx) const {
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700662 DCHECK_LT(idx, NumProtoIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700663 return proto_ids_[idx];
664 }
665
666 uint16_t GetIndexForProtoId(const ProtoId& proto_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800667 CHECK_GE(&proto_id, proto_ids_) << GetLocation();
668 CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700669 return &proto_id - proto_ids_;
670 }
671
672 // Looks up a proto id for a given return type and signature type list
Ian Rogersd91d6d62013-09-25 20:26:14 -0700673 const ProtoId* FindProtoId(uint16_t return_type_idx,
Vladimir Marko5c96e6b2013-11-14 15:34:17 +0000674 const uint16_t* signature_type_idxs, uint32_t signature_length) const;
675 const ProtoId* FindProtoId(uint16_t return_type_idx,
676 const std::vector<uint16_t>& signature_type_idxs) const {
677 return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size());
678 }
Ian Rogers0571d352011-11-03 19:51:38 -0700679
680 // Given a signature place the type ids into the given vector, returns true on success
Ian Rogersd91d6d62013-09-25 20:26:14 -0700681 bool CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx,
682 std::vector<uint16_t>* param_type_idxs) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700683
Ian Rogersd91d6d62013-09-25 20:26:14 -0700684 // Create a Signature from the given string signature or return Signature::NoSignature if not
685 // possible.
686 const Signature CreateSignature(const StringPiece& signature) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700687
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700688 // Returns the short form method descriptor for the given prototype.
689 const char* GetShorty(uint32_t proto_idx) const {
690 const ProtoId& proto_id = GetProtoId(proto_idx);
Ian Rogers0571d352011-11-03 19:51:38 -0700691 return StringDataByIdx(proto_id.shorty_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700692 }
693
694 const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
695 if (proto_id.parameters_off_ == 0) {
696 return NULL;
697 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800698 const byte* addr = begin_ + proto_id.parameters_off_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700699 return reinterpret_cast<const TypeList*>(addr);
700 }
701 }
702
Ian Rogers0571d352011-11-03 19:51:38 -0700703 const byte* GetEncodedStaticFieldValuesArray(const ClassDef& class_def) const {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700704 if (class_def.static_values_off_ == 0) {
705 return 0;
706 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800707 return begin_ + class_def.static_values_off_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700708 }
709 }
710
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800711 static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700712
713 // Get the base of the encoded data for the given DexCode.
Ian Rogers0571d352011-11-03 19:51:38 -0700714 static const byte* GetCatchHandlerData(const CodeItem& code_item, uint32_t offset) {
715 const byte* handler_data =
716 reinterpret_cast<const byte*>(GetTryItems(code_item, code_item.tries_size_));
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700717 return handler_data + offset;
718 }
719
Ian Rogersdbbc99d2013-04-18 16:51:54 -0700720 // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
721 static int32_t FindTryItem(const CodeItem &code_item, uint32_t address);
722
723 // Find the handler offset associated with the given address (ie dex pc). Returns -1 if none.
724 static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700725
Shih-wei Liao195487c2011-08-20 13:29:04 -0700726 // Get the pointer to the start of the debugging data
Ian Rogers0571d352011-11-03 19:51:38 -0700727 const byte* GetDebugInfoStream(const CodeItem* code_item) const {
Shih-wei Liao195487c2011-08-20 13:29:04 -0700728 if (code_item->debug_info_off_ == 0) {
729 return NULL;
730 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800731 return begin_ + code_item->debug_info_off_;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700732 }
733 }
734
735 // Callback for "new position table entry".
736 // Returning true causes the decoder to stop early.
Elliott Hughes2435a572012-02-17 16:07:41 -0800737 typedef bool (*DexDebugNewPositionCb)(void* context, uint32_t address, uint32_t line_num);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700738
739 // Callback for "new locals table entry". "signature" is an empty string
740 // if no signature is available for an entry.
Elliott Hughes2435a572012-02-17 16:07:41 -0800741 typedef void (*DexDebugNewLocalCb)(void* context, uint16_t reg,
Elliott Hughes24edeb52012-06-18 15:29:46 -0700742 uint32_t start_address,
743 uint32_t end_address,
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700744 const char* name,
745 const char* descriptor,
746 const char* signature);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700747
Elliott Hughes2435a572012-02-17 16:07:41 -0800748 static bool LineNumForPcCb(void* context, uint32_t address, uint32_t line_num);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700749
750 // Debug info opcodes and constants
751 enum {
752 DBG_END_SEQUENCE = 0x00,
753 DBG_ADVANCE_PC = 0x01,
754 DBG_ADVANCE_LINE = 0x02,
755 DBG_START_LOCAL = 0x03,
756 DBG_START_LOCAL_EXTENDED = 0x04,
757 DBG_END_LOCAL = 0x05,
758 DBG_RESTART_LOCAL = 0x06,
759 DBG_SET_PROLOGUE_END = 0x07,
760 DBG_SET_EPILOGUE_BEGIN = 0x08,
761 DBG_SET_FILE = 0x09,
762 DBG_FIRST_SPECIAL = 0x0a,
763 DBG_LINE_BASE = -4,
764 DBG_LINE_RANGE = 15,
765 };
766
767 struct LocalInfo {
Ian Rogersca190662012-06-26 15:45:57 -0700768 LocalInfo()
769 : name_(NULL), descriptor_(NULL), signature_(NULL), start_address_(0), is_live_(false) {}
Shih-wei Liao195487c2011-08-20 13:29:04 -0700770
Ian Rogers0571d352011-11-03 19:51:38 -0700771 const char* name_; // E.g., list
772 const char* descriptor_; // E.g., Ljava/util/LinkedList;
773 const char* signature_; // E.g., java.util.LinkedList<java.lang.Integer>
774 uint16_t start_address_; // PC location where the local is first defined.
775 bool is_live_; // Is the local defined and live.
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700776
777 private:
778 DISALLOW_COPY_AND_ASSIGN(LocalInfo);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700779 };
780
781 struct LineNumFromPcContext {
Ian Rogersca190662012-06-26 15:45:57 -0700782 LineNumFromPcContext(uint32_t address, uint32_t line_num)
783 : address_(address), line_num_(line_num) {}
Shih-wei Liao195487c2011-08-20 13:29:04 -0700784 uint32_t address_;
785 uint32_t line_num_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700786 private:
787 DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700788 };
789
Elliott Hughes2435a572012-02-17 16:07:41 -0800790 void InvokeLocalCbIfLive(void* context, int reg, uint32_t end_address,
Brian Carlstrom78128a62011-09-15 17:21:19 -0700791 LocalInfo* local_in_reg, DexDebugNewLocalCb local_cb) const {
Shih-wei Liao195487c2011-08-20 13:29:04 -0700792 if (local_cb != NULL && local_in_reg[reg].is_live_) {
Elliott Hughes2435a572012-02-17 16:07:41 -0800793 local_cb(context, reg, local_in_reg[reg].start_address_, end_address,
Elliott Hughesdbb40792011-11-18 17:05:22 -0800794 local_in_reg[reg].name_, local_in_reg[reg].descriptor_,
795 local_in_reg[reg].signature_ != NULL ? local_in_reg[reg].signature_ : "");
Shih-wei Liao195487c2011-08-20 13:29:04 -0700796 }
797 }
798
799 // Determine the source file line number based on the program counter.
800 // "pc" is an offset, in 16-bit units, from the start of the method's code.
801 //
802 // Returns -1 if no match was found (possibly because the source files were
803 // compiled without "-g", so no line number information is present).
804 // Returns -2 for native methods (as expected in exception traces).
805 //
806 // This is used by runtime; therefore use art::Method not art::DexFile::Method.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800807 int32_t GetLineNumFromPC(mirror::ArtMethod* method, uint32_t rel_pc) const
Ian Rogersb726dcb2012-09-05 08:57:23 -0700808 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700809
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800810 void DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
Elliott Hughes2435a572012-02-17 16:07:41 -0800811 DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
812 void* context) const;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700813
Ian Rogers0571d352011-11-03 19:51:38 -0700814 const char* GetSourceFile(const ClassDef& class_def) const {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700815 if (class_def.source_file_idx_ == 0xffffffff) {
816 return NULL;
817 } else {
Ian Rogers0571d352011-11-03 19:51:38 -0700818 return StringDataByIdx(class_def.source_file_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700819 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700820 }
821
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800822 int GetPermissions() const;
Ian Rogers1c849e52012-06-28 14:00:33 -0700823
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200824 bool IsReadOnly() const;
825
Brian Carlstrome0948e12013-08-29 09:36:15 -0700826 bool EnableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200827
Brian Carlstrome0948e12013-08-29 09:36:15 -0700828 bool DisableWrite() const;
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200829
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700830 const byte* Begin() const {
831 return begin_;
832 }
833
834 size_t Size() const {
835 return size_;
836 }
837
Calin Juravle4e1d5792014-07-15 23:56:47 +0100838 static std::string GetMultiDexClassesDexName(size_t number, const char* dex_location);
839
840 // Returns the canonical form of the given dex location.
841 //
842 // There are different flavors of "dex locations" as follows:
843 // the file name of a dex file:
844 // The actual file path that the dex file has on disk.
845 // dex_location:
846 // This acts as a key for the class linker to know which dex file to load.
847 // It may correspond to either an old odex file or a particular dex file
848 // inside an oat file. In the first case it will also match the file name
849 // of the dex file. In the second case (oat) it will include the file name
850 // and possibly some multidex annotation to uniquely identify it.
851 // canonical_dex_location:
852 // the dex_location where it's file name part has been made canonical.
853 static std::string GetDexCanonicalLocation(const char* dex_location);
854
Carl Shapiro1fb86202011-06-27 17:43:13 -0700855 private:
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700856 // Opens a .dex file
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700857 static const DexFile* OpenFile(int fd, const char* location, bool verify, std::string* error_msg);
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700858
Andreas Gampe833a4852014-05-21 18:46:59 -0700859 // Opens dex files from within a .jar, .zip, or .apk file
860 static bool OpenZip(int fd, const std::string& location, std::string* error_msg,
861 std::vector<const DexFile*>* dex_files);
862
863 enum class ZipOpenErrorCode { // private
864 kNoError,
865 kEntryNotFound,
866 kExtractToMemoryError,
867 kDexFileError,
868 kMakeReadOnlyError,
869 kVerifyError
870 };
871
872 // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-nullptr
873 // return.
874 static const DexFile* Open(const ZipArchive& zip_archive, const char* entry_name,
875 const std::string& location, std::string* error_msg,
876 ZipOpenErrorCode* error_code);
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700877
Brian Carlstrom89521892011-12-07 22:05:07 -0800878 // Opens a .dex file at the given address backed by a MemMap
879 static const DexFile* OpenMemory(const std::string& location,
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800880 uint32_t location_checksum,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700881 MemMap* mem_map,
882 std::string* error_msg);
Brian Carlstrom89521892011-12-07 22:05:07 -0800883
884 // Opens a .dex file at the given address, optionally backed by a MemMap
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700885 static const DexFile* OpenMemory(const byte* dex_file,
jeffhaof6174e82012-01-31 16:14:17 -0800886 size_t size,
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700887 const std::string& location,
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800888 uint32_t location_checksum,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700889 MemMap* mem_map,
890 std::string* error_msg);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700891
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800892 DexFile(const byte* base, size_t size,
Brian Carlstrom28db0122012-10-18 16:20:41 -0700893 const std::string& location,
894 uint32_t location_checksum,
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800895 MemMap* mem_map);
jeffhaof6174e82012-01-31 16:14:17 -0800896
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700897 // Top-level initializer that calls other Init methods.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700898 bool Init(std::string* error_msg);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700899
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800900 // Returns true if the header magic and version numbers are of the expected values.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700901 bool CheckMagicAndVersion(std::string* error_msg) const;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700902
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800903 void DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx,
Elliott Hughes2435a572012-02-17 16:07:41 -0800904 DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
905 void* context, const byte* stream, LocalInfo* local_in_reg) const;
Elliott Hughes03181a82011-11-17 17:22:21 -0800906
Andreas Gampe833a4852014-05-21 18:46:59 -0700907 // Check whether a location denotes a multidex dex file. This is a very simple check: returns
908 // whether the string contains the separator character.
909 static bool IsMultiDexLocation(const char* location);
910
911 // Splits a multidex location at the last separator character. The second component is a pointer
912 // to the character after the separator. The first is a copy of the substring up to the separator.
913 //
914 // Note: It's the caller's job to free the first component of the returned pair.
915 // Bug 15313523: gcc/libc++ don't allow a unique_ptr for the first component
916 static std::pair<const char*, const char*> SplitMultiDexLocation(const char* location);
917
918
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700919 // The base address of the memory mapping.
Ian Rogers62d6c772013-02-27 08:32:07 -0800920 const byte* const begin_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700921
922 // The size of the underlying memory allocation in bytes.
Ian Rogers62d6c772013-02-27 08:32:07 -0800923 const size_t size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700924
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700925 // Typically the dex file name when available, alternatively some identifying string.
Brian Carlstroma663ea52011-08-19 23:33:41 -0700926 //
927 // The ClassLinker will use this to match DexFiles the boot class
928 // path to DexCache::GetLocation when loading from an image.
929 const std::string location_;
930
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800931 const uint32_t location_checksum_;
932
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700933 // Manages the underlying memory allocation.
Ian Rogers700a4022014-05-19 16:49:03 -0700934 std::unique_ptr<MemMap> mem_map_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700935
936 // Points to the header section.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800937 const Header* const header_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700938
939 // Points to the base of the string identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800940 const StringId* const string_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700941
942 // Points to the base of the type identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800943 const TypeId* const type_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700944
945 // Points to the base of the field identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800946 const FieldId* const field_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700947
948 // Points to the base of the method identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800949 const MethodId* const method_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700950
951 // Points to the base of the prototype identifier list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800952 const ProtoId* const proto_ids_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700953
954 // Points to the base of the class definition list.
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800955 const ClassDef* const class_defs_;
Ian Rogers68b56852014-08-29 20:19:11 -0700956
957 // Number of misses finding a class def from a descriptor.
958 mutable Atomic<uint32_t> find_class_def_misses_;
959
960 struct UTF16HashCmp {
961 // Hash function.
962 size_t operator()(const char* key) const {
963 return ComputeUtf8Hash(key);
964 }
965 // std::equal function.
966 bool operator()(const char* a, const char* b) const {
967 return CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(a, b) == 0;
968 }
969 };
970 typedef std::unordered_map<const char*, const ClassDef*, UTF16HashCmp, UTF16HashCmp> Index;
971 mutable Atomic<Index*> class_def_index_;
972 mutable Mutex build_class_def_index_mutex_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700973};
Brian Carlstrom0d6adac2014-02-05 17:39:16 -0800974std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);
Carl Shapiro1fb86202011-06-27 17:43:13 -0700975
Ian Rogers0571d352011-11-03 19:51:38 -0700976// Iterate over a dex file's ProtoId's paramters
977class DexFileParameterIterator {
978 public:
979 DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id)
980 : dex_file_(dex_file), size_(0), pos_(0) {
981 type_list_ = dex_file_.GetProtoParameters(proto_id);
982 if (type_list_ != NULL) {
983 size_ = type_list_->Size();
984 }
985 }
986 bool HasNext() const { return pos_ < size_; }
987 void Next() { ++pos_; }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800988 uint16_t GetTypeIdx() {
Ian Rogers0571d352011-11-03 19:51:38 -0700989 return type_list_->GetTypeItem(pos_).type_idx_;
990 }
991 const char* GetDescriptor() {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800992 return dex_file_.StringByTypeIdx(GetTypeIdx());
Ian Rogers0571d352011-11-03 19:51:38 -0700993 }
994 private:
995 const DexFile& dex_file_;
996 const DexFile::TypeList* type_list_;
997 uint32_t size_;
998 uint32_t pos_;
999 DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
1000};
1001
Ian Rogersd91d6d62013-09-25 20:26:14 -07001002// Abstract the signature of a method.
1003class Signature {
1004 public:
1005 std::string ToString() const;
1006
1007 static Signature NoSignature() {
1008 return Signature();
1009 }
1010
Ian Rogersdfb325e2013-10-30 01:00:44 -07001011 bool operator==(const Signature& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001012 bool operator!=(const Signature& rhs) const {
1013 return !(*this == rhs);
1014 }
1015
Vladimir Markod9cffea2013-11-25 15:08:02 +00001016 bool operator==(const StringPiece& rhs) const;
Ian Rogersd91d6d62013-09-25 20:26:14 -07001017
1018 private:
1019 Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
1020 }
1021
1022 Signature() : dex_file_(nullptr), proto_id_(nullptr) {
1023 }
1024
1025 friend class DexFile;
1026
1027 const DexFile* const dex_file_;
1028 const DexFile::ProtoId* const proto_id_;
1029};
1030std::ostream& operator<<(std::ostream& os, const Signature& sig);
1031
Ian Rogers0571d352011-11-03 19:51:38 -07001032// Iterate and decode class_data_item
1033class ClassDataItemIterator {
1034 public:
1035 ClassDataItemIterator(const DexFile& dex_file, const byte* raw_class_data_item)
1036 : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) {
1037 ReadClassDataHeader();
1038 if (EndOfInstanceFieldsPos() > 0) {
1039 ReadClassDataField();
1040 } else if (EndOfVirtualMethodsPos() > 0) {
1041 ReadClassDataMethod();
1042 }
1043 }
1044 uint32_t NumStaticFields() const {
1045 return header_.static_fields_size_;
1046 }
1047 uint32_t NumInstanceFields() const {
1048 return header_.instance_fields_size_;
1049 }
1050 uint32_t NumDirectMethods() const {
1051 return header_.direct_methods_size_;
1052 }
1053 uint32_t NumVirtualMethods() const {
1054 return header_.virtual_methods_size_;
1055 }
1056 bool HasNextStaticField() const {
1057 return pos_ < EndOfStaticFieldsPos();
1058 }
1059 bool HasNextInstanceField() const {
1060 return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos();
1061 }
1062 bool HasNextDirectMethod() const {
1063 return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos();
1064 }
1065 bool HasNextVirtualMethod() const {
1066 return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos();
1067 }
1068 bool HasNext() const {
1069 return pos_ < EndOfVirtualMethodsPos();
1070 }
Ian Rogers637c65b2013-05-31 11:46:00 -07001071 inline void Next() {
Ian Rogers0571d352011-11-03 19:51:38 -07001072 pos_++;
1073 if (pos_ < EndOfStaticFieldsPos()) {
1074 last_idx_ = GetMemberIndex();
1075 ReadClassDataField();
1076 } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) {
1077 last_idx_ = 0; // transition to next array, reset last index
1078 ReadClassDataField();
1079 } else if (pos_ < EndOfInstanceFieldsPos()) {
1080 last_idx_ = GetMemberIndex();
1081 ReadClassDataField();
1082 } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) {
1083 last_idx_ = 0; // transition to next array, reset last index
1084 ReadClassDataMethod();
1085 } else if (pos_ < EndOfDirectMethodsPos()) {
1086 last_idx_ = GetMemberIndex();
1087 ReadClassDataMethod();
1088 } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) {
1089 last_idx_ = 0; // transition to next array, reset last index
1090 ReadClassDataMethod();
1091 } else if (pos_ < EndOfVirtualMethodsPos()) {
1092 last_idx_ = GetMemberIndex();
1093 ReadClassDataMethod();
1094 } else {
1095 DCHECK(!HasNext());
1096 }
1097 }
1098 uint32_t GetMemberIndex() const {
1099 if (pos_ < EndOfInstanceFieldsPos()) {
1100 return last_idx_ + field_.field_idx_delta_;
1101 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001102 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001103 return last_idx_ + method_.method_idx_delta_;
1104 }
1105 }
1106 uint32_t GetMemberAccessFlags() const {
1107 if (pos_ < EndOfInstanceFieldsPos()) {
1108 return field_.access_flags_;
1109 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001110 DCHECK_LT(pos_, EndOfVirtualMethodsPos());
Ian Rogers0571d352011-11-03 19:51:38 -07001111 return method_.access_flags_;
1112 }
1113 }
Ian Rogers08f753d2012-08-24 14:35:25 -07001114 InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const {
1115 if (HasNextDirectMethod()) {
Brian Carlstromdf629502013-07-17 22:39:56 -07001116 if ((GetMemberAccessFlags() & kAccStatic) != 0) {
Ian Rogers08f753d2012-08-24 14:35:25 -07001117 return kStatic;
1118 } else {
1119 return kDirect;
1120 }
1121 } else {
Sebastien Hertzb24bd992013-08-02 15:19:09 +02001122 DCHECK_EQ(GetMemberAccessFlags() & kAccStatic, 0U);
Ian Rogers08f753d2012-08-24 14:35:25 -07001123 if ((class_def.access_flags_ & kAccInterface) != 0) {
1124 return kInterface;
1125 } else if ((GetMemberAccessFlags() & kAccConstructor) != 0) {
1126 return kSuper;
1127 } else {
1128 return kVirtual;
1129 }
1130 }
1131 }
Ian Rogers0571d352011-11-03 19:51:38 -07001132 const DexFile::CodeItem* GetMethodCodeItem() const {
1133 return dex_file_.GetCodeItem(method_.code_off_);
1134 }
1135 uint32_t GetMethodCodeItemOffset() const {
1136 return method_.code_off_;
1137 }
jeffhao10037c82012-01-23 15:06:23 -08001138 const byte* EndDataPointer() const {
1139 CHECK(!HasNext());
1140 return ptr_pos_;
1141 }
Elliott Hughesa21039c2012-06-21 12:09:25 -07001142
Ian Rogers0571d352011-11-03 19:51:38 -07001143 private:
1144 // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the
1145 // header for a class_data_item
1146 struct ClassDataHeader {
1147 uint32_t static_fields_size_; // the number of static fields
1148 uint32_t instance_fields_size_; // the number of instance fields
1149 uint32_t direct_methods_size_; // the number of direct methods
1150 uint32_t virtual_methods_size_; // the number of virtual methods
1151 } header_;
1152
1153 // Read and decode header from a class_data_item stream into header
1154 void ReadClassDataHeader();
1155
1156 uint32_t EndOfStaticFieldsPos() const {
1157 return header_.static_fields_size_;
1158 }
1159 uint32_t EndOfInstanceFieldsPos() const {
1160 return EndOfStaticFieldsPos() + header_.instance_fields_size_;
1161 }
1162 uint32_t EndOfDirectMethodsPos() const {
1163 return EndOfInstanceFieldsPos() + header_.direct_methods_size_;
1164 }
1165 uint32_t EndOfVirtualMethodsPos() const {
1166 return EndOfDirectMethodsPos() + header_.virtual_methods_size_;
1167 }
1168
1169 // A decoded version of the field of a class_data_item
1170 struct ClassDataField {
1171 uint32_t field_idx_delta_; // delta of index into the field_ids array for FieldId
1172 uint32_t access_flags_; // access flags for the field
1173 ClassDataField() : field_idx_delta_(0), access_flags_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001174
Ian Rogers0571d352011-11-03 19:51:38 -07001175 private:
1176 DISALLOW_COPY_AND_ASSIGN(ClassDataField);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001177 };
1178 ClassDataField field_;
Ian Rogers0571d352011-11-03 19:51:38 -07001179
1180 // Read and decode a field from a class_data_item stream into field
1181 void ReadClassDataField();
1182
1183 // A decoded version of the method of a class_data_item
1184 struct ClassDataMethod {
1185 uint32_t method_idx_delta_; // delta of index into the method_ids array for MethodId
1186 uint32_t access_flags_;
1187 uint32_t code_off_;
1188 ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {}
Elliott Hughesa21039c2012-06-21 12:09:25 -07001189
Ian Rogers0571d352011-11-03 19:51:38 -07001190 private:
1191 DISALLOW_COPY_AND_ASSIGN(ClassDataMethod);
Elliott Hughesee0fa762012-03-26 17:12:41 -07001192 };
1193 ClassDataMethod method_;
Ian Rogers0571d352011-11-03 19:51:38 -07001194
1195 // Read and decode a method from a class_data_item stream into method
1196 void ReadClassDataMethod();
1197
1198 const DexFile& dex_file_;
1199 size_t pos_; // integral number of items passed
1200 const byte* ptr_pos_; // pointer into stream of class_data_item
1201 uint32_t last_idx_; // last read field or method index to apply delta to
1202 DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
1203};
1204
Ian Rogers0571d352011-11-03 19:51:38 -07001205class EncodedStaticFieldValueIterator {
1206 public:
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001207 EncodedStaticFieldValueIterator(const DexFile& dex_file, Handle<mirror::DexCache>* dex_cache,
1208 Handle<mirror::ClassLoader>* class_loader,
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001209 ClassLinker* linker, const DexFile::ClassDef& class_def)
Ian Rogersb726dcb2012-09-05 08:57:23 -07001210 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers0571d352011-11-03 19:51:38 -07001211
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001212 template<bool kTransactionActive>
Hiroshi Yamauchi67ef46a2014-08-21 15:59:43 -07001213 void ReadValueToField(Handle<mirror::ArtField> field) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers0571d352011-11-03 19:51:38 -07001214
1215 bool HasNext() { return pos_ < array_size_; }
1216
1217 void Next();
Elliott Hughesa21039c2012-06-21 12:09:25 -07001218
Ian Rogers0571d352011-11-03 19:51:38 -07001219 enum ValueType {
1220 kByte = 0x00,
1221 kShort = 0x02,
1222 kChar = 0x03,
1223 kInt = 0x04,
1224 kLong = 0x06,
1225 kFloat = 0x10,
1226 kDouble = 0x11,
1227 kString = 0x17,
1228 kType = 0x18,
1229 kField = 0x19,
1230 kMethod = 0x1a,
1231 kEnum = 0x1b,
1232 kArray = 0x1c,
1233 kAnnotation = 0x1d,
1234 kNull = 0x1e,
1235 kBoolean = 0x1f
1236 };
1237
Brian Carlstrom88f36542012-10-16 23:24:21 -07001238 private:
Ian Rogers0571d352011-11-03 19:51:38 -07001239 static const byte kEncodedValueTypeMask = 0x1f; // 0b11111
1240 static const byte kEncodedValueArgShift = 5;
1241
1242 const DexFile& dex_file_;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001243 Handle<mirror::DexCache>* const dex_cache_; // Dex cache to resolve literal objects.
1244 Handle<mirror::ClassLoader>* const class_loader_; // ClassLoader to resolve types.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001245 ClassLinker* linker_; // Linker to resolve literal objects.
1246 size_t array_size_; // Size of array.
1247 size_t pos_; // Current position.
1248 const byte* ptr_; // Pointer into encoded data array.
1249 ValueType type_; // Type of current encoded value.
1250 jvalue jval_; // Value of current encoded value.
Ian Rogers0571d352011-11-03 19:51:38 -07001251 DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
1252};
Brian Carlstrom88f36542012-10-16 23:24:21 -07001253std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code);
Ian Rogers0571d352011-11-03 19:51:38 -07001254
1255class CatchHandlerIterator {
1256 public:
1257 CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address);
Logan Chien736df022012-04-27 16:25:57 +08001258
1259 CatchHandlerIterator(const DexFile::CodeItem& code_item,
1260 const DexFile::TryItem& try_item);
1261
Ian Rogers0571d352011-11-03 19:51:38 -07001262 explicit CatchHandlerIterator(const byte* handler_data) {
1263 Init(handler_data);
1264 }
1265
1266 uint16_t GetHandlerTypeIndex() const {
1267 return handler_.type_idx_;
1268 }
1269 uint32_t GetHandlerAddress() const {
1270 return handler_.address_;
1271 }
1272 void Next();
1273 bool HasNext() const {
1274 return remaining_count_ != -1 || catch_all_;
1275 }
1276 // End of this set of catch blocks, convenience method to locate next set of catch blocks
1277 const byte* EndDataPointer() const {
1278 CHECK(!HasNext());
1279 return current_data_;
1280 }
Elliott Hughesa21039c2012-06-21 12:09:25 -07001281
Ian Rogers0571d352011-11-03 19:51:38 -07001282 private:
Logan Chien736df022012-04-27 16:25:57 +08001283 void Init(const DexFile::CodeItem& code_item, int32_t offset);
Ian Rogers0571d352011-11-03 19:51:38 -07001284 void Init(const byte* handler_data);
1285
1286 struct CatchHandlerItem {
1287 uint16_t type_idx_; // type index of the caught exception type
1288 uint32_t address_; // handler address
1289 } handler_;
1290 const byte *current_data_; // the current handler in dex file.
1291 int32_t remaining_count_; // number of handlers not read.
1292 bool catch_all_; // is there a handler that will catch all exceptions in case
1293 // that all typed handler does not match.
1294};
1295
Carl Shapiro1fb86202011-06-27 17:43:13 -07001296} // namespace art
1297
Brian Carlstromfc0e3212013-07-17 14:40:12 -07001298#endif // ART_RUNTIME_DEX_FILE_H_