• 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 "delta_encoder.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,ELF::Sxword addend,std::vector<ELF::Rela> * relocations)14 void AddRelocation(ELF::Addr addr,
15                    ELF::Sxword addend,
16                    std::vector<ELF::Rela>* relocations) {
17   ELF::Rela relocation;
18   relocation.r_offset = addr;
19   relocation.r_info = ELF_R_INFO(0, ELF::kRelativeRelocationCode);
20   relocation.r_addend = addend;
21   relocations->push_back(relocation);
22 }
23 
CheckRelocation(ELF::Addr addr,ELF::Sxword addend,const ELF::Rela & relocation)24 bool CheckRelocation(ELF::Addr addr,
25                      ELF::Sxword addend,
26                      const ELF::Rela& relocation) {
27   return relocation.r_offset == addr &&
28       ELF_R_SYM(relocation.r_info) == 0 &&
29       ELF_R_TYPE(relocation.r_info) == ELF::kRelativeRelocationCode &&
30       relocation.r_addend == addend;
31 }
32 
33 }  // namespace
34 
35 namespace relocation_packer {
36 
TEST(Delta,Encode)37 TEST(Delta, Encode) {
38   std::vector<ELF::Rela> relocations;
39   std::vector<ELF::Sxword> packed;
40 
41   RelocationDeltaCodec codec;
42 
43   packed.clear();
44   codec.Encode(relocations, &packed);
45 
46   EXPECT_EQ(0, packed.size());
47 
48   // Initial relocation.
49   AddRelocation(0xf00d0000, 10000, &relocations);
50 
51   packed.clear();
52   codec.Encode(relocations, &packed);
53 
54   EXPECT_EQ(3, packed.size());
55   // One pair present.
56   EXPECT_EQ(1, packed[0]);
57   // Delta from the neutral element is the initial relocation.
58   EXPECT_EQ(0xf00d0000, packed[1]);
59   EXPECT_EQ(10000, packed[2]);
60 
61   // Add a second relocation, 4 byte offset delta, 12 byte addend delta.
62   AddRelocation(0xf00d0004, 10012, &relocations);
63 
64   packed.clear();
65   codec.Encode(relocations, &packed);
66 
67   EXPECT_EQ(5, packed.size());
68   // Two pairs present.
69   EXPECT_EQ(2, packed[0]);
70   // Delta from the neutral element is the initial relocation.
71   EXPECT_EQ(0xf00d0000, packed[1]);
72   EXPECT_EQ(10000, packed[2]);
73   // 4 byte offset delta, 12 byte addend delta.
74   EXPECT_EQ(4, packed[3]);
75   EXPECT_EQ(12, packed[4]);
76 
77   // Add a third relocation, 4 byte offset delta, 12 byte addend delta.
78   AddRelocation(0xf00d0008, 10024, &relocations);
79 
80   // Add three more relocations, 8 byte offset deltas, -24 byte addend deltas.
81   AddRelocation(0xf00d0010, 10000, &relocations);
82   AddRelocation(0xf00d0018, 9976, &relocations);
83   AddRelocation(0xf00d0020, 9952, &relocations);
84 
85   packed.clear();
86   codec.Encode(relocations, &packed);
87 
88   EXPECT_EQ(13, packed.size());
89   // Six pairs present.
90   EXPECT_EQ(6, packed[0]);
91   // Initial relocation.
92   EXPECT_EQ(0xf00d0000, packed[1]);
93   EXPECT_EQ(10000, packed[2]);
94   // Two relocations, 4 byte offset deltas, 12 byte addend deltas.
95   EXPECT_EQ(4, packed[3]);
96   EXPECT_EQ(12, packed[4]);
97   EXPECT_EQ(4, packed[5]);
98   EXPECT_EQ(12, packed[6]);
99   // Three relocations, 8 byte offset deltas, -24 byte addend deltas.
100   EXPECT_EQ(8, packed[7]);
101   EXPECT_EQ(-24, packed[8]);
102   EXPECT_EQ(8, packed[9]);
103   EXPECT_EQ(-24, packed[10]);
104   EXPECT_EQ(8, packed[11]);
105   EXPECT_EQ(-24, packed[12]);
106 }
107 
TEST(Delta,Decode)108 TEST(Delta, Decode) {
109   std::vector<ELF::Sxword> packed;
110   std::vector<ELF::Rela> relocations;
111 
112   RelocationDeltaCodec codec;
113   codec.Decode(packed, &relocations);
114 
115   EXPECT_EQ(0, relocations.size());
116 
117   // Six pairs.
118   packed.push_back(6);
119   // Initial relocation.
120   packed.push_back(0xc0de0000);
121   packed.push_back(10000);
122   // Two relocations, 4 byte offset deltas, 12 byte addend deltas.
123   packed.push_back(4);
124   packed.push_back(12);
125   packed.push_back(4);
126   packed.push_back(12);
127   // Three relocations, 8 byte offset deltas, -24 byte addend deltas.
128   packed.push_back(8);
129   packed.push_back(-24);
130   packed.push_back(8);
131   packed.push_back(-24);
132   packed.push_back(8);
133   packed.push_back(-24);
134 
135   relocations.clear();
136   codec.Decode(packed, &relocations);
137 
138   EXPECT_EQ(6, relocations.size());
139   // Initial relocation.
140   EXPECT_TRUE(CheckRelocation(0xc0de0000, 10000, relocations[0]));
141   // Two relocations, 4 byte offset deltas, 12 byte addend deltas.
142   EXPECT_TRUE(CheckRelocation(0xc0de0004, 10012, relocations[1]));
143   EXPECT_TRUE(CheckRelocation(0xc0de0008, 10024, relocations[2]));
144   // Three relocations, 8 byte offset deltas, -24 byte addend deltas.
145   EXPECT_TRUE(CheckRelocation(0xc0de0010, 10000, relocations[3]));
146   EXPECT_TRUE(CheckRelocation(0xc0de0018, 9976, relocations[4]));
147   EXPECT_TRUE(CheckRelocation(0xc0de0020, 9952, relocations[5]));
148 }
149 
150 }  // namespace relocation_packer
151