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