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 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 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 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 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