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

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

Issue 1072533002: crazy linker: convert relocation unpacking to Android style. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updates to gn to match gyp. Created 5 years, 6 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 #ifndef DT_LOOS
62 #define DT_LOOS 0x6000000d
63 #endif
64
65 // Extension dynamic tags for packed relocations.
66 #if defined(__arm__) || defined(__aarch64__)
67
68 #define DT_ANDROID_REL_OFFSET (DT_LOOS)
69 #define DT_ANDROID_REL_SIZE (DT_LOOS + 1)
70
71 #endif // __arm__ || __aarch64__
72
73 namespace crazy { 61 namespace crazy {
74 62
75 namespace { 63 namespace {
76 64
77 typedef SharedLibrary::linker_function_t linker_function_t; 65 typedef SharedLibrary::linker_function_t linker_function_t;
78 typedef int (*JNI_OnLoadFunctionPtr)(void* vm, void* reserved); 66 typedef int (*JNI_OnLoadFunctionPtr)(void* vm, void* reserved);
79 typedef void (*JNI_OnUnloadFunctionPtr)(void* vm, void* reserved); 67 typedef void (*JNI_OnUnloadFunctionPtr)(void* vm, void* reserved);
80 68
81 // Call a constructor or destructor function pointer. Ignore 69 // Call a constructor or destructor function pointer. Ignore
82 // NULL and -1 values intentionally. They correspond to markers 70 // NULL and -1 values intentionally. They correspond to markers
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 175
188 return NULL; 176 return NULL;
189 } 177 }
190 178
191 void* main_program_handle_; 179 void* main_program_handle_;
192 SharedLibrary* lib_; 180 SharedLibrary* lib_;
193 Vector<LibraryView*>* preloads_; 181 Vector<LibraryView*>* preloads_;
194 Vector<LibraryView*>* dependencies_; 182 Vector<LibraryView*>* dependencies_;
195 }; 183 };
196 184
197 #if defined(__arm__) || defined(__aarch64__)
198
199 // Helper class to provide a simple scoped buffer. ScopedPtr is not
200 // usable here because it calls delete, not delete [].
201 class ScopedBuffer {
202 public:
203 explicit ScopedBuffer(size_t bytes) : buffer_(new uint8_t[bytes]) { }
204 ~ScopedBuffer() { delete [] buffer_; }
205
206 uint8_t* Get() { return buffer_; }
207
208 uint8_t* Release() {
209 uint8_t* ptr = buffer_;
210 buffer_ = NULL;
211 return ptr;
212 }
213
214 private:
215 uint8_t* buffer_;
216 };
217
218 // Read an .android.rel.dyn packed relocations section.
219 // Returns an allocated buffer holding the data, or NULL on error.
220 uint8_t* ReadPackedRelocations(const char* full_path,
221 off_t offset,
222 size_t bytes,
223 Error* error) {
224 FileDescriptor fd;
225 if (!fd.OpenReadOnly(full_path)) {
226 error->Format("Error opening file '%s'", full_path);
227 return NULL;
228 }
229 if (fd.SeekTo(offset) == -1) {
230 error->Format("Error seeking to %d in file '%s'", offset, full_path);
231 return NULL;
232 }
233
234 ScopedBuffer buffer(bytes);
235 const ssize_t bytes_read = fd.Read(buffer.Get(), bytes);
236 if (static_cast<size_t>(bytes_read) != bytes) {
237 error->Format("Error reading %d bytes from file '%s'", bytes, full_path);
238 return NULL;
239 }
240 fd.Close();
241
242 uint8_t* packed_data = buffer.Release();
243 return packed_data;
244 }
245
246 #endif // __arm__ || __aarch64__
247
248 } // namespace 185 } // namespace
249 186
250 SharedLibrary::SharedLibrary() { ::memset(this, 0, sizeof(*this)); } 187 SharedLibrary::SharedLibrary() { ::memset(this, 0, sizeof(*this)); }
251 188
252 SharedLibrary::~SharedLibrary() { 189 SharedLibrary::~SharedLibrary() {
253 // Ensure the library is unmapped on destruction. 190 // Ensure the library is unmapped on destruction.
254 if (view_.load_address()) 191 if (view_.load_address())
255 munmap(reinterpret_cast<void*>(view_.load_address()), view_.load_size()); 192 munmap(reinterpret_cast<void*>(view_.load_address()), view_.load_size());
256
257 #if defined(__arm__) || defined(__aarch64__)
258 delete [] packed_relocations_;
259 #endif
260 } 193 }
261 194
262 bool SharedLibrary::Load(const char* full_path, 195 bool SharedLibrary::Load(const char* full_path,
263 size_t load_address, 196 size_t load_address,
264 size_t file_offset, 197 size_t file_offset,
265 Error* error) { 198 Error* error) {
266 // First, record the path. 199 // First, record the path.
267 LOG("%s: full path '%s'\n", __FUNCTION__, full_path); 200 LOG("%s: full path '%s'\n", __FUNCTION__, full_path);
268 201
269 size_t full_path_len = strlen(full_path); 202 size_t full_path_len = strlen(full_path);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 relro_start_ = 0; 238 relro_start_ = 0;
306 relro_size_ = 0; 239 relro_size_ = 0;
307 } 240 }
308 241
309 #ifdef __arm__ 242 #ifdef __arm__
310 LOG("%s: Extracting ARM.exidx table for %s\n", __FUNCTION__, base_name_); 243 LOG("%s: Extracting ARM.exidx table for %s\n", __FUNCTION__, base_name_);
311 (void)phdr_table_get_arm_exidx( 244 (void)phdr_table_get_arm_exidx(
312 phdr(), phdr_count(), load_bias(), &arm_exidx_, &arm_exidx_count_); 245 phdr(), phdr_count(), load_bias(), &arm_exidx_, &arm_exidx_count_);
313 #endif 246 #endif
314 247
315 #if defined(__arm__) || defined(__aarch64__)
316 off_t packed_relocations_offset = 0;
317 size_t packed_relocations_size = 0;
318 #endif
319
320 LOG("%s: Parsing dynamic table for %s\n", __FUNCTION__, base_name_); 248 LOG("%s: Parsing dynamic table for %s\n", __FUNCTION__, base_name_);
321 ElfView::DynamicIterator dyn(&view_); 249 ElfView::DynamicIterator dyn(&view_);
322 for (; dyn.HasNext(); dyn.GetNext()) { 250 for (; dyn.HasNext(); dyn.GetNext()) {
323 ELF::Addr dyn_value = dyn.GetValue(); 251 ELF::Addr dyn_value = dyn.GetValue();
324 uintptr_t dyn_addr = dyn.GetAddress(load_bias()); 252 uintptr_t dyn_addr = dyn.GetAddress(load_bias());
325 switch (dyn.GetTag()) { 253 switch (dyn.GetTag()) {
326 case DT_DEBUG: 254 case DT_DEBUG:
327 if (view_.dynamic_flags() & PF_W) { 255 if (view_.dynamic_flags() & PF_W) {
328 *dyn.GetValuePointer() = 256 *dyn.GetValuePointer() =
329 reinterpret_cast<uintptr_t>(Globals::GetRDebug()->GetAddress()); 257 reinterpret_cast<uintptr_t>(Globals::GetRDebug()->GetAddress());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 preinit_array_count_); 296 preinit_array_count_);
369 break; 297 break;
370 case DT_SYMBOLIC: 298 case DT_SYMBOLIC:
371 LOG(" DT_SYMBOLIC\n"); 299 LOG(" DT_SYMBOLIC\n");
372 has_DT_SYMBOLIC_ = true; 300 has_DT_SYMBOLIC_ = true;
373 break; 301 break;
374 case DT_FLAGS: 302 case DT_FLAGS:
375 if (dyn_value & DF_SYMBOLIC) 303 if (dyn_value & DF_SYMBOLIC)
376 has_DT_SYMBOLIC_ = true; 304 has_DT_SYMBOLIC_ = true;
377 break; 305 break;
378 #if defined(__arm__) || defined(__aarch64__)
379 case DT_ANDROID_REL_OFFSET:
380 packed_relocations_offset = dyn.GetOffset();
381 LOG(" DT_ANDROID_REL_OFFSET addr=%p\n", packed_relocations_offset);
382 break;
383 case DT_ANDROID_REL_SIZE:
384 packed_relocations_size = dyn.GetValue();
385 LOG(" DT_ANDROID_REL_SIZE=%d\n", packed_relocations_size);
386 break;
387 #endif
388 #if defined(__mips__) 306 #if defined(__mips__)
389 case DT_MIPS_RLD_MAP: 307 case DT_MIPS_RLD_MAP:
390 *dyn.GetValuePointer() = 308 *dyn.GetValuePointer() =
391 reinterpret_cast<ELF::Addr>(Globals::GetRDebug()->GetAddress()); 309 reinterpret_cast<ELF::Addr>(Globals::GetRDebug()->GetAddress());
392 break; 310 break;
393 #endif 311 #endif
394 default: 312 default:
395 ; 313 ;
396 } 314 }
397 } 315 }
398 316
399 #if defined(__arm__) || defined(__aarch64__)
400 // If packed relocations are present in the target library, read the
401 // section data and save it in packed_relocations_.
402 if (packed_relocations_offset && packed_relocations_size) {
403 LOG("%s: Packed relocations found at offset %d, %d bytes\n",
404 __FUNCTION__,
405 packed_relocations_offset,
406 packed_relocations_size);
407
408 packed_relocations_ =
409 ReadPackedRelocations(full_path,
410 packed_relocations_offset + file_offset,
411 packed_relocations_size,
412 error);
413 if (!packed_relocations_)
414 return false;
415
416 LOG("%s: Packed relocations stored at %p\n",
417 __FUNCTION__,
418 packed_relocations_);
419
420 // Add packed relocations to the view.
421 view_.RegisterPackedRelocations(packed_relocations_);
422 }
423 #endif
424
425 LOG("%s: Load complete for %s\n", __FUNCTION__, base_name_); 317 LOG("%s: Load complete for %s\n", __FUNCTION__, base_name_);
426 return true; 318 return true;
427 } 319 }
428 320
429 bool SharedLibrary::Relocate(LibraryList* lib_list, 321 bool SharedLibrary::Relocate(LibraryList* lib_list,
430 Vector<LibraryView*>* preloads, 322 Vector<LibraryView*>* preloads,
431 Vector<LibraryView*>* dependencies, 323 Vector<LibraryView*>* dependencies,
432 Error* error) { 324 Error* error) {
433 // Apply relocations. 325 // Apply relocations.
434 LOG("%s: Applying relocations to %s\n", __FUNCTION__, base_name_); 326 LOG("%s: Applying relocations to %s\n", __FUNCTION__, base_name_);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 if (iter_.GetTag() == DT_NEEDED) { 476 if (iter_.GetTag() == DT_NEEDED) {
585 dep_name_ = symbols_->GetStringById(iter_.GetValue()); 477 dep_name_ = symbols_->GetStringById(iter_.GetValue());
586 iter_.GetNext(); 478 iter_.GetNext();
587 return true; 479 return true;
588 } 480 }
589 } 481 }
590 return false; 482 return false;
591 } 483 }
592 484
593 } // namespace crazy 485 } // 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