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.
10 #include "delta_encoder.h"
11 #include "elf_traits.h"
15 namespace relocation_packer
{
17 // Pack relocations into a group encoded packed representation.
18 template <typename ELF
>
19 void RelocationPacker
<ELF
>::PackRelocations(const std::vector
<typename
ELF::Rela
>& relocations
,
20 std::vector
<uint8_t>* packed
) {
22 std::vector
<typename
ELF::Addr
> packed_words
;
23 RelocationDeltaCodec
<ELF
> codec
;
24 codec
.Encode(relocations
, &packed_words
);
26 // If insufficient data do nothing.
27 if (packed_words
.empty())
30 Sleb128Encoder
<typename
ELF::Addr
> sleb128_encoder
;
31 Leb128Encoder
<typename
ELF::Addr
> leb128_encoder
;
33 std::vector
<uint8_t> leb128_packed
;
34 std::vector
<uint8_t> sleb128_packed
;
36 leb128_encoder
.EnqueueAll(packed_words
);
37 leb128_encoder
.GetEncoding(&leb128_packed
);
39 sleb128_encoder
.EnqueueAll(packed_words
);
40 sleb128_encoder
.GetEncoding(&sleb128_packed
);
42 // TODO (simonb): Estimate savings on current android system image and consider using
43 // one encoder for all packed relocations to reduce complexity.
44 if (leb128_packed
.size() <= sleb128_packed
.size()) {
45 packed
->push_back('A');
46 packed
->push_back('P');
47 packed
->push_back('U');
48 packed
->push_back('2');
49 packed
->insert(packed
->end(), leb128_packed
.begin(), leb128_packed
.end());
51 packed
->push_back('A');
52 packed
->push_back('P');
53 packed
->push_back('S');
54 packed
->push_back('2');
55 packed
->insert(packed
->end(), sleb128_packed
.begin(), sleb128_packed
.end());
59 // Unpack relative relocations from a run-length encoded packed
61 template <typename ELF
>
62 void RelocationPacker
<ELF
>::UnpackRelocations(
63 const std::vector
<uint8_t>& packed
,
64 std::vector
<typename
ELF::Rela
>* relocations
) {
66 std::vector
<typename
ELF::Addr
> packed_words
;
67 CHECK(packed
.size() > 4 &&
70 (packed
[2] == 'U' || packed
[2] == 'S') &&
73 if (packed
[2] == 'U') {
74 Leb128Decoder
<typename
ELF::Addr
> decoder(packed
, 4);
75 decoder
.DequeueAll(&packed_words
);
77 Sleb128Decoder
<typename
ELF::Addr
> decoder(packed
, 4);
78 decoder
.DequeueAll(&packed_words
);
81 RelocationDeltaCodec
<ELF
> codec
;
82 codec
.Decode(packed_words
, relocations
);
85 template class RelocationPacker
<ELF32_traits
>;
86 template class RelocationPacker
<ELF64_traits
>;
88 } // namespace relocation_packer