OLD | NEW |
---|---|
(Empty) | |
1 Introduction: | |
2 ------------- | |
3 | |
4 R_ARM_RELATIVE relocations are the bulk of dynamic relocations (the .rel.dyn | |
5 section) in libchrome.<version>.so. The ELF standard representation of them | |
6 is wasteful. | |
7 | |
8 Packing uses run length encoding to store them more efficiently. Packed | |
9 relocations are placed in a new .android.rel.dyn section. Packing reduces | |
10 the footprint of libchrome.<version>.so in the filesystem, in APK downloads, | |
11 and in memory when loaded on the device. | |
12 | |
13 A packed libchrome.<version>.so is designed so that it can be loaded directly | |
14 on Android, but requires the explicit support of a crazy linker that has been | |
15 extended to understand packed relocations. The crazy linker currently only | |
rmcilroy
2014/06/07 11:49:07
/s/The crazy linker currently only.../Currently pa
simonb (inactive)
2014/06/09 14:39:19
Done.
| |
16 supports ARM. | |
17 | |
18 A packed libchrome.<version>.so cannot currently be used with the standard | |
19 Android runtime linker. | |
20 | |
21 See src/*.h for design and implementation notes. | |
22 | |
23 | |
24 Notes: | |
25 ------ | |
26 | |
27 Packing does not adjust debug data. An unstripped libchrome.<version>.so | |
28 can be packed and will run, but may no longer be useful for debugging. | |
29 | |
30 Unpacking on the device requires the explicit support of an extended crazy | |
31 linker. Adds the following new .dynamic tags, used by the crazy linker to | |
32 find 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 | |
39 The 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 | |
46 All numbers in the encoding stream are stored as LEB128 values. For details | |
47 see http://en.wikipedia.org/wiki/LEB128. | |
48 | |
49 The 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 | |
63 Usage instructions: | |
64 ------------------- | |
65 | |
66 To 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 relocations_packer libchrome.<version>.so.packed | |
74 | |
75 To unpack and restore the shared library to its original state: | |
76 | |
77 cp libchrome.<version>.so.packed unpackable | |
78 relocations_packer -u unpackable | |
79 arm-linux-gnueabi-objcopy \ | |
80 --remove-section=.android.rel.dyn unpackable libchrome.<version>.so | |
81 rm unpackable | |
82 | |
83 | |
84 Bugs & TODOs: | |
85 ------------- | |
86 | |
87 Currently only supports arm32. Support for arm64 requires some extension | |
88 and modification. | |
89 | |
90 Requires two free slots in the .dynamic section. Uses these to add data that | |
91 tells the crazy linker where to find the packed .android.rel.dyn data. Fails | |
92 if insufficient free slots exist (use gold --spare-dynamic-slots to increase | |
93 the allocation). | |
94 | |
95 Requires libelf 0.158 or later. Earlier libelf releases may be buggy in | |
96 ways that prevent the packer from working correctly. | |
97 | |
98 | |
99 Testing: | |
100 -------- | |
101 | |
102 Unittests run under gtest, on the host system. | |
OLD | NEW |