OLD | NEW |
---|---|
(Empty) | |
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 "delta_encoder.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "debug.h" | |
10 #include "elf_traits.h" | |
11 | |
12 namespace relocation_packer { | |
13 | |
14 // Encode relative relocations with addends into a delta encoded (packed) | |
15 // representation. Represented as simple r_offset and r_addend delta pairs, | |
16 // with an implicit neutral element at the start. | |
17 void RelocationDeltaCodec::Encode(const std::vector<ELF::Rela>& relocations, | |
18 std::vector<ELF::Sxword>* packed) { | |
19 // One relocation is sufficient for delta encoding. | |
20 if (relocations.size() < 1) | |
21 return; | |
22 | |
23 // Start with the element count, then append the delta pairs. | |
24 packed->push_back(relocations.size()); | |
25 | |
26 ELF::Addr offset = 0; | |
27 ELF::Sxword addend = 0; | |
28 | |
29 for (size_t i = 0; i < relocations.size(); ++i) { | |
rmcilroy
2014/07/28 10:08:44
Could you add an assert here that the relocations[
simonb (inactive)
2014/07/28 12:20:56
Done. Also added similar to run_length_encoder.cc
| |
30 packed->push_back(relocations[i].r_offset - offset); | |
31 offset = relocations[i].r_offset; | |
32 packed->push_back(relocations[i].r_addend - addend); | |
33 addend = relocations[i].r_addend; | |
34 } | |
35 } | |
36 | |
37 // Decode relative relocations with addends from a delta encoded (packed) | |
38 // representation. | |
39 void RelocationDeltaCodec::Decode(const std::vector<ELF::Sxword>& packed, | |
40 std::vector<ELF::Rela>* relocations) { | |
41 // We need at least one packed pair after the packed pair count to be | |
42 // able to unpack. | |
43 if (packed.size() < 3) | |
44 return; | |
45 | |
46 // Ensure that the packed data offers enough pairs. There may be zero | |
47 // padding on it that we ignore. | |
48 CHECK(packed[0] <= (packed.size() - 1) >> 1); | |
49 | |
50 ELF::Addr offset = 0; | |
51 ELF::Sxword addend = 0; | |
52 | |
53 // The first packed vector element is the pairs count. Start uncondensing | |
54 // pairs at the second, and finish at the end of the pairs data. | |
55 const size_t pairs_count = packed[0]; | |
56 for (size_t i = 1; i < 1 + (pairs_count << 1); i += 2) { | |
57 offset += packed[i]; | |
58 addend += packed[i + 1]; | |
59 | |
60 // Generate a relocation for this offset and addend pair. | |
61 ELF::Rela relocation; | |
62 relocation.r_offset = offset; | |
63 relocation.r_info = ELF_R_INFO(0, ELF::kRelativeRelocationCode); | |
64 relocation.r_addend = addend; | |
65 relocations->push_back(relocation); | |
66 } | |
67 } | |
68 | |
69 } // namespace relocation_packer | |
OLD | NEW |