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