blob: 2f2106b82eefb988e9d372c4fdd9316da538ad3a [file] [log] [blame]
Carl Shapiro1fb86202011-06-27 17:43:13 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#ifndef ART_SRC_DEX_FILE_H_
4#define ART_SRC_DEX_FILE_H_
5
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07006#include <map>
Elliott Hughes0c424cb2011-08-26 10:16:25 -07007#include <string>
Brian Carlstrom74eb46a2011-08-02 20:10:14 -07008#include <vector>
Brian Carlstrom7e49dca2011-07-22 18:07:34 -07009
Elliott Hughes90a33692011-08-30 13:27:07 -070010#include "UniquePtr.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070011#include "globals.h"
Jesse Wilson6bf19152011-09-29 13:12:33 -040012#include "jni.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070013#include "logging.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070014#include "mem_map.h"
Jesse Wilson6bf19152011-09-29 13:12:33 -040015#include "mutex.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070016#include "stringpiece.h"
Shih-wei Liao2fb97532011-08-11 16:17:23 -070017#include "utils.h"
Carl Shapiro1fb86202011-06-27 17:43:13 -070018
19namespace art {
20
Brian Carlstroma6cc8932012-01-04 14:44:07 -080021class ZipArchive;
22
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070023// TODO: move all of the macro functionality into the DexCache class.
Brian Carlstromf615a612011-07-23 12:50:34 -070024class DexFile {
Carl Shapiro1fb86202011-06-27 17:43:13 -070025 public:
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070026 static const byte kDexMagic[];
27 static const byte kDexMagicVersion[];
28 static const size_t kSha1DigestSize = 20;
jeffhao10037c82012-01-23 15:06:23 -080029 static const uint32_t kDexEndianConstant = 0x12345678;
Carl Shapiro80d4dde2011-06-28 16:24:07 -070030
Brian Carlstromb7bbba42011-10-13 14:58:47 -070031 // name of the DexFile entry within a zip archive
32 static const char* kClassesDex;
33
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070034 // The value of an invalid index.
35 static const uint32_t kDexNoIndex = 0xFFFFFFFF;
36
Ian Rogers0571d352011-11-03 19:51:38 -070037 // The value of an invalid index.
38 static const uint16_t kDexNoIndex16 = 0xFFFF;
Carl Shapiro1fb86202011-06-27 17:43:13 -070039
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070040 // Raw header_item.
41 struct Header {
42 uint8_t magic_[8];
43 uint32_t checksum_;
44 uint8_t signature_[kSha1DigestSize];
45 uint32_t file_size_; // length of entire file
46 uint32_t header_size_; // offset to start of next section
47 uint32_t endian_tag_;
Ian Rogers0571d352011-11-03 19:51:38 -070048 uint32_t link_size_; // unused
49 uint32_t link_off_; // unused
50 uint32_t map_off_; // unused
51 uint32_t string_ids_size_; // number of StringIds
52 uint32_t string_ids_off_; // file offset of StringIds array
53 uint32_t type_ids_size_; // number of TypeIds, we don't support more than 65535
54 uint32_t type_ids_off_; // file offset of TypeIds array
55 uint32_t proto_ids_size_; // number of ProtoIds, we don't support more than 65535
56 uint32_t proto_ids_off_; // file offset of ProtoIds array
57 uint32_t field_ids_size_; // number of FieldIds
58 uint32_t field_ids_off_; // file offset of FieldIds array
59 uint32_t method_ids_size_; // number of MethodIds
60 uint32_t method_ids_off_; // file offset of MethodIds array
61 uint32_t class_defs_size_; // number of ClassDefs
62 uint32_t class_defs_off_; // file offset of ClassDef array
63 uint32_t data_size_; // unused
64 uint32_t data_off_; // unused
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -070065 private:
66 DISALLOW_COPY_AND_ASSIGN(Header);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070067 };
Carl Shapiro1fb86202011-06-27 17:43:13 -070068
jeffhao10037c82012-01-23 15:06:23 -080069 // Map item type codes.
70 enum {
71 kDexTypeHeaderItem = 0x0000,
72 kDexTypeStringIdItem = 0x0001,
73 kDexTypeTypeIdItem = 0x0002,
74 kDexTypeProtoIdItem = 0x0003,
75 kDexTypeFieldIdItem = 0x0004,
76 kDexTypeMethodIdItem = 0x0005,
77 kDexTypeClassDefItem = 0x0006,
78 kDexTypeMapList = 0x1000,
79 kDexTypeTypeList = 0x1001,
80 kDexTypeAnnotationSetRefList = 0x1002,
81 kDexTypeAnnotationSetItem = 0x1003,
82 kDexTypeClassDataItem = 0x2000,
83 kDexTypeCodeItem = 0x2001,
84 kDexTypeStringDataItem = 0x2002,
85 kDexTypeDebugInfoItem = 0x2003,
86 kDexTypeAnnotationItem = 0x2004,
87 kDexTypeEncodedArrayItem = 0x2005,
88 kDexTypeAnnotationsDirectoryItem = 0x2006,
89 };
90
91 struct MapItem {
92 uint16_t type_;
93 uint16_t unused_;
94 uint32_t size_;
95 uint32_t offset_;
96 private:
97 DISALLOW_COPY_AND_ASSIGN(MapItem);
98 };
99
100 struct MapList {
101 uint32_t size_;
102 MapItem list_[1];
103 private:
104 DISALLOW_COPY_AND_ASSIGN(MapList);
105 };
106
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700107 // Raw string_id_item.
108 struct StringId {
109 uint32_t string_data_off_; // offset in bytes from the base address
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700110 private:
111 DISALLOW_COPY_AND_ASSIGN(StringId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700112 };
113
114 // Raw type_id_item.
115 struct TypeId {
116 uint32_t descriptor_idx_; // index into string_ids
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700117 private:
118 DISALLOW_COPY_AND_ASSIGN(TypeId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700119 };
120
121 // Raw field_id_item.
122 struct FieldId {
Ian Rogers0571d352011-11-03 19:51:38 -0700123 uint16_t class_idx_; // index into type_ids_ array for defining class
124 uint16_t type_idx_; // index into type_ids_ array for field type
125 uint32_t name_idx_; // index into string_ids_ array for field name
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700126 private:
127 DISALLOW_COPY_AND_ASSIGN(FieldId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700128 };
129
130 // Raw method_id_item.
131 struct MethodId {
Ian Rogers0571d352011-11-03 19:51:38 -0700132 uint16_t class_idx_; // index into type_ids_ array for defining class
133 uint16_t proto_idx_; // index into proto_ids_ array for method prototype
134 uint32_t name_idx_; // index into string_ids_ array for method name
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700135 private:
136 DISALLOW_COPY_AND_ASSIGN(MethodId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700137 };
138
139 // Raw proto_id_item.
140 struct ProtoId {
Ian Rogers0571d352011-11-03 19:51:38 -0700141 uint32_t shorty_idx_; // index into string_ids array for shorty descriptor
142 uint16_t return_type_idx_; // index into type_ids array for return type
143 uint16_t pad_; // padding = 0
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700144 uint32_t parameters_off_; // file offset to type_list for parameter types
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700145 private:
146 DISALLOW_COPY_AND_ASSIGN(ProtoId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700147 };
148
149 // Raw class_def_item.
150 struct ClassDef {
Ian Rogers0571d352011-11-03 19:51:38 -0700151 uint16_t class_idx_; // index into type_ids_ array for this class
152 uint16_t pad1_; // padding = 0
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700153 uint32_t access_flags_;
Ian Rogers0571d352011-11-03 19:51:38 -0700154 uint16_t superclass_idx_; // index into type_ids_ array for superclass
155 uint16_t pad2_; // padding = 0
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700156 uint32_t interfaces_off_; // file offset to TypeList
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700157 uint32_t source_file_idx_; // index into string_ids_ for source file name
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700158 uint32_t annotations_off_; // file offset to annotations_directory_item
159 uint32_t class_data_off_; // file offset to class_data_item
160 uint32_t static_values_off_; // file offset to EncodedArray
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700161 private:
162 DISALLOW_COPY_AND_ASSIGN(ClassDef);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700163 };
164
165 // Raw type_item.
166 struct TypeItem {
167 uint16_t type_idx_; // index into type_ids section
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700168 private:
169 DISALLOW_COPY_AND_ASSIGN(TypeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700170 };
171
172 // Raw type_list.
173 class TypeList {
174 public:
175 uint32_t Size() const {
176 return size_;
177 }
178
179 const TypeItem& GetTypeItem(uint32_t idx) const {
180 CHECK_LT(idx, this->size_);
181 return this->list_[idx];
182 }
183
184 private:
185 uint32_t size_; // size of the list, in entries
186 TypeItem list_[1]; // elements of the list
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700187 DISALLOW_COPY_AND_ASSIGN(TypeList);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700188 };
189
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700190 // Raw code_item.
191 struct CodeItem {
192 uint16_t registers_size_;
193 uint16_t ins_size_;
194 uint16_t outs_size_;
195 uint16_t tries_size_;
196 uint32_t debug_info_off_; // file offset to debug info stream
Ian Rogersd81871c2011-10-03 13:57:23 -0700197 uint32_t insns_size_in_code_units_; // size of the insns array, in 2 byte code units
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700198 uint16_t insns_[1];
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700199 private:
200 DISALLOW_COPY_AND_ASSIGN(CodeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700201 };
202
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700203 // Raw try_item.
204 struct TryItem {
205 uint32_t start_addr_;
206 uint16_t insn_count_;
207 uint16_t handler_off_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700208 private:
209 DISALLOW_COPY_AND_ASSIGN(TryItem);
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700210 };
211
jeffhao10037c82012-01-23 15:06:23 -0800212 // Annotation constants.
213 enum {
214 kDexVisibilityBuild = 0x00, /* annotation visibility */
215 kDexVisibilityRuntime = 0x01,
216 kDexVisibilitySystem = 0x02,
217
218 kDexAnnotationByte = 0x00,
219 kDexAnnotationShort = 0x02,
220 kDexAnnotationChar = 0x03,
221 kDexAnnotationInt = 0x04,
222 kDexAnnotationLong = 0x06,
223 kDexAnnotationFloat = 0x10,
224 kDexAnnotationDouble = 0x11,
225 kDexAnnotationString = 0x17,
226 kDexAnnotationType = 0x18,
227 kDexAnnotationField = 0x19,
228 kDexAnnotationMethod = 0x1a,
229 kDexAnnotationEnum = 0x1b,
230 kDexAnnotationArray = 0x1c,
231 kDexAnnotationAnnotation = 0x1d,
232 kDexAnnotationNull = 0x1e,
233 kDexAnnotationBoolean = 0x1f,
234
235 kDexAnnotationValueTypeMask = 0x1f, /* low 5 bits */
236 kDexAnnotationValueArgShift = 5,
237 };
238
239 struct AnnotationsDirectoryItem {
240 uint32_t class_annotations_off_;
241 uint32_t fields_size_;
242 uint32_t methods_size_;
243 uint32_t parameters_size_;
244 private:
245 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
246 };
247
248 struct FieldAnnotationsItem {
249 uint32_t field_idx_;
250 uint32_t annotations_off_;
251 private:
252 DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem);
253 };
254
255 struct MethodAnnotationsItem {
256 uint32_t method_idx_;
257 uint32_t annotations_off_;
258 private:
259 DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem);
260 };
261
262 struct ParameterAnnotationsItem {
263 uint32_t method_idx_;
264 uint32_t annotations_off_;
265 private:
266 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem);
267 };
268
269 struct AnnotationSetRefItem {
270 uint32_t annotations_off_;
271 private:
272 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem);
273 };
274
275 struct AnnotationSetRefList {
276 uint32_t size_;
277 AnnotationSetRefItem list_[1];
278 private:
279 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
280 };
281
282 struct AnnotationSetItem {
283 uint32_t size_;
284 uint32_t entries_[1];
285 private:
286 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
287 };
288
289 struct AnnotationItem {
290 uint8_t visibility_;
291 uint8_t annotation_[1];
292 private:
293 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
294 };
295
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700296 typedef std::pair<const DexFile*, const DexFile::ClassDef*> ClassPathEntry;
297 typedef std::vector<const DexFile*> ClassPath;
298
299 // Search a collection of DexFiles for a descriptor
300 static ClassPathEntry FindInClassPath(const StringPiece& descriptor,
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700301 const ClassPath& class_path);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700302
Brian Carlstrom78128a62011-09-15 17:21:19 -0700303 // Opens a collection of .dex files
Brian Carlstromae826982011-11-09 01:33:42 -0800304 static void OpenDexFiles(const std::vector<const char*>& dex_filenames,
Brian Carlstrom78128a62011-09-15 17:21:19 -0700305 std::vector<const DexFile*>& dex_files,
306 const std::string& strip_location_prefix);
307
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700308 // Opens .dex file, guessing the container format based on file extension
Brian Carlstrom16192862011-09-12 17:50:06 -0700309 static const DexFile* Open(const std::string& filename,
310 const std::string& strip_location_prefix);
jeffhao262bf462011-10-20 18:36:32 -0700311
Brian Carlstrom89521892011-12-07 22:05:07 -0800312 // Opens .dex file, backed by existing memory
313 static const DexFile* Open(const uint8_t* base, size_t length, const std::string& location) {
314 return OpenMemory(base, length, location, NULL);
315 }
316
Brian Carlstroma6cc8932012-01-04 14:44:07 -0800317 // Opens .dex file from the classes.dex in a zip archive
318 static const DexFile* Open(const ZipArchive& zip_archive, const std::string& location);
319
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700320 // Closes a .dex file.
Brian Carlstromf615a612011-07-23 12:50:34 -0700321 virtual ~DexFile();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700322
Brian Carlstroma663ea52011-08-19 23:33:41 -0700323 const std::string& GetLocation() const {
324 return location_;
325 }
326
Jesse Wilson6bf19152011-09-29 13:12:33 -0400327 // Returns a com.android.dex.Dex object corresponding to the mapped-in dex file.
328 // Used by managed code to implement annotations.
329 jobject GetDexObject(JNIEnv* env) const;
330
Brian Carlstroma663ea52011-08-19 23:33:41 -0700331 const Header& GetHeader() const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800332 CHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700333 return *header_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700334 }
335
Ian Rogers0571d352011-11-03 19:51:38 -0700336 // Decode the dex magic version
Ian Rogersd81871c2011-10-03 13:57:23 -0700337 uint32_t GetVersion() const;
338
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800339 // Returns true if the byte string points to the magic value.
340 static bool IsMagicValid(const byte* magic);
341
342 // Returns true if the byte string after the magic is the correct value.
343 static bool IsVersionValid(const byte* magic);
344
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700345 // Returns the number of string identifiers in the .dex file.
346 size_t NumStringIds() const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800347 CHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700348 return header_->string_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700349 }
350
Ian Rogers0571d352011-11-03 19:51:38 -0700351 // Returns the StringId at the specified index.
352 const StringId& GetStringId(uint32_t idx) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800353 CHECK_LT(idx, NumStringIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700354 return string_ids_[idx];
355 }
356
357 uint32_t GetIndexForStringId(const StringId& string_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800358 CHECK_GE(&string_id, string_ids_) << GetLocation();
359 CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700360 return &string_id - string_ids_;
361 }
362
363 int32_t GetStringLength(const StringId& string_id) const;
364
365 // Returns a pointer to the UTF-8 string data referred to by the given string_id.
366 const char* GetStringDataAndLength(const StringId& string_id, int32_t* length) const;
367
368 const char* GetStringData(const StringId& string_id) const {
369 int32_t length;
370 return GetStringDataAndLength(string_id, &length);
371 }
372
373 // return the UTF-8 encoded string with the specified string_id index
374 const char* StringDataAndLengthByIdx(uint32_t idx, int32_t* unicode_length) const {
375 if (idx == kDexNoIndex) {
376 *unicode_length = 0;
377 return NULL;
378 }
379 const StringId& string_id = GetStringId(idx);
380 return GetStringDataAndLength(string_id, unicode_length);
381 }
382
383 const char* StringDataByIdx(uint32_t idx) const {
384 int32_t unicode_length;
385 return StringDataAndLengthByIdx(idx, &unicode_length);
386 }
387
388 // Looks up a string id for a given string
389 const StringId* FindStringId(const std::string& string) const;
390
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700391 // Returns the number of type identifiers in the .dex file.
392 size_t NumTypeIds() const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800393 CHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700394 return header_->type_ids_size_;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700395 }
396
Ian Rogers0571d352011-11-03 19:51:38 -0700397 // Returns the TypeId at the specified index.
398 const TypeId& GetTypeId(uint32_t idx) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800399 CHECK_LT(idx, NumTypeIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700400 return type_ids_[idx];
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700401 }
402
Ian Rogers0571d352011-11-03 19:51:38 -0700403 uint16_t GetIndexForTypeId(const TypeId& type_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800404 CHECK_GE(&type_id, type_ids_) << GetLocation();
405 CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700406 size_t result = &type_id - type_ids_;
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800407 DCHECK_LT(result, 65536U) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700408 return static_cast<uint16_t>(result);
409 }
410
411 // Get the descriptor string associated with a given type index.
412 const char* StringByTypeIdx(uint32_t idx, int32_t* unicode_length) const {
413 const TypeId& type_id = GetTypeId(idx);
414 return StringDataAndLengthByIdx(type_id.descriptor_idx_, unicode_length);
415 }
416
417 const char* StringByTypeIdx(uint32_t idx) const {
418 const TypeId& type_id = GetTypeId(idx);
419 return StringDataByIdx(type_id.descriptor_idx_);
420 }
421
422 // Returns the type descriptor string of a type id.
423 const char* GetTypeDescriptor(const TypeId& type_id) const {
424 return StringDataByIdx(type_id.descriptor_idx_);
425 }
426
427 // Looks up a type for the given string index
428 const TypeId* FindTypeId(uint32_t string_idx) const;
429
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700430 // Returns the number of field identifiers in the .dex file.
431 size_t NumFieldIds() const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800432 CHECK(header_ != NULL) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700433 return header_->field_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700434 }
435
Ian Rogers0571d352011-11-03 19:51:38 -0700436 // Returns the FieldId at the specified index.
437 const FieldId& GetFieldId(uint32_t idx) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800438 CHECK_LT(idx, NumFieldIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700439 return field_ids_[idx];
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700440 }
441
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800442 uint32_t GetIndexForFieldId(const FieldId& field_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800443 CHECK_GE(&field_id, field_ids_) << GetLocation();
444 CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation();
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800445 return &field_id - field_ids_;
446 }
447
448 // Looks up a field by its declaring class, name and type
449 const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass,
450 const DexFile::StringId& name,
451 const DexFile::TypeId& type) const;
452
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700453 // Returns the declaring class descriptor string of a field id.
454 const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const {
Brian Carlstromb9edb842011-08-28 16:31:06 -0700455 const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_);
456 return GetTypeDescriptor(type_id);
457 }
458
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700459 // Returns the class descriptor string of a field id.
460 const char* GetFieldTypeDescriptor(const FieldId& field_id) const {
461 const DexFile::TypeId& type_id = GetTypeId(field_id.type_idx_);
462 return GetTypeDescriptor(type_id);
463 }
464
Brian Carlstromb9edb842011-08-28 16:31:06 -0700465 // Returns the name of a field id.
466 const char* GetFieldName(const FieldId& field_id) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700467 return StringDataByIdx(field_id.name_idx_);
Brian Carlstromb9edb842011-08-28 16:31:06 -0700468 }
469
Ian Rogers0571d352011-11-03 19:51:38 -0700470 // Returns the number of method identifiers in the .dex file.
471 size_t NumMethodIds() const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800472 CHECK(header_ != NULL) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700473 return header_->method_ids_size_;
474 }
475
476 // Returns the MethodId at the specified index.
477 const MethodId& GetMethodId(uint32_t idx) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800478 CHECK_LT(idx, NumMethodIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700479 return method_ids_[idx];
480 }
481
482 uint32_t GetIndexForMethodId(const MethodId& method_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800483 CHECK_GE(&method_id, method_ids_) << GetLocation();
484 CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700485 return &method_id - method_ids_;
486 }
487
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800488 // Looks up a method by its declaring class, name and proto_id
489 const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass,
490 const DexFile::StringId& name,
Ian Rogers0571d352011-11-03 19:51:38 -0700491 const DexFile::ProtoId& signature) const;
492
Brian Carlstrom6b4ef022011-10-23 14:59:04 -0700493 // Returns the declaring class descriptor string of a method id.
494 const char* GetMethodDeclaringClassDescriptor(const MethodId& method_id) const {
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700495 const DexFile::TypeId& type_id = GetTypeId(method_id.class_idx_);
496 return GetTypeDescriptor(type_id);
497 }
498
jeffhao98eacac2011-09-14 16:11:53 -0700499 // Returns the prototype of a method id.
Brian Carlstromaded5f72011-10-07 17:15:04 -0700500 const ProtoId& GetMethodPrototype(const MethodId& method_id) const {
501 return GetProtoId(method_id.proto_idx_);
502 }
503
504 // Returns the signature of a method id.
505 const std::string GetMethodSignature(const MethodId& method_id) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700506 return CreateMethodSignature(method_id.proto_idx_, NULL);
jeffhao98eacac2011-09-14 16:11:53 -0700507 }
508
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700509 // Returns the name of a method id.
510 const char* GetMethodName(const MethodId& method_id) const {
Ian Rogers0571d352011-11-03 19:51:38 -0700511 return StringDataByIdx(method_id.name_idx_);
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700512 }
513
Ian Rogers0571d352011-11-03 19:51:38 -0700514 // Returns the shorty of a method id.
515 const char* GetMethodShorty(const MethodId& method_id) const {
516 return StringDataByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700517 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800518 const char* GetMethodShorty(const MethodId& method_id, int32_t* length) const {
519 return StringDataAndLengthByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_, length);
520 }
Ian Rogers0571d352011-11-03 19:51:38 -0700521 // Returns the number of class definitions in the .dex file.
522 size_t NumClassDefs() const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800523 CHECK(header_ != NULL) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700524 return header_->class_defs_size_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700525 }
526
527 // Returns the ClassDef at the specified index.
528 const ClassDef& GetClassDef(uint32_t idx) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800529 CHECK_LT(idx, NumClassDefs()) << GetLocation();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700530 return class_defs_[idx];
531 }
532
Ian Rogers0571d352011-11-03 19:51:38 -0700533 uint32_t GetIndexForClassDef(const ClassDef& class_def) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800534 CHECK_GE(&class_def, class_defs_) << GetLocation();
535 CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700536 return &class_def - class_defs_;
537 }
538
539 // Returns the class descriptor string of a class definition.
540 const char* GetClassDescriptor(const ClassDef& class_def) const {
541 return StringByTypeIdx(class_def.class_idx_);
542 }
543
544 // Looks up a class definition by its class descriptor.
545 const ClassDef* FindClassDef(const StringPiece& descriptor) const;
546
547 // Looks up a class definition index by its class descriptor.
548 bool FindClassDefIndex(const StringPiece& descriptor, uint32_t& idx) const;
549
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700550 const TypeList* GetInterfacesList(const ClassDef& class_def) const {
551 if (class_def.interfaces_off_ == 0) {
552 return NULL;
553 } else {
554 const byte* addr = base_ + class_def.interfaces_off_;
555 return reinterpret_cast<const TypeList*>(addr);
556 }
557 }
558
Ian Rogers0571d352011-11-03 19:51:38 -0700559 // Returns a pointer to the raw memory mapped class_data_item
560 const byte* GetClassData(const ClassDef& class_def) const {
561 if (class_def.class_data_off_ == 0) {
562 return NULL;
563 } else {
564 return base_ + class_def.class_data_off_;
565 }
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700566 }
567
Ian Rogers0571d352011-11-03 19:51:38 -0700568 //
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800569 const CodeItem* GetCodeItem(const uint32_t code_off) const {
570 if (code_off == 0) {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700571 return NULL; // native or abstract method
572 } else {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800573 const byte* addr = base_ + code_off;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700574 return reinterpret_cast<const CodeItem*>(addr);
575 }
576 }
577
Ian Rogers0571d352011-11-03 19:51:38 -0700578 const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const {
579 return StringByTypeIdx(proto_id.return_type_idx_);
580 }
581
582 // Returns the number of prototype identifiers in the .dex file.
583 size_t NumProtoIds() const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800584 CHECK(header_ != NULL) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700585 return header_->proto_ids_size_;
586 }
587
588 // Returns the ProtoId at the specified index.
589 const ProtoId& GetProtoId(uint32_t idx) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800590 CHECK_LT(idx, NumProtoIds()) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700591 return proto_ids_[idx];
592 }
593
594 uint16_t GetIndexForProtoId(const ProtoId& proto_id) const {
Brian Carlstrom61e513c2011-12-09 15:30:06 -0800595 CHECK_GE(&proto_id, proto_ids_) << GetLocation();
596 CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation();
Ian Rogers0571d352011-11-03 19:51:38 -0700597 return &proto_id - proto_ids_;
598 }
599
600 // Looks up a proto id for a given return type and signature type list
601 const ProtoId* FindProtoId(uint16_t return_type_id,
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800602 const std::vector<uint16_t>& signature_type_idxs_) const;
Ian Rogers0571d352011-11-03 19:51:38 -0700603
604 // Given a signature place the type ids into the given vector, returns true on success
605 bool CreateTypeList(uint16_t* return_type_idx, std::vector<uint16_t>* param_type_idxs,
606 const std::string& signature) const;
607
608 // Given a proto_idx decode the type list and return type into a method signature
609 std::string CreateMethodSignature(uint32_t proto_idx, int32_t* unicode_length) const;
610
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700611 // Returns the short form method descriptor for the given prototype.
612 const char* GetShorty(uint32_t proto_idx) const {
613 const ProtoId& proto_id = GetProtoId(proto_idx);
Ian Rogers0571d352011-11-03 19:51:38 -0700614 return StringDataByIdx(proto_id.shorty_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700615 }
616
617 const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
618 if (proto_id.parameters_off_ == 0) {
619 return NULL;
620 } else {
621 const byte* addr = base_ + proto_id.parameters_off_;
622 return reinterpret_cast<const TypeList*>(addr);
623 }
624 }
625
Ian Rogers0571d352011-11-03 19:51:38 -0700626 const byte* GetEncodedStaticFieldValuesArray(const ClassDef& class_def) const {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700627 if (class_def.static_values_off_ == 0) {
628 return 0;
629 } else {
630 return base_ + class_def.static_values_off_;
631 }
632 }
633
Ian Rogers0571d352011-11-03 19:51:38 -0700634 static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset) {
Ian Rogersd81871c2011-10-03 13:57:23 -0700635 const uint16_t* insns_end_ = &code_item.insns_[code_item.insns_size_in_code_units_];
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700636 return reinterpret_cast<const TryItem*>
637 (RoundUp(reinterpret_cast<uint32_t>(insns_end_), 4)) + offset;
638 }
639
640 // Get the base of the encoded data for the given DexCode.
Ian Rogers0571d352011-11-03 19:51:38 -0700641 static const byte* GetCatchHandlerData(const CodeItem& code_item, uint32_t offset) {
642 const byte* handler_data =
643 reinterpret_cast<const byte*>(GetTryItems(code_item, code_item.tries_size_));
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700644 return handler_data + offset;
645 }
646
647 // Find the handler associated with a given address, if any.
648 // Initializes the given iterator and returns true if a match is
649 // found. Returns end if there is no applicable handler.
Ian Rogers0571d352011-11-03 19:51:38 -0700650 static int32_t FindCatchHandlerOffset(const CodeItem &code_item, int32_t tries_size,
651 uint32_t address);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700652
Shih-wei Liao195487c2011-08-20 13:29:04 -0700653 // Get the pointer to the start of the debugging data
Ian Rogers0571d352011-11-03 19:51:38 -0700654 const byte* GetDebugInfoStream(const CodeItem* code_item) const {
Shih-wei Liao195487c2011-08-20 13:29:04 -0700655 if (code_item->debug_info_off_ == 0) {
656 return NULL;
657 } else {
658 return base_ + code_item->debug_info_off_;
659 }
660 }
661
662 // Callback for "new position table entry".
663 // Returning true causes the decoder to stop early.
Brian Carlstrom78128a62011-09-15 17:21:19 -0700664 typedef bool (*DexDebugNewPositionCb)(void* cnxt, uint32_t address, uint32_t line_num);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700665
666 // Callback for "new locals table entry". "signature" is an empty string
667 // if no signature is available for an entry.
Brian Carlstrom78128a62011-09-15 17:21:19 -0700668 typedef void (*DexDebugNewLocalCb)(void* cnxt, uint16_t reg,
Shih-wei Liao195487c2011-08-20 13:29:04 -0700669 uint32_t startAddress,
670 uint32_t endAddress,
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700671 const char* name,
672 const char* descriptor,
673 const char* signature);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700674
Ian Rogers0571d352011-11-03 19:51:38 -0700675 static bool LineNumForPcCb(void* cnxt, uint32_t address, uint32_t line_num);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700676
677 // Debug info opcodes and constants
678 enum {
679 DBG_END_SEQUENCE = 0x00,
680 DBG_ADVANCE_PC = 0x01,
681 DBG_ADVANCE_LINE = 0x02,
682 DBG_START_LOCAL = 0x03,
683 DBG_START_LOCAL_EXTENDED = 0x04,
684 DBG_END_LOCAL = 0x05,
685 DBG_RESTART_LOCAL = 0x06,
686 DBG_SET_PROLOGUE_END = 0x07,
687 DBG_SET_EPILOGUE_BEGIN = 0x08,
688 DBG_SET_FILE = 0x09,
689 DBG_FIRST_SPECIAL = 0x0a,
690 DBG_LINE_BASE = -4,
691 DBG_LINE_RANGE = 15,
692 };
693
694 struct LocalInfo {
Ian Rogers0571d352011-11-03 19:51:38 -0700695 LocalInfo() : name_(NULL), descriptor_(NULL), signature_(NULL), start_address_(0),
696 is_live_(false) {}
Shih-wei Liao195487c2011-08-20 13:29:04 -0700697
Ian Rogers0571d352011-11-03 19:51:38 -0700698 const char* name_; // E.g., list
699 const char* descriptor_; // E.g., Ljava/util/LinkedList;
700 const char* signature_; // E.g., java.util.LinkedList<java.lang.Integer>
701 uint16_t start_address_; // PC location where the local is first defined.
702 bool is_live_; // Is the local defined and live.
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700703
704 private:
705 DISALLOW_COPY_AND_ASSIGN(LocalInfo);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700706 };
707
708 struct LineNumFromPcContext {
709 LineNumFromPcContext(uint32_t address, uint32_t line_num) :
710 address_(address), line_num_(line_num) {}
711 uint32_t address_;
712 uint32_t line_num_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700713 private:
714 DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700715 };
716
Brian Carlstrom78128a62011-09-15 17:21:19 -0700717 void InvokeLocalCbIfLive(void* cnxt, int reg, uint32_t end_address,
718 LocalInfo* local_in_reg, DexDebugNewLocalCb local_cb) const {
Shih-wei Liao195487c2011-08-20 13:29:04 -0700719 if (local_cb != NULL && local_in_reg[reg].is_live_) {
720 local_cb(cnxt, reg, local_in_reg[reg].start_address_, end_address,
Elliott Hughesdbb40792011-11-18 17:05:22 -0800721 local_in_reg[reg].name_, local_in_reg[reg].descriptor_,
722 local_in_reg[reg].signature_ != NULL ? local_in_reg[reg].signature_ : "");
Shih-wei Liao195487c2011-08-20 13:29:04 -0700723 }
724 }
725
726 // Determine the source file line number based on the program counter.
727 // "pc" is an offset, in 16-bit units, from the start of the method's code.
728 //
729 // Returns -1 if no match was found (possibly because the source files were
730 // compiled without "-g", so no line number information is present).
731 // Returns -2 for native methods (as expected in exception traces).
732 //
733 // This is used by runtime; therefore use art::Method not art::DexFile::Method.
Ian Rogers0571d352011-11-03 19:51:38 -0700734 int32_t GetLineNumFromPC(const Method* method, uint32_t rel_pc) const;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700735
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800736 void DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
Ian Rogers0571d352011-11-03 19:51:38 -0700737 DexDebugNewPositionCb posCb, DexDebugNewLocalCb local_cb,
738 void* cnxt) const;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700739
Ian Rogers0571d352011-11-03 19:51:38 -0700740 const char* GetSourceFile(const ClassDef& class_def) const {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700741 if (class_def.source_file_idx_ == 0xffffffff) {
742 return NULL;
743 } else {
Ian Rogers0571d352011-11-03 19:51:38 -0700744 return StringDataByIdx(class_def.source_file_idx_);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700745 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700746 }
747
jeffhaob4df5142011-09-19 20:25:32 -0700748 void ChangePermissions(int prot) const;
749
Carl Shapiro1fb86202011-06-27 17:43:13 -0700750 private:
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700751
752 // Opens a .dex file
753 static const DexFile* OpenFile(const std::string& filename,
754 const std::string& original_location,
755 const std::string& strip_location_prefix);
756
757 // Opens a dex file from within a .jar, .zip, or .apk file
758 static const DexFile* OpenZip(const std::string& filename,
759 const std::string& strip_location_prefix);
760
Brian Carlstrom89521892011-12-07 22:05:07 -0800761 // Opens a .dex file at the given address backed by a MemMap
762 static const DexFile* OpenMemory(const std::string& location,
763 MemMap* mem_map) {
764 return OpenMemory(mem_map->GetAddress(),
765 mem_map->GetLength(),
766 location,
767 mem_map);
768 }
769
770 // Opens a .dex file at the given address, optionally backed by a MemMap
Brian Carlstrom58ae9412011-10-04 00:56:06 -0700771 static const DexFile* OpenMemory(const byte* dex_file,
772 size_t length,
773 const std::string& location,
774 MemMap* mem_map);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700775
Brian Carlstrom89521892011-12-07 22:05:07 -0800776 DexFile(const byte* base, size_t length, const std::string& location, MemMap* mem_map)
777 : base_(base),
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700778 length_(length),
Brian Carlstroma663ea52011-08-19 23:33:41 -0700779 location_(location),
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700780 mem_map_(mem_map),
Jesse Wilson6bf19152011-09-29 13:12:33 -0400781 dex_object_lock_("a dex_object_lock_"),
782 dex_object_(NULL),
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700783 header_(0),
784 string_ids_(0),
785 type_ids_(0),
786 field_ids_(0),
787 method_ids_(0),
788 proto_ids_(0),
Brian Carlstroma663ea52011-08-19 23:33:41 -0700789 class_defs_(0) {
Brian Carlstrom89521892011-12-07 22:05:07 -0800790 CHECK(base_ != NULL) << GetLocation();
791 CHECK_GT(length_, 0U) << GetLocation();
Brian Carlstroma663ea52011-08-19 23:33:41 -0700792 }
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700793
794 // Top-level initializer that calls other Init methods.
795 bool Init();
796
797 // Caches pointers into to the various file sections.
798 void InitMembers();
799
800 // Builds the index of descriptors to class definitions.
801 void InitIndex();
802
Brian Carlstrom6e3b1d92012-01-11 01:36:32 -0800803 // Returns true if the header magic and version numbers are of the expected values.
jeffhao10037c82012-01-23 15:06:23 -0800804 bool CheckMagicAndVersion() const;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700805
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800806 void DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx,
Elliott Hughes03181a82011-11-17 17:22:21 -0800807 DexDebugNewPositionCb posCb, DexDebugNewLocalCb local_cb,
808 void* cnxt, const byte* stream, LocalInfo* local_in_reg) const;
809
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800810 // The index of descriptors to class definition indexes (as opposed to type id indexes)
Brian Carlstrome24fa612011-09-29 00:53:55 -0700811 typedef std::map<const StringPiece, uint32_t> Index;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700812 Index index_;
813
814 // The base address of the memory mapping.
815 const byte* base_;
816
817 // The size of the underlying memory allocation in bytes.
818 size_t length_;
819
Elliott Hughes64bf5a32011-09-20 14:43:12 -0700820 // Typically the dex file name when available, alternatively some identifying string.
Brian Carlstroma663ea52011-08-19 23:33:41 -0700821 //
822 // The ClassLinker will use this to match DexFiles the boot class
823 // path to DexCache::GetLocation when loading from an image.
824 const std::string location_;
825
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700826 // Manages the underlying memory allocation.
827 UniquePtr<MemMap> mem_map_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700828
Jesse Wilson6bf19152011-09-29 13:12:33 -0400829 // A cached com.android.dex.Dex instance, possibly NULL. Use GetDexObject.
830 mutable Mutex dex_object_lock_;
831 mutable jobject dex_object_;
832
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700833 // Points to the header section.
834 const Header* header_;
835
836 // Points to the base of the string identifier list.
837 const StringId* string_ids_;
838
839 // Points to the base of the type identifier list.
840 const TypeId* type_ids_;
841
842 // Points to the base of the field identifier list.
843 const FieldId* field_ids_;
844
845 // Points to the base of the method identifier list.
846 const MethodId* method_ids_;
847
848 // Points to the base of the prototype identifier list.
849 const ProtoId* proto_ids_;
850
851 // Points to the base of the class definition list.
852 const ClassDef* class_defs_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700853};
854
Ian Rogers0571d352011-11-03 19:51:38 -0700855// Iterate over a dex file's ProtoId's paramters
856class DexFileParameterIterator {
857 public:
858 DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id)
859 : dex_file_(dex_file), size_(0), pos_(0) {
860 type_list_ = dex_file_.GetProtoParameters(proto_id);
861 if (type_list_ != NULL) {
862 size_ = type_list_->Size();
863 }
864 }
865 bool HasNext() const { return pos_ < size_; }
866 void Next() { ++pos_; }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800867 uint16_t GetTypeIdx() {
Ian Rogers0571d352011-11-03 19:51:38 -0700868 return type_list_->GetTypeItem(pos_).type_idx_;
869 }
870 const char* GetDescriptor() {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800871 return dex_file_.StringByTypeIdx(GetTypeIdx());
Ian Rogers0571d352011-11-03 19:51:38 -0700872 }
873 private:
874 const DexFile& dex_file_;
875 const DexFile::TypeList* type_list_;
876 uint32_t size_;
877 uint32_t pos_;
878 DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
879};
880
881// Iterate and decode class_data_item
882class ClassDataItemIterator {
883 public:
884 ClassDataItemIterator(const DexFile& dex_file, const byte* raw_class_data_item)
885 : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) {
886 ReadClassDataHeader();
887 if (EndOfInstanceFieldsPos() > 0) {
888 ReadClassDataField();
889 } else if (EndOfVirtualMethodsPos() > 0) {
890 ReadClassDataMethod();
891 }
892 }
893 uint32_t NumStaticFields() const {
894 return header_.static_fields_size_;
895 }
896 uint32_t NumInstanceFields() const {
897 return header_.instance_fields_size_;
898 }
899 uint32_t NumDirectMethods() const {
900 return header_.direct_methods_size_;
901 }
902 uint32_t NumVirtualMethods() const {
903 return header_.virtual_methods_size_;
904 }
905 bool HasNextStaticField() const {
906 return pos_ < EndOfStaticFieldsPos();
907 }
908 bool HasNextInstanceField() const {
909 return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos();
910 }
911 bool HasNextDirectMethod() const {
912 return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos();
913 }
914 bool HasNextVirtualMethod() const {
915 return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos();
916 }
917 bool HasNext() const {
918 return pos_ < EndOfVirtualMethodsPos();
919 }
920 void Next() {
921 pos_++;
922 if (pos_ < EndOfStaticFieldsPos()) {
923 last_idx_ = GetMemberIndex();
924 ReadClassDataField();
925 } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) {
926 last_idx_ = 0; // transition to next array, reset last index
927 ReadClassDataField();
928 } else if (pos_ < EndOfInstanceFieldsPos()) {
929 last_idx_ = GetMemberIndex();
930 ReadClassDataField();
931 } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) {
932 last_idx_ = 0; // transition to next array, reset last index
933 ReadClassDataMethod();
934 } else if (pos_ < EndOfDirectMethodsPos()) {
935 last_idx_ = GetMemberIndex();
936 ReadClassDataMethod();
937 } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) {
938 last_idx_ = 0; // transition to next array, reset last index
939 ReadClassDataMethod();
940 } else if (pos_ < EndOfVirtualMethodsPos()) {
941 last_idx_ = GetMemberIndex();
942 ReadClassDataMethod();
943 } else {
944 DCHECK(!HasNext());
945 }
946 }
947 uint32_t GetMemberIndex() const {
948 if (pos_ < EndOfInstanceFieldsPos()) {
949 return last_idx_ + field_.field_idx_delta_;
950 } else {
951 CHECK_LT(pos_, EndOfVirtualMethodsPos());
952 return last_idx_ + method_.method_idx_delta_;
953 }
954 }
955 uint32_t GetMemberAccessFlags() const {
956 if (pos_ < EndOfInstanceFieldsPos()) {
957 return field_.access_flags_;
958 } else {
959 CHECK_LT(pos_, EndOfVirtualMethodsPos());
960 return method_.access_flags_;
961 }
962 }
963 const DexFile::CodeItem* GetMethodCodeItem() const {
964 return dex_file_.GetCodeItem(method_.code_off_);
965 }
966 uint32_t GetMethodCodeItemOffset() const {
967 return method_.code_off_;
968 }
jeffhao10037c82012-01-23 15:06:23 -0800969 const byte* EndDataPointer() const {
970 CHECK(!HasNext());
971 return ptr_pos_;
972 }
Ian Rogers0571d352011-11-03 19:51:38 -0700973 private:
974 // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the
975 // header for a class_data_item
976 struct ClassDataHeader {
977 uint32_t static_fields_size_; // the number of static fields
978 uint32_t instance_fields_size_; // the number of instance fields
979 uint32_t direct_methods_size_; // the number of direct methods
980 uint32_t virtual_methods_size_; // the number of virtual methods
981 } header_;
982
983 // Read and decode header from a class_data_item stream into header
984 void ReadClassDataHeader();
985
986 uint32_t EndOfStaticFieldsPos() const {
987 return header_.static_fields_size_;
988 }
989 uint32_t EndOfInstanceFieldsPos() const {
990 return EndOfStaticFieldsPos() + header_.instance_fields_size_;
991 }
992 uint32_t EndOfDirectMethodsPos() const {
993 return EndOfInstanceFieldsPos() + header_.direct_methods_size_;
994 }
995 uint32_t EndOfVirtualMethodsPos() const {
996 return EndOfDirectMethodsPos() + header_.virtual_methods_size_;
997 }
998
999 // A decoded version of the field of a class_data_item
1000 struct ClassDataField {
1001 uint32_t field_idx_delta_; // delta of index into the field_ids array for FieldId
1002 uint32_t access_flags_; // access flags for the field
1003 ClassDataField() : field_idx_delta_(0), access_flags_(0) {}
1004 private:
1005 DISALLOW_COPY_AND_ASSIGN(ClassDataField);
1006 } field_;
1007
1008 // Read and decode a field from a class_data_item stream into field
1009 void ReadClassDataField();
1010
1011 // A decoded version of the method of a class_data_item
1012 struct ClassDataMethod {
1013 uint32_t method_idx_delta_; // delta of index into the method_ids array for MethodId
1014 uint32_t access_flags_;
1015 uint32_t code_off_;
1016 ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {}
1017 private:
1018 DISALLOW_COPY_AND_ASSIGN(ClassDataMethod);
1019 } method_;
1020
1021 // Read and decode a method from a class_data_item stream into method
1022 void ReadClassDataMethod();
1023
1024 const DexFile& dex_file_;
1025 size_t pos_; // integral number of items passed
1026 const byte* ptr_pos_; // pointer into stream of class_data_item
1027 uint32_t last_idx_; // last read field or method index to apply delta to
1028 DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
1029};
1030
1031class ClassLinker;
1032class DexCache;
1033class Field;
1034
1035class EncodedStaticFieldValueIterator {
1036 public:
1037 EncodedStaticFieldValueIterator(const DexFile& dex_file, DexCache* dex_cache,
1038 ClassLinker* linker, const DexFile::ClassDef& class_def);
1039
1040 void ReadValueToField(Field* field) const;
1041
1042 bool HasNext() { return pos_ < array_size_; }
1043
1044 void Next();
1045 private:
1046 enum ValueType {
1047 kByte = 0x00,
1048 kShort = 0x02,
1049 kChar = 0x03,
1050 kInt = 0x04,
1051 kLong = 0x06,
1052 kFloat = 0x10,
1053 kDouble = 0x11,
1054 kString = 0x17,
1055 kType = 0x18,
1056 kField = 0x19,
1057 kMethod = 0x1a,
1058 kEnum = 0x1b,
1059 kArray = 0x1c,
1060 kAnnotation = 0x1d,
1061 kNull = 0x1e,
1062 kBoolean = 0x1f
1063 };
1064
1065 static const byte kEncodedValueTypeMask = 0x1f; // 0b11111
1066 static const byte kEncodedValueArgShift = 5;
1067
1068 const DexFile& dex_file_;
1069 DexCache* dex_cache_; // dex cache to resolve literal objects
1070 ClassLinker* linker_; // linker to resolve literal objects
1071 size_t array_size_; // size of array
1072 size_t pos_; // current position
1073 const byte* ptr_; // pointer into encoded data array
1074 byte type_; // type of current encoded value
1075 jvalue jval_; // value of current encoded value
1076 DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
1077};
1078
1079class CatchHandlerIterator {
1080 public:
1081 CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address);
1082 explicit CatchHandlerIterator(const byte* handler_data) {
1083 Init(handler_data);
1084 }
1085
1086 uint16_t GetHandlerTypeIndex() const {
1087 return handler_.type_idx_;
1088 }
1089 uint32_t GetHandlerAddress() const {
1090 return handler_.address_;
1091 }
1092 void Next();
1093 bool HasNext() const {
1094 return remaining_count_ != -1 || catch_all_;
1095 }
1096 // End of this set of catch blocks, convenience method to locate next set of catch blocks
1097 const byte* EndDataPointer() const {
1098 CHECK(!HasNext());
1099 return current_data_;
1100 }
1101 private:
1102 void Init(const byte* handler_data);
1103
1104 struct CatchHandlerItem {
1105 uint16_t type_idx_; // type index of the caught exception type
1106 uint32_t address_; // handler address
1107 } handler_;
1108 const byte *current_data_; // the current handler in dex file.
1109 int32_t remaining_count_; // number of handlers not read.
1110 bool catch_all_; // is there a handler that will catch all exceptions in case
1111 // that all typed handler does not match.
1112};
1113
Carl Shapiro1fb86202011-06-27 17:43:13 -07001114} // namespace art
1115
1116#endif // ART_SRC_DEX_FILE_H_