| Elliott Hughes | 2faa5f1 | 2012-01-30 14:42:07 -0800 | [diff] [blame] | 1 | /* | 
 | 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 Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 16 |  | 
| Brian Carlstrom | fc0e321 | 2013-07-17 14:40:12 -0700 | [diff] [blame] | 17 | #ifndef ART_RUNTIME_DEX_FILE_H_ | 
 | 18 | #define ART_RUNTIME_DEX_FILE_H_ | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 19 |  | 
| Ian Rogers | 700a402 | 2014-05-19 16:49:03 -0700 | [diff] [blame] | 20 | #include <memory> | 
| Elliott Hughes | 0c424cb | 2011-08-26 10:16:25 -0700 | [diff] [blame] | 21 | #include <string> | 
| Ian Rogers | 68b5685 | 2014-08-29 20:19:11 -0700 | [diff] [blame] | 22 | #include <unordered_map> | 
| Brian Carlstrom | 74eb46a | 2011-08-02 20:10:14 -0700 | [diff] [blame] | 23 | #include <vector> | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 24 |  | 
| Elliott Hughes | 07ed66b | 2012-12-12 18:34:25 -0800 | [diff] [blame] | 25 | #include "base/logging.h" | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 26 | #include "base/mutex.h"  // For Locks::mutator_lock_. | 
| Ian Rogers | 03b6eaf | 2014-10-28 09:34:57 -0700 | [diff] [blame] | 27 | #include "base/value_object.h" | 
| Brian Carlstrom | 578bbdc | 2011-07-21 14:07:47 -0700 | [diff] [blame] | 28 | #include "globals.h" | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 29 | #include "invoke_type.h" | 
| Jesse Wilson | 6bf1915 | 2011-09-29 13:12:33 -0400 | [diff] [blame] | 30 | #include "jni.h" | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 31 | #include "modifiers.h" | 
| Ian Rogers | 68b5685 | 2014-08-29 20:19:11 -0700 | [diff] [blame] | 32 | #include "utf.h" | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 33 |  | 
 | 34 | namespace art { | 
 | 35 |  | 
| Brian Carlstrom | e810452 | 2013-10-15 21:56:36 -0700 | [diff] [blame] | 36 | // TODO: remove dependencies on mirror classes, primarily by moving | 
 | 37 | // EncodedStaticFieldValueIterator to its own file. | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 38 | namespace mirror { | 
| Brian Carlstrom | ea46f95 | 2013-07-30 01:26:50 -0700 | [diff] [blame] | 39 |   class ArtField; | 
 | 40 |   class ArtMethod; | 
 | 41 |   class ClassLoader; | 
 | 42 |   class DexCache; | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 43 | }  // namespace mirror | 
 | 44 | class ClassLinker; | 
| Ian Rogers | 576ca0c | 2014-06-06 15:58:22 -0700 | [diff] [blame] | 45 | class MemMap; | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 46 | class Signature; | 
| Mathieu Chartier | eb8167a | 2014-05-07 15:43:14 -0700 | [diff] [blame] | 47 | template<class T> class Handle; | 
| Ian Rogers | fc0e94b | 2013-09-23 23:51:32 -0700 | [diff] [blame] | 48 | class StringPiece; | 
| Brian Carlstrom | a6cc893 | 2012-01-04 14:44:07 -0800 | [diff] [blame] | 49 | class ZipArchive; | 
 | 50 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 51 | // TODO: move all of the macro functionality into the DexCache class. | 
| Brian Carlstrom | f615a61 | 2011-07-23 12:50:34 -0700 | [diff] [blame] | 52 | class DexFile { | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 53 |  public: | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 54 |   static const uint8_t kDexMagic[]; | 
 | 55 |   static const uint8_t kDexMagicVersion[]; | 
 | 56 |   static constexpr size_t kSha1DigestSize = 20; | 
 | 57 |   static constexpr uint32_t kDexEndianConstant = 0x12345678; | 
| Carl Shapiro | 80d4dde | 2011-06-28 16:24:07 -0700 | [diff] [blame] | 58 |  | 
| Brian Carlstrom | b7bbba4 | 2011-10-13 14:58:47 -0700 | [diff] [blame] | 59 |   // name of the DexFile entry within a zip archive | 
 | 60 |   static const char* kClassesDex; | 
 | 61 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 62 |   // The value of an invalid index. | 
 | 63 |   static const uint32_t kDexNoIndex = 0xFFFFFFFF; | 
 | 64 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 65 |   // The value of an invalid index. | 
 | 66 |   static const uint16_t kDexNoIndex16 = 0xFFFF; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 67 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 68 |   // The separator charactor in MultiDex locations. | 
 | 69 |   static constexpr char kMultiDexSeparator = ':'; | 
 | 70 |  | 
 | 71 |   // A string version of the previous. This is a define so that we can merge string literals in the | 
 | 72 |   // preprocessor. | 
 | 73 |   #define kMultiDexSeparatorString ":" | 
 | 74 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 75 |   // Raw header_item. | 
 | 76 |   struct Header { | 
 | 77 |     uint8_t magic_[8]; | 
| Brian Carlstrom | 7934ac2 | 2013-07-26 10:54:15 -0700 | [diff] [blame] | 78 |     uint32_t checksum_;  // See also location_checksum_ | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 79 |     uint8_t signature_[kSha1DigestSize]; | 
| jeffhao | f6174e8 | 2012-01-31 16:14:17 -0800 | [diff] [blame] | 80 |     uint32_t file_size_;  // size of entire file | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 81 |     uint32_t header_size_;  // offset to start of next section | 
 | 82 |     uint32_t endian_tag_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 83 |     uint32_t link_size_;  // unused | 
 | 84 |     uint32_t link_off_;  // unused | 
 | 85 |     uint32_t map_off_;  // unused | 
 | 86 |     uint32_t string_ids_size_;  // number of StringIds | 
 | 87 |     uint32_t string_ids_off_;  // file offset of StringIds array | 
 | 88 |     uint32_t type_ids_size_;  // number of TypeIds, we don't support more than 65535 | 
 | 89 |     uint32_t type_ids_off_;  // file offset of TypeIds array | 
 | 90 |     uint32_t proto_ids_size_;  // number of ProtoIds, we don't support more than 65535 | 
 | 91 |     uint32_t proto_ids_off_;  // file offset of ProtoIds array | 
 | 92 |     uint32_t field_ids_size_;  // number of FieldIds | 
 | 93 |     uint32_t field_ids_off_;  // file offset of FieldIds array | 
 | 94 |     uint32_t method_ids_size_;  // number of MethodIds | 
 | 95 |     uint32_t method_ids_off_;  // file offset of MethodIds array | 
 | 96 |     uint32_t class_defs_size_;  // number of ClassDefs | 
 | 97 |     uint32_t class_defs_off_;  // file offset of ClassDef array | 
 | 98 |     uint32_t data_size_;  // unused | 
 | 99 |     uint32_t data_off_;  // unused | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 100 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 101 |    private: | 
 | 102 |     DISALLOW_COPY_AND_ASSIGN(Header); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 103 |   }; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 104 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 105 |   // Map item type codes. | 
 | 106 |   enum { | 
 | 107 |     kDexTypeHeaderItem               = 0x0000, | 
 | 108 |     kDexTypeStringIdItem             = 0x0001, | 
 | 109 |     kDexTypeTypeIdItem               = 0x0002, | 
 | 110 |     kDexTypeProtoIdItem              = 0x0003, | 
 | 111 |     kDexTypeFieldIdItem              = 0x0004, | 
 | 112 |     kDexTypeMethodIdItem             = 0x0005, | 
 | 113 |     kDexTypeClassDefItem             = 0x0006, | 
 | 114 |     kDexTypeMapList                  = 0x1000, | 
 | 115 |     kDexTypeTypeList                 = 0x1001, | 
 | 116 |     kDexTypeAnnotationSetRefList     = 0x1002, | 
 | 117 |     kDexTypeAnnotationSetItem        = 0x1003, | 
 | 118 |     kDexTypeClassDataItem            = 0x2000, | 
 | 119 |     kDexTypeCodeItem                 = 0x2001, | 
 | 120 |     kDexTypeStringDataItem           = 0x2002, | 
 | 121 |     kDexTypeDebugInfoItem            = 0x2003, | 
 | 122 |     kDexTypeAnnotationItem           = 0x2004, | 
 | 123 |     kDexTypeEncodedArrayItem         = 0x2005, | 
 | 124 |     kDexTypeAnnotationsDirectoryItem = 0x2006, | 
 | 125 |   }; | 
 | 126 |  | 
 | 127 |   struct MapItem { | 
 | 128 |     uint16_t type_; | 
 | 129 |     uint16_t unused_; | 
 | 130 |     uint32_t size_; | 
 | 131 |     uint32_t offset_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 132 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 133 |    private: | 
 | 134 |     DISALLOW_COPY_AND_ASSIGN(MapItem); | 
 | 135 |   }; | 
 | 136 |  | 
 | 137 |   struct MapList { | 
 | 138 |     uint32_t size_; | 
 | 139 |     MapItem list_[1]; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 140 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 141 |    private: | 
 | 142 |     DISALLOW_COPY_AND_ASSIGN(MapList); | 
 | 143 |   }; | 
 | 144 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 145 |   // Raw string_id_item. | 
 | 146 |   struct StringId { | 
 | 147 |     uint32_t string_data_off_;  // offset in bytes from the base address | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 148 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 149 |    private: | 
 | 150 |     DISALLOW_COPY_AND_ASSIGN(StringId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 151 |   }; | 
 | 152 |  | 
 | 153 |   // Raw type_id_item. | 
 | 154 |   struct TypeId { | 
 | 155 |     uint32_t descriptor_idx_;  // index into string_ids | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 156 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 157 |    private: | 
 | 158 |     DISALLOW_COPY_AND_ASSIGN(TypeId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 159 |   }; | 
 | 160 |  | 
 | 161 |   // Raw field_id_item. | 
 | 162 |   struct FieldId { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 163 |     uint16_t class_idx_;  // index into type_ids_ array for defining class | 
 | 164 |     uint16_t type_idx_;  // index into type_ids_ array for field type | 
 | 165 |     uint32_t name_idx_;  // index into string_ids_ array for field name | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 166 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 167 |    private: | 
 | 168 |     DISALLOW_COPY_AND_ASSIGN(FieldId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 169 |   }; | 
 | 170 |  | 
 | 171 |   // Raw method_id_item. | 
 | 172 |   struct MethodId { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 173 |     uint16_t class_idx_;  // index into type_ids_ array for defining class | 
 | 174 |     uint16_t proto_idx_;  // index into proto_ids_ array for method prototype | 
 | 175 |     uint32_t name_idx_;  // index into string_ids_ array for method name | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 176 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 177 |    private: | 
 | 178 |     DISALLOW_COPY_AND_ASSIGN(MethodId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 179 |   }; | 
 | 180 |  | 
 | 181 |   // Raw proto_id_item. | 
 | 182 |   struct ProtoId { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 183 |     uint32_t shorty_idx_;  // index into string_ids array for shorty descriptor | 
 | 184 |     uint16_t return_type_idx_;  // index into type_ids array for return type | 
 | 185 |     uint16_t pad_;             // padding = 0 | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 186 |     uint32_t parameters_off_;  // file offset to type_list for parameter types | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 187 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 188 |    private: | 
 | 189 |     DISALLOW_COPY_AND_ASSIGN(ProtoId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 190 |   }; | 
 | 191 |  | 
 | 192 |   // Raw class_def_item. | 
 | 193 |   struct ClassDef { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 194 |     uint16_t class_idx_;  // index into type_ids_ array for this class | 
 | 195 |     uint16_t pad1_;  // padding = 0 | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 196 |     uint32_t access_flags_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 197 |     uint16_t superclass_idx_;  // index into type_ids_ array for superclass | 
 | 198 |     uint16_t pad2_;  // padding = 0 | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 199 |     uint32_t interfaces_off_;  // file offset to TypeList | 
| Brian Carlstrom | 4a96b60 | 2011-07-26 16:40:23 -0700 | [diff] [blame] | 200 |     uint32_t source_file_idx_;  // index into string_ids_ for source file name | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 201 |     uint32_t annotations_off_;  // file offset to annotations_directory_item | 
 | 202 |     uint32_t class_data_off_;  // file offset to class_data_item | 
 | 203 |     uint32_t static_values_off_;  // file offset to EncodedArray | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 204 |  | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 205 |     // Returns the valid access flags, that is, Java modifier bits relevant to the ClassDef type | 
 | 206 |     // (class or interface). These are all in the lower 16b and do not contain runtime flags. | 
 | 207 |     uint32_t GetJavaAccessFlags() const { | 
 | 208 |       // Make sure that none of our runtime-only flags are set. | 
| Andreas Gampe | 575e78c | 2014-11-03 23:41:03 -0800 | [diff] [blame^] | 209 |       static_assert((kAccValidClassFlags & kAccJavaFlagsMask) == kAccValidClassFlags, | 
 | 210 |                     "Valid class flags not a subset of Java flags"); | 
 | 211 |       static_assert((kAccValidInterfaceFlags & kAccJavaFlagsMask) == kAccValidInterfaceFlags, | 
 | 212 |                     "Valid interface flags not a subset of Java flags"); | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 213 |  | 
 | 214 |       if ((access_flags_ & kAccInterface) != 0) { | 
 | 215 |         // Interface. | 
 | 216 |         return access_flags_ & kAccValidInterfaceFlags; | 
 | 217 |       } else { | 
 | 218 |         // Class. | 
 | 219 |         return access_flags_ & kAccValidClassFlags; | 
 | 220 |       } | 
 | 221 |     } | 
 | 222 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 223 |    private: | 
 | 224 |     DISALLOW_COPY_AND_ASSIGN(ClassDef); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 225 |   }; | 
 | 226 |  | 
 | 227 |   // Raw type_item. | 
 | 228 |   struct TypeItem { | 
 | 229 |     uint16_t type_idx_;  // index into type_ids section | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 230 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 231 |    private: | 
 | 232 |     DISALLOW_COPY_AND_ASSIGN(TypeItem); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 233 |   }; | 
 | 234 |  | 
 | 235 |   // Raw type_list. | 
 | 236 |   class TypeList { | 
 | 237 |    public: | 
 | 238 |     uint32_t Size() const { | 
 | 239 |       return size_; | 
 | 240 |     } | 
 | 241 |  | 
 | 242 |     const TypeItem& GetTypeItem(uint32_t idx) const { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 243 |       DCHECK_LT(idx, this->size_); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 244 |       return this->list_[idx]; | 
 | 245 |     } | 
 | 246 |  | 
| Andreas Gampe | 31a7a0c | 2014-08-29 16:07:49 -0700 | [diff] [blame] | 247 |     // Size in bytes of the part of the list that is common. | 
 | 248 |     static constexpr size_t GetHeaderSize() { | 
 | 249 |       return 4U; | 
 | 250 |     } | 
 | 251 |  | 
 | 252 |     // Size in bytes of the whole type list including all the stored elements. | 
 | 253 |     static constexpr size_t GetListSize(size_t count) { | 
 | 254 |       return GetHeaderSize() + sizeof(TypeItem) * count; | 
 | 255 |     } | 
 | 256 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 257 |    private: | 
 | 258 |     uint32_t size_;  // size of the list, in entries | 
 | 259 |     TypeItem list_[1];  // elements of the list | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 260 |     DISALLOW_COPY_AND_ASSIGN(TypeList); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 261 |   }; | 
 | 262 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 263 |   // Raw code_item. | 
 | 264 |   struct CodeItem { | 
 | 265 |     uint16_t registers_size_; | 
 | 266 |     uint16_t ins_size_; | 
 | 267 |     uint16_t outs_size_; | 
 | 268 |     uint16_t tries_size_; | 
 | 269 |     uint32_t debug_info_off_;  // file offset to debug info stream | 
| Ian Rogers | d81871c | 2011-10-03 13:57:23 -0700 | [diff] [blame] | 270 |     uint32_t insns_size_in_code_units_;  // size of the insns array, in 2 byte code units | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 271 |     uint16_t insns_[1]; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 272 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 273 |    private: | 
 | 274 |     DISALLOW_COPY_AND_ASSIGN(CodeItem); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 275 |   }; | 
 | 276 |  | 
| Carl Shapiro | 2eaa968 | 2011-08-04 19:26:11 -0700 | [diff] [blame] | 277 |   // Raw try_item. | 
 | 278 |   struct TryItem { | 
 | 279 |     uint32_t start_addr_; | 
 | 280 |     uint16_t insn_count_; | 
 | 281 |     uint16_t handler_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 282 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 283 |    private: | 
 | 284 |     DISALLOW_COPY_AND_ASSIGN(TryItem); | 
| Carl Shapiro | 2eaa968 | 2011-08-04 19:26:11 -0700 | [diff] [blame] | 285 |   }; | 
 | 286 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 287 |   // Annotation constants. | 
 | 288 |   enum { | 
 | 289 |     kDexVisibilityBuild         = 0x00,     /* annotation visibility */ | 
 | 290 |     kDexVisibilityRuntime       = 0x01, | 
 | 291 |     kDexVisibilitySystem        = 0x02, | 
 | 292 |  | 
 | 293 |     kDexAnnotationByte          = 0x00, | 
 | 294 |     kDexAnnotationShort         = 0x02, | 
 | 295 |     kDexAnnotationChar          = 0x03, | 
 | 296 |     kDexAnnotationInt           = 0x04, | 
 | 297 |     kDexAnnotationLong          = 0x06, | 
 | 298 |     kDexAnnotationFloat         = 0x10, | 
 | 299 |     kDexAnnotationDouble        = 0x11, | 
 | 300 |     kDexAnnotationString        = 0x17, | 
 | 301 |     kDexAnnotationType          = 0x18, | 
 | 302 |     kDexAnnotationField         = 0x19, | 
 | 303 |     kDexAnnotationMethod        = 0x1a, | 
 | 304 |     kDexAnnotationEnum          = 0x1b, | 
 | 305 |     kDexAnnotationArray         = 0x1c, | 
 | 306 |     kDexAnnotationAnnotation    = 0x1d, | 
 | 307 |     kDexAnnotationNull          = 0x1e, | 
 | 308 |     kDexAnnotationBoolean       = 0x1f, | 
 | 309 |  | 
 | 310 |     kDexAnnotationValueTypeMask = 0x1f,     /* low 5 bits */ | 
 | 311 |     kDexAnnotationValueArgShift = 5, | 
 | 312 |   }; | 
 | 313 |  | 
 | 314 |   struct AnnotationsDirectoryItem { | 
 | 315 |     uint32_t class_annotations_off_; | 
 | 316 |     uint32_t fields_size_; | 
 | 317 |     uint32_t methods_size_; | 
 | 318 |     uint32_t parameters_size_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 319 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 320 |    private: | 
 | 321 |     DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem); | 
 | 322 |   }; | 
 | 323 |  | 
 | 324 |   struct FieldAnnotationsItem { | 
 | 325 |     uint32_t field_idx_; | 
 | 326 |     uint32_t annotations_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 327 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 328 |    private: | 
 | 329 |     DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem); | 
 | 330 |   }; | 
 | 331 |  | 
 | 332 |   struct MethodAnnotationsItem { | 
 | 333 |     uint32_t method_idx_; | 
 | 334 |     uint32_t annotations_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 335 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 336 |    private: | 
 | 337 |     DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem); | 
 | 338 |   }; | 
 | 339 |  | 
 | 340 |   struct ParameterAnnotationsItem { | 
 | 341 |     uint32_t method_idx_; | 
 | 342 |     uint32_t annotations_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 343 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 344 |    private: | 
 | 345 |     DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem); | 
 | 346 |   }; | 
 | 347 |  | 
 | 348 |   struct AnnotationSetRefItem { | 
 | 349 |     uint32_t annotations_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 350 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 351 |    private: | 
 | 352 |     DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem); | 
 | 353 |   }; | 
 | 354 |  | 
 | 355 |   struct AnnotationSetRefList { | 
 | 356 |     uint32_t size_; | 
 | 357 |     AnnotationSetRefItem list_[1]; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 358 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 359 |    private: | 
 | 360 |     DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList); | 
 | 361 |   }; | 
 | 362 |  | 
 | 363 |   struct AnnotationSetItem { | 
 | 364 |     uint32_t size_; | 
 | 365 |     uint32_t entries_[1]; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 366 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 367 |    private: | 
 | 368 |     DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem); | 
 | 369 |   }; | 
 | 370 |  | 
 | 371 |   struct AnnotationItem { | 
 | 372 |     uint8_t visibility_; | 
 | 373 |     uint8_t annotation_[1]; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 374 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 375 |    private: | 
 | 376 |     DISALLOW_COPY_AND_ASSIGN(AnnotationItem); | 
 | 377 |   }; | 
 | 378 |  | 
| Brian Carlstrom | 5b332c8 | 2012-02-01 15:02:31 -0800 | [diff] [blame] | 379 |   // Returns the checksum of a file for comparison with GetLocationChecksum(). | 
 | 380 |   // For .dex files, this is the header checksum. | 
 | 381 |   // For zip files, this is the classes.dex zip entry CRC32 checksum. | 
 | 382 |   // Return true if the checksum could be found, false otherwise. | 
| Ian Rogers | 8d31bbd | 2013-10-13 10:44:14 -0700 | [diff] [blame] | 383 |   static bool GetChecksum(const char* filename, uint32_t* checksum, std::string* error_msg); | 
| Brian Carlstrom | 78128a6 | 2011-09-15 17:21:19 -0700 | [diff] [blame] | 384 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 385 |   // Opens .dex files found in the container, guessing the container format based on file extension. | 
 | 386 |   static bool Open(const char* filename, const char* location, std::string* error_msg, | 
 | 387 |                    std::vector<const DexFile*>* dex_files); | 
| jeffhao | 262bf46 | 2011-10-20 18:36:32 -0700 | [diff] [blame] | 388 |  | 
| Brian Carlstrom | 8952189 | 2011-12-07 22:05:07 -0800 | [diff] [blame] | 389 |   // Opens .dex file, backed by existing memory | 
| Brian Carlstrom | 5b332c8 | 2012-02-01 15:02:31 -0800 | [diff] [blame] | 390 |   static const DexFile* Open(const uint8_t* base, size_t size, | 
| Brian Carlstrom | 28db012 | 2012-10-18 16:20:41 -0700 | [diff] [blame] | 391 |                              const std::string& location, | 
| Ian Rogers | 8d31bbd | 2013-10-13 10:44:14 -0700 | [diff] [blame] | 392 |                              uint32_t location_checksum, | 
 | 393 |                              std::string* error_msg) { | 
 | 394 |     return OpenMemory(base, size, location, location_checksum, NULL, error_msg); | 
| Brian Carlstrom | 8952189 | 2011-12-07 22:05:07 -0800 | [diff] [blame] | 395 |   } | 
 | 396 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 397 |   // Open all classesXXX.dex files from a zip archive. | 
 | 398 |   static bool OpenFromZip(const ZipArchive& zip_archive, const std::string& location, | 
 | 399 |                           std::string* error_msg, std::vector<const DexFile*>* dex_files); | 
| Brian Carlstrom | a6cc893 | 2012-01-04 14:44:07 -0800 | [diff] [blame] | 400 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 401 |   // Closes a .dex file. | 
| Brian Carlstrom | f615a61 | 2011-07-23 12:50:34 -0700 | [diff] [blame] | 402 |   virtual ~DexFile(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 403 |  | 
| Brian Carlstrom | a663ea5 | 2011-08-19 23:33:41 -0700 | [diff] [blame] | 404 |   const std::string& GetLocation() const { | 
 | 405 |     return location_; | 
 | 406 |   } | 
 | 407 |  | 
| Andreas Gampe | cb8f9e8 | 2014-07-24 15:35:50 -0700 | [diff] [blame] | 408 |   // For normal dex files, location and base location coincide. If a dex file is part of a multidex | 
 | 409 |   // archive, the base location is the name of the originating jar/apk, stripped of any internal | 
 | 410 |   // classes*.dex path. | 
| Vladimir Marko | aa4497d | 2014-09-05 14:01:17 +0100 | [diff] [blame] | 411 |   static std::string GetBaseLocation(const char* location) { | 
 | 412 |     const char* pos = strrchr(location, kMultiDexSeparator); | 
 | 413 |     if (pos == nullptr) { | 
 | 414 |       return location; | 
| Andreas Gampe | cb8f9e8 | 2014-07-24 15:35:50 -0700 | [diff] [blame] | 415 |     } else { | 
| Vladimir Marko | aa4497d | 2014-09-05 14:01:17 +0100 | [diff] [blame] | 416 |       return std::string(location, pos - location); | 
 | 417 |     } | 
 | 418 |   } | 
 | 419 |  | 
 | 420 |   std::string GetBaseLocation() const { | 
 | 421 |     size_t pos = location_.rfind(kMultiDexSeparator); | 
 | 422 |     if (pos == std::string::npos) { | 
| Andreas Gampe | cb8f9e8 | 2014-07-24 15:35:50 -0700 | [diff] [blame] | 423 |       return location_; | 
| Vladimir Marko | aa4497d | 2014-09-05 14:01:17 +0100 | [diff] [blame] | 424 |     } else { | 
 | 425 |       return location_.substr(0, pos); | 
| Andreas Gampe | cb8f9e8 | 2014-07-24 15:35:50 -0700 | [diff] [blame] | 426 |     } | 
 | 427 |   } | 
 | 428 |  | 
| Brian Carlstrom | 5b332c8 | 2012-02-01 15:02:31 -0800 | [diff] [blame] | 429 |   // For DexFiles directly from .dex files, this is the checksum from the DexFile::Header. | 
 | 430 |   // For DexFiles opened from a zip files, this will be the ZipEntry CRC32 of classes.dex. | 
 | 431 |   uint32_t GetLocationChecksum() const { | 
 | 432 |     return location_checksum_; | 
 | 433 |   } | 
 | 434 |  | 
| Brian Carlstrom | a663ea5 | 2011-08-19 23:33:41 -0700 | [diff] [blame] | 435 |   const Header& GetHeader() const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 436 |     DCHECK(header_ != NULL) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 437 |     return *header_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 438 |   } | 
 | 439 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 440 |   // Decode the dex magic version | 
| Ian Rogers | d81871c | 2011-10-03 13:57:23 -0700 | [diff] [blame] | 441 |   uint32_t GetVersion() const; | 
 | 442 |  | 
| Brian Carlstrom | 6e3b1d9 | 2012-01-11 01:36:32 -0800 | [diff] [blame] | 443 |   // Returns true if the byte string points to the magic value. | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 444 |   static bool IsMagicValid(const uint8_t* magic); | 
| Brian Carlstrom | 6e3b1d9 | 2012-01-11 01:36:32 -0800 | [diff] [blame] | 445 |  | 
 | 446 |   // Returns true if the byte string after the magic is the correct value. | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 447 |   static bool IsVersionValid(const uint8_t* magic); | 
| Brian Carlstrom | 6e3b1d9 | 2012-01-11 01:36:32 -0800 | [diff] [blame] | 448 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 449 |   // Returns the number of string identifiers in the .dex file. | 
 | 450 |   size_t NumStringIds() const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 451 |     DCHECK(header_ != NULL) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 452 |     return header_->string_ids_size_; | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame] | 453 |   } | 
 | 454 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 455 |   // Returns the StringId at the specified index. | 
 | 456 |   const StringId& GetStringId(uint32_t idx) const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 457 |     DCHECK_LT(idx, NumStringIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 458 |     return string_ids_[idx]; | 
 | 459 |   } | 
 | 460 |  | 
 | 461 |   uint32_t GetIndexForStringId(const StringId& string_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 462 |     CHECK_GE(&string_id, string_ids_) << GetLocation(); | 
 | 463 |     CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 464 |     return &string_id - string_ids_; | 
 | 465 |   } | 
 | 466 |  | 
 | 467 |   int32_t GetStringLength(const StringId& string_id) const; | 
 | 468 |  | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 469 |   // Returns a pointer to the UTF-8 string data referred to by the given string_id as well as the | 
 | 470 |   // length of the string when decoded as a UTF-16 string. Note the UTF-16 length is not the same | 
 | 471 |   // as the string length of the string data. | 
 | 472 |   const char* GetStringDataAndUtf16Length(const StringId& string_id, uint32_t* utf16_length) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 473 |  | 
 | 474 |   const char* GetStringData(const StringId& string_id) const { | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 475 |     uint32_t ignored; | 
 | 476 |     return GetStringDataAndUtf16Length(string_id, &ignored); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 477 |   } | 
 | 478 |  | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 479 |   // Index version of GetStringDataAndUtf16Length. | 
 | 480 |   const char* StringDataAndUtf16LengthByIdx(uint32_t idx, uint32_t* utf16_length) const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 481 |     if (idx == kDexNoIndex) { | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 482 |       *utf16_length = 0; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 483 |       return NULL; | 
 | 484 |     } | 
 | 485 |     const StringId& string_id = GetStringId(idx); | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 486 |     return GetStringDataAndUtf16Length(string_id, utf16_length); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 487 |   } | 
 | 488 |  | 
 | 489 |   const char* StringDataByIdx(uint32_t idx) const { | 
| Elliott Hughes | 45651fd | 2012-02-21 15:48:20 -0800 | [diff] [blame] | 490 |     uint32_t unicode_length; | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 491 |     return StringDataAndUtf16LengthByIdx(idx, &unicode_length); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 492 |   } | 
 | 493 |  | 
| Ian Rogers | 637c65b | 2013-05-31 11:46:00 -0700 | [diff] [blame] | 494 |   // Looks up a string id for a given modified utf8 string. | 
 | 495 |   const StringId* FindStringId(const char* string) const; | 
 | 496 |  | 
 | 497 |   // Looks up a string id for a given utf16 string. | 
 | 498 |   const StringId* FindStringId(const uint16_t* string) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 499 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 500 |   // Returns the number of type identifiers in the .dex file. | 
| Ian Rogers | 68b5685 | 2014-08-29 20:19:11 -0700 | [diff] [blame] | 501 |   uint32_t NumTypeIds() const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 502 |     DCHECK(header_ != NULL) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 503 |     return header_->type_ids_size_; | 
| Carl Shapiro | 5fafe2b | 2011-07-09 15:34:41 -0700 | [diff] [blame] | 504 |   } | 
 | 505 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 506 |   // Returns the TypeId at the specified index. | 
 | 507 |   const TypeId& GetTypeId(uint32_t idx) const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 508 |     DCHECK_LT(idx, NumTypeIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 509 |     return type_ids_[idx]; | 
| Carl Shapiro | 5fafe2b | 2011-07-09 15:34:41 -0700 | [diff] [blame] | 510 |   } | 
 | 511 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 512 |   uint16_t GetIndexForTypeId(const TypeId& type_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 513 |     CHECK_GE(&type_id, type_ids_) << GetLocation(); | 
 | 514 |     CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 515 |     size_t result = &type_id - type_ids_; | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 516 |     DCHECK_LT(result, 65536U) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 517 |     return static_cast<uint16_t>(result); | 
 | 518 |   } | 
 | 519 |  | 
 | 520 |   // Get the descriptor string associated with a given type index. | 
| Elliott Hughes | 45651fd | 2012-02-21 15:48:20 -0800 | [diff] [blame] | 521 |   const char* StringByTypeIdx(uint32_t idx, uint32_t* unicode_length) const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 522 |     const TypeId& type_id = GetTypeId(idx); | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 523 |     return StringDataAndUtf16LengthByIdx(type_id.descriptor_idx_, unicode_length); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 524 |   } | 
 | 525 |  | 
 | 526 |   const char* StringByTypeIdx(uint32_t idx) const { | 
 | 527 |     const TypeId& type_id = GetTypeId(idx); | 
 | 528 |     return StringDataByIdx(type_id.descriptor_idx_); | 
 | 529 |   } | 
 | 530 |  | 
 | 531 |   // Returns the type descriptor string of a type id. | 
 | 532 |   const char* GetTypeDescriptor(const TypeId& type_id) const { | 
 | 533 |     return StringDataByIdx(type_id.descriptor_idx_); | 
 | 534 |   } | 
 | 535 |  | 
 | 536 |   // Looks up a type for the given string index | 
 | 537 |   const TypeId* FindTypeId(uint32_t string_idx) const; | 
 | 538 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 539 |   // Returns the number of field identifiers in the .dex file. | 
 | 540 |   size_t NumFieldIds() const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 541 |     DCHECK(header_ != NULL) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 542 |     return header_->field_ids_size_; | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame] | 543 |   } | 
 | 544 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 545 |   // Returns the FieldId at the specified index. | 
 | 546 |   const FieldId& GetFieldId(uint32_t idx) const { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 547 |     DCHECK_LT(idx, NumFieldIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 548 |     return field_ids_[idx]; | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 549 |   } | 
 | 550 |  | 
| Ian Rogers | 9b1a4f4 | 2011-11-14 18:35:10 -0800 | [diff] [blame] | 551 |   uint32_t GetIndexForFieldId(const FieldId& field_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 552 |     CHECK_GE(&field_id, field_ids_) << GetLocation(); | 
 | 553 |     CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation(); | 
| Ian Rogers | 9b1a4f4 | 2011-11-14 18:35:10 -0800 | [diff] [blame] | 554 |     return &field_id - field_ids_; | 
 | 555 |   } | 
 | 556 |  | 
 | 557 |   // Looks up a field by its declaring class, name and type | 
 | 558 |   const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass, | 
 | 559 |                              const DexFile::StringId& name, | 
 | 560 |                              const DexFile::TypeId& type) const; | 
 | 561 |  | 
| Brian Carlstrom | 6b4ef02 | 2011-10-23 14:59:04 -0700 | [diff] [blame] | 562 |   // Returns the declaring class descriptor string of a field id. | 
 | 563 |   const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const { | 
| Brian Carlstrom | b9edb84 | 2011-08-28 16:31:06 -0700 | [diff] [blame] | 564 |     const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_); | 
 | 565 |     return GetTypeDescriptor(type_id); | 
 | 566 |   } | 
 | 567 |  | 
| Brian Carlstrom | 6b4ef02 | 2011-10-23 14:59:04 -0700 | [diff] [blame] | 568 |   // Returns the class descriptor string of a field id. | 
 | 569 |   const char* GetFieldTypeDescriptor(const FieldId& field_id) const { | 
 | 570 |     const DexFile::TypeId& type_id = GetTypeId(field_id.type_idx_); | 
 | 571 |     return GetTypeDescriptor(type_id); | 
 | 572 |   } | 
 | 573 |  | 
| Brian Carlstrom | b9edb84 | 2011-08-28 16:31:06 -0700 | [diff] [blame] | 574 |   // Returns the name of a field id. | 
 | 575 |   const char* GetFieldName(const FieldId& field_id) const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 576 |     return StringDataByIdx(field_id.name_idx_); | 
| Brian Carlstrom | b9edb84 | 2011-08-28 16:31:06 -0700 | [diff] [blame] | 577 |   } | 
 | 578 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 579 |   // Returns the number of method identifiers in the .dex file. | 
 | 580 |   size_t NumMethodIds() const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 581 |     DCHECK(header_ != NULL) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 582 |     return header_->method_ids_size_; | 
 | 583 |   } | 
 | 584 |  | 
 | 585 |   // Returns the MethodId at the specified index. | 
 | 586 |   const MethodId& GetMethodId(uint32_t idx) const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 587 |     DCHECK_LT(idx, NumMethodIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 588 |     return method_ids_[idx]; | 
 | 589 |   } | 
 | 590 |  | 
 | 591 |   uint32_t GetIndexForMethodId(const MethodId& method_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 592 |     CHECK_GE(&method_id, method_ids_) << GetLocation(); | 
 | 593 |     CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 594 |     return &method_id - method_ids_; | 
 | 595 |   } | 
 | 596 |  | 
| Ian Rogers | 9b1a4f4 | 2011-11-14 18:35:10 -0800 | [diff] [blame] | 597 |   // Looks up a method by its declaring class, name and proto_id | 
 | 598 |   const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass, | 
 | 599 |                                const DexFile::StringId& name, | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 600 |                                const DexFile::ProtoId& signature) const; | 
 | 601 |  | 
| Brian Carlstrom | 6b4ef02 | 2011-10-23 14:59:04 -0700 | [diff] [blame] | 602 |   // Returns the declaring class descriptor string of a method id. | 
 | 603 |   const char* GetMethodDeclaringClassDescriptor(const MethodId& method_id) const { | 
| Brian Carlstrom | 7540ff4 | 2011-09-04 16:38:46 -0700 | [diff] [blame] | 604 |     const DexFile::TypeId& type_id = GetTypeId(method_id.class_idx_); | 
 | 605 |     return GetTypeDescriptor(type_id); | 
 | 606 |   } | 
 | 607 |  | 
| jeffhao | 98eacac | 2011-09-14 16:11:53 -0700 | [diff] [blame] | 608 |   // Returns the prototype of a method id. | 
| Brian Carlstrom | aded5f7 | 2011-10-07 17:15:04 -0700 | [diff] [blame] | 609 |   const ProtoId& GetMethodPrototype(const MethodId& method_id) const { | 
 | 610 |     return GetProtoId(method_id.proto_idx_); | 
 | 611 |   } | 
 | 612 |  | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 613 |   // Returns a representation of the signature of a method id. | 
 | 614 |   const Signature GetMethodSignature(const MethodId& method_id) const; | 
| jeffhao | 98eacac | 2011-09-14 16:11:53 -0700 | [diff] [blame] | 615 |  | 
| Brian Carlstrom | 7540ff4 | 2011-09-04 16:38:46 -0700 | [diff] [blame] | 616 |   // Returns the name of a method id. | 
 | 617 |   const char* GetMethodName(const MethodId& method_id) const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 618 |     return StringDataByIdx(method_id.name_idx_); | 
| Brian Carlstrom | 7540ff4 | 2011-09-04 16:38:46 -0700 | [diff] [blame] | 619 |   } | 
 | 620 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 621 |   // Returns the shorty of a method id. | 
 | 622 |   const char* GetMethodShorty(const MethodId& method_id) const { | 
 | 623 |     return StringDataByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 624 |   } | 
| Elliott Hughes | 45651fd | 2012-02-21 15:48:20 -0800 | [diff] [blame] | 625 |   const char* GetMethodShorty(const MethodId& method_id, uint32_t* length) const { | 
| Ian Rogers | cf5077a | 2013-10-31 12:37:54 -0700 | [diff] [blame] | 626 |     // Using the UTF16 length is safe here as shorties are guaranteed to be ASCII characters. | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 627 |     return StringDataAndUtf16LengthByIdx(GetProtoId(method_id.proto_idx_).shorty_idx_, length); | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 628 |   } | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 629 |   // Returns the number of class definitions in the .dex file. | 
| Ian Rogers | 68b5685 | 2014-08-29 20:19:11 -0700 | [diff] [blame] | 630 |   uint32_t NumClassDefs() const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 631 |     DCHECK(header_ != NULL) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 632 |     return header_->class_defs_size_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 633 |   } | 
 | 634 |  | 
 | 635 |   // Returns the ClassDef at the specified index. | 
| Ian Rogers | 8b2c0b9 | 2013-09-19 02:56:49 -0700 | [diff] [blame] | 636 |   const ClassDef& GetClassDef(uint16_t idx) const { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 637 |     DCHECK_LT(idx, NumClassDefs()) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 638 |     return class_defs_[idx]; | 
 | 639 |   } | 
 | 640 |  | 
| Ian Rogers | 8b2c0b9 | 2013-09-19 02:56:49 -0700 | [diff] [blame] | 641 |   uint16_t GetIndexForClassDef(const ClassDef& class_def) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 642 |     CHECK_GE(&class_def, class_defs_) << GetLocation(); | 
 | 643 |     CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 644 |     return &class_def - class_defs_; | 
 | 645 |   } | 
 | 646 |  | 
 | 647 |   // Returns the class descriptor string of a class definition. | 
 | 648 |   const char* GetClassDescriptor(const ClassDef& class_def) const { | 
 | 649 |     return StringByTypeIdx(class_def.class_idx_); | 
 | 650 |   } | 
 | 651 |  | 
 | 652 |   // Looks up a class definition by its class descriptor. | 
| Ian Rogers | 8b2c0b9 | 2013-09-19 02:56:49 -0700 | [diff] [blame] | 653 |   const ClassDef* FindClassDef(const char* descriptor) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 654 |  | 
| Ian Rogers | 8b2c0b9 | 2013-09-19 02:56:49 -0700 | [diff] [blame] | 655 |   // Looks up a class definition by its type index. | 
 | 656 |   const ClassDef* FindClassDef(uint16_t type_idx) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 657 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 658 |   const TypeList* GetInterfacesList(const ClassDef& class_def) const { | 
 | 659 |     if (class_def.interfaces_off_ == 0) { | 
 | 660 |         return NULL; | 
 | 661 |     } else { | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 662 |       const uint8_t* addr = begin_ + class_def.interfaces_off_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 663 |       return reinterpret_cast<const TypeList*>(addr); | 
 | 664 |     } | 
 | 665 |   } | 
 | 666 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 667 |   // Returns a pointer to the raw memory mapped class_data_item | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 668 |   const uint8_t* GetClassData(const ClassDef& class_def) const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 669 |     if (class_def.class_data_off_ == 0) { | 
 | 670 |       return NULL; | 
 | 671 |     } else { | 
| Ian Rogers | 30fab40 | 2012-01-23 15:43:46 -0800 | [diff] [blame] | 672 |       return begin_ + class_def.class_data_off_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 673 |     } | 
| Shih-wei Liao | 2fb9753 | 2011-08-11 16:17:23 -0700 | [diff] [blame] | 674 |   } | 
 | 675 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 676 |   // | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 677 |   const CodeItem* GetCodeItem(const uint32_t code_off) const { | 
 | 678 |     if (code_off == 0) { | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 679 |       return NULL;  // native or abstract method | 
 | 680 |     } else { | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 681 |       const uint8_t* addr = begin_ + code_off; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 682 |       return reinterpret_cast<const CodeItem*>(addr); | 
 | 683 |     } | 
 | 684 |   } | 
 | 685 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 686 |   const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const { | 
 | 687 |     return StringByTypeIdx(proto_id.return_type_idx_); | 
 | 688 |   } | 
 | 689 |  | 
 | 690 |   // Returns the number of prototype identifiers in the .dex file. | 
 | 691 |   size_t NumProtoIds() const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 692 |     DCHECK(header_ != NULL) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 693 |     return header_->proto_ids_size_; | 
 | 694 |   } | 
 | 695 |  | 
 | 696 |   // Returns the ProtoId at the specified index. | 
 | 697 |   const ProtoId& GetProtoId(uint32_t idx) const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 698 |     DCHECK_LT(idx, NumProtoIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 699 |     return proto_ids_[idx]; | 
 | 700 |   } | 
 | 701 |  | 
 | 702 |   uint16_t GetIndexForProtoId(const ProtoId& proto_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 703 |     CHECK_GE(&proto_id, proto_ids_) << GetLocation(); | 
 | 704 |     CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 705 |     return &proto_id - proto_ids_; | 
 | 706 |   } | 
 | 707 |  | 
 | 708 |   // Looks up a proto id for a given return type and signature type list | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 709 |   const ProtoId* FindProtoId(uint16_t return_type_idx, | 
| Vladimir Marko | 5c96e6b | 2013-11-14 15:34:17 +0000 | [diff] [blame] | 710 |                              const uint16_t* signature_type_idxs, uint32_t signature_length) const; | 
 | 711 |   const ProtoId* FindProtoId(uint16_t return_type_idx, | 
 | 712 |                              const std::vector<uint16_t>& signature_type_idxs) const { | 
 | 713 |     return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size()); | 
 | 714 |   } | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 715 |  | 
 | 716 |   // Given a signature place the type ids into the given vector, returns true on success | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 717 |   bool CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx, | 
 | 718 |                       std::vector<uint16_t>* param_type_idxs) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 719 |  | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 720 |   // Create a Signature from the given string signature or return Signature::NoSignature if not | 
 | 721 |   // possible. | 
 | 722 |   const Signature CreateSignature(const StringPiece& signature) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 723 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 724 |   // Returns the short form method descriptor for the given prototype. | 
 | 725 |   const char* GetShorty(uint32_t proto_idx) const { | 
 | 726 |     const ProtoId& proto_id = GetProtoId(proto_idx); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 727 |     return StringDataByIdx(proto_id.shorty_idx_); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 728 |   } | 
 | 729 |  | 
 | 730 |   const TypeList* GetProtoParameters(const ProtoId& proto_id) const { | 
 | 731 |     if (proto_id.parameters_off_ == 0) { | 
 | 732 |       return NULL; | 
 | 733 |     } else { | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 734 |       const uint8_t* addr = begin_ + proto_id.parameters_off_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 735 |       return reinterpret_cast<const TypeList*>(addr); | 
 | 736 |     } | 
 | 737 |   } | 
 | 738 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 739 |   const uint8_t* GetEncodedStaticFieldValuesArray(const ClassDef& class_def) const { | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 740 |     if (class_def.static_values_off_ == 0) { | 
 | 741 |       return 0; | 
 | 742 |     } else { | 
| Ian Rogers | 30fab40 | 2012-01-23 15:43:46 -0800 | [diff] [blame] | 743 |       return begin_ + class_def.static_values_off_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 744 |     } | 
 | 745 |   } | 
 | 746 |  | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 747 |   static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset); | 
| Shih-wei Liao | 2fb9753 | 2011-08-11 16:17:23 -0700 | [diff] [blame] | 748 |  | 
 | 749 |   // Get the base of the encoded data for the given DexCode. | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 750 |   static const uint8_t* GetCatchHandlerData(const CodeItem& code_item, uint32_t offset) { | 
 | 751 |     const uint8_t* handler_data = | 
 | 752 |         reinterpret_cast<const uint8_t*>(GetTryItems(code_item, code_item.tries_size_)); | 
| Shih-wei Liao | 2fb9753 | 2011-08-11 16:17:23 -0700 | [diff] [blame] | 753 |     return handler_data + offset; | 
 | 754 |   } | 
 | 755 |  | 
| Ian Rogers | dbbc99d | 2013-04-18 16:51:54 -0700 | [diff] [blame] | 756 |   // Find which try region is associated with the given address (ie dex pc). Returns -1 if none. | 
 | 757 |   static int32_t FindTryItem(const CodeItem &code_item, uint32_t address); | 
 | 758 |  | 
 | 759 |   // Find the handler offset associated with the given address (ie dex pc). Returns -1 if none. | 
 | 760 |   static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address); | 
| Shih-wei Liao | 2fb9753 | 2011-08-11 16:17:23 -0700 | [diff] [blame] | 761 |  | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 762 |   // Get the pointer to the start of the debugging data | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 763 |   const uint8_t* GetDebugInfoStream(const CodeItem* code_item) const { | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 764 |     if (code_item->debug_info_off_ == 0) { | 
 | 765 |       return NULL; | 
 | 766 |     } else { | 
| Ian Rogers | 30fab40 | 2012-01-23 15:43:46 -0800 | [diff] [blame] | 767 |       return begin_ + code_item->debug_info_off_; | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 768 |     } | 
 | 769 |   } | 
 | 770 |  | 
 | 771 |   // Callback for "new position table entry". | 
 | 772 |   // Returning true causes the decoder to stop early. | 
| Elliott Hughes | 2435a57 | 2012-02-17 16:07:41 -0800 | [diff] [blame] | 773 |   typedef bool (*DexDebugNewPositionCb)(void* context, uint32_t address, uint32_t line_num); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 774 |  | 
 | 775 |   // Callback for "new locals table entry". "signature" is an empty string | 
 | 776 |   // if no signature is available for an entry. | 
| Elliott Hughes | 2435a57 | 2012-02-17 16:07:41 -0800 | [diff] [blame] | 777 |   typedef void (*DexDebugNewLocalCb)(void* context, uint16_t reg, | 
| Elliott Hughes | 24edeb5 | 2012-06-18 15:29:46 -0700 | [diff] [blame] | 778 |                                      uint32_t start_address, | 
 | 779 |                                      uint32_t end_address, | 
| Brian Carlstrom | 40381fb | 2011-10-19 14:13:40 -0700 | [diff] [blame] | 780 |                                      const char* name, | 
 | 781 |                                      const char* descriptor, | 
 | 782 |                                      const char* signature); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 783 |  | 
| Elliott Hughes | 2435a57 | 2012-02-17 16:07:41 -0800 | [diff] [blame] | 784 |   static bool LineNumForPcCb(void* context, uint32_t address, uint32_t line_num); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 785 |  | 
 | 786 |   // Debug info opcodes and constants | 
 | 787 |   enum { | 
 | 788 |     DBG_END_SEQUENCE         = 0x00, | 
 | 789 |     DBG_ADVANCE_PC           = 0x01, | 
 | 790 |     DBG_ADVANCE_LINE         = 0x02, | 
 | 791 |     DBG_START_LOCAL          = 0x03, | 
 | 792 |     DBG_START_LOCAL_EXTENDED = 0x04, | 
 | 793 |     DBG_END_LOCAL            = 0x05, | 
 | 794 |     DBG_RESTART_LOCAL        = 0x06, | 
 | 795 |     DBG_SET_PROLOGUE_END     = 0x07, | 
 | 796 |     DBG_SET_EPILOGUE_BEGIN   = 0x08, | 
 | 797 |     DBG_SET_FILE             = 0x09, | 
 | 798 |     DBG_FIRST_SPECIAL        = 0x0a, | 
 | 799 |     DBG_LINE_BASE            = -4, | 
 | 800 |     DBG_LINE_RANGE           = 15, | 
 | 801 |   }; | 
 | 802 |  | 
 | 803 |   struct LocalInfo { | 
| Ian Rogers | ca19066 | 2012-06-26 15:45:57 -0700 | [diff] [blame] | 804 |     LocalInfo() | 
 | 805 |         : name_(NULL), descriptor_(NULL), signature_(NULL), start_address_(0), is_live_(false) {} | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 806 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 807 |     const char* name_;  // E.g., list | 
 | 808 |     const char* descriptor_;  // E.g., Ljava/util/LinkedList; | 
 | 809 |     const char* signature_;  // E.g., java.util.LinkedList<java.lang.Integer> | 
 | 810 |     uint16_t start_address_;  // PC location where the local is first defined. | 
 | 811 |     bool is_live_;  // Is the local defined and live. | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 812 |  | 
 | 813 |    private: | 
 | 814 |     DISALLOW_COPY_AND_ASSIGN(LocalInfo); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 815 |   }; | 
 | 816 |  | 
 | 817 |   struct LineNumFromPcContext { | 
| Ian Rogers | ca19066 | 2012-06-26 15:45:57 -0700 | [diff] [blame] | 818 |     LineNumFromPcContext(uint32_t address, uint32_t line_num) | 
 | 819 |         : address_(address), line_num_(line_num) {} | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 820 |     uint32_t address_; | 
 | 821 |     uint32_t line_num_; | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 822 |    private: | 
 | 823 |     DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 824 |   }; | 
 | 825 |  | 
| Elliott Hughes | 2435a57 | 2012-02-17 16:07:41 -0800 | [diff] [blame] | 826 |   void InvokeLocalCbIfLive(void* context, int reg, uint32_t end_address, | 
| Brian Carlstrom | 78128a6 | 2011-09-15 17:21:19 -0700 | [diff] [blame] | 827 |                            LocalInfo* local_in_reg, DexDebugNewLocalCb local_cb) const { | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 828 |     if (local_cb != NULL && local_in_reg[reg].is_live_) { | 
| Elliott Hughes | 2435a57 | 2012-02-17 16:07:41 -0800 | [diff] [blame] | 829 |       local_cb(context, reg, local_in_reg[reg].start_address_, end_address, | 
| Elliott Hughes | dbb4079 | 2011-11-18 17:05:22 -0800 | [diff] [blame] | 830 |           local_in_reg[reg].name_, local_in_reg[reg].descriptor_, | 
 | 831 |           local_in_reg[reg].signature_ != NULL ? local_in_reg[reg].signature_ : ""); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 832 |     } | 
 | 833 |   } | 
 | 834 |  | 
 | 835 |   // Determine the source file line number based on the program counter. | 
 | 836 |   // "pc" is an offset, in 16-bit units, from the start of the method's code. | 
 | 837 |   // | 
 | 838 |   // Returns -1 if no match was found (possibly because the source files were | 
 | 839 |   // compiled without "-g", so no line number information is present). | 
 | 840 |   // Returns -2 for native methods (as expected in exception traces). | 
 | 841 |   // | 
 | 842 |   // This is used by runtime; therefore use art::Method not art::DexFile::Method. | 
| Ian Rogers | ef7d42f | 2014-01-06 12:55:46 -0800 | [diff] [blame] | 843 |   int32_t GetLineNumFromPC(mirror::ArtMethod* method, uint32_t rel_pc) const | 
| Ian Rogers | b726dcb | 2012-09-05 08:57:23 -0700 | [diff] [blame] | 844 |       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 845 |  | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 846 |   void DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx, | 
| Elliott Hughes | 2435a57 | 2012-02-17 16:07:41 -0800 | [diff] [blame] | 847 |                        DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb, | 
 | 848 |                        void* context) const; | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 849 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 850 |   const char* GetSourceFile(const ClassDef& class_def) const { | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 851 |     if (class_def.source_file_idx_ == 0xffffffff) { | 
 | 852 |       return NULL; | 
 | 853 |     } else { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 854 |       return StringDataByIdx(class_def.source_file_idx_); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 855 |     } | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame] | 856 |   } | 
 | 857 |  | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 858 |   int GetPermissions() const; | 
| Ian Rogers | 1c849e5 | 2012-06-28 14:00:33 -0700 | [diff] [blame] | 859 |  | 
| Sebastien Hertz | 2d6ba51 | 2013-05-17 11:31:37 +0200 | [diff] [blame] | 860 |   bool IsReadOnly() const; | 
 | 861 |  | 
| Brian Carlstrom | e0948e1 | 2013-08-29 09:36:15 -0700 | [diff] [blame] | 862 |   bool EnableWrite() const; | 
| Sebastien Hertz | 2d6ba51 | 2013-05-17 11:31:37 +0200 | [diff] [blame] | 863 |  | 
| Brian Carlstrom | e0948e1 | 2013-08-29 09:36:15 -0700 | [diff] [blame] | 864 |   bool DisableWrite() const; | 
| Sebastien Hertz | 2d6ba51 | 2013-05-17 11:31:37 +0200 | [diff] [blame] | 865 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 866 |   const uint8_t* Begin() const { | 
| Ian Rogers | 8b2c0b9 | 2013-09-19 02:56:49 -0700 | [diff] [blame] | 867 |     return begin_; | 
 | 868 |   } | 
 | 869 |  | 
 | 870 |   size_t Size() const { | 
 | 871 |     return size_; | 
 | 872 |   } | 
 | 873 |  | 
| Calin Juravle | 4e1d579 | 2014-07-15 23:56:47 +0100 | [diff] [blame] | 874 |   static std::string GetMultiDexClassesDexName(size_t number, const char* dex_location); | 
 | 875 |  | 
 | 876 |   // Returns the canonical form of the given dex location. | 
 | 877 |   // | 
 | 878 |   // There are different flavors of "dex locations" as follows: | 
 | 879 |   // the file name of a dex file: | 
 | 880 |   //     The actual file path that the dex file has on disk. | 
 | 881 |   // dex_location: | 
 | 882 |   //     This acts as a key for the class linker to know which dex file to load. | 
 | 883 |   //     It may correspond to either an old odex file or a particular dex file | 
 | 884 |   //     inside an oat file. In the first case it will also match the file name | 
 | 885 |   //     of the dex file. In the second case (oat) it will include the file name | 
 | 886 |   //     and possibly some multidex annotation to uniquely identify it. | 
 | 887 |   // canonical_dex_location: | 
 | 888 |   //     the dex_location where it's file name part has been made canonical. | 
 | 889 |   static std::string GetDexCanonicalLocation(const char* dex_location); | 
 | 890 |  | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 891 |  private: | 
| Brian Carlstrom | 58ae941 | 2011-10-04 00:56:06 -0700 | [diff] [blame] | 892 |   // Opens a .dex file | 
| Ian Rogers | 8d31bbd | 2013-10-13 10:44:14 -0700 | [diff] [blame] | 893 |   static const DexFile* OpenFile(int fd, const char* location, bool verify, std::string* error_msg); | 
| Brian Carlstrom | 58ae941 | 2011-10-04 00:56:06 -0700 | [diff] [blame] | 894 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 895 |   // Opens dex files from within a .jar, .zip, or .apk file | 
 | 896 |   static bool OpenZip(int fd, const std::string& location, std::string* error_msg, | 
 | 897 |                       std::vector<const DexFile*>* dex_files); | 
 | 898 |  | 
 | 899 |   enum class ZipOpenErrorCode {  // private | 
 | 900 |     kNoError, | 
 | 901 |     kEntryNotFound, | 
 | 902 |     kExtractToMemoryError, | 
 | 903 |     kDexFileError, | 
 | 904 |     kMakeReadOnlyError, | 
 | 905 |     kVerifyError | 
 | 906 |   }; | 
 | 907 |  | 
 | 908 |   // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-nullptr | 
 | 909 |   // return. | 
 | 910 |   static const DexFile* Open(const ZipArchive& zip_archive, const char* entry_name, | 
 | 911 |                              const std::string& location, std::string* error_msg, | 
 | 912 |                              ZipOpenErrorCode* error_code); | 
| Brian Carlstrom | 58ae941 | 2011-10-04 00:56:06 -0700 | [diff] [blame] | 913 |  | 
| Brian Carlstrom | 8952189 | 2011-12-07 22:05:07 -0800 | [diff] [blame] | 914 |   // Opens a .dex file at the given address backed by a MemMap | 
 | 915 |   static const DexFile* OpenMemory(const std::string& location, | 
| Brian Carlstrom | 5b332c8 | 2012-02-01 15:02:31 -0800 | [diff] [blame] | 916 |                                    uint32_t location_checksum, | 
| Ian Rogers | 8d31bbd | 2013-10-13 10:44:14 -0700 | [diff] [blame] | 917 |                                    MemMap* mem_map, | 
 | 918 |                                    std::string* error_msg); | 
| Brian Carlstrom | 8952189 | 2011-12-07 22:05:07 -0800 | [diff] [blame] | 919 |  | 
 | 920 |   // Opens a .dex file at the given address, optionally backed by a MemMap | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 921 |   static const DexFile* OpenMemory(const uint8_t* dex_file, | 
| jeffhao | f6174e8 | 2012-01-31 16:14:17 -0800 | [diff] [blame] | 922 |                                    size_t size, | 
| Brian Carlstrom | 58ae941 | 2011-10-04 00:56:06 -0700 | [diff] [blame] | 923 |                                    const std::string& location, | 
| Brian Carlstrom | 5b332c8 | 2012-02-01 15:02:31 -0800 | [diff] [blame] | 924 |                                    uint32_t location_checksum, | 
| Ian Rogers | 8d31bbd | 2013-10-13 10:44:14 -0700 | [diff] [blame] | 925 |                                    MemMap* mem_map, | 
 | 926 |                                    std::string* error_msg); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 927 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 928 |   DexFile(const uint8_t* base, size_t size, | 
| Brian Carlstrom | 28db012 | 2012-10-18 16:20:41 -0700 | [diff] [blame] | 929 |           const std::string& location, | 
 | 930 |           uint32_t location_checksum, | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 931 |           MemMap* mem_map); | 
| jeffhao | f6174e8 | 2012-01-31 16:14:17 -0800 | [diff] [blame] | 932 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 933 |   // Top-level initializer that calls other Init methods. | 
| Ian Rogers | 8d31bbd | 2013-10-13 10:44:14 -0700 | [diff] [blame] | 934 |   bool Init(std::string* error_msg); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 935 |  | 
| Brian Carlstrom | 6e3b1d9 | 2012-01-11 01:36:32 -0800 | [diff] [blame] | 936 |   // Returns true if the header magic and version numbers are of the expected values. | 
| Ian Rogers | 8d31bbd | 2013-10-13 10:44:14 -0700 | [diff] [blame] | 937 |   bool CheckMagicAndVersion(std::string* error_msg) const; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 938 |  | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 939 |   void DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx, | 
| Elliott Hughes | 2435a57 | 2012-02-17 16:07:41 -0800 | [diff] [blame] | 940 |       DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb, | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 941 |       void* context, const uint8_t* stream, LocalInfo* local_in_reg) const; | 
| Elliott Hughes | 03181a8 | 2011-11-17 17:22:21 -0800 | [diff] [blame] | 942 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 943 |   // Check whether a location denotes a multidex dex file. This is a very simple check: returns | 
 | 944 |   // whether the string contains the separator character. | 
 | 945 |   static bool IsMultiDexLocation(const char* location); | 
 | 946 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 947 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 948 |   // The base address of the memory mapping. | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 949 |   const uint8_t* const begin_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 950 |  | 
 | 951 |   // The size of the underlying memory allocation in bytes. | 
| Ian Rogers | 62d6c77 | 2013-02-27 08:32:07 -0800 | [diff] [blame] | 952 |   const size_t size_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 953 |  | 
| Elliott Hughes | 64bf5a3 | 2011-09-20 14:43:12 -0700 | [diff] [blame] | 954 |   // Typically the dex file name when available, alternatively some identifying string. | 
| Brian Carlstrom | a663ea5 | 2011-08-19 23:33:41 -0700 | [diff] [blame] | 955 |   // | 
 | 956 |   // The ClassLinker will use this to match DexFiles the boot class | 
 | 957 |   // path to DexCache::GetLocation when loading from an image. | 
 | 958 |   const std::string location_; | 
 | 959 |  | 
| Brian Carlstrom | 5b332c8 | 2012-02-01 15:02:31 -0800 | [diff] [blame] | 960 |   const uint32_t location_checksum_; | 
 | 961 |  | 
| Brian Carlstrom | 33f741e | 2011-10-03 11:24:05 -0700 | [diff] [blame] | 962 |   // Manages the underlying memory allocation. | 
| Ian Rogers | 700a402 | 2014-05-19 16:49:03 -0700 | [diff] [blame] | 963 |   std::unique_ptr<MemMap> mem_map_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 964 |  | 
 | 965 |   // Points to the header section. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 966 |   const Header* const header_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 967 |  | 
 | 968 |   // Points to the base of the string identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 969 |   const StringId* const string_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 970 |  | 
 | 971 |   // Points to the base of the type identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 972 |   const TypeId* const type_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 973 |  | 
 | 974 |   // Points to the base of the field identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 975 |   const FieldId* const field_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 976 |  | 
 | 977 |   // Points to the base of the method identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 978 |   const MethodId* const method_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 979 |  | 
 | 980 |   // Points to the base of the prototype identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 981 |   const ProtoId* const proto_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 982 |  | 
 | 983 |   // Points to the base of the class definition list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 984 |   const ClassDef* const class_defs_; | 
| Ian Rogers | 68b5685 | 2014-08-29 20:19:11 -0700 | [diff] [blame] | 985 |  | 
 | 986 |   // Number of misses finding a class def from a descriptor. | 
 | 987 |   mutable Atomic<uint32_t> find_class_def_misses_; | 
 | 988 |  | 
 | 989 |   struct UTF16HashCmp { | 
 | 990 |     // Hash function. | 
 | 991 |     size_t operator()(const char* key) const { | 
 | 992 |       return ComputeUtf8Hash(key); | 
 | 993 |     } | 
 | 994 |     // std::equal function. | 
 | 995 |     bool operator()(const char* a, const char* b) const { | 
 | 996 |       return CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(a, b) == 0; | 
 | 997 |     } | 
 | 998 |   }; | 
 | 999 |   typedef std::unordered_map<const char*, const ClassDef*, UTF16HashCmp, UTF16HashCmp> Index; | 
 | 1000 |   mutable Atomic<Index*> class_def_index_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 1001 | }; | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 1002 | std::ostream& operator<<(std::ostream& os, const DexFile& dex_file); | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 1003 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1004 | // Iterate over a dex file's ProtoId's paramters | 
 | 1005 | class DexFileParameterIterator { | 
 | 1006 |  public: | 
 | 1007 |   DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id) | 
 | 1008 |       : dex_file_(dex_file), size_(0), pos_(0) { | 
 | 1009 |     type_list_ = dex_file_.GetProtoParameters(proto_id); | 
 | 1010 |     if (type_list_ != NULL) { | 
 | 1011 |       size_ = type_list_->Size(); | 
 | 1012 |     } | 
 | 1013 |   } | 
 | 1014 |   bool HasNext() const { return pos_ < size_; } | 
 | 1015 |   void Next() { ++pos_; } | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 1016 |   uint16_t GetTypeIdx() { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1017 |     return type_list_->GetTypeItem(pos_).type_idx_; | 
 | 1018 |   } | 
 | 1019 |   const char* GetDescriptor() { | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 1020 |     return dex_file_.StringByTypeIdx(GetTypeIdx()); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1021 |   } | 
 | 1022 |  private: | 
 | 1023 |   const DexFile& dex_file_; | 
 | 1024 |   const DexFile::TypeList* type_list_; | 
 | 1025 |   uint32_t size_; | 
 | 1026 |   uint32_t pos_; | 
 | 1027 |   DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator); | 
 | 1028 | }; | 
 | 1029 |  | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 1030 | // Abstract the signature of a method. | 
| Ian Rogers | 03b6eaf | 2014-10-28 09:34:57 -0700 | [diff] [blame] | 1031 | class Signature : public ValueObject { | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 1032 |  public: | 
 | 1033 |   std::string ToString() const; | 
 | 1034 |  | 
 | 1035 |   static Signature NoSignature() { | 
 | 1036 |     return Signature(); | 
 | 1037 |   } | 
 | 1038 |  | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 1039 |   bool operator==(const Signature& rhs) const; | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 1040 |   bool operator!=(const Signature& rhs) const { | 
 | 1041 |     return !(*this == rhs); | 
 | 1042 |   } | 
 | 1043 |  | 
| Vladimir Marko | d9cffea | 2013-11-25 15:08:02 +0000 | [diff] [blame] | 1044 |   bool operator==(const StringPiece& rhs) const; | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 1045 |  | 
 | 1046 |  private: | 
 | 1047 |   Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) { | 
 | 1048 |   } | 
 | 1049 |  | 
 | 1050 |   Signature() : dex_file_(nullptr), proto_id_(nullptr) { | 
 | 1051 |   } | 
 | 1052 |  | 
 | 1053 |   friend class DexFile; | 
 | 1054 |  | 
 | 1055 |   const DexFile* const dex_file_; | 
 | 1056 |   const DexFile::ProtoId* const proto_id_; | 
 | 1057 | }; | 
 | 1058 | std::ostream& operator<<(std::ostream& os, const Signature& sig); | 
 | 1059 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1060 | // Iterate and decode class_data_item | 
 | 1061 | class ClassDataItemIterator { | 
 | 1062 |  public: | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1063 |   ClassDataItemIterator(const DexFile& dex_file, const uint8_t* raw_class_data_item) | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1064 |       : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) { | 
 | 1065 |     ReadClassDataHeader(); | 
 | 1066 |     if (EndOfInstanceFieldsPos() > 0) { | 
 | 1067 |       ReadClassDataField(); | 
 | 1068 |     } else if (EndOfVirtualMethodsPos() > 0) { | 
 | 1069 |       ReadClassDataMethod(); | 
 | 1070 |     } | 
 | 1071 |   } | 
 | 1072 |   uint32_t NumStaticFields() const { | 
 | 1073 |     return header_.static_fields_size_; | 
 | 1074 |   } | 
 | 1075 |   uint32_t NumInstanceFields() const { | 
 | 1076 |     return header_.instance_fields_size_; | 
 | 1077 |   } | 
 | 1078 |   uint32_t NumDirectMethods() const { | 
 | 1079 |     return header_.direct_methods_size_; | 
 | 1080 |   } | 
 | 1081 |   uint32_t NumVirtualMethods() const { | 
 | 1082 |     return header_.virtual_methods_size_; | 
 | 1083 |   } | 
 | 1084 |   bool HasNextStaticField() const { | 
 | 1085 |     return pos_ < EndOfStaticFieldsPos(); | 
 | 1086 |   } | 
 | 1087 |   bool HasNextInstanceField() const { | 
 | 1088 |     return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos(); | 
 | 1089 |   } | 
 | 1090 |   bool HasNextDirectMethod() const { | 
 | 1091 |     return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos(); | 
 | 1092 |   } | 
 | 1093 |   bool HasNextVirtualMethod() const { | 
 | 1094 |     return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos(); | 
 | 1095 |   } | 
 | 1096 |   bool HasNext() const { | 
 | 1097 |     return pos_ < EndOfVirtualMethodsPos(); | 
 | 1098 |   } | 
| Ian Rogers | 637c65b | 2013-05-31 11:46:00 -0700 | [diff] [blame] | 1099 |   inline void Next() { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1100 |     pos_++; | 
 | 1101 |     if (pos_ < EndOfStaticFieldsPos()) { | 
 | 1102 |       last_idx_ = GetMemberIndex(); | 
 | 1103 |       ReadClassDataField(); | 
 | 1104 |     } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) { | 
 | 1105 |       last_idx_ = 0;  // transition to next array, reset last index | 
 | 1106 |       ReadClassDataField(); | 
 | 1107 |     } else if (pos_ < EndOfInstanceFieldsPos()) { | 
 | 1108 |       last_idx_ = GetMemberIndex(); | 
 | 1109 |       ReadClassDataField(); | 
 | 1110 |     } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) { | 
 | 1111 |       last_idx_ = 0;  // transition to next array, reset last index | 
 | 1112 |       ReadClassDataMethod(); | 
 | 1113 |     } else if (pos_ < EndOfDirectMethodsPos()) { | 
 | 1114 |       last_idx_ = GetMemberIndex(); | 
 | 1115 |       ReadClassDataMethod(); | 
 | 1116 |     } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) { | 
 | 1117 |       last_idx_ = 0;  // transition to next array, reset last index | 
 | 1118 |       ReadClassDataMethod(); | 
 | 1119 |     } else if (pos_ < EndOfVirtualMethodsPos()) { | 
 | 1120 |       last_idx_ = GetMemberIndex(); | 
 | 1121 |       ReadClassDataMethod(); | 
 | 1122 |     } else { | 
 | 1123 |       DCHECK(!HasNext()); | 
 | 1124 |     } | 
 | 1125 |   } | 
 | 1126 |   uint32_t GetMemberIndex() const { | 
 | 1127 |     if (pos_ < EndOfInstanceFieldsPos()) { | 
 | 1128 |       return last_idx_ + field_.field_idx_delta_; | 
 | 1129 |     } else { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 1130 |       DCHECK_LT(pos_, EndOfVirtualMethodsPos()); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1131 |       return last_idx_ + method_.method_idx_delta_; | 
 | 1132 |     } | 
 | 1133 |   } | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1134 |   uint32_t GetRawMemberAccessFlags() const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1135 |     if (pos_ < EndOfInstanceFieldsPos()) { | 
 | 1136 |       return field_.access_flags_; | 
 | 1137 |     } else { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 1138 |       DCHECK_LT(pos_, EndOfVirtualMethodsPos()); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1139 |       return method_.access_flags_; | 
 | 1140 |     } | 
 | 1141 |   } | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1142 |   uint32_t GetFieldAccessFlags() const { | 
 | 1143 |     return GetRawMemberAccessFlags() & kAccValidFieldFlags; | 
 | 1144 |   } | 
 | 1145 |   uint32_t GetMethodAccessFlags() const { | 
 | 1146 |     return GetRawMemberAccessFlags() & kAccValidMethodFlags; | 
 | 1147 |   } | 
 | 1148 |   bool MemberIsNative() const { | 
 | 1149 |     return GetRawMemberAccessFlags() & kAccNative; | 
 | 1150 |   } | 
 | 1151 |   bool MemberIsFinal() const { | 
 | 1152 |     return GetRawMemberAccessFlags() & kAccFinal; | 
 | 1153 |   } | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 1154 |   InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const { | 
 | 1155 |     if (HasNextDirectMethod()) { | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1156 |       if ((GetRawMemberAccessFlags() & kAccStatic) != 0) { | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 1157 |         return kStatic; | 
 | 1158 |       } else { | 
 | 1159 |         return kDirect; | 
 | 1160 |       } | 
 | 1161 |     } else { | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1162 |       DCHECK_EQ(GetRawMemberAccessFlags() & kAccStatic, 0U); | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 1163 |       if ((class_def.access_flags_ & kAccInterface) != 0) { | 
 | 1164 |         return kInterface; | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1165 |       } else if ((GetRawMemberAccessFlags() & kAccConstructor) != 0) { | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 1166 |         return kSuper; | 
 | 1167 |       } else { | 
 | 1168 |         return kVirtual; | 
 | 1169 |       } | 
 | 1170 |     } | 
 | 1171 |   } | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1172 |   const DexFile::CodeItem* GetMethodCodeItem() const { | 
 | 1173 |     return dex_file_.GetCodeItem(method_.code_off_); | 
 | 1174 |   } | 
 | 1175 |   uint32_t GetMethodCodeItemOffset() const { | 
 | 1176 |     return method_.code_off_; | 
 | 1177 |   } | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1178 |   const uint8_t* EndDataPointer() const { | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 1179 |     CHECK(!HasNext()); | 
 | 1180 |     return ptr_pos_; | 
 | 1181 |   } | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1182 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1183 |  private: | 
 | 1184 |   // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the | 
 | 1185 |   // header for a class_data_item | 
 | 1186 |   struct ClassDataHeader { | 
 | 1187 |     uint32_t static_fields_size_;  // the number of static fields | 
 | 1188 |     uint32_t instance_fields_size_;  // the number of instance fields | 
 | 1189 |     uint32_t direct_methods_size_;  // the number of direct methods | 
 | 1190 |     uint32_t virtual_methods_size_;  // the number of virtual methods | 
 | 1191 |   } header_; | 
 | 1192 |  | 
 | 1193 |   // Read and decode header from a class_data_item stream into header | 
 | 1194 |   void ReadClassDataHeader(); | 
 | 1195 |  | 
 | 1196 |   uint32_t EndOfStaticFieldsPos() const { | 
 | 1197 |     return header_.static_fields_size_; | 
 | 1198 |   } | 
 | 1199 |   uint32_t EndOfInstanceFieldsPos() const { | 
 | 1200 |     return EndOfStaticFieldsPos() + header_.instance_fields_size_; | 
 | 1201 |   } | 
 | 1202 |   uint32_t EndOfDirectMethodsPos() const { | 
 | 1203 |     return EndOfInstanceFieldsPos() + header_.direct_methods_size_; | 
 | 1204 |   } | 
 | 1205 |   uint32_t EndOfVirtualMethodsPos() const { | 
 | 1206 |     return EndOfDirectMethodsPos() + header_.virtual_methods_size_; | 
 | 1207 |   } | 
 | 1208 |  | 
 | 1209 |   // A decoded version of the field of a class_data_item | 
 | 1210 |   struct ClassDataField { | 
 | 1211 |     uint32_t field_idx_delta_;  // delta of index into the field_ids array for FieldId | 
 | 1212 |     uint32_t access_flags_;  // access flags for the field | 
 | 1213 |     ClassDataField() :  field_idx_delta_(0), access_flags_(0) {} | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1214 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1215 |    private: | 
 | 1216 |     DISALLOW_COPY_AND_ASSIGN(ClassDataField); | 
| Elliott Hughes | ee0fa76 | 2012-03-26 17:12:41 -0700 | [diff] [blame] | 1217 |   }; | 
 | 1218 |   ClassDataField field_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1219 |  | 
 | 1220 |   // Read and decode a field from a class_data_item stream into field | 
 | 1221 |   void ReadClassDataField(); | 
 | 1222 |  | 
 | 1223 |   // A decoded version of the method of a class_data_item | 
 | 1224 |   struct ClassDataMethod { | 
 | 1225 |     uint32_t method_idx_delta_;  // delta of index into the method_ids array for MethodId | 
 | 1226 |     uint32_t access_flags_; | 
 | 1227 |     uint32_t code_off_; | 
 | 1228 |     ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {} | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1229 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1230 |    private: | 
 | 1231 |     DISALLOW_COPY_AND_ASSIGN(ClassDataMethod); | 
| Elliott Hughes | ee0fa76 | 2012-03-26 17:12:41 -0700 | [diff] [blame] | 1232 |   }; | 
 | 1233 |   ClassDataMethod method_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1234 |  | 
 | 1235 |   // Read and decode a method from a class_data_item stream into method | 
 | 1236 |   void ReadClassDataMethod(); | 
 | 1237 |  | 
 | 1238 |   const DexFile& dex_file_; | 
 | 1239 |   size_t pos_;  // integral number of items passed | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1240 |   const uint8_t* ptr_pos_;  // pointer into stream of class_data_item | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1241 |   uint32_t last_idx_;  // last read field or method index to apply delta to | 
 | 1242 |   DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator); | 
 | 1243 | }; | 
 | 1244 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1245 | class EncodedStaticFieldValueIterator { | 
 | 1246 |  public: | 
| Mathieu Chartier | eb8167a | 2014-05-07 15:43:14 -0700 | [diff] [blame] | 1247 |   EncodedStaticFieldValueIterator(const DexFile& dex_file, Handle<mirror::DexCache>* dex_cache, | 
 | 1248 |                                   Handle<mirror::ClassLoader>* class_loader, | 
| Ian Rogers | 00f7d0e | 2012-07-19 15:28:27 -0700 | [diff] [blame] | 1249 |                                   ClassLinker* linker, const DexFile::ClassDef& class_def) | 
| Ian Rogers | b726dcb | 2012-09-05 08:57:23 -0700 | [diff] [blame] | 1250 |       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1251 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 1252 |   template<bool kTransactionActive> | 
| Hiroshi Yamauchi | 67ef46a | 2014-08-21 15:59:43 -0700 | [diff] [blame] | 1253 |   void ReadValueToField(Handle<mirror::ArtField> field) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1254 |  | 
| Ian Rogers | 6a3c1fc | 2014-10-31 00:33:20 -0700 | [diff] [blame] | 1255 |   bool HasNext() const { return pos_ < array_size_; } | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1256 |  | 
 | 1257 |   void Next(); | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1258 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1259 |   enum ValueType { | 
 | 1260 |     kByte = 0x00, | 
 | 1261 |     kShort = 0x02, | 
 | 1262 |     kChar = 0x03, | 
 | 1263 |     kInt = 0x04, | 
 | 1264 |     kLong = 0x06, | 
 | 1265 |     kFloat = 0x10, | 
 | 1266 |     kDouble = 0x11, | 
 | 1267 |     kString = 0x17, | 
 | 1268 |     kType = 0x18, | 
 | 1269 |     kField = 0x19, | 
 | 1270 |     kMethod = 0x1a, | 
 | 1271 |     kEnum = 0x1b, | 
 | 1272 |     kArray = 0x1c, | 
 | 1273 |     kAnnotation = 0x1d, | 
 | 1274 |     kNull = 0x1e, | 
 | 1275 |     kBoolean = 0x1f | 
 | 1276 |   }; | 
 | 1277 |  | 
| Brian Carlstrom | 88f3654 | 2012-10-16 23:24:21 -0700 | [diff] [blame] | 1278 |  private: | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1279 |   static constexpr uint8_t kEncodedValueTypeMask = 0x1f;  // 0b11111 | 
 | 1280 |   static constexpr uint8_t kEncodedValueArgShift = 5; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1281 |  | 
 | 1282 |   const DexFile& dex_file_; | 
| Mathieu Chartier | eb8167a | 2014-05-07 15:43:14 -0700 | [diff] [blame] | 1283 |   Handle<mirror::DexCache>* const dex_cache_;  // Dex cache to resolve literal objects. | 
 | 1284 |   Handle<mirror::ClassLoader>* const class_loader_;  // ClassLoader to resolve types. | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 1285 |   ClassLinker* linker_;  // Linker to resolve literal objects. | 
 | 1286 |   size_t array_size_;  // Size of array. | 
 | 1287 |   size_t pos_;  // Current position. | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1288 |   const uint8_t* ptr_;  // Pointer into encoded data array. | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 1289 |   ValueType type_;  // Type of current encoded value. | 
 | 1290 |   jvalue jval_;  // Value of current encoded value. | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1291 |   DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator); | 
 | 1292 | }; | 
| Brian Carlstrom | 88f3654 | 2012-10-16 23:24:21 -0700 | [diff] [blame] | 1293 | std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1294 |  | 
 | 1295 | class CatchHandlerIterator { | 
 | 1296 |   public: | 
 | 1297 |     CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address); | 
| Logan Chien | 736df02 | 2012-04-27 16:25:57 +0800 | [diff] [blame] | 1298 |  | 
 | 1299 |     CatchHandlerIterator(const DexFile::CodeItem& code_item, | 
 | 1300 |                          const DexFile::TryItem& try_item); | 
 | 1301 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1302 |     explicit CatchHandlerIterator(const uint8_t* handler_data) { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1303 |       Init(handler_data); | 
 | 1304 |     } | 
 | 1305 |  | 
 | 1306 |     uint16_t GetHandlerTypeIndex() const { | 
 | 1307 |       return handler_.type_idx_; | 
 | 1308 |     } | 
 | 1309 |     uint32_t GetHandlerAddress() const { | 
 | 1310 |       return handler_.address_; | 
 | 1311 |     } | 
 | 1312 |     void Next(); | 
 | 1313 |     bool HasNext() const { | 
 | 1314 |       return remaining_count_ != -1 || catch_all_; | 
 | 1315 |     } | 
 | 1316 |     // End of this set of catch blocks, convenience method to locate next set of catch blocks | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1317 |     const uint8_t* EndDataPointer() const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1318 |       CHECK(!HasNext()); | 
 | 1319 |       return current_data_; | 
 | 1320 |     } | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1321 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1322 |   private: | 
| Logan Chien | 736df02 | 2012-04-27 16:25:57 +0800 | [diff] [blame] | 1323 |     void Init(const DexFile::CodeItem& code_item, int32_t offset); | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1324 |     void Init(const uint8_t* handler_data); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1325 |  | 
 | 1326 |     struct CatchHandlerItem { | 
 | 1327 |       uint16_t type_idx_;  // type index of the caught exception type | 
 | 1328 |       uint32_t address_;  // handler address | 
 | 1329 |     } handler_; | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1330 |     const uint8_t* current_data_;  // the current handler in dex file. | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1331 |     int32_t remaining_count_;   // number of handlers not read. | 
 | 1332 |     bool catch_all_;            // is there a handler that will catch all exceptions in case | 
 | 1333 |                                 // that all typed handler does not match. | 
 | 1334 | }; | 
 | 1335 |  | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 1336 | }  // namespace art | 
 | 1337 |  | 
| Brian Carlstrom | fc0e321 | 2013-07-17 14:40:12 -0700 | [diff] [blame] | 1338 | #endif  // ART_RUNTIME_DEX_FILE_H_ |