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
18 #include "compact_dex_file.h"
19 #include "dex_file_loader.h"
20 #include "gtest/gtest.h"
21
22 namespace art {
23
TEST(CompactDexFileTest,MagicAndVersion)24 TEST(CompactDexFileTest, MagicAndVersion) {
25 // Test permutations of valid/invalid headers.
26 for (size_t i = 0; i < 2; ++i) {
27 for (size_t j = 0; j < 2; ++j) {
28 static const size_t len = CompactDexFile::kDexVersionLen + CompactDexFile::kDexMagicSize;
29 uint8_t header[len] = {};
30 std::fill_n(header, len, 0x99);
31 const bool valid_magic = (i & 1) == 0;
32 const bool valid_version = (j & 1) == 0;
33 if (valid_magic) {
34 CompactDexFile::WriteMagic(header);
35 }
36 if (valid_version) {
37 CompactDexFile::WriteCurrentVersion(header);
38 }
39 EXPECT_EQ(valid_magic, CompactDexFile::IsMagicValid(header));
40 EXPECT_EQ(valid_version, CompactDexFile::IsVersionValid(header));
41 EXPECT_EQ(valid_magic, DexFileLoader::IsMagicValid(header));
42 EXPECT_EQ(valid_magic && valid_version, DexFileLoader::IsVersionAndMagicValid(header));
43 }
44 }
45 }
46
TEST(CompactDexFileTest,CodeItemFields)47 TEST(CompactDexFileTest, CodeItemFields) {
48 auto test_and_write = [&] (uint16_t registers_size,
49 uint16_t ins_size,
50 uint16_t outs_size,
51 uint16_t tries_size,
52 uint32_t insns_size_in_code_units) {
53 ASSERT_GE(registers_size, ins_size);
54 uint16_t buffer[sizeof(CompactDexFile::CodeItem) +
55 CompactDexFile::CodeItem::kMaxPreHeaderSize] = {};
56 CompactDexFile::CodeItem* code_item = reinterpret_cast<CompactDexFile::CodeItem*>(
57 &buffer[CompactDexFile::CodeItem::kMaxPreHeaderSize]);
58 const uint16_t* preheader_ptr = code_item->Create(registers_size,
59 ins_size,
60 outs_size,
61 tries_size,
62 insns_size_in_code_units,
63 code_item->GetPreHeader());
64 ASSERT_GT(preheader_ptr, buffer);
65
66 uint16_t out_registers_size;
67 uint16_t out_ins_size;
68 uint16_t out_outs_size;
69 uint16_t out_tries_size;
70 uint32_t out_insns_size_in_code_units;
71 code_item->DecodeFields</*kDecodeOnlyInstructionCount=*/false>(&out_insns_size_in_code_units,
72 &out_registers_size,
73 &out_ins_size,
74 &out_outs_size,
75 &out_tries_size);
76 ASSERT_EQ(registers_size, out_registers_size);
77 ASSERT_EQ(ins_size, out_ins_size);
78 ASSERT_EQ(outs_size, out_outs_size);
79 ASSERT_EQ(tries_size, out_tries_size);
80 ASSERT_EQ(insns_size_in_code_units, out_insns_size_in_code_units);
81
82 ++out_insns_size_in_code_units; // Force value to change.
83 code_item->DecodeFields</*kDecodeOnlyInstructionCount=*/true>(&out_insns_size_in_code_units,
84 /*registers_size=*/ nullptr,
85 /*ins_size=*/ nullptr,
86 /*outs_size=*/ nullptr,
87 /*tries_size=*/ nullptr);
88 ASSERT_EQ(insns_size_in_code_units, out_insns_size_in_code_units);
89 };
90 static constexpr uint32_t kMax32 = std::numeric_limits<uint32_t>::max();
91 static constexpr uint16_t kMax16 = std::numeric_limits<uint16_t>::max();
92 test_and_write(0, 0, 0, 0, 0);
93 test_and_write(kMax16, kMax16, kMax16, kMax16, kMax32);
94 test_and_write(kMax16 - 1, kMax16 - 2, kMax16 - 3, kMax16 - 4, kMax32 - 5);
95 test_and_write(kMax16 - 4, kMax16 - 5, kMax16 - 3, kMax16 - 2, kMax32 - 1);
96 test_and_write(5, 4, 3, 2, 1);
97 test_and_write(5, 0, 3, 2, 1);
98 test_and_write(kMax16, 0, kMax16 / 2, 1234, kMax32 / 4);
99 }
100
101 } // namespace art
102