README.TXT revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1Introduction:
2-------------
3
4Relative relocations are the bulk of dynamic relocations (the .rel.dyn
5or .rela.dyn sections) in libchrome.<version>.so.  The ELF standard
6representation of them is wasteful.
7
8Packing uses a combination of run length encoding, delta encoding, and LEB128
9encoding to store them more efficiently.  Packed relocations are placed in
10a new .android.rel.dyn or .android.rela.dyn section.  Packing reduces
11the footprint of libchrome.<version>.so in the filesystem, in APK downloads,
12and in memory when loaded on the device.
13
14A packed libchrome.<version>.so is designed so that it can be loaded directly
15on Android, but requires the explicit support of a crazy linker that has been
16extended to understand packed relocations.  Packed relocations are currently
17only supported on ARM.
18
19A packed libchrome.<version>.so cannot currently be used with the standard
20Android runtime linker.
21
22See src/*.h for design and implementation notes.
23
24
25Notes:
26------
27
28Packing does not adjust debug data.  An unstripped libchrome.<version>.so
29can be packed and will run, but may no longer be useful for debugging.
30
31Unpacking on the device requires the explicit support of an extended crazy
32linker.  Adds the following new .dynamic tags, used by the crazy linker to
33find the packed .android.rel.dyn or .android.rela.dyn section data:
34
35  DT_ANDROID_REL_OFFSET = DT_LOOS    (Operating System specific: 0x6000000d)
36    - The offset of packed relocation data in libchrome.<version>.so
37  DT_ANDROID_REL_SIZE = DT_LOOS + 1  (Operating System Specific: 0x6000000e)
38    - The size of packed relocation data in bytes
39
4032 bit ARM libraries use relocations without addends.  64 bit ARM libraries
41use relocations with addends.  The packing strategy necessarily differs for
42the two relocation types.
43
44Where libchrome.<version>.so contains relocations without addends, the format
45of .android.rel.dyn data is:
46
47  "APR1" identifier
48  N: the number of count-delta pairs in the encoding
49  A: the initial offset
50  N * C,D: N count-delta pairs
51
52Where libchrome.<version>.so contains relocations with addends, the format
53of .android.rela.dyn data is:
54
55  "APA1" identifier
56  N: the number of addr-addend delta pairs in the encoding
57  N * A,V: N addr-addend delta pairs
58
59All numbers in the encoding stream are stored as LEB128 values.  For details
60see http://en.wikipedia.org/wiki/LEB128.
61
62The streaming unpacking algorithm for 32 bit ARM is:
63
64  skip over "APR1"
65  pairs, addr = next leb128 value, next leb128 value
66  emit R_ARM_RELATIVE relocation with r_offset = addr
67  while pairs:
68    count, delta = next leb128 value, next leb128 value
69    while count:
70      addr += delta
71      emit R_ARM_RELATIVE relocation with r_offset = addr
72      count--
73    pairs--;
74
75The streaming unpacking algorithm for 64 bit ARM is:
76
77  skip over "APA1"
78  pairs = next signed leb128 value
79  addr, addend = 0, 0
80  while pairs:
81    addr += next signed leb128 value
82    addend += next signed leb128 value
83    emit R_AARCH64_RELATIVE relocation with r_offset = addr, r_addend = addend
84    pairs--;
85
86
87Usage instructions:
88-------------------
89
90To pack relocations, add an empty .android.rel.dyn or .android.rela.dyn and
91then run the tool:
92
93    echo -n 'NULL' >/tmp/small
94    if file libchrome.<version>.so | grep -q 'ELF 32'; then
95      arm-linux-androideabi-objcopy
96          --add-section .android.rel.dyn=/tmp/small
97          libchrome.<version>.so libchrome.<version>.so.packed
98    else
99      aarch64-linux-android-objcopy
100          --add-section .android.rela.dyn=/tmp/small
101          libchrome.<version>.so libchrome.<version>.so.packed
102    fi
103    rm /tmp/small
104    relocation_packer libchrome.<version>.so.packed
105
106To unpack and restore the shared library to its original state:
107
108    cp libchrome.<version>.so.packed unpackable
109    relocation_packer -u unpackable
110    if file libchrome.<version>.so | grep -q 'ELF 32'; then
111      arm-linux-androideabi-objcopy \
112          --remove-section=.android.rel.dyn unpackable libchrome.<version>.so
113    else
114      aarch64-linux-android-objcopy \
115          --remove-section=.android.rela.dyn unpackable libchrome.<version>.so
116    endif
117    rm unpackable
118
119
120Bugs & TODOs:
121-------------
122
123Requires two free slots in the .dynamic section.  Uses these to add data that
124tells the crazy linker where to find the packed relocation data.  Fails
125if insufficient free slots exist (use gold --spare-dynamic-slots to increase
126the allocation).
127
128Requires libelf 0.158 or later.  Earlier libelf releases may be buggy in
129ways that prevent the packer from working correctly.
130
131
132Testing:
133--------
134
135Unittests run under gtest, on the host system.
136