| 308 | } |
| 309 | |
| 310 | std::unique_ptr<DexFile> DexFileLoader::OpenCommon(const uint8_t* base, |
| 311 | size_t size, |
| 312 | const uint8_t* data_base, |
| 313 | size_t data_size, |
| 314 | const std::string& location, |
| 315 | uint32_t location_checksum, |
| 316 | const OatDexFile* oat_dex_file, |
| 317 | bool verify, |
| 318 | bool verify_checksum, |
| 319 | std::string* error_msg, |
| 320 | std::unique_ptr<DexFileContainer> container, |
| 321 | VerifyResult* verify_result) { |
| 322 | if (verify_result != nullptr) { |
| 323 | *verify_result = VerifyResult::kVerifyNotAttempted; |
| 324 | } |
| 325 | std::unique_ptr<DexFile> dex_file; |
| 326 | if (size >= sizeof(StandardDexFile::Header) && StandardDexFile::IsMagicValid(base)) { |
| 327 | if (data_size != 0) { |
| 328 | CHECK_EQ(base, data_base) << "Unsupported for standard dex"; |
| 329 | } |
| 330 | dex_file.reset(new StandardDexFile(base, |
| 331 | size, |
| 332 | location, |
| 333 | location_checksum, |
| 334 | oat_dex_file, |
| 335 | std::move(container))); |
| 336 | } else if (size >= sizeof(CompactDexFile::Header) && CompactDexFile::IsMagicValid(base)) { |
| 337 | if (data_base == nullptr) { |
| 338 | // TODO: Is there a clean way to support both an explicit data section and reading the one |
| 339 | // from the header. |
| 340 | CHECK_EQ(data_size, 0u); |
| 341 | const CompactDexFile::Header* const header = CompactDexFile::Header::At(base); |
| 342 | data_base = base + header->data_off_; |
| 343 | data_size = header->data_size_; |
| 344 | } |
| 345 | dex_file.reset(new CompactDexFile(base, |
| 346 | size, |
| 347 | data_base, |
| 348 | data_size, |
| 349 | location, |
| 350 | location_checksum, |
| 351 | oat_dex_file, |
| 352 | std::move(container))); |
| 353 | // Disable verification for CompactDex input. |
| 354 | verify = false; |
| 355 | } else { |
| 356 | *error_msg = "Invalid or truncated dex file"; |
| 357 | } |
| 358 | if (dex_file == nullptr) { |
| 359 | *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(), |
| 360 | error_msg->c_str()); |
| 361 | return nullptr; |
| 362 | } |
| 363 | if (!dex_file->Init(error_msg)) { |
| 364 | dex_file.reset(); |
| 365 | return nullptr; |
| 366 | } |
| 367 | if (verify && !DexFileVerifier::Verify(dex_file.get(), |