| 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> | 
| Brian Carlstrom | 74eb46a | 2011-08-02 20:10:14 -0700 | [diff] [blame] | 22 | #include <vector> | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 23 |  | 
| Elliott Hughes | 07ed66b | 2012-12-12 18:34:25 -0800 | [diff] [blame] | 24 | #include "base/logging.h" | 
| Ian Rogers | b0fa5dc | 2014-04-28 16:47:08 -0700 | [diff] [blame] | 25 | #include "base/mutex.h"  // For Locks::mutator_lock_. | 
| Ian Rogers | 03b6eaf | 2014-10-28 09:34:57 -0700 | [diff] [blame] | 26 | #include "base/value_object.h" | 
| Brian Carlstrom | 578bbdc | 2011-07-21 14:07:47 -0700 | [diff] [blame] | 27 | #include "globals.h" | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 28 | #include "invoke_type.h" | 
| Jesse Wilson | 6bf1915 | 2011-09-29 13:12:33 -0400 | [diff] [blame] | 29 | #include "jni.h" | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 30 | #include "mirror/object_array.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 ClassLoader; | 
|  | 40 | class DexCache; | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 41 | }  // namespace mirror | 
| Mathieu Chartier | c785344 | 2015-03-27 14:35:38 -0700 | [diff] [blame] | 42 | class ArtField; | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 43 | class ArtMethod; | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 44 | class ClassLinker; | 
| Andreas Gampe | 2a5c468 | 2015-08-14 08:22:54 -0700 | [diff] [blame] | 45 | template <class Key, class Value, class EmptyFn, class HashFn, class Pred, class Alloc> | 
|  | 46 | class HashMap; | 
| Ian Rogers | 576ca0c | 2014-06-06 15:58:22 -0700 | [diff] [blame] | 47 | class MemMap; | 
| Richard Uhler | 07b3c23 | 2015-03-31 15:57:54 -0700 | [diff] [blame] | 48 | class OatDexFile; | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 49 | class Signature; | 
| Mathieu Chartier | eb8167a | 2014-05-07 15:43:14 -0700 | [diff] [blame] | 50 | template<class T> class Handle; | 
| Ian Rogers | fc0e94b | 2013-09-23 23:51:32 -0700 | [diff] [blame] | 51 | class StringPiece; | 
| Artem Udovichenko | d9786b0 | 2015-10-14 16:36:55 +0300 | [diff] [blame] | 52 | class TypeLookupTable; | 
| Brian Carlstrom | a6cc893 | 2012-01-04 14:44:07 -0800 | [diff] [blame] | 53 | class ZipArchive; | 
|  | 54 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 55 | // TODO: move all of the macro functionality into the DexCache class. | 
| Brian Carlstrom | f615a61 | 2011-07-23 12:50:34 -0700 | [diff] [blame] | 56 | class DexFile { | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 57 | public: | 
| Roland Levillain | 621b5ea | 2016-05-18 11:41:33 +0100 | [diff] [blame] | 58 | // First Dex format version supporting default methods. | 
| Alex Light | b55f1ac | 2016-04-12 15:50:55 -0700 | [diff] [blame] | 59 | static const uint32_t kDefaultMethodsVersion = 37; | 
| Roland Levillain | 621b5ea | 2016-05-18 11:41:33 +0100 | [diff] [blame] | 60 | // First Dex format version enforcing class definition ordering rules. | 
|  | 61 | static const uint32_t kClassDefinitionOrderEnforcedVersion = 37; | 
|  | 62 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 63 | static const uint8_t kDexMagic[]; | 
| Narayan Kamath | 52e6650 | 2016-08-01 14:20:31 +0100 | [diff] [blame] | 64 | static constexpr size_t kNumDexVersions = 3; | 
| Alex Light | c496181 | 2016-03-23 10:20:41 -0700 | [diff] [blame] | 65 | static constexpr size_t kDexVersionLen = 4; | 
|  | 66 | static const uint8_t kDexMagicVersions[kNumDexVersions][kDexVersionLen]; | 
|  | 67 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 68 | static constexpr size_t kSha1DigestSize = 20; | 
|  | 69 | static constexpr uint32_t kDexEndianConstant = 0x12345678; | 
| Carl Shapiro | 80d4dde | 2011-06-28 16:24:07 -0700 | [diff] [blame] | 70 |  | 
| Brian Carlstrom | b7bbba4 | 2011-10-13 14:58:47 -0700 | [diff] [blame] | 71 | // name of the DexFile entry within a zip archive | 
|  | 72 | static const char* kClassesDex; | 
|  | 73 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 74 | // The value of an invalid index. | 
|  | 75 | static const uint32_t kDexNoIndex = 0xFFFFFFFF; | 
|  | 76 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 77 | // The value of an invalid index. | 
|  | 78 | static const uint16_t kDexNoIndex16 = 0xFFFF; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 79 |  | 
| Alex Light | c496181 | 2016-03-23 10:20:41 -0700 | [diff] [blame] | 80 | // The separator character in MultiDex locations. | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 81 | static constexpr char kMultiDexSeparator = ':'; | 
|  | 82 |  | 
|  | 83 | // A string version of the previous. This is a define so that we can merge string literals in the | 
|  | 84 | // preprocessor. | 
|  | 85 | #define kMultiDexSeparatorString ":" | 
|  | 86 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 87 | // Raw header_item. | 
|  | 88 | struct Header { | 
|  | 89 | uint8_t magic_[8]; | 
| Brian Carlstrom | 7934ac2 | 2013-07-26 10:54:15 -0700 | [diff] [blame] | 90 | uint32_t checksum_;  // See also location_checksum_ | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 91 | uint8_t signature_[kSha1DigestSize]; | 
| jeffhao | f6174e8 | 2012-01-31 16:14:17 -0800 | [diff] [blame] | 92 | uint32_t file_size_;  // size of entire file | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 93 | uint32_t header_size_;  // offset to start of next section | 
|  | 94 | uint32_t endian_tag_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 95 | uint32_t link_size_;  // unused | 
|  | 96 | uint32_t link_off_;  // unused | 
|  | 97 | uint32_t map_off_;  // unused | 
|  | 98 | uint32_t string_ids_size_;  // number of StringIds | 
|  | 99 | uint32_t string_ids_off_;  // file offset of StringIds array | 
|  | 100 | uint32_t type_ids_size_;  // number of TypeIds, we don't support more than 65535 | 
|  | 101 | uint32_t type_ids_off_;  // file offset of TypeIds array | 
|  | 102 | uint32_t proto_ids_size_;  // number of ProtoIds, we don't support more than 65535 | 
|  | 103 | uint32_t proto_ids_off_;  // file offset of ProtoIds array | 
|  | 104 | uint32_t field_ids_size_;  // number of FieldIds | 
|  | 105 | uint32_t field_ids_off_;  // file offset of FieldIds array | 
|  | 106 | uint32_t method_ids_size_;  // number of MethodIds | 
|  | 107 | uint32_t method_ids_off_;  // file offset of MethodIds array | 
|  | 108 | uint32_t class_defs_size_;  // number of ClassDefs | 
|  | 109 | uint32_t class_defs_off_;  // file offset of ClassDef array | 
|  | 110 | uint32_t data_size_;  // unused | 
|  | 111 | uint32_t data_off_;  // unused | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 112 |  | 
| Andreas Gampe | 76ed99d | 2016-03-28 18:31:29 -0700 | [diff] [blame] | 113 | // Decode the dex magic version | 
|  | 114 | uint32_t GetVersion() const; | 
|  | 115 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 116 | private: | 
|  | 117 | DISALLOW_COPY_AND_ASSIGN(Header); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 118 | }; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 119 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 120 | // Map item type codes. | 
|  | 121 | enum { | 
|  | 122 | kDexTypeHeaderItem               = 0x0000, | 
|  | 123 | kDexTypeStringIdItem             = 0x0001, | 
|  | 124 | kDexTypeTypeIdItem               = 0x0002, | 
|  | 125 | kDexTypeProtoIdItem              = 0x0003, | 
|  | 126 | kDexTypeFieldIdItem              = 0x0004, | 
|  | 127 | kDexTypeMethodIdItem             = 0x0005, | 
|  | 128 | kDexTypeClassDefItem             = 0x0006, | 
|  | 129 | kDexTypeMapList                  = 0x1000, | 
|  | 130 | kDexTypeTypeList                 = 0x1001, | 
|  | 131 | kDexTypeAnnotationSetRefList     = 0x1002, | 
|  | 132 | kDexTypeAnnotationSetItem        = 0x1003, | 
|  | 133 | kDexTypeClassDataItem            = 0x2000, | 
|  | 134 | kDexTypeCodeItem                 = 0x2001, | 
|  | 135 | kDexTypeStringDataItem           = 0x2002, | 
|  | 136 | kDexTypeDebugInfoItem            = 0x2003, | 
|  | 137 | kDexTypeAnnotationItem           = 0x2004, | 
|  | 138 | kDexTypeEncodedArrayItem         = 0x2005, | 
|  | 139 | kDexTypeAnnotationsDirectoryItem = 0x2006, | 
|  | 140 | }; | 
|  | 141 |  | 
|  | 142 | struct MapItem { | 
|  | 143 | uint16_t type_; | 
|  | 144 | uint16_t unused_; | 
|  | 145 | uint32_t size_; | 
|  | 146 | uint32_t offset_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 147 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 148 | private: | 
|  | 149 | DISALLOW_COPY_AND_ASSIGN(MapItem); | 
|  | 150 | }; | 
|  | 151 |  | 
|  | 152 | struct MapList { | 
|  | 153 | uint32_t size_; | 
|  | 154 | MapItem list_[1]; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 155 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 156 | private: | 
|  | 157 | DISALLOW_COPY_AND_ASSIGN(MapList); | 
|  | 158 | }; | 
|  | 159 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 160 | // Raw string_id_item. | 
|  | 161 | struct StringId { | 
|  | 162 | uint32_t string_data_off_;  // offset in bytes from the base address | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 163 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 164 | private: | 
|  | 165 | DISALLOW_COPY_AND_ASSIGN(StringId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 166 | }; | 
|  | 167 |  | 
|  | 168 | // Raw type_id_item. | 
|  | 169 | struct TypeId { | 
|  | 170 | uint32_t descriptor_idx_;  // index into string_ids | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 171 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 172 | private: | 
|  | 173 | DISALLOW_COPY_AND_ASSIGN(TypeId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 174 | }; | 
|  | 175 |  | 
|  | 176 | // Raw field_id_item. | 
|  | 177 | struct FieldId { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 178 | uint16_t class_idx_;  // index into type_ids_ array for defining class | 
|  | 179 | uint16_t type_idx_;  // index into type_ids_ array for field type | 
|  | 180 | uint32_t name_idx_;  // index into string_ids_ array for field name | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 181 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 182 | private: | 
|  | 183 | DISALLOW_COPY_AND_ASSIGN(FieldId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 184 | }; | 
|  | 185 |  | 
|  | 186 | // Raw method_id_item. | 
|  | 187 | struct MethodId { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 188 | uint16_t class_idx_;  // index into type_ids_ array for defining class | 
|  | 189 | uint16_t proto_idx_;  // index into proto_ids_ array for method prototype | 
|  | 190 | uint32_t name_idx_;  // index into string_ids_ array for method name | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 191 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 192 | private: | 
|  | 193 | DISALLOW_COPY_AND_ASSIGN(MethodId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 194 | }; | 
|  | 195 |  | 
|  | 196 | // Raw proto_id_item. | 
|  | 197 | struct ProtoId { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 198 | uint32_t shorty_idx_;  // index into string_ids array for shorty descriptor | 
|  | 199 | uint16_t return_type_idx_;  // index into type_ids array for return type | 
|  | 200 | uint16_t pad_;             // padding = 0 | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 201 | uint32_t parameters_off_;  // file offset to type_list for parameter types | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 202 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 203 | private: | 
|  | 204 | DISALLOW_COPY_AND_ASSIGN(ProtoId); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 205 | }; | 
|  | 206 |  | 
|  | 207 | // Raw class_def_item. | 
|  | 208 | struct ClassDef { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 209 | uint16_t class_idx_;  // index into type_ids_ array for this class | 
|  | 210 | uint16_t pad1_;  // padding = 0 | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 211 | uint32_t access_flags_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 212 | uint16_t superclass_idx_;  // index into type_ids_ array for superclass | 
|  | 213 | uint16_t pad2_;  // padding = 0 | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 214 | uint32_t interfaces_off_;  // file offset to TypeList | 
| Brian Carlstrom | 4a96b60 | 2011-07-26 16:40:23 -0700 | [diff] [blame] | 215 | 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] | 216 | uint32_t annotations_off_;  // file offset to annotations_directory_item | 
|  | 217 | uint32_t class_data_off_;  // file offset to class_data_item | 
|  | 218 | uint32_t static_values_off_;  // file offset to EncodedArray | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 219 |  | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 220 | // Returns the valid access flags, that is, Java modifier bits relevant to the ClassDef type | 
|  | 221 | // (class or interface). These are all in the lower 16b and do not contain runtime flags. | 
|  | 222 | uint32_t GetJavaAccessFlags() const { | 
|  | 223 | // Make sure that none of our runtime-only flags are set. | 
| Andreas Gampe | 575e78c | 2014-11-03 23:41:03 -0800 | [diff] [blame] | 224 | static_assert((kAccValidClassFlags & kAccJavaFlagsMask) == kAccValidClassFlags, | 
|  | 225 | "Valid class flags not a subset of Java flags"); | 
|  | 226 | static_assert((kAccValidInterfaceFlags & kAccJavaFlagsMask) == kAccValidInterfaceFlags, | 
|  | 227 | "Valid interface flags not a subset of Java flags"); | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 228 |  | 
|  | 229 | if ((access_flags_ & kAccInterface) != 0) { | 
|  | 230 | // Interface. | 
|  | 231 | return access_flags_ & kAccValidInterfaceFlags; | 
|  | 232 | } else { | 
|  | 233 | // Class. | 
|  | 234 | return access_flags_ & kAccValidClassFlags; | 
|  | 235 | } | 
|  | 236 | } | 
|  | 237 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 238 | private: | 
|  | 239 | DISALLOW_COPY_AND_ASSIGN(ClassDef); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 240 | }; | 
|  | 241 |  | 
|  | 242 | // Raw type_item. | 
|  | 243 | struct TypeItem { | 
|  | 244 | uint16_t type_idx_;  // index into type_ids section | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 245 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 246 | private: | 
|  | 247 | DISALLOW_COPY_AND_ASSIGN(TypeItem); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 248 | }; | 
|  | 249 |  | 
|  | 250 | // Raw type_list. | 
|  | 251 | class TypeList { | 
|  | 252 | public: | 
|  | 253 | uint32_t Size() const { | 
|  | 254 | return size_; | 
|  | 255 | } | 
|  | 256 |  | 
|  | 257 | const TypeItem& GetTypeItem(uint32_t idx) const { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 258 | DCHECK_LT(idx, this->size_); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 259 | return this->list_[idx]; | 
|  | 260 | } | 
|  | 261 |  | 
| Andreas Gampe | 31a7a0c | 2014-08-29 16:07:49 -0700 | [diff] [blame] | 262 | // Size in bytes of the part of the list that is common. | 
|  | 263 | static constexpr size_t GetHeaderSize() { | 
|  | 264 | return 4U; | 
|  | 265 | } | 
|  | 266 |  | 
|  | 267 | // Size in bytes of the whole type list including all the stored elements. | 
|  | 268 | static constexpr size_t GetListSize(size_t count) { | 
|  | 269 | return GetHeaderSize() + sizeof(TypeItem) * count; | 
|  | 270 | } | 
|  | 271 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 272 | private: | 
|  | 273 | uint32_t size_;  // size of the list, in entries | 
|  | 274 | TypeItem list_[1];  // elements of the list | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 275 | DISALLOW_COPY_AND_ASSIGN(TypeList); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 276 | }; | 
|  | 277 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 278 | // Raw code_item. | 
|  | 279 | struct CodeItem { | 
| Igor Murashkin | c449e8b | 2015-06-10 15:56:42 -0700 | [diff] [blame] | 280 | uint16_t registers_size_;            // the number of registers used by this code | 
|  | 281 | //   (locals + parameters) | 
|  | 282 | uint16_t ins_size_;                  // the number of words of incoming arguments to the method | 
|  | 283 | //   that this code is for | 
|  | 284 | uint16_t outs_size_;                 // the number of words of outgoing argument space required | 
|  | 285 | //   by this code for method invocation | 
|  | 286 | uint16_t tries_size_;                // the number of try_items for this instance. If non-zero, | 
|  | 287 | //   then these appear as the tries array just after the | 
|  | 288 | //   insns in this instance. | 
|  | 289 | uint32_t debug_info_off_;            // file offset to debug info stream | 
| Ian Rogers | d81871c | 2011-10-03 13:57:23 -0700 | [diff] [blame] | 290 | uint32_t insns_size_in_code_units_;  // size of the insns array, in 2 byte code units | 
| Igor Murashkin | c449e8b | 2015-06-10 15:56:42 -0700 | [diff] [blame] | 291 | uint16_t insns_[1];                  // actual array of bytecode. | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 292 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 293 | private: | 
|  | 294 | DISALLOW_COPY_AND_ASSIGN(CodeItem); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 295 | }; | 
|  | 296 |  | 
| Carl Shapiro | 2eaa968 | 2011-08-04 19:26:11 -0700 | [diff] [blame] | 297 | // Raw try_item. | 
|  | 298 | struct TryItem { | 
|  | 299 | uint32_t start_addr_; | 
|  | 300 | uint16_t insn_count_; | 
|  | 301 | uint16_t handler_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 302 |  | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 303 | private: | 
|  | 304 | DISALLOW_COPY_AND_ASSIGN(TryItem); | 
| Carl Shapiro | 2eaa968 | 2011-08-04 19:26:11 -0700 | [diff] [blame] | 305 | }; | 
|  | 306 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 307 | // Annotation constants. | 
|  | 308 | enum { | 
|  | 309 | kDexVisibilityBuild         = 0x00,     /* annotation visibility */ | 
|  | 310 | kDexVisibilityRuntime       = 0x01, | 
|  | 311 | kDexVisibilitySystem        = 0x02, | 
|  | 312 |  | 
|  | 313 | kDexAnnotationByte          = 0x00, | 
|  | 314 | kDexAnnotationShort         = 0x02, | 
|  | 315 | kDexAnnotationChar          = 0x03, | 
|  | 316 | kDexAnnotationInt           = 0x04, | 
|  | 317 | kDexAnnotationLong          = 0x06, | 
|  | 318 | kDexAnnotationFloat         = 0x10, | 
|  | 319 | kDexAnnotationDouble        = 0x11, | 
|  | 320 | kDexAnnotationString        = 0x17, | 
|  | 321 | kDexAnnotationType          = 0x18, | 
|  | 322 | kDexAnnotationField         = 0x19, | 
|  | 323 | kDexAnnotationMethod        = 0x1a, | 
|  | 324 | kDexAnnotationEnum          = 0x1b, | 
|  | 325 | kDexAnnotationArray         = 0x1c, | 
|  | 326 | kDexAnnotationAnnotation    = 0x1d, | 
|  | 327 | kDexAnnotationNull          = 0x1e, | 
|  | 328 | kDexAnnotationBoolean       = 0x1f, | 
|  | 329 |  | 
|  | 330 | kDexAnnotationValueTypeMask = 0x1f,     /* low 5 bits */ | 
|  | 331 | kDexAnnotationValueArgShift = 5, | 
|  | 332 | }; | 
|  | 333 |  | 
|  | 334 | struct AnnotationsDirectoryItem { | 
|  | 335 | uint32_t class_annotations_off_; | 
|  | 336 | uint32_t fields_size_; | 
|  | 337 | uint32_t methods_size_; | 
|  | 338 | uint32_t parameters_size_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 339 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 340 | private: | 
|  | 341 | DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem); | 
|  | 342 | }; | 
|  | 343 |  | 
|  | 344 | struct FieldAnnotationsItem { | 
|  | 345 | uint32_t field_idx_; | 
|  | 346 | uint32_t annotations_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 347 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 348 | private: | 
|  | 349 | DISALLOW_COPY_AND_ASSIGN(FieldAnnotationsItem); | 
|  | 350 | }; | 
|  | 351 |  | 
|  | 352 | struct MethodAnnotationsItem { | 
|  | 353 | uint32_t method_idx_; | 
|  | 354 | uint32_t annotations_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 355 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 356 | private: | 
|  | 357 | DISALLOW_COPY_AND_ASSIGN(MethodAnnotationsItem); | 
|  | 358 | }; | 
|  | 359 |  | 
|  | 360 | struct ParameterAnnotationsItem { | 
|  | 361 | uint32_t method_idx_; | 
|  | 362 | uint32_t annotations_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 363 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 364 | private: | 
|  | 365 | DISALLOW_COPY_AND_ASSIGN(ParameterAnnotationsItem); | 
|  | 366 | }; | 
|  | 367 |  | 
|  | 368 | struct AnnotationSetRefItem { | 
|  | 369 | uint32_t annotations_off_; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 370 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 371 | private: | 
|  | 372 | DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefItem); | 
|  | 373 | }; | 
|  | 374 |  | 
|  | 375 | struct AnnotationSetRefList { | 
|  | 376 | uint32_t size_; | 
|  | 377 | AnnotationSetRefItem list_[1]; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 378 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 379 | private: | 
|  | 380 | DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList); | 
|  | 381 | }; | 
|  | 382 |  | 
|  | 383 | struct AnnotationSetItem { | 
|  | 384 | uint32_t size_; | 
|  | 385 | uint32_t entries_[1]; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 386 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 387 | private: | 
|  | 388 | DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem); | 
|  | 389 | }; | 
|  | 390 |  | 
|  | 391 | struct AnnotationItem { | 
|  | 392 | uint8_t visibility_; | 
|  | 393 | uint8_t annotation_[1]; | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 394 |  | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 395 | private: | 
|  | 396 | DISALLOW_COPY_AND_ASSIGN(AnnotationItem); | 
|  | 397 | }; | 
|  | 398 |  | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 399 | enum AnnotationResultStyle {  // private | 
|  | 400 | kAllObjects, | 
|  | 401 | kPrimitivesOrObjects, | 
|  | 402 | kAllRaw | 
|  | 403 | }; | 
|  | 404 |  | 
| Brian Carlstrom | 5b332c8 | 2012-02-01 15:02:31 -0800 | [diff] [blame] | 405 | // Returns the checksum of a file for comparison with GetLocationChecksum(). | 
|  | 406 | // For .dex files, this is the header checksum. | 
|  | 407 | // For zip files, this is the classes.dex zip entry CRC32 checksum. | 
|  | 408 | // Return true if the checksum could be found, false otherwise. | 
| Ian Rogers | 8d31bbd | 2013-10-13 10:44:14 -0700 | [diff] [blame] | 409 | 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] | 410 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 411 | // Opens .dex files found in the container, guessing the container format based on file extension. | 
| Aart Bik | 37d6a3b | 2016-06-21 18:30:10 -0700 | [diff] [blame] | 412 | static bool Open(const char* filename, | 
|  | 413 | const char* location, | 
|  | 414 | bool verify_checksum, | 
|  | 415 | std::string* error_msg, | 
| Richard Uhler | fbef44d | 2014-12-23 09:48:51 -0800 | [diff] [blame] | 416 | std::vector<std::unique_ptr<const DexFile>>* dex_files); | 
| jeffhao | 262bf46 | 2011-10-20 18:36:32 -0700 | [diff] [blame] | 417 |  | 
| Brian Carlstrom | 8952189 | 2011-12-07 22:05:07 -0800 | [diff] [blame] | 418 | // Opens .dex file, backed by existing memory | 
| Richard Uhler | fbef44d | 2014-12-23 09:48:51 -0800 | [diff] [blame] | 419 | static std::unique_ptr<const DexFile> Open(const uint8_t* base, size_t size, | 
|  | 420 | const std::string& location, | 
|  | 421 | uint32_t location_checksum, | 
| Richard Uhler | 07b3c23 | 2015-03-31 15:57:54 -0700 | [diff] [blame] | 422 | const OatDexFile* oat_dex_file, | 
| Andreas Gampe | 3a2bd29 | 2016-01-26 17:23:47 -0800 | [diff] [blame] | 423 | bool verify, | 
| Aart Bik | 37d6a3b | 2016-06-21 18:30:10 -0700 | [diff] [blame] | 424 | bool verify_checksum, | 
| Andreas Gampe | 3a2bd29 | 2016-01-26 17:23:47 -0800 | [diff] [blame] | 425 | std::string* error_msg); | 
| Brian Carlstrom | 8952189 | 2011-12-07 22:05:07 -0800 | [diff] [blame] | 426 |  | 
| Orion Hodson | a4c2a05 | 2016-08-17 10:51:42 +0100 | [diff] [blame] | 427 | // Opens .dex file that has been memory-mapped by the caller. | 
|  | 428 | static std::unique_ptr<const DexFile> Open(const std::string& location, | 
|  | 429 | uint32_t location_checkum, | 
|  | 430 | std::unique_ptr<MemMap> mem_map, | 
|  | 431 | bool verify, | 
|  | 432 | bool verify_checksum, | 
|  | 433 | std::string* error_msg); | 
|  | 434 |  | 
|  | 435 | // Checks whether the given file has the dex magic, or is a zip file with a classes.dex entry. | 
|  | 436 | // If this function returns false, Open will not succeed. The inverse is not true, however. | 
|  | 437 | static bool MaybeDex(const char* filename); | 
|  | 438 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 439 | // Open all classesXXX.dex files from a zip archive. | 
| Aart Bik | 37d6a3b | 2016-06-21 18:30:10 -0700 | [diff] [blame] | 440 | static bool OpenFromZip(const ZipArchive& zip_archive, | 
|  | 441 | const std::string& location, | 
|  | 442 | bool verify_checksum, | 
| Richard Uhler | fbef44d | 2014-12-23 09:48:51 -0800 | [diff] [blame] | 443 | std::string* error_msg, | 
|  | 444 | std::vector<std::unique_ptr<const DexFile>>* dex_files); | 
| Brian Carlstrom | a6cc893 | 2012-01-04 14:44:07 -0800 | [diff] [blame] | 445 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 446 | // Closes a .dex file. | 
| Brian Carlstrom | f615a61 | 2011-07-23 12:50:34 -0700 | [diff] [blame] | 447 | virtual ~DexFile(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 448 |  | 
| Brian Carlstrom | a663ea5 | 2011-08-19 23:33:41 -0700 | [diff] [blame] | 449 | const std::string& GetLocation() const { | 
|  | 450 | return location_; | 
|  | 451 | } | 
|  | 452 |  | 
| Andreas Gampe | cb8f9e8 | 2014-07-24 15:35:50 -0700 | [diff] [blame] | 453 | // For normal dex files, location and base location coincide. If a dex file is part of a multidex | 
|  | 454 | // archive, the base location is the name of the originating jar/apk, stripped of any internal | 
|  | 455 | // classes*.dex path. | 
| Vladimir Marko | aa4497d | 2014-09-05 14:01:17 +0100 | [diff] [blame] | 456 | static std::string GetBaseLocation(const char* location) { | 
|  | 457 | const char* pos = strrchr(location, kMultiDexSeparator); | 
|  | 458 | if (pos == nullptr) { | 
|  | 459 | return location; | 
| Andreas Gampe | cb8f9e8 | 2014-07-24 15:35:50 -0700 | [diff] [blame] | 460 | } else { | 
| Vladimir Marko | aa4497d | 2014-09-05 14:01:17 +0100 | [diff] [blame] | 461 | return std::string(location, pos - location); | 
|  | 462 | } | 
|  | 463 | } | 
|  | 464 |  | 
| Richard Uhler | e5fed03 | 2015-03-18 08:21:11 -0700 | [diff] [blame] | 465 | static std::string GetBaseLocation(const std::string& location) { | 
|  | 466 | return GetBaseLocation(location.c_str()); | 
|  | 467 | } | 
|  | 468 |  | 
|  | 469 | // Returns the ':classes*.dex' part of the dex location. Returns an empty | 
|  | 470 | // string if there is no multidex suffix for the given location. | 
|  | 471 | // The kMultiDexSeparator is included in the returned suffix. | 
|  | 472 | static std::string GetMultiDexSuffix(const std::string& location) { | 
|  | 473 | size_t pos = location.rfind(kMultiDexSeparator); | 
| Vladimir Marko | aa4497d | 2014-09-05 14:01:17 +0100 | [diff] [blame] | 474 | if (pos == std::string::npos) { | 
| Richard Uhler | e5fed03 | 2015-03-18 08:21:11 -0700 | [diff] [blame] | 475 | return ""; | 
| Vladimir Marko | aa4497d | 2014-09-05 14:01:17 +0100 | [diff] [blame] | 476 | } else { | 
| Richard Uhler | e5fed03 | 2015-03-18 08:21:11 -0700 | [diff] [blame] | 477 | return location.substr(pos); | 
| Andreas Gampe | cb8f9e8 | 2014-07-24 15:35:50 -0700 | [diff] [blame] | 478 | } | 
|  | 479 | } | 
|  | 480 |  | 
| Richard Uhler | e5fed03 | 2015-03-18 08:21:11 -0700 | [diff] [blame] | 481 | std::string GetBaseLocation() const { | 
|  | 482 | return GetBaseLocation(location_); | 
|  | 483 | } | 
|  | 484 |  | 
| Brian Carlstrom | 5b332c8 | 2012-02-01 15:02:31 -0800 | [diff] [blame] | 485 | // For DexFiles directly from .dex files, this is the checksum from the DexFile::Header. | 
|  | 486 | // For DexFiles opened from a zip files, this will be the ZipEntry CRC32 of classes.dex. | 
|  | 487 | uint32_t GetLocationChecksum() const { | 
|  | 488 | return location_checksum_; | 
|  | 489 | } | 
|  | 490 |  | 
| Brian Carlstrom | a663ea5 | 2011-08-19 23:33:41 -0700 | [diff] [blame] | 491 | const Header& GetHeader() const { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 492 | DCHECK(header_ != nullptr) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 493 | return *header_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 494 | } | 
|  | 495 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 496 | // Decode the dex magic version | 
| Andreas Gampe | 76ed99d | 2016-03-28 18:31:29 -0700 | [diff] [blame] | 497 | uint32_t GetVersion() const { | 
|  | 498 | return GetHeader().GetVersion(); | 
|  | 499 | } | 
| Ian Rogers | d81871c | 2011-10-03 13:57:23 -0700 | [diff] [blame] | 500 |  | 
| Brian Carlstrom | 6e3b1d9 | 2012-01-11 01:36:32 -0800 | [diff] [blame] | 501 | // Returns true if the byte string points to the magic value. | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 502 | static bool IsMagicValid(const uint8_t* magic); | 
| Brian Carlstrom | 6e3b1d9 | 2012-01-11 01:36:32 -0800 | [diff] [blame] | 503 |  | 
|  | 504 | // 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] | 505 | static bool IsVersionValid(const uint8_t* magic); | 
| Brian Carlstrom | 6e3b1d9 | 2012-01-11 01:36:32 -0800 | [diff] [blame] | 506 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 507 | // Returns the number of string identifiers in the .dex file. | 
|  | 508 | size_t NumStringIds() const { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 509 | DCHECK(header_ != nullptr) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 510 | return header_->string_ids_size_; | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame] | 511 | } | 
|  | 512 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 513 | // Returns the StringId at the specified index. | 
|  | 514 | const StringId& GetStringId(uint32_t idx) const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 515 | DCHECK_LT(idx, NumStringIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 516 | return string_ids_[idx]; | 
|  | 517 | } | 
|  | 518 |  | 
|  | 519 | uint32_t GetIndexForStringId(const StringId& string_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 520 | CHECK_GE(&string_id, string_ids_) << GetLocation(); | 
|  | 521 | CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 522 | return &string_id - string_ids_; | 
|  | 523 | } | 
|  | 524 |  | 
|  | 525 | int32_t GetStringLength(const StringId& string_id) const; | 
|  | 526 |  | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 527 | // Returns a pointer to the UTF-8 string data referred to by the given string_id as well as the | 
|  | 528 | // length of the string when decoded as a UTF-16 string. Note the UTF-16 length is not the same | 
|  | 529 | // as the string length of the string data. | 
|  | 530 | const char* GetStringDataAndUtf16Length(const StringId& string_id, uint32_t* utf16_length) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 531 |  | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 532 | const char* GetStringData(const StringId& string_id) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 533 |  | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 534 | // Index version of GetStringDataAndUtf16Length. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 535 | const char* StringDataAndUtf16LengthByIdx(uint32_t idx, uint32_t* utf16_length) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 536 |  | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 537 | const char* StringDataByIdx(uint32_t idx) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 538 |  | 
| Ian Rogers | 637c65b | 2013-05-31 11:46:00 -0700 | [diff] [blame] | 539 | // Looks up a string id for a given modified utf8 string. | 
|  | 540 | const StringId* FindStringId(const char* string) const; | 
|  | 541 |  | 
| Artem Udovichenko | d9786b0 | 2015-10-14 16:36:55 +0300 | [diff] [blame] | 542 | const TypeId* FindTypeId(const char* string) const; | 
|  | 543 |  | 
| Ian Rogers | 637c65b | 2013-05-31 11:46:00 -0700 | [diff] [blame] | 544 | // Looks up a string id for a given utf16 string. | 
| Vladimir Marko | a48aef4 | 2014-12-03 17:53:53 +0000 | [diff] [blame] | 545 | const StringId* FindStringId(const uint16_t* string, size_t length) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 546 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 547 | // Returns the number of type identifiers in the .dex file. | 
| Ian Rogers | 68b5685 | 2014-08-29 20:19:11 -0700 | [diff] [blame] | 548 | uint32_t NumTypeIds() const { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 549 | DCHECK(header_ != nullptr) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 550 | return header_->type_ids_size_; | 
| Carl Shapiro | 5fafe2b | 2011-07-09 15:34:41 -0700 | [diff] [blame] | 551 | } | 
|  | 552 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 553 | // Returns the TypeId at the specified index. | 
|  | 554 | const TypeId& GetTypeId(uint32_t idx) const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 555 | DCHECK_LT(idx, NumTypeIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 556 | return type_ids_[idx]; | 
| Carl Shapiro | 5fafe2b | 2011-07-09 15:34:41 -0700 | [diff] [blame] | 557 | } | 
|  | 558 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 559 | uint16_t GetIndexForTypeId(const TypeId& type_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 560 | CHECK_GE(&type_id, type_ids_) << GetLocation(); | 
|  | 561 | CHECK_LT(&type_id, type_ids_ + header_->type_ids_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 562 | size_t result = &type_id - type_ids_; | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 563 | DCHECK_LT(result, 65536U) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 564 | return static_cast<uint16_t>(result); | 
|  | 565 | } | 
|  | 566 |  | 
|  | 567 | // Get the descriptor string associated with a given type index. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 568 | const char* StringByTypeIdx(uint32_t idx, uint32_t* unicode_length) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 569 |  | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 570 | const char* StringByTypeIdx(uint32_t idx) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 571 |  | 
|  | 572 | // Returns the type descriptor string of a type id. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 573 | const char* GetTypeDescriptor(const TypeId& type_id) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 574 |  | 
|  | 575 | // Looks up a type for the given string index | 
|  | 576 | const TypeId* FindTypeId(uint32_t string_idx) const; | 
|  | 577 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 578 | // Returns the number of field identifiers in the .dex file. | 
|  | 579 | size_t NumFieldIds() const { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 580 | DCHECK(header_ != nullptr) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 581 | return header_->field_ids_size_; | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame] | 582 | } | 
|  | 583 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 584 | // Returns the FieldId at the specified index. | 
|  | 585 | const FieldId& GetFieldId(uint32_t idx) const { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 586 | DCHECK_LT(idx, NumFieldIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 587 | return field_ids_[idx]; | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 588 | } | 
|  | 589 |  | 
| Ian Rogers | 9b1a4f4 | 2011-11-14 18:35:10 -0800 | [diff] [blame] | 590 | uint32_t GetIndexForFieldId(const FieldId& field_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 591 | CHECK_GE(&field_id, field_ids_) << GetLocation(); | 
|  | 592 | CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_) << GetLocation(); | 
| Ian Rogers | 9b1a4f4 | 2011-11-14 18:35:10 -0800 | [diff] [blame] | 593 | return &field_id - field_ids_; | 
|  | 594 | } | 
|  | 595 |  | 
|  | 596 | // Looks up a field by its declaring class, name and type | 
|  | 597 | const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass, | 
|  | 598 | const DexFile::StringId& name, | 
|  | 599 | const DexFile::TypeId& type) const; | 
|  | 600 |  | 
| Brian Carlstrom | 6b4ef02 | 2011-10-23 14:59:04 -0700 | [diff] [blame] | 601 | // Returns the declaring class descriptor string of a field id. | 
|  | 602 | const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const { | 
| Brian Carlstrom | b9edb84 | 2011-08-28 16:31:06 -0700 | [diff] [blame] | 603 | const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_); | 
|  | 604 | return GetTypeDescriptor(type_id); | 
|  | 605 | } | 
|  | 606 |  | 
| Brian Carlstrom | 6b4ef02 | 2011-10-23 14:59:04 -0700 | [diff] [blame] | 607 | // Returns the class descriptor string of a field id. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 608 | const char* GetFieldTypeDescriptor(const FieldId& field_id) const; | 
| Brian Carlstrom | 6b4ef02 | 2011-10-23 14:59:04 -0700 | [diff] [blame] | 609 |  | 
| Brian Carlstrom | b9edb84 | 2011-08-28 16:31:06 -0700 | [diff] [blame] | 610 | // Returns the name of a field id. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 611 | const char* GetFieldName(const FieldId& field_id) const; | 
| Brian Carlstrom | b9edb84 | 2011-08-28 16:31:06 -0700 | [diff] [blame] | 612 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 613 | // Returns the number of method identifiers in the .dex file. | 
|  | 614 | size_t NumMethodIds() const { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 615 | DCHECK(header_ != nullptr) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 616 | return header_->method_ids_size_; | 
|  | 617 | } | 
|  | 618 |  | 
|  | 619 | // Returns the MethodId at the specified index. | 
|  | 620 | const MethodId& GetMethodId(uint32_t idx) const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 621 | DCHECK_LT(idx, NumMethodIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 622 | return method_ids_[idx]; | 
|  | 623 | } | 
|  | 624 |  | 
|  | 625 | uint32_t GetIndexForMethodId(const MethodId& method_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 626 | CHECK_GE(&method_id, method_ids_) << GetLocation(); | 
|  | 627 | CHECK_LT(&method_id, method_ids_ + header_->method_ids_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 628 | return &method_id - method_ids_; | 
|  | 629 | } | 
|  | 630 |  | 
| Ian Rogers | 9b1a4f4 | 2011-11-14 18:35:10 -0800 | [diff] [blame] | 631 | // Looks up a method by its declaring class, name and proto_id | 
|  | 632 | const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass, | 
|  | 633 | const DexFile::StringId& name, | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 634 | const DexFile::ProtoId& signature) const; | 
|  | 635 |  | 
| Brian Carlstrom | 6b4ef02 | 2011-10-23 14:59:04 -0700 | [diff] [blame] | 636 | // Returns the declaring class descriptor string of a method id. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 637 | const char* GetMethodDeclaringClassDescriptor(const MethodId& method_id) const; | 
| Brian Carlstrom | 7540ff4 | 2011-09-04 16:38:46 -0700 | [diff] [blame] | 638 |  | 
| jeffhao | 98eacac | 2011-09-14 16:11:53 -0700 | [diff] [blame] | 639 | // Returns the prototype of a method id. | 
| Brian Carlstrom | aded5f7 | 2011-10-07 17:15:04 -0700 | [diff] [blame] | 640 | const ProtoId& GetMethodPrototype(const MethodId& method_id) const { | 
|  | 641 | return GetProtoId(method_id.proto_idx_); | 
|  | 642 | } | 
|  | 643 |  | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 644 | // Returns a representation of the signature of a method id. | 
|  | 645 | const Signature GetMethodSignature(const MethodId& method_id) const; | 
| jeffhao | 98eacac | 2011-09-14 16:11:53 -0700 | [diff] [blame] | 646 |  | 
| Brian Carlstrom | 7540ff4 | 2011-09-04 16:38:46 -0700 | [diff] [blame] | 647 | // Returns the name of a method id. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 648 | const char* GetMethodName(const MethodId& method_id) const; | 
| Brian Carlstrom | 7540ff4 | 2011-09-04 16:38:46 -0700 | [diff] [blame] | 649 |  | 
| Calin Juravle | 68ad649 | 2015-08-18 17:08:12 +0100 | [diff] [blame] | 650 | // Returns the shorty of a method by its index. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 651 | const char* GetMethodShorty(uint32_t idx) const; | 
| Calin Juravle | 68ad649 | 2015-08-18 17:08:12 +0100 | [diff] [blame] | 652 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 653 | // Returns the shorty of a method id. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 654 | const char* GetMethodShorty(const MethodId& method_id) const; | 
|  | 655 | const char* GetMethodShorty(const MethodId& method_id, uint32_t* length) const; | 
|  | 656 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 657 | // Returns the number of class definitions in the .dex file. | 
| Ian Rogers | 68b5685 | 2014-08-29 20:19:11 -0700 | [diff] [blame] | 658 | uint32_t NumClassDefs() const { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 659 | DCHECK(header_ != nullptr) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 660 | return header_->class_defs_size_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 661 | } | 
|  | 662 |  | 
|  | 663 | // Returns the ClassDef at the specified index. | 
| Ian Rogers | 8b2c0b9 | 2013-09-19 02:56:49 -0700 | [diff] [blame] | 664 | const ClassDef& GetClassDef(uint16_t idx) const { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 665 | DCHECK_LT(idx, NumClassDefs()) << GetLocation(); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 666 | return class_defs_[idx]; | 
|  | 667 | } | 
|  | 668 |  | 
| Ian Rogers | 8b2c0b9 | 2013-09-19 02:56:49 -0700 | [diff] [blame] | 669 | uint16_t GetIndexForClassDef(const ClassDef& class_def) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 670 | CHECK_GE(&class_def, class_defs_) << GetLocation(); | 
|  | 671 | CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 672 | return &class_def - class_defs_; | 
|  | 673 | } | 
|  | 674 |  | 
|  | 675 | // Returns the class descriptor string of a class definition. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 676 | const char* GetClassDescriptor(const ClassDef& class_def) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 677 |  | 
| Mathieu Chartier | e7c9a8c | 2014-11-06 16:35:45 -0800 | [diff] [blame] | 678 | // Looks up a class definition by its class descriptor. Hash must be | 
|  | 679 | // ComputeModifiedUtf8Hash(descriptor). | 
|  | 680 | const ClassDef* FindClassDef(const char* descriptor, size_t hash) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 681 |  | 
| Ian Rogers | 8b2c0b9 | 2013-09-19 02:56:49 -0700 | [diff] [blame] | 682 | // Looks up a class definition by its type index. | 
|  | 683 | const ClassDef* FindClassDef(uint16_t type_idx) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 684 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 685 | const TypeList* GetInterfacesList(const ClassDef& class_def) const { | 
|  | 686 | if (class_def.interfaces_off_ == 0) { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 687 | return nullptr; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 688 | } else { | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 689 | const uint8_t* addr = begin_ + class_def.interfaces_off_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 690 | return reinterpret_cast<const TypeList*>(addr); | 
|  | 691 | } | 
|  | 692 | } | 
|  | 693 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 694 | // Returns a pointer to the raw memory mapped class_data_item | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 695 | const uint8_t* GetClassData(const ClassDef& class_def) const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 696 | if (class_def.class_data_off_ == 0) { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 697 | return nullptr; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 698 | } else { | 
| Ian Rogers | 30fab40 | 2012-01-23 15:43:46 -0800 | [diff] [blame] | 699 | return begin_ + class_def.class_data_off_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 700 | } | 
| Shih-wei Liao | 2fb9753 | 2011-08-11 16:17:23 -0700 | [diff] [blame] | 701 | } | 
|  | 702 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 703 | // | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 704 | const CodeItem* GetCodeItem(const uint32_t code_off) const { | 
| Alex Light | 9139e00 | 2015-10-09 15:59:48 -0700 | [diff] [blame] | 705 | DCHECK_LT(code_off, size_) << "Code item offset larger then maximum allowed offset"; | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 706 | if (code_off == 0) { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 707 | return nullptr;  // native or abstract method | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 708 | } else { | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 709 | const uint8_t* addr = begin_ + code_off; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 710 | return reinterpret_cast<const CodeItem*>(addr); | 
|  | 711 | } | 
|  | 712 | } | 
|  | 713 |  | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 714 | const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 715 |  | 
|  | 716 | // Returns the number of prototype identifiers in the .dex file. | 
|  | 717 | size_t NumProtoIds() const { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 718 | DCHECK(header_ != nullptr) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 719 | return header_->proto_ids_size_; | 
|  | 720 | } | 
|  | 721 |  | 
|  | 722 | // Returns the ProtoId at the specified index. | 
|  | 723 | const ProtoId& GetProtoId(uint32_t idx) const { | 
| Ian Rogers | 4f6ad8a | 2013-03-18 15:27:28 -0700 | [diff] [blame] | 724 | DCHECK_LT(idx, NumProtoIds()) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 725 | return proto_ids_[idx]; | 
|  | 726 | } | 
|  | 727 |  | 
|  | 728 | uint16_t GetIndexForProtoId(const ProtoId& proto_id) const { | 
| Brian Carlstrom | 61e513c | 2011-12-09 15:30:06 -0800 | [diff] [blame] | 729 | CHECK_GE(&proto_id, proto_ids_) << GetLocation(); | 
|  | 730 | CHECK_LT(&proto_id, proto_ids_ + header_->proto_ids_size_) << GetLocation(); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 731 | return &proto_id - proto_ids_; | 
|  | 732 | } | 
|  | 733 |  | 
|  | 734 | // 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] | 735 | const ProtoId* FindProtoId(uint16_t return_type_idx, | 
| Vladimir Marko | 5c96e6b | 2013-11-14 15:34:17 +0000 | [diff] [blame] | 736 | const uint16_t* signature_type_idxs, uint32_t signature_length) const; | 
|  | 737 | const ProtoId* FindProtoId(uint16_t return_type_idx, | 
|  | 738 | const std::vector<uint16_t>& signature_type_idxs) const { | 
|  | 739 | return FindProtoId(return_type_idx, &signature_type_idxs[0], signature_type_idxs.size()); | 
|  | 740 | } | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 741 |  | 
|  | 742 | // 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] | 743 | bool CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx, | 
|  | 744 | std::vector<uint16_t>* param_type_idxs) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 745 |  | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 746 | // Create a Signature from the given string signature or return Signature::NoSignature if not | 
|  | 747 | // possible. | 
|  | 748 | const Signature CreateSignature(const StringPiece& signature) const; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 749 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 750 | // Returns the short form method descriptor for the given prototype. | 
| Vladimir Marko | 5c6a587 | 2016-06-27 13:50:16 +0100 | [diff] [blame] | 751 | const char* GetShorty(uint32_t proto_idx) const; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 752 |  | 
|  | 753 | const TypeList* GetProtoParameters(const ProtoId& proto_id) const { | 
|  | 754 | if (proto_id.parameters_off_ == 0) { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 755 | return nullptr; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 756 | } else { | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 757 | const uint8_t* addr = begin_ + proto_id.parameters_off_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 758 | return reinterpret_cast<const TypeList*>(addr); | 
|  | 759 | } | 
|  | 760 | } | 
|  | 761 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 762 | const uint8_t* GetEncodedStaticFieldValuesArray(const ClassDef& class_def) const { | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 763 | if (class_def.static_values_off_ == 0) { | 
|  | 764 | return 0; | 
|  | 765 | } else { | 
| Ian Rogers | 30fab40 | 2012-01-23 15:43:46 -0800 | [diff] [blame] | 766 | return begin_ + class_def.static_values_off_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 767 | } | 
|  | 768 | } | 
|  | 769 |  | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 770 | static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset); | 
| Shih-wei Liao | 2fb9753 | 2011-08-11 16:17:23 -0700 | [diff] [blame] | 771 |  | 
|  | 772 | // Get the base of the encoded data for the given DexCode. | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 773 | static const uint8_t* GetCatchHandlerData(const CodeItem& code_item, uint32_t offset) { | 
|  | 774 | const uint8_t* handler_data = | 
|  | 775 | 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] | 776 | return handler_data + offset; | 
|  | 777 | } | 
|  | 778 |  | 
| Ian Rogers | dbbc99d | 2013-04-18 16:51:54 -0700 | [diff] [blame] | 779 | // Find which try region is associated with the given address (ie dex pc). Returns -1 if none. | 
|  | 780 | static int32_t FindTryItem(const CodeItem &code_item, uint32_t address); | 
|  | 781 |  | 
|  | 782 | // Find the handler offset associated with the given address (ie dex pc). Returns -1 if none. | 
|  | 783 | static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address); | 
| Shih-wei Liao | 2fb9753 | 2011-08-11 16:17:23 -0700 | [diff] [blame] | 784 |  | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 785 | // Get the pointer to the start of the debugging data | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 786 | const uint8_t* GetDebugInfoStream(const CodeItem* code_item) const { | 
| David Srbecky | 6852942 | 2015-07-07 19:13:29 +0100 | [diff] [blame] | 787 | // Check that the offset is in bounds. | 
|  | 788 | // Note that although the specification says that 0 should be used if there | 
|  | 789 | // is no debug information, some applications incorrectly use 0xFFFFFFFF. | 
|  | 790 | if (code_item->debug_info_off_ == 0 || code_item->debug_info_off_ >= size_) { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 791 | return nullptr; | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 792 | } else { | 
| Ian Rogers | 30fab40 | 2012-01-23 15:43:46 -0800 | [diff] [blame] | 793 | return begin_ + code_item->debug_info_off_; | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 794 | } | 
|  | 795 | } | 
|  | 796 |  | 
| David Srbecky | b06e28e | 2015-12-10 13:15:00 +0000 | [diff] [blame] | 797 | struct PositionInfo { | 
|  | 798 | PositionInfo() | 
|  | 799 | : address_(0), | 
|  | 800 | line_(0), | 
|  | 801 | source_file_(nullptr), | 
|  | 802 | prologue_end_(false), | 
|  | 803 | epilogue_begin_(false) { | 
|  | 804 | } | 
|  | 805 |  | 
|  | 806 | uint32_t address_;  // In 16-bit code units. | 
|  | 807 | uint32_t line_;  // Source code line number starting at 1. | 
|  | 808 | const char* source_file_;  // nullptr if the file from ClassDef still applies. | 
|  | 809 | bool prologue_end_; | 
|  | 810 | bool epilogue_begin_; | 
|  | 811 | }; | 
|  | 812 |  | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 813 | // Callback for "new position table entry". | 
|  | 814 | // Returning true causes the decoder to stop early. | 
| David Srbecky | b06e28e | 2015-12-10 13:15:00 +0000 | [diff] [blame] | 815 | typedef bool (*DexDebugNewPositionCb)(void* context, const PositionInfo& entry); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 816 |  | 
| David Srbecky | b06e28e | 2015-12-10 13:15:00 +0000 | [diff] [blame] | 817 | struct LocalInfo { | 
|  | 818 | LocalInfo() | 
|  | 819 | : name_(nullptr), | 
|  | 820 | descriptor_(nullptr), | 
|  | 821 | signature_(nullptr), | 
|  | 822 | start_address_(0), | 
|  | 823 | end_address_(0), | 
|  | 824 | reg_(0), | 
|  | 825 | is_live_(false) { | 
|  | 826 | } | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 827 |  | 
| David Srbecky | b06e28e | 2015-12-10 13:15:00 +0000 | [diff] [blame] | 828 | const char* name_;  // E.g., list.  It can be nullptr if unknown. | 
|  | 829 | const char* descriptor_;  // E.g., Ljava/util/LinkedList; | 
|  | 830 | const char* signature_;  // E.g., java.util.LinkedList<java.lang.Integer> | 
|  | 831 | uint32_t start_address_;  // PC location where the local is first defined. | 
|  | 832 | uint32_t end_address_;  // PC location where the local is no longer defined. | 
|  | 833 | uint16_t reg_;  // Dex register which stores the values. | 
|  | 834 | bool is_live_;  // Is the local defined and live. | 
|  | 835 | }; | 
|  | 836 |  | 
|  | 837 | // Callback for "new locals table entry". | 
|  | 838 | typedef void (*DexDebugNewLocalCb)(void* context, const LocalInfo& entry); | 
|  | 839 |  | 
|  | 840 | static bool LineNumForPcCb(void* context, const PositionInfo& entry); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 841 |  | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 842 | const AnnotationsDirectoryItem* GetAnnotationsDirectory(const ClassDef& class_def) const { | 
|  | 843 | if (class_def.annotations_off_ == 0) { | 
|  | 844 | return nullptr; | 
|  | 845 | } else { | 
|  | 846 | return reinterpret_cast<const AnnotationsDirectoryItem*>(begin_ + class_def.annotations_off_); | 
|  | 847 | } | 
|  | 848 | } | 
|  | 849 |  | 
|  | 850 | const AnnotationSetItem* GetClassAnnotationSet(const AnnotationsDirectoryItem* anno_dir) const { | 
|  | 851 | if (anno_dir->class_annotations_off_ == 0) { | 
|  | 852 | return nullptr; | 
|  | 853 | } else { | 
|  | 854 | return reinterpret_cast<const AnnotationSetItem*>(begin_ + anno_dir->class_annotations_off_); | 
|  | 855 | } | 
|  | 856 | } | 
|  | 857 |  | 
|  | 858 | const FieldAnnotationsItem* GetFieldAnnotations(const AnnotationsDirectoryItem* anno_dir) const { | 
|  | 859 | if (anno_dir->fields_size_ == 0) { | 
|  | 860 | return nullptr; | 
|  | 861 | } else { | 
|  | 862 | return reinterpret_cast<const FieldAnnotationsItem*>(&anno_dir[1]); | 
|  | 863 | } | 
|  | 864 | } | 
|  | 865 |  | 
|  | 866 | const MethodAnnotationsItem* GetMethodAnnotations(const AnnotationsDirectoryItem* anno_dir) | 
|  | 867 | const { | 
|  | 868 | if (anno_dir->methods_size_ == 0) { | 
|  | 869 | return nullptr; | 
|  | 870 | } else { | 
|  | 871 | // Skip past the header and field annotations. | 
|  | 872 | const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]); | 
|  | 873 | addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem); | 
|  | 874 | return reinterpret_cast<const MethodAnnotationsItem*>(addr); | 
|  | 875 | } | 
|  | 876 | } | 
|  | 877 |  | 
|  | 878 | const ParameterAnnotationsItem* GetParameterAnnotations(const AnnotationsDirectoryItem* anno_dir) | 
|  | 879 | const { | 
|  | 880 | if (anno_dir->parameters_size_ == 0) { | 
|  | 881 | return nullptr; | 
|  | 882 | } else { | 
|  | 883 | // Skip past the header, field annotations, and method annotations. | 
|  | 884 | const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]); | 
|  | 885 | addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem); | 
|  | 886 | addr += anno_dir->methods_size_ * sizeof(MethodAnnotationsItem); | 
|  | 887 | return reinterpret_cast<const ParameterAnnotationsItem*>(addr); | 
|  | 888 | } | 
|  | 889 | } | 
|  | 890 |  | 
|  | 891 | const AnnotationSetItem* GetFieldAnnotationSetItem(const FieldAnnotationsItem& anno_item) const { | 
|  | 892 | uint32_t offset = anno_item.annotations_off_; | 
|  | 893 | if (offset == 0) { | 
|  | 894 | return nullptr; | 
|  | 895 | } else { | 
|  | 896 | return reinterpret_cast<const AnnotationSetItem*>(begin_ + offset); | 
|  | 897 | } | 
|  | 898 | } | 
|  | 899 |  | 
|  | 900 | const AnnotationSetItem* GetMethodAnnotationSetItem(const MethodAnnotationsItem& anno_item) | 
|  | 901 | const { | 
|  | 902 | uint32_t offset = anno_item.annotations_off_; | 
|  | 903 | if (offset == 0) { | 
|  | 904 | return nullptr; | 
|  | 905 | } else { | 
|  | 906 | return reinterpret_cast<const AnnotationSetItem*>(begin_ + offset); | 
|  | 907 | } | 
|  | 908 | } | 
|  | 909 |  | 
|  | 910 | const AnnotationSetRefList* GetParameterAnnotationSetRefList( | 
|  | 911 | const ParameterAnnotationsItem* anno_item) const { | 
|  | 912 | uint32_t offset = anno_item->annotations_off_; | 
|  | 913 | if (offset == 0) { | 
|  | 914 | return nullptr; | 
|  | 915 | } | 
|  | 916 | return reinterpret_cast<const AnnotationSetRefList*>(begin_ + offset); | 
|  | 917 | } | 
|  | 918 |  | 
|  | 919 | const AnnotationItem* GetAnnotationItem(const AnnotationSetItem* set_item, uint32_t index) const { | 
|  | 920 | DCHECK_LE(index, set_item->size_); | 
|  | 921 | uint32_t offset = set_item->entries_[index]; | 
|  | 922 | if (offset == 0) { | 
|  | 923 | return nullptr; | 
|  | 924 | } else { | 
|  | 925 | return reinterpret_cast<const AnnotationItem*>(begin_ + offset); | 
|  | 926 | } | 
|  | 927 | } | 
|  | 928 |  | 
|  | 929 | const AnnotationSetItem* GetSetRefItemItem(const AnnotationSetRefItem* anno_item) const { | 
|  | 930 | uint32_t offset = anno_item->annotations_off_; | 
|  | 931 | if (offset == 0) { | 
|  | 932 | return nullptr; | 
|  | 933 | } | 
|  | 934 | return reinterpret_cast<const AnnotationSetItem*>(begin_ + offset); | 
|  | 935 | } | 
|  | 936 |  | 
|  | 937 | const AnnotationSetItem* FindAnnotationSetForField(ArtField* field) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 938 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 939 | mirror::Object* GetAnnotationForField(ArtField* field, Handle<mirror::Class> annotation_class) | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 940 | const REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 941 | mirror::ObjectArray<mirror::Object>* GetAnnotationsForField(ArtField* field) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 942 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 943 | mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForField(ArtField* field) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 944 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 945 | bool IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 946 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 947 |  | 
|  | 948 | const AnnotationSetItem* FindAnnotationSetForMethod(ArtMethod* method) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 949 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 950 | const ParameterAnnotationsItem* FindAnnotationsItemForMethod(ArtMethod* method) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 951 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 952 | mirror::Object* GetAnnotationDefaultValue(ArtMethod* method) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 953 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 954 | mirror::Object* GetAnnotationForMethod(ArtMethod* method, Handle<mirror::Class> annotation_class) | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 955 | const REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 956 | mirror::ObjectArray<mirror::Object>* GetAnnotationsForMethod(ArtMethod* method) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 957 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 958 | mirror::ObjectArray<mirror::Class>* GetExceptionTypesForMethod(ArtMethod* method) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 959 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 960 | mirror::ObjectArray<mirror::Object>* GetParameterAnnotations(ArtMethod* method) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 961 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 1133db7 | 2016-04-04 19:50:14 -0700 | [diff] [blame] | 962 | mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForMethod(ArtMethod* method) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 963 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Igor Murashkin | 9d4b6da | 2016-07-29 09:51:58 -0700 | [diff] [blame] | 964 | bool IsMethodAnnotationPresent(ArtMethod* method, | 
|  | 965 | Handle<mirror::Class> annotation_class, | 
|  | 966 | uint32_t visibility = kDexVisibilityRuntime) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 967 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 968 |  | 
|  | 969 | const AnnotationSetItem* FindAnnotationSetForClass(Handle<mirror::Class> klass) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 970 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 971 | mirror::Object* GetAnnotationForClass(Handle<mirror::Class> klass, | 
|  | 972 | Handle<mirror::Class> annotation_class) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 973 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 974 | mirror::ObjectArray<mirror::Object>* GetAnnotationsForClass(Handle<mirror::Class> klass) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 975 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 976 | mirror::ObjectArray<mirror::Class>* GetDeclaredClasses(Handle<mirror::Class> klass) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 977 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 978 | mirror::Class* GetDeclaringClass(Handle<mirror::Class> klass) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 979 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 980 | mirror::Class* GetEnclosingClass(Handle<mirror::Class> klass) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 981 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 982 | mirror::Object* GetEnclosingMethod(Handle<mirror::Class> klass) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 983 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 984 | bool GetInnerClass(Handle<mirror::Class> klass, mirror::String** name) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 985 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 986 | bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 987 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 1133db7 | 2016-04-04 19:50:14 -0700 | [diff] [blame] | 988 | mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForClass(Handle<mirror::Class> klass) | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 989 | const REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 990 | bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class) | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 991 | const REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 992 |  | 
|  | 993 | mirror::Object* CreateAnnotationMember(Handle<mirror::Class> klass, | 
|  | 994 | Handle<mirror::Class> annotation_class, | 
|  | 995 | const uint8_t** annotation) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 996 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 997 | const AnnotationItem* GetAnnotationItemFromAnnotationSet(Handle<mirror::Class> klass, | 
|  | 998 | const AnnotationSetItem* annotation_set, | 
|  | 999 | uint32_t visibility, | 
|  | 1000 | Handle<mirror::Class> annotation_class) | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1001 | const REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1002 | mirror::Object* GetAnnotationObjectFromAnnotationSet(Handle<mirror::Class> klass, | 
|  | 1003 | const AnnotationSetItem* annotation_set, | 
|  | 1004 | uint32_t visibility, | 
|  | 1005 | Handle<mirror::Class> annotation_class) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1006 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1007 | mirror::Object* GetAnnotationValue(Handle<mirror::Class> klass, | 
|  | 1008 | const AnnotationItem* annotation_item, | 
|  | 1009 | const char* annotation_name, | 
|  | 1010 | Handle<mirror::Class> array_class, | 
|  | 1011 | uint32_t expected_type) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1012 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 1013 | mirror::ObjectArray<mirror::String>* GetSignatureValue(Handle<mirror::Class> klass, | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1014 | const AnnotationSetItem* annotation_set) | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1015 | const REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 2a5892f | 2015-08-31 15:00:40 -0700 | [diff] [blame] | 1016 | mirror::ObjectArray<mirror::Class>* GetThrowsValue(Handle<mirror::Class> klass, | 
|  | 1017 | const AnnotationSetItem* annotation_set) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1018 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1019 | mirror::ObjectArray<mirror::Object>* ProcessAnnotationSet(Handle<mirror::Class> klass, | 
|  | 1020 | const AnnotationSetItem* annotation_set, | 
|  | 1021 | uint32_t visibility) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1022 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1023 | mirror::ObjectArray<mirror::Object>* ProcessAnnotationSetRefList(Handle<mirror::Class> klass, | 
|  | 1024 | const AnnotationSetRefList* set_ref_list, uint32_t size) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1025 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1026 | mirror::Object* ProcessEncodedAnnotation(Handle<mirror::Class> klass, | 
|  | 1027 | const uint8_t** annotation) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1028 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1029 | const AnnotationItem* SearchAnnotationSet(const AnnotationSetItem* annotation_set, | 
|  | 1030 | const char* descriptor, uint32_t visibility) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1031 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1032 | const uint8_t* SearchEncodedAnnotation(const uint8_t* annotation, const char* name) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1033 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1034 | bool SkipAnnotationValue(const uint8_t** annotation_ptr) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1035 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Jeff Hao | 13e748b | 2015-08-25 20:44:19 +0000 | [diff] [blame] | 1036 |  | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 1037 | // Debug info opcodes and constants | 
|  | 1038 | enum { | 
|  | 1039 | DBG_END_SEQUENCE         = 0x00, | 
|  | 1040 | DBG_ADVANCE_PC           = 0x01, | 
|  | 1041 | DBG_ADVANCE_LINE         = 0x02, | 
|  | 1042 | DBG_START_LOCAL          = 0x03, | 
|  | 1043 | DBG_START_LOCAL_EXTENDED = 0x04, | 
|  | 1044 | DBG_END_LOCAL            = 0x05, | 
|  | 1045 | DBG_RESTART_LOCAL        = 0x06, | 
|  | 1046 | DBG_SET_PROLOGUE_END     = 0x07, | 
|  | 1047 | DBG_SET_EPILOGUE_BEGIN   = 0x08, | 
|  | 1048 | DBG_SET_FILE             = 0x09, | 
|  | 1049 | DBG_FIRST_SPECIAL        = 0x0a, | 
|  | 1050 | DBG_LINE_BASE            = -4, | 
|  | 1051 | DBG_LINE_RANGE           = 15, | 
|  | 1052 | }; | 
|  | 1053 |  | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 1054 | struct LineNumFromPcContext { | 
| Ian Rogers | ca19066 | 2012-06-26 15:45:57 -0700 | [diff] [blame] | 1055 | LineNumFromPcContext(uint32_t address, uint32_t line_num) | 
|  | 1056 | : address_(address), line_num_(line_num) {} | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 1057 | uint32_t address_; | 
|  | 1058 | uint32_t line_num_; | 
| Brian Carlstrom | d2fbb2b | 2011-08-23 11:57:08 -0700 | [diff] [blame] | 1059 | private: | 
|  | 1060 | DISALLOW_COPY_AND_ASSIGN(LineNumFromPcContext); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 1061 | }; | 
|  | 1062 |  | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 1063 | // Determine the source file line number based on the program counter. | 
|  | 1064 | // "pc" is an offset, in 16-bit units, from the start of the method's code. | 
|  | 1065 | // | 
|  | 1066 | // Returns -1 if no match was found (possibly because the source files were | 
|  | 1067 | // compiled without "-g", so no line number information is present). | 
|  | 1068 | // Returns -2 for native methods (as expected in exception traces). | 
|  | 1069 | // | 
|  | 1070 | // This is used by runtime; therefore use art::Method not art::DexFile::Method. | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 1071 | int32_t GetLineNumFromPC(ArtMethod* method, uint32_t rel_pc) const | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1072 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 1073 |  | 
| Roland Levillain | 91d65e0 | 2016-01-19 15:59:16 +0000 | [diff] [blame] | 1074 | // Returns false if there is no debugging information or if it cannot be decoded. | 
| David Srbecky | b06e28e | 2015-12-10 13:15:00 +0000 | [diff] [blame] | 1075 | bool DecodeDebugLocalInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx, | 
|  | 1076 | DexDebugNewLocalCb local_cb, void* context) const; | 
|  | 1077 |  | 
| Roland Levillain | 91d65e0 | 2016-01-19 15:59:16 +0000 | [diff] [blame] | 1078 | // Returns false if there is no debugging information or if it cannot be decoded. | 
| David Srbecky | b06e28e | 2015-12-10 13:15:00 +0000 | [diff] [blame] | 1079 | bool DecodeDebugPositionInfo(const CodeItem* code_item, DexDebugNewPositionCb position_cb, | 
|  | 1080 | void* context) const; | 
| Shih-wei Liao | 195487c | 2011-08-20 13:29:04 -0700 | [diff] [blame] | 1081 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1082 | const char* GetSourceFile(const ClassDef& class_def) const { | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1083 | if (class_def.source_file_idx_ == 0xffffffff) { | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 1084 | return nullptr; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1085 | } else { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1086 | return StringDataByIdx(class_def.source_file_idx_); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1087 | } | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame] | 1088 | } | 
|  | 1089 |  | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 1090 | int GetPermissions() const; | 
| Ian Rogers | 1c849e5 | 2012-06-28 14:00:33 -0700 | [diff] [blame] | 1091 |  | 
| Sebastien Hertz | 2d6ba51 | 2013-05-17 11:31:37 +0200 | [diff] [blame] | 1092 | bool IsReadOnly() const; | 
|  | 1093 |  | 
| Brian Carlstrom | e0948e1 | 2013-08-29 09:36:15 -0700 | [diff] [blame] | 1094 | bool EnableWrite() const; | 
| Sebastien Hertz | 2d6ba51 | 2013-05-17 11:31:37 +0200 | [diff] [blame] | 1095 |  | 
| Brian Carlstrom | e0948e1 | 2013-08-29 09:36:15 -0700 | [diff] [blame] | 1096 | bool DisableWrite() const; | 
| Sebastien Hertz | 2d6ba51 | 2013-05-17 11:31:37 +0200 | [diff] [blame] | 1097 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1098 | const uint8_t* Begin() const { | 
| Ian Rogers | 8b2c0b9 | 2013-09-19 02:56:49 -0700 | [diff] [blame] | 1099 | return begin_; | 
|  | 1100 | } | 
|  | 1101 |  | 
|  | 1102 | size_t Size() const { | 
|  | 1103 | return size_; | 
|  | 1104 | } | 
|  | 1105 |  | 
| Andreas Gampe | 90e3404 | 2015-04-27 20:01:52 -0700 | [diff] [blame] | 1106 | // Return the name of the index-th classes.dex in a multidex zip file. This is classes.dex for | 
|  | 1107 | // index == 0, and classes{index + 1}.dex else. | 
|  | 1108 | static std::string GetMultiDexClassesDexName(size_t index); | 
|  | 1109 |  | 
|  | 1110 | // Return the (possibly synthetic) dex location for a multidex entry. This is dex_location for | 
|  | 1111 | // index == 0, and dex_location + multi-dex-separator + GetMultiDexClassesDexName(index) else. | 
|  | 1112 | static std::string GetMultiDexLocation(size_t index, const char* dex_location); | 
| Calin Juravle | 4e1d579 | 2014-07-15 23:56:47 +0100 | [diff] [blame] | 1113 |  | 
|  | 1114 | // Returns the canonical form of the given dex location. | 
|  | 1115 | // | 
|  | 1116 | // There are different flavors of "dex locations" as follows: | 
|  | 1117 | // the file name of a dex file: | 
|  | 1118 | //     The actual file path that the dex file has on disk. | 
|  | 1119 | // dex_location: | 
|  | 1120 | //     This acts as a key for the class linker to know which dex file to load. | 
|  | 1121 | //     It may correspond to either an old odex file or a particular dex file | 
|  | 1122 | //     inside an oat file. In the first case it will also match the file name | 
|  | 1123 | //     of the dex file. In the second case (oat) it will include the file name | 
|  | 1124 | //     and possibly some multidex annotation to uniquely identify it. | 
|  | 1125 | // canonical_dex_location: | 
|  | 1126 | //     the dex_location where it's file name part has been made canonical. | 
|  | 1127 | static std::string GetDexCanonicalLocation(const char* dex_location); | 
|  | 1128 |  | 
| Richard Uhler | 07b3c23 | 2015-03-31 15:57:54 -0700 | [diff] [blame] | 1129 | const OatDexFile* GetOatDexFile() const { | 
|  | 1130 | return oat_dex_file_; | 
| Andreas Gampe | fd9eb39 | 2014-11-06 16:52:58 -0800 | [diff] [blame] | 1131 | } | 
|  | 1132 |  | 
| Artem Udovichenko | d9786b0 | 2015-10-14 16:36:55 +0300 | [diff] [blame] | 1133 | TypeLookupTable* GetTypeLookupTable() const { | 
|  | 1134 | return lookup_table_.get(); | 
|  | 1135 | } | 
|  | 1136 |  | 
| Vladimir Marko | 9bdf108 | 2016-01-21 12:15:52 +0000 | [diff] [blame] | 1137 | void CreateTypeLookupTable(uint8_t* storage = nullptr) const; | 
| Artem Udovichenko | d9786b0 | 2015-10-14 16:36:55 +0300 | [diff] [blame] | 1138 |  | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 1139 | private: | 
| Brian Carlstrom | 58ae941 | 2011-10-04 00:56:06 -0700 | [diff] [blame] | 1140 | // Opens a .dex file | 
| Aart Bik | 37d6a3b | 2016-06-21 18:30:10 -0700 | [diff] [blame] | 1141 | static std::unique_ptr<const DexFile> OpenFile(int fd, | 
|  | 1142 | const char* location, | 
|  | 1143 | bool verify, | 
|  | 1144 | bool verify_checksum, | 
|  | 1145 | std::string* error_msg); | 
| Brian Carlstrom | 58ae941 | 2011-10-04 00:56:06 -0700 | [diff] [blame] | 1146 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 1147 | // Opens dex files from within a .jar, .zip, or .apk file | 
| Aart Bik | 37d6a3b | 2016-06-21 18:30:10 -0700 | [diff] [blame] | 1148 | static bool OpenZip(int fd, | 
|  | 1149 | const std::string& location, | 
|  | 1150 | bool verify_checksum, | 
|  | 1151 | std::string* error_msg, | 
| Richard Uhler | fbef44d | 2014-12-23 09:48:51 -0800 | [diff] [blame] | 1152 | std::vector<std::unique_ptr<const DexFile>>* dex_files); | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 1153 |  | 
|  | 1154 | enum class ZipOpenErrorCode {  // private | 
|  | 1155 | kNoError, | 
|  | 1156 | kEntryNotFound, | 
|  | 1157 | kExtractToMemoryError, | 
|  | 1158 | kDexFileError, | 
|  | 1159 | kMakeReadOnlyError, | 
|  | 1160 | kVerifyError | 
|  | 1161 | }; | 
|  | 1162 |  | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 1163 | // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 1164 | // return. | 
| Aart Bik | 37d6a3b | 2016-06-21 18:30:10 -0700 | [diff] [blame] | 1165 | static std::unique_ptr<const DexFile> Open(const ZipArchive& zip_archive, | 
|  | 1166 | const char* entry_name, | 
|  | 1167 | const std::string& location, | 
|  | 1168 | bool verify_checksum, | 
|  | 1169 | std::string* error_msg, | 
| Richard Uhler | fbef44d | 2014-12-23 09:48:51 -0800 | [diff] [blame] | 1170 | ZipOpenErrorCode* error_code); | 
| Brian Carlstrom | 58ae941 | 2011-10-04 00:56:06 -0700 | [diff] [blame] | 1171 |  | 
| Brian Carlstrom | 8952189 | 2011-12-07 22:05:07 -0800 | [diff] [blame] | 1172 | // Opens a .dex file at the given address backed by a MemMap | 
| Richard Uhler | fbef44d | 2014-12-23 09:48:51 -0800 | [diff] [blame] | 1173 | static std::unique_ptr<const DexFile> OpenMemory(const std::string& location, | 
|  | 1174 | uint32_t location_checksum, | 
| Orion Hodson | a4c2a05 | 2016-08-17 10:51:42 +0100 | [diff] [blame] | 1175 | std::unique_ptr<MemMap> mem_map, | 
| Richard Uhler | fbef44d | 2014-12-23 09:48:51 -0800 | [diff] [blame] | 1176 | std::string* error_msg); | 
| Brian Carlstrom | 8952189 | 2011-12-07 22:05:07 -0800 | [diff] [blame] | 1177 |  | 
|  | 1178 | // Opens a .dex file at the given address, optionally backed by a MemMap | 
| Richard Uhler | fbef44d | 2014-12-23 09:48:51 -0800 | [diff] [blame] | 1179 | static std::unique_ptr<const DexFile> OpenMemory(const uint8_t* dex_file, | 
|  | 1180 | size_t size, | 
|  | 1181 | const std::string& location, | 
|  | 1182 | uint32_t location_checksum, | 
| Orion Hodson | a4c2a05 | 2016-08-17 10:51:42 +0100 | [diff] [blame] | 1183 | std::unique_ptr<MemMap> mem_map, | 
| Richard Uhler | 07b3c23 | 2015-03-31 15:57:54 -0700 | [diff] [blame] | 1184 | const OatDexFile* oat_dex_file, | 
| Richard Uhler | fbef44d | 2014-12-23 09:48:51 -0800 | [diff] [blame] | 1185 | std::string* error_msg); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1186 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1187 | DexFile(const uint8_t* base, size_t size, | 
| Brian Carlstrom | 28db012 | 2012-10-18 16:20:41 -0700 | [diff] [blame] | 1188 | const std::string& location, | 
|  | 1189 | uint32_t location_checksum, | 
| Orion Hodson | a4c2a05 | 2016-08-17 10:51:42 +0100 | [diff] [blame] | 1190 | std::unique_ptr<MemMap> mem_map, | 
| Richard Uhler | 07b3c23 | 2015-03-31 15:57:54 -0700 | [diff] [blame] | 1191 | const OatDexFile* oat_dex_file); | 
| jeffhao | f6174e8 | 2012-01-31 16:14:17 -0800 | [diff] [blame] | 1192 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1193 | // Top-level initializer that calls other Init methods. | 
| Ian Rogers | 8d31bbd | 2013-10-13 10:44:14 -0700 | [diff] [blame] | 1194 | bool Init(std::string* error_msg); | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1195 |  | 
| Brian Carlstrom | 6e3b1d9 | 2012-01-11 01:36:32 -0800 | [diff] [blame] | 1196 | // 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] | 1197 | bool CheckMagicAndVersion(std::string* error_msg) const; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1198 |  | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 1199 | // Check whether a location denotes a multidex dex file. This is a very simple check: returns | 
|  | 1200 | // whether the string contains the separator character. | 
|  | 1201 | static bool IsMultiDexLocation(const char* location); | 
|  | 1202 |  | 
| Vladimir Marko | 3a21e38 | 2016-09-02 12:38:38 +0100 | [diff] [blame] | 1203 | struct AnnotationValue; | 
|  | 1204 |  | 
|  | 1205 | bool ProcessAnnotationValue(Handle<mirror::Class> klass, const uint8_t** annotation_ptr, | 
|  | 1206 | AnnotationValue* annotation_value, Handle<mirror::Class> return_class, | 
|  | 1207 | DexFile::AnnotationResultStyle result_style) const | 
|  | 1208 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Andreas Gampe | 833a485 | 2014-05-21 18:46:59 -0700 | [diff] [blame] | 1209 |  | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1210 | // The base address of the memory mapping. | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1211 | const uint8_t* const begin_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1212 |  | 
|  | 1213 | // The size of the underlying memory allocation in bytes. | 
| Ian Rogers | 62d6c77 | 2013-02-27 08:32:07 -0800 | [diff] [blame] | 1214 | const size_t size_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1215 |  | 
| Elliott Hughes | 64bf5a3 | 2011-09-20 14:43:12 -0700 | [diff] [blame] | 1216 | // Typically the dex file name when available, alternatively some identifying string. | 
| Brian Carlstrom | a663ea5 | 2011-08-19 23:33:41 -0700 | [diff] [blame] | 1217 | // | 
|  | 1218 | // The ClassLinker will use this to match DexFiles the boot class | 
|  | 1219 | // path to DexCache::GetLocation when loading from an image. | 
|  | 1220 | const std::string location_; | 
|  | 1221 |  | 
| Brian Carlstrom | 5b332c8 | 2012-02-01 15:02:31 -0800 | [diff] [blame] | 1222 | const uint32_t location_checksum_; | 
|  | 1223 |  | 
| Brian Carlstrom | 33f741e | 2011-10-03 11:24:05 -0700 | [diff] [blame] | 1224 | // Manages the underlying memory allocation. | 
| Ian Rogers | 700a402 | 2014-05-19 16:49:03 -0700 | [diff] [blame] | 1225 | std::unique_ptr<MemMap> mem_map_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1226 |  | 
|  | 1227 | // Points to the header section. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 1228 | const Header* const header_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1229 |  | 
|  | 1230 | // Points to the base of the string identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 1231 | const StringId* const string_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1232 |  | 
|  | 1233 | // Points to the base of the type identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 1234 | const TypeId* const type_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1235 |  | 
|  | 1236 | // Points to the base of the field identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 1237 | const FieldId* const field_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1238 |  | 
|  | 1239 | // Points to the base of the method identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 1240 | const MethodId* const method_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1241 |  | 
|  | 1242 | // Points to the base of the prototype identifier list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 1243 | const ProtoId* const proto_ids_; | 
| Brian Carlstrom | 7e49dca | 2011-07-22 18:07:34 -0700 | [diff] [blame] | 1244 |  | 
|  | 1245 | // Points to the base of the class definition list. | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 1246 | const ClassDef* const class_defs_; | 
| Ian Rogers | 68b5685 | 2014-08-29 20:19:11 -0700 | [diff] [blame] | 1247 |  | 
| Richard Uhler | 07b3c23 | 2015-03-31 15:57:54 -0700 | [diff] [blame] | 1248 | // If this dex file was loaded from an oat file, oat_dex_file_ contains a | 
|  | 1249 | // pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is | 
|  | 1250 | // null. | 
|  | 1251 | const OatDexFile* oat_dex_file_; | 
| Artem Udovichenko | d9786b0 | 2015-10-14 16:36:55 +0300 | [diff] [blame] | 1252 | mutable std::unique_ptr<TypeLookupTable> lookup_table_; | 
| Andreas Gampe | e6215c0 | 2015-08-31 18:54:38 -0700 | [diff] [blame] | 1253 |  | 
|  | 1254 | friend class DexFileVerifierTest; | 
| Mathieu Chartier | 7617216 | 2016-01-26 14:54:06 -0800 | [diff] [blame] | 1255 | ART_FRIEND_TEST(ClassLinkerTest, RegisterDexFileName);  // for constructor | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 1256 | }; | 
| Mathieu Chartier | e5f13e5 | 2015-02-24 09:37:21 -0800 | [diff] [blame] | 1257 |  | 
|  | 1258 | struct DexFileReference { | 
|  | 1259 | DexFileReference(const DexFile* file, uint32_t idx) : dex_file(file), index(idx) { } | 
|  | 1260 | const DexFile* dex_file; | 
|  | 1261 | uint32_t index; | 
|  | 1262 | }; | 
|  | 1263 |  | 
| Brian Carlstrom | 0d6adac | 2014-02-05 17:39:16 -0800 | [diff] [blame] | 1264 | std::ostream& operator<<(std::ostream& os, const DexFile& dex_file); | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 1265 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1266 | // Iterate over a dex file's ProtoId's paramters | 
|  | 1267 | class DexFileParameterIterator { | 
|  | 1268 | public: | 
|  | 1269 | DexFileParameterIterator(const DexFile& dex_file, const DexFile::ProtoId& proto_id) | 
|  | 1270 | : dex_file_(dex_file), size_(0), pos_(0) { | 
|  | 1271 | type_list_ = dex_file_.GetProtoParameters(proto_id); | 
| Mathieu Chartier | 2cebb24 | 2015-04-21 16:50:40 -0700 | [diff] [blame] | 1272 | if (type_list_ != nullptr) { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1273 | size_ = type_list_->Size(); | 
|  | 1274 | } | 
|  | 1275 | } | 
|  | 1276 | bool HasNext() const { return pos_ < size_; } | 
| David Srbecky | b06e28e | 2015-12-10 13:15:00 +0000 | [diff] [blame] | 1277 | size_t Size() const { return size_; } | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1278 | void Next() { ++pos_; } | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 1279 | uint16_t GetTypeIdx() { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1280 | return type_list_->GetTypeItem(pos_).type_idx_; | 
|  | 1281 | } | 
|  | 1282 | const char* GetDescriptor() { | 
| Ian Rogers | 6d4d9fc | 2011-11-30 16:24:48 -0800 | [diff] [blame] | 1283 | return dex_file_.StringByTypeIdx(GetTypeIdx()); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1284 | } | 
|  | 1285 | private: | 
|  | 1286 | const DexFile& dex_file_; | 
|  | 1287 | const DexFile::TypeList* type_list_; | 
|  | 1288 | uint32_t size_; | 
|  | 1289 | uint32_t pos_; | 
|  | 1290 | DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator); | 
|  | 1291 | }; | 
|  | 1292 |  | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 1293 | // Abstract the signature of a method. | 
| Ian Rogers | 03b6eaf | 2014-10-28 09:34:57 -0700 | [diff] [blame] | 1294 | class Signature : public ValueObject { | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 1295 | public: | 
|  | 1296 | std::string ToString() const; | 
|  | 1297 |  | 
|  | 1298 | static Signature NoSignature() { | 
|  | 1299 | return Signature(); | 
|  | 1300 | } | 
|  | 1301 |  | 
| Ian Rogers | dfb325e | 2013-10-30 01:00:44 -0700 | [diff] [blame] | 1302 | bool operator==(const Signature& rhs) const; | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 1303 | bool operator!=(const Signature& rhs) const { | 
|  | 1304 | return !(*this == rhs); | 
|  | 1305 | } | 
|  | 1306 |  | 
| Vladimir Marko | d9cffea | 2013-11-25 15:08:02 +0000 | [diff] [blame] | 1307 | bool operator==(const StringPiece& rhs) const; | 
| Ian Rogers | d91d6d6 | 2013-09-25 20:26:14 -0700 | [diff] [blame] | 1308 |  | 
|  | 1309 | private: | 
|  | 1310 | Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) { | 
|  | 1311 | } | 
|  | 1312 |  | 
|  | 1313 | Signature() : dex_file_(nullptr), proto_id_(nullptr) { | 
|  | 1314 | } | 
|  | 1315 |  | 
|  | 1316 | friend class DexFile; | 
|  | 1317 |  | 
|  | 1318 | const DexFile* const dex_file_; | 
|  | 1319 | const DexFile::ProtoId* const proto_id_; | 
|  | 1320 | }; | 
|  | 1321 | std::ostream& operator<<(std::ostream& os, const Signature& sig); | 
|  | 1322 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1323 | // Iterate and decode class_data_item | 
|  | 1324 | class ClassDataItemIterator { | 
|  | 1325 | public: | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1326 | ClassDataItemIterator(const DexFile& dex_file, const uint8_t* raw_class_data_item) | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1327 | : dex_file_(dex_file), pos_(0), ptr_pos_(raw_class_data_item), last_idx_(0) { | 
|  | 1328 | ReadClassDataHeader(); | 
|  | 1329 | if (EndOfInstanceFieldsPos() > 0) { | 
|  | 1330 | ReadClassDataField(); | 
|  | 1331 | } else if (EndOfVirtualMethodsPos() > 0) { | 
|  | 1332 | ReadClassDataMethod(); | 
|  | 1333 | } | 
|  | 1334 | } | 
|  | 1335 | uint32_t NumStaticFields() const { | 
|  | 1336 | return header_.static_fields_size_; | 
|  | 1337 | } | 
|  | 1338 | uint32_t NumInstanceFields() const { | 
|  | 1339 | return header_.instance_fields_size_; | 
|  | 1340 | } | 
|  | 1341 | uint32_t NumDirectMethods() const { | 
|  | 1342 | return header_.direct_methods_size_; | 
|  | 1343 | } | 
|  | 1344 | uint32_t NumVirtualMethods() const { | 
|  | 1345 | return header_.virtual_methods_size_; | 
|  | 1346 | } | 
|  | 1347 | bool HasNextStaticField() const { | 
|  | 1348 | return pos_ < EndOfStaticFieldsPos(); | 
|  | 1349 | } | 
|  | 1350 | bool HasNextInstanceField() const { | 
|  | 1351 | return pos_ >= EndOfStaticFieldsPos() && pos_ < EndOfInstanceFieldsPos(); | 
|  | 1352 | } | 
|  | 1353 | bool HasNextDirectMethod() const { | 
|  | 1354 | return pos_ >= EndOfInstanceFieldsPos() && pos_ < EndOfDirectMethodsPos(); | 
|  | 1355 | } | 
|  | 1356 | bool HasNextVirtualMethod() const { | 
|  | 1357 | return pos_ >= EndOfDirectMethodsPos() && pos_ < EndOfVirtualMethodsPos(); | 
|  | 1358 | } | 
|  | 1359 | bool HasNext() const { | 
|  | 1360 | return pos_ < EndOfVirtualMethodsPos(); | 
|  | 1361 | } | 
| Ian Rogers | 637c65b | 2013-05-31 11:46:00 -0700 | [diff] [blame] | 1362 | inline void Next() { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1363 | pos_++; | 
|  | 1364 | if (pos_ < EndOfStaticFieldsPos()) { | 
|  | 1365 | last_idx_ = GetMemberIndex(); | 
|  | 1366 | ReadClassDataField(); | 
|  | 1367 | } else if (pos_ == EndOfStaticFieldsPos() && NumInstanceFields() > 0) { | 
|  | 1368 | last_idx_ = 0;  // transition to next array, reset last index | 
|  | 1369 | ReadClassDataField(); | 
|  | 1370 | } else if (pos_ < EndOfInstanceFieldsPos()) { | 
|  | 1371 | last_idx_ = GetMemberIndex(); | 
|  | 1372 | ReadClassDataField(); | 
|  | 1373 | } else if (pos_ == EndOfInstanceFieldsPos() && NumDirectMethods() > 0) { | 
|  | 1374 | last_idx_ = 0;  // transition to next array, reset last index | 
|  | 1375 | ReadClassDataMethod(); | 
|  | 1376 | } else if (pos_ < EndOfDirectMethodsPos()) { | 
|  | 1377 | last_idx_ = GetMemberIndex(); | 
|  | 1378 | ReadClassDataMethod(); | 
|  | 1379 | } else if (pos_ == EndOfDirectMethodsPos() && NumVirtualMethods() > 0) { | 
|  | 1380 | last_idx_ = 0;  // transition to next array, reset last index | 
|  | 1381 | ReadClassDataMethod(); | 
|  | 1382 | } else if (pos_ < EndOfVirtualMethodsPos()) { | 
|  | 1383 | last_idx_ = GetMemberIndex(); | 
|  | 1384 | ReadClassDataMethod(); | 
|  | 1385 | } else { | 
|  | 1386 | DCHECK(!HasNext()); | 
|  | 1387 | } | 
|  | 1388 | } | 
|  | 1389 | uint32_t GetMemberIndex() const { | 
|  | 1390 | if (pos_ < EndOfInstanceFieldsPos()) { | 
|  | 1391 | return last_idx_ + field_.field_idx_delta_; | 
|  | 1392 | } else { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 1393 | DCHECK_LT(pos_, EndOfVirtualMethodsPos()); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1394 | return last_idx_ + method_.method_idx_delta_; | 
|  | 1395 | } | 
|  | 1396 | } | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1397 | uint32_t GetRawMemberAccessFlags() const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1398 | if (pos_ < EndOfInstanceFieldsPos()) { | 
|  | 1399 | return field_.access_flags_; | 
|  | 1400 | } else { | 
| Sebastien Hertz | b24bd99 | 2013-08-02 15:19:09 +0200 | [diff] [blame] | 1401 | DCHECK_LT(pos_, EndOfVirtualMethodsPos()); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1402 | return method_.access_flags_; | 
|  | 1403 | } | 
|  | 1404 | } | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1405 | uint32_t GetFieldAccessFlags() const { | 
|  | 1406 | return GetRawMemberAccessFlags() & kAccValidFieldFlags; | 
|  | 1407 | } | 
|  | 1408 | uint32_t GetMethodAccessFlags() const { | 
|  | 1409 | return GetRawMemberAccessFlags() & kAccValidMethodFlags; | 
|  | 1410 | } | 
|  | 1411 | bool MemberIsNative() const { | 
|  | 1412 | return GetRawMemberAccessFlags() & kAccNative; | 
|  | 1413 | } | 
|  | 1414 | bool MemberIsFinal() const { | 
|  | 1415 | return GetRawMemberAccessFlags() & kAccFinal; | 
|  | 1416 | } | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 1417 | InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const { | 
|  | 1418 | if (HasNextDirectMethod()) { | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1419 | if ((GetRawMemberAccessFlags() & kAccStatic) != 0) { | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 1420 | return kStatic; | 
|  | 1421 | } else { | 
|  | 1422 | return kDirect; | 
|  | 1423 | } | 
|  | 1424 | } else { | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1425 | DCHECK_EQ(GetRawMemberAccessFlags() & kAccStatic, 0U); | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 1426 | if ((class_def.access_flags_ & kAccInterface) != 0) { | 
|  | 1427 | return kInterface; | 
| Andreas Gampe | 5182932 | 2014-08-25 15:05:04 -0700 | [diff] [blame] | 1428 | } else if ((GetRawMemberAccessFlags() & kAccConstructor) != 0) { | 
| Ian Rogers | 08f753d | 2012-08-24 14:35:25 -0700 | [diff] [blame] | 1429 | return kSuper; | 
|  | 1430 | } else { | 
|  | 1431 | return kVirtual; | 
|  | 1432 | } | 
|  | 1433 | } | 
|  | 1434 | } | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1435 | const DexFile::CodeItem* GetMethodCodeItem() const { | 
|  | 1436 | return dex_file_.GetCodeItem(method_.code_off_); | 
|  | 1437 | } | 
|  | 1438 | uint32_t GetMethodCodeItemOffset() const { | 
|  | 1439 | return method_.code_off_; | 
|  | 1440 | } | 
| Andreas Gampe | e6215c0 | 2015-08-31 18:54:38 -0700 | [diff] [blame] | 1441 | const uint8_t* DataPointer() const { | 
|  | 1442 | return ptr_pos_; | 
|  | 1443 | } | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1444 | const uint8_t* EndDataPointer() const { | 
| jeffhao | 10037c8 | 2012-01-23 15:06:23 -0800 | [diff] [blame] | 1445 | CHECK(!HasNext()); | 
|  | 1446 | return ptr_pos_; | 
|  | 1447 | } | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1448 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1449 | private: | 
|  | 1450 | // A dex file's class_data_item is leb128 encoded, this structure holds a decoded form of the | 
|  | 1451 | // header for a class_data_item | 
|  | 1452 | struct ClassDataHeader { | 
|  | 1453 | uint32_t static_fields_size_;  // the number of static fields | 
|  | 1454 | uint32_t instance_fields_size_;  // the number of instance fields | 
|  | 1455 | uint32_t direct_methods_size_;  // the number of direct methods | 
|  | 1456 | uint32_t virtual_methods_size_;  // the number of virtual methods | 
|  | 1457 | } header_; | 
|  | 1458 |  | 
|  | 1459 | // Read and decode header from a class_data_item stream into header | 
|  | 1460 | void ReadClassDataHeader(); | 
|  | 1461 |  | 
|  | 1462 | uint32_t EndOfStaticFieldsPos() const { | 
|  | 1463 | return header_.static_fields_size_; | 
|  | 1464 | } | 
|  | 1465 | uint32_t EndOfInstanceFieldsPos() const { | 
|  | 1466 | return EndOfStaticFieldsPos() + header_.instance_fields_size_; | 
|  | 1467 | } | 
|  | 1468 | uint32_t EndOfDirectMethodsPos() const { | 
|  | 1469 | return EndOfInstanceFieldsPos() + header_.direct_methods_size_; | 
|  | 1470 | } | 
|  | 1471 | uint32_t EndOfVirtualMethodsPos() const { | 
|  | 1472 | return EndOfDirectMethodsPos() + header_.virtual_methods_size_; | 
|  | 1473 | } | 
|  | 1474 |  | 
|  | 1475 | // A decoded version of the field of a class_data_item | 
|  | 1476 | struct ClassDataField { | 
|  | 1477 | uint32_t field_idx_delta_;  // delta of index into the field_ids array for FieldId | 
|  | 1478 | uint32_t access_flags_;  // access flags for the field | 
|  | 1479 | ClassDataField() :  field_idx_delta_(0), access_flags_(0) {} | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1480 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1481 | private: | 
|  | 1482 | DISALLOW_COPY_AND_ASSIGN(ClassDataField); | 
| Elliott Hughes | ee0fa76 | 2012-03-26 17:12:41 -0700 | [diff] [blame] | 1483 | }; | 
|  | 1484 | ClassDataField field_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1485 |  | 
|  | 1486 | // Read and decode a field from a class_data_item stream into field | 
|  | 1487 | void ReadClassDataField(); | 
|  | 1488 |  | 
|  | 1489 | // A decoded version of the method of a class_data_item | 
|  | 1490 | struct ClassDataMethod { | 
|  | 1491 | uint32_t method_idx_delta_;  // delta of index into the method_ids array for MethodId | 
|  | 1492 | uint32_t access_flags_; | 
|  | 1493 | uint32_t code_off_; | 
|  | 1494 | ClassDataMethod() : method_idx_delta_(0), access_flags_(0), code_off_(0) {} | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1495 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1496 | private: | 
|  | 1497 | DISALLOW_COPY_AND_ASSIGN(ClassDataMethod); | 
| Elliott Hughes | ee0fa76 | 2012-03-26 17:12:41 -0700 | [diff] [blame] | 1498 | }; | 
|  | 1499 | ClassDataMethod method_; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1500 |  | 
|  | 1501 | // Read and decode a method from a class_data_item stream into method | 
|  | 1502 | void ReadClassDataMethod(); | 
|  | 1503 |  | 
|  | 1504 | const DexFile& dex_file_; | 
|  | 1505 | size_t pos_;  // integral number of items passed | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1506 | const uint8_t* ptr_pos_;  // pointer into stream of class_data_item | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1507 | uint32_t last_idx_;  // last read field or method index to apply delta to | 
|  | 1508 | DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator); | 
|  | 1509 | }; | 
|  | 1510 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1511 | class EncodedStaticFieldValueIterator { | 
|  | 1512 | public: | 
| Shinichiro Hamaji | 82863f0 | 2015-11-05 16:51:33 +0900 | [diff] [blame] | 1513 | // A constructor for static tools. You cannot call | 
|  | 1514 | // ReadValueToField() for an object created by this. | 
|  | 1515 | EncodedStaticFieldValueIterator(const DexFile& dex_file, | 
|  | 1516 | const DexFile::ClassDef& class_def); | 
|  | 1517 |  | 
|  | 1518 | // A constructor meant to be called from runtime code. | 
| Shinichiro Hamaji | 50a2f8d | 2015-12-11 09:45:28 +0900 | [diff] [blame] | 1519 | EncodedStaticFieldValueIterator(const DexFile& dex_file, | 
|  | 1520 | Handle<mirror::DexCache>* dex_cache, | 
| Mathieu Chartier | eb8167a | 2014-05-07 15:43:14 -0700 | [diff] [blame] | 1521 | Handle<mirror::ClassLoader>* class_loader, | 
| Shinichiro Hamaji | 50a2f8d | 2015-12-11 09:45:28 +0900 | [diff] [blame] | 1522 | ClassLinker* linker, | 
|  | 1523 | const DexFile::ClassDef& class_def) | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1524 | REQUIRES_SHARED(Locks::mutator_lock_); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1525 |  | 
| Sebastien Hertz | d2fe10a | 2014-01-15 10:20:56 +0100 | [diff] [blame] | 1526 | template<bool kTransactionActive> | 
| Andreas Gampe | bdf7f1c | 2016-08-30 16:38:47 -0700 | [diff] [blame] | 1527 | void ReadValueToField(ArtField* field) const REQUIRES_SHARED(Locks::mutator_lock_); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1528 |  | 
| Ian Rogers | 6a3c1fc | 2014-10-31 00:33:20 -0700 | [diff] [blame] | 1529 | bool HasNext() const { return pos_ < array_size_; } | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1530 |  | 
|  | 1531 | void Next(); | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1532 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1533 | enum ValueType { | 
|  | 1534 | kByte = 0x00, | 
|  | 1535 | kShort = 0x02, | 
|  | 1536 | kChar = 0x03, | 
|  | 1537 | kInt = 0x04, | 
|  | 1538 | kLong = 0x06, | 
|  | 1539 | kFloat = 0x10, | 
|  | 1540 | kDouble = 0x11, | 
|  | 1541 | kString = 0x17, | 
|  | 1542 | kType = 0x18, | 
|  | 1543 | kField = 0x19, | 
|  | 1544 | kMethod = 0x1a, | 
|  | 1545 | kEnum = 0x1b, | 
|  | 1546 | kArray = 0x1c, | 
|  | 1547 | kAnnotation = 0x1d, | 
|  | 1548 | kNull = 0x1e, | 
|  | 1549 | kBoolean = 0x1f | 
|  | 1550 | }; | 
|  | 1551 |  | 
| Shinichiro Hamaji | 82863f0 | 2015-11-05 16:51:33 +0900 | [diff] [blame] | 1552 | ValueType GetValueType() const { return type_; } | 
|  | 1553 | const jvalue& GetJavaValue() const { return jval_; } | 
|  | 1554 |  | 
| Brian Carlstrom | 88f3654 | 2012-10-16 23:24:21 -0700 | [diff] [blame] | 1555 | private: | 
| Shinichiro Hamaji | 50a2f8d | 2015-12-11 09:45:28 +0900 | [diff] [blame] | 1556 | EncodedStaticFieldValueIterator(const DexFile& dex_file, | 
|  | 1557 | Handle<mirror::DexCache>* dex_cache, | 
|  | 1558 | Handle<mirror::ClassLoader>* class_loader, | 
|  | 1559 | ClassLinker* linker, | 
|  | 1560 | const DexFile::ClassDef& class_def, | 
|  | 1561 | size_t pos, | 
|  | 1562 | ValueType type); | 
|  | 1563 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1564 | static constexpr uint8_t kEncodedValueTypeMask = 0x1f;  // 0b11111 | 
|  | 1565 | static constexpr uint8_t kEncodedValueArgShift = 5; | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1566 |  | 
|  | 1567 | const DexFile& dex_file_; | 
| Mathieu Chartier | eb8167a | 2014-05-07 15:43:14 -0700 | [diff] [blame] | 1568 | Handle<mirror::DexCache>* const dex_cache_;  // Dex cache to resolve literal objects. | 
|  | 1569 | Handle<mirror::ClassLoader>* const class_loader_;  // ClassLoader to resolve types. | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 1570 | ClassLinker* linker_;  // Linker to resolve literal objects. | 
|  | 1571 | size_t array_size_;  // Size of array. | 
|  | 1572 | size_t pos_;  // Current position. | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1573 | const uint8_t* ptr_;  // Pointer into encoded data array. | 
| Ian Rogers | 2dd0e2c | 2013-01-24 12:42:14 -0800 | [diff] [blame] | 1574 | ValueType type_;  // Type of current encoded value. | 
|  | 1575 | jvalue jval_;  // Value of current encoded value. | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1576 | DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator); | 
|  | 1577 | }; | 
| Brian Carlstrom | 88f3654 | 2012-10-16 23:24:21 -0700 | [diff] [blame] | 1578 | std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1579 |  | 
|  | 1580 | class CatchHandlerIterator { | 
|  | 1581 | public: | 
|  | 1582 | CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address); | 
| Logan Chien | 736df02 | 2012-04-27 16:25:57 +0800 | [diff] [blame] | 1583 |  | 
|  | 1584 | CatchHandlerIterator(const DexFile::CodeItem& code_item, | 
|  | 1585 | const DexFile::TryItem& try_item); | 
|  | 1586 |  | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1587 | explicit CatchHandlerIterator(const uint8_t* handler_data) { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1588 | Init(handler_data); | 
|  | 1589 | } | 
|  | 1590 |  | 
|  | 1591 | uint16_t GetHandlerTypeIndex() const { | 
|  | 1592 | return handler_.type_idx_; | 
|  | 1593 | } | 
|  | 1594 | uint32_t GetHandlerAddress() const { | 
|  | 1595 | return handler_.address_; | 
|  | 1596 | } | 
|  | 1597 | void Next(); | 
|  | 1598 | bool HasNext() const { | 
|  | 1599 | return remaining_count_ != -1 || catch_all_; | 
|  | 1600 | } | 
|  | 1601 | // 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] | 1602 | const uint8_t* EndDataPointer() const { | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1603 | CHECK(!HasNext()); | 
|  | 1604 | return current_data_; | 
|  | 1605 | } | 
| Elliott Hughes | a21039c | 2012-06-21 12:09:25 -0700 | [diff] [blame] | 1606 |  | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1607 | private: | 
| Logan Chien | 736df02 | 2012-04-27 16:25:57 +0800 | [diff] [blame] | 1608 | void Init(const DexFile::CodeItem& code_item, int32_t offset); | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1609 | void Init(const uint8_t* handler_data); | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1610 |  | 
|  | 1611 | struct CatchHandlerItem { | 
|  | 1612 | uint16_t type_idx_;  // type index of the caught exception type | 
|  | 1613 | uint32_t address_;  // handler address | 
|  | 1614 | } handler_; | 
| Ian Rogers | 1373595 | 2014-10-08 12:43:28 -0700 | [diff] [blame] | 1615 | const uint8_t* current_data_;  // the current handler in dex file. | 
| Ian Rogers | 0571d35 | 2011-11-03 19:51:38 -0700 | [diff] [blame] | 1616 | int32_t remaining_count_;   // number of handlers not read. | 
|  | 1617 | bool catch_all_;            // is there a handler that will catch all exceptions in case | 
|  | 1618 | // that all typed handler does not match. | 
|  | 1619 | }; | 
|  | 1620 |  | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 1621 | }  // namespace art | 
|  | 1622 |  | 
| Brian Carlstrom | fc0e321 | 2013-07-17 14:40:12 -0700 | [diff] [blame] | 1623 | #endif  // ART_RUNTIME_DEX_FILE_H_ |