Remove unused/unusable relocation packer files.

Removes:
- src/run_length_encoder.h
    artifact of the original packing tool, not used here
- test_data/generate_elf_file_unittest_relocs.sh
- test_data/generate_elf_file_unittest_relocs.py
    test data generation for chromium/gyp, not usable here
- README.TXT
    because it is now almost entirely outdated

Change-Id: Ic4cd372647d9a365dc52833a6cc1cf66f0c95ec9
This commit is contained in:
Simon Baldwin 2015-03-25 16:14:30 +00:00
parent f5e0ba94d9
commit d2bd5739ed
4 changed files with 0 additions and 339 deletions

View File

@ -1,135 +0,0 @@
Introduction:
-------------
Relative relocations are the bulk of dynamic relocations (the .rel.dyn
or .rela.dyn sections) in libchrome.<version>.so. The ELF standard
representation of them is wasteful.
Packing uses a combination of run length encoding, delta encoding, and LEB128
encoding to store them more efficiently. Packed relocations are placed in
a new .android.rel.dyn or .android.rela.dyn section. Packing reduces
the footprint of libchrome.<version>.so in the filesystem, in APK downloads,
and in memory when loaded on the device.
A packed libchrome.<version>.so is designed so that it can be loaded directly
on Android, but requires the explicit support of a crazy linker that has been
extended to understand packed relocations. Packed relocations are currently
only supported on ARM.
A packed libchrome.<version>.so cannot currently be used with the standard
Android runtime linker.
See src/*.h for design and implementation notes.
Notes:
------
Packing does not adjust debug data. An unstripped libchrome.<version>.so
can be packed and will run, but may no longer be useful for debugging.
Unpacking on the device requires the explicit support of an extended crazy
linker. Adds the following new .dynamic tags, used by the crazy linker to
find the packed .android.rel.dyn or .android.rela.dyn section data:
DT_ANDROID_REL_OFFSET = DT_LOOS (Operating System specific: 0x6000000d)
- The offset of packed relocation data in libchrome.<version>.so
DT_ANDROID_REL_SIZE = DT_LOOS + 1 (Operating System Specific: 0x6000000e)
- The size of packed relocation data in bytes
32 bit ARM libraries use relocations without addends. 64 bit ARM libraries
use relocations with addends. The packing strategy necessarily differs for
the two relocation types.
Where libchrome.<version>.so contains relocations without addends, the format
of .android.rel.dyn data is:
"APR1" identifier
N: the number of count-delta pairs in the encoding
A: the initial offset
N * C,D: N count-delta pairs
Where libchrome.<version>.so contains relocations with addends, the format
of .android.rela.dyn data is:
"APA1" identifier
N: the number of addr-addend delta pairs in the encoding
N * A,V: N addr-addend delta pairs
All numbers in the encoding stream are stored as LEB128 values. For details
see http://en.wikipedia.org/wiki/LEB128.
The streaming unpacking algorithm for 32 bit ARM is:
skip over "APR1"
pairs, addr = next leb128 value, next leb128 value
emit R_ARM_RELATIVE relocation with r_offset = addr
while pairs:
count, delta = next leb128 value, next leb128 value
while count:
addr += delta
emit R_ARM_RELATIVE relocation with r_offset = addr
count--
pairs--
The streaming unpacking algorithm for 64 bit ARM is:
skip over "APA1"
pairs = next signed leb128 value
addr, addend = 0, 0
while pairs:
addr += next signed leb128 value
addend += next signed leb128 value
emit R_AARCH64_RELATIVE relocation with r_offset = addr, r_addend = addend
pairs--
Usage instructions:
-------------------
To pack relocations, add an empty .android.rel.dyn or .android.rela.dyn and
then run the tool:
echo -n 'NULL' >/tmp/small
if file libchrome.<version>.so | grep -q 'ELF 32'; then
arm-linux-androideabi-objcopy
--add-section .android.rel.dyn=/tmp/small
libchrome.<version>.so libchrome.<version>.so.packed
else
aarch64-linux-android-objcopy
--add-section .android.rela.dyn=/tmp/small
libchrome.<version>.so libchrome.<version>.so.packed
fi
rm /tmp/small
relocation_packer libchrome.<version>.so.packed
To unpack and restore the shared library to its original state:
cp libchrome.<version>.so.packed unpackable
relocation_packer -u unpackable
if file libchrome.<version>.so | grep -q 'ELF 32'; then
arm-linux-androideabi-objcopy \
--remove-section=.android.rel.dyn unpackable libchrome.<version>.so
else
aarch64-linux-android-objcopy \
--remove-section=.android.rela.dyn unpackable libchrome.<version>.so
endif
rm unpackable
Bugs & TODOs:
-------------
Requires two free slots in the .dynamic section. Uses these to add data that
tells the crazy linker where to find the packed relocation data. Fails
if insufficient free slots exist (use gold --spare-dynamic-slots to increase
the allocation).
Requires libelf 0.158 or later. Earlier libelf releases may be buggy in
ways that prevent the packer from working correctly.
Testing:
--------
Unittests run under gtest, on the host system.

View File

@ -1,81 +0,0 @@
// 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.
// Run-length encode and decode relative relocations.
//
// Relative relocations are the bulk of dynamic relocations (the
// .rel.dyn or .rela.dyn sections) in libchrome.<version>.so, and the ELF
// standard representation of them is wasteful. .rel.dyn contains
// relocations without addends, .rela.dyn relocations with addends.
//
// A relocation with no addend is 8 bytes on 32 bit platforms and 16 bytes
// on 64 bit plaforms, split into offset and info fields. Offsets strictly
// increase, and each is commonly a few bytes different from its predecessor.
// There are long runs where the difference does not change. The info field
// is constant. Example, from 'readelf -x4 libchrome.<version>.so' 32 bit:
//
// offset info offset info
// 808fef01 17000000 848fef01 17000000 ................
// 888fef01 17000000 8c8fef01 17000000 ................
// 908fef01 17000000 948fef01 17000000 ................
//
// Run length encoding packs this data more efficiently, by representing it
// as a delta and a count of entries each differing from its predecessor
// by this delta. The above can be represented as a start address followed
// by an encoded count of 6 and offset difference of 4:
//
// start count diff
// 01ef8f80 00000006 00000004
//
// Because relative relocation offsets strictly increase, the complete
// set of relative relocations in libchrome.<version>.so can be
// represented by a single start address followed by one or more difference
// and count encoded word pairs:
//
// start run1 count run1 diff run2 count run2 diff
// 01ef8f80 00000006 00000004 00000010 00000008 ...
//
// Decoding regenerates relative relocations beginning at address
// 'start' and for each encoded run, incrementing the address by 'difference'
// for 'count' iterations and emitting a new relative relocation.
//
// Once encoded, data is prefixed by a single word count of packed delta and
// count pairs. A final run-length encoded relative relocations vector
// might therefore look something like:
//
// pairs start run 1 run 2 ... run 15
// 0000000f 01ef8f80 00000006 00000004 00000010 00000008 ...
// Interpreted as:
// pairs=15 start=.. count=6,delta=4 count=16,delta=8
#ifndef TOOLS_RELOCATION_PACKER_SRC_RUN_LENGTH_ENCODER_H_
#define TOOLS_RELOCATION_PACKER_SRC_RUN_LENGTH_ENCODER_H_
#include <vector>
#include "elf.h"
#include "elf_traits.h"
namespace relocation_packer {
// A RelocationRunLengthCodec packs vectors of relative relocations
// into more compact forms, and unpacks them to reproduce the pre-packed data.
class RelocationRunLengthCodec {
public:
// Encode relative relocations into a more compact form.
// |relocations| is a vector of relative relocation structs.
// |packed| is the vector of packed words into which relocations are packed.
static void Encode(const std::vector<ELF::Rel>& relocations,
std::vector<ELF::Xword>* packed);
// Decode relative relocations from their more compact form.
// |packed| is the vector of packed relocations.
// |relocations| is a vector of unpacked relative relocation structs.
static void Decode(const std::vector<ELF::Xword>& packed,
std::vector<ELF::Rel>* relocations);
};
} // namespace relocation_packer
#endif // TOOLS_RELOCATION_PACKER_SRC_RUN_LENGTH_ENCODER_H_

View File

@ -1,88 +0,0 @@
#!/usr/bin/env python
#
# 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.
"""Build relocation packer unit test data.
Uses a built relocation packer to generate 'golden' reference test data
files for elf_file_unittests.cc.
"""
import optparse
import os
import shutil
import subprocess
import sys
import tempfile
def PackArmLibraryRelocations(android_pack_relocations,
android_objcopy,
added_section,
input_path,
output_path):
# Copy and add a 'NULL' .android.rel.dyn section for the packing tool.
with tempfile.NamedTemporaryFile() as stream:
stream.write('NULL')
stream.flush()
objcopy_command = [android_objcopy,
'--add-section', '%s=%s' % (added_section, stream.name),
input_path, output_path]
subprocess.check_call(objcopy_command)
# Pack relocations.
pack_command = [android_pack_relocations, output_path]
subprocess.check_call(pack_command)
def UnpackArmLibraryRelocations(android_pack_relocations,
input_path,
output_path):
shutil.copy(input_path, output_path)
# Unpack relocations. We leave the .android.rel.dyn or .android.rela.dyn
# in place.
unpack_command = [android_pack_relocations, '-u', output_path]
subprocess.check_call(unpack_command)
def main():
parser = optparse.OptionParser()
parser.add_option('--android-pack-relocations',
help='Path to the ARM relocations packer binary')
parser.add_option('--android-objcopy',
help='Path to the toolchain\'s objcopy binary')
parser.add_option('--added-section',
choices=['.android.rel.dyn', '.android.rela.dyn'],
help='Section to add, one of ".android.rel.dyn" or ".android.rela.dyn"')
parser.add_option('--test-file',
help='Path to the input test file, an unpacked ARM .so')
parser.add_option('--unpacked-output',
help='Path to the output file for reference unpacked data')
parser.add_option('--packed-output',
help='Path to the output file for reference packed data')
options, _ = parser.parse_args()
for output in [options.unpacked_output, options.packed_output]:
directory = os.path.dirname(output)
if not os.path.exists(directory):
os.makedirs(directory)
PackArmLibraryRelocations(options.android_pack_relocations,
options.android_objcopy,
options.added_section,
options.test_file,
options.packed_output)
UnpackArmLibraryRelocations(options.android_pack_relocations,
options.packed_output,
options.unpacked_output)
return 0
if __name__ == '__main__':
sys.exit(main())

View File

@ -1,35 +0,0 @@
#!/bin/bash
#
# 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.
# Generates elf_file_unittest_relocs_arm{32,64}{,_packed}.so test data files
# from elf_file_unittest_relocs.cc. Run once to create these test data
# files; the files are checked into the source tree.
#
# To use:
# ./generate_elf_file_unittest_relocs.sh
# git add elf_file_unittest_relocs_arm{32,64}{,_packed}.so
function main() {
local '-r' test_data_directory="$(pwd)"
cd '../../..'
source tools/cr/cr-bash-helpers.sh
local arch
for arch in 'arm32' 'arm64'; do
cr 'init' '--platform=android' '--type=Debug' '--architecture='"${arch}"
cr 'build' 'relocation_packer_unittests_test_data'
done
local '-r' packer='out_android/Debug/obj/tools/relocation_packer'
local '-r' gen="${packer}/relocation_packer_unittests_test_data.gen"
cp "${gen}/elf_file_unittest_relocs_arm"{32,64}{,_packed}'.so' \
"${test_data_directory}"
return 0
}
main