1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file. 4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "run_length_encoder.h" 6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <vector> 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "elf.h" 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "elf_traits.h" 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace { 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AddRelocation(ELF::Addr addr, std::vector<ELF::Rel>* relocations) { 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ELF::Rel relocation; 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) relocation.r_offset = addr; 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) relocation.r_info = ELF_R_INFO(0, ELF::kRelativeRelocationCode); 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relocations->push_back(relocation); 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool CheckRelocation(ELF::Addr addr, const ELF::Rel& relocation) { 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return relocation.r_offset == addr && 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ELF_R_SYM(relocation.r_info) == 0 && 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ELF_R_TYPE(relocation.r_info) == ELF::kRelativeRelocationCode; 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace relocation_packer { 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST(RunLength, Encode) { 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<ELF::Rel> relocations; 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<ELF::Xword> packed; 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) RelocationRunLengthCodec codec; 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packed.clear(); 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) codec.Encode(relocations, &packed); 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0, packed.size()); 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Add one relocation (insufficient data to encode). 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AddRelocation(0xf00d0000, &relocations); 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packed.clear(); 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) codec.Encode(relocations, &packed); 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0, packed.size()); 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Add a second relocation, 4 byte delta (minimum data to encode). 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AddRelocation(0xf00d0004, &relocations); 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packed.clear(); 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) codec.Encode(relocations, &packed); 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(4, packed.size()); 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // One count-delta pair present. 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(1, packed[0]); 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Initial relocation. 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(0xf00d0000, packed[1]); 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Run of a single relocation, 4 byte delta. 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(1, packed[2]); 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(4, packed[3]); 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Add a third relocation, 4 byte delta. 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AddRelocation(0xf00d0008, &relocations); 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Add three more relocations, 8 byte deltas. 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AddRelocation(0xf00d0010, &relocations); 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AddRelocation(0xf00d0018, &relocations); 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AddRelocation(0xf00d0020, &relocations); 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packed.clear(); 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) codec.Encode(relocations, &packed); 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(6, packed.size()); 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Two count-delta pairs present. 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(2, packed[0]); 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Initial relocation. 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(0xf00d0000, packed[1]); 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Run of two relocations, 4 byte deltas. 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(2, packed[2]); 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(4, packed[3]); 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Run of three relocations, 8 byte deltas. 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(3, packed[4]); 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(8, packed[5]); 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST(RunLength, Decode) { 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<ELF::Xword> packed; 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<ELF::Rel> relocations; 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) RelocationRunLengthCodec codec; 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) codec.Decode(packed, &relocations); 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0, relocations.size()); 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Two count-delta pairs. 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) packed.push_back(2); 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Initial relocation. 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) packed.push_back(0xc0de0000); 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Run of two relocations, 4 byte deltas. 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) packed.push_back(2); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) packed.push_back(4); 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Run of three relocations, 8 byte deltas. 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) packed.push_back(3); 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) packed.push_back(8); 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) relocations.clear(); 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) codec.Decode(packed, &relocations); 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(6, relocations.size()); 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Initial relocation. 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(CheckRelocation(0xc0de0000, relocations[0])); 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Two relocations, 4 byte deltas. 116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(CheckRelocation(0xc0de0004, relocations[1])); 117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(CheckRelocation(0xc0de0008, relocations[2])); 118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Three relocations, 8 byte deltas. 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(CheckRelocation(0xc0de0010, relocations[3])); 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(CheckRelocation(0xc0de0018, relocations[4])); 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(CheckRelocation(0xc0de0020, relocations[5])); 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace relocation_packer 125