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 
      9 #include "debug.h"
     10 #include "delta_encoder.h"
     11 #include "elf_traits.h"
     12 #include "sleb128.h"
     13 
     14 namespace relocation_packer {
     15 
     16 // Pack relocations into a group encoded packed representation.
     17 template <typename ELF>
     18 void RelocationPacker<ELF>::PackRelocations(const std::vector<typename ELF::Rela>& relocations,
     19                                             std::vector<uint8_t>* packed) {
     20   // Run-length encode.
     21   std::vector<typename ELF::Addr> packed_words;
     22   RelocationDeltaCodec<ELF> codec;
     23   codec.Encode(relocations, &packed_words);
     24 
     25   // If insufficient data do nothing.
     26   if (packed_words.empty())
     27     return;
     28 
     29   Sleb128Encoder<typename ELF::Addr> sleb128_encoder;
     30 
     31   std::vector<uint8_t> sleb128_packed;
     32 
     33   sleb128_encoder.EnqueueAll(packed_words);
     34   sleb128_encoder.GetEncoding(&sleb128_packed);
     35 
     36   packed->push_back('A');
     37   packed->push_back('P');
     38   packed->push_back('S');
     39   packed->push_back('2');
     40   packed->insert(packed->end(), sleb128_packed.begin(), sleb128_packed.end());
     41 }
     42 
     43 // Unpack relative relocations from a run-length encoded packed
     44 // representation.
     45 template <typename ELF>
     46 void RelocationPacker<ELF>::UnpackRelocations(
     47     const std::vector<uint8_t>& packed,
     48     std::vector<typename ELF::Rela>* relocations) {
     49 
     50   std::vector<typename ELF::Addr> packed_words;
     51   CHECK(packed.size() > 4 &&
     52         packed[0] == 'A' &&
     53         packed[1] == 'P' &&
     54         packed[2] == 'S' &&
     55         packed[3] == '2');
     56 
     57   Sleb128Decoder<typename ELF::Addr> decoder(packed, 4);
     58   decoder.DequeueAll(&packed_words);
     59 
     60   RelocationDeltaCodec<ELF> codec;
     61   codec.Decode(packed_words, relocations);
     62 }
     63 
     64 template class RelocationPacker<ELF32_traits>;
     65 template class RelocationPacker<ELF64_traits>;
     66 
     67 }  // namespace relocation_packer
     68