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