| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "compact_dex_file.h" |
| |
| #include "base/leb128.h" |
| #include "code_item_accessors-inl.h" |
| #include "dex_file-inl.h" |
| |
| namespace art { |
| |
| constexpr uint8_t CompactDexFile::kDexMagic[kDexMagicSize]; |
| constexpr uint8_t CompactDexFile::kDexMagicVersion[]; |
| |
| void CompactDexFile::WriteMagic(uint8_t* magic) { |
| std::copy_n(kDexMagic, kDexMagicSize, magic); |
| } |
| |
| void CompactDexFile::WriteCurrentVersion(uint8_t* magic) { |
| std::copy_n(kDexMagicVersion, kDexVersionLen, magic + kDexMagicSize); |
| } |
| |
| bool CompactDexFile::IsMagicValid(const uint8_t* magic) { |
| return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0); |
| } |
| |
| bool CompactDexFile::IsVersionValid(const uint8_t* magic) { |
| const uint8_t* version = &magic[sizeof(kDexMagic)]; |
| return memcmp(version, kDexMagicVersion, kDexVersionLen) == 0; |
| } |
| |
| bool CompactDexFile::IsMagicValid() const { |
| return IsMagicValid(header_->magic_); |
| } |
| |
| bool CompactDexFile::IsVersionValid() const { |
| return IsVersionValid(header_->magic_); |
| } |
| |
| bool CompactDexFile::SupportsDefaultMethods() const { |
| return (GetHeader().GetFeatureFlags() & |
| static_cast<uint32_t>(FeatureFlags::kDefaultMethods)) != 0; |
| } |
| |
| uint32_t CompactDexFile::GetCodeItemSize(const DexFile::CodeItem& item) const { |
| DCHECK(IsInDataSection(&item)); |
| return reinterpret_cast<uintptr_t>(CodeItemDataAccessor(*this, &item).CodeItemDataEnd()) - |
| reinterpret_cast<uintptr_t>(&item); |
| } |
| |
| |
| uint32_t CompactDexFile::CalculateChecksum(const uint8_t* base_begin, |
| size_t base_size, |
| const uint8_t* data_begin, |
| size_t data_size) { |
| Header temp_header(*Header::At(base_begin)); |
| // Zero out fields that are not included in the sum. |
| temp_header.checksum_ = 0u; |
| temp_header.data_off_ = 0u; |
| temp_header.data_size_ = 0u; |
| uint32_t checksum = ChecksumMemoryRange(reinterpret_cast<const uint8_t*>(&temp_header), |
| sizeof(temp_header)); |
| // Exclude the header since we already computed it's checksum. |
| checksum = (checksum * 31) ^ ChecksumMemoryRange(base_begin + sizeof(temp_header), |
| base_size - sizeof(temp_header)); |
| checksum = (checksum * 31) ^ ChecksumMemoryRange(data_begin, data_size); |
| return checksum; |
| } |
| |
| uint32_t CompactDexFile::CalculateChecksum() const { |
| return CalculateChecksum(Begin(), Size(), DataBegin(), DataSize()); |
| } |
| |
| CompactDexFile::CompactDexFile(const uint8_t* base, |
| size_t size, |
| const uint8_t* data_begin, |
| size_t data_size, |
| const std::string& location, |
| uint32_t location_checksum, |
| const OatDexFile* oat_dex_file, |
| std::unique_ptr<DexFileContainer> container) |
| : DexFile(base, |
| size, |
| data_begin, |
| data_size, |
| location, |
| location_checksum, |
| oat_dex_file, |
| std::move(container), |
| /*is_compact_dex=*/ true), |
| debug_info_offsets_(DataBegin() + GetHeader().debug_info_offsets_pos_, |
| GetHeader().debug_info_base_, |
| GetHeader().debug_info_offsets_table_offset_) {} |
| |
| } // namespace art |