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>
PackRelocations(const std::vector<typename ELF::Rela> & relocations,std::vector<uint8_t> * packed)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>
UnpackRelocations(const std::vector<uint8_t> & packed,std::vector<typename ELF::Rela> * relocations)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