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// TODO(simonb): Extend for 64-bit target libraries. 6 7#include "packer.h" 8 9#include <string.h> 10#include <string> 11#include <vector> 12 13#include "debug.h" 14#include "leb128.h" 15#include "run_length_encoder.h" 16 17namespace relocation_packer { 18 19// Pack R_ARM_RELATIVE relocations into a run-length encoded packed 20// representation. 21void RelocationPacker::PackRelativeRelocations( 22 const std::vector<Elf32_Rel>& relocations, 23 std::vector<uint8_t>* packed) { 24 25 // Run-length encode. 26 std::vector<Elf32_Word> packed_words; 27 RelocationRunLengthCodec codec; 28 codec.Encode(relocations, &packed_words); 29 30 // If insufficient data to run-length encode, do nothing. 31 if (packed_words.empty()) 32 return; 33 34 // LEB128 encode, with "APR1" prefix. 35 Leb128Encoder encoder; 36 encoder.Enqueue('A'); 37 encoder.Enqueue('P'); 38 encoder.Enqueue('R'); 39 encoder.Enqueue('1'); 40 encoder.EnqueueAll(packed_words); 41 42 encoder.GetEncoding(packed); 43 44 // Pad packed to a whole number of words. This padding will decode as 45 // LEB128 zeroes. Run-length decoding ignores it because encoding 46 // embeds the pairs count in the stream itself. 47 while (packed->size() % sizeof(uint32_t)) 48 packed->push_back(0); 49} 50 51// Unpack R_ARM_RELATIVE relocations from a run-length encoded packed 52// representation. 53void RelocationPacker::UnpackRelativeRelocations( 54 const std::vector<uint8_t>& packed, 55 std::vector<Elf32_Rel>* relocations) { 56 57 // LEB128 decode, after checking and stripping "APR1" prefix. 58 std::vector<Elf32_Word> packed_words; 59 Leb128Decoder decoder(packed); 60 CHECK(decoder.Dequeue() == 'A' && decoder.Dequeue() == 'P' && 61 decoder.Dequeue() == 'R' && decoder.Dequeue() == '1'); 62 decoder.DequeueAll(&packed_words); 63 64 // Run-length decode. 65 RelocationRunLengthCodec codec; 66 codec.Decode(packed_words, relocations); 67} 68 69} // namespace relocation_packer 70