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