Chromium Code Reviews| 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 |