• Home
Name Date Size #Lines LOC

..--

src/03-May-2024-2,3541,410

test_data/03-May-2024-6434

LICENSED03-May-20241.5 KiB2827

README.TXTD03-May-20243.3 KiB10373

relocation_packer.gypD03-May-20241.6 KiB6765

README.TXT

1Introduction:
2-------------
3
4R_ARM_RELATIVE relocations are the bulk of dynamic relocations (the .rel.dyn
5section) in libchrome.<version>.so.  The ELF standard representation of them
6is wasteful.
7
8Packing uses run length encoding to store them more efficiently.  Packed
9relocations are placed in a new .android.rel.dyn section.  Packing reduces
10the footprint of libchrome.<version>.so in the filesystem, in APK downloads,
11and in memory when loaded on the device.
12
13A packed libchrome.<version>.so is designed so that it can be loaded directly
14on Android, but requires the explicit support of a crazy linker that has been
15extended to understand packed relocations.  Packed relocations are currently
16only supported on ARM.
17
18A packed libchrome.<version>.so cannot currently be used with the standard
19Android runtime linker.
20
21See src/*.h for design and implementation notes.
22
23
24Notes:
25------
26
27Packing does not adjust debug data.  An unstripped libchrome.<version>.so
28can be packed and will run, but may no longer be useful for debugging.
29
30Unpacking on the device requires the explicit support of an extended crazy
31linker.  Adds the following new .dynamic tags, used by the crazy linker to
32find the packed .android.rel.dyn section data:
33
34  DT_ANDROID_ARM_REL_OFFSET = DT_LOPROC    (Processor specific: 0x70000000)
35    - The offset of .android.rel.dyn data in libchrome.<version>.so
36  DT_ANDROID_ARM_REL_SIZE = DT_LOPROC + 1  (Processor Specific: 0x70000001)
37    - The size of .android.rel.dyn data in bytes
38
39The format of .android.rel.dyn data is:
40
41  "APR1" identifier
42  N: the number of count-delta pairs in the encoding
43  A: the initial offset
44  N * C,D: N count-delta pairs
45
46All numbers in the encoding stream are stored as LEB128 values.  For details
47see http://en.wikipedia.org/wiki/LEB128.
48
49The streaming unpacking algorithm is:
50
51  skip over "APR1"
52  pairs, addr = next leb128 value, next leb128 value
53  emit R_ARM_RELATIVE relocation with r_offset = addr
54  while pairs:
55    count, delta = next leb128 value, next leb128 value
56    while count:
57      addr += delta
58      emit R_ARM_RELATIVE relocation with r_offset = addr
59      count--
60    pairs--;
61
62
63Usage instructions:
64-------------------
65
66To pack relocations, add an empty .android.rel.dyn and then run the tool:
67
68    echo -n 'NULL' >/tmp/small
69    arm-linux-gnueabi-objcopy \
70        --add-section .android.rel.dyn=/tmp/small \
71        libchrome.<version>.so libchrome.<version>.so.packed
72    rm /tmp/small
73    relocation_packer libchrome.<version>.so.packed
74
75To unpack and restore the shared library to its original state:
76
77    cp libchrome.<version>.so.packed unpackable
78    relocation_packer -u unpackable
79    arm-linux-gnueabi-objcopy \
80        --remove-section=.android.rel.dyn unpackable libchrome.<version>.so
81    rm unpackable
82
83
84Bugs & TODOs:
85-------------
86
87Currently only supports arm32.  Support for arm64 requires some extension
88and modification.
89
90Requires two free slots in the .dynamic section.  Uses these to add data that
91tells the crazy linker where to find the packed .android.rel.dyn data.  Fails
92if insufficient free slots exist (use gold --spare-dynamic-slots to increase
93the allocation).
94
95Requires libelf 0.158 or later.  Earlier libelf releases may be buggy in
96ways that prevent the packer from working correctly.
97
98
99Testing:
100--------
101
102Unittests run under gtest, on the host system.
103