Home | History | Annotate | Download | only in runtime
      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  */
     16 
     17 #include "dex_file.h"
     18 
     19 #include <fcntl.h>
     20 #include <limits.h>
     21 #include <stdio.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 #include <sys/file.h>
     25 #include <sys/stat.h>
     26 #include <memory>
     27 
     28 #include "base/logging.h"
     29 #include "base/stringprintf.h"
     30 #include "class_linker.h"
     31 #include "dex_file-inl.h"
     32 #include "dex_file_verifier.h"
     33 #include "globals.h"
     34 #include "leb128.h"
     35 #include "mirror/art_field-inl.h"
     36 #include "mirror/art_method-inl.h"
     37 #include "mirror/string.h"
     38 #include "os.h"
     39 #include "safe_map.h"
     40 #include "ScopedFd.h"
     41 #include "handle_scope-inl.h"
     42 #include "thread.h"
     43 #include "utf-inl.h"
     44 #include "utils.h"
     45 #include "well_known_classes.h"
     46 #include "zip_archive.h"
     47 
     48 namespace art {
     49 
     50 const byte DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
     51 const byte DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
     52 
     53 static int OpenAndReadMagic(const char* filename, uint32_t* magic, std::string* error_msg) {
     54   CHECK(magic != NULL);
     55   ScopedFd fd(open(filename, O_RDONLY, 0));
     56   if (fd.get() == -1) {
     57     *error_msg = StringPrintf("Unable to open '%s' : %s", filename, strerror(errno));
     58     return -1;
     59   }
     60   int n = TEMP_FAILURE_RETRY(read(fd.get(), magic, sizeof(*magic)));
     61   if (n != sizeof(*magic)) {
     62     *error_msg = StringPrintf("Failed to find magic in '%s'", filename);
     63     return -1;
     64   }
     65   if (lseek(fd.get(), 0, SEEK_SET) != 0) {
     66     *error_msg = StringPrintf("Failed to seek to beginning of file '%s' : %s", filename,
     67                               strerror(errno));
     68     return -1;
     69   }
     70   return fd.release();
     71 }
     72 
     73 bool DexFile::GetChecksum(const char* filename, uint32_t* checksum, std::string* error_msg) {
     74   CHECK(checksum != NULL);
     75   uint32_t magic;
     76 
     77   // Strip ":...", which is the location
     78   const char* zip_entry_name = kClassesDex;
     79   const char* file_part = filename;
     80   std::string file_part_storage;
     81 
     82   if (DexFile::IsMultiDexLocation(filename)) {
     83     file_part_storage = GetBaseLocation(filename);
     84     file_part = file_part_storage.c_str();
     85     zip_entry_name = filename + file_part_storage.size() + 1;
     86     DCHECK_EQ(zip_entry_name[-1], kMultiDexSeparator);
     87   }
     88 
     89   ScopedFd fd(OpenAndReadMagic(file_part, &magic, error_msg));
     90   if (fd.get() == -1) {
     91     DCHECK(!error_msg->empty());
     92     return false;
     93   }
     94   if (IsZipMagic(magic)) {
     95     std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd.release(), filename, error_msg));
     96     if (zip_archive.get() == NULL) {
     97       *error_msg = StringPrintf("Failed to open zip archive '%s'", file_part);
     98       return false;
     99     }
    100     std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(zip_entry_name, error_msg));
    101     if (zip_entry.get() == NULL) {
    102       *error_msg = StringPrintf("Zip archive '%s' doesn't contain %s (error msg: %s)", file_part,
    103                                 zip_entry_name, error_msg->c_str());
    104       return false;
    105     }
    106     *checksum = zip_entry->GetCrc32();
    107     return true;
    108   }
    109   if (IsDexMagic(magic)) {
    110     std::unique_ptr<const DexFile> dex_file(DexFile::OpenFile(fd.release(), filename, false, error_msg));
    111     if (dex_file.get() == NULL) {
    112       return false;
    113     }
    114     *checksum = dex_file->GetHeader().checksum_;
    115     return true;
    116   }
    117   *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);
    118   return false;
    119 }
    120 
    121 bool DexFile::Open(const char* filename, const char* location, std::string* error_msg,
    122                    std::vector<const DexFile*>* dex_files) {
    123   uint32_t magic;
    124   ScopedFd fd(OpenAndReadMagic(filename, &magic, error_msg));
    125   if (fd.get() == -1) {
    126     DCHECK(!error_msg->empty());
    127     return false;
    128   }
    129   if (IsZipMagic(magic)) {
    130     return DexFile::OpenZip(fd.release(), location, error_msg, dex_files);
    131   }
    132   if (IsDexMagic(magic)) {
    133     std::unique_ptr<const DexFile> dex_file(DexFile::OpenFile(fd.release(), location, true,
    134                                                               error_msg));
    135     if (dex_file.get() != nullptr) {
    136       dex_files->push_back(dex_file.release());
    137       return true;
    138     } else {
    139       return false;
    140     }
    141   }
    142   *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);
    143   return false;
    144 }
    145 
    146 int DexFile::GetPermissions() const {
    147   if (mem_map_.get() == NULL) {
    148     return 0;
    149   } else {
    150     return mem_map_->GetProtect();
    151   }
    152 }
    153 
    154 bool DexFile::IsReadOnly() const {
    155   return GetPermissions() == PROT_READ;
    156 }
    157 
    158 bool DexFile::EnableWrite() const {
    159   CHECK(IsReadOnly());
    160   if (mem_map_.get() == NULL) {
    161     return false;
    162   } else {
    163     return mem_map_->Protect(PROT_READ | PROT_WRITE);
    164   }
    165 }
    166 
    167 bool DexFile::DisableWrite() const {
    168   CHECK(!IsReadOnly());
    169   if (mem_map_.get() == NULL) {
    170     return false;
    171   } else {
    172     return mem_map_->Protect(PROT_READ);
    173   }
    174 }
    175 
    176 const DexFile* DexFile::OpenFile(int fd, const char* location, bool verify,
    177                                  std::string* error_msg) {
    178   CHECK(location != nullptr);
    179   std::unique_ptr<MemMap> map;
    180   {
    181     ScopedFd delayed_close(fd);
    182     struct stat sbuf;
    183     memset(&sbuf, 0, sizeof(sbuf));
    184     if (fstat(fd, &sbuf) == -1) {
    185       *error_msg = StringPrintf("DexFile: fstat '%s' failed: %s", location, strerror(errno));
    186       return nullptr;
    187     }
    188     if (S_ISDIR(sbuf.st_mode)) {
    189       *error_msg = StringPrintf("Attempt to mmap directory '%s'", location);
    190       return nullptr;
    191     }
    192     size_t length = sbuf.st_size;
    193     map.reset(MemMap::MapFile(length, PROT_READ, MAP_PRIVATE, fd, 0, location, error_msg));
    194     if (map.get() == nullptr) {
    195       DCHECK(!error_msg->empty());
    196       return nullptr;
    197     }
    198   }
    199 
    200   if (map->Size() < sizeof(DexFile::Header)) {
    201     *error_msg = StringPrintf(
    202         "DexFile: failed to open dex file '%s' that is too short to have a header", location);
    203     return nullptr;
    204   }
    205 
    206   const Header* dex_header = reinterpret_cast<const Header*>(map->Begin());
    207 
    208   const DexFile* dex_file = OpenMemory(location, dex_header->checksum_, map.release(), error_msg);
    209   if (dex_file == nullptr) {
    210     *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location,
    211                               error_msg->c_str());
    212     return nullptr;
    213   }
    214 
    215   if (verify && !DexFileVerifier::Verify(dex_file, dex_file->Begin(), dex_file->Size(), location,
    216                                          error_msg)) {
    217     return nullptr;
    218   }
    219 
    220   return dex_file;
    221 }
    222 
    223 const char* DexFile::kClassesDex = "classes.dex";
    224 
    225 bool DexFile::OpenZip(int fd, const std::string& location, std::string* error_msg,
    226                       std::vector<const  DexFile*>* dex_files) {
    227   std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd, location.c_str(), error_msg));
    228   if (zip_archive.get() == nullptr) {
    229     DCHECK(!error_msg->empty());
    230     return false;
    231   }
    232   return DexFile::OpenFromZip(*zip_archive, location, error_msg, dex_files);
    233 }
    234 
    235 const DexFile* DexFile::OpenMemory(const std::string& location,
    236                                    uint32_t location_checksum,
    237                                    MemMap* mem_map,
    238                                    std::string* error_msg) {
    239   return OpenMemory(mem_map->Begin(),
    240                     mem_map->Size(),
    241                     location,
    242                     location_checksum,
    243                     mem_map,
    244                     nullptr,
    245                     error_msg);
    246 }
    247 
    248 const DexFile* DexFile::Open(const ZipArchive& zip_archive, const char* entry_name,
    249                              const std::string& location, std::string* error_msg,
    250                              ZipOpenErrorCode* error_code) {
    251   CHECK(!location.empty());
    252   std::unique_ptr<ZipEntry> zip_entry(zip_archive.Find(entry_name, error_msg));
    253   if (zip_entry.get() == NULL) {
    254     *error_code = ZipOpenErrorCode::kEntryNotFound;
    255     return nullptr;
    256   }
    257   std::unique_ptr<MemMap> map(zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg));
    258   if (map.get() == NULL) {
    259     *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", entry_name, location.c_str(),
    260                               error_msg->c_str());
    261     *error_code = ZipOpenErrorCode::kExtractToMemoryError;
    262     return nullptr;
    263   }
    264   std::unique_ptr<const DexFile> dex_file(OpenMemory(location, zip_entry->GetCrc32(), map.release(),
    265                                                error_msg));
    266   if (dex_file.get() == nullptr) {
    267     *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(),
    268                               error_msg->c_str());
    269     *error_code = ZipOpenErrorCode::kDexFileError;
    270     return nullptr;
    271   }
    272   if (!dex_file->DisableWrite()) {
    273     *error_msg = StringPrintf("Failed to make dex file '%s' read only", location.c_str());
    274     *error_code = ZipOpenErrorCode::kMakeReadOnlyError;
    275     return nullptr;
    276   }
    277   CHECK(dex_file->IsReadOnly()) << location;
    278   if (!DexFileVerifier::Verify(dex_file.get(), dex_file->Begin(), dex_file->Size(),
    279                                location.c_str(), error_msg)) {
    280     *error_code = ZipOpenErrorCode::kVerifyError;
    281     return nullptr;
    282   }
    283   *error_code = ZipOpenErrorCode::kNoError;
    284   return dex_file.release();
    285 }
    286 
    287 bool DexFile::OpenFromZip(const ZipArchive& zip_archive, const std::string& location,
    288                           std::string* error_msg, std::vector<const DexFile*>* dex_files) {
    289   ZipOpenErrorCode error_code;
    290   std::unique_ptr<const DexFile> dex_file(Open(zip_archive, kClassesDex, location, error_msg,
    291                                                &error_code));
    292   if (dex_file.get() == nullptr) {
    293     return false;
    294   } else {
    295     // Had at least classes.dex.
    296     dex_files->push_back(dex_file.release());
    297 
    298     // Now try some more.
    299     size_t i = 2;
    300 
    301     // We could try to avoid std::string allocations by working on a char array directly. As we
    302     // do not expect a lot of iterations, this seems too involved and brittle.
    303 
    304     while (i < 100) {
    305       std::string name = StringPrintf("classes%zu.dex", i);
    306       std::string fake_location = location + kMultiDexSeparator + name;
    307       std::unique_ptr<const DexFile> next_dex_file(Open(zip_archive, name.c_str(), fake_location,
    308                                                         error_msg, &error_code));
    309       if (next_dex_file.get() == nullptr) {
    310         if (error_code != ZipOpenErrorCode::kEntryNotFound) {
    311           LOG(WARNING) << error_msg;
    312         }
    313         break;
    314       } else {
    315         dex_files->push_back(next_dex_file.release());
    316       }
    317 
    318       i++;
    319     }
    320 
    321     return true;
    322   }
    323 }
    324 
    325 
    326 const DexFile* DexFile::OpenMemory(const byte* base,
    327                                    size_t size,
    328                                    const std::string& location,
    329                                    uint32_t location_checksum,
    330                                    MemMap* mem_map,
    331                                    const OatFile* oat_file,
    332                                    std::string* error_msg) {
    333   CHECK_ALIGNED(base, 4);  // various dex file structures must be word aligned
    334   std::unique_ptr<DexFile> dex_file(
    335       new DexFile(base, size, location, location_checksum, mem_map, oat_file));
    336   if (!dex_file->Init(error_msg)) {
    337     return nullptr;
    338   } else {
    339     return dex_file.release();
    340   }
    341 }
    342 
    343 DexFile::DexFile(const byte* base, size_t size,
    344                  const std::string& location,
    345                  uint32_t location_checksum,
    346                  MemMap* mem_map,
    347                  const OatFile* oat_file)
    348     : begin_(base),
    349       size_(size),
    350       location_(location),
    351       location_checksum_(location_checksum),
    352       mem_map_(mem_map),
    353       header_(reinterpret_cast<const Header*>(base)),
    354       string_ids_(reinterpret_cast<const StringId*>(base + header_->string_ids_off_)),
    355       type_ids_(reinterpret_cast<const TypeId*>(base + header_->type_ids_off_)),
    356       field_ids_(reinterpret_cast<const FieldId*>(base + header_->field_ids_off_)),
    357       method_ids_(reinterpret_cast<const MethodId*>(base + header_->method_ids_off_)),
    358       proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)),
    359       class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)),
    360       find_class_def_misses_(0),
    361       class_def_index_(nullptr),
    362       build_class_def_index_mutex_("DexFile index creation mutex"),
    363       oat_file_(oat_file) {
    364   CHECK(begin_ != NULL) << GetLocation();
    365   CHECK_GT(size_, 0U) << GetLocation();
    366 }
    367 
    368 DexFile::~DexFile() {
    369   // We don't call DeleteGlobalRef on dex_object_ because we're only called by DestroyJavaVM, and
    370   // that's only called after DetachCurrentThread, which means there's no JNIEnv. We could
    371   // re-attach, but cleaning up these global references is not obviously useful. It's not as if
    372   // the global reference table is otherwise empty!
    373   // Remove the index if one were created.
    374   delete class_def_index_.LoadRelaxed();
    375 }
    376 
    377 bool DexFile::Init(std::string* error_msg) {
    378   if (!CheckMagicAndVersion(error_msg)) {
    379     return false;
    380   }
    381   return true;
    382 }
    383 
    384 bool DexFile::CheckMagicAndVersion(std::string* error_msg) const {
    385   if (!IsMagicValid(header_->magic_)) {
    386     std::ostringstream oss;
    387     oss << "Unrecognized magic number in "  << GetLocation() << ":"
    388             << " " << header_->magic_[0]
    389             << " " << header_->magic_[1]
    390             << " " << header_->magic_[2]
    391             << " " << header_->magic_[3];
    392     *error_msg = oss.str();
    393     return false;
    394   }
    395   if (!IsVersionValid(header_->magic_)) {
    396     std::ostringstream oss;
    397     oss << "Unrecognized version number in "  << GetLocation() << ":"
    398             << " " << header_->magic_[4]
    399             << " " << header_->magic_[5]
    400             << " " << header_->magic_[6]
    401             << " " << header_->magic_[7];
    402     *error_msg = oss.str();
    403     return false;
    404   }
    405   return true;
    406 }
    407 
    408 bool DexFile::IsMagicValid(const byte* magic) {
    409   return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0);
    410 }
    411 
    412 bool DexFile::IsVersionValid(const byte* magic) {
    413   const byte* version = &magic[sizeof(kDexMagic)];
    414   return (memcmp(version, kDexMagicVersion, sizeof(kDexMagicVersion)) == 0);
    415 }
    416 
    417 uint32_t DexFile::GetVersion() const {
    418   const char* version = reinterpret_cast<const char*>(&GetHeader().magic_[sizeof(kDexMagic)]);
    419   return atoi(version);
    420 }
    421 
    422 const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor, size_t hash) const {
    423   DCHECK_EQ(ComputeModifiedUtf8Hash(descriptor), hash);
    424   // If we have an index lookup the descriptor via that as its constant time to search.
    425   Index* index = class_def_index_.LoadSequentiallyConsistent();
    426   if (index != nullptr) {
    427     auto it = index->FindWithHash(descriptor, hash);
    428     return (it == index->end()) ? nullptr : it->second;
    429   }
    430   // Fast path for rate no class defs case.
    431   uint32_t num_class_defs = NumClassDefs();
    432   if (num_class_defs == 0) {
    433     return nullptr;
    434   }
    435   // Search for class def with 2 binary searches and then a linear search.
    436   const StringId* string_id = FindStringId(descriptor);
    437   if (string_id != nullptr) {
    438     const TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id));
    439     if (type_id != nullptr) {
    440       uint16_t type_idx = GetIndexForTypeId(*type_id);
    441       for (size_t i = 0; i < num_class_defs; ++i) {
    442         const ClassDef& class_def = GetClassDef(i);
    443         if (class_def.class_idx_ == type_idx) {
    444           return &class_def;
    445         }
    446       }
    447     }
    448   }
    449   // A miss. If we've had kMaxFailedDexClassDefLookups misses then build an index to speed things
    450   // up. This isn't done eagerly at construction as construction is not performed in multi-threaded
    451   // sections of tools like dex2oat. If we're lazy we hopefully increase the chance of balancing
    452   // out which thread builds the index.
    453   find_class_def_misses_++;
    454   const uint32_t kMaxFailedDexClassDefLookups = 100;
    455   if (find_class_def_misses_ > kMaxFailedDexClassDefLookups) {
    456     MutexLock mu(Thread::Current(), build_class_def_index_mutex_);
    457     // Are we the first ones building the index?
    458     if (class_def_index_.LoadSequentiallyConsistent() == nullptr) {
    459       index = new Index;
    460       for (uint32_t i = 0; i < num_class_defs;  ++i) {
    461         const ClassDef& class_def = GetClassDef(i);
    462         const char* descriptor = GetClassDescriptor(class_def);
    463         index->Insert(std::make_pair(descriptor, &class_def));
    464       }
    465       class_def_index_.StoreSequentiallyConsistent(index);
    466     }
    467   }
    468   return nullptr;
    469 }
    470 
    471 const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const {
    472   size_t num_class_defs = NumClassDefs();
    473   for (size_t i = 0; i < num_class_defs; ++i) {
    474     const ClassDef& class_def = GetClassDef(i);
    475     if (class_def.class_idx_ == type_idx) {
    476       return &class_def;
    477     }
    478   }
    479   return NULL;
    480 }
    481 
    482 const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass,
    483                                               const DexFile::StringId& name,
    484                                               const DexFile::TypeId& type) const {
    485   // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
    486   const uint16_t class_idx = GetIndexForTypeId(declaring_klass);
    487   const uint32_t name_idx = GetIndexForStringId(name);
    488   const uint16_t type_idx = GetIndexForTypeId(type);
    489   int32_t lo = 0;
    490   int32_t hi = NumFieldIds() - 1;
    491   while (hi >= lo) {
    492     int32_t mid = (hi + lo) / 2;
    493     const DexFile::FieldId& field = GetFieldId(mid);
    494     if (class_idx > field.class_idx_) {
    495       lo = mid + 1;
    496     } else if (class_idx < field.class_idx_) {
    497       hi = mid - 1;
    498     } else {
    499       if (name_idx > field.name_idx_) {
    500         lo = mid + 1;
    501       } else if (name_idx < field.name_idx_) {
    502         hi = mid - 1;
    503       } else {
    504         if (type_idx > field.type_idx_) {
    505           lo = mid + 1;
    506         } else if (type_idx < field.type_idx_) {
    507           hi = mid - 1;
    508         } else {
    509           return &field;
    510         }
    511       }
    512     }
    513   }
    514   return NULL;
    515 }
    516 
    517 const DexFile::MethodId* DexFile::FindMethodId(const DexFile::TypeId& declaring_klass,
    518                                                const DexFile::StringId& name,
    519                                                const DexFile::ProtoId& signature) const {
    520   // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
    521   const uint16_t class_idx = GetIndexForTypeId(declaring_klass);
    522   const uint32_t name_idx = GetIndexForStringId(name);
    523   const uint16_t proto_idx = GetIndexForProtoId(signature);
    524   int32_t lo = 0;
    525   int32_t hi = NumMethodIds() - 1;
    526   while (hi >= lo) {
    527     int32_t mid = (hi + lo) / 2;
    528     const DexFile::MethodId& method = GetMethodId(mid);
    529     if (class_idx > method.class_idx_) {
    530       lo = mid + 1;
    531     } else if (class_idx < method.class_idx_) {
    532       hi = mid - 1;
    533     } else {
    534       if (name_idx > method.name_idx_) {
    535         lo = mid + 1;
    536       } else if (name_idx < method.name_idx_) {
    537         hi = mid - 1;
    538       } else {
    539         if (proto_idx > method.proto_idx_) {
    540           lo = mid + 1;
    541         } else if (proto_idx < method.proto_idx_) {
    542           hi = mid - 1;
    543         } else {
    544           return &method;
    545         }
    546       }
    547     }
    548   }
    549   return NULL;
    550 }
    551 
    552 const DexFile::StringId* DexFile::FindStringId(const char* string) const {
    553   int32_t lo = 0;
    554   int32_t hi = NumStringIds() - 1;
    555   while (hi >= lo) {
    556     int32_t mid = (hi + lo) / 2;
    557     const DexFile::StringId& str_id = GetStringId(mid);
    558     const char* str = GetStringData(str_id);
    559     int compare = CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(string, str);
    560     if (compare > 0) {
    561       lo = mid + 1;
    562     } else if (compare < 0) {
    563       hi = mid - 1;
    564     } else {
    565       return &str_id;
    566     }
    567   }
    568   return NULL;
    569 }
    570 
    571 const DexFile::StringId* DexFile::FindStringId(const uint16_t* string) const {
    572   int32_t lo = 0;
    573   int32_t hi = NumStringIds() - 1;
    574   while (hi >= lo) {
    575     int32_t mid = (hi + lo) / 2;
    576     const DexFile::StringId& str_id = GetStringId(mid);
    577     const char* str = GetStringData(str_id);
    578     int compare = CompareModifiedUtf8ToUtf16AsCodePointValues(str, string);
    579     if (compare > 0) {
    580       lo = mid + 1;
    581     } else if (compare < 0) {
    582       hi = mid - 1;
    583     } else {
    584       return &str_id;
    585     }
    586   }
    587   return NULL;
    588 }
    589 
    590 const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const {
    591   int32_t lo = 0;
    592   int32_t hi = NumTypeIds() - 1;
    593   while (hi >= lo) {
    594     int32_t mid = (hi + lo) / 2;
    595     const TypeId& type_id = GetTypeId(mid);
    596     if (string_idx > type_id.descriptor_idx_) {
    597       lo = mid + 1;
    598     } else if (string_idx < type_id.descriptor_idx_) {
    599       hi = mid - 1;
    600     } else {
    601       return &type_id;
    602     }
    603   }
    604   return NULL;
    605 }
    606 
    607 const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx,
    608                                              const uint16_t* signature_type_idxs,
    609                                              uint32_t signature_length) const {
    610   int32_t lo = 0;
    611   int32_t hi = NumProtoIds() - 1;
    612   while (hi >= lo) {
    613     int32_t mid = (hi + lo) / 2;
    614     const DexFile::ProtoId& proto = GetProtoId(mid);
    615     int compare = return_type_idx - proto.return_type_idx_;
    616     if (compare == 0) {
    617       DexFileParameterIterator it(*this, proto);
    618       size_t i = 0;
    619       while (it.HasNext() && i < signature_length && compare == 0) {
    620         compare = signature_type_idxs[i] - it.GetTypeIdx();
    621         it.Next();
    622         i++;
    623       }
    624       if (compare == 0) {
    625         if (it.HasNext()) {
    626           compare = -1;
    627         } else if (i < signature_length) {
    628           compare = 1;
    629         }
    630       }
    631     }
    632     if (compare > 0) {
    633       lo = mid + 1;
    634     } else if (compare < 0) {
    635       hi = mid - 1;
    636     } else {
    637       return &proto;
    638     }
    639   }
    640   return NULL;
    641 }
    642 
    643 // Given a signature place the type ids into the given vector
    644 bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx,
    645                              std::vector<uint16_t>* param_type_idxs) const {
    646   if (signature[0] != '(') {
    647     return false;
    648   }
    649   size_t offset = 1;
    650   size_t end = signature.size();
    651   bool process_return = false;
    652   while (offset < end) {
    653     size_t start_offset = offset;
    654     char c = signature[offset];
    655     offset++;
    656     if (c == ')') {
    657       process_return = true;
    658       continue;
    659     }
    660     while (c == '[') {  // process array prefix
    661       if (offset >= end) {  // expect some descriptor following [
    662         return false;
    663       }
    664       c = signature[offset];
    665       offset++;
    666     }
    667     if (c == 'L') {  // process type descriptors
    668       do {
    669         if (offset >= end) {  // unexpected early termination of descriptor
    670           return false;
    671         }
    672         c = signature[offset];
    673         offset++;
    674       } while (c != ';');
    675     }
    676     // TODO: avoid creating a std::string just to get a 0-terminated char array
    677     std::string descriptor(signature.data() + start_offset, offset - start_offset);
    678     const DexFile::StringId* string_id = FindStringId(descriptor.c_str());
    679     if (string_id == NULL) {
    680       return false;
    681     }
    682     const DexFile::TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id));
    683     if (type_id == NULL) {
    684       return false;
    685     }
    686     uint16_t type_idx = GetIndexForTypeId(*type_id);
    687     if (!process_return) {
    688       param_type_idxs->push_back(type_idx);
    689     } else {
    690       *return_type_idx = type_idx;
    691       return offset == end;  // return true if the signature had reached a sensible end
    692     }
    693   }
    694   return false;  // failed to correctly parse return type
    695 }
    696 
    697 const Signature DexFile::CreateSignature(const StringPiece& signature) const {
    698   uint16_t return_type_idx;
    699   std::vector<uint16_t> param_type_indices;
    700   bool success = CreateTypeList(signature, &return_type_idx, &param_type_indices);
    701   if (!success) {
    702     return Signature::NoSignature();
    703   }
    704   const ProtoId* proto_id = FindProtoId(return_type_idx, param_type_indices);
    705   if (proto_id == NULL) {
    706     return Signature::NoSignature();
    707   }
    708   return Signature(this, *proto_id);
    709 }
    710 
    711 int32_t DexFile::GetLineNumFromPC(mirror::ArtMethod* method, uint32_t rel_pc) const {
    712   // For native method, lineno should be -2 to indicate it is native. Note that
    713   // "line number == -2" is how libcore tells from StackTraceElement.
    714   if (method->GetCodeItemOffset() == 0) {
    715     return -2;
    716   }
    717 
    718   const CodeItem* code_item = GetCodeItem(method->GetCodeItemOffset());
    719   DCHECK(code_item != NULL) << PrettyMethod(method) << " " << GetLocation();
    720 
    721   // A method with no line number info should return -1
    722   LineNumFromPcContext context(rel_pc, -1);
    723   DecodeDebugInfo(code_item, method->IsStatic(), method->GetDexMethodIndex(), LineNumForPcCb,
    724                   NULL, &context);
    725   return context.line_num_;
    726 }
    727 
    728 int32_t DexFile::FindTryItem(const CodeItem &code_item, uint32_t address) {
    729   // Note: Signed type is important for max and min.
    730   int32_t min = 0;
    731   int32_t max = code_item.tries_size_ - 1;
    732 
    733   while (min <= max) {
    734     int32_t mid = min + ((max - min) / 2);
    735 
    736     const art::DexFile::TryItem* ti = GetTryItems(code_item, mid);
    737     uint32_t start = ti->start_addr_;
    738     uint32_t end = start + ti->insn_count_;
    739 
    740     if (address < start) {
    741       max = mid - 1;
    742     } else if (address >= end) {
    743       min = mid + 1;
    744     } else {  // We have a winner!
    745       return mid;
    746     }
    747   }
    748   // No match.
    749   return -1;
    750 }
    751 
    752 int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address) {
    753   int32_t try_item = FindTryItem(code_item, address);
    754   if (try_item == -1) {
    755     return -1;
    756   } else {
    757     return DexFile::GetTryItems(code_item, try_item)->handler_off_;
    758   }
    759 }
    760 
    761 void DexFile::DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx,
    762                                DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
    763                                void* context, const byte* stream, LocalInfo* local_in_reg) const {
    764   uint32_t line = DecodeUnsignedLeb128(&stream);
    765   uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
    766   uint16_t arg_reg = code_item->registers_size_ - code_item->ins_size_;
    767   uint32_t address = 0;
    768   bool need_locals = (local_cb != NULL);
    769 
    770   if (!is_static) {
    771     if (need_locals) {
    772       const char* descriptor = GetMethodDeclaringClassDescriptor(GetMethodId(method_idx));
    773       local_in_reg[arg_reg].name_ = "this";
    774       local_in_reg[arg_reg].descriptor_ = descriptor;
    775       local_in_reg[arg_reg].signature_ = NULL;
    776       local_in_reg[arg_reg].start_address_ = 0;
    777       local_in_reg[arg_reg].is_live_ = true;
    778     }
    779     arg_reg++;
    780   }
    781 
    782   DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx)));
    783   for (uint32_t i = 0; i < parameters_size && it.HasNext(); ++i, it.Next()) {
    784     if (arg_reg >= code_item->registers_size_) {
    785       LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg
    786                  << " >= " << code_item->registers_size_ << ") in " << GetLocation();
    787       return;
    788     }
    789     uint32_t id = DecodeUnsignedLeb128P1(&stream);
    790     const char* descriptor = it.GetDescriptor();
    791     if (need_locals && id != kDexNoIndex) {
    792       const char* name = StringDataByIdx(id);
    793       local_in_reg[arg_reg].name_ = name;
    794       local_in_reg[arg_reg].descriptor_ = descriptor;
    795       local_in_reg[arg_reg].signature_ = NULL;
    796       local_in_reg[arg_reg].start_address_ = address;
    797       local_in_reg[arg_reg].is_live_ = true;
    798     }
    799     switch (*descriptor) {
    800       case 'D':
    801       case 'J':
    802         arg_reg += 2;
    803         break;
    804       default:
    805         arg_reg += 1;
    806         break;
    807     }
    808   }
    809 
    810   if (it.HasNext()) {
    811     LOG(ERROR) << "invalid stream - problem with parameter iterator in " << GetLocation()
    812                << " for method " << PrettyMethod(method_idx, *this);
    813     return;
    814   }
    815 
    816   for (;;)  {
    817     uint8_t opcode = *stream++;
    818     uint16_t reg;
    819     uint32_t name_idx;
    820     uint32_t descriptor_idx;
    821     uint32_t signature_idx = 0;
    822 
    823     switch (opcode) {
    824       case DBG_END_SEQUENCE:
    825         return;
    826 
    827       case DBG_ADVANCE_PC:
    828         address += DecodeUnsignedLeb128(&stream);
    829         break;
    830 
    831       case DBG_ADVANCE_LINE:
    832         line += DecodeSignedLeb128(&stream);
    833         break;
    834 
    835       case DBG_START_LOCAL:
    836       case DBG_START_LOCAL_EXTENDED:
    837         reg = DecodeUnsignedLeb128(&stream);
    838         if (reg > code_item->registers_size_) {
    839           LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > "
    840                      << code_item->registers_size_ << ") in " << GetLocation();
    841           return;
    842         }
    843 
    844         name_idx = DecodeUnsignedLeb128P1(&stream);
    845         descriptor_idx = DecodeUnsignedLeb128P1(&stream);
    846         if (opcode == DBG_START_LOCAL_EXTENDED) {
    847           signature_idx = DecodeUnsignedLeb128P1(&stream);
    848         }
    849 
    850         // Emit what was previously there, if anything
    851         if (need_locals) {
    852           InvokeLocalCbIfLive(context, reg, address, local_in_reg, local_cb);
    853 
    854           local_in_reg[reg].name_ = StringDataByIdx(name_idx);
    855           local_in_reg[reg].descriptor_ = StringByTypeIdx(descriptor_idx);
    856           if (opcode == DBG_START_LOCAL_EXTENDED) {
    857             local_in_reg[reg].signature_ = StringDataByIdx(signature_idx);
    858           }
    859           local_in_reg[reg].start_address_ = address;
    860           local_in_reg[reg].is_live_ = true;
    861         }
    862         break;
    863 
    864       case DBG_END_LOCAL:
    865         reg = DecodeUnsignedLeb128(&stream);
    866         if (reg > code_item->registers_size_) {
    867           LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > "
    868                      << code_item->registers_size_ << ") in " << GetLocation();
    869           return;
    870         }
    871 
    872         if (need_locals) {
    873           InvokeLocalCbIfLive(context, reg, address, local_in_reg, local_cb);
    874           local_in_reg[reg].is_live_ = false;
    875         }
    876         break;
    877 
    878       case DBG_RESTART_LOCAL:
    879         reg = DecodeUnsignedLeb128(&stream);
    880         if (reg > code_item->registers_size_) {
    881           LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > "
    882                      << code_item->registers_size_ << ") in " << GetLocation();
    883           return;
    884         }
    885 
    886         if (need_locals) {
    887           if (local_in_reg[reg].name_ == NULL || local_in_reg[reg].descriptor_ == NULL) {
    888             LOG(ERROR) << "invalid stream - no name or descriptor in " << GetLocation();
    889             return;
    890           }
    891 
    892           // If the register is live, the "restart" is superfluous,
    893           // and we don't want to mess with the existing start address.
    894           if (!local_in_reg[reg].is_live_) {
    895             local_in_reg[reg].start_address_ = address;
    896             local_in_reg[reg].is_live_ = true;
    897           }
    898         }
    899         break;
    900 
    901       case DBG_SET_PROLOGUE_END:
    902       case DBG_SET_EPILOGUE_BEGIN:
    903       case DBG_SET_FILE:
    904         break;
    905 
    906       default: {
    907         int adjopcode = opcode - DBG_FIRST_SPECIAL;
    908 
    909         address += adjopcode / DBG_LINE_RANGE;
    910         line += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
    911 
    912         if (position_cb != NULL) {
    913           if (position_cb(context, address, line)) {
    914             // early exit
    915             return;
    916           }
    917         }
    918         break;
    919       }
    920     }
    921   }
    922 }
    923 
    924 void DexFile::DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
    925                               DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
    926                               void* context) const {
    927   DCHECK(code_item != nullptr);
    928   const byte* stream = GetDebugInfoStream(code_item);
    929   std::unique_ptr<LocalInfo[]> local_in_reg(local_cb != NULL ?
    930                                       new LocalInfo[code_item->registers_size_] :
    931                                       NULL);
    932   if (stream != NULL) {
    933     DecodeDebugInfo0(code_item, is_static, method_idx, position_cb, local_cb, context, stream, &local_in_reg[0]);
    934   }
    935   for (int reg = 0; reg < code_item->registers_size_; reg++) {
    936     InvokeLocalCbIfLive(context, reg, code_item->insns_size_in_code_units_, &local_in_reg[0], local_cb);
    937   }
    938 }
    939 
    940 bool DexFile::LineNumForPcCb(void* raw_context, uint32_t address, uint32_t line_num) {
    941   LineNumFromPcContext* context = reinterpret_cast<LineNumFromPcContext*>(raw_context);
    942 
    943   // We know that this callback will be called in
    944   // ascending address order, so keep going until we find
    945   // a match or we've just gone past it.
    946   if (address > context->address_) {
    947     // The line number from the previous positions callback
    948     // wil be the final result.
    949     return true;
    950   } else {
    951     context->line_num_ = line_num;
    952     return address == context->address_;
    953   }
    954 }
    955 
    956 bool DexFile::IsMultiDexLocation(const char* location) {
    957   return strrchr(location, kMultiDexSeparator) != nullptr;
    958 }
    959 
    960 std::string DexFile::GetMultiDexClassesDexName(size_t number, const char* dex_location) {
    961   if (number == 0) {
    962     return dex_location;
    963   } else {
    964     return StringPrintf("%s" kMultiDexSeparatorString "classes%zu.dex", dex_location, number + 1);
    965   }
    966 }
    967 
    968 std::string DexFile::GetDexCanonicalLocation(const char* dex_location) {
    969   CHECK_NE(dex_location, static_cast<const char*>(nullptr));
    970   std::string base_location = GetBaseLocation(dex_location);
    971   const char* suffix = dex_location + base_location.size();
    972   DCHECK(suffix[0] == 0 || suffix[0] == kMultiDexSeparator);
    973   UniqueCPtr<const char[]> path(realpath(base_location.c_str(), nullptr));
    974   if (path != nullptr && path.get() != base_location) {
    975     return std::string(path.get()) + suffix;
    976   } else if (suffix[0] == 0) {
    977     return base_location;
    978   } else {
    979     return dex_location;
    980   }
    981 }
    982 
    983 std::ostream& operator<<(std::ostream& os, const DexFile& dex_file) {
    984   os << StringPrintf("[DexFile: %s dex-checksum=%08x location-checksum=%08x %p-%p]",
    985                      dex_file.GetLocation().c_str(),
    986                      dex_file.GetHeader().checksum_, dex_file.GetLocationChecksum(),
    987                      dex_file.Begin(), dex_file.Begin() + dex_file.Size());
    988   return os;
    989 }
    990 
    991 std::string Signature::ToString() const {
    992   if (dex_file_ == nullptr) {
    993     CHECK(proto_id_ == nullptr);
    994     return "<no signature>";
    995   }
    996   const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
    997   std::string result;
    998   if (params == nullptr) {
    999     result += "()";
   1000   } else {
   1001     result += "(";
   1002     for (uint32_t i = 0; i < params->Size(); ++i) {
   1003       result += dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_);
   1004     }
   1005     result += ")";
   1006   }
   1007   result += dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
   1008   return result;
   1009 }
   1010 
   1011 bool Signature::operator==(const StringPiece& rhs) const {
   1012   if (dex_file_ == nullptr) {
   1013     return false;
   1014   }
   1015   StringPiece tail(rhs);
   1016   if (!tail.starts_with("(")) {
   1017     return false;  // Invalid signature
   1018   }
   1019   tail.remove_prefix(1);  // "(";
   1020   const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
   1021   if (params != nullptr) {
   1022     for (uint32_t i = 0; i < params->Size(); ++i) {
   1023       StringPiece param(dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_));
   1024       if (!tail.starts_with(param)) {
   1025         return false;
   1026       }
   1027       tail.remove_prefix(param.length());
   1028     }
   1029   }
   1030   if (!tail.starts_with(")")) {
   1031     return false;
   1032   }
   1033   tail.remove_prefix(1);  // ")";
   1034   return tail == dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
   1035 }
   1036 
   1037 std::ostream& operator<<(std::ostream& os, const Signature& sig) {
   1038   return os << sig.ToString();
   1039 }
   1040 
   1041 // Decodes the header section from the class data bytes.
   1042 void ClassDataItemIterator::ReadClassDataHeader() {
   1043   CHECK(ptr_pos_ != NULL);
   1044   header_.static_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_);
   1045   header_.instance_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_);
   1046   header_.direct_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_);
   1047   header_.virtual_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_);
   1048 }
   1049 
   1050 void ClassDataItemIterator::ReadClassDataField() {
   1051   field_.field_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_);
   1052   field_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
   1053   if (last_idx_ != 0 && field_.field_idx_delta_ == 0) {
   1054     LOG(WARNING) << "Duplicate field in " << dex_file_.GetLocation();
   1055   }
   1056 }
   1057 
   1058 void ClassDataItemIterator::ReadClassDataMethod() {
   1059   method_.method_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_);
   1060   method_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
   1061   method_.code_off_ = DecodeUnsignedLeb128(&ptr_pos_);
   1062   if (last_idx_ != 0 && method_.method_idx_delta_ == 0) {
   1063     LOG(WARNING) << "Duplicate method in " << dex_file_.GetLocation();
   1064   }
   1065 }
   1066 
   1067 // Read a signed integer.  "zwidth" is the zero-based byte count.
   1068 static int32_t ReadSignedInt(const byte* ptr, int zwidth) {
   1069   int32_t val = 0;
   1070   for (int i = zwidth; i >= 0; --i) {
   1071     val = ((uint32_t)val >> 8) | (((int32_t)*ptr++) << 24);
   1072   }
   1073   val >>= (3 - zwidth) * 8;
   1074   return val;
   1075 }
   1076 
   1077 // Read an unsigned integer.  "zwidth" is the zero-based byte count,
   1078 // "fill_on_right" indicates which side we want to zero-fill from.
   1079 static uint32_t ReadUnsignedInt(const byte* ptr, int zwidth, bool fill_on_right) {
   1080   uint32_t val = 0;
   1081   if (!fill_on_right) {
   1082     for (int i = zwidth; i >= 0; --i) {
   1083       val = (val >> 8) | (((uint32_t)*ptr++) << 24);
   1084     }
   1085     val >>= (3 - zwidth) * 8;
   1086   } else {
   1087     for (int i = zwidth; i >= 0; --i) {
   1088       val = (val >> 8) | (((uint32_t)*ptr++) << 24);
   1089     }
   1090   }
   1091   return val;
   1092 }
   1093 
   1094 // Read a signed long.  "zwidth" is the zero-based byte count.
   1095 static int64_t ReadSignedLong(const byte* ptr, int zwidth) {
   1096   int64_t val = 0;
   1097   for (int i = zwidth; i >= 0; --i) {
   1098     val = ((uint64_t)val >> 8) | (((int64_t)*ptr++) << 56);
   1099   }
   1100   val >>= (7 - zwidth) * 8;
   1101   return val;
   1102 }
   1103 
   1104 // Read an unsigned long.  "zwidth" is the zero-based byte count,
   1105 // "fill_on_right" indicates which side we want to zero-fill from.
   1106 static uint64_t ReadUnsignedLong(const byte* ptr, int zwidth, bool fill_on_right) {
   1107   uint64_t val = 0;
   1108   if (!fill_on_right) {
   1109     for (int i = zwidth; i >= 0; --i) {
   1110       val = (val >> 8) | (((uint64_t)*ptr++) << 56);
   1111     }
   1112     val >>= (7 - zwidth) * 8;
   1113   } else {
   1114     for (int i = zwidth; i >= 0; --i) {
   1115       val = (val >> 8) | (((uint64_t)*ptr++) << 56);
   1116     }
   1117   }
   1118   return val;
   1119 }
   1120 
   1121 EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(const DexFile& dex_file,
   1122                                                                  Handle<mirror::DexCache>* dex_cache,
   1123                                                                  Handle<mirror::ClassLoader>* class_loader,
   1124                                                                  ClassLinker* linker,
   1125                                                                  const DexFile::ClassDef& class_def)
   1126     : dex_file_(dex_file), dex_cache_(dex_cache), class_loader_(class_loader), linker_(linker),
   1127       array_size_(), pos_(-1), type_(kByte) {
   1128   DCHECK(dex_cache != nullptr);
   1129   DCHECK(class_loader != nullptr);
   1130   ptr_ = dex_file.GetEncodedStaticFieldValuesArray(class_def);
   1131   if (ptr_ == NULL) {
   1132     array_size_ = 0;
   1133   } else {
   1134     array_size_ = DecodeUnsignedLeb128(&ptr_);
   1135   }
   1136   if (array_size_ > 0) {
   1137     Next();
   1138   }
   1139 }
   1140 
   1141 void EncodedStaticFieldValueIterator::Next() {
   1142   pos_++;
   1143   if (pos_ >= array_size_) {
   1144     return;
   1145   }
   1146   byte value_type = *ptr_++;
   1147   byte value_arg = value_type >> kEncodedValueArgShift;
   1148   size_t width = value_arg + 1;  // assume and correct later
   1149   type_ = static_cast<ValueType>(value_type & kEncodedValueTypeMask);
   1150   switch (type_) {
   1151   case kBoolean:
   1152     jval_.i = (value_arg != 0) ? 1 : 0;
   1153     width = 0;
   1154     break;
   1155   case kByte:
   1156     jval_.i = ReadSignedInt(ptr_, value_arg);
   1157     CHECK(IsInt(8, jval_.i));
   1158     break;
   1159   case kShort:
   1160     jval_.i = ReadSignedInt(ptr_, value_arg);
   1161     CHECK(IsInt(16, jval_.i));
   1162     break;
   1163   case kChar:
   1164     jval_.i = ReadUnsignedInt(ptr_, value_arg, false);
   1165     CHECK(IsUint(16, jval_.i));
   1166     break;
   1167   case kInt:
   1168     jval_.i = ReadSignedInt(ptr_, value_arg);
   1169     break;
   1170   case kLong:
   1171     jval_.j = ReadSignedLong(ptr_, value_arg);
   1172     break;
   1173   case kFloat:
   1174     jval_.i = ReadUnsignedInt(ptr_, value_arg, true);
   1175     break;
   1176   case kDouble:
   1177     jval_.j = ReadUnsignedLong(ptr_, value_arg, true);
   1178     break;
   1179   case kString:
   1180   case kType:
   1181     jval_.i = ReadUnsignedInt(ptr_, value_arg, false);
   1182     break;
   1183   case kField:
   1184   case kMethod:
   1185   case kEnum:
   1186   case kArray:
   1187   case kAnnotation:
   1188     UNIMPLEMENTED(FATAL) << ": type " << type_;
   1189     break;
   1190   case kNull:
   1191     jval_.l = NULL;
   1192     width = 0;
   1193     break;
   1194   default:
   1195     LOG(FATAL) << "Unreached";
   1196   }
   1197   ptr_ += width;
   1198 }
   1199 
   1200 template<bool kTransactionActive>
   1201 void EncodedStaticFieldValueIterator::ReadValueToField(mirror::ArtField* field) const {
   1202   switch (type_) {
   1203     case kBoolean: field->SetBoolean<kTransactionActive>(field->GetDeclaringClass(), jval_.z); break;
   1204     case kByte:    field->SetByte<kTransactionActive>(field->GetDeclaringClass(), jval_.b); break;
   1205     case kShort:   field->SetShort<kTransactionActive>(field->GetDeclaringClass(), jval_.s); break;
   1206     case kChar:    field->SetChar<kTransactionActive>(field->GetDeclaringClass(), jval_.c); break;
   1207     case kInt:     field->SetInt<kTransactionActive>(field->GetDeclaringClass(), jval_.i); break;
   1208     case kLong:    field->SetLong<kTransactionActive>(field->GetDeclaringClass(), jval_.j); break;
   1209     case kFloat:   field->SetFloat<kTransactionActive>(field->GetDeclaringClass(), jval_.f); break;
   1210     case kDouble:  field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break;
   1211     case kNull:    field->SetObject<kTransactionActive>(field->GetDeclaringClass(), NULL); break;
   1212     case kString: {
   1213       CHECK(!kMovingFields);
   1214       mirror::String* resolved = linker_->ResolveString(dex_file_, jval_.i, *dex_cache_);
   1215       field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
   1216       break;
   1217     }
   1218     case kType: {
   1219       CHECK(!kMovingFields);
   1220       mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, *dex_cache_,
   1221                                                      *class_loader_);
   1222       field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
   1223       break;
   1224     }
   1225     default: UNIMPLEMENTED(FATAL) << ": type " << type_;
   1226   }
   1227 }
   1228 template void EncodedStaticFieldValueIterator::ReadValueToField<true>(mirror::ArtField* field) const;
   1229 template void EncodedStaticFieldValueIterator::ReadValueToField<false>(mirror::ArtField* field) const;
   1230 
   1231 CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address) {
   1232   handler_.address_ = -1;
   1233   int32_t offset = -1;
   1234 
   1235   // Short-circuit the overwhelmingly common cases.
   1236   switch (code_item.tries_size_) {
   1237     case 0:
   1238       break;
   1239     case 1: {
   1240       const DexFile::TryItem* tries = DexFile::GetTryItems(code_item, 0);
   1241       uint32_t start = tries->start_addr_;
   1242       if (address >= start) {
   1243         uint32_t end = start + tries->insn_count_;
   1244         if (address < end) {
   1245           offset = tries->handler_off_;
   1246         }
   1247       }
   1248       break;
   1249     }
   1250     default:
   1251       offset = DexFile::FindCatchHandlerOffset(code_item, address);
   1252   }
   1253   Init(code_item, offset);
   1254 }
   1255 
   1256 CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item,
   1257                                            const DexFile::TryItem& try_item) {
   1258   handler_.address_ = -1;
   1259   Init(code_item, try_item.handler_off_);
   1260 }
   1261 
   1262 void CatchHandlerIterator::Init(const DexFile::CodeItem& code_item,
   1263                                 int32_t offset) {
   1264   if (offset >= 0) {
   1265     Init(DexFile::GetCatchHandlerData(code_item, offset));
   1266   } else {
   1267     // Not found, initialize as empty
   1268     current_data_ = NULL;
   1269     remaining_count_ = -1;
   1270     catch_all_ = false;
   1271     DCHECK(!HasNext());
   1272   }
   1273 }
   1274 
   1275 void CatchHandlerIterator::Init(const byte* handler_data) {
   1276   current_data_ = handler_data;
   1277   remaining_count_ = DecodeSignedLeb128(&current_data_);
   1278 
   1279   // If remaining_count_ is non-positive, then it is the negative of
   1280   // the number of catch types, and the catches are followed by a
   1281   // catch-all handler.
   1282   if (remaining_count_ <= 0) {
   1283     catch_all_ = true;
   1284     remaining_count_ = -remaining_count_;
   1285   } else {
   1286     catch_all_ = false;
   1287   }
   1288   Next();
   1289 }
   1290 
   1291 void CatchHandlerIterator::Next() {
   1292   if (remaining_count_ > 0) {
   1293     handler_.type_idx_ = DecodeUnsignedLeb128(&current_data_);
   1294     handler_.address_  = DecodeUnsignedLeb128(&current_data_);
   1295     remaining_count_--;
   1296     return;
   1297   }
   1298 
   1299   if (catch_all_) {
   1300     handler_.type_idx_ = DexFile::kDexNoIndex16;
   1301     handler_.address_  = DecodeUnsignedLeb128(&current_data_);
   1302     catch_all_ = false;
   1303     return;
   1304   }
   1305 
   1306   // no more handler
   1307   remaining_count_ = -1;
   1308 }
   1309 
   1310 }  // namespace art
   1311