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 // Delta encode and decode relative relocations with addends. | |
6 // | |
7 // Relative relocations are the bulk of dynamic relocations (the | |
8 // .rel.dyn or .rela.dyn sections) in libchrome<version>.so, and the ELF | |
9 // standard representation of them is wasteful. .rel.dyn contains | |
10 // relocations without addends, .rela.dyn relocations with addends. | |
11 // | |
12 // A relocation with an addend is 12 bytes on 32 bit platforms and 24 bytes | |
13 // on 64 bit plaforms. It is split into offset, info, and addend fields. | |
14 // Offsets strictly increase, and each is commonly a few bytes different | |
15 // from its predecessor. Addends are less well behaved. The info field is | |
16 // constant. Example, from 'readelf -x4 libchrome.<version>.so' 64 bit: | |
17 // | |
18 // offset info | |
19 // 80949303 00000000 03040000 00000000 ................ | |
20 // addend offset | |
21 // fc015b00 00000000 88949303 00000000 ..[............. | |
22 // info addend | |
23 // 03040000 00000000 24025b00 00000000 ........$.[..... | |
24 // offset info | |
25 // 90949303 00000000 03040000 00000000 ................ | |
26 // addend offset | |
27 // 3c025b00 00000000 98949303 00000000 <.[............. | |
28 // info addend | |
29 // 03040000 00000000 50025b00 00000000 ........P.[..... | |
30 // | |
31 // The offset strictly increases, but the addend is unpredictable, so run | |
32 // length encoding will not work well with this data. We can however pack | |
33 // with delta encoding. The difference between offsets is small, between | |
34 // addends is sometimes small, four of eight bytes are almost always | |
rmcilroy
2014/07/28 10:08:44
"small - four of the eight bytes are almost always
simonb (inactive)
2014/07/28 12:20:56
Reworded for clarity.
| |
35 // unused, and the info is constant and so can be eliminated. | |
36 // | |
37 // Delta encoding reduces the size of the data modestly, so that the first | |
38 // three relocations above can be represented as: | |
39 // | |
40 // initial offset initial addend offset delta addend delta | |
41 // 00000000 03939480 00000000 005b01fc 00000000 00000008 00000000 00000028 | |
42 // offset delta addend delta ... | |
43 // 00000000 00000008 00000000 0000009f | |
44 // | |
45 // The addend delta can be negative as well as positive, but overall the | |
46 // deltas have a much smaller range than the input data. When encoded as | |
47 // signed LEB128 the total data reduction becomes useful. | |
48 | |
49 #ifndef TOOLS_RELOCATION_PACKER_SRC_DELTA_ENCODER_H_ | |
50 #define TOOLS_RELOCATION_PACKER_SRC_DELTA_ENCODER_H_ | |
51 | |
52 #include <vector> | |
53 | |
54 #include "elf.h" | |
55 #include "elf_traits.h" | |
56 | |
57 namespace relocation_packer { | |
58 | |
59 // A RelocationDeltaCodec packs vectors of relative relocations with | |
60 // addends into more compact forms, and unpacks them to reproduce the | |
61 // pre-packed data. | |
62 class RelocationDeltaCodec { | |
63 public: | |
64 // Encode relative relocations with addends into a more compact form. | |
65 // |relocations| is a vector of relative relocation with addend structs. | |
66 // |packed| is the vector of packed words into which relocations are packed. | |
67 static void Encode(const std::vector<ELF::Rela>& relocations, | |
68 std::vector<ELF::Sxword>* packed); | |
69 | |
70 // Decode relative relocations with addends from their more compact form. | |
71 // |packed| is the vector of packed relocations. | |
72 // |relocations| is a vector of unpacked relative relocations. | |
73 static void Decode(const std::vector<ELF::Sxword>& packed, | |
74 std::vector<ELF::Rela>* relocations); | |
75 }; | |
76 | |
77 } // namespace relocation_packer | |
78 | |
79 #endif // TOOLS_RELOCATION_PACKER_SRC_DELTA_ENCODER_H_ | |
OLD | NEW |