packer_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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
12namespace {
13
14void 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
21bool 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
27void 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
37bool 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
48namespace relocation_packer {
49
50TEST(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
94TEST(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
138TEST(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
194TEST(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