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

Side by Side Diff: third_party/android_crazy_linker/src/src/crazy_linker_shared_library.cpp

Issue 340523003: Support for unpacked ARM packed relocations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fork_switch
Patch Set: Another review update Created 6 years, 5 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
« no previous file with comments | « third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "crazy_linker_shared_library.h" 5 #include "crazy_linker_shared_library.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <sys/mman.h> 9 #include <sys/mman.h>
10 #include <elf.h> 10 #include <elf.h>
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #endif 51 #endif
52 52
53 #ifndef DT_PREINIT_ARRAY 53 #ifndef DT_PREINIT_ARRAY
54 #define DT_PREINIT_ARRAY 32 54 #define DT_PREINIT_ARRAY 32
55 #endif 55 #endif
56 56
57 #ifndef DT_PREINIT_ARRAYSZ 57 #ifndef DT_PREINIT_ARRAYSZ
58 #define DT_PREINIT_ARRAYSZ 33 58 #define DT_PREINIT_ARRAYSZ 33
59 #endif 59 #endif
60 60
61 // Processor-specific extension dynamic tags for packed relocations.
62 #ifdef __arm__
63
64 #define DT_ANDROID_ARM_REL_OFFSET (DT_LOPROC)
65 #define DT_ANDROID_ARM_REL_SIZE (DT_LOPROC + 1)
66
67 #endif // __arm__
68
61 namespace crazy { 69 namespace crazy {
62 70
63 namespace { 71 namespace {
64 72
65 typedef SharedLibrary::linker_function_t linker_function_t; 73 typedef SharedLibrary::linker_function_t linker_function_t;
66 typedef int (*JNI_OnLoadFunctionPtr)(void* vm, void* reserved); 74 typedef int (*JNI_OnLoadFunctionPtr)(void* vm, void* reserved);
67 typedef void (*JNI_OnUnloadFunctionPtr)(void* vm, void* reserved); 75 typedef void (*JNI_OnUnloadFunctionPtr)(void* vm, void* reserved);
68 76
69 // Call a constructor or destructor function pointer. Ignore 77 // Call a constructor or destructor function pointer. Ignore
70 // NULL and -1 values intentionally. They correspond to markers 78 // NULL and -1 values intentionally. They correspond to markers
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 149
142 // Nothing found here. 150 // Nothing found here.
143 return NULL; 151 return NULL;
144 } 152 }
145 153
146 private: 154 private:
147 SharedLibrary* lib_; 155 SharedLibrary* lib_;
148 Vector<LibraryView*>* dependencies_; 156 Vector<LibraryView*>* dependencies_;
149 }; 157 };
150 158
159 #ifdef __arm__
160
161 // Helper class to provide a simple scoped buffer. ScopedPtr is not
162 // usable here because it calls delete, not delete [].
163 class ScopedBuffer {
164 public:
165 explicit ScopedBuffer(size_t bytes) : buffer_(new uint8_t[bytes]) { }
166 ~ScopedBuffer() { delete [] buffer_; }
167
168 uint8_t* Get() { return buffer_; }
169
170 uint8_t* Release() {
171 uint8_t* ptr = buffer_;
172 buffer_ = NULL;
173 return ptr;
174 }
175
176 private:
177 uint8_t* buffer_;
178 };
179
180 // Read an .android.rel.dyn ARM packed relocations section.
181 // Returns an allocated buffer holding the data, or NULL on error.
182 uint8_t* ReadArmPackedRelocs(const char* full_path,
183 off_t offset,
184 size_t bytes,
185 Error* error) {
186 FileDescriptor fd;
187 if (!fd.OpenReadOnly(full_path)) {
188 error->Format("Error opening file '%s'", full_path);
189 return NULL;
190 }
191 if (fd.SeekTo(offset) == -1) {
192 error->Format("Error seeking to %d in file '%s'", offset, full_path);
193 return NULL;
194 }
195
196 ScopedBuffer buffer(bytes);
197 const ssize_t bytes_read = fd.Read(buffer.Get(), bytes);
198 if (bytes_read != bytes) {
199 error->Format("Error reading %d bytes from file '%s'", bytes, full_path);
200 return NULL;
201 }
202 fd.Close();
203
204 uint8_t* packed_data = buffer.Release();
205 return packed_data;
206 }
207
208 #endif // __arm__
209
151 } // namespace 210 } // namespace
152 211
153 SharedLibrary::SharedLibrary() { ::memset(this, 0, sizeof(*this)); } 212 SharedLibrary::SharedLibrary() { ::memset(this, 0, sizeof(*this)); }
154 213
155 SharedLibrary::~SharedLibrary() { 214 SharedLibrary::~SharedLibrary() {
156 // Ensure the library is unmapped on destruction. 215 // Ensure the library is unmapped on destruction.
157 if (view_.load_address()) 216 if (view_.load_address())
158 munmap(reinterpret_cast<void*>(view_.load_address()), view_.load_size()); 217 munmap(reinterpret_cast<void*>(view_.load_address()), view_.load_size());
218
219 #ifdef __arm__
220 delete [] arm_packed_relocs_;
221 #endif
159 } 222 }
160 223
161 bool SharedLibrary::Load(const char* full_path, 224 bool SharedLibrary::Load(const char* full_path,
162 size_t load_address, 225 size_t load_address,
163 size_t file_offset, 226 size_t file_offset,
164 Error* error) { 227 Error* error) {
165 // First, record the path. 228 // First, record the path.
166 LOG("%s: full path '%s'\n", __FUNCTION__, full_path); 229 LOG("%s: full path '%s'\n", __FUNCTION__, full_path);
167 230
168 size_t full_path_len = strlen(full_path); 231 size_t full_path_len = strlen(full_path);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 &relro_start_, 265 &relro_start_,
203 &relro_size_) < 0) { 266 &relro_size_) < 0) {
204 relro_start_ = 0; 267 relro_start_ = 0;
205 relro_size_ = 0; 268 relro_size_ = 0;
206 } 269 }
207 270
208 #ifdef __arm__ 271 #ifdef __arm__
209 LOG("%s: Extracting ARM.exidx table for %s\n", __FUNCTION__, base_name_); 272 LOG("%s: Extracting ARM.exidx table for %s\n", __FUNCTION__, base_name_);
210 (void)phdr_table_get_arm_exidx( 273 (void)phdr_table_get_arm_exidx(
211 phdr(), phdr_count(), load_bias(), &arm_exidx_, &arm_exidx_count_); 274 phdr(), phdr_count(), load_bias(), &arm_exidx_, &arm_exidx_count_);
275
276 off_t arm_packed_relocs_offset = 0;
277 size_t arm_packed_relocs_size = 0;
212 #endif 278 #endif
213 279
214 LOG("%s: Parsing dynamic table for %s\n", __FUNCTION__, base_name_); 280 LOG("%s: Parsing dynamic table for %s\n", __FUNCTION__, base_name_);
215 ElfView::DynamicIterator dyn(&view_); 281 ElfView::DynamicIterator dyn(&view_);
216 for (; dyn.HasNext(); dyn.GetNext()) { 282 for (; dyn.HasNext(); dyn.GetNext()) {
217 ELF::Addr dyn_value = dyn.GetValue(); 283 ELF::Addr dyn_value = dyn.GetValue();
218 uintptr_t dyn_addr = dyn.GetAddress(load_bias()); 284 uintptr_t dyn_addr = dyn.GetAddress(load_bias());
219 switch (dyn.GetTag()) { 285 switch (dyn.GetTag()) {
220 case DT_DEBUG: 286 case DT_DEBUG:
221 if (view_.dynamic_flags() & PF_W) { 287 if (view_.dynamic_flags() & PF_W) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 preinit_array_count_); 328 preinit_array_count_);
263 break; 329 break;
264 case DT_SYMBOLIC: 330 case DT_SYMBOLIC:
265 LOG(" DT_SYMBOLIC\n"); 331 LOG(" DT_SYMBOLIC\n");
266 has_DT_SYMBOLIC_ = true; 332 has_DT_SYMBOLIC_ = true;
267 break; 333 break;
268 case DT_FLAGS: 334 case DT_FLAGS:
269 if (dyn_value & DF_SYMBOLIC) 335 if (dyn_value & DF_SYMBOLIC)
270 has_DT_SYMBOLIC_ = true; 336 has_DT_SYMBOLIC_ = true;
271 break; 337 break;
338 #if defined(__arm__)
339 case DT_ANDROID_ARM_REL_OFFSET:
340 arm_packed_relocs_offset = dyn.GetOffset();
341 LOG(" DT_ANDROID_ARM_REL_OFFSET addr=%p\n", arm_packed_relocs_offset);
342 break;
343 case DT_ANDROID_ARM_REL_SIZE:
344 arm_packed_relocs_size = dyn.GetValue();
345 LOG(" DT_ANDROID_ARM_REL_SIZE=%d\n", arm_packed_relocs_size);
346 break;
347 #endif
272 #if defined(__mips__) 348 #if defined(__mips__)
273 case DT_MIPS_RLD_MAP: 349 case DT_MIPS_RLD_MAP:
274 *dyn.GetValuePointer() = 350 *dyn.GetValuePointer() =
275 reinterpret_cast<ELF::Addr>(Globals::GetRDebug()->GetAddress()); 351 reinterpret_cast<ELF::Addr>(Globals::GetRDebug()->GetAddress());
276 break; 352 break;
277 #endif 353 #endif
278 default: 354 default:
279 ; 355 ;
280 } 356 }
281 } 357 }
282 358
359 #ifdef __arm__
360 // If ARM packed relocations are present in the target library, read the
361 // section data and save it in arm_packed_relocs_.
362 if (arm_packed_relocs_offset && arm_packed_relocs_size) {
363 LOG("%s: ARM packed relocations found at offset %d, %d bytes\n",
364 __FUNCTION__,
365 arm_packed_relocs_offset,
366 arm_packed_relocs_size);
367
368 arm_packed_relocs_ =
369 ReadArmPackedRelocs(full_path,
370 arm_packed_relocs_offset + file_offset,
371 arm_packed_relocs_size,
372 error);
373 if (!arm_packed_relocs_)
374 return false;
375
376 LOG("%s: ARM packed relocations stored at %p\n",
377 __FUNCTION__,
378 arm_packed_relocs_);
379 }
380 #endif
381
283 LOG("%s: Load complete for %s\n", __FUNCTION__, base_name_); 382 LOG("%s: Load complete for %s\n", __FUNCTION__, base_name_);
284 return true; 383 return true;
285 } 384 }
286 385
287 bool SharedLibrary::Relocate(LibraryList* lib_list, 386 bool SharedLibrary::Relocate(LibraryList* lib_list,
288 Vector<LibraryView*>* dependencies, 387 Vector<LibraryView*>* dependencies,
289 Error* error) { 388 Error* error) {
290 // Apply relocations. 389 // Apply relocations.
291 LOG("%s: Applying relocations to %s\n", __FUNCTION__, base_name_); 390 LOG("%s: Applying relocations to %s\n", __FUNCTION__, base_name_);
292 391
293 ElfRelocations relocations; 392 ElfRelocations relocations;
294 393
295 if (!relocations.Init(&view_, error)) 394 if (!relocations.Init(&view_, error))
296 return false; 395 return false;
297 396
397 #ifdef __arm__
398 relocations.RegisterArmPackedRelocs(arm_packed_relocs_);
399 #endif
400
298 SharedLibraryResolver resolver(this, lib_list, dependencies); 401 SharedLibraryResolver resolver(this, lib_list, dependencies);
299 if (!relocations.ApplyAll(&symbols_, &resolver, error)) 402 if (!relocations.ApplyAll(&symbols_, &resolver, error))
300 return false; 403 return false;
301 404
302 LOG("%s: Relocations applied for %s\n", __FUNCTION__, base_name_); 405 LOG("%s: Relocations applied for %s\n", __FUNCTION__, base_name_);
303 return true; 406 return true;
304 } 407 }
305 408
306 const ELF::Sym* SharedLibrary::LookupSymbolEntry(const char* symbol_name) { 409 const ELF::Sym* SharedLibrary::LookupSymbolEntry(const char* symbol_name) {
307 return symbols_.LookupByName(symbol_name); 410 return symbols_.LookupByName(symbol_name);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 if (iter_.GetTag() == DT_NEEDED) { 544 if (iter_.GetTag() == DT_NEEDED) {
442 dep_name_ = symbols_->GetStringById(iter_.GetValue()); 545 dep_name_ = symbols_->GetStringById(iter_.GetValue());
443 iter_.GetNext(); 546 iter_.GetNext();
444 return true; 547 return true;
445 } 548 }
446 } 549 }
447 return false; 550 return false;
448 } 551 }
449 552
450 } // namespace crazy 553 } // namespace crazy
OLDNEW
« no previous file with comments | « third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698