Home | History | Annotate | Download | only in src
      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 "run_length_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, 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 
     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 
     27 }  // namespace
     28 
     29 namespace relocation_packer {
     30 
     31 TEST(RunLength, Encode) {
     32   std::vector<ELF::Rel> relocations;
     33   std::vector<ELF::Xword> packed;
     34 
     35   RelocationRunLengthCodec codec;
     36 
     37   packed.clear();
     38   codec.Encode(relocations, &packed);
     39 
     40   EXPECT_EQ(0, packed.size());
     41 
     42   // Add one relocation (insufficient data to encode).
     43   AddRelocation(0xf00d0000, &relocations);
     44 
     45   packed.clear();
     46   codec.Encode(relocations, &packed);
     47 
     48   EXPECT_EQ(0, packed.size());
     49 
     50   // Add a second relocation, 4 byte delta (minimum data to encode).
     51   AddRelocation(0xf00d0004, &relocations);
     52 
     53   packed.clear();
     54   codec.Encode(relocations, &packed);
     55 
     56   EXPECT_EQ(4, packed.size());
     57   // One count-delta pair present.
     58   EXPECT_EQ(1, packed[0]);
     59   // Initial relocation.
     60   EXPECT_EQ(0xf00d0000, packed[1]);
     61   // Run of a single relocation, 4 byte delta.
     62   EXPECT_EQ(1, packed[2]);
     63   EXPECT_EQ(4, packed[3]);
     64 
     65   // Add a third relocation, 4 byte delta.
     66   AddRelocation(0xf00d0008, &relocations);
     67 
     68   // Add three more relocations, 8 byte deltas.
     69   AddRelocation(0xf00d0010, &relocations);
     70   AddRelocation(0xf00d0018, &relocations);
     71   AddRelocation(0xf00d0020, &relocations);
     72 
     73   packed.clear();
     74   codec.Encode(relocations, &packed);
     75 
     76   EXPECT_EQ(6, packed.size());
     77   // Two count-delta pairs present.
     78   EXPECT_EQ(2, packed[0]);
     79   // Initial relocation.
     80   EXPECT_EQ(0xf00d0000, packed[1]);
     81   // Run of two relocations, 4 byte deltas.
     82   EXPECT_EQ(2, packed[2]);
     83   EXPECT_EQ(4, packed[3]);
     84   // Run of three relocations, 8 byte deltas.
     85   EXPECT_EQ(3, packed[4]);
     86   EXPECT_EQ(8, packed[5]);
     87 }
     88 
     89 TEST(RunLength, Decode) {
     90   std::vector<ELF::Xword> packed;
     91   std::vector<ELF::Rel> relocations;
     92 
     93   RelocationRunLengthCodec codec;
     94   codec.Decode(packed, &relocations);
     95 
     96   EXPECT_EQ(0, relocations.size());
     97 
     98   // Two count-delta pairs.
     99   packed.push_back(2);
    100   // Initial relocation.
    101   packed.push_back(0xc0de0000);
    102   // Run of two relocations, 4 byte deltas.
    103   packed.push_back(2);
    104   packed.push_back(4);
    105   // Run of three relocations, 8 byte deltas.
    106   packed.push_back(3);
    107   packed.push_back(8);
    108 
    109   relocations.clear();
    110   codec.Decode(packed, &relocations);
    111 
    112   EXPECT_EQ(6, relocations.size());
    113   // Initial relocation.
    114   EXPECT_TRUE(CheckRelocation(0xc0de0000, relocations[0]));
    115   // Two relocations, 4 byte deltas.
    116   EXPECT_TRUE(CheckRelocation(0xc0de0004, relocations[1]));
    117   EXPECT_TRUE(CheckRelocation(0xc0de0008, relocations[2]));
    118   // Three relocations, 8 byte deltas.
    119   EXPECT_TRUE(CheckRelocation(0xc0de0010, relocations[3]));
    120   EXPECT_TRUE(CheckRelocation(0xc0de0018, relocations[4]));
    121   EXPECT_TRUE(CheckRelocation(0xc0de0020, relocations[5]));
    122 }
    123 
    124 }  // namespace relocation_packer
    125