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 "index_bss_mapping_encoder.h"
18
19 #include "base/enums.h"
20 #include "gtest/gtest.h"
21
22 namespace art {
23 namespace linker {
24
TEST(IndexBssMappingEncoder,TryMerge16BitIndex)25 TEST(IndexBssMappingEncoder, TryMerge16BitIndex) {
26 for (PointerSize pointer_size : {PointerSize::k32, PointerSize::k64}) {
27 size_t raw_pointer_size = static_cast<size_t>(pointer_size);
28 IndexBssMappingEncoder encoder(/* number_of_indexes */ 0x10000, raw_pointer_size);
29 encoder.Reset(1u, 0u);
30 ASSERT_FALSE(encoder.TryMerge(5u, raw_pointer_size + 1)); // Wrong bss_offset difference.
31 ASSERT_FALSE(encoder.TryMerge(18u, raw_pointer_size)); // Index out of range.
32 ASSERT_TRUE(encoder.TryMerge(5u, raw_pointer_size));
33 ASSERT_EQ(0u, encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 1u, raw_pointer_size));
34 ASSERT_EQ(raw_pointer_size,
35 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 5u, raw_pointer_size));
36 ASSERT_EQ(IndexBssMappingLookup::npos,
37 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 17u, raw_pointer_size));
38 ASSERT_FALSE(encoder.TryMerge(17u, 2 * raw_pointer_size + 1)); // Wrong bss_offset difference.
39 ASSERT_FALSE(encoder.TryMerge(18u, 2 * raw_pointer_size)); // Index out of range.
40 ASSERT_TRUE(encoder.TryMerge(17u, 2 * raw_pointer_size));
41 ASSERT_EQ(0u, encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 1u, raw_pointer_size));
42 ASSERT_EQ(raw_pointer_size,
43 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 5u, raw_pointer_size));
44 ASSERT_EQ(2 * raw_pointer_size,
45 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 17u, raw_pointer_size));
46 ASSERT_EQ(0x00110000u | 17u, encoder.GetEntry().index_and_mask);
47 ASSERT_FALSE(encoder.TryMerge(18u, 3 * raw_pointer_size)); // Index out of range.
48 }
49 }
50
TEST(IndexBssMappingEncoder,TryMerge8BitIndex)51 TEST(IndexBssMappingEncoder, TryMerge8BitIndex) {
52 for (PointerSize pointer_size : {PointerSize::k32, PointerSize::k64}) {
53 size_t raw_pointer_size = static_cast<size_t>(pointer_size);
54 IndexBssMappingEncoder encoder(/* number_of_indexes */ 0x100, raw_pointer_size);
55 encoder.Reset(1u, 0u);
56 ASSERT_FALSE(encoder.TryMerge(5u, raw_pointer_size + 1)); // Wrong bss_offset difference.
57 ASSERT_FALSE(encoder.TryMerge(26u, raw_pointer_size)); // Index out of range.
58 ASSERT_TRUE(encoder.TryMerge(5u, raw_pointer_size));
59 ASSERT_EQ(0u, encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 1u, raw_pointer_size));
60 ASSERT_EQ(raw_pointer_size,
61 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 5u, raw_pointer_size));
62 ASSERT_EQ(IndexBssMappingLookup::npos,
63 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 17u, raw_pointer_size));
64 ASSERT_FALSE(encoder.TryMerge(25u, 2 * raw_pointer_size + 1)); // Wrong bss_offset difference.
65 ASSERT_FALSE(encoder.TryMerge(26u, 2 * raw_pointer_size)); // Index out of range.
66 ASSERT_TRUE(encoder.TryMerge(25u, 2 * raw_pointer_size));
67 ASSERT_EQ(0u, encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 1u, raw_pointer_size));
68 ASSERT_EQ(raw_pointer_size,
69 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 5u, raw_pointer_size));
70 ASSERT_EQ(2 * raw_pointer_size,
71 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 25u, raw_pointer_size));
72 ASSERT_EQ(0x00001100u | 25u, encoder.GetEntry().index_and_mask);
73 ASSERT_FALSE(encoder.TryMerge(26u, 3 * raw_pointer_size)); // Index out of range.
74 }
75 }
76
TEST(IndexBssMappingEncoder,TryMerge20BitIndex)77 TEST(IndexBssMappingEncoder, TryMerge20BitIndex) {
78 for (PointerSize pointer_size : {PointerSize::k32, PointerSize::k64}) {
79 size_t raw_pointer_size = static_cast<size_t>(pointer_size);
80 IndexBssMappingEncoder encoder(/* number_of_indexes */ 0x100000, raw_pointer_size);
81 encoder.Reset(1u, 0u);
82 ASSERT_FALSE(encoder.TryMerge(5u, raw_pointer_size + 1)); // Wrong bss_offset difference.
83 ASSERT_FALSE(encoder.TryMerge(14u, raw_pointer_size)); // Index out of range.
84 ASSERT_TRUE(encoder.TryMerge(5u, raw_pointer_size));
85 ASSERT_EQ(0u, encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 1u, raw_pointer_size));
86 ASSERT_EQ(raw_pointer_size,
87 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 5u, raw_pointer_size));
88 ASSERT_EQ(IndexBssMappingLookup::npos,
89 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 17u, raw_pointer_size));
90 ASSERT_FALSE(encoder.TryMerge(13u, 2 * raw_pointer_size + 1)); // Wrong bss_offset difference.
91 ASSERT_FALSE(encoder.TryMerge(14u, 2 * raw_pointer_size)); // Index out of range.
92 ASSERT_TRUE(encoder.TryMerge(13u, 2 * raw_pointer_size));
93 ASSERT_EQ(0u, encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 1u, raw_pointer_size));
94 ASSERT_EQ(raw_pointer_size,
95 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 5u, raw_pointer_size));
96 ASSERT_EQ(2 * raw_pointer_size,
97 encoder.GetEntry().GetBssOffset(encoder.GetIndexBits(), 13u, raw_pointer_size));
98 ASSERT_EQ(0x01100000u | 13u, encoder.GetEntry().index_and_mask);
99 ASSERT_FALSE(encoder.TryMerge(14u, 3 * raw_pointer_size)); // Index out of range.
100 }
101 }
102
103 } // namespace linker
104 } // namespace art
105