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 "packer.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 void AddRelocation(ELF::Addr addr,
     28                    ELF::Sxword addend,
     29                    std::vector<ELF::Rela>* relocations) {
     30   ELF::Rela relocation;
     31   relocation.r_offset = addr;
     32   relocation.r_info = ELF_R_INFO(0, ELF::kRelativeRelocationCode);
     33   relocation.r_addend = addend;
     34   relocations->push_back(relocation);
     35 }
     36 
     37 bool CheckRelocation(ELF::Addr addr,
     38                      ELF::Sxword addend,
     39                      const ELF::Rela& relocation) {
     40   return relocation.r_offset == addr &&
     41       ELF_R_SYM(relocation.r_info) == 0 &&
     42       ELF_R_TYPE(relocation.r_info) == ELF::kRelativeRelocationCode &&
     43       relocation.r_addend == addend;
     44 }
     45 
     46 }  // namespace
     47 
     48 namespace relocation_packer {
     49 
     50 TEST(Packer, PackRel) {
     51   std::vector<ELF::Rel> relocations;
     52   std::vector<uint8_t> packed;
     53 
     54   RelocationPacker packer;
     55 
     56   // Initial relocation.
     57   AddRelocation(0xd1ce0000, &relocations);
     58   // Two more relocations, 4 byte deltas.
     59   AddRelocation(0xd1ce0004, &relocations);
     60   AddRelocation(0xd1ce0008, &relocations);
     61   // Three more relocations, 8 byte deltas.
     62   AddRelocation(0xd1ce0010, &relocations);
     63   AddRelocation(0xd1ce0018, &relocations);
     64   AddRelocation(0xd1ce0020, &relocations);
     65 
     66   packed.clear();
     67   packer.PackRelativeRelocations(relocations, &packed);
     68 
     69   EXPECT_EQ(16, packed.size());
     70   // Identifier.
     71   EXPECT_EQ('A', packed[0]);
     72   EXPECT_EQ('P', packed[1]);
     73   EXPECT_EQ('R', packed[2]);
     74   EXPECT_EQ('1', packed[3]);
     75   // Count-delta pairs count.
     76   EXPECT_EQ(2, packed[4]);
     77   // 0xd1ce0000
     78   EXPECT_EQ(128, packed[5]);
     79   EXPECT_EQ(128, packed[6]);
     80   EXPECT_EQ(184, packed[7]);
     81   EXPECT_EQ(142, packed[8]);
     82   EXPECT_EQ(13, packed[9]);
     83   // Run of two relocations, 4 byte deltas.
     84   EXPECT_EQ(2, packed[10]);
     85   EXPECT_EQ(4, packed[11]);
     86   // Run of three relocations, 8 byte deltas.
     87   EXPECT_EQ(3, packed[12]);
     88   EXPECT_EQ(8, packed[13]);
     89   // Padding.
     90   EXPECT_EQ(0, packed[14]);
     91   EXPECT_EQ(0, packed[15]);
     92 }
     93 
     94 TEST(Packer, UnpackRel) {
     95   std::vector<uint8_t> packed;
     96   std::vector<ELF::Rel> relocations;
     97 
     98   RelocationPacker packer;
     99 
    100   // Identifier.
    101   packed.push_back('A');
    102   packed.push_back('P');
    103   packed.push_back('R');
    104   packed.push_back('1');
    105   // Count-delta pairs count.
    106   packed.push_back(2);
    107   // 0xd1ce0000
    108   packed.push_back(128);
    109   packed.push_back(128);
    110   packed.push_back(184);
    111   packed.push_back(142);
    112   packed.push_back(13);
    113   // Run of two relocations, 4 byte deltas.
    114   packed.push_back(2);
    115   packed.push_back(4);
    116   // Run of three relocations, 8 byte deltas.
    117   packed.push_back(3);
    118   packed.push_back(8);
    119   // Padding.
    120   packed.push_back(0);
    121   packed.push_back(0);
    122 
    123   relocations.clear();
    124   packer.UnpackRelativeRelocations(packed, &relocations);
    125 
    126   EXPECT_EQ(6, relocations.size());
    127   // Initial relocation.
    128   EXPECT_TRUE(CheckRelocation(0xd1ce0000, relocations[0]));
    129   // Two relocations, 4 byte deltas.
    130   EXPECT_TRUE(CheckRelocation(0xd1ce0004, relocations[1]));
    131   EXPECT_TRUE(CheckRelocation(0xd1ce0008, relocations[2]));
    132   // Three relocations, 8 byte deltas.
    133   EXPECT_TRUE(CheckRelocation(0xd1ce0010, relocations[3]));
    134   EXPECT_TRUE(CheckRelocation(0xd1ce0018, relocations[4]));
    135   EXPECT_TRUE(CheckRelocation(0xd1ce0020, relocations[5]));
    136 }
    137 
    138 TEST(Packer, PackRela) {
    139   std::vector<ELF::Rela> relocations;
    140   std::vector<uint8_t> packed;
    141 
    142   RelocationPacker packer;
    143 
    144   // Initial relocation.
    145   AddRelocation(0xd1ce0000, 10000, &relocations);
    146   // Two more relocations, 4 byte offset deltas, 12 byte addend deltas.
    147   AddRelocation(0xd1ce0004, 10012, &relocations);
    148   AddRelocation(0xd1ce0008, 10024, &relocations);
    149   // Three more relocations, 8 byte deltas, -24 byte addend deltas.
    150   AddRelocation(0xd1ce0010, 10000, &relocations);
    151   AddRelocation(0xd1ce0018, 9976, &relocations);
    152   AddRelocation(0xd1ce0020, 9952, &relocations);
    153 
    154   packed.clear();
    155   packer.PackRelativeRelocations(relocations, &packed);
    156 
    157   EXPECT_EQ(24, packed.size());
    158   // Identifier.
    159   EXPECT_EQ('A', packed[0]);
    160   EXPECT_EQ('P', packed[1]);
    161   EXPECT_EQ('A', packed[2]);
    162   EXPECT_EQ('1', packed[3]);
    163   // Delta pairs count.
    164   EXPECT_EQ(6, packed[4]);
    165   // 0xd1ce0000
    166   EXPECT_EQ(128, packed[5]);
    167   EXPECT_EQ(128, packed[6]);
    168   EXPECT_EQ(184, packed[7]);
    169   EXPECT_EQ(142, packed[8]);
    170   EXPECT_EQ(13, packed[9]);
    171   // 10000
    172   EXPECT_EQ(144, packed[10]);
    173   EXPECT_EQ(206, packed[11]);
    174   EXPECT_EQ(0, packed[12]);
    175   // 4, 12
    176   EXPECT_EQ(4, packed[13]);
    177   EXPECT_EQ(12, packed[14]);
    178   // 4, 12
    179   EXPECT_EQ(4, packed[15]);
    180   EXPECT_EQ(12, packed[16]);
    181   // 8, -24
    182   EXPECT_EQ(8, packed[17]);
    183   EXPECT_EQ(104, packed[18]);
    184   // 8, -24
    185   EXPECT_EQ(8, packed[19]);
    186   EXPECT_EQ(104, packed[20]);
    187   // 8, -24
    188   EXPECT_EQ(8, packed[21]);
    189   EXPECT_EQ(104, packed[22]);
    190   // Padding.
    191   EXPECT_EQ(0, packed[23]);
    192 }
    193 
    194 TEST(Packer, UnpackRela) {
    195   std::vector<uint8_t> packed;
    196   std::vector<ELF::Rela> relocations;
    197 
    198   RelocationPacker packer;
    199 
    200   // Identifier.
    201   packed.push_back('A');
    202   packed.push_back('P');
    203   packed.push_back('A');
    204   packed.push_back('1');
    205   // Delta pairs count.
    206   packed.push_back(6);
    207   // 0xd1ce0000
    208   packed.push_back(128);
    209   packed.push_back(128);
    210   packed.push_back(184);
    211   packed.push_back(142);
    212   packed.push_back(13);
    213   // 10000
    214   packed.push_back(144);
    215   packed.push_back(206);
    216   packed.push_back(0);
    217   // 4, 12
    218   packed.push_back(4);
    219   packed.push_back(12);
    220   // 4, 12
    221   packed.push_back(4);
    222   packed.push_back(12);
    223   // 8, -24
    224   packed.push_back(8);
    225   packed.push_back(104);
    226   // 8, -24
    227   packed.push_back(8);
    228   packed.push_back(104);
    229   // 8, -24
    230   packed.push_back(8);
    231   packed.push_back(104);
    232   // Padding.
    233   packed.push_back(0);
    234 
    235   relocations.clear();
    236   packer.UnpackRelativeRelocations(packed, &relocations);
    237 
    238   EXPECT_EQ(6, relocations.size());
    239   // Initial relocation.
    240   EXPECT_TRUE(CheckRelocation(0xd1ce0000, 10000, relocations[0]));
    241   // Two more relocations, 4 byte offset deltas, 12 byte addend deltas.
    242   EXPECT_TRUE(CheckRelocation(0xd1ce0004, 10012, relocations[1]));
    243   EXPECT_TRUE(CheckRelocation(0xd1ce0008, 10024, relocations[2]));
    244   // Three more relocations, 8 byte offset deltas, -24 byte addend deltas.
    245   EXPECT_TRUE(CheckRelocation(0xd1ce0010, 10000, relocations[3]));
    246   EXPECT_TRUE(CheckRelocation(0xd1ce0018, 9976, relocations[4]));
    247   EXPECT_TRUE(CheckRelocation(0xd1ce0020, 9952, relocations[5]));
    248 }
    249 
    250 }  // namespace relocation_packer
    251