OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Tool to pack and unpack R_ARM_RELATIVE relocations in a shared library. | 5 // Tool to pack and unpack ARM relative relocations in a shared library. |
6 // | 6 // |
7 // Packing removes R_ARM_RELATIVE relocations from .rel.dyn and writes them | 7 // Packing removes ARM relative relocations from .rel.dyn and writes them |
8 // in a more compact form to .android.rel.dyn. Unpacking does the reverse. | 8 // in a more compact form to .android.rel.dyn. Unpacking does the reverse. |
9 // | 9 // |
10 // Invoke with -v to trace actions taken when packing or unpacking. | 10 // Invoke with -v to trace actions taken when packing or unpacking. |
11 // Invoke with -p to pad removed relocations with R_ARM_NONE. Suppresses | 11 // Invoke with -p to pad removed relocations with R_*_NONE. Suppresses |
12 // shrinking of .rel.dyn. | 12 // shrinking of .rel.dyn. |
13 // See PrintUsage() below for full usage details. | 13 // See PrintUsage() below for full usage details. |
14 // | 14 // |
15 // NOTE: Breaks with libelf 0.152, which is buggy. libelf 0.158 works. | 15 // NOTE: Breaks with libelf 0.152, which is buggy. libelf 0.158 works. |
16 | 16 |
17 // TODO(simonb): Extend for 64-bit target libraries. | |
18 | |
19 #include <errno.h> | 17 #include <errno.h> |
20 #include <fcntl.h> | 18 #include <fcntl.h> |
21 #include <getopt.h> | 19 #include <getopt.h> |
22 #include <stdio.h> | 20 #include <stdio.h> |
23 #include <stdlib.h> | 21 #include <stdlib.h> |
24 #include <string.h> | |
25 #include <sys/types.h> | 22 #include <sys/types.h> |
26 #include <unistd.h> | 23 #include <unistd.h> |
27 #include <string> | 24 #include <string> |
28 | 25 |
29 #include "debug.h" | 26 #include "debug.h" |
30 #include "elf_file.h" | 27 #include "elf_file.h" |
31 #include "libelf.h" | 28 #include "libelf.h" |
32 | 29 |
33 namespace { | 30 namespace { |
34 | 31 |
35 void PrintUsage(const char* argv0) { | 32 void PrintUsage(const char* argv0) { |
36 std::string temporary = argv0; | 33 std::string temporary = argv0; |
37 const size_t last_slash = temporary.find_last_of("/"); | 34 const size_t last_slash = temporary.find_last_of("/"); |
38 if (last_slash != temporary.npos) { | 35 if (last_slash != temporary.npos) { |
39 temporary.erase(0, last_slash + 1); | 36 temporary.erase(0, last_slash + 1); |
40 } | 37 } |
41 const char* basename = temporary.c_str(); | 38 const char* basename = temporary.c_str(); |
42 | 39 |
43 printf( | 40 printf( |
44 "Usage: %s [-u] [-v] [-p] file\n" | 41 "Usage: %s [-u] [-v] [-p] file\n" |
45 "Pack or unpack R_ARM_RELATIVE relocations in a shared library.\n\n" | 42 "Pack or unpack ARM relative relocations in a shared library.\n\n" |
46 " -u, --unpack unpack previously packed R_ARM_RELATIVE relocations\n" | 43 " -u, --unpack unpack previously packed ARM relative relocations\n" |
47 " -v, --verbose trace object file modifications (for debugging)\n" | 44 " -v, --verbose trace object file modifications (for debugging)\n" |
48 " -p, --pad do not shrink .rel.dyn, but pad (for debugging)\n\n" | 45 " -p, --pad do not shrink .rel.dyn, but pad (for debugging)\n\n" |
49 "Extracts R_ARM_RELATIVE relocations from the .rel.dyn section, packs\n" | 46 "Extracts ARM relative relocations from the .rel.dyn section, packs\n" |
50 "them into a more compact format, and stores the packed relocations in\n" | 47 "them into a more compact format, and stores the packed relocations in\n" |
51 ".android.rel.dyn. Expands .android.rel.dyn to hold the packed data,\n" | 48 ".android.rel.dyn. Expands .android.rel.dyn to hold the packed data,\n" |
52 "and shrinks .rel.dyn by the amount of unpacked data removed from it.\n\n" | 49 "and shrinks .rel.dyn by the amount of unpacked data removed from it.\n\n" |
53 "Before being packed, a shared library needs to be prepared by adding\n" | 50 "Before being packed, a shared library needs to be prepared by adding\n" |
54 "a null .android.rel.dyn section. A complete packing process is:\n\n" | 51 "a null .android.rel.dyn section. A complete packing process is:\n\n" |
55 " echo -n 'NULL' >/tmp/small\n" | 52 " echo -n 'NULL' >/tmp/small\n" |
56 " arm-linux-gnueabi-objcopy \\\n" | 53 " arm-linux-gnueabi-objcopy \\\n" |
57 " --add-section .android.rel.dyn=/tmp/small \\\n" | 54 " --add-section .android.rel.dyn=/tmp/small \\\n" |
58 " libchrome.<version>.so\n" | 55 " libchrome.<version>.so\n" |
59 " rm /tmp/small\n" | 56 " rm /tmp/small\n" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 } | 103 } |
107 if (optind != argc - 1) { | 104 if (optind != argc - 1) { |
108 LOG(INFO) << "Try '" << argv[0] << " --help' for more information."; | 105 LOG(INFO) << "Try '" << argv[0] << " --help' for more information."; |
109 return 1; | 106 return 1; |
110 } | 107 } |
111 | 108 |
112 if (elf_version(EV_CURRENT) == EV_NONE) { | 109 if (elf_version(EV_CURRENT) == EV_NONE) { |
113 LOG(WARNING) << "Elf Library is out of date!"; | 110 LOG(WARNING) << "Elf Library is out of date!"; |
114 } | 111 } |
115 | 112 |
| 113 LOG(INFO) << "Configured for " << ELF::Machine(); |
| 114 |
116 const char* file = argv[argc - 1]; | 115 const char* file = argv[argc - 1]; |
117 const int fd = open(file, O_RDWR); | 116 const int fd = open(file, O_RDWR); |
118 if (fd == -1) { | 117 if (fd == -1) { |
119 LOG(ERROR) << file << ": " << strerror(errno); | 118 LOG(ERROR) << file << ": " << strerror(errno); |
120 return 1; | 119 return 1; |
121 } | 120 } |
122 | 121 |
123 if (is_verbose) | 122 if (is_verbose) |
124 relocation_packer::Logger::SetVerbose(1); | 123 relocation_packer::Logger::SetVerbose(1); |
125 | 124 |
126 relocation_packer::ElfFile elf_file(fd); | 125 relocation_packer::ElfFile elf_file(fd); |
127 elf_file.SetPadding(is_padding); | 126 elf_file.SetPadding(is_padding); |
128 | 127 |
129 bool status; | 128 bool status; |
130 if (is_unpacking) | 129 if (is_unpacking) |
131 status = elf_file.UnpackRelocations(); | 130 status = elf_file.UnpackRelocations(); |
132 else | 131 else |
133 status = elf_file.PackRelocations(); | 132 status = elf_file.PackRelocations(); |
134 | 133 |
135 close(fd); | 134 close(fd); |
136 | 135 |
137 if (!status) { | 136 if (!status) { |
138 LOG(ERROR) << file << ": failed to pack/unpack file"; | 137 LOG(ERROR) << file << ": failed to pack/unpack file"; |
139 return 1; | 138 return 1; |
140 } | 139 } |
141 | 140 |
142 return 0; | 141 return 0; |
143 } | 142 } |
OLD | NEW |