• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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