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