Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: tools/relocation_packer/src/run_length_encoder.cc

Issue 410933004: Extend relocation packing to cover arm64. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase to master Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/relocation_packer/src/run_length_encoder.h ('k') | tools/relocation_packer/src/sleb128.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "run_length_encoder.h" 5 #include "run_length_encoder.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "debug.h" 9 #include "debug.h"
10 #include "elf_traits.h" 10 #include "elf_traits.h"
11 11
12 namespace relocation_packer { 12 namespace relocation_packer {
13 13
14 namespace { 14 namespace {
15 15
16 // Generate a vector of deltas between the r_offset fields of adjacent 16 // Generate a vector of deltas between the r_offset fields of adjacent
17 // ARM relative relocations. 17 // relative relocations.
18 void GetDeltas(const std::vector<ELF::Rel>& relocations, 18 void GetDeltas(const std::vector<ELF::Rel>& relocations,
19 std::vector<ELF::Addr>* deltas) { 19 std::vector<ELF::Addr>* deltas) {
20 CHECK(relocations.size() >= 2); 20 CHECK(relocations.size() >= 2);
21 21
22 for (size_t i = 0; i < relocations.size() - 1; ++i) { 22 for (size_t i = 0; i < relocations.size() - 1; ++i) {
23 const ELF::Addr first = relocations[i].r_offset; 23 const ELF::Rel* first = &relocations[i];
24 const ELF::Addr second = relocations[i + 1].r_offset; 24 CHECK(ELF_R_TYPE(first->r_info) == ELF::kRelativeRelocationCode);
25
26 const ELF::Rel* second = &relocations[i + 1];
27 CHECK(ELF_R_TYPE(second->r_info) == ELF::kRelativeRelocationCode);
28
25 // Requires that offsets are 'strictly increasing'. The packing 29 // Requires that offsets are 'strictly increasing'. The packing
26 // algorithm fails if this does not hold. 30 // algorithm fails if this does not hold.
27 CHECK(second > first); 31 CHECK(second->r_offset > first->r_offset);
28 deltas->push_back(second - first); 32 deltas->push_back(second->r_offset - first->r_offset);
29 } 33 }
30 } 34 }
31 35
32 // Condense a set of r_offset deltas into a run-length encoded packing. 36 // Condense a set of r_offset deltas into a run-length encoded packing.
33 // Represented as count-delta pairs, where count is the run length and 37 // Represented as count-delta pairs, where count is the run length and
34 // delta the common difference between adjacent r_offsets. 38 // delta the common difference between adjacent r_offsets.
35 void Condense(const std::vector<ELF::Addr>& deltas, 39 void Condense(const std::vector<ELF::Addr>& deltas,
36 std::vector<ELF::Xword>* packed) { 40 std::vector<ELF::Xword>* packed) {
37 CHECK(!deltas.empty()); 41 CHECK(!deltas.empty());
38 size_t count = 0; 42 size_t count = 0;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 relocation.r_offset = addr; 89 relocation.r_offset = addr;
86 relocation.r_info = ELF_R_INFO(0, ELF::kRelativeRelocationCode); 90 relocation.r_info = ELF_R_INFO(0, ELF::kRelativeRelocationCode);
87 relocations->push_back(relocation); 91 relocations->push_back(relocation);
88 count--; 92 count--;
89 } 93 }
90 } 94 }
91 } 95 }
92 96
93 } // namespace 97 } // namespace
94 98
95 // Encode ARM relative relocations into a run-length encoded (packed) 99 // Encode relative relocations into a run-length encoded (packed)
96 // representation. 100 // representation.
97 void RelocationRunLengthCodec::Encode(const std::vector<ELF::Rel>& relocations, 101 void RelocationRunLengthCodec::Encode(const std::vector<ELF::Rel>& relocations,
98 std::vector<ELF::Xword>* packed) { 102 std::vector<ELF::Xword>* packed) {
99 // If we have zero or one relocation only then there is no packing 103 // If we have zero or one relocation only then there is no packing
100 // possible; a run-length encoding needs a run. 104 // possible; a run-length encoding needs a run.
101 if (relocations.size() < 2) 105 if (relocations.size() < 2)
102 return; 106 return;
103 107
104 std::vector<ELF::Addr> deltas; 108 std::vector<ELF::Addr> deltas;
105 GetDeltas(relocations, &deltas); 109 GetDeltas(relocations, &deltas);
106 110
107 // Reserve space for the element count. 111 // Reserve space for the element count.
108 packed->push_back(0); 112 packed->push_back(0);
109 113
110 // Initialize the packed data with the first offset, then follow up with 114 // Initialize the packed data with the first offset, then follow up with
111 // the condensed deltas vector. 115 // the condensed deltas vector.
112 packed->push_back(relocations[0].r_offset); 116 packed->push_back(relocations[0].r_offset);
113 Condense(deltas, packed); 117 Condense(deltas, packed);
114 118
115 // Fill in the packed pair count. 119 // Fill in the packed pair count.
116 packed->at(0) = (packed->size() - 2) >> 1; 120 packed->at(0) = (packed->size() - 2) >> 1;
117 } 121 }
118 122
119 // Decode ARM relative relocations from a run-length encoded (packed) 123 // Decode relative relocations from a run-length encoded (packed)
120 // representation. 124 // representation.
121 void RelocationRunLengthCodec::Decode(const std::vector<ELF::Xword>& packed, 125 void RelocationRunLengthCodec::Decode(const std::vector<ELF::Xword>& packed,
122 std::vector<ELF::Rel>* relocations) { 126 std::vector<ELF::Rel>* relocations) {
123 // We need at least one packed pair after the packed pair count and start 127 // We need at least one packed pair after the packed pair count and start
124 // address to be able to unpack. 128 // address to be able to unpack.
125 if (packed.size() < 4) 129 if (packed.size() < 4)
126 return; 130 return;
127 131
128 // Ensure that the packed data offers enough pairs. There may be zero 132 // Ensure that the packed data offers enough pairs. There may be zero
129 // padding on it that we ignore. 133 // padding on it that we ignore.
130 CHECK(packed[0] <= (packed.size() - 2) >> 1); 134 CHECK(packed[0] <= (packed.size() - 2) >> 1);
131 135
132 // The first packed vector element is the pairs count and the second the 136 // The first packed vector element is the pairs count and the second the
133 // initial address. Start uncondensing pairs at the third, and finish 137 // initial address. Start uncondensing pairs at the third, and finish
134 // at the end of the pairs data. 138 // at the end of the pairs data.
135 const size_t pairs_count = packed[0]; 139 const size_t pairs_count = packed[0];
136 const ELF::Addr addr = packed[1]; 140 const ELF::Addr addr = packed[1];
137 Uncondense(addr, packed, 2, 2 + (pairs_count << 1), relocations); 141 Uncondense(addr, packed, 2, 2 + (pairs_count << 1), relocations);
138 } 142 }
139 143
140 } // namespace relocation_packer 144 } // namespace relocation_packer
OLDNEW
« no previous file with comments | « tools/relocation_packer/src/run_length_encoder.h ('k') | tools/relocation_packer/src/sleb128.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698