1 /*
2 * Copyright (C) 2017 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 "compact_dex_file.h"
18
19 #include "base/leb128.h"
20 #include "code_item_accessors-inl.h"
21 #include "dex_file-inl.h"
22
23 namespace art {
24
25 constexpr uint8_t CompactDexFile::kDexMagic[kDexMagicSize];
26 constexpr uint8_t CompactDexFile::kDexMagicVersion[];
27
WriteMagic(uint8_t * magic)28 void CompactDexFile::WriteMagic(uint8_t* magic) {
29 std::copy_n(kDexMagic, kDexMagicSize, magic);
30 }
31
WriteCurrentVersion(uint8_t * magic)32 void CompactDexFile::WriteCurrentVersion(uint8_t* magic) {
33 std::copy_n(kDexMagicVersion, kDexVersionLen, magic + kDexMagicSize);
34 }
35
IsMagicValid(const uint8_t * magic)36 bool CompactDexFile::IsMagicValid(const uint8_t* magic) {
37 return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0);
38 }
39
IsVersionValid(const uint8_t * magic)40 bool CompactDexFile::IsVersionValid(const uint8_t* magic) {
41 const uint8_t* version = &magic[sizeof(kDexMagic)];
42 return memcmp(version, kDexMagicVersion, kDexVersionLen) == 0;
43 }
44
IsMagicValid() const45 bool CompactDexFile::IsMagicValid() const {
46 return IsMagicValid(header_->magic_);
47 }
48
IsVersionValid() const49 bool CompactDexFile::IsVersionValid() const {
50 return IsVersionValid(header_->magic_);
51 }
52
SupportsDefaultMethods() const53 bool CompactDexFile::SupportsDefaultMethods() const {
54 return (GetHeader().GetFeatureFlags() &
55 static_cast<uint32_t>(FeatureFlags::kDefaultMethods)) != 0;
56 }
57
GetCodeItemSize(const dex::CodeItem & item) const58 uint32_t CompactDexFile::GetCodeItemSize(const dex::CodeItem& item) const {
59 DCHECK(IsInDataSection(&item));
60 return reinterpret_cast<uintptr_t>(CodeItemDataAccessor(*this, &item).CodeItemDataEnd()) -
61 reinterpret_cast<uintptr_t>(&item);
62 }
63
64
CalculateChecksum(const uint8_t * base_begin,size_t base_size,const uint8_t * data_begin,size_t data_size)65 uint32_t CompactDexFile::CalculateChecksum(const uint8_t* base_begin,
66 size_t base_size,
67 const uint8_t* data_begin,
68 size_t data_size) {
69 Header temp_header(*Header::At(base_begin));
70 // Zero out fields that are not included in the sum.
71 temp_header.checksum_ = 0u;
72 temp_header.data_off_ = 0u;
73 temp_header.data_size_ = 0u;
74 uint32_t checksum = ChecksumMemoryRange(reinterpret_cast<const uint8_t*>(&temp_header),
75 sizeof(temp_header));
76 // Exclude the header since we already computed it's checksum.
77 checksum = (checksum * 31) ^ ChecksumMemoryRange(base_begin + sizeof(temp_header),
78 base_size - sizeof(temp_header));
79 checksum = (checksum * 31) ^ ChecksumMemoryRange(data_begin, data_size);
80 return checksum;
81 }
82
CalculateChecksum() const83 uint32_t CompactDexFile::CalculateChecksum() const {
84 return CalculateChecksum(Begin(), Size(), DataBegin(), DataSize());
85 }
86
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)87 CompactDexFile::CompactDexFile(const uint8_t* base,
88 size_t size,
89 const uint8_t* data_begin,
90 size_t data_size,
91 const std::string& location,
92 uint32_t location_checksum,
93 const OatDexFile* oat_dex_file,
94 std::unique_ptr<DexFileContainer> container)
95 : DexFile(base,
96 size,
97 data_begin,
98 data_size,
99 location,
100 location_checksum,
101 oat_dex_file,
102 std::move(container),
103 /*is_compact_dex=*/ true),
104 debug_info_offsets_(DataBegin() + GetHeader().debug_info_offsets_pos_,
105 GetHeader().debug_info_base_,
106 GetHeader().debug_info_offsets_table_offset_) {}
107
108 } // namespace art
109