OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "packer.h" | 5 #include "packer.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "debug.h" | 9 #include "debug.h" |
10 #include "delta_encoder.h" | 10 #include "delta_encoder.h" |
11 #include "elf_traits.h" | 11 #include "elf_traits.h" |
12 #include "leb128.h" | |
13 #include "sleb128.h" | 12 #include "sleb128.h" |
14 | 13 |
15 namespace relocation_packer { | 14 namespace relocation_packer { |
16 | 15 |
17 // Pack relocations into a group encoded packed representation. | 16 // Pack relocations into a group encoded packed representation. |
18 template <typename ELF> | 17 template <typename ELF> |
19 void RelocationPacker<ELF>::PackRelocations(const std::vector<typename ELF::Rela
>& relocations, | 18 void RelocationPacker<ELF>::PackRelocations(const std::vector<typename ELF::Rela
>& relocations, |
20 std::vector<uint8_t>* packed) { | 19 std::vector<uint8_t>* packed) { |
21 // Run-length encode. | 20 // Run-length encode. |
22 std::vector<typename ELF::Addr> packed_words; | 21 std::vector<typename ELF::Addr> packed_words; |
23 RelocationDeltaCodec<ELF> codec; | 22 RelocationDeltaCodec<ELF> codec; |
24 codec.Encode(relocations, &packed_words); | 23 codec.Encode(relocations, &packed_words); |
25 | 24 |
26 // If insufficient data do nothing. | 25 // If insufficient data do nothing. |
27 if (packed_words.empty()) | 26 if (packed_words.empty()) |
28 return; | 27 return; |
29 | 28 |
30 Sleb128Encoder<typename ELF::Addr> sleb128_encoder; | 29 Sleb128Encoder<typename ELF::Addr> sleb128_encoder; |
31 Leb128Encoder<typename ELF::Addr> leb128_encoder; | |
32 | 30 |
33 std::vector<uint8_t> leb128_packed; | |
34 std::vector<uint8_t> sleb128_packed; | 31 std::vector<uint8_t> sleb128_packed; |
35 | 32 |
36 leb128_encoder.EnqueueAll(packed_words); | |
37 leb128_encoder.GetEncoding(&leb128_packed); | |
38 | |
39 sleb128_encoder.EnqueueAll(packed_words); | 33 sleb128_encoder.EnqueueAll(packed_words); |
40 sleb128_encoder.GetEncoding(&sleb128_packed); | 34 sleb128_encoder.GetEncoding(&sleb128_packed); |
41 | 35 |
42 // TODO (simonb): Estimate savings on current android system image and conside
r using | 36 packed->push_back('A'); |
43 // one encoder for all packed relocations to reduce complexity. | 37 packed->push_back('P'); |
44 if (leb128_packed.size() <= sleb128_packed.size()) { | 38 packed->push_back('S'); |
45 packed->push_back('A'); | 39 packed->push_back('2'); |
46 packed->push_back('P'); | 40 packed->insert(packed->end(), sleb128_packed.begin(), sleb128_packed.end()); |
47 packed->push_back('U'); | |
48 packed->push_back('2'); | |
49 packed->insert(packed->end(), leb128_packed.begin(), leb128_packed.end()); | |
50 } else { | |
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()); | |
56 } | |
57 } | 41 } |
58 | 42 |
59 // Unpack relative relocations from a run-length encoded packed | 43 // Unpack relative relocations from a run-length encoded packed |
60 // representation. | 44 // representation. |
61 template <typename ELF> | 45 template <typename ELF> |
62 void RelocationPacker<ELF>::UnpackRelocations( | 46 void RelocationPacker<ELF>::UnpackRelocations( |
63 const std::vector<uint8_t>& packed, | 47 const std::vector<uint8_t>& packed, |
64 std::vector<typename ELF::Rela>* relocations) { | 48 std::vector<typename ELF::Rela>* relocations) { |
65 | 49 |
66 std::vector<typename ELF::Addr> packed_words; | 50 std::vector<typename ELF::Addr> packed_words; |
67 CHECK(packed.size() > 4 && | 51 CHECK(packed.size() > 4 && |
68 packed[0] == 'A' && | 52 packed[0] == 'A' && |
69 packed[1] == 'P' && | 53 packed[1] == 'P' && |
70 (packed[2] == 'U' || packed[2] == 'S') && | 54 packed[2] == 'S' && |
71 packed[3] == '2'); | 55 packed[3] == '2'); |
72 | 56 |
73 if (packed[2] == 'U') { | 57 Sleb128Decoder<typename ELF::Addr> decoder(packed, 4); |
74 Leb128Decoder<typename ELF::Addr> decoder(packed, 4); | 58 decoder.DequeueAll(&packed_words); |
75 decoder.DequeueAll(&packed_words); | |
76 } else { | |
77 Sleb128Decoder<typename ELF::Addr> decoder(packed, 4); | |
78 decoder.DequeueAll(&packed_words); | |
79 } | |
80 | 59 |
81 RelocationDeltaCodec<ELF> codec; | 60 RelocationDeltaCodec<ELF> codec; |
82 codec.Decode(packed_words, relocations); | 61 codec.Decode(packed_words, relocations); |
83 } | 62 } |
84 | 63 |
85 template class RelocationPacker<ELF32_traits>; | 64 template class RelocationPacker<ELF32_traits>; |
86 template class RelocationPacker<ELF64_traits>; | 65 template class RelocationPacker<ELF64_traits>; |
87 | 66 |
88 } // namespace relocation_packer | 67 } // namespace relocation_packer |
OLD | NEW |