
According to runs on /system/lib there using unsigned leb128 does not save us any additional space. In order to keep packing as simple as possible switch to using signed leb128 for everything. Bug: http://b/18051137 Change-Id: I1a47cb9eb2175895b3c3f7c13b4c6b1060de86c0
68 lines
1.9 KiB
C++
68 lines
1.9 KiB
C++
// Copyright 2014 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "packer.h"
|
|
|
|
#include <vector>
|
|
|
|
#include "debug.h"
|
|
#include "delta_encoder.h"
|
|
#include "elf_traits.h"
|
|
#include "sleb128.h"
|
|
|
|
namespace relocation_packer {
|
|
|
|
// Pack relocations into a group encoded packed representation.
|
|
template <typename ELF>
|
|
void RelocationPacker<ELF>::PackRelocations(const std::vector<typename ELF::Rela>& relocations,
|
|
std::vector<uint8_t>* packed) {
|
|
// Run-length encode.
|
|
std::vector<typename ELF::Addr> packed_words;
|
|
RelocationDeltaCodec<ELF> codec;
|
|
codec.Encode(relocations, &packed_words);
|
|
|
|
// If insufficient data do nothing.
|
|
if (packed_words.empty())
|
|
return;
|
|
|
|
Sleb128Encoder<typename ELF::Addr> sleb128_encoder;
|
|
|
|
std::vector<uint8_t> sleb128_packed;
|
|
|
|
sleb128_encoder.EnqueueAll(packed_words);
|
|
sleb128_encoder.GetEncoding(&sleb128_packed);
|
|
|
|
packed->push_back('A');
|
|
packed->push_back('P');
|
|
packed->push_back('S');
|
|
packed->push_back('2');
|
|
packed->insert(packed->end(), sleb128_packed.begin(), sleb128_packed.end());
|
|
}
|
|
|
|
// Unpack relative relocations from a run-length encoded packed
|
|
// representation.
|
|
template <typename ELF>
|
|
void RelocationPacker<ELF>::UnpackRelocations(
|
|
const std::vector<uint8_t>& packed,
|
|
std::vector<typename ELF::Rela>* relocations) {
|
|
|
|
std::vector<typename ELF::Addr> packed_words;
|
|
CHECK(packed.size() > 4 &&
|
|
packed[0] == 'A' &&
|
|
packed[1] == 'P' &&
|
|
packed[2] == 'S' &&
|
|
packed[3] == '2');
|
|
|
|
Sleb128Decoder<typename ELF::Addr> decoder(packed, 4);
|
|
decoder.DequeueAll(&packed_words);
|
|
|
|
RelocationDeltaCodec<ELF> codec;
|
|
codec.Decode(packed_words, relocations);
|
|
}
|
|
|
|
template class RelocationPacker<ELF32_traits>;
|
|
template class RelocationPacker<ELF64_traits>;
|
|
|
|
} // namespace relocation_packer
|