• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // TODO(simonb): Extend for 64-bit target libraries.
6 
7 #include "packer.h"
8 
9 #include <string.h>
10 #include <string>
11 #include <vector>
12 
13 #include "debug.h"
14 #include "leb128.h"
15 #include "run_length_encoder.h"
16 
17 namespace relocation_packer {
18 
19 // Pack R_ARM_RELATIVE relocations into a run-length encoded packed
20 // representation.
PackRelativeRelocations(const std::vector<Elf32_Rel> & relocations,std::vector<uint8_t> * packed)21 void RelocationPacker::PackRelativeRelocations(
22     const std::vector<Elf32_Rel>& relocations,
23     std::vector<uint8_t>* packed) {
24 
25   // Run-length encode.
26   std::vector<Elf32_Word> packed_words;
27   RelocationRunLengthCodec codec;
28   codec.Encode(relocations, &packed_words);
29 
30   // If insufficient data to run-length encode, do nothing.
31   if (packed_words.empty())
32     return;
33 
34   // LEB128 encode, with "APR1" prefix.
35   Leb128Encoder encoder;
36   encoder.Enqueue('A');
37   encoder.Enqueue('P');
38   encoder.Enqueue('R');
39   encoder.Enqueue('1');
40   encoder.EnqueueAll(packed_words);
41 
42   encoder.GetEncoding(packed);
43 
44   // Pad packed to a whole number of words.  This padding will decode as
45   // LEB128 zeroes.  Run-length decoding ignores it because encoding
46   // embeds the pairs count in the stream itself.
47   while (packed->size() % sizeof(uint32_t))
48     packed->push_back(0);
49 }
50 
51 // Unpack R_ARM_RELATIVE relocations from a run-length encoded packed
52 // representation.
UnpackRelativeRelocations(const std::vector<uint8_t> & packed,std::vector<Elf32_Rel> * relocations)53 void RelocationPacker::UnpackRelativeRelocations(
54     const std::vector<uint8_t>& packed,
55     std::vector<Elf32_Rel>* relocations) {
56 
57   // LEB128 decode, after checking and stripping "APR1" prefix.
58   std::vector<Elf32_Word> packed_words;
59   Leb128Decoder decoder(packed);
60   CHECK(decoder.Dequeue() == 'A' && decoder.Dequeue() == 'P' &&
61         decoder.Dequeue() == 'R' && decoder.Dequeue() == '1');
62   decoder.DequeueAll(&packed_words);
63 
64   // Run-length decode.
65   RelocationRunLengthCodec codec;
66   codec.Decode(packed_words, relocations);
67 }
68 
69 }  // namespace relocation_packer
70