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.
5 #include "delta_encoder.h"
9 #include "elf_traits.h"
10 #include "testing/gtest/include/gtest/gtest.h"
14 void AddRelocation(ELF::Addr addr
,
16 std::vector
<ELF::Rela
>* relocations
) {
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
);
24 bool CheckRelocation(ELF::Addr addr
,
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
;
35 namespace relocation_packer
{
38 std::vector
<ELF::Rela
> relocations
;
39 std::vector
<ELF::Sxword
> packed
;
41 RelocationDeltaCodec codec
;
44 codec
.Encode(relocations
, &packed
);
46 EXPECT_EQ(0, packed
.size());
48 // Initial relocation.
49 AddRelocation(0xf00d0000, 10000, &relocations
);
52 codec
.Encode(relocations
, &packed
);
54 EXPECT_EQ(3, packed
.size());
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]);
61 // Add a second relocation, 4 byte offset delta, 12 byte addend delta.
62 AddRelocation(0xf00d0004, 10012, &relocations
);
65 codec
.Encode(relocations
, &packed
);
67 EXPECT_EQ(5, packed
.size());
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]);
77 // Add a third relocation, 4 byte offset delta, 12 byte addend delta.
78 AddRelocation(0xf00d0008, 10024, &relocations
);
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
);
86 codec
.Encode(relocations
, &packed
);
88 EXPECT_EQ(13, packed
.size());
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]);
108 TEST(Delta
, Decode
) {
109 std::vector
<ELF::Sxword
> packed
;
110 std::vector
<ELF::Rela
> relocations
;
112 RelocationDeltaCodec codec
;
113 codec
.Decode(packed
, &relocations
);
115 EXPECT_EQ(0, relocations
.size());
119 // Initial relocation.
120 packed
.push_back(0xc0de0000);
121 packed
.push_back(10000);
122 // Two relocations, 4 byte offset deltas, 12 byte addend deltas.
124 packed
.push_back(12);
126 packed
.push_back(12);
127 // Three relocations, 8 byte offset deltas, -24 byte addend deltas.
129 packed
.push_back(-24);
131 packed
.push_back(-24);
133 packed
.push_back(-24);
136 codec
.Decode(packed
, &relocations
);
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]));
150 } // namespace relocation_packer