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 
49 namespace art {
50 
51 using android::base::StringPrintf;
52 
53 static_assert(sizeof(dex::StringIndex) == sizeof(uint32_t), "StringIndex size is wrong");
54 static_assert(std::is_trivially_copyable<dex::StringIndex>::value, "StringIndex not trivial");
55 static_assert(sizeof(dex::TypeIndex) == sizeof(uint16_t), "TypeIndex size is wrong");
56 static_assert(std::is_trivially_copyable<dex::TypeIndex>::value, "TypeIndex not trivial");
57 
58 static constexpr OatDexFile* kNoOatDexFile = nullptr;
59 
60 const char* DexFile::kClassesDex = "classes.dex";
61 
62 const uint8_t DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
63 const 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 
CalculateChecksum() const72 uint32_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 
78 struct DexFile::AnnotationValue {
79   JValue value_;
80   uint8_t type_;
81 };
82 
GetMultiDexChecksums(const char * filename,std::vector<uint32_t> * checksums,std::string * error_msg)83 bool 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 
GetPermissions() const132 int DexFile::GetPermissions() const {
133   if (mem_map_.get() == nullptr) {
134     return 0;
135   } else {
136     return mem_map_->GetProtect();
137   }
138 }
139 
IsReadOnly() const140 bool DexFile::IsReadOnly() const {
141   return GetPermissions() == PROT_READ;
142 }
143 
EnableWrite() const144 bool 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 
DisableWrite() const153 bool 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 
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)163 std::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 
Open(const std::string & location,uint32_t location_checksum,std::unique_ptr<MemMap> map,bool verify,bool verify_checksum,std::string * error_msg)182 std::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 
Open(const char * filename,const std::string & location,bool verify_checksum,std::string * error_msg,std::vector<std::unique_ptr<const DexFile>> * dex_files)212 bool 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 
OpenDex(int fd,const std::string & location,bool verify_checksum,std::string * error_msg)245 std::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 
OpenZip(int fd,const std::string & location,bool verify_checksum,std::string * error_msg,std::vector<std::unique_ptr<const DexFile>> * dex_files)253 bool 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 
OpenFile(int fd,const std::string & location,bool verify,bool verify_checksum,std::string * error_msg)272 std::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 
OpenOneDexFileFromZip(const ZipArchive & zip_archive,const char * entry_name,const std::string & location,bool verify_checksum,std::string * error_msg,ZipOpenErrorCode * error_code)332 std::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.
419 static constexpr size_t kWarnOnManyDexFilesThreshold = 100;
420 
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)421 bool 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 
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)480 std::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 
DexFile(const uint8_t * base,size_t size,const std::string & location,uint32_t location_checksum,const OatDexFile * oat_dex_file)523 DexFile::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 
~DexFile()554 DexFile::~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 
Init(std::string * error_msg)561 bool DexFile::Init(std::string* error_msg) {
562   if (!CheckMagicAndVersion(error_msg)) {
563     return false;
564   }
565   return true;
566 }
567 
CheckMagicAndVersion(std::string * error_msg) const568 bool 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 
InitializeSectionsFromMapList()592 void 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 
IsMagicValid(const uint8_t * magic)619 bool DexFile::IsMagicValid(const uint8_t* magic) {
620   return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0);
621 }
622 
IsVersionValid(const uint8_t * magic)623 bool 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 
GetVersion() const633 uint32_t DexFile::Header::GetVersion() const {
634   const char* version = reinterpret_cast<const char*>(&magic_[sizeof(kDexMagic)]);
635   return atoi(version);
636 }
637 
FindClassDef(dex::TypeIndex type_idx) const638 const 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 
FindCodeItemOffset(const DexFile::ClassDef & class_def,uint32_t method_idx) const653 uint32_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 
FindFieldId(const DexFile::TypeId & declaring_klass,const DexFile::StringId & name,const DexFile::TypeId & type) const681 const 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 
FindMethodId(const DexFile::TypeId & declaring_klass,const DexFile::StringId & name,const DexFile::ProtoId & signature) const716 const 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 
FindStringId(const char * string) const751 const 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 
FindTypeId(const char * string) const770 const 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 
FindStringId(const uint16_t * string,size_t length) const790 const 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 
FindTypeId(dex::StringIndex string_idx) const809 const 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 
FindProtoId(dex::TypeIndex return_type_idx,const dex::TypeIndex * signature_type_idxs,uint32_t signature_length) const826 const 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
CreateTypeList(const StringPiece & signature,dex::TypeIndex * return_type_idx,std::vector<dex::TypeIndex> * param_type_idxs) const863 bool 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 
CreateSignature(const StringPiece & signature) const913 const 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 
FindTryItem(const CodeItem & code_item,uint32_t address)927 int32_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 
FindCatchHandlerOffset(const CodeItem & code_item,uint32_t address)951 int32_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 
DecodeDebugLocalInfo(const CodeItem * code_item,bool is_static,uint32_t method_idx,DexDebugNewLocalCb local_cb,void * context) const960 bool 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 
DecodeDebugPositionInfo(const CodeItem * code_item,DexDebugNewPositionCb position_cb,void * context) const1112 bool 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 
LineNumForPcCb(void * raw_context,const PositionInfo & entry)1182 bool 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 
IsMultiDexLocation(const char * location)1198 bool DexFile::IsMultiDexLocation(const char* location) {
1199   return strrchr(location, kMultiDexSeparator) != nullptr;
1200 }
1201 
GetMultiDexClassesDexName(size_t index)1202 std::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 
GetMultiDexLocation(size_t index,const char * dex_location)1210 std::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 
GetDexCanonicalLocation(const char * dex_location)1218 std::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.
ReadSignedInt(const uint8_t * ptr,int zwidth)1234 int32_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.
ReadUnsignedInt(const uint8_t * ptr,int zwidth,bool fill_on_right)1245 uint32_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.
ReadSignedLong(const uint8_t * ptr,int zwidth)1257 int64_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.
ReadUnsignedLong(const uint8_t * ptr,int zwidth,bool fill_on_right)1268 uint64_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 
PrettyMethod(uint32_t method_idx,bool with_signature) const1279 std::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 
PrettyField(uint32_t field_idx,bool with_type) const1299 std::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 
PrettyType(dex::TypeIndex type_idx) const1315 std::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.
operator <<(std::ostream & os,const DexFile & dex_file)1325 std::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 
ToString() const1333 std::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 
GetNumberOfParameters() const1353 uint32_t Signature::GetNumberOfParameters() const {
1354   const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
1355   return (params != nullptr) ? params->Size() : 0;
1356 }
1357 
IsVoid() const1358 bool Signature::IsVoid() const {
1359   const char* return_type = dex_file_->GetReturnTypeDescriptor(*proto_id_);
1360   return strcmp(return_type, "V") == 0;
1361 }
1362 
operator ==(const StringPiece & rhs) const1363 bool 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 
operator <<(std::ostream & os,const Signature & sig)1389 std::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.
ReadClassDataHeader()1394 void 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 
ReadClassDataField()1402 void 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 
ReadClassDataMethod()1409 void 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 
EncodedArrayValueIterator(const DexFile & dex_file,const uint8_t * array_data)1418 EncodedArrayValueIterator::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 
Next()1431 void 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 
CatchHandlerIterator(const DexFile::CodeItem & code_item,uint32_t address)1493 CatchHandlerIterator::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 
CatchHandlerIterator(const DexFile::CodeItem & code_item,const DexFile::TryItem & try_item)1518 CatchHandlerIterator::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 
Init(const DexFile::CodeItem & code_item,int32_t offset)1524 void 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 
Init(const uint8_t * handler_data)1537 void 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 
Next()1553 void 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 
1572 namespace dex {
1573 
operator <<(std::ostream & os,const StringIndex & index)1574 std::ostream& operator<<(std::ostream& os, const StringIndex& index) {
1575   os << "StringIndex[" << index.index_ << "]";
1576   return os;
1577 }
1578 
operator <<(std::ostream & os,const TypeIndex & index)1579 std::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