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