109 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
/*
 | 
						|
 * 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 dex::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
 |