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 73 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 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 133 int DexFile::GetPermissions() const { 134 if (mem_map_.get() == nullptr) { 135 return 0; 136 } else { 137 return mem_map_->GetProtect(); 138 } 139 } 140 141 bool DexFile::IsReadOnly() const { 142 return GetPermissions() == PROT_READ; 143 } 144 145 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 154 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 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 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 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 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 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 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 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 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 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 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 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 562 bool DexFile::Init(std::string* error_msg) { 563 if (!CheckMagicAndVersion(error_msg)) { 564 return false; 565 } 566 return true; 567 } 568 569 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 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 620 bool DexFile::IsMagicValid(const uint8_t* magic) { 621 return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0); 622 } 623 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 634 uint32_t DexFile::Header::GetVersion() const { 635 const char* version = reinterpret_cast<const char*>(&magic_[sizeof(kDexMagic)]); 636 return atoi(version); 637 } 638 639 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 654 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 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 702 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 737 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 772 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 791 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 811 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 830 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 847 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 884 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 934 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, ¶m_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 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 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 981 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 1133 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 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 1219 bool DexFile::IsMultiDexLocation(const char* location) { 1220 return strrchr(location, kMultiDexSeparator) != nullptr; 1221 } 1222 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 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 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. 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. 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. 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. 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 1300 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 1320 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 1336 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. 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 1354 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 1374 uint32_t Signature::GetNumberOfParameters() const { 1375 const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_); 1376 return (params != nullptr) ? params->Size() : 0; 1377 } 1378 1379 bool Signature::IsVoid() const { 1380 const char* return_type = dex_file_->GetReturnTypeDescriptor(*proto_id_); 1381 return strcmp(return_type, "V") == 0; 1382 } 1383 1384 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 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. 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 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 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 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 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 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 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 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 1558 void CatchHandlerIterator::Init(const uint8_t* handler_data) { 1559 current_data_ = handler_data; 1560 remaining_count_ = DecodeSignedLeb128(¤t_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 1574 void CatchHandlerIterator::Next() { 1575 if (remaining_count_ > 0) { 1576 handler_.type_idx_ = dex::TypeIndex(DecodeUnsignedLeb128(¤t_data_)); 1577 handler_.address_ = DecodeUnsignedLeb128(¤t_data_); 1578 remaining_count_--; 1579 return; 1580 } 1581 1582 if (catch_all_) { 1583 handler_.type_idx_ = dex::TypeIndex(DexFile::kDexNoIndex16); 1584 handler_.address_ = DecodeUnsignedLeb128(¤t_data_); 1585 catch_all_ = false; 1586 return; 1587 } 1588 1589 // no more handler 1590 remaining_count_ = -1; 1591 } 1592 1593 namespace dex { 1594 1595 std::ostream& operator<<(std::ostream& os, const StringIndex& index) { 1596 os << "StringIndex[" << index.index_ << "]"; 1597 return os; 1598 } 1599 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