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