Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(368)

Side by Side Diff: third_party/android_platform/bionic/tools/relocation_packer/src/main.cc

Issue 1027823002: Port Android relocation packer to chromium build (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed two nugatory files Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 relative relocations in a shared library. 5 // Tool to pack and unpack relative relocations in a shared library.
6 // 6 //
7 // Packing removes relative relocations from .rel.dyn and writes them 7 // Packing removes 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_*_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 #include <errno.h> 17 #include <errno.h>
18 #include <fcntl.h> 18 #include <fcntl.h>
19 #include <getopt.h> 19 #include <getopt.h>
20 #include <stdio.h> 20 #include <stdio.h>
21 #include <stdlib.h> 21 #include <stdlib.h>
22 #include <sys/types.h> 22 #include <sys/types.h>
23 #include <unistd.h> 23 #include <unistd.h>
24 #include <string> 24 #include <string>
25 25
26 #include "debug.h" 26 #include "debug.h"
27 #include "elf_file.h" 27 #include "elf_file.h"
28 #include "elf_traits.h"
28 #include "libelf.h" 29 #include "libelf.h"
29 30
30 namespace { 31 #include "nativehelper/ScopedFd.h"
31 32
32 void PrintUsage(const char* argv0) { 33 static void PrintUsage(const char* argv0) {
33 std::string temporary = argv0; 34 std::string temporary = argv0;
34 const size_t last_slash = temporary.find_last_of("/"); 35 const size_t last_slash = temporary.find_last_of("/");
35 if (last_slash != temporary.npos) { 36 if (last_slash != temporary.npos) {
36 temporary.erase(0, last_slash + 1); 37 temporary.erase(0, last_slash + 1);
37 } 38 }
38 const char* basename = temporary.c_str(); 39 const char* basename = temporary.c_str();
39 40
40 printf( 41 printf(
41 "Usage: %s [-u] [-v] [-p] file\n\n" 42 "Usage: %s [-u] [-v] [-p] file\n\n"
42 "Pack or unpack relative relocations in a shared library.\n\n" 43 "Pack or unpack relative relocations in a shared library.\n\n"
43 " -u, --unpack unpack previously packed relative relocations\n" 44 " -u, --unpack unpack previously packed relative relocations\n"
44 " -v, --verbose trace object file modifications (for debugging)\n" 45 " -v, --verbose trace object file modifications (for debugging)\n"
45 " -p, --pad do not shrink relocations, but pad (for debugging)\n\n", 46 " -p, --pad do not shrink relocations, but pad (for debugging)\n\n",
46 basename); 47 basename);
47 48
48 if (ELF::kMachine == EM_ARM) {
49 printf(
50 "Extracts relative relocations from the .rel.dyn section, packs them\n"
51 "into a more compact format, and stores the packed relocations in\n"
52 ".android.rel.dyn. Expands .android.rel.dyn to hold the packed\n"
53 "data, and shrinks .rel.dyn by the amount of unpacked data removed\n"
54 "from it.\n\n"
55 "Before being packed, a shared library needs to be prepared by adding\n"
56 "a null .android.rel.dyn section.\n\n"
57 "To pack relocations in a shared library:\n\n"
58 " echo -n 'NULL' >/tmp/small\n"
59 " arm-linux-androideabi-objcopy \\\n"
60 " --add-section .android.rel.dyn=/tmp/small \\\n"
61 " libchrome.<version>.so\n"
62 " rm /tmp/small\n"
63 " %s libchrome.<version>.so\n\n"
64 "To unpack and restore the shared library to its original state:\n\n"
65 " %s -u libchrome.<version>.so\n"
66 " arm-linux-androideabi-objcopy \\\n"
67 " --remove-section=.android.rel.dyn libchrome.<version>.so\n\n",
68 basename, basename);
69 } else if (ELF::kMachine == EM_AARCH64) {
70 printf(
71 "Extracts relative relocations from the .rela.dyn section, packs them\n"
72 "into a more compact format, and stores the packed relocations in\n"
73 ".android.rela.dyn. Expands .android.rela.dyn to hold the packed\n"
74 "data, and shrinks .rela.dyn by the amount of unpacked data removed\n"
75 "from it.\n\n"
76 "Before being packed, a shared library needs to be prepared by adding\n"
77 "a null .android.rela.dyn section.\n\n"
78 "To pack relocations in a shared library:\n\n"
79 " echo -n 'NULL' >/tmp/small\n"
80 " aarch64-linux-android-objcopy \\\n"
81 " --add-section .android.rela.dyn=/tmp/small \\\n"
82 " libchrome.<version>.so\n"
83 " rm /tmp/small\n"
84 " %s libchrome.<version>.so\n\n"
85 "To unpack and restore the shared library to its original state:\n\n"
86 " %s -u libchrome.<version>.so\n"
87 " aarch64-linux-android-objcopy \\\n"
88 " --remove-section=.android.rela.dyn libchrome.<version>.so\n\n",
89 basename, basename);
90 } else {
91 NOTREACHED();
92 }
93
94 printf( 49 printf(
95 "Debug sections are not handled, so packing should not be used on\n" 50 "Debug sections are not handled, so packing should not be used on\n"
96 "shared libraries compiled for debugging or otherwise unstripped.\n"); 51 "shared libraries compiled for debugging or otherwise unstripped.\n");
97 } 52 }
98 53
99 } // namespace
100
101 int main(int argc, char* argv[]) { 54 int main(int argc, char* argv[]) {
102 bool is_unpacking = false; 55 bool is_unpacking = false;
103 bool is_verbose = false; 56 bool is_verbose = false;
104 bool is_padding = false; 57 bool is_padding = false;
105 58
106 static const option options[] = { 59 static const option options[] = {
107 {"unpack", 0, 0, 'u'}, {"verbose", 0, 0, 'v'}, {"pad", 0, 0, 'p'}, 60 {"unpack", 0, 0, 'u'}, {"verbose", 0, 0, 'v'}, {"pad", 0, 0, 'p'},
108 {"help", 0, 0, 'h'}, {NULL, 0, 0, 0} 61 {"help", 0, 0, 'h'}, {NULL, 0, 0, 0}
109 }; 62 };
110 bool has_options = true; 63 bool has_options = true;
(...skipping 25 matching lines...) Expand all
136 } 89 }
137 if (optind != argc - 1) { 90 if (optind != argc - 1) {
138 LOG(INFO) << "Try '" << argv[0] << " --help' for more information."; 91 LOG(INFO) << "Try '" << argv[0] << " --help' for more information.";
139 return 1; 92 return 1;
140 } 93 }
141 94
142 if (elf_version(EV_CURRENT) == EV_NONE) { 95 if (elf_version(EV_CURRENT) == EV_NONE) {
143 LOG(WARNING) << "Elf Library is out of date!"; 96 LOG(WARNING) << "Elf Library is out of date!";
144 } 97 }
145 98
146 LOG(INFO) << "Configured for " << ELF::Machine();
147
148 const char* file = argv[argc - 1]; 99 const char* file = argv[argc - 1];
149 const int fd = open(file, O_RDWR); 100 ScopedFd fd(open(file, O_RDWR));
150 if (fd == -1) { 101 if (fd.get() == -1) {
151 LOG(ERROR) << file << ": " << strerror(errno); 102 LOG(ERROR) << file << ": " << strerror(errno);
152 return 1; 103 return 1;
153 } 104 }
154 105
155 if (is_verbose) 106 if (is_verbose)
156 relocation_packer::Logger::SetVerbose(1); 107 relocation_packer::Logger::SetVerbose(1);
157 108
158 relocation_packer::ElfFile elf_file(fd); 109 // We need to detect elf class in order to create
159 elf_file.SetPadding(is_padding); 110 // correct implementation
111 uint8_t e_ident[EI_NIDENT];
112 if (TEMP_FAILURE_RETRY(read(fd.get(), e_ident, EI_NIDENT) != EI_NIDENT)) {
113 LOG(ERROR) << file << ": failed to read elf header:" << strerror(errno);
114 return 1;
115 }
160 116
161 bool status; 117 if (TEMP_FAILURE_RETRY(lseek(fd.get(), 0, SEEK_SET)) != 0) {
162 if (is_unpacking) 118 LOG(ERROR) << file << ": lseek to 0 failed:" << strerror(errno);
163 status = elf_file.UnpackRelocations(); 119 return 1;
164 else 120 }
165 status = elf_file.PackRelocations();
166 121
167 close(fd); 122 bool status = false;
123
124 if (e_ident[EI_CLASS] == ELFCLASS32) {
125 relocation_packer::ElfFile<ELF32_traits> elf_file(fd.get());
126 elf_file.SetPadding(is_padding);
127
128 if (is_unpacking) {
129 status = elf_file.UnpackRelocations();
130 } else {
131 status = elf_file.PackRelocations();
132 }
133 } else if (e_ident[EI_CLASS] == ELFCLASS64) {
134 relocation_packer::ElfFile<ELF64_traits> elf_file(fd.get());
135 elf_file.SetPadding(is_padding);
136
137 if (is_unpacking) {
138 status = elf_file.UnpackRelocations();
139 } else {
140 status = elf_file.PackRelocations();
141 }
142 } else {
143 LOG(ERROR) << file << ": unknown ELFCLASS: " << e_ident[EI_CLASS];
144 return 1;
145 }
168 146
169 if (!status) { 147 if (!status) {
170 LOG(ERROR) << file << ": failed to pack/unpack file"; 148 LOG(ERROR) << file << ": failed to pack/unpack file";
171 return 1; 149 return 1;
172 } 150 }
173 151
174 return 0; 152 return 0;
175 } 153 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698