1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "packer.h"
6
7 #include <vector>
8 #include "elf.h"
9 #include "elf_traits.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace {
13
AddRelocation(ELF::Addr addr,std::vector<ELF::Rel> * relocations)14 void AddRelocation(ELF::Addr addr, std::vector<ELF::Rel>* relocations) {
15 ELF::Rel relocation;
16 relocation.r_offset = addr;
17 relocation.r_info = ELF_R_INFO(0, ELF::kRelativeRelocationCode);
18 relocations->push_back(relocation);
19 }
20
CheckRelocation(ELF::Addr addr,const ELF::Rel & relocation)21 bool CheckRelocation(ELF::Addr addr, const ELF::Rel& relocation) {
22 return relocation.r_offset == addr &&
23 ELF_R_SYM(relocation.r_info) == 0 &&
24 ELF_R_TYPE(relocation.r_info) == ELF::kRelativeRelocationCode;
25 }
26
AddRelocation(ELF::Addr addr,ELF::Sxword addend,std::vector<ELF::Rela> * relocations)27 void AddRelocation(ELF::Addr addr,
28 ELF::Sxword addend,
29 std::vector<ELF::Rela>* relocations) {
30 ELF::Rela relocation;
31 relocation.r_offset = addr;
32 relocation.r_info = ELF_R_INFO(0, ELF::kRelativeRelocationCode);
33 relocation.r_addend = addend;
34 relocations->push_back(relocation);
35 }
36
CheckRelocation(ELF::Addr addr,ELF::Sxword addend,const ELF::Rela & relocation)37 bool CheckRelocation(ELF::Addr addr,
38 ELF::Sxword addend,
39 const ELF::Rela& relocation) {
40 return relocation.r_offset == addr &&
41 ELF_R_SYM(relocation.r_info) == 0 &&
42 ELF_R_TYPE(relocation.r_info) == ELF::kRelativeRelocationCode &&
43 relocation.r_addend == addend;
44 }
45
46 } // namespace
47
48 namespace relocation_packer {
49
TEST(Packer,PackRel)50 TEST(Packer, PackRel) {
51 std::vector<ELF::Rel> relocations;
52 std::vector<uint8_t> packed;
53
54 RelocationPacker packer;
55
56 // Initial relocation.
57 AddRelocation(0xd1ce0000, &relocations);
58 // Two more relocations, 4 byte deltas.
59 AddRelocation(0xd1ce0004, &relocations);
60 AddRelocation(0xd1ce0008, &relocations);
61 // Three more relocations, 8 byte deltas.
62 AddRelocation(0xd1ce0010, &relocations);
63 AddRelocation(0xd1ce0018, &relocations);
64 AddRelocation(0xd1ce0020, &relocations);
65
66 packed.clear();
67 packer.PackRelativeRelocations(relocations, &packed);
68
69 EXPECT_EQ(16, packed.size());
70 // Identifier.
71 EXPECT_EQ('A', packed[0]);
72 EXPECT_EQ('P', packed[1]);
73 EXPECT_EQ('R', packed[2]);
74 EXPECT_EQ('1', packed[3]);
75 // Count-delta pairs count.
76 EXPECT_EQ(2, packed[4]);
77 // 0xd1ce0000
78 EXPECT_EQ(128, packed[5]);
79 EXPECT_EQ(128, packed[6]);
80 EXPECT_EQ(184, packed[7]);
81 EXPECT_EQ(142, packed[8]);
82 EXPECT_EQ(13, packed[9]);
83 // Run of two relocations, 4 byte deltas.
84 EXPECT_EQ(2, packed[10]);
85 EXPECT_EQ(4, packed[11]);
86 // Run of three relocations, 8 byte deltas.
87 EXPECT_EQ(3, packed[12]);
88 EXPECT_EQ(8, packed[13]);
89 // Padding.
90 EXPECT_EQ(0, packed[14]);
91 EXPECT_EQ(0, packed[15]);
92 }
93
TEST(Packer,UnpackRel)94 TEST(Packer, UnpackRel) {
95 std::vector<uint8_t> packed;
96 std::vector<ELF::Rel> relocations;
97
98 RelocationPacker packer;
99
100 // Identifier.
101 packed.push_back('A');
102 packed.push_back('P');
103 packed.push_back('R');
104 packed.push_back('1');
105 // Count-delta pairs count.
106 packed.push_back(2);
107 // 0xd1ce0000
108 packed.push_back(128);
109 packed.push_back(128);
110 packed.push_back(184);
111 packed.push_back(142);
112 packed.push_back(13);
113 // Run of two relocations, 4 byte deltas.
114 packed.push_back(2);
115 packed.push_back(4);
116 // Run of three relocations, 8 byte deltas.
117 packed.push_back(3);
118 packed.push_back(8);
119 // Padding.
120 packed.push_back(0);
121 packed.push_back(0);
122
123 relocations.clear();
124 packer.UnpackRelativeRelocations(packed, &relocations);
125
126 EXPECT_EQ(6, relocations.size());
127 // Initial relocation.
128 EXPECT_TRUE(CheckRelocation(0xd1ce0000, relocations[0]));
129 // Two relocations, 4 byte deltas.
130 EXPECT_TRUE(CheckRelocation(0xd1ce0004, relocations[1]));
131 EXPECT_TRUE(CheckRelocation(0xd1ce0008, relocations[2]));
132 // Three relocations, 8 byte deltas.
133 EXPECT_TRUE(CheckRelocation(0xd1ce0010, relocations[3]));
134 EXPECT_TRUE(CheckRelocation(0xd1ce0018, relocations[4]));
135 EXPECT_TRUE(CheckRelocation(0xd1ce0020, relocations[5]));
136 }
137
TEST(Packer,PackRela)138 TEST(Packer, PackRela) {
139 std::vector<ELF::Rela> relocations;
140 std::vector<uint8_t> packed;
141
142 RelocationPacker packer;
143
144 // Initial relocation.
145 AddRelocation(0xd1ce0000, 10000, &relocations);
146 // Two more relocations, 4 byte offset deltas, 12 byte addend deltas.
147 AddRelocation(0xd1ce0004, 10012, &relocations);
148 AddRelocation(0xd1ce0008, 10024, &relocations);
149 // Three more relocations, 8 byte deltas, -24 byte addend deltas.
150 AddRelocation(0xd1ce0010, 10000, &relocations);
151 AddRelocation(0xd1ce0018, 9976, &relocations);
152 AddRelocation(0xd1ce0020, 9952, &relocations);
153
154 packed.clear();
155 packer.PackRelativeRelocations(relocations, &packed);
156
157 EXPECT_EQ(24, packed.size());
158 // Identifier.
159 EXPECT_EQ('A', packed[0]);
160 EXPECT_EQ('P', packed[1]);
161 EXPECT_EQ('A', packed[2]);
162 EXPECT_EQ('1', packed[3]);
163 // Delta pairs count.
164 EXPECT_EQ(6, packed[4]);
165 // 0xd1ce0000
166 EXPECT_EQ(128, packed[5]);
167 EXPECT_EQ(128, packed[6]);
168 EXPECT_EQ(184, packed[7]);
169 EXPECT_EQ(142, packed[8]);
170 EXPECT_EQ(13, packed[9]);
171 // 10000
172 EXPECT_EQ(144, packed[10]);
173 EXPECT_EQ(206, packed[11]);
174 EXPECT_EQ(0, packed[12]);
175 // 4, 12
176 EXPECT_EQ(4, packed[13]);
177 EXPECT_EQ(12, packed[14]);
178 // 4, 12
179 EXPECT_EQ(4, packed[15]);
180 EXPECT_EQ(12, packed[16]);
181 // 8, -24
182 EXPECT_EQ(8, packed[17]);
183 EXPECT_EQ(104, packed[18]);
184 // 8, -24
185 EXPECT_EQ(8, packed[19]);
186 EXPECT_EQ(104, packed[20]);
187 // 8, -24
188 EXPECT_EQ(8, packed[21]);
189 EXPECT_EQ(104, packed[22]);
190 // Padding.
191 EXPECT_EQ(0, packed[23]);
192 }
193
TEST(Packer,UnpackRela)194 TEST(Packer, UnpackRela) {
195 std::vector<uint8_t> packed;
196 std::vector<ELF::Rela> relocations;
197
198 RelocationPacker packer;
199
200 // Identifier.
201 packed.push_back('A');
202 packed.push_back('P');
203 packed.push_back('A');
204 packed.push_back('1');
205 // Delta pairs count.
206 packed.push_back(6);
207 // 0xd1ce0000
208 packed.push_back(128);
209 packed.push_back(128);
210 packed.push_back(184);
211 packed.push_back(142);
212 packed.push_back(13);
213 // 10000
214 packed.push_back(144);
215 packed.push_back(206);
216 packed.push_back(0);
217 // 4, 12
218 packed.push_back(4);
219 packed.push_back(12);
220 // 4, 12
221 packed.push_back(4);
222 packed.push_back(12);
223 // 8, -24
224 packed.push_back(8);
225 packed.push_back(104);
226 // 8, -24
227 packed.push_back(8);
228 packed.push_back(104);
229 // 8, -24
230 packed.push_back(8);
231 packed.push_back(104);
232 // Padding.
233 packed.push_back(0);
234
235 relocations.clear();
236 packer.UnpackRelativeRelocations(packed, &relocations);
237
238 EXPECT_EQ(6, relocations.size());
239 // Initial relocation.
240 EXPECT_TRUE(CheckRelocation(0xd1ce0000, 10000, relocations[0]));
241 // Two more relocations, 4 byte offset deltas, 12 byte addend deltas.
242 EXPECT_TRUE(CheckRelocation(0xd1ce0004, 10012, relocations[1]));
243 EXPECT_TRUE(CheckRelocation(0xd1ce0008, 10024, relocations[2]));
244 // Three more relocations, 8 byte offset deltas, -24 byte addend deltas.
245 EXPECT_TRUE(CheckRelocation(0xd1ce0010, 10000, relocations[3]));
246 EXPECT_TRUE(CheckRelocation(0xd1ce0018, 9976, relocations[4]));
247 EXPECT_TRUE(CheckRelocation(0xd1ce0020, 9952, relocations[5]));
248 }
249
250 } // namespace relocation_packer
251