blob: 4448981b8a5e9667304ba7091f0e374d22a131b4 [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"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070012#include "leb128.h"
13#include "logging.h"
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070014#include "stringpiece.h"
15#include "strutil.h"
Shih-wei Liao2fb97532011-08-11 16:17:23 -070016#include "utils.h"
Carl Shapiro1fb86202011-06-27 17:43:13 -070017
18namespace art {
19
Carl Shapiro5fafe2b2011-07-09 15:34:41 -070020union JValue;
Shih-wei Liao195487c2011-08-20 13:29:04 -070021class String;
22class Method;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070023
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070024// TODO: move all of the macro functionality into the DexCache class.
Brian Carlstromf615a612011-07-23 12:50:34 -070025class DexFile {
Carl Shapiro1fb86202011-06-27 17:43:13 -070026 public:
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070027 static const byte kDexMagic[];
28 static const byte kDexMagicVersion[];
29 static const size_t kSha1DigestSize = 20;
Carl Shapiro80d4dde2011-06-28 16:24:07 -070030
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070031 static const byte kEncodedValueTypeMask = 0x1f; // 0b11111
32 static const byte kEncodedValueArgShift = 5;
33
34 // The value of an invalid index.
35 static const uint32_t kDexNoIndex = 0xFFFFFFFF;
36
37 enum ValueType {
38 kByte = 0x00,
39 kShort = 0x02,
40 kChar = 0x03,
41 kInt = 0x04,
42 kLong = 0x06,
43 kFloat = 0x10,
44 kDouble = 0x11,
45 kString = 0x17,
46 kType = 0x18,
47 kField = 0x19,
48 kMethod = 0x1a,
49 kEnum = 0x1b,
50 kArray = 0x1c,
51 kAnnotation = 0x1d,
52 kNull = 0x1e,
53 kBoolean = 0x1f
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070054 };
Carl Shapiro1fb86202011-06-27 17:43:13 -070055
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070056 // Raw header_item.
57 struct Header {
58 uint8_t magic_[8];
59 uint32_t checksum_;
60 uint8_t signature_[kSha1DigestSize];
61 uint32_t file_size_; // length of entire file
62 uint32_t header_size_; // offset to start of next section
63 uint32_t endian_tag_;
64 uint32_t link_size_;
65 uint32_t link_off_;
66 uint32_t map_off_;
67 uint32_t string_ids_size_;
68 uint32_t string_ids_off_;
69 uint32_t type_ids_size_;
70 uint32_t type_ids_off_;
71 uint32_t proto_ids_size_;
72 uint32_t proto_ids_off_;
73 uint32_t field_ids_size_;
74 uint32_t field_ids_off_;
75 uint32_t method_ids_size_;
76 uint32_t method_ids_off_;
77 uint32_t class_defs_size_;
78 uint32_t class_defs_off_;
79 uint32_t data_size_;
80 uint32_t data_off_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -070081 private:
82 DISALLOW_COPY_AND_ASSIGN(Header);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070083 };
Carl Shapiro1fb86202011-06-27 17:43:13 -070084
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070085 // Raw string_id_item.
86 struct StringId {
87 uint32_t string_data_off_; // offset in bytes from the base address
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -070088 private:
89 DISALLOW_COPY_AND_ASSIGN(StringId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070090 };
91
92 // Raw type_id_item.
93 struct TypeId {
94 uint32_t descriptor_idx_; // index into string_ids
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -070095 private:
96 DISALLOW_COPY_AND_ASSIGN(TypeId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070097 };
98
99 // Raw field_id_item.
100 struct FieldId {
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700101 uint16_t class_idx_; // index into type_ids_ list for defining class
102 uint16_t type_idx_; // index into type_ids_ for field type
103 uint32_t name_idx_; // index into string_ids_ for field name
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700104 private:
105 DISALLOW_COPY_AND_ASSIGN(FieldId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700106 };
107
108 // Raw method_id_item.
109 struct MethodId {
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700110 uint16_t class_idx_; // index into type_ids_ list for defining class
111 uint16_t proto_idx_; // index into proto_ids_ for method prototype
112 uint32_t name_idx_; // index into string_ids_ for method name
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700113 private:
114 DISALLOW_COPY_AND_ASSIGN(MethodId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700115 };
116
117 // Raw proto_id_item.
118 struct ProtoId {
119 uint32_t shorty_idx_; // index into string_ids for shorty descriptor
120 uint32_t return_type_idx_; // index into type_ids list for return type
121 uint32_t parameters_off_; // file offset to type_list for parameter types
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700122 private:
123 DISALLOW_COPY_AND_ASSIGN(ProtoId);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700124 };
125
126 // Raw class_def_item.
127 struct ClassDef {
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700128 uint32_t class_idx_; // index into type_ids_ for this class
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700129 uint32_t access_flags_;
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700130 uint32_t superclass_idx_; // index into type_ids_ for superclass
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700131 uint32_t interfaces_off_; // file offset to TypeList
Brian Carlstrom4a96b602011-07-26 16:40:23 -0700132 uint32_t source_file_idx_; // index into string_ids_ for source file name
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700133 uint32_t annotations_off_; // file offset to annotations_directory_item
134 uint32_t class_data_off_; // file offset to class_data_item
135 uint32_t static_values_off_; // file offset to EncodedArray
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700136 private:
137 DISALLOW_COPY_AND_ASSIGN(ClassDef);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700138 };
139
140 // Raw type_item.
141 struct TypeItem {
142 uint16_t type_idx_; // index into type_ids section
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700143 private:
144 DISALLOW_COPY_AND_ASSIGN(TypeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700145 };
146
147 // Raw type_list.
148 class TypeList {
149 public:
150 uint32_t Size() const {
151 return size_;
152 }
153
154 const TypeItem& GetTypeItem(uint32_t idx) const {
155 CHECK_LT(idx, this->size_);
156 return this->list_[idx];
157 }
158
159 private:
160 uint32_t size_; // size of the list, in entries
161 TypeItem list_[1]; // elements of the list
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700162 DISALLOW_COPY_AND_ASSIGN(TypeList);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700163 };
164
165 class ParameterIterator { // TODO: stream
166 public:
Brian Carlstromf615a612011-07-23 12:50:34 -0700167 ParameterIterator(const DexFile& dex_file, const ProtoId& proto_id)
168 : dex_file_(dex_file), size_(0), pos_(0) {
169 type_list_ = dex_file_.GetProtoParameters(proto_id);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700170 if (type_list_ != NULL) {
171 size_ = type_list_->Size();
172 }
173 }
174 bool HasNext() const { return pos_ != size_; }
175 void Next() { ++pos_; }
176 const char* GetDescriptor() {
177 uint32_t type_idx = type_list_->GetTypeItem(pos_).type_idx_;
Brian Carlstromf615a612011-07-23 12:50:34 -0700178 return dex_file_.dexStringByTypeIdx(type_idx);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700179 }
180 private:
Brian Carlstromf615a612011-07-23 12:50:34 -0700181 const DexFile& dex_file_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700182 const TypeList* type_list_;
183 uint32_t size_;
184 uint32_t pos_;
185 DISALLOW_IMPLICIT_CONSTRUCTORS(ParameterIterator);
186 };
187
188 ParameterIterator* GetParameterIterator(const ProtoId& proto_id) const {
189 return new ParameterIterator(*this, proto_id);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700190 }
191
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700192 const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const {
193 return dexStringByTypeIdx(proto_id.return_type_idx_);
Carl Shapiro1fb86202011-06-27 17:43:13 -0700194 }
195
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700196 // Raw code_item.
197 struct CodeItem {
198 uint16_t registers_size_;
199 uint16_t ins_size_;
200 uint16_t outs_size_;
201 uint16_t tries_size_;
202 uint32_t debug_info_off_; // file offset to debug info stream
203 uint32_t insns_size_; // size of the insns array, in 2 byte code units
204 uint16_t insns_[1];
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700205 private:
206 DISALLOW_COPY_AND_ASSIGN(CodeItem);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700207 };
208
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700209 struct CatchHandlerItem {
210 uint32_t type_idx_; // type index of the caught exception type
211 uint32_t address_; // handler address
212 };
213
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700214 // Raw try_item.
215 struct TryItem {
216 uint32_t start_addr_;
217 uint16_t insn_count_;
218 uint16_t handler_off_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700219 private:
220 DISALLOW_COPY_AND_ASSIGN(TryItem);
Carl Shapiro2eaa9682011-08-04 19:26:11 -0700221 };
222
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700223 class CatchHandlerIterator {
224 public:
225 CatchHandlerIterator() {
226 remaining_count_ = -1;
227 catch_all_ = false;
228 }
229
230 CatchHandlerIterator(const byte* handler_data) {
231 current_data_ = handler_data;
jeffhaoba5ebb92011-08-25 17:24:37 -0700232 remaining_count_ = DecodeSignedLeb128(&current_data_);
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700233
234 // If remaining_count_ is non-positive, then it is the negative of
235 // the number of catch types, and the catches are followed by a
236 // catch-all handler.
237 if (remaining_count_ <= 0) {
238 catch_all_ = true;
239 remaining_count_ = -remaining_count_;
240 } else {
241 catch_all_ = false;
242 }
243 Next();
244 }
245
Shih-wei Liaofe909f22011-08-12 19:20:26 -0700246 const CatchHandlerItem& Get() const {
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700247 return handler_;
248 }
249
jeffhaoba5ebb92011-08-25 17:24:37 -0700250 const byte* GetData() const {
251 return current_data_;
252 }
253
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700254 void Next() {
255 if (remaining_count_ > 0) {
256 handler_.type_idx_ = DecodeUnsignedLeb128(&current_data_);
257 handler_.address_ = DecodeUnsignedLeb128(&current_data_);
258 remaining_count_--;
259 return;
260 }
261
262 if (catch_all_) {
263 handler_.type_idx_ = kDexNoIndex;
264 handler_.address_ = DecodeUnsignedLeb128(&current_data_);
265 catch_all_ = false;
266 return;
267 }
268
269 // no more handler
270 remaining_count_ = -1;
271 }
272
Shih-wei Liao1a18c8c2011-08-14 17:47:36 -0700273 bool HasNext() const {
Shih-wei Liao4e5c0b92011-08-11 22:50:08 -0700274 return remaining_count_ == -1 && catch_all_ == false;
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700275 }
276
277 private:
278 CatchHandlerItem handler_;
279 const byte *current_data_; // the current handlder in dex file.
280 int32_t remaining_count_; // number of handler not read.
281 bool catch_all_; // is there a handler that will catch all exceptions in case
282 // that all typed handler does not match.
283 };
284
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700285 // Partially decoded form of class_data_item.
286 struct ClassDataHeader {
287 uint32_t static_fields_size_; // the number of static fields
288 uint32_t instance_fields_size_; // the number of instance fields
289 uint32_t direct_methods_size_; // the number of direct methods
290 uint32_t virtual_methods_size_; // the number of virtual methods
291 };
292
293 // Decoded form of encoded_field.
294 struct Field {
295 uint32_t field_idx_; // index into the field_ids list for the identity of this field
296 uint32_t access_flags_; // access flags for the field
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700297 Field() {};
298 private:
299 DISALLOW_COPY_AND_ASSIGN(Field);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700300 };
301
302 // Decoded form of encoded_method.
303 struct Method {
304 uint32_t method_idx_;
305 uint32_t access_flags_;
306 uint32_t code_off_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700307 Method() {};
308 private:
309 DISALLOW_COPY_AND_ASSIGN(Method);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700310 };
311
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700312 typedef std::pair<const DexFile*, const DexFile::ClassDef*> ClassPathEntry;
313 typedef std::vector<const DexFile*> ClassPath;
314
315 // Search a collection of DexFiles for a descriptor
316 static ClassPathEntry FindInClassPath(const StringPiece& descriptor,
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700317 const ClassPath& class_path);
Brian Carlstrom74eb46a2011-08-02 20:10:14 -0700318
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700319 // Opens .dex file, guessing the format based on file extension
Brian Carlstrom16192862011-09-12 17:50:06 -0700320 static const DexFile* Open(const std::string& filename,
321 const std::string& strip_location_prefix);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700322
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700323 // Opens a .dex file from the file system.
Brian Carlstrom16192862011-09-12 17:50:06 -0700324 static const DexFile* OpenFile(const std::string& filename,
325 const std::string& original_location,
326 const std::string& strip_location_prefix);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700327
328 // Opens a .jar, .zip, or .apk file from the file system.
Brian Carlstrom16192862011-09-12 17:50:06 -0700329 static const DexFile* OpenZip(const std::string& filename,
330 const std::string& strip_location_prefix);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700331
Brian Carlstroma663ea52011-08-19 23:33:41 -0700332 // Opens a .dex file from a new allocated pointer. location is used
333 // to identify the source, for example "/system/framework/core.jar"
334 // or "contrived-test-42". When initializing a ClassLinker from an
335 // image, the location is used to match DexCaches the image to their
336 // corresponding DexFiles.N
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700337 static const DexFile* OpenPtr(byte* ptr, size_t length, const std::string& location);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700338
339 // Closes a .dex file.
Brian Carlstromf615a612011-07-23 12:50:34 -0700340 virtual ~DexFile();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700341
Brian Carlstroma663ea52011-08-19 23:33:41 -0700342 const std::string& GetLocation() const {
343 return location_;
344 }
345
346 const Header& GetHeader() const {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700347 CHECK(header_ != NULL);
348 return *header_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700349 }
350
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700351 // Looks up a class definition by its class descriptor.
352 const ClassDef* FindClassDef(const StringPiece& descriptor) const;
353
354 // Returns the number of string identifiers in the .dex file.
355 size_t NumStringIds() const {
356 CHECK(header_ != NULL);
357 return header_->string_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700358 }
359
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700360 // Returns the number of type identifiers in the .dex file.
361 size_t NumTypeIds() const {
362 CHECK(header_ != NULL);
363 return header_->type_ids_size_;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700364 }
365
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700366 // Returns the number of prototype identifiers in the .dex file.
367 size_t NumProtoIds() const {
368 CHECK(header_ != NULL);
369 return header_->proto_ids_size_;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700370 }
371
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700372 // Returns the number of field identifiers in the .dex file.
373 size_t NumFieldIds() const {
374 CHECK(header_ != NULL);
375 return header_->field_ids_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700376 }
377
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700378 // Returns the number of method identifiers in the .dex file.
379 size_t NumMethodIds() const {
380 CHECK(header_ != NULL);
381 return header_->method_ids_size_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700382 }
383
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700384 // Returns the number of class definitions in the .dex file.
385 size_t NumClassDefs() const {
386 CHECK(header_ != NULL);
387 return header_->class_defs_size_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700388 }
389
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700390 // Returns a pointer to the memory mapped class data.
391 // TODO: return a stream
392 const byte* GetClassData(const ClassDef& class_def) const {
393 if (class_def.class_data_off_ == 0) {
394 return NULL;
395 } else {
396 return base_ + class_def.class_data_off_;
397 }
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700398 }
399
Brian Carlstromf615a612011-07-23 12:50:34 -0700400 // Decodes the header section from the class data bytes.
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700401 ClassDataHeader ReadClassDataHeader(const byte** class_data) const {
402 CHECK(class_data != NULL);
403 ClassDataHeader header;
404 memset(&header, 0, sizeof(ClassDataHeader));
405 if (*class_data != NULL) {
406 header.static_fields_size_ = DecodeUnsignedLeb128(class_data);
407 header.instance_fields_size_ = DecodeUnsignedLeb128(class_data);
408 header.direct_methods_size_ = DecodeUnsignedLeb128(class_data);
409 header.virtual_methods_size_ = DecodeUnsignedLeb128(class_data);
410 }
411 return header;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700412 }
413
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700414 // Returns the class descriptor string of a class definition.
415 const char* GetClassDescriptor(const ClassDef& class_def) const {
416 return dexStringByTypeIdx(class_def.class_idx_);
417 }
418
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700419 // Returns the type descriptor string of a type id.
420 const char* GetTypeDescriptor(const TypeId& type_id) const {
421 return dexStringById(type_id.descriptor_idx_);
422 }
423
Brian Carlstromb9edb842011-08-28 16:31:06 -0700424 // Returns the class descriptor string of a field id.
425 const char* GetFieldClassDescriptor(const FieldId& field_id) const {
426 const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_);
427 return GetTypeDescriptor(type_id);
428 }
429
430 // Returns the name of a field id.
431 const char* GetFieldName(const FieldId& field_id) const {
432 return dexStringById(field_id.name_idx_);
433 }
434
Brian Carlstrom7540ff42011-09-04 16:38:46 -0700435 // Returns the class descriptor string of a method id.
436 const char* GetMethodClassDescriptor(const MethodId& method_id) const {
437 const DexFile::TypeId& type_id = GetTypeId(method_id.class_idx_);
438 return GetTypeDescriptor(type_id);
439 }
440
441 // Returns the name of a method id.
442 const char* GetMethodName(const MethodId& method_id) const {
443 return dexStringById(method_id.name_idx_);
444 }
445
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700446 // Returns the StringId at the specified index.
447 const StringId& GetStringId(uint32_t idx) const {
448 CHECK_LT(idx, NumStringIds());
449 return string_ids_[idx];
450 }
451
452 // Returns the TypeId at the specified index.
453 const TypeId& GetTypeId(uint32_t idx) const {
454 CHECK_LT(idx, NumTypeIds());
455 return type_ids_[idx];
456 }
457
458 // Returns the FieldId at the specified index.
459 const FieldId& GetFieldId(uint32_t idx) const {
460 CHECK_LT(idx, NumFieldIds());
461 return field_ids_[idx];
462 }
463
464 // Returns the MethodId at the specified index.
465 const MethodId& GetMethodId(uint32_t idx) const {
466 CHECK_LT(idx, NumMethodIds());
467 return method_ids_[idx];
468 }
469
470 // Returns the ProtoId at the specified index.
471 const ProtoId& GetProtoId(uint32_t idx) const {
472 CHECK_LT(idx, NumProtoIds());
473 return proto_ids_[idx];
474 }
475
476 // Returns the ClassDef at the specified index.
477 const ClassDef& GetClassDef(uint32_t idx) const {
478 CHECK_LT(idx, NumClassDefs());
479 return class_defs_[idx];
480 }
481
482 const TypeList* GetInterfacesList(const ClassDef& class_def) const {
483 if (class_def.interfaces_off_ == 0) {
484 return NULL;
485 } else {
486 const byte* addr = base_ + class_def.interfaces_off_;
487 return reinterpret_cast<const TypeList*>(addr);
488 }
489 }
490
491 const CodeItem* GetCodeItem(const Method& method) const {
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700492 return GetCodeItem(method.code_off_);
493 }
494
495 const CodeItem* GetCodeItem(const uint32_t code_off_) const {
496 if (code_off_ == 0) {
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700497 return NULL; // native or abstract method
498 } else {
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700499 const byte* addr = base_ + code_off_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700500 return reinterpret_cast<const CodeItem*>(addr);
501 }
502 }
503
504 // Returns the short form method descriptor for the given prototype.
505 const char* GetShorty(uint32_t proto_idx) const {
506 const ProtoId& proto_id = GetProtoId(proto_idx);
507 return dexStringById(proto_id.shorty_idx_);
508 }
509
510 const TypeList* GetProtoParameters(const ProtoId& proto_id) const {
511 if (proto_id.parameters_off_ == 0) {
512 return NULL;
513 } else {
514 const byte* addr = base_ + proto_id.parameters_off_;
515 return reinterpret_cast<const TypeList*>(addr);
516 }
517 }
518
Elliott Hughes0c424cb2011-08-26 10:16:25 -0700519 std::string CreateMethodDescriptor(uint32_t proto_idx, int32_t* unicode_length) const;
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700520
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700521 const byte* GetEncodedArray(const ClassDef& class_def) const {
522 if (class_def.static_values_off_ == 0) {
523 return 0;
524 } else {
525 return base_ + class_def.static_values_off_;
526 }
527 }
528
529 int32_t GetStringLength(const StringId& string_id) const {
530 const byte* ptr = base_ + string_id.string_data_off_;
531 return DecodeUnsignedLeb128(&ptr);
532 }
533
534 ValueType ReadEncodedValue(const byte** encoded_value, JValue* value) const;
535
536 // From libdex...
537
538 // Returns a pointer to the UTF-8 string data referred to by the
539 // given string_id.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700540 const char* GetStringData(const StringId& string_id, int32_t* length) const {
541 CHECK(length != NULL);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700542 const byte* ptr = base_ + string_id.string_data_off_;
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700543 *length = DecodeUnsignedLeb128(&ptr);
Brian Carlstrom0b138b22011-07-27 15:19:17 -0700544 return reinterpret_cast<const char*>(ptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700545 }
546
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700547 const char* GetStringData(const StringId& string_id) const {
548 int32_t length;
549 return GetStringData(string_id, &length);
550 }
551
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700552 // return the UTF-8 encoded string with the specified string_id index
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700553 const char* dexStringById(uint32_t idx, int32_t* unicode_length) const {
Shih-wei Liao195487c2011-08-20 13:29:04 -0700554 if (idx == kDexNoIndex) {
555 *unicode_length = 0;
556 return NULL;
557 }
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700558 const StringId& string_id = GetStringId(idx);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700559 return GetStringData(string_id, unicode_length);
560 }
561
562 const char* dexStringById(uint32_t idx) const {
563 int32_t unicode_length;
564 return dexStringById(idx, &unicode_length);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700565 }
566
Shih-wei Liao55df06b2011-08-26 14:39:27 -0700567 String* dexArtStringById(int32_t idx) const;
Shih-wei Liao195487c2011-08-20 13:29:04 -0700568
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700569 // Get the descriptor string associated with a given type index.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700570 const char* dexStringByTypeIdx(uint32_t idx, int32_t* unicode_length) const {
571 const TypeId& type_id = GetTypeId(idx);
572 return dexStringById(type_id.descriptor_idx_, unicode_length);
573 }
574
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700575 const char* dexStringByTypeIdx(uint32_t idx) const {
576 const TypeId& type_id = GetTypeId(idx);
577 return dexStringById(type_id.descriptor_idx_);
578 }
579
Shih-wei Liao55df06b2011-08-26 14:39:27 -0700580 String* dexArtStringByTypeIdx(int32_t idx) const {
Shih-wei Liao195487c2011-08-20 13:29:04 -0700581 const TypeId& type_id = GetTypeId(idx);
582 return dexArtStringById(type_id.descriptor_idx_);
583 }
584
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700585 // TODO: encoded_field is actually a stream of bytes
586 void dexReadClassDataField(const byte** encoded_field,
Brian Carlstromf615a612011-07-23 12:50:34 -0700587 DexFile::Field* field,
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700588 uint32_t* last_idx) const {
589 uint32_t idx = *last_idx + DecodeUnsignedLeb128(encoded_field);
590 field->access_flags_ = DecodeUnsignedLeb128(encoded_field);
591 field->field_idx_ = idx;
592 *last_idx = idx;
593 }
594
595 // TODO: encoded_method is actually a stream of bytes
596 void dexReadClassDataMethod(const byte** encoded_method,
Brian Carlstromf615a612011-07-23 12:50:34 -0700597 DexFile::Method* method,
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700598 uint32_t* last_idx) const {
599 uint32_t idx = *last_idx + DecodeUnsignedLeb128(encoded_method);
600 method->access_flags_ = DecodeUnsignedLeb128(encoded_method);
601 method->code_off_ = DecodeUnsignedLeb128(encoded_method);
602 method->method_idx_ = idx;
603 *last_idx = idx;
604 }
605
jeffhaoba5ebb92011-08-25 17:24:37 -0700606 static const TryItem* dexGetTryItems(const CodeItem& code_item, uint32_t offset) {
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700607 const uint16_t* insns_end_ = &code_item.insns_[code_item.insns_size_];
608 return reinterpret_cast<const TryItem*>
609 (RoundUp(reinterpret_cast<uint32_t>(insns_end_), 4)) + offset;
610 }
611
612 // Get the base of the encoded data for the given DexCode.
jeffhaoba5ebb92011-08-25 17:24:37 -0700613 static const byte* dexGetCatchHandlerData(const CodeItem& code_item, uint32_t offset) {
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700614 const byte* handler_data = reinterpret_cast<const byte*>
615 (dexGetTryItems(code_item, code_item.tries_size_));
616 return handler_data + offset;
617 }
618
619 // Find the handler associated with a given address, if any.
620 // Initializes the given iterator and returns true if a match is
621 // found. Returns end if there is no applicable handler.
jeffhaoba5ebb92011-08-25 17:24:37 -0700622 static CatchHandlerIterator dexFindCatchHandler(const CodeItem& code_item, uint32_t address) {
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700623 CatchHandlerItem handler;
624 handler.address_ = -1;
625 int32_t offset = -1;
626
627 // Short-circuit the overwhelmingly common cases.
628 switch (code_item.tries_size_) {
629 case 0:
630 break;
631 case 1: {
632 const TryItem* tries = dexGetTryItems(code_item, 0);
633 uint32_t start = tries->start_addr_;
634 if (address < start)
635 break;
636
637 uint32_t end = start + tries->insn_count_;
638 if (address >= end)
639 break;
640
641 offset = tries->handler_off_;
642 break;
643 }
644 default:
645 offset = dexFindCatchHandlerOffset0(code_item, code_item.tries_size_, address);
646 }
647
648 if (offset >= 0) {
649 const byte* handler_data = dexGetCatchHandlerData(code_item, offset);
650 return CatchHandlerIterator(handler_data);
651 }
652 return CatchHandlerIterator();
653 }
654
jeffhaoba5ebb92011-08-25 17:24:37 -0700655 static int32_t dexFindCatchHandlerOffset0(const CodeItem &code_item,
656 int32_t tries_size,
657 uint32_t address) {
Shih-wei Liao2fb97532011-08-11 16:17:23 -0700658 // Note: Signed type is important for max and min.
659 int32_t min = 0;
660 int32_t max = tries_size - 1;
661
662 while (max >= min) {
663 int32_t guess = (min + max) >> 1;
664 const TryItem* pTry = dexGetTryItems(code_item, guess);
665 uint32_t start = pTry->start_addr_;
666
667 if (address < start) {
668 max = guess - 1;
669 continue;
670 }
671
672 uint32_t end = start + pTry->insn_count_;
673 if (address >= end) {
674 min = guess + 1;
675 continue;
676 }
677
678 // We have a winner!
679 return (int32_t) pTry->handler_off_;
680 }
681
682 // No match.
683 return -1;
684 }
685
Shih-wei Liao195487c2011-08-20 13:29:04 -0700686 // Get the pointer to the start of the debugging data
687 const byte* dexGetDebugInfoStream(const CodeItem* code_item) const {
688 if (code_item->debug_info_off_ == 0) {
689 return NULL;
690 } else {
691 return base_ + code_item->debug_info_off_;
692 }
693 }
694
695 // Callback for "new position table entry".
696 // Returning true causes the decoder to stop early.
697 typedef bool (*DexDebugNewPositionCb)(void *cnxt, uint32_t address, uint32_t line_num);
698
699 // Callback for "new locals table entry". "signature" is an empty string
700 // if no signature is available for an entry.
701 typedef void (*DexDebugNewLocalCb)(void *cnxt, uint16_t reg,
702 uint32_t startAddress,
703 uint32_t endAddress,
704 const String* name,
705 const String* descriptor,
706 const String* signature);
707
708 static bool LineNumForPcCb(void *cnxt, uint32_t address, uint32_t line_num) {
709 LineNumFromPcContext *context = (LineNumFromPcContext *)cnxt;
710
711 // We know that this callback will be called in
712 // ascending address order, so keep going until we find
713 // a match or we've just gone past it.
714 if (address > context->address_) {
715 // The line number from the previous positions callback
716 // wil be the final result.
717 return true;
718 } else {
719 context->line_num_ = line_num;
720 return address == context->address_;
721 }
722 }
723
724
725 // Debug info opcodes and constants
726 enum {
727 DBG_END_SEQUENCE = 0x00,
728 DBG_ADVANCE_PC = 0x01,
729 DBG_ADVANCE_LINE = 0x02,
730 DBG_START_LOCAL = 0x03,
731 DBG_START_LOCAL_EXTENDED = 0x04,
732 DBG_END_LOCAL = 0x05,
733 DBG_RESTART_LOCAL = 0x06,
734 DBG_SET_PROLOGUE_END = 0x07,
735 DBG_SET_EPILOGUE_BEGIN = 0x08,
736 DBG_SET_FILE = 0x09,
737 DBG_FIRST_SPECIAL = 0x0a,
738 DBG_LINE_BASE = -4,
739 DBG_LINE_RANGE = 15,
740 };
741
742 struct LocalInfo {
743 LocalInfo() : name_(NULL), descriptor_(NULL), signature_(NULL), start_address_(0), is_live_(false) {}
744
745 // E.g., list
746 const String* name_;
747
748 // E.g., Ljava/util/LinkedList;
749 const String* descriptor_;
750
751 // E.g., java.util.LinkedList<java.lang.Integer>
752 const String* signature_;
753
754 // PC location where the local is first defined.
755 uint16_t start_address_;
756
757 // Is the local defined and live.
758 bool is_live_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700759
760 private:
761 DISALLOW_COPY_AND_ASSIGN(LocalInfo);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700762 };
763
764 struct LineNumFromPcContext {
765 LineNumFromPcContext(uint32_t address, uint32_t line_num) :
766 address_(address), line_num_(line_num) {}
767 uint32_t address_;
768 uint32_t line_num_;
Brian Carlstromd2fbb2b2011-08-23 11:57:08 -0700769 private:
770 DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext);
Shih-wei Liao195487c2011-08-20 13:29:04 -0700771 };
772
773 void InvokeLocalCbIfLive(void *cnxt, int reg, uint32_t end_address,
774 LocalInfo *local_in_reg, DexDebugNewLocalCb local_cb) const {
775 if (local_cb != NULL && local_in_reg[reg].is_live_) {
776 local_cb(cnxt, reg, local_in_reg[reg].start_address_, end_address,
777 local_in_reg[reg].name_, local_in_reg[reg].descriptor_,
778 local_in_reg[reg].signature_);
779 }
780 }
781
782 // Determine the source file line number based on the program counter.
783 // "pc" is an offset, in 16-bit units, from the start of the method's code.
784 //
785 // Returns -1 if no match was found (possibly because the source files were
786 // compiled without "-g", so no line number information is present).
787 // Returns -2 for native methods (as expected in exception traces).
788 //
789 // This is used by runtime; therefore use art::Method not art::DexFile::Method.
790 int32_t GetLineNumFromPC(const art::Method* method, uint32_t rel_pc) const;
791
792 void dexDecodeDebugInfo0(const CodeItem* code_item, const art::Method* method,
793 DexDebugNewPositionCb posCb, DexDebugNewLocalCb local_cb,
794 void* cnxt, const byte* stream, LocalInfo* local_in_reg) const;
795
796 void dexDecodeDebugInfo(const CodeItem* code_item, const art::Method *method,
797 DexDebugNewPositionCb posCb, DexDebugNewLocalCb local_cb,
798 void* cnxt) const {
799 const byte* stream = dexGetDebugInfoStream(code_item);
800 LocalInfo local_in_reg[code_item->registers_size_];
801
802 if (stream != NULL) {
803 dexDecodeDebugInfo0(code_item, method, posCb, local_cb, cnxt, stream, local_in_reg);
804 }
805 for (int reg = 0; reg < code_item->registers_size_; reg++) {
806 InvokeLocalCbIfLive(cnxt, reg, code_item->insns_size_, local_in_reg, local_cb);
807 }
808 }
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700809
810 // TODO: const reference
811 uint32_t dexGetIndexForClassDef(const ClassDef* class_def) const {
812 CHECK_GE(class_def, class_defs_);
813 CHECK_LT(class_def, class_defs_ + header_->class_defs_size_);
814 return class_def - class_defs_;
815 }
816
817 const char* dexGetSourceFile(const ClassDef& class_def) const {
818 if (class_def.source_file_idx_ == 0xffffffff) {
819 return NULL;
820 } else {
821 return dexStringById(class_def.source_file_idx_);
822 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700823 }
824
Carl Shapiro1fb86202011-06-27 17:43:13 -0700825 private:
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700826 // Helper class to deallocate underlying storage.
827 class Closer {
828 public:
829 virtual ~Closer();
830 };
831
832 // Helper class to deallocate mmap-backed .dex files.
833 class MmapCloser : public Closer {
834 public:
835 MmapCloser(void* addr, size_t length);
836 virtual ~MmapCloser();
837 private:
838 void* addr_;
839 size_t length_;
840 };
841
842 // Helper class for deallocating new/delete-backed .dex files.
843 class PtrCloser : public Closer {
844 public:
845 PtrCloser(byte* addr);
846 virtual ~PtrCloser();
847 private:
848 byte* addr_;
849 };
850
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700851 // Opens a .dex file at the given address.
852 static const DexFile* Open(const byte* dex_file,
853 size_t length,
854 const std::string& location,
855 Closer* closer);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700856
Brian Carlstroma663ea52011-08-19 23:33:41 -0700857 DexFile(const byte* addr, size_t length, const std::string& location, Closer* closer)
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700858 : base_(addr),
859 length_(length),
Brian Carlstroma663ea52011-08-19 23:33:41 -0700860 location_(location),
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700861 closer_(closer),
862 header_(0),
863 string_ids_(0),
864 type_ids_(0),
865 field_ids_(0),
866 method_ids_(0),
867 proto_ids_(0),
Brian Carlstroma663ea52011-08-19 23:33:41 -0700868 class_defs_(0) {
869 CHECK(addr != NULL);
870 CHECK_GT(length, 0U);
871 CHECK(closer != NULL);
872 }
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700873
874 // Top-level initializer that calls other Init methods.
875 bool Init();
876
877 // Caches pointers into to the various file sections.
878 void InitMembers();
879
880 // Builds the index of descriptors to class definitions.
881 void InitIndex();
882
883 // Returns true if the byte string equals the magic value.
884 bool CheckMagic(const byte* magic);
885
886 // Returns true if the header magic is of the expected value.
887 bool IsMagicValid();
888
889 // The index of descriptors to class definitions.
Brian Carlstromf615a612011-07-23 12:50:34 -0700890 typedef std::map<const StringPiece, const DexFile::ClassDef*> Index;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700891 Index index_;
892
893 // The base address of the memory mapping.
894 const byte* base_;
895
896 // The size of the underlying memory allocation in bytes.
897 size_t length_;
898
Brian Carlstroma663ea52011-08-19 23:33:41 -0700899 // Typically the dex file name when availble, alternatively some identifying string.
900 //
901 // The ClassLinker will use this to match DexFiles the boot class
902 // path to DexCache::GetLocation when loading from an image.
903 const std::string location_;
904
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700905 // Helper object to free the underlying allocation.
Elliott Hughes90a33692011-08-30 13:27:07 -0700906 UniquePtr<Closer> closer_;
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700907
908 // Points to the header section.
909 const Header* header_;
910
911 // Points to the base of the string identifier list.
912 const StringId* string_ids_;
913
914 // Points to the base of the type identifier list.
915 const TypeId* type_ids_;
916
917 // Points to the base of the field identifier list.
918 const FieldId* field_ids_;
919
920 // Points to the base of the method identifier list.
921 const MethodId* method_ids_;
922
923 // Points to the base of the prototype identifier list.
924 const ProtoId* proto_ids_;
925
926 // Points to the base of the class definition list.
927 const ClassDef* class_defs_;
Carl Shapiro1fb86202011-06-27 17:43:13 -0700928};
929
930} // namespace art
931
932#endif // ART_SRC_DEX_FILE_H_