packer.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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
17namespace relocation_packer {
18
19// Pack R_ARM_RELATIVE relocations into a run-length encoded packed
20// representation.
21void 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.
53void 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