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/stat.h> 26 27#include <memory> 28#include <sstream> 29 30#include "art_field-inl.h" 31#include "art_method-inl.h" 32#include "base/logging.h" 33#include "base/stringprintf.h" 34#include "class_linker.h" 35#include "dex_file-inl.h" 36#include "dex_file_verifier.h" 37#include "globals.h" 38#include "leb128.h" 39#include "mirror/string.h" 40#include "os.h" 41#include "safe_map.h" 42#include "handle_scope-inl.h" 43#include "thread.h" 44#include "utf-inl.h" 45#include "utils.h" 46#include "well_known_classes.h" 47#include "zip_archive.h" 48 49#pragma GCC diagnostic push 50#pragma GCC diagnostic ignored "-Wshadow" 51#include "ScopedFd.h" 52#pragma GCC diagnostic pop 53 54namespace art { 55 56const uint8_t DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' }; 57const uint8_t DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' }; 58 59static int OpenAndReadMagic(const char* filename, uint32_t* magic, std::string* error_msg) { 60 CHECK(magic != nullptr); 61 ScopedFd fd(open(filename, O_RDONLY, 0)); 62 if (fd.get() == -1) { 63 *error_msg = StringPrintf("Unable to open '%s' : %s", filename, strerror(errno)); 64 return -1; 65 } 66 int n = TEMP_FAILURE_RETRY(read(fd.get(), magic, sizeof(*magic))); 67 if (n != sizeof(*magic)) { 68 *error_msg = StringPrintf("Failed to find magic in '%s'", filename); 69 return -1; 70 } 71 if (lseek(fd.get(), 0, SEEK_SET) != 0) { 72 *error_msg = StringPrintf("Failed to seek to beginning of file '%s' : %s", filename, 73 strerror(errno)); 74 return -1; 75 } 76 return fd.release(); 77} 78 79bool DexFile::GetChecksum(const char* filename, uint32_t* checksum, std::string* error_msg) { 80 CHECK(checksum != nullptr); 81 uint32_t magic; 82 83 // Strip ":...", which is the location 84 const char* zip_entry_name = kClassesDex; 85 const char* file_part = filename; 86 std::string file_part_storage; 87 88 if (DexFile::IsMultiDexLocation(filename)) { 89 file_part_storage = GetBaseLocation(filename); 90 file_part = file_part_storage.c_str(); 91 zip_entry_name = filename + file_part_storage.size() + 1; 92 DCHECK_EQ(zip_entry_name[-1], kMultiDexSeparator); 93 } 94 95 ScopedFd fd(OpenAndReadMagic(file_part, &magic, error_msg)); 96 if (fd.get() == -1) { 97 DCHECK(!error_msg->empty()); 98 return false; 99 } 100 if (IsZipMagic(magic)) { 101 std::unique_ptr<ZipArchive> zip_archive( 102 ZipArchive::OpenFromFd(fd.release(), filename, error_msg)); 103 if (zip_archive.get() == nullptr) { 104 *error_msg = StringPrintf("Failed to open zip archive '%s' (error msg: %s)", file_part, 105 error_msg->c_str()); 106 return false; 107 } 108 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(zip_entry_name, error_msg)); 109 if (zip_entry.get() == nullptr) { 110 *error_msg = StringPrintf("Zip archive '%s' doesn't contain %s (error msg: %s)", file_part, 111 zip_entry_name, error_msg->c_str()); 112 return false; 113 } 114 *checksum = zip_entry->GetCrc32(); 115 return true; 116 } 117 if (IsDexMagic(magic)) { 118 std::unique_ptr<const DexFile> dex_file( 119 DexFile::OpenFile(fd.release(), filename, false, error_msg)); 120 if (dex_file.get() == nullptr) { 121 return false; 122 } 123 *checksum = dex_file->GetHeader().checksum_; 124 return true; 125 } 126 *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename); 127 return false; 128} 129 130bool DexFile::Open(const char* filename, const char* location, std::string* error_msg, 131 std::vector<std::unique_ptr<const DexFile>>* dex_files) { 132 DCHECK(dex_files != nullptr) << "DexFile::Open: out-param is nullptr"; 133 uint32_t magic; 134 ScopedFd fd(OpenAndReadMagic(filename, &magic, error_msg)); 135 if (fd.get() == -1) { 136 DCHECK(!error_msg->empty()); 137 return false; 138 } 139 if (IsZipMagic(magic)) { 140 return DexFile::OpenZip(fd.release(), location, error_msg, dex_files); 141 } 142 if (IsDexMagic(magic)) { 143 std::unique_ptr<const DexFile> dex_file(DexFile::OpenFile(fd.release(), location, true, 144 error_msg)); 145 if (dex_file.get() != nullptr) { 146 dex_files->push_back(std::move(dex_file)); 147 return true; 148 } else { 149 return false; 150 } 151 } 152 *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename); 153 return false; 154} 155 156static bool ContainsClassesDex(int fd, const char* filename) { 157 std::string error_msg; 158 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd, filename, &error_msg)); 159 if (zip_archive.get() == nullptr) { 160 return false; 161 } 162 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(DexFile::kClassesDex, &error_msg)); 163 return (zip_entry.get() != nullptr); 164} 165 166bool DexFile::MaybeDex(const char* filename) { 167 uint32_t magic; 168 std::string error_msg; 169 ScopedFd fd(OpenAndReadMagic(filename, &magic, &error_msg)); 170 if (fd.get() == -1) { 171 return false; 172 } 173 if (IsZipMagic(magic)) { 174 return ContainsClassesDex(fd.release(), filename); 175 } else if (IsDexMagic(magic)) { 176 return true; 177 } 178 return false; 179} 180 181int DexFile::GetPermissions() const { 182 if (mem_map_.get() == nullptr) { 183 return 0; 184 } else { 185 return mem_map_->GetProtect(); 186 } 187} 188 189bool DexFile::IsReadOnly() const { 190 return GetPermissions() == PROT_READ; 191} 192 193bool DexFile::EnableWrite() const { 194 CHECK(IsReadOnly()); 195 if (mem_map_.get() == nullptr) { 196 return false; 197 } else { 198 return mem_map_->Protect(PROT_READ | PROT_WRITE); 199 } 200} 201 202bool DexFile::DisableWrite() const { 203 CHECK(!IsReadOnly()); 204 if (mem_map_.get() == nullptr) { 205 return false; 206 } else { 207 return mem_map_->Protect(PROT_READ); 208 } 209} 210 211std::unique_ptr<const DexFile> DexFile::OpenFile(int fd, const char* location, bool verify, 212 std::string* error_msg) { 213 CHECK(location != nullptr); 214 std::unique_ptr<MemMap> map; 215 { 216 ScopedFd delayed_close(fd); 217 struct stat sbuf; 218 memset(&sbuf, 0, sizeof(sbuf)); 219 if (fstat(fd, &sbuf) == -1) { 220 *error_msg = StringPrintf("DexFile: fstat '%s' failed: %s", location, strerror(errno)); 221 return nullptr; 222 } 223 if (S_ISDIR(sbuf.st_mode)) { 224 *error_msg = StringPrintf("Attempt to mmap directory '%s'", location); 225 return nullptr; 226 } 227 size_t length = sbuf.st_size; 228 map.reset(MemMap::MapFile(length, PROT_READ, MAP_PRIVATE, fd, 0, location, error_msg)); 229 if (map.get() == nullptr) { 230 DCHECK(!error_msg->empty()); 231 return nullptr; 232 } 233 } 234 235 if (map->Size() < sizeof(DexFile::Header)) { 236 *error_msg = StringPrintf( 237 "DexFile: failed to open dex file '%s' that is too short to have a header", location); 238 return nullptr; 239 } 240 241 const Header* dex_header = reinterpret_cast<const Header*>(map->Begin()); 242 243 std::unique_ptr<const DexFile> dex_file(OpenMemory(location, dex_header->checksum_, map.release(), 244 error_msg)); 245 if (dex_file.get() == nullptr) { 246 *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location, 247 error_msg->c_str()); 248 return nullptr; 249 } 250 251 if (verify && !DexFileVerifier::Verify(dex_file.get(), dex_file->Begin(), dex_file->Size(), 252 location, error_msg)) { 253 return nullptr; 254 } 255 256 return dex_file; 257} 258 259const char* DexFile::kClassesDex = "classes.dex"; 260 261bool DexFile::OpenZip(int fd, const std::string& location, std::string* error_msg, 262 std::vector<std::unique_ptr<const DexFile>>* dex_files) { 263 DCHECK(dex_files != nullptr) << "DexFile::OpenZip: out-param is nullptr"; 264 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd, location.c_str(), error_msg)); 265 if (zip_archive.get() == nullptr) { 266 DCHECK(!error_msg->empty()); 267 return false; 268 } 269 return DexFile::OpenFromZip(*zip_archive, location, error_msg, dex_files); 270} 271 272std::unique_ptr<const DexFile> DexFile::OpenMemory(const std::string& location, 273 uint32_t location_checksum, 274 MemMap* mem_map, 275 std::string* error_msg) { 276 return OpenMemory(mem_map->Begin(), 277 mem_map->Size(), 278 location, 279 location_checksum, 280 mem_map, 281 nullptr, 282 error_msg); 283} 284 285std::unique_ptr<const DexFile> DexFile::Open(const ZipArchive& zip_archive, const char* entry_name, 286 const std::string& location, std::string* error_msg, 287 ZipOpenErrorCode* error_code) { 288 CHECK(!location.empty()); 289 std::unique_ptr<ZipEntry> zip_entry(zip_archive.Find(entry_name, error_msg)); 290 if (zip_entry.get() == nullptr) { 291 *error_code = ZipOpenErrorCode::kEntryNotFound; 292 return nullptr; 293 } 294 std::unique_ptr<MemMap> map(zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg)); 295 if (map.get() == nullptr) { 296 *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", entry_name, location.c_str(), 297 error_msg->c_str()); 298 *error_code = ZipOpenErrorCode::kExtractToMemoryError; 299 return nullptr; 300 } 301 std::unique_ptr<const DexFile> dex_file(OpenMemory(location, zip_entry->GetCrc32(), map.release(), 302 error_msg)); 303 if (dex_file.get() == nullptr) { 304 *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(), 305 error_msg->c_str()); 306 *error_code = ZipOpenErrorCode::kDexFileError; 307 return nullptr; 308 } 309 if (!dex_file->DisableWrite()) { 310 *error_msg = StringPrintf("Failed to make dex file '%s' read only", location.c_str()); 311 *error_code = ZipOpenErrorCode::kMakeReadOnlyError; 312 return nullptr; 313 } 314 CHECK(dex_file->IsReadOnly()) << location; 315 if (!DexFileVerifier::Verify(dex_file.get(), dex_file->Begin(), dex_file->Size(), 316 location.c_str(), error_msg)) { 317 *error_code = ZipOpenErrorCode::kVerifyError; 318 return nullptr; 319 } 320 *error_code = ZipOpenErrorCode::kNoError; 321 return dex_file; 322} 323 324// Technically we do not have a limitation with respect to the number of dex files that can be in a 325// multidex APK. However, it's bad practice, as each dex file requires its own tables for symbols 326// (types, classes, methods, ...) and dex caches. So warn the user that we open a zip with what 327// seems an excessive number. 328static constexpr size_t kWarnOnManyDexFilesThreshold = 100; 329 330bool DexFile::OpenFromZip(const ZipArchive& zip_archive, const std::string& location, 331 std::string* error_msg, 332 std::vector<std::unique_ptr<const DexFile>>* dex_files) { 333 DCHECK(dex_files != nullptr) << "DexFile::OpenFromZip: out-param is nullptr"; 334 ZipOpenErrorCode error_code; 335 std::unique_ptr<const DexFile> dex_file(Open(zip_archive, kClassesDex, location, error_msg, 336 &error_code)); 337 if (dex_file.get() == nullptr) { 338 return false; 339 } else { 340 // Had at least classes.dex. 341 dex_files->push_back(std::move(dex_file)); 342 343 // Now try some more. 344 345 // We could try to avoid std::string allocations by working on a char array directly. As we 346 // do not expect a lot of iterations, this seems too involved and brittle. 347 348 for (size_t i = 1; ; ++i) { 349 std::string name = GetMultiDexClassesDexName(i); 350 std::string fake_location = GetMultiDexLocation(i, location.c_str()); 351 std::unique_ptr<const DexFile> next_dex_file(Open(zip_archive, name.c_str(), fake_location, 352 error_msg, &error_code)); 353 if (next_dex_file.get() == nullptr) { 354 if (error_code != ZipOpenErrorCode::kEntryNotFound) { 355 LOG(WARNING) << error_msg; 356 } 357 break; 358 } else { 359 dex_files->push_back(std::move(next_dex_file)); 360 } 361 362 if (i == kWarnOnManyDexFilesThreshold) { 363 LOG(WARNING) << location << " has in excess of " << kWarnOnManyDexFilesThreshold 364 << " dex files. Please consider coalescing and shrinking the number to " 365 " avoid runtime overhead."; 366 } 367 368 if (i == std::numeric_limits<size_t>::max()) { 369 LOG(ERROR) << "Overflow in number of dex files!"; 370 break; 371 } 372 } 373 374 return true; 375 } 376} 377 378 379std::unique_ptr<const DexFile> DexFile::OpenMemory(const uint8_t* base, 380 size_t size, 381 const std::string& location, 382 uint32_t location_checksum, 383 MemMap* mem_map, 384 const OatDexFile* oat_dex_file, 385 std::string* error_msg) { 386 CHECK_ALIGNED(base, 4); // various dex file structures must be word aligned 387 std::unique_ptr<DexFile> dex_file( 388 new DexFile(base, size, location, location_checksum, mem_map, oat_dex_file)); 389 if (!dex_file->Init(error_msg)) { 390 dex_file.reset(); 391 } 392 return std::unique_ptr<const DexFile>(dex_file.release()); 393} 394 395DexFile::DexFile(const uint8_t* base, size_t size, 396 const std::string& location, 397 uint32_t location_checksum, 398 MemMap* mem_map, 399 const OatDexFile* oat_dex_file) 400 : begin_(base), 401 size_(size), 402 location_(location), 403 location_checksum_(location_checksum), 404 mem_map_(mem_map), 405 header_(reinterpret_cast<const Header*>(base)), 406 string_ids_(reinterpret_cast<const StringId*>(base + header_->string_ids_off_)), 407 type_ids_(reinterpret_cast<const TypeId*>(base + header_->type_ids_off_)), 408 field_ids_(reinterpret_cast<const FieldId*>(base + header_->field_ids_off_)), 409 method_ids_(reinterpret_cast<const MethodId*>(base + header_->method_ids_off_)), 410 proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)), 411 class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)), 412 find_class_def_misses_(0), 413 class_def_index_(nullptr), 414 oat_dex_file_(oat_dex_file) { 415 CHECK(begin_ != nullptr) << GetLocation(); 416 CHECK_GT(size_, 0U) << GetLocation(); 417} 418 419DexFile::~DexFile() { 420 // We don't call DeleteGlobalRef on dex_object_ because we're only called by DestroyJavaVM, and 421 // that's only called after DetachCurrentThread, which means there's no JNIEnv. We could 422 // re-attach, but cleaning up these global references is not obviously useful. It's not as if 423 // the global reference table is otherwise empty! 424 // Remove the index if one were created. 425 delete class_def_index_.LoadRelaxed(); 426} 427 428bool DexFile::Init(std::string* error_msg) { 429 if (!CheckMagicAndVersion(error_msg)) { 430 return false; 431 } 432 return true; 433} 434 435bool DexFile::CheckMagicAndVersion(std::string* error_msg) const { 436 if (!IsMagicValid(header_->magic_)) { 437 std::ostringstream oss; 438 oss << "Unrecognized magic number in " << GetLocation() << ":" 439 << " " << header_->magic_[0] 440 << " " << header_->magic_[1] 441 << " " << header_->magic_[2] 442 << " " << header_->magic_[3]; 443 *error_msg = oss.str(); 444 return false; 445 } 446 if (!IsVersionValid(header_->magic_)) { 447 std::ostringstream oss; 448 oss << "Unrecognized version number in " << GetLocation() << ":" 449 << " " << header_->magic_[4] 450 << " " << header_->magic_[5] 451 << " " << header_->magic_[6] 452 << " " << header_->magic_[7]; 453 *error_msg = oss.str(); 454 return false; 455 } 456 return true; 457} 458 459bool DexFile::IsMagicValid(const uint8_t* magic) { 460 return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0); 461} 462 463bool DexFile::IsVersionValid(const uint8_t* magic) { 464 const uint8_t* version = &magic[sizeof(kDexMagic)]; 465 return (memcmp(version, kDexMagicVersion, sizeof(kDexMagicVersion)) == 0); 466} 467 468uint32_t DexFile::GetVersion() const { 469 const char* version = reinterpret_cast<const char*>(&GetHeader().magic_[sizeof(kDexMagic)]); 470 return atoi(version); 471} 472 473const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor, size_t hash) const { 474 DCHECK_EQ(ComputeModifiedUtf8Hash(descriptor), hash); 475 // If we have an index lookup the descriptor via that as its constant time to search. 476 Index* index = class_def_index_.LoadSequentiallyConsistent(); 477 if (index != nullptr) { 478 auto it = index->FindWithHash(descriptor, hash); 479 return (it == index->end()) ? nullptr : it->second; 480 } 481 // Fast path for rate no class defs case. 482 uint32_t num_class_defs = NumClassDefs(); 483 if (num_class_defs == 0) { 484 return nullptr; 485 } 486 // Search for class def with 2 binary searches and then a linear search. 487 const StringId* string_id = FindStringId(descriptor); 488 if (string_id != nullptr) { 489 const TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id)); 490 if (type_id != nullptr) { 491 uint16_t type_idx = GetIndexForTypeId(*type_id); 492 for (size_t i = 0; i < num_class_defs; ++i) { 493 const ClassDef& class_def = GetClassDef(i); 494 if (class_def.class_idx_ == type_idx) { 495 return &class_def; 496 } 497 } 498 } 499 } 500 // A miss. If we've had kMaxFailedDexClassDefLookups misses then build an index to speed things 501 // up. This isn't done eagerly at construction as construction is not performed in multi-threaded 502 // sections of tools like dex2oat. If we're lazy we hopefully increase the chance of balancing 503 // out which thread builds the index. 504 const uint32_t kMaxFailedDexClassDefLookups = 100; 505 uint32_t old_misses = find_class_def_misses_.FetchAndAddSequentiallyConsistent(1); 506 if (old_misses == kMaxFailedDexClassDefLookups) { 507 // Are we the ones moving the miss count past the max? Sanity check the index doesn't exist. 508 CHECK(class_def_index_.LoadSequentiallyConsistent() == nullptr); 509 // Build the index. 510 index = new Index(); 511 for (uint32_t i = 0; i < num_class_defs; ++i) { 512 const ClassDef& class_def = GetClassDef(i); 513 const char* class_descriptor = GetClassDescriptor(class_def); 514 index->Insert(std::make_pair(class_descriptor, &class_def)); 515 } 516 // Sanity check the index still doesn't exist, only 1 thread should build it. 517 CHECK(class_def_index_.LoadSequentiallyConsistent() == nullptr); 518 class_def_index_.StoreSequentiallyConsistent(index); 519 } 520 return nullptr; 521} 522 523const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const { 524 size_t num_class_defs = NumClassDefs(); 525 for (size_t i = 0; i < num_class_defs; ++i) { 526 const ClassDef& class_def = GetClassDef(i); 527 if (class_def.class_idx_ == type_idx) { 528 return &class_def; 529 } 530 } 531 return nullptr; 532} 533 534const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass, 535 const DexFile::StringId& name, 536 const DexFile::TypeId& type) const { 537 // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx 538 const uint16_t class_idx = GetIndexForTypeId(declaring_klass); 539 const uint32_t name_idx = GetIndexForStringId(name); 540 const uint16_t type_idx = GetIndexForTypeId(type); 541 int32_t lo = 0; 542 int32_t hi = NumFieldIds() - 1; 543 while (hi >= lo) { 544 int32_t mid = (hi + lo) / 2; 545 const DexFile::FieldId& field = GetFieldId(mid); 546 if (class_idx > field.class_idx_) { 547 lo = mid + 1; 548 } else if (class_idx < field.class_idx_) { 549 hi = mid - 1; 550 } else { 551 if (name_idx > field.name_idx_) { 552 lo = mid + 1; 553 } else if (name_idx < field.name_idx_) { 554 hi = mid - 1; 555 } else { 556 if (type_idx > field.type_idx_) { 557 lo = mid + 1; 558 } else if (type_idx < field.type_idx_) { 559 hi = mid - 1; 560 } else { 561 return &field; 562 } 563 } 564 } 565 } 566 return nullptr; 567} 568 569const DexFile::MethodId* DexFile::FindMethodId(const DexFile::TypeId& declaring_klass, 570 const DexFile::StringId& name, 571 const DexFile::ProtoId& signature) const { 572 // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx 573 const uint16_t class_idx = GetIndexForTypeId(declaring_klass); 574 const uint32_t name_idx = GetIndexForStringId(name); 575 const uint16_t proto_idx = GetIndexForProtoId(signature); 576 int32_t lo = 0; 577 int32_t hi = NumMethodIds() - 1; 578 while (hi >= lo) { 579 int32_t mid = (hi + lo) / 2; 580 const DexFile::MethodId& method = GetMethodId(mid); 581 if (class_idx > method.class_idx_) { 582 lo = mid + 1; 583 } else if (class_idx < method.class_idx_) { 584 hi = mid - 1; 585 } else { 586 if (name_idx > method.name_idx_) { 587 lo = mid + 1; 588 } else if (name_idx < method.name_idx_) { 589 hi = mid - 1; 590 } else { 591 if (proto_idx > method.proto_idx_) { 592 lo = mid + 1; 593 } else if (proto_idx < method.proto_idx_) { 594 hi = mid - 1; 595 } else { 596 return &method; 597 } 598 } 599 } 600 } 601 return nullptr; 602} 603 604const DexFile::StringId* DexFile::FindStringId(const char* string) const { 605 int32_t lo = 0; 606 int32_t hi = NumStringIds() - 1; 607 while (hi >= lo) { 608 int32_t mid = (hi + lo) / 2; 609 const DexFile::StringId& str_id = GetStringId(mid); 610 const char* str = GetStringData(str_id); 611 int compare = CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(string, str); 612 if (compare > 0) { 613 lo = mid + 1; 614 } else if (compare < 0) { 615 hi = mid - 1; 616 } else { 617 return &str_id; 618 } 619 } 620 return nullptr; 621} 622 623const DexFile::StringId* DexFile::FindStringId(const uint16_t* string, size_t length) const { 624 int32_t lo = 0; 625 int32_t hi = NumStringIds() - 1; 626 while (hi >= lo) { 627 int32_t mid = (hi + lo) / 2; 628 const DexFile::StringId& str_id = GetStringId(mid); 629 const char* str = GetStringData(str_id); 630 int compare = CompareModifiedUtf8ToUtf16AsCodePointValues(str, string, length); 631 if (compare > 0) { 632 lo = mid + 1; 633 } else if (compare < 0) { 634 hi = mid - 1; 635 } else { 636 return &str_id; 637 } 638 } 639 return nullptr; 640} 641 642const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const { 643 int32_t lo = 0; 644 int32_t hi = NumTypeIds() - 1; 645 while (hi >= lo) { 646 int32_t mid = (hi + lo) / 2; 647 const TypeId& type_id = GetTypeId(mid); 648 if (string_idx > type_id.descriptor_idx_) { 649 lo = mid + 1; 650 } else if (string_idx < type_id.descriptor_idx_) { 651 hi = mid - 1; 652 } else { 653 return &type_id; 654 } 655 } 656 return nullptr; 657} 658 659const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx, 660 const uint16_t* signature_type_idxs, 661 uint32_t signature_length) const { 662 int32_t lo = 0; 663 int32_t hi = NumProtoIds() - 1; 664 while (hi >= lo) { 665 int32_t mid = (hi + lo) / 2; 666 const DexFile::ProtoId& proto = GetProtoId(mid); 667 int compare = return_type_idx - proto.return_type_idx_; 668 if (compare == 0) { 669 DexFileParameterIterator it(*this, proto); 670 size_t i = 0; 671 while (it.HasNext() && i < signature_length && compare == 0) { 672 compare = signature_type_idxs[i] - it.GetTypeIdx(); 673 it.Next(); 674 i++; 675 } 676 if (compare == 0) { 677 if (it.HasNext()) { 678 compare = -1; 679 } else if (i < signature_length) { 680 compare = 1; 681 } 682 } 683 } 684 if (compare > 0) { 685 lo = mid + 1; 686 } else if (compare < 0) { 687 hi = mid - 1; 688 } else { 689 return &proto; 690 } 691 } 692 return nullptr; 693} 694 695// Given a signature place the type ids into the given vector 696bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx, 697 std::vector<uint16_t>* param_type_idxs) const { 698 if (signature[0] != '(') { 699 return false; 700 } 701 size_t offset = 1; 702 size_t end = signature.size(); 703 bool process_return = false; 704 while (offset < end) { 705 size_t start_offset = offset; 706 char c = signature[offset]; 707 offset++; 708 if (c == ')') { 709 process_return = true; 710 continue; 711 } 712 while (c == '[') { // process array prefix 713 if (offset >= end) { // expect some descriptor following [ 714 return false; 715 } 716 c = signature[offset]; 717 offset++; 718 } 719 if (c == 'L') { // process type descriptors 720 do { 721 if (offset >= end) { // unexpected early termination of descriptor 722 return false; 723 } 724 c = signature[offset]; 725 offset++; 726 } while (c != ';'); 727 } 728 // TODO: avoid creating a std::string just to get a 0-terminated char array 729 std::string descriptor(signature.data() + start_offset, offset - start_offset); 730 const DexFile::StringId* string_id = FindStringId(descriptor.c_str()); 731 if (string_id == nullptr) { 732 return false; 733 } 734 const DexFile::TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id)); 735 if (type_id == nullptr) { 736 return false; 737 } 738 uint16_t type_idx = GetIndexForTypeId(*type_id); 739 if (!process_return) { 740 param_type_idxs->push_back(type_idx); 741 } else { 742 *return_type_idx = type_idx; 743 return offset == end; // return true if the signature had reached a sensible end 744 } 745 } 746 return false; // failed to correctly parse return type 747} 748 749const Signature DexFile::CreateSignature(const StringPiece& signature) const { 750 uint16_t return_type_idx; 751 std::vector<uint16_t> param_type_indices; 752 bool success = CreateTypeList(signature, &return_type_idx, ¶m_type_indices); 753 if (!success) { 754 return Signature::NoSignature(); 755 } 756 const ProtoId* proto_id = FindProtoId(return_type_idx, param_type_indices); 757 if (proto_id == nullptr) { 758 return Signature::NoSignature(); 759 } 760 return Signature(this, *proto_id); 761} 762 763int32_t DexFile::GetLineNumFromPC(ArtMethod* method, uint32_t rel_pc) const { 764 // For native method, lineno should be -2 to indicate it is native. Note that 765 // "line number == -2" is how libcore tells from StackTraceElement. 766 if (method->GetCodeItemOffset() == 0) { 767 return -2; 768 } 769 770 const CodeItem* code_item = GetCodeItem(method->GetCodeItemOffset()); 771 DCHECK(code_item != nullptr) << PrettyMethod(method) << " " << GetLocation(); 772 773 // A method with no line number info should return -1 774 LineNumFromPcContext context(rel_pc, -1); 775 DecodeDebugInfo(code_item, method->IsStatic(), method->GetDexMethodIndex(), LineNumForPcCb, 776 nullptr, &context); 777 return context.line_num_; 778} 779 780int32_t DexFile::FindTryItem(const CodeItem &code_item, uint32_t address) { 781 // Note: Signed type is important for max and min. 782 int32_t min = 0; 783 int32_t max = code_item.tries_size_ - 1; 784 785 while (min <= max) { 786 int32_t mid = min + ((max - min) / 2); 787 788 const art::DexFile::TryItem* ti = GetTryItems(code_item, mid); 789 uint32_t start = ti->start_addr_; 790 uint32_t end = start + ti->insn_count_; 791 792 if (address < start) { 793 max = mid - 1; 794 } else if (address >= end) { 795 min = mid + 1; 796 } else { // We have a winner! 797 return mid; 798 } 799 } 800 // No match. 801 return -1; 802} 803 804int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address) { 805 int32_t try_item = FindTryItem(code_item, address); 806 if (try_item == -1) { 807 return -1; 808 } else { 809 return DexFile::GetTryItems(code_item, try_item)->handler_off_; 810 } 811} 812 813void DexFile::DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx, 814 DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb, 815 void* context, const uint8_t* stream, LocalInfo* local_in_reg) 816 const { 817 uint32_t line = DecodeUnsignedLeb128(&stream); 818 uint32_t parameters_size = DecodeUnsignedLeb128(&stream); 819 uint16_t arg_reg = code_item->registers_size_ - code_item->ins_size_; 820 uint32_t address = 0; 821 bool need_locals = (local_cb != nullptr); 822 823 if (!is_static) { 824 if (need_locals) { 825 const char* descriptor = GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)); 826 local_in_reg[arg_reg].name_ = "this"; 827 local_in_reg[arg_reg].descriptor_ = descriptor; 828 local_in_reg[arg_reg].signature_ = nullptr; 829 local_in_reg[arg_reg].start_address_ = 0; 830 local_in_reg[arg_reg].is_live_ = true; 831 } 832 arg_reg++; 833 } 834 835 DexFileParameterIterator it(*this, GetMethodPrototype(GetMethodId(method_idx))); 836 for (uint32_t i = 0; i < parameters_size && it.HasNext(); ++i, it.Next()) { 837 if (arg_reg >= code_item->registers_size_) { 838 LOG(ERROR) << "invalid stream - arg reg >= reg size (" << arg_reg 839 << " >= " << code_item->registers_size_ << ") in " << GetLocation(); 840 return; 841 } 842 uint32_t id = DecodeUnsignedLeb128P1(&stream); 843 const char* descriptor = it.GetDescriptor(); 844 if (need_locals && id != kDexNoIndex) { 845 const char* name = StringDataByIdx(id); 846 local_in_reg[arg_reg].name_ = name; 847 local_in_reg[arg_reg].descriptor_ = descriptor; 848 local_in_reg[arg_reg].signature_ = nullptr; 849 local_in_reg[arg_reg].start_address_ = address; 850 local_in_reg[arg_reg].is_live_ = true; 851 } 852 switch (*descriptor) { 853 case 'D': 854 case 'J': 855 arg_reg += 2; 856 break; 857 default: 858 arg_reg += 1; 859 break; 860 } 861 } 862 863 if (it.HasNext()) { 864 LOG(ERROR) << "invalid stream - problem with parameter iterator in " << GetLocation() 865 << " for method " << PrettyMethod(method_idx, *this); 866 return; 867 } 868 869 for (;;) { 870 uint8_t opcode = *stream++; 871 uint16_t reg; 872 uint32_t name_idx; 873 uint32_t descriptor_idx; 874 uint32_t signature_idx = 0; 875 876 switch (opcode) { 877 case DBG_END_SEQUENCE: 878 return; 879 880 case DBG_ADVANCE_PC: 881 address += DecodeUnsignedLeb128(&stream); 882 break; 883 884 case DBG_ADVANCE_LINE: 885 line += DecodeSignedLeb128(&stream); 886 break; 887 888 case DBG_START_LOCAL: 889 case DBG_START_LOCAL_EXTENDED: 890 reg = DecodeUnsignedLeb128(&stream); 891 if (reg > code_item->registers_size_) { 892 LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > " 893 << code_item->registers_size_ << ") in " << GetLocation(); 894 return; 895 } 896 897 name_idx = DecodeUnsignedLeb128P1(&stream); 898 descriptor_idx = DecodeUnsignedLeb128P1(&stream); 899 if (opcode == DBG_START_LOCAL_EXTENDED) { 900 signature_idx = DecodeUnsignedLeb128P1(&stream); 901 } 902 903 // Emit what was previously there, if anything 904 if (need_locals) { 905 InvokeLocalCbIfLive(context, reg, address, local_in_reg, local_cb); 906 907 local_in_reg[reg].name_ = StringDataByIdx(name_idx); 908 local_in_reg[reg].descriptor_ = StringByTypeIdx(descriptor_idx); 909 if (opcode == DBG_START_LOCAL_EXTENDED) { 910 local_in_reg[reg].signature_ = StringDataByIdx(signature_idx); 911 } 912 local_in_reg[reg].start_address_ = address; 913 local_in_reg[reg].is_live_ = true; 914 } 915 break; 916 917 case DBG_END_LOCAL: 918 reg = DecodeUnsignedLeb128(&stream); 919 if (reg > code_item->registers_size_) { 920 LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > " 921 << code_item->registers_size_ << ") in " << GetLocation(); 922 return; 923 } 924 925 if (need_locals) { 926 InvokeLocalCbIfLive(context, reg, address, local_in_reg, local_cb); 927 local_in_reg[reg].is_live_ = false; 928 } 929 break; 930 931 case DBG_RESTART_LOCAL: 932 reg = DecodeUnsignedLeb128(&stream); 933 if (reg > code_item->registers_size_) { 934 LOG(ERROR) << "invalid stream - reg > reg size (" << reg << " > " 935 << code_item->registers_size_ << ") in " << GetLocation(); 936 return; 937 } 938 939 if (need_locals) { 940 if (local_in_reg[reg].name_ == nullptr || local_in_reg[reg].descriptor_ == nullptr) { 941 LOG(ERROR) << "invalid stream - no name or descriptor in " << GetLocation(); 942 return; 943 } 944 945 // If the register is live, the "restart" is superfluous, 946 // and we don't want to mess with the existing start address. 947 if (!local_in_reg[reg].is_live_) { 948 local_in_reg[reg].start_address_ = address; 949 local_in_reg[reg].is_live_ = true; 950 } 951 } 952 break; 953 954 case DBG_SET_PROLOGUE_END: 955 case DBG_SET_EPILOGUE_BEGIN: 956 case DBG_SET_FILE: 957 break; 958 959 default: { 960 int adjopcode = opcode - DBG_FIRST_SPECIAL; 961 962 address += adjopcode / DBG_LINE_RANGE; 963 line += DBG_LINE_BASE + (adjopcode % DBG_LINE_RANGE); 964 965 if (position_cb != nullptr) { 966 if (position_cb(context, address, line)) { 967 // early exit 968 return; 969 } 970 } 971 break; 972 } 973 } 974 } 975} 976 977void DexFile::DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx, 978 DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb, 979 void* context) const { 980 DCHECK(code_item != nullptr); 981 const uint8_t* stream = GetDebugInfoStream(code_item); 982 std::unique_ptr<LocalInfo[]> local_in_reg(local_cb != nullptr ? 983 new LocalInfo[code_item->registers_size_] : 984 nullptr); 985 if (stream != nullptr) { 986 DecodeDebugInfo0(code_item, is_static, method_idx, position_cb, local_cb, context, stream, 987 &local_in_reg[0]); 988 } 989 for (int reg = 0; reg < code_item->registers_size_; reg++) { 990 InvokeLocalCbIfLive(context, reg, code_item->insns_size_in_code_units_, &local_in_reg[0], 991 local_cb); 992 } 993} 994 995bool DexFile::LineNumForPcCb(void* raw_context, uint32_t address, uint32_t line_num) { 996 LineNumFromPcContext* context = reinterpret_cast<LineNumFromPcContext*>(raw_context); 997 998 // We know that this callback will be called in 999 // ascending address order, so keep going until we find 1000 // a match or we've just gone past it. 1001 if (address > context->address_) { 1002 // The line number from the previous positions callback 1003 // wil be the final result. 1004 return true; 1005 } else { 1006 context->line_num_ = line_num; 1007 return address == context->address_; 1008 } 1009} 1010 1011bool DexFile::IsMultiDexLocation(const char* location) { 1012 return strrchr(location, kMultiDexSeparator) != nullptr; 1013} 1014 1015std::string DexFile::GetMultiDexClassesDexName(size_t index) { 1016 if (index == 0) { 1017 return "classes.dex"; 1018 } else { 1019 return StringPrintf("classes%zu.dex", index + 1); 1020 } 1021} 1022 1023std::string DexFile::GetMultiDexLocation(size_t index, const char* dex_location) { 1024 if (index == 0) { 1025 return dex_location; 1026 } else { 1027 return StringPrintf("%s" kMultiDexSeparatorString "classes%zu.dex", dex_location, index + 1); 1028 } 1029} 1030 1031std::string DexFile::GetDexCanonicalLocation(const char* dex_location) { 1032 CHECK_NE(dex_location, static_cast<const char*>(nullptr)); 1033 std::string base_location = GetBaseLocation(dex_location); 1034 const char* suffix = dex_location + base_location.size(); 1035 DCHECK(suffix[0] == 0 || suffix[0] == kMultiDexSeparator); 1036 UniqueCPtr<const char[]> path(realpath(base_location.c_str(), nullptr)); 1037 if (path != nullptr && path.get() != base_location) { 1038 return std::string(path.get()) + suffix; 1039 } else if (suffix[0] == 0) { 1040 return base_location; 1041 } else { 1042 return dex_location; 1043 } 1044} 1045 1046std::ostream& operator<<(std::ostream& os, const DexFile& dex_file) { 1047 os << StringPrintf("[DexFile: %s dex-checksum=%08x location-checksum=%08x %p-%p]", 1048 dex_file.GetLocation().c_str(), 1049 dex_file.GetHeader().checksum_, dex_file.GetLocationChecksum(), 1050 dex_file.Begin(), dex_file.Begin() + dex_file.Size()); 1051 return os; 1052} 1053 1054std::string Signature::ToString() const { 1055 if (dex_file_ == nullptr) { 1056 CHECK(proto_id_ == nullptr); 1057 return "<no signature>"; 1058 } 1059 const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_); 1060 std::string result; 1061 if (params == nullptr) { 1062 result += "()"; 1063 } else { 1064 result += "("; 1065 for (uint32_t i = 0; i < params->Size(); ++i) { 1066 result += dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_); 1067 } 1068 result += ")"; 1069 } 1070 result += dex_file_->StringByTypeIdx(proto_id_->return_type_idx_); 1071 return result; 1072} 1073 1074bool Signature::operator==(const StringPiece& rhs) const { 1075 if (dex_file_ == nullptr) { 1076 return false; 1077 } 1078 StringPiece tail(rhs); 1079 if (!tail.starts_with("(")) { 1080 return false; // Invalid signature 1081 } 1082 tail.remove_prefix(1); // "("; 1083 const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_); 1084 if (params != nullptr) { 1085 for (uint32_t i = 0; i < params->Size(); ++i) { 1086 StringPiece param(dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_)); 1087 if (!tail.starts_with(param)) { 1088 return false; 1089 } 1090 tail.remove_prefix(param.length()); 1091 } 1092 } 1093 if (!tail.starts_with(")")) { 1094 return false; 1095 } 1096 tail.remove_prefix(1); // ")"; 1097 return tail == dex_file_->StringByTypeIdx(proto_id_->return_type_idx_); 1098} 1099 1100std::ostream& operator<<(std::ostream& os, const Signature& sig) { 1101 return os << sig.ToString(); 1102} 1103 1104// Decodes the header section from the class data bytes. 1105void ClassDataItemIterator::ReadClassDataHeader() { 1106 CHECK(ptr_pos_ != nullptr); 1107 header_.static_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_); 1108 header_.instance_fields_size_ = DecodeUnsignedLeb128(&ptr_pos_); 1109 header_.direct_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_); 1110 header_.virtual_methods_size_ = DecodeUnsignedLeb128(&ptr_pos_); 1111} 1112 1113void ClassDataItemIterator::ReadClassDataField() { 1114 field_.field_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_); 1115 field_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_); 1116 if (last_idx_ != 0 && field_.field_idx_delta_ == 0) { 1117 LOG(WARNING) << "Duplicate field in " << dex_file_.GetLocation(); 1118 } 1119} 1120 1121void ClassDataItemIterator::ReadClassDataMethod() { 1122 method_.method_idx_delta_ = DecodeUnsignedLeb128(&ptr_pos_); 1123 method_.access_flags_ = DecodeUnsignedLeb128(&ptr_pos_); 1124 method_.code_off_ = DecodeUnsignedLeb128(&ptr_pos_); 1125 if (last_idx_ != 0 && method_.method_idx_delta_ == 0) { 1126 LOG(WARNING) << "Duplicate method in " << dex_file_.GetLocation(); 1127 } 1128} 1129 1130// Read a signed integer. "zwidth" is the zero-based byte count. 1131static int32_t ReadSignedInt(const uint8_t* ptr, int zwidth) { 1132 int32_t val = 0; 1133 for (int i = zwidth; i >= 0; --i) { 1134 val = ((uint32_t)val >> 8) | (((int32_t)*ptr++) << 24); 1135 } 1136 val >>= (3 - zwidth) * 8; 1137 return val; 1138} 1139 1140// Read an unsigned integer. "zwidth" is the zero-based byte count, 1141// "fill_on_right" indicates which side we want to zero-fill from. 1142static uint32_t ReadUnsignedInt(const uint8_t* ptr, int zwidth, bool fill_on_right) { 1143 uint32_t val = 0; 1144 if (!fill_on_right) { 1145 for (int i = zwidth; i >= 0; --i) { 1146 val = (val >> 8) | (((uint32_t)*ptr++) << 24); 1147 } 1148 val >>= (3 - zwidth) * 8; 1149 } else { 1150 for (int i = zwidth; i >= 0; --i) { 1151 val = (val >> 8) | (((uint32_t)*ptr++) << 24); 1152 } 1153 } 1154 return val; 1155} 1156 1157// Read a signed long. "zwidth" is the zero-based byte count. 1158static int64_t ReadSignedLong(const uint8_t* ptr, int zwidth) { 1159 int64_t val = 0; 1160 for (int i = zwidth; i >= 0; --i) { 1161 val = ((uint64_t)val >> 8) | (((int64_t)*ptr++) << 56); 1162 } 1163 val >>= (7 - zwidth) * 8; 1164 return val; 1165} 1166 1167// Read an unsigned long. "zwidth" is the zero-based byte count, 1168// "fill_on_right" indicates which side we want to zero-fill from. 1169static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right) { 1170 uint64_t val = 0; 1171 if (!fill_on_right) { 1172 for (int i = zwidth; i >= 0; --i) { 1173 val = (val >> 8) | (((uint64_t)*ptr++) << 56); 1174 } 1175 val >>= (7 - zwidth) * 8; 1176 } else { 1177 for (int i = zwidth; i >= 0; --i) { 1178 val = (val >> 8) | (((uint64_t)*ptr++) << 56); 1179 } 1180 } 1181 return val; 1182} 1183 1184EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator( 1185 const DexFile& dex_file, Handle<mirror::DexCache>* dex_cache, 1186 Handle<mirror::ClassLoader>* class_loader, ClassLinker* linker, 1187 const DexFile::ClassDef& class_def) 1188 : dex_file_(dex_file), dex_cache_(dex_cache), class_loader_(class_loader), linker_(linker), 1189 array_size_(), pos_(-1), type_(kByte) { 1190 DCHECK(dex_cache != nullptr); 1191 DCHECK(class_loader != nullptr); 1192 ptr_ = dex_file.GetEncodedStaticFieldValuesArray(class_def); 1193 if (ptr_ == nullptr) { 1194 array_size_ = 0; 1195 } else { 1196 array_size_ = DecodeUnsignedLeb128(&ptr_); 1197 } 1198 if (array_size_ > 0) { 1199 Next(); 1200 } 1201} 1202 1203void EncodedStaticFieldValueIterator::Next() { 1204 pos_++; 1205 if (pos_ >= array_size_) { 1206 return; 1207 } 1208 uint8_t value_type = *ptr_++; 1209 uint8_t value_arg = value_type >> kEncodedValueArgShift; 1210 size_t width = value_arg + 1; // assume and correct later 1211 type_ = static_cast<ValueType>(value_type & kEncodedValueTypeMask); 1212 switch (type_) { 1213 case kBoolean: 1214 jval_.i = (value_arg != 0) ? 1 : 0; 1215 width = 0; 1216 break; 1217 case kByte: 1218 jval_.i = ReadSignedInt(ptr_, value_arg); 1219 CHECK(IsInt<8>(jval_.i)); 1220 break; 1221 case kShort: 1222 jval_.i = ReadSignedInt(ptr_, value_arg); 1223 CHECK(IsInt<16>(jval_.i)); 1224 break; 1225 case kChar: 1226 jval_.i = ReadUnsignedInt(ptr_, value_arg, false); 1227 CHECK(IsUint<16>(jval_.i)); 1228 break; 1229 case kInt: 1230 jval_.i = ReadSignedInt(ptr_, value_arg); 1231 break; 1232 case kLong: 1233 jval_.j = ReadSignedLong(ptr_, value_arg); 1234 break; 1235 case kFloat: 1236 jval_.i = ReadUnsignedInt(ptr_, value_arg, true); 1237 break; 1238 case kDouble: 1239 jval_.j = ReadUnsignedLong(ptr_, value_arg, true); 1240 break; 1241 case kString: 1242 case kType: 1243 jval_.i = ReadUnsignedInt(ptr_, value_arg, false); 1244 break; 1245 case kField: 1246 case kMethod: 1247 case kEnum: 1248 case kArray: 1249 case kAnnotation: 1250 UNIMPLEMENTED(FATAL) << ": type " << type_; 1251 UNREACHABLE(); 1252 case kNull: 1253 jval_.l = nullptr; 1254 width = 0; 1255 break; 1256 default: 1257 LOG(FATAL) << "Unreached"; 1258 UNREACHABLE(); 1259 } 1260 ptr_ += width; 1261} 1262 1263template<bool kTransactionActive> 1264void EncodedStaticFieldValueIterator::ReadValueToField(ArtField* field) const { 1265 switch (type_) { 1266 case kBoolean: field->SetBoolean<kTransactionActive>(field->GetDeclaringClass(), jval_.z); 1267 break; 1268 case kByte: field->SetByte<kTransactionActive>(field->GetDeclaringClass(), jval_.b); break; 1269 case kShort: field->SetShort<kTransactionActive>(field->GetDeclaringClass(), jval_.s); break; 1270 case kChar: field->SetChar<kTransactionActive>(field->GetDeclaringClass(), jval_.c); break; 1271 case kInt: field->SetInt<kTransactionActive>(field->GetDeclaringClass(), jval_.i); break; 1272 case kLong: field->SetLong<kTransactionActive>(field->GetDeclaringClass(), jval_.j); break; 1273 case kFloat: field->SetFloat<kTransactionActive>(field->GetDeclaringClass(), jval_.f); break; 1274 case kDouble: field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break; 1275 case kNull: field->SetObject<kTransactionActive>(field->GetDeclaringClass(), nullptr); break; 1276 case kString: { 1277 mirror::String* resolved = linker_->ResolveString(dex_file_, jval_.i, *dex_cache_); 1278 field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved); 1279 break; 1280 } 1281 case kType: { 1282 mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, *dex_cache_, 1283 *class_loader_); 1284 field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved); 1285 break; 1286 } 1287 default: UNIMPLEMENTED(FATAL) << ": type " << type_; 1288 } 1289} 1290template void EncodedStaticFieldValueIterator::ReadValueToField<true>(ArtField* field) const; 1291template void EncodedStaticFieldValueIterator::ReadValueToField<false>(ArtField* field) const; 1292 1293CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address) { 1294 handler_.address_ = -1; 1295 int32_t offset = -1; 1296 1297 // Short-circuit the overwhelmingly common cases. 1298 switch (code_item.tries_size_) { 1299 case 0: 1300 break; 1301 case 1: { 1302 const DexFile::TryItem* tries = DexFile::GetTryItems(code_item, 0); 1303 uint32_t start = tries->start_addr_; 1304 if (address >= start) { 1305 uint32_t end = start + tries->insn_count_; 1306 if (address < end) { 1307 offset = tries->handler_off_; 1308 } 1309 } 1310 break; 1311 } 1312 default: 1313 offset = DexFile::FindCatchHandlerOffset(code_item, address); 1314 } 1315 Init(code_item, offset); 1316} 1317 1318CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, 1319 const DexFile::TryItem& try_item) { 1320 handler_.address_ = -1; 1321 Init(code_item, try_item.handler_off_); 1322} 1323 1324void CatchHandlerIterator::Init(const DexFile::CodeItem& code_item, 1325 int32_t offset) { 1326 if (offset >= 0) { 1327 Init(DexFile::GetCatchHandlerData(code_item, offset)); 1328 } else { 1329 // Not found, initialize as empty 1330 current_data_ = nullptr; 1331 remaining_count_ = -1; 1332 catch_all_ = false; 1333 DCHECK(!HasNext()); 1334 } 1335} 1336 1337void CatchHandlerIterator::Init(const uint8_t* handler_data) { 1338 current_data_ = handler_data; 1339 remaining_count_ = DecodeSignedLeb128(¤t_data_); 1340 1341 // If remaining_count_ is non-positive, then it is the negative of 1342 // the number of catch types, and the catches are followed by a 1343 // catch-all handler. 1344 if (remaining_count_ <= 0) { 1345 catch_all_ = true; 1346 remaining_count_ = -remaining_count_; 1347 } else { 1348 catch_all_ = false; 1349 } 1350 Next(); 1351} 1352 1353void CatchHandlerIterator::Next() { 1354 if (remaining_count_ > 0) { 1355 handler_.type_idx_ = DecodeUnsignedLeb128(¤t_data_); 1356 handler_.address_ = DecodeUnsignedLeb128(¤t_data_); 1357 remaining_count_--; 1358 return; 1359 } 1360 1361 if (catch_all_) { 1362 handler_.type_idx_ = DexFile::kDexNoIndex16; 1363 handler_.address_ = DecodeUnsignedLeb128(¤t_data_); 1364 catch_all_ = false; 1365 return; 1366 } 1367 1368 // no more handler 1369 remaining_count_ = -1; 1370} 1371 1372} // namespace art 1373