1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker
18*795d594fSAndroid Build Coastguard Worker #include "compact_dex_file.h"
19*795d594fSAndroid Build Coastguard Worker #include "dex_file_loader.h"
20*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
21*795d594fSAndroid Build Coastguard Worker
22*795d594fSAndroid Build Coastguard Worker namespace art {
23*795d594fSAndroid Build Coastguard Worker
TEST(CompactDexFileTest,MagicAndVersion)24*795d594fSAndroid Build Coastguard Worker TEST(CompactDexFileTest, MagicAndVersion) {
25*795d594fSAndroid Build Coastguard Worker // Test permutations of valid/invalid headers.
26*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i < 2; ++i) {
27*795d594fSAndroid Build Coastguard Worker for (size_t j = 0; j < 2; ++j) {
28*795d594fSAndroid Build Coastguard Worker static const size_t len = CompactDexFile::kDexVersionLen + CompactDexFile::kDexMagicSize;
29*795d594fSAndroid Build Coastguard Worker uint8_t header[len] = {};
30*795d594fSAndroid Build Coastguard Worker std::fill_n(header, len, 0x99);
31*795d594fSAndroid Build Coastguard Worker const bool valid_magic = (i & 1) == 0;
32*795d594fSAndroid Build Coastguard Worker const bool valid_version = (j & 1) == 0;
33*795d594fSAndroid Build Coastguard Worker if (valid_magic) {
34*795d594fSAndroid Build Coastguard Worker CompactDexFile::WriteMagic(header);
35*795d594fSAndroid Build Coastguard Worker }
36*795d594fSAndroid Build Coastguard Worker if (valid_version) {
37*795d594fSAndroid Build Coastguard Worker CompactDexFile::WriteCurrentVersion(header);
38*795d594fSAndroid Build Coastguard Worker }
39*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(valid_magic, CompactDexFile::IsMagicValid(header));
40*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(valid_version, CompactDexFile::IsVersionValid(header));
41*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(valid_magic, DexFileLoader::IsMagicValid(header));
42*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(valid_magic && valid_version, DexFileLoader::IsVersionAndMagicValid(header));
43*795d594fSAndroid Build Coastguard Worker }
44*795d594fSAndroid Build Coastguard Worker }
45*795d594fSAndroid Build Coastguard Worker }
46*795d594fSAndroid Build Coastguard Worker
TEST(CompactDexFileTest,CodeItemFields)47*795d594fSAndroid Build Coastguard Worker TEST(CompactDexFileTest, CodeItemFields) {
48*795d594fSAndroid Build Coastguard Worker auto test_and_write = [&] (uint16_t registers_size,
49*795d594fSAndroid Build Coastguard Worker uint16_t ins_size,
50*795d594fSAndroid Build Coastguard Worker uint16_t outs_size,
51*795d594fSAndroid Build Coastguard Worker uint16_t tries_size,
52*795d594fSAndroid Build Coastguard Worker uint32_t insns_size_in_code_units) {
53*795d594fSAndroid Build Coastguard Worker ASSERT_GE(registers_size, ins_size);
54*795d594fSAndroid Build Coastguard Worker uint16_t buffer[sizeof(CompactDexFile::CodeItem) +
55*795d594fSAndroid Build Coastguard Worker CompactDexFile::CodeItem::kMaxPreHeaderSize] = {};
56*795d594fSAndroid Build Coastguard Worker CompactDexFile::CodeItem* code_item = reinterpret_cast<CompactDexFile::CodeItem*>(
57*795d594fSAndroid Build Coastguard Worker &buffer[CompactDexFile::CodeItem::kMaxPreHeaderSize]);
58*795d594fSAndroid Build Coastguard Worker const uint16_t* preheader_ptr = code_item->Create(registers_size,
59*795d594fSAndroid Build Coastguard Worker ins_size,
60*795d594fSAndroid Build Coastguard Worker outs_size,
61*795d594fSAndroid Build Coastguard Worker tries_size,
62*795d594fSAndroid Build Coastguard Worker insns_size_in_code_units,
63*795d594fSAndroid Build Coastguard Worker code_item->GetPreHeader());
64*795d594fSAndroid Build Coastguard Worker ASSERT_GT(preheader_ptr, buffer);
65*795d594fSAndroid Build Coastguard Worker
66*795d594fSAndroid Build Coastguard Worker uint16_t out_registers_size;
67*795d594fSAndroid Build Coastguard Worker uint16_t out_ins_size;
68*795d594fSAndroid Build Coastguard Worker uint16_t out_outs_size;
69*795d594fSAndroid Build Coastguard Worker uint16_t out_tries_size;
70*795d594fSAndroid Build Coastguard Worker uint32_t out_insns_size_in_code_units;
71*795d594fSAndroid Build Coastguard Worker code_item->DecodeFields</*kDecodeOnlyInstructionCount=*/false>(&out_insns_size_in_code_units,
72*795d594fSAndroid Build Coastguard Worker &out_registers_size,
73*795d594fSAndroid Build Coastguard Worker &out_ins_size,
74*795d594fSAndroid Build Coastguard Worker &out_outs_size,
75*795d594fSAndroid Build Coastguard Worker &out_tries_size);
76*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(registers_size, out_registers_size);
77*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(ins_size, out_ins_size);
78*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(outs_size, out_outs_size);
79*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(tries_size, out_tries_size);
80*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(insns_size_in_code_units, out_insns_size_in_code_units);
81*795d594fSAndroid Build Coastguard Worker
82*795d594fSAndroid Build Coastguard Worker ++out_insns_size_in_code_units; // Force value to change.
83*795d594fSAndroid Build Coastguard Worker code_item->DecodeFields</*kDecodeOnlyInstructionCount=*/true>(&out_insns_size_in_code_units,
84*795d594fSAndroid Build Coastguard Worker /*registers_size=*/ nullptr,
85*795d594fSAndroid Build Coastguard Worker /*ins_size=*/ nullptr,
86*795d594fSAndroid Build Coastguard Worker /*outs_size=*/ nullptr,
87*795d594fSAndroid Build Coastguard Worker /*tries_size=*/ nullptr);
88*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(insns_size_in_code_units, out_insns_size_in_code_units);
89*795d594fSAndroid Build Coastguard Worker };
90*795d594fSAndroid Build Coastguard Worker static constexpr uint32_t kMax32 = std::numeric_limits<uint32_t>::max();
91*795d594fSAndroid Build Coastguard Worker static constexpr uint16_t kMax16 = std::numeric_limits<uint16_t>::max();
92*795d594fSAndroid Build Coastguard Worker test_and_write(0, 0, 0, 0, 0);
93*795d594fSAndroid Build Coastguard Worker test_and_write(kMax16, kMax16, kMax16, kMax16, kMax32);
94*795d594fSAndroid Build Coastguard Worker test_and_write(kMax16 - 1, kMax16 - 2, kMax16 - 3, kMax16 - 4, kMax32 - 5);
95*795d594fSAndroid Build Coastguard Worker test_and_write(kMax16 - 4, kMax16 - 5, kMax16 - 3, kMax16 - 2, kMax32 - 1);
96*795d594fSAndroid Build Coastguard Worker test_and_write(5, 4, 3, 2, 1);
97*795d594fSAndroid Build Coastguard Worker test_and_write(5, 0, 3, 2, 1);
98*795d594fSAndroid Build Coastguard Worker test_and_write(kMax16, 0, kMax16 / 2, 1234, kMax32 / 4);
99*795d594fSAndroid Build Coastguard Worker }
100*795d594fSAndroid Build Coastguard Worker
101*795d594fSAndroid Build Coastguard Worker } // namespace art
102