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