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/mman.h>  // For the PROT_* and MAP_* constants.
26#include <sys/stat.h>
27#include <zlib.h>
28
29#include <memory>
30#include <sstream>
31#include <type_traits>
32
33#include "android-base/stringprintf.h"
34
35#include "base/enums.h"
36#include "base/file_magic.h"
37#include "base/logging.h"
38#include "base/systrace.h"
39#include "base/unix_file/fd_file.h"
40#include "dex_file-inl.h"
41#include "dex_file_verifier.h"
42#include "jvalue.h"
43#include "leb128.h"
44#include "os.h"
45#include "utf-inl.h"
46#include "utils.h"
47#include "zip_archive.h"
48
49namespace art {
50
51using android::base::StringPrintf;
52
53static_assert(sizeof(dex::StringIndex) == sizeof(uint32_t), "StringIndex size is wrong");
54static_assert(std::is_trivially_copyable<dex::StringIndex>::value, "StringIndex not trivial");
55static_assert(sizeof(dex::TypeIndex) == sizeof(uint16_t), "TypeIndex size is wrong");
56static_assert(std::is_trivially_copyable<dex::TypeIndex>::value, "TypeIndex not trivial");
57
58static constexpr OatDexFile* kNoOatDexFile = nullptr;
59
60const char* DexFile::kClassesDex = "classes.dex";
61
62const uint8_t DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
63const uint8_t DexFile::kDexMagicVersions[DexFile::kNumDexVersions][DexFile::kDexVersionLen] = {
64  {'0', '3', '5', '\0'},
65  // Dex version 036 skipped because of an old dalvik bug on some versions of android where dex
66  // files with that version number would erroneously be accepted and run.
67  {'0', '3', '7', '\0'},
68  // Dex version 038: Android "O" and beyond.
69  {'0', '3', '8', '\0'}
70};
71
72uint32_t DexFile::CalculateChecksum() const {
73  const uint32_t non_sum = OFFSETOF_MEMBER(DexFile::Header, signature_);
74  const uint8_t* non_sum_ptr = Begin() + non_sum;
75  return adler32(adler32(0L, Z_NULL, 0), non_sum_ptr, Size() - non_sum);
76}
77
78struct DexFile::AnnotationValue {
79  JValue value_;
80  uint8_t type_;
81};
82
83bool DexFile::GetMultiDexChecksums(const char* filename,
84                                   std::vector<uint32_t>* checksums,
85                                   std::string* error_msg) {
86  CHECK(checksums != nullptr);
87  uint32_t magic;
88
89  File fd = OpenAndReadMagic(filename, &magic, error_msg);
90  if (fd.Fd() == -1) {
91    DCHECK(!error_msg->empty());
92    return false;
93  }
94  if (IsZipMagic(magic)) {
95    std::unique_ptr<ZipArchive> zip_archive(
96        ZipArchive::OpenFromFd(fd.Release(), filename, error_msg));
97    if (zip_archive.get() == nullptr) {
98      *error_msg = StringPrintf("Failed to open zip archive '%s' (error msg: %s)", filename,
99                                error_msg->c_str());
100      return false;
101    }
102
103    uint32_t i = 0;
104    std::string zip_entry_name = GetMultiDexClassesDexName(i++);
105    std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(zip_entry_name.c_str(), error_msg));
106    if (zip_entry.get() == nullptr) {
107      *error_msg = StringPrintf("Zip archive '%s' doesn't contain %s (error msg: %s)", filename,
108          zip_entry_name.c_str(), error_msg->c_str());
109      return false;
110    }
111
112    do {
113      checksums->push_back(zip_entry->GetCrc32());
114      zip_entry_name = DexFile::GetMultiDexClassesDexName(i++);
115      zip_entry.reset(zip_archive->Find(zip_entry_name.c_str(), error_msg));
116    } while (zip_entry.get() != nullptr);
117    return true;
118  }
119  if (IsDexMagic(magic)) {
120    std::unique_ptr<const DexFile> dex_file(
121        DexFile::OpenFile(fd.Release(), filename, false, false, error_msg));
122    if (dex_file.get() == nullptr) {
123      return false;
124    }
125    checksums->push_back(dex_file->GetHeader().checksum_);
126    return true;
127  }
128  *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);
129  return false;
130}
131
132int DexFile::GetPermissions() const {
133  if (mem_map_.get() == nullptr) {
134    return 0;
135  } else {
136    return mem_map_->GetProtect();
137  }
138}
139
140bool DexFile::IsReadOnly() const {
141  return GetPermissions() == PROT_READ;
142}
143
144bool DexFile::EnableWrite() const {
145  CHECK(IsReadOnly());
146  if (mem_map_.get() == nullptr) {
147    return false;
148  } else {
149    return mem_map_->Protect(PROT_READ | PROT_WRITE);
150  }
151}
152
153bool DexFile::DisableWrite() const {
154  CHECK(!IsReadOnly());
155  if (mem_map_.get() == nullptr) {
156    return false;
157  } else {
158    return mem_map_->Protect(PROT_READ);
159  }
160}
161
162
163std::unique_ptr<const DexFile> DexFile::Open(const uint8_t* base,
164                                             size_t size,
165                                             const std::string& location,
166                                             uint32_t location_checksum,
167                                             const OatDexFile* oat_dex_file,
168                                             bool verify,
169                                             bool verify_checksum,
170                                             std::string* error_msg) {
171  ScopedTrace trace(std::string("Open dex file from RAM ") + location);
172  return OpenCommon(base,
173                    size,
174                    location,
175                    location_checksum,
176                    oat_dex_file,
177                    verify,
178                    verify_checksum,
179                    error_msg);
180}
181
182std::unique_ptr<const DexFile> DexFile::Open(const std::string& location,
183                                             uint32_t location_checksum,
184                                             std::unique_ptr<MemMap> map,
185                                             bool verify,
186                                             bool verify_checksum,
187                                             std::string* error_msg) {
188  ScopedTrace trace(std::string("Open dex file from mapped-memory ") + location);
189  CHECK(map.get() != nullptr);
190
191  if (map->Size() < sizeof(DexFile::Header)) {
192    *error_msg = StringPrintf(
193        "DexFile: failed to open dex file '%s' that is too short to have a header",
194        location.c_str());
195    return nullptr;
196  }
197
198  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
199                                                 map->Size(),
200                                                 location,
201                                                 location_checksum,
202                                                 kNoOatDexFile,
203                                                 verify,
204                                                 verify_checksum,
205                                                 error_msg);
206  if (dex_file != nullptr) {
207    dex_file->mem_map_.reset(map.release());
208  }
209  return dex_file;
210}
211
212bool DexFile::Open(const char* filename,
213                   const std::string& location,
214                   bool verify_checksum,
215                   std::string* error_msg,
216                   std::vector<std::unique_ptr<const DexFile>>* dex_files) {
217  ScopedTrace trace(std::string("Open dex file ") + std::string(location));
218  DCHECK(dex_files != nullptr) << "DexFile::Open: out-param is nullptr";
219  uint32_t magic;
220  File fd = OpenAndReadMagic(filename, &magic, error_msg);
221  if (fd.Fd() == -1) {
222    DCHECK(!error_msg->empty());
223    return false;
224  }
225  if (IsZipMagic(magic)) {
226    return DexFile::OpenZip(fd.Release(), location, verify_checksum, error_msg, dex_files);
227  }
228  if (IsDexMagic(magic)) {
229    std::unique_ptr<const DexFile> dex_file(DexFile::OpenFile(fd.Release(),
230                                                              location,
231                                                              /* verify */ true,
232                                                              verify_checksum,
233                                                              error_msg));
234    if (dex_file.get() != nullptr) {
235      dex_files->push_back(std::move(dex_file));
236      return true;
237    } else {
238      return false;
239    }
240  }
241  *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);
242  return false;
243}
244
245std::unique_ptr<const DexFile> DexFile::OpenDex(int fd,
246                                                const std::string& location,
247                                                bool verify_checksum,
248                                                std::string* error_msg) {
249  ScopedTrace trace("Open dex file " + std::string(location));
250  return OpenFile(fd, location, true /* verify */, verify_checksum, error_msg);
251}
252
253bool DexFile::OpenZip(int fd,
254                      const std::string& location,
255                      bool verify_checksum,
256                      std::string* error_msg,
257                      std::vector<std::unique_ptr<const DexFile>>* dex_files) {
258  ScopedTrace trace("Dex file open Zip " + std::string(location));
259  DCHECK(dex_files != nullptr) << "DexFile::OpenZip: out-param is nullptr";
260  std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd, location.c_str(), error_msg));
261  if (zip_archive.get() == nullptr) {
262    DCHECK(!error_msg->empty());
263    return false;
264  }
265  return DexFile::OpenAllDexFilesFromZip(*zip_archive,
266                                         location,
267                                         verify_checksum,
268                                         error_msg,
269                                         dex_files);
270}
271
272std::unique_ptr<const DexFile> DexFile::OpenFile(int fd,
273                                                 const std::string& location,
274                                                 bool verify,
275                                                 bool verify_checksum,
276                                                 std::string* error_msg) {
277  ScopedTrace trace(std::string("Open dex file ") + std::string(location));
278  CHECK(!location.empty());
279  std::unique_ptr<MemMap> map;
280  {
281    File delayed_close(fd, /* check_usage */ false);
282    struct stat sbuf;
283    memset(&sbuf, 0, sizeof(sbuf));
284    if (fstat(fd, &sbuf) == -1) {
285      *error_msg = StringPrintf("DexFile: fstat '%s' failed: %s", location.c_str(),
286                                strerror(errno));
287      return nullptr;
288    }
289    if (S_ISDIR(sbuf.st_mode)) {
290      *error_msg = StringPrintf("Attempt to mmap directory '%s'", location.c_str());
291      return nullptr;
292    }
293    size_t length = sbuf.st_size;
294    map.reset(MemMap::MapFile(length,
295                              PROT_READ,
296                              MAP_PRIVATE,
297                              fd,
298                              0,
299                              /*low_4gb*/false,
300                              location.c_str(),
301                              error_msg));
302    if (map == nullptr) {
303      DCHECK(!error_msg->empty());
304      return nullptr;
305    }
306  }
307
308  if (map->Size() < sizeof(DexFile::Header)) {
309    *error_msg = StringPrintf(
310        "DexFile: failed to open dex file '%s' that is too short to have a header",
311        location.c_str());
312    return nullptr;
313  }
314
315  const Header* dex_header = reinterpret_cast<const Header*>(map->Begin());
316
317  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
318                                                 map->Size(),
319                                                 location,
320                                                 dex_header->checksum_,
321                                                 kNoOatDexFile,
322                                                 verify,
323                                                 verify_checksum,
324                                                 error_msg);
325  if (dex_file != nullptr) {
326    dex_file->mem_map_.reset(map.release());
327  }
328
329  return dex_file;
330}
331
332std::unique_ptr<const DexFile> DexFile::OpenOneDexFileFromZip(const ZipArchive& zip_archive,
333                                                              const char* entry_name,
334                                                              const std::string& location,
335                                                              bool verify_checksum,
336                                                              std::string* error_msg,
337                                                              ZipOpenErrorCode* error_code) {
338  ScopedTrace trace("Dex file open from Zip Archive " + std::string(location));
339  CHECK(!location.empty());
340  std::unique_ptr<ZipEntry> zip_entry(zip_archive.Find(entry_name, error_msg));
341  if (zip_entry == nullptr) {
342    *error_code = ZipOpenErrorCode::kEntryNotFound;
343    return nullptr;
344  }
345  if (zip_entry->GetUncompressedLength() == 0) {
346    *error_msg = StringPrintf("Dex file '%s' has zero length", location.c_str());
347    *error_code = ZipOpenErrorCode::kDexFileError;
348    return nullptr;
349  }
350
351  std::unique_ptr<MemMap> map;
352  if (zip_entry->IsUncompressed()) {
353    if (!zip_entry->IsAlignedTo(alignof(Header))) {
354      // Do not mmap unaligned ZIP entries because
355      // doing so would fail dex verification which requires 4 byte alignment.
356      LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; "
357                   << "please zipalign to " << alignof(Header) << " bytes. "
358                   << "Falling back to extracting file.";
359    } else {
360      // Map uncompressed files within zip as file-backed to avoid a dirty copy.
361      map.reset(zip_entry->MapDirectlyFromFile(location.c_str(), /*out*/error_msg));
362      if (map == nullptr) {
363        LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; "
364                     << "is your ZIP file corrupted? Falling back to extraction.";
365        // Try again with Extraction which still has a chance of recovery.
366      }
367    }
368  }
369
370  if (map == nullptr) {
371    // Default path for compressed ZIP entries,
372    // and fallback for stored ZIP entries.
373    map.reset(zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg));
374  }
375
376  if (map == nullptr) {
377    *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", entry_name, location.c_str(),
378                              error_msg->c_str());
379    *error_code = ZipOpenErrorCode::kExtractToMemoryError;
380    return nullptr;
381  }
382  VerifyResult verify_result;
383  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
384                                                 map->Size(),
385                                                 location,
386                                                 zip_entry->GetCrc32(),
387                                                 kNoOatDexFile,
388                                                 /* verify */ true,
389                                                 verify_checksum,
390                                                 error_msg,
391                                                 &verify_result);
392  if (dex_file == nullptr) {
393    if (verify_result == VerifyResult::kVerifyNotAttempted) {
394      *error_code = ZipOpenErrorCode::kDexFileError;
395    } else {
396      *error_code = ZipOpenErrorCode::kVerifyError;
397    }
398    return nullptr;
399  }
400  dex_file->mem_map_.reset(map.release());
401  if (!dex_file->DisableWrite()) {
402    *error_msg = StringPrintf("Failed to make dex file '%s' read only", location.c_str());
403    *error_code = ZipOpenErrorCode::kMakeReadOnlyError;
404    return nullptr;
405  }
406  CHECK(dex_file->IsReadOnly()) << location;
407  if (verify_result != VerifyResult::kVerifySucceeded) {
408    *error_code = ZipOpenErrorCode::kVerifyError;
409    return nullptr;
410  }
411  *error_code = ZipOpenErrorCode::kNoError;
412  return dex_file;
413}
414
415// Technically we do not have a limitation with respect to the number of dex files that can be in a
416// multidex APK. However, it's bad practice, as each dex file requires its own tables for symbols
417// (types, classes, methods, ...) and dex caches. So warn the user that we open a zip with what
418// seems an excessive number.
419static constexpr size_t kWarnOnManyDexFilesThreshold = 100;
420
421bool DexFile::OpenAllDexFilesFromZip(const ZipArchive& zip_archive,
422                                     const std::string& location,
423                                     bool verify_checksum,
424                                     std::string* error_msg,
425                                     std::vector<std::unique_ptr<const DexFile>>* dex_files) {
426  ScopedTrace trace("Dex file open from Zip " + std::string(location));
427  DCHECK(dex_files != nullptr) << "DexFile::OpenFromZip: out-param is nullptr";
428  ZipOpenErrorCode error_code;
429  std::unique_ptr<const DexFile> dex_file(OpenOneDexFileFromZip(zip_archive,
430                                                                kClassesDex,
431                                                                location,
432                                                                verify_checksum,
433                                                                error_msg,
434                                                                &error_code));
435  if (dex_file.get() == nullptr) {
436    return false;
437  } else {
438    // Had at least classes.dex.
439    dex_files->push_back(std::move(dex_file));
440
441    // Now try some more.
442
443    // We could try to avoid std::string allocations by working on a char array directly. As we
444    // do not expect a lot of iterations, this seems too involved and brittle.
445
446    for (size_t i = 1; ; ++i) {
447      std::string name = GetMultiDexClassesDexName(i);
448      std::string fake_location = GetMultiDexLocation(i, location.c_str());
449      std::unique_ptr<const DexFile> next_dex_file(OpenOneDexFileFromZip(zip_archive,
450                                                                         name.c_str(),
451                                                                         fake_location,
452                                                                         verify_checksum,
453                                                                         error_msg,
454                                                                         &error_code));
455      if (next_dex_file.get() == nullptr) {
456        if (error_code != ZipOpenErrorCode::kEntryNotFound) {
457          LOG(WARNING) << "Zip open failed: " << *error_msg;
458        }
459        break;
460      } else {
461        dex_files->push_back(std::move(next_dex_file));
462      }
463
464      if (i == kWarnOnManyDexFilesThreshold) {
465        LOG(WARNING) << location << " has in excess of " << kWarnOnManyDexFilesThreshold
466                     << " dex files. Please consider coalescing and shrinking the number to "
467                        " avoid runtime overhead.";
468      }
469
470      if (i == std::numeric_limits<size_t>::max()) {
471        LOG(ERROR) << "Overflow in number of dex files!";
472        break;
473      }
474    }
475
476    return true;
477  }
478}
479
480std::unique_ptr<DexFile> DexFile::OpenCommon(const uint8_t* base,
481                                             size_t size,
482                                             const std::string& location,
483                                             uint32_t location_checksum,
484                                             const OatDexFile* oat_dex_file,
485                                             bool verify,
486                                             bool verify_checksum,
487                                             std::string* error_msg,
488                                             VerifyResult* verify_result) {
489  if (verify_result != nullptr) {
490    *verify_result = VerifyResult::kVerifyNotAttempted;
491  }
492  std::unique_ptr<DexFile> dex_file(new DexFile(base,
493                                                size,
494                                                location,
495                                                location_checksum,
496                                                oat_dex_file));
497  if (dex_file == nullptr) {
498    *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(),
499                              error_msg->c_str());
500    return nullptr;
501  }
502  if (!dex_file->Init(error_msg)) {
503    dex_file.reset();
504    return nullptr;
505  }
506  if (verify && !DexFileVerifier::Verify(dex_file.get(),
507                                         dex_file->Begin(),
508                                         dex_file->Size(),
509                                         location.c_str(),
510                                         verify_checksum,
511                                         error_msg)) {
512    if (verify_result != nullptr) {
513      *verify_result = VerifyResult::kVerifyFailed;
514    }
515    return nullptr;
516  }
517  if (verify_result != nullptr) {
518    *verify_result = VerifyResult::kVerifySucceeded;
519  }
520  return dex_file;
521}
522
523DexFile::DexFile(const uint8_t* base,
524                 size_t size,
525                 const std::string& location,
526                 uint32_t location_checksum,
527                 const OatDexFile* oat_dex_file)
528    : begin_(base),
529      size_(size),
530      location_(location),
531      location_checksum_(location_checksum),
532      header_(reinterpret_cast<const Header*>(base)),
533      string_ids_(reinterpret_cast<const StringId*>(base + header_->string_ids_off_)),
534      type_ids_(reinterpret_cast<const TypeId*>(base + header_->type_ids_off_)),
535      field_ids_(reinterpret_cast<const FieldId*>(base + header_->field_ids_off_)),
536      method_ids_(reinterpret_cast<const MethodId*>(base + header_->method_ids_off_)),
537      proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)),
538      class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)),
539      method_handles_(nullptr),
540      num_method_handles_(0),
541      call_site_ids_(nullptr),
542      num_call_site_ids_(0),
543      oat_dex_file_(oat_dex_file) {
544  CHECK(begin_ != nullptr) << GetLocation();
545  CHECK_GT(size_, 0U) << GetLocation();
546  // Check base (=header) alignment.
547  // Must be 4-byte aligned to avoid undefined behavior when accessing
548  // any of the sections via a pointer.
549  CHECK_ALIGNED(begin_, alignof(Header));
550
551  InitializeSectionsFromMapList();
552}
553
554DexFile::~DexFile() {
555  // We don't call DeleteGlobalRef on dex_object_ because we're only called by DestroyJavaVM, and
556  // that's only called after DetachCurrentThread, which means there's no JNIEnv. We could
557  // re-attach, but cleaning up these global references is not obviously useful. It's not as if
558  // the global reference table is otherwise empty!
559}
560
561bool DexFile::Init(std::string* error_msg) {
562  if (!CheckMagicAndVersion(error_msg)) {
563    return false;
564  }
565  return true;
566}
567
568bool DexFile::CheckMagicAndVersion(std::string* error_msg) const {
569  if (!IsMagicValid(header_->magic_)) {
570    std::ostringstream oss;
571    oss << "Unrecognized magic number in "  << GetLocation() << ":"
572            << " " << header_->magic_[0]
573            << " " << header_->magic_[1]
574            << " " << header_->magic_[2]
575            << " " << header_->magic_[3];
576    *error_msg = oss.str();
577    return false;
578  }
579  if (!IsVersionValid(header_->magic_)) {
580    std::ostringstream oss;
581    oss << "Unrecognized version number in "  << GetLocation() << ":"
582            << " " << header_->magic_[4]
583            << " " << header_->magic_[5]
584            << " " << header_->magic_[6]
585            << " " << header_->magic_[7];
586    *error_msg = oss.str();
587    return false;
588  }
589  return true;
590}
591
592void DexFile::InitializeSectionsFromMapList() {
593  const MapList* map_list = reinterpret_cast<const MapList*>(begin_ + header_->map_off_);
594  if (header_->map_off_ == 0 || header_->map_off_ > size_) {
595    // Bad offset. The dex file verifier runs after this method and will reject the file.
596    return;
597  }
598  const size_t count = map_list->size_;
599
600  size_t map_limit = header_->map_off_ + count * sizeof(MapItem);
601  if (header_->map_off_ >= map_limit || map_limit > size_) {
602    // Overflow or out out of bounds. The dex file verifier runs after
603    // this method and will reject the file as it is malformed.
604    return;
605  }
606
607  for (size_t i = 0; i < count; ++i) {
608    const MapItem& map_item = map_list->list_[i];
609    if (map_item.type_ == kDexTypeMethodHandleItem) {
610      method_handles_ = reinterpret_cast<const MethodHandleItem*>(begin_ + map_item.offset_);
611      num_method_handles_ = map_item.size_;
612    } else if (map_item.type_ == kDexTypeCallSiteIdItem) {
613      call_site_ids_ = reinterpret_cast<const CallSiteIdItem*>(begin_ + map_item.offset_);
614      num_call_site_ids_ = map_item.size_;
615    }
616  }
617}
618
619bool DexFile::IsMagicValid(const uint8_t* magic) {
620  return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0);
621}
622
623bool DexFile::IsVersionValid(const uint8_t* magic) {
624  const uint8_t* version = &magic[sizeof(kDexMagic)];
625  for (uint32_t i = 0; i < kNumDexVersions; i++) {
626    if (memcmp(version, kDexMagicVersions[i], kDexVersionLen) == 0) {
627      return true;
628    }
629  }
630  return false;
631}
632
633uint32_t DexFile::Header::GetVersion() const {
634  const char* version = reinterpret_cast<const char*>(&magic_[sizeof(kDexMagic)]);
635  return atoi(version);
636}
637
638const DexFile::ClassDef* DexFile::FindClassDef(dex::TypeIndex type_idx) const {
639  size_t num_class_defs = NumClassDefs();
640  // Fast path for rare no class defs case.
641  if (num_class_defs == 0) {
642    return nullptr;
643  }
644  for (size_t i = 0; i < num_class_defs; ++i) {
645    const ClassDef& class_def = GetClassDef(i);
646    if (class_def.class_idx_ == type_idx) {
647      return &class_def;
648    }
649  }
650  return nullptr;
651}
652
653uint32_t DexFile::FindCodeItemOffset(const DexFile::ClassDef& class_def,
654                                     uint32_t method_idx) const {
655  const uint8_t* class_data = GetClassData(class_def);
656  CHECK(class_data != nullptr);
657  ClassDataItemIterator it(*this, class_data);
658  // Skip fields
659  while (it.HasNextStaticField()) {
660    it.Next();
661  }
662  while (it.HasNextInstanceField()) {
663    it.Next();
664  }
665  while (it.HasNextDirectMethod()) {
666    if (it.GetMemberIndex() == method_idx) {
667      return it.GetMethodCodeItemOffset();
668    }
669    it.Next();
670  }
671  while (it.HasNextVirtualMethod()) {
672    if (it.GetMemberIndex() == method_idx) {
673      return it.GetMethodCodeItemOffset();
674    }
675    it.Next();
676  }
677  LOG(FATAL) << "Unable to find method " << method_idx;
678  UNREACHABLE();
679}
680
681const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass,
682                                             const DexFile::StringId& name,
683                                             const DexFile::TypeId& type) const {
684  // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
685  const dex::TypeIndex class_idx = GetIndexForTypeId(declaring_klass);
686  const dex::StringIndex name_idx = GetIndexForStringId(name);
687  const dex::TypeIndex type_idx = GetIndexForTypeId(type);
688  int32_t lo = 0;
689  int32_t hi = NumFieldIds() - 1;
690  while (hi >= lo) {
691    int32_t mid = (hi + lo) / 2;
692    const DexFile::FieldId& field = GetFieldId(mid);
693    if (class_idx > field.class_idx_) {
694      lo = mid + 1;
695    } else if (class_idx < field.class_idx_) {
696      hi = mid - 1;
697    } else {
698      if (name_idx > field.name_idx_) {
699        lo = mid + 1;
700      } else if (name_idx < field.name_idx_) {
701        hi = mid - 1;
702      } else {
703        if (type_idx > field.type_idx_) {
704          lo = mid + 1;
705        } else if (type_idx < field.type_idx_) {
706          hi = mid - 1;
707        } else {
708          return &field;
709        }
710      }
711    }
712  }
713  return nullptr;
714}
715
716const DexFile::MethodId* DexFile::FindMethodId(const DexFile::TypeId& declaring_klass,
717                                               const DexFile::StringId& name,
718                                               const DexFile::ProtoId& signature) const {
719  // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
720  const dex::TypeIndex class_idx = GetIndexForTypeId(declaring_klass);
721  const dex::StringIndex name_idx = GetIndexForStringId(name);
722  const uint16_t proto_idx = GetIndexForProtoId(signature);
723  int32_t lo = 0;
724  int32_t hi = NumMethodIds() - 1;
725  while (hi >= lo) {
726    int32_t mid = (hi + lo) / 2;
727    const DexFile::MethodId& method = GetMethodId(mid);
728    if (class_idx > method.class_idx_) {
729      lo = mid + 1;
730    } else if (class_idx < method.class_idx_) {
731      hi = mid - 1;
732    } else {
733      if (name_idx > method.name_idx_) {
734        lo = mid + 1;
735      } else if (name_idx < method.name_idx_) {
736        hi = mid - 1;
737      } else {
738        if (proto_idx > method.proto_idx_) {
739          lo = mid + 1;
740        } else if (proto_idx < method.proto_idx_) {
741          hi = mid - 1;
742        } else {
743          return &method;
744        }
745      }
746    }
747  }
748  return nullptr;
749}
750
751const DexFile::StringId* DexFile::FindStringId(const char* string) const {
752  int32_t lo = 0;
753  int32_t hi = NumStringIds() - 1;
754  while (hi >= lo) {
755    int32_t mid = (hi + lo) / 2;
756    const DexFile::StringId& str_id = GetStringId(dex::StringIndex(mid));
757    const char* str = GetStringData(str_id);
758    int compare = CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(string, str);
759    if (compare > 0) {
760      lo = mid + 1;
761    } else if (compare < 0) {
762      hi = mid - 1;
763    } else {
764      return &str_id;
765    }
766  }
767  return nullptr;
768}
769
770const DexFile::TypeId* DexFile::FindTypeId(const char* string) const {
771  int32_t lo = 0;
772  int32_t hi = NumTypeIds() - 1;
773  while (hi >= lo) {
774    int32_t mid = (hi + lo) / 2;
775    const TypeId& type_id = GetTypeId(dex::TypeIndex(mid));
776    const DexFile::StringId& str_id = GetStringId(type_id.descriptor_idx_);
777    const char* str = GetStringData(str_id);
778    int compare = CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(string, str);
779    if (compare > 0) {
780      lo = mid + 1;
781    } else if (compare < 0) {
782      hi = mid - 1;
783    } else {
784      return &type_id;
785    }
786  }
787  return nullptr;
788}
789
790const DexFile::StringId* DexFile::FindStringId(const uint16_t* string, size_t length) const {
791  int32_t lo = 0;
792  int32_t hi = NumStringIds() - 1;
793  while (hi >= lo) {
794    int32_t mid = (hi + lo) / 2;
795    const DexFile::StringId& str_id = GetStringId(dex::StringIndex(mid));
796    const char* str = GetStringData(str_id);
797    int compare = CompareModifiedUtf8ToUtf16AsCodePointValues(str, string, length);
798    if (compare > 0) {
799      lo = mid + 1;
800    } else if (compare < 0) {
801      hi = mid - 1;
802    } else {
803      return &str_id;
804    }
805  }
806  return nullptr;
807}
808
809const DexFile::TypeId* DexFile::FindTypeId(dex::StringIndex string_idx) const {
810  int32_t lo = 0;
811  int32_t hi = NumTypeIds() - 1;
812  while (hi >= lo) {
813    int32_t mid = (hi + lo) / 2;
814    const TypeId& type_id = GetTypeId(dex::TypeIndex(mid));
815    if (string_idx > type_id.descriptor_idx_) {
816      lo = mid + 1;
817    } else if (string_idx < type_id.descriptor_idx_) {
818      hi = mid - 1;
819    } else {
820      return &type_id;
821    }
822  }
823  return nullptr;
824}
825
826const DexFile::ProtoId* DexFile::FindProtoId(dex::TypeIndex return_type_idx,
827                                             const dex::TypeIndex* signature_type_idxs,
828                                             uint32_t signature_length) const {
829  int32_t lo = 0;
830  int32_t hi = NumProtoIds() - 1;
831  while (hi >= lo) {
832    int32_t mid = (hi + lo) / 2;
833    const DexFile::ProtoId& proto = GetProtoId(mid);
834    int compare = return_type_idx.index_ - proto.return_type_idx_.index_;
835    if (compare == 0) {
836      DexFileParameterIterator it(*this, proto);
837      size_t i = 0;
838      while (it.HasNext() && i < signature_length && compare == 0) {
839        compare = signature_type_idxs[i].index_ - it.GetTypeIdx().index_;
840        it.Next();
841        i++;
842      }
843      if (compare == 0) {
844        if (it.HasNext()) {
845          compare = -1;
846        } else if (i < signature_length) {
847          compare = 1;
848        }
849      }
850    }
851    if (compare > 0) {
852      lo = mid + 1;
853    } else if (compare < 0) {
854      hi = mid - 1;
855    } else {
856      return &proto;
857    }
858  }
859  return nullptr;
860}
861
862// Given a signature place the type ids into the given vector
863bool DexFile::CreateTypeList(const StringPiece& signature,
864                             dex::TypeIndex* return_type_idx,
865                             std::vector<dex::TypeIndex>* param_type_idxs) const {
866  if (signature[0] != '(') {
867    return false;
868  }
869  size_t offset = 1;
870  size_t end = signature.size();
871  bool process_return = false;
872  while (offset < end) {
873    size_t start_offset = offset;
874    char c = signature[offset];
875    offset++;
876    if (c == ')') {
877      process_return = true;
878      continue;
879    }
880    while (c == '[') {  // process array prefix
881      if (offset >= end) {  // expect some descriptor following [
882        return false;
883      }
884      c = signature[offset];
885      offset++;
886    }
887    if (c == 'L') {  // process type descriptors
888      do {
889        if (offset >= end) {  // unexpected early termination of descriptor
890          return false;
891        }
892        c = signature[offset];
893        offset++;
894      } while (c != ';');
895    }
896    // TODO: avoid creating a std::string just to get a 0-terminated char array
897    std::string descriptor(signature.data() + start_offset, offset - start_offset);
898    const DexFile::TypeId* type_id = FindTypeId(descriptor.c_str());
899    if (type_id == nullptr) {
900      return false;
901    }
902    dex::TypeIndex type_idx = GetIndexForTypeId(*type_id);
903    if (!process_return) {
904      param_type_idxs->push_back(type_idx);
905    } else {
906      *return_type_idx = type_idx;
907      return offset == end;  // return true if the signature had reached a sensible end
908    }
909  }
910  return false;  // failed to correctly parse return type
911}
912
913const Signature DexFile::CreateSignature(const StringPiece& signature) const {
914  dex::TypeIndex return_type_idx;
915  std::vector<dex::TypeIndex> param_type_indices;
916  bool success = CreateTypeList(signature, &return_type_idx, &param_type_indices);
917  if (!success) {
918    return Signature::NoSignature();
919  }
920  const ProtoId* proto_id = FindProtoId(return_type_idx, param_type_indices);
921  if (proto_id == nullptr) {
922    return Signature::NoSignature();
923  }
924  return Signature(this, *proto_id);
925}
926
927int32_t DexFile::FindTryItem(const CodeItem &code_item, uint32_t address) {
928  // Note: Signed type is important for max and min.
929  int32_t min = 0;
930  int32_t max = code_item.tries_size_ - 1;
931
932  while (min <= max) {
933    int32_t mid = min + ((max - min) / 2);
934
935    const art::DexFile::TryItem* ti = GetTryItems(code_item, mid);
936    uint32_t start = ti->start_addr_;
937    uint32_t end = start + ti->insn_count_;
938
939    if (address < start) {
940      max = mid - 1;
941    } else if (address >= end) {
942      min = mid + 1;
943    } else {  // We have a winner!
944      return mid;
945    }
946  }
947  // No match.
948  return -1;
949}
950
951int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address) {
952  int32_t try_item = FindTryItem(code_item, address);
953  if (try_item == -1) {
954    return -1;
955  } else {
956    return DexFile::GetTryItems(code_item, try_item)->handler_off_;
957  }
958}
959
960bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
961                                   DexDebugNewLocalCb local_cb, void* context) const {
962  DCHECK(local_cb != nullptr);
963  if (code_item == nullptr) {
964    return false;
965  }
966  const uint8_t* stream = GetDebugInfoStream(code_item);
967  if (stream == nullptr) {
968    return false;
969  }
970  std::vector<LocalInfo> local_in_reg(code_item->registers_size_);
971
972  uint16_t arg_reg = code_item->registers_size_ - code_item->ins_size_;
973  if (!is_static) {
974    const char* descriptor = GetMethodDeclaringClassDescriptor(GetMethodId(method_idx));
975    local_in_reg[arg_reg].name_ = "this";
976    local_in_reg[arg_reg].descriptor_ = descriptor;
977    local_in_reg[arg_reg].signature_ = nullptr;
978    local_in_reg[arg_reg].start_address_ = 0;
979    local_in_reg[arg_reg].reg_ = arg_reg;
980    local_in_reg[arg_reg].is_live_ = true;
981    arg_reg++;
982  }
983
984  DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx)));
985  DecodeUnsignedLeb128(&stream);  // Line.
986  uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
987  uint32_t i;
988  for (i = 0; i < parameters_size && it.HasNext(); ++i, it.Next()) {
989    if (arg_reg >= code_item->registers_size_) {
990      LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg
991                 << " >= " << code_item->registers_size_ << ") in " << GetLocation();
992      return false;
993    }
994    uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
995    const char* descriptor = it.GetDescriptor();
996    local_in_reg[arg_reg].name_ = StringDataByIdx(dex::StringIndex(name_idx));
997    local_in_reg[arg_reg].descriptor_ = descriptor;
998    local_in_reg[arg_reg].signature_ = nullptr;
999    local_in_reg[arg_reg].start_address_ = 0;
1000    local_in_reg[arg_reg].reg_ = arg_reg;
1001    local_in_reg[arg_reg].is_live_ = true;
1002    switch (*descriptor) {
1003      case 'D':
1004      case 'J':
1005        arg_reg += 2;
1006        break;
1007      default:
1008        arg_reg += 1;
1009        break;
1010    }
1011  }
1012  if (i != parameters_size || it.HasNext()) {
1013    LOG(ERROR) << "invalid stream - problem with parameter iterator in " << GetLocation()
1014               << " for method " << this->PrettyMethod(method_idx);
1015    return false;
1016  }
1017
1018  uint32_t address = 0;
1019  for (;;)  {
1020    uint8_t opcode = *stream++;
1021    switch (opcode) {
1022      case DBG_END_SEQUENCE:
1023        // Emit all variables which are still alive at the end of the method.
1024        for (uint16_t reg = 0; reg < code_item->registers_size_; reg++) {
1025          if (local_in_reg[reg].is_live_) {
1026            local_in_reg[reg].end_address_ = code_item->insns_size_in_code_units_;
1027            local_cb(context, local_in_reg[reg]);
1028          }
1029        }
1030        return true;
1031      case DBG_ADVANCE_PC:
1032        address += DecodeUnsignedLeb128(&stream);
1033        break;
1034      case DBG_ADVANCE_LINE:
1035        DecodeSignedLeb128(&stream);  // Line.
1036        break;
1037      case DBG_START_LOCAL:
1038      case DBG_START_LOCAL_EXTENDED: {
1039        uint16_t reg = DecodeUnsignedLeb128(&stream);
1040        if (reg >= code_item->registers_size_) {
1041          LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
1042                     << code_item->registers_size_ << ") in " << GetLocation();
1043          return false;
1044        }
1045
1046        uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
1047        uint16_t descriptor_idx = DecodeUnsignedLeb128P1(&stream);
1048        uint32_t signature_idx = kDexNoIndex;
1049        if (opcode == DBG_START_LOCAL_EXTENDED) {
1050          signature_idx = DecodeUnsignedLeb128P1(&stream);
1051        }
1052
1053        // Emit what was previously there, if anything
1054        if (local_in_reg[reg].is_live_) {
1055          local_in_reg[reg].end_address_ = address;
1056          local_cb(context, local_in_reg[reg]);
1057        }
1058
1059        local_in_reg[reg].name_ = StringDataByIdx(dex::StringIndex(name_idx));
1060        local_in_reg[reg].descriptor_ =
1061            StringByTypeIdx(dex::TypeIndex(dchecked_integral_cast<uint16_t>(descriptor_idx)));;
1062        local_in_reg[reg].signature_ = StringDataByIdx(dex::StringIndex(signature_idx));
1063        local_in_reg[reg].start_address_ = address;
1064        local_in_reg[reg].reg_ = reg;
1065        local_in_reg[reg].is_live_ = true;
1066        break;
1067      }
1068      case DBG_END_LOCAL: {
1069        uint16_t reg = DecodeUnsignedLeb128(&stream);
1070        if (reg >= code_item->registers_size_) {
1071          LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
1072                     << code_item->registers_size_ << ") in " << GetLocation();
1073          return false;
1074        }
1075        if (!local_in_reg[reg].is_live_) {
1076          LOG(ERROR) << "invalid stream - end without start in " << GetLocation();
1077          return false;
1078        }
1079        local_in_reg[reg].end_address_ = address;
1080        local_cb(context, local_in_reg[reg]);
1081        local_in_reg[reg].is_live_ = false;
1082        break;
1083      }
1084      case DBG_RESTART_LOCAL: {
1085        uint16_t reg = DecodeUnsignedLeb128(&stream);
1086        if (reg >= code_item->registers_size_) {
1087          LOG(ERROR) << "invalid stream - reg >= reg size (" << reg << " >= "
1088                     << code_item->registers_size_ << ") in " << GetLocation();
1089          return false;
1090        }
1091        // If the register is live, the "restart" is superfluous,
1092        // and we don't want to mess with the existing start address.
1093        if (!local_in_reg[reg].is_live_) {
1094          local_in_reg[reg].start_address_ = address;
1095          local_in_reg[reg].is_live_ = true;
1096        }
1097        break;
1098      }
1099      case DBG_SET_PROLOGUE_END:
1100      case DBG_SET_EPILOGUE_BEGIN:
1101        break;
1102      case DBG_SET_FILE:
1103        DecodeUnsignedLeb128P1(&stream);  // name.
1104        break;
1105      default:
1106        address += (opcode - DBG_FIRST_SPECIAL) / DBG_LINE_RANGE;
1107        break;
1108    }
1109  }
1110}
1111
1112bool DexFile::DecodeDebugPositionInfo(const CodeItem* code_item, DexDebugNewPositionCb position_cb,
1113                                      void* context) const {
1114  DCHECK(position_cb != nullptr);
1115  if (code_item == nullptr) {
1116    return false;
1117  }
1118  const uint8_t* stream = GetDebugInfoStream(code_item);
1119  if (stream == nullptr) {
1120    return false;
1121  }
1122
1123  PositionInfo entry = PositionInfo();
1124  entry.line_ = DecodeUnsignedLeb128(&stream);
1125  uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
1126  for (uint32_t i = 0; i < parameters_size; ++i) {
1127    DecodeUnsignedLeb128P1(&stream);  // Parameter name.
1128  }
1129
1130  for (;;)  {
1131    uint8_t opcode = *stream++;
1132    switch (opcode) {
1133      case DBG_END_SEQUENCE:
1134        return true;  // end of stream.
1135      case DBG_ADVANCE_PC:
1136        entry.address_ += DecodeUnsignedLeb128(&stream);
1137        break;
1138      case DBG_ADVANCE_LINE:
1139        entry.line_ += DecodeSignedLeb128(&stream);
1140        break;
1141      case DBG_START_LOCAL:
1142        DecodeUnsignedLeb128(&stream);  // reg.
1143        DecodeUnsignedLeb128P1(&stream);  // name.
1144        DecodeUnsignedLeb128P1(&stream);  // descriptor.
1145        break;
1146      case DBG_START_LOCAL_EXTENDED:
1147        DecodeUnsignedLeb128(&stream);  // reg.
1148        DecodeUnsignedLeb128P1(&stream);  // name.
1149        DecodeUnsignedLeb128P1(&stream);  // descriptor.
1150        DecodeUnsignedLeb128P1(&stream);  // signature.
1151        break;
1152      case DBG_END_LOCAL:
1153      case DBG_RESTART_LOCAL:
1154        DecodeUnsignedLeb128(&stream);  // reg.
1155        break;
1156      case DBG_SET_PROLOGUE_END:
1157        entry.prologue_end_ = true;
1158        break;
1159      case DBG_SET_EPILOGUE_BEGIN:
1160        entry.epilogue_begin_ = true;
1161        break;
1162      case DBG_SET_FILE: {
1163        uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
1164        entry.source_file_ = StringDataByIdx(dex::StringIndex(name_idx));
1165        break;
1166      }
1167      default: {
1168        int adjopcode = opcode - DBG_FIRST_SPECIAL;
1169        entry.address_ += adjopcode / DBG_LINE_RANGE;
1170        entry.line_ += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE);
1171        if (position_cb(context, entry)) {
1172          return true;  // early exit.
1173        }
1174        entry.prologue_end_ = false;
1175        entry.epilogue_begin_ = false;
1176        break;
1177      }
1178    }
1179  }
1180}
1181
1182bool DexFile::LineNumForPcCb(void* raw_context, const PositionInfo& entry) {
1183  LineNumFromPcContext* context = reinterpret_cast<LineNumFromPcContext*>(raw_context);
1184
1185  // We know that this callback will be called in
1186  // ascending address order, so keep going until we find
1187  // a match or we've just gone past it.
1188  if (entry.address_ > context->address_) {
1189    // The line number from the previous positions callback
1190    // wil be the final result.
1191    return true;
1192  } else {
1193    context->line_num_ = entry.line_;
1194    return entry.address_ == context->address_;
1195  }
1196}
1197
1198bool DexFile::IsMultiDexLocation(const char* location) {
1199  return strrchr(location, kMultiDexSeparator) != nullptr;
1200}
1201
1202std::string DexFile::GetMultiDexClassesDexName(size_t index) {
1203  if (index == 0) {
1204    return "classes.dex";
1205  } else {
1206    return StringPrintf("classes%zu.dex", index + 1);
1207  }
1208}
1209
1210std::string DexFile::GetMultiDexLocation(size_t index, const char* dex_location) {
1211  if (index == 0) {
1212    return dex_location;
1213  } else {
1214    return StringPrintf("%s" kMultiDexSeparatorString "classes%zu.dex", dex_location, index + 1);
1215  }
1216}
1217
1218std::string DexFile::GetDexCanonicalLocation(const char* dex_location) {
1219  CHECK_NE(dex_location, static_cast<const char*>(nullptr));
1220  std::string base_location = GetBaseLocation(dex_location);
1221  const char* suffix = dex_location + base_location.size();
1222  DCHECK(suffix[0] == 0 || suffix[0] == kMultiDexSeparator);
1223  UniqueCPtr<const char[]> path(realpath(base_location.c_str(), nullptr));
1224  if (path != nullptr && path.get() != base_location) {
1225    return std::string(path.get()) + suffix;
1226  } else if (suffix[0] == 0) {
1227    return base_location;
1228  } else {
1229    return dex_location;
1230  }
1231}
1232
1233// Read a signed integer.  "zwidth" is the zero-based byte count.
1234int32_t DexFile::ReadSignedInt(const uint8_t* ptr, int zwidth) {
1235  int32_t val = 0;
1236  for (int i = zwidth; i >= 0; --i) {
1237    val = ((uint32_t)val >> 8) | (((int32_t)*ptr++) << 24);
1238  }
1239  val >>= (3 - zwidth) * 8;
1240  return val;
1241}
1242
1243// Read an unsigned integer.  "zwidth" is the zero-based byte count,
1244// "fill_on_right" indicates which side we want to zero-fill from.
1245uint32_t DexFile::ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right) {
1246  uint32_t val = 0;
1247  for (int i = zwidth; i >= 0; --i) {
1248    val = (val >> 8) | (((uint32_t)*ptr++) << 24);
1249  }
1250  if (!fill_on_right) {
1251    val >>= (3 - zwidth) * 8;
1252  }
1253  return val;
1254}
1255
1256// Read a signed long.  "zwidth" is the zero-based byte count.
1257int64_t DexFile::ReadSignedLong(const uint8_t* ptr, int zwidth) {
1258  int64_t val = 0;
1259  for (int i = zwidth; i >= 0; --i) {
1260    val = ((uint64_t)val >> 8) | (((int64_t)*ptr++) << 56);
1261  }
1262  val >>= (7 - zwidth) * 8;
1263  return val;
1264}
1265
1266// Read an unsigned long.  "zwidth" is the zero-based byte count,
1267// "fill_on_right" indicates which side we want to zero-fill from.
1268uint64_t DexFile::ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right) {
1269  uint64_t val = 0;
1270  for (int i = zwidth; i >= 0; --i) {
1271    val = (val >> 8) | (((uint64_t)*ptr++) << 56);
1272  }
1273  if (!fill_on_right) {
1274    val >>= (7 - zwidth) * 8;
1275  }
1276  return val;
1277}
1278
1279std::string DexFile::PrettyMethod(uint32_t method_idx, bool with_signature) const {
1280  if (method_idx >= NumMethodIds()) {
1281    return StringPrintf("<<invalid-method-idx-%d>>", method_idx);
1282  }
1283  const DexFile::MethodId& method_id = GetMethodId(method_idx);
1284  std::string result(PrettyDescriptor(GetMethodDeclaringClassDescriptor(method_id)));
1285  result += '.';
1286  result += GetMethodName(method_id);
1287  if (with_signature) {
1288    const Signature signature = GetMethodSignature(method_id);
1289    std::string sig_as_string(signature.ToString());
1290    if (signature == Signature::NoSignature()) {
1291      return result + sig_as_string;
1292    }
1293    result = PrettyReturnType(sig_as_string.c_str()) + " " + result +
1294        PrettyArguments(sig_as_string.c_str());
1295  }
1296  return result;
1297}
1298
1299std::string DexFile::PrettyField(uint32_t field_idx, bool with_type) const {
1300  if (field_idx >= NumFieldIds()) {
1301    return StringPrintf("<<invalid-field-idx-%d>>", field_idx);
1302  }
1303  const DexFile::FieldId& field_id = GetFieldId(field_idx);
1304  std::string result;
1305  if (with_type) {
1306    result += GetFieldTypeDescriptor(field_id);
1307    result += ' ';
1308  }
1309  result += PrettyDescriptor(GetFieldDeclaringClassDescriptor(field_id));
1310  result += '.';
1311  result += GetFieldName(field_id);
1312  return result;
1313}
1314
1315std::string DexFile::PrettyType(dex::TypeIndex type_idx) const {
1316  if (type_idx.index_ >= NumTypeIds()) {
1317    return StringPrintf("<<invalid-type-idx-%d>>", type_idx.index_);
1318  }
1319  const DexFile::TypeId& type_id = GetTypeId(type_idx);
1320  return PrettyDescriptor(GetTypeDescriptor(type_id));
1321}
1322
1323// Checks that visibility is as expected. Includes special behavior for M and
1324// before to allow runtime and build visibility when expecting runtime.
1325std::ostream& operator<<(std::ostream& os, const DexFile& dex_file) {
1326  os << StringPrintf("[DexFile: %s dex-checksum=%08x location-checksum=%08x %p-%p]",
1327                     dex_file.GetLocation().c_str(),
1328                     dex_file.GetHeader().checksum_, dex_file.GetLocationChecksum(),
1329                     dex_file.Begin(), dex_file.Begin() + dex_file.Size());
1330  return os;
1331}
1332
1333std::string Signature::ToString() const {
1334  if (dex_file_ == nullptr) {
1335    CHECK(proto_id_ == nullptr);
1336    return "<no signature>";
1337  }
1338  const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
1339  std::string result;
1340  if (params == nullptr) {
1341    result += "()";
1342  } else {
1343    result += "(";
1344    for (uint32_t i = 0; i < params->Size(); ++i) {
1345      result += dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_);
1346    }
1347    result += ")";
1348  }
1349  result += dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
1350  return result;
1351}
1352
1353uint32_t Signature::GetNumberOfParameters() const {
1354  const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
1355  return (params != nullptr) ? params->Size() : 0;
1356}
1357
1358bool Signature::IsVoid() const {
1359  const char* return_type = dex_file_->GetReturnTypeDescriptor(*proto_id_);
1360  return strcmp(return_type, "V") == 0;
1361}
1362
1363bool Signature::operator==(const StringPiece& rhs) const {
1364  if (dex_file_ == nullptr) {
1365    return false;
1366  }
1367  StringPiece tail(rhs);
1368  if (!tail.starts_with("(")) {
1369    return false;  // Invalid signature
1370  }
1371  tail.remove_prefix(1);  // "(";
1372  const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
1373  if (params != nullptr) {
1374    for (uint32_t i = 0; i < params->Size(); ++i) {
1375      StringPiece param(dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_));
1376      if (!tail.starts_with(param)) {
1377        return false;
1378      }
1379      tail.remove_prefix(param.length());
1380    }
1381  }
1382  if (!tail.starts_with(")")) {
1383    return false;
1384  }
1385  tail.remove_prefix(1);  // ")";
1386  return tail == dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
1387}
1388
1389std::ostream& operator<<(std::ostream& os, const Signature& sig) {
1390  return os << sig.ToString();
1391}
1392
1393// Decodes the header section from the class data bytes.
1394void ClassDataItemIterator::ReadClassDataHeader() {
1395  CHECK(ptr_pos_ != nullptr);
1396  header_.static_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_);
1397  header_.instance_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_);
1398  header_.direct_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_);
1399  header_.virtual_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_);
1400}
1401
1402void ClassDataItemIterator::ReadClassDataField() {
1403  field_.field_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_);
1404  field_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
1405  // The user of the iterator is responsible for checking if there
1406  // are unordered or duplicate indexes.
1407}
1408
1409void ClassDataItemIterator::ReadClassDataMethod() {
1410  method_.method_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_);
1411  method_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_);
1412  method_.code_off_ = DecodeUnsignedLeb128(&ptr_pos_);
1413  if (last_idx_ != 0 && method_.method_idx_delta_ == 0) {
1414    LOG(WARNING) << "Duplicate method in " << dex_file_.GetLocation();
1415  }
1416}
1417
1418EncodedArrayValueIterator::EncodedArrayValueIterator(const DexFile& dex_file,
1419                                                     const uint8_t* array_data)
1420    : dex_file_(dex_file),
1421      array_size_(),
1422      pos_(-1),
1423      ptr_(array_data),
1424      type_(kByte) {
1425  array_size_ = (ptr_ != nullptr) ? DecodeUnsignedLeb128(&ptr_) : 0;
1426  if (array_size_ > 0) {
1427    Next();
1428  }
1429}
1430
1431void EncodedArrayValueIterator::Next() {
1432  pos_++;
1433  if (pos_ >= array_size_) {
1434    return;
1435  }
1436  uint8_t value_type = *ptr_++;
1437  uint8_t value_arg = value_type >> kEncodedValueArgShift;
1438  size_t width = value_arg + 1;  // assume and correct later
1439  type_ = static_cast<ValueType>(value_type & kEncodedValueTypeMask);
1440  switch (type_) {
1441  case kBoolean:
1442    jval_.i = (value_arg != 0) ? 1 : 0;
1443    width = 0;
1444    break;
1445  case kByte:
1446    jval_.i = DexFile::ReadSignedInt(ptr_, value_arg);
1447    CHECK(IsInt<8>(jval_.i));
1448    break;
1449  case kShort:
1450    jval_.i = DexFile::ReadSignedInt(ptr_, value_arg);
1451    CHECK(IsInt<16>(jval_.i));
1452    break;
1453  case kChar:
1454    jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, false);
1455    CHECK(IsUint<16>(jval_.i));
1456    break;
1457  case kInt:
1458    jval_.i = DexFile::ReadSignedInt(ptr_, value_arg);
1459    break;
1460  case kLong:
1461    jval_.j = DexFile::ReadSignedLong(ptr_, value_arg);
1462    break;
1463  case kFloat:
1464    jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, true);
1465    break;
1466  case kDouble:
1467    jval_.j = DexFile::ReadUnsignedLong(ptr_, value_arg, true);
1468    break;
1469  case kString:
1470  case kType:
1471  case kMethodType:
1472  case kMethodHandle:
1473    jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, false);
1474    break;
1475  case kField:
1476  case kMethod:
1477  case kEnum:
1478  case kArray:
1479  case kAnnotation:
1480    UNIMPLEMENTED(FATAL) << ": type " << type_;
1481    UNREACHABLE();
1482  case kNull:
1483    jval_.l = nullptr;
1484    width = 0;
1485    break;
1486  default:
1487    LOG(FATAL) << "Unreached";
1488    UNREACHABLE();
1489  }
1490  ptr_ += width;
1491}
1492
1493CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address) {
1494  handler_.address_ = -1;
1495  int32_t offset = -1;
1496
1497  // Short-circuit the overwhelmingly common cases.
1498  switch (code_item.tries_size_) {
1499    case 0:
1500      break;
1501    case 1: {
1502      const DexFile::TryItem* tries = DexFile::GetTryItems(code_item, 0);
1503      uint32_t start = tries->start_addr_;
1504      if (address >= start) {
1505        uint32_t end = start + tries->insn_count_;
1506        if (address < end) {
1507          offset = tries->handler_off_;
1508        }
1509      }
1510      break;
1511    }
1512    default:
1513      offset = DexFile::FindCatchHandlerOffset(code_item, address);
1514  }
1515  Init(code_item, offset);
1516}
1517
1518CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item,
1519                                           const DexFile::TryItem& try_item) {
1520  handler_.address_ = -1;
1521  Init(code_item, try_item.handler_off_);
1522}
1523
1524void CatchHandlerIterator::Init(const DexFile::CodeItem& code_item,
1525                                int32_t offset) {
1526  if (offset >= 0) {
1527    Init(DexFile::GetCatchHandlerData(code_item, offset));
1528  } else {
1529    // Not found, initialize as empty
1530    current_data_ = nullptr;
1531    remaining_count_ = -1;
1532    catch_all_ = false;
1533    DCHECK(!HasNext());
1534  }
1535}
1536
1537void CatchHandlerIterator::Init(const uint8_t* handler_data) {
1538  current_data_ = handler_data;
1539  remaining_count_ = DecodeSignedLeb128(&current_data_);
1540
1541  // If remaining_count_ is non-positive, then it is the negative of
1542  // the number of catch types, and the catches are followed by a
1543  // catch-all handler.
1544  if (remaining_count_ <= 0) {
1545    catch_all_ = true;
1546    remaining_count_ = -remaining_count_;
1547  } else {
1548    catch_all_ = false;
1549  }
1550  Next();
1551}
1552
1553void CatchHandlerIterator::Next() {
1554  if (remaining_count_ > 0) {
1555    handler_.type_idx_ = dex::TypeIndex(DecodeUnsignedLeb128(&current_data_));
1556    handler_.address_  = DecodeUnsignedLeb128(&current_data_);
1557    remaining_count_--;
1558    return;
1559  }
1560
1561  if (catch_all_) {
1562    handler_.type_idx_ = dex::TypeIndex(DexFile::kDexNoIndex16);
1563    handler_.address_  = DecodeUnsignedLeb128(&current_data_);
1564    catch_all_ = false;
1565    return;
1566  }
1567
1568  // no more handler
1569  remaining_count_ = -1;
1570}
1571
1572namespace dex {
1573
1574std::ostream& operator<<(std::ostream& os, const StringIndex& index) {
1575  os << "StringIndex[" << index.index_ << "]";
1576  return os;
1577}
1578
1579std::ostream& operator<<(std::ostream& os, const TypeIndex& index) {
1580  os << "TypeIndex[" << index.index_ << "]";
1581  return os;
1582}
1583
1584}  // namespace dex
1585
1586}  // namespace art
1587