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 17 namespace relocation_packer { 18 19 // Pack R_ARM_RELATIVE relocations into a run-length encoded packed 20 // representation. 21 void 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. 53 void 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