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

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: Update for review feedback Created 6 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 // 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 // Read an .android.rel.dyn ARM packed relocations section.
162 // Returns an allocated buffer holding the data, or NULL on error.
163 uint8_t* ReadArmPackedRelocs(const char* full_path,
164 off_t offset,
165 size_t bytes,
166 Error* error) {
167 uint8_t* packed_data = new uint8_t[bytes];
168
169 FileDescriptor fd;
170 if (!fd.OpenReadOnly(full_path)) {
171 error->Format("Error opening file '%s'", full_path);
172 delete [] packed_data;
173 return NULL;
174 }
175 if (fd.SeekTo(offset) == -1) {
176 error->Format("Error seeking to %d in file '%s'", offset, full_path);
177 delete [] packed_data;
178 return NULL;
179 }
180 const ssize_t bytes_read = fd.Read(packed_data, bytes);
181 if (bytes_read != bytes) {
182 error->Format("Error reading %d bytes from file '%s'", bytes, full_path);
183 delete [] packed_data;
184 return NULL;
185 }
186 fd.Close();
187
188 return packed_data;
189 }
190
191 #endif // __arm__
192
151 } // namespace 193 } // namespace
152 194
153 SharedLibrary::SharedLibrary() { ::memset(this, 0, sizeof(*this)); } 195 SharedLibrary::SharedLibrary() { ::memset(this, 0, sizeof(*this)); }
154 196
155 SharedLibrary::~SharedLibrary() { 197 SharedLibrary::~SharedLibrary() {
156 // Ensure the library is unmapped on destruction. 198 // Ensure the library is unmapped on destruction.
157 if (view_.load_address()) 199 if (view_.load_address())
158 munmap(reinterpret_cast<void*>(view_.load_address()), view_.load_size()); 200 munmap(reinterpret_cast<void*>(view_.load_address()), view_.load_size());
201
202 #ifdef __arm__
203 delete [] arm_packed_relocs_;
rmcilroy 2014/06/19 10:49:44 I think you could still use your ScopedBuffer clas
simonb (inactive) 2014/06/23 14:51:32 Done.
204 #endif
159 } 205 }
160 206
161 bool SharedLibrary::Load(const char* full_path, 207 bool SharedLibrary::Load(const char* full_path,
162 size_t load_address, 208 size_t load_address,
163 size_t file_offset, 209 size_t file_offset,
164 Error* error) { 210 Error* error) {
165 // First, record the path. 211 // First, record the path.
166 LOG("%s: full path '%s'\n", __FUNCTION__, full_path); 212 LOG("%s: full path '%s'\n", __FUNCTION__, full_path);
167 213
168 size_t full_path_len = strlen(full_path); 214 size_t full_path_len = strlen(full_path);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 &relro_start_, 248 &relro_start_,
203 &relro_size_) < 0) { 249 &relro_size_) < 0) {
204 relro_start_ = 0; 250 relro_start_ = 0;
205 relro_size_ = 0; 251 relro_size_ = 0;
206 } 252 }
207 253
208 #ifdef __arm__ 254 #ifdef __arm__
209 LOG("%s: Extracting ARM.exidx table for %s\n", __FUNCTION__, base_name_); 255 LOG("%s: Extracting ARM.exidx table for %s\n", __FUNCTION__, base_name_);
210 (void)phdr_table_get_arm_exidx( 256 (void)phdr_table_get_arm_exidx(
211 phdr(), phdr_count(), load_bias(), &arm_exidx_, &arm_exidx_count_); 257 phdr(), phdr_count(), load_bias(), &arm_exidx_, &arm_exidx_count_);
258
259 off_t arm_packed_relocs_offset = 0;
260 size_t arm_packed_relocs_size = 0;
212 #endif 261 #endif
213 262
214 LOG("%s: Parsing dynamic table for %s\n", __FUNCTION__, base_name_); 263 LOG("%s: Parsing dynamic table for %s\n", __FUNCTION__, base_name_);
215 ElfView::DynamicIterator dyn(&view_); 264 ElfView::DynamicIterator dyn(&view_);
216 for (; dyn.HasNext(); dyn.GetNext()) { 265 for (; dyn.HasNext(); dyn.GetNext()) {
217 ELF::Addr dyn_value = dyn.GetValue(); 266 ELF::Addr dyn_value = dyn.GetValue();
218 uintptr_t dyn_addr = dyn.GetAddress(load_bias()); 267 uintptr_t dyn_addr = dyn.GetAddress(load_bias());
219 switch (dyn.GetTag()) { 268 switch (dyn.GetTag()) {
220 case DT_DEBUG: 269 case DT_DEBUG:
221 if (view_.dynamic_flags() & PF_W) { 270 if (view_.dynamic_flags() & PF_W) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 preinit_array_count_); 311 preinit_array_count_);
263 break; 312 break;
264 case DT_SYMBOLIC: 313 case DT_SYMBOLIC:
265 LOG(" DT_SYMBOLIC\n"); 314 LOG(" DT_SYMBOLIC\n");
266 has_DT_SYMBOLIC_ = true; 315 has_DT_SYMBOLIC_ = true;
267 break; 316 break;
268 case DT_FLAGS: 317 case DT_FLAGS:
269 if (dyn_value & DF_SYMBOLIC) 318 if (dyn_value & DF_SYMBOLIC)
270 has_DT_SYMBOLIC_ = true; 319 has_DT_SYMBOLIC_ = true;
271 break; 320 break;
321 #if defined(__arm__)
322 case DT_ANDROID_ARM_REL_OFFSET:
323 arm_packed_relocs_offset = dyn.GetOffset();
324 LOG(" DT_ANDROID_ARM_REL_OFFSET addr=%p\n", arm_packed_relocs_offset);
325 break;
326 case DT_ANDROID_ARM_REL_SIZE:
327 arm_packed_relocs_size = dyn.GetValue();
328 LOG(" DT_ANDROID_ARM_REL_SIZE=%d\n", arm_packed_relocs_size);
329 break;
330 #endif
272 #if defined(__mips__) 331 #if defined(__mips__)
273 case DT_MIPS_RLD_MAP: 332 case DT_MIPS_RLD_MAP:
274 *dyn.GetValuePointer() = 333 *dyn.GetValuePointer() =
275 reinterpret_cast<ELF::Addr>(Globals::GetRDebug()->GetAddress()); 334 reinterpret_cast<ELF::Addr>(Globals::GetRDebug()->GetAddress());
276 break; 335 break;
277 #endif 336 #endif
278 default: 337 default:
279 ; 338 ;
280 } 339 }
281 } 340 }
282 341
342 #ifdef __arm__
343 // If ARM packed relocations are present in the target library, read the
344 // section data and save it in arm_packed_relocs_.
345 if (arm_packed_relocs_offset && arm_packed_relocs_size) {
346 LOG("%s: ARM packed relocations found at offset %d, %d bytes\n",
347 __FUNCTION__,
348 arm_packed_relocs_offset,
349 arm_packed_relocs_size);
350
351 arm_packed_relocs_ =
352 ReadArmPackedRelocs(full_path,
353 arm_packed_relocs_offset + file_offset,
354 arm_packed_relocs_size,
355 error);
356 if (!arm_packed_relocs_)
357 return false;
358
359 LOG("%s: ARM packed relocations stored at %p\n",
360 __FUNCTION__,
361 arm_packed_relocs_);
362 }
363 #endif
364
283 LOG("%s: Load complete for %s\n", __FUNCTION__, base_name_); 365 LOG("%s: Load complete for %s\n", __FUNCTION__, base_name_);
284 return true; 366 return true;
285 } 367 }
286 368
287 bool SharedLibrary::Relocate(LibraryList* lib_list, 369 bool SharedLibrary::Relocate(LibraryList* lib_list,
288 Vector<LibraryView*>* dependencies, 370 Vector<LibraryView*>* dependencies,
289 Error* error) { 371 Error* error) {
290 // Apply relocations. 372 // Apply relocations.
291 LOG("%s: Applying relocations to %s\n", __FUNCTION__, base_name_); 373 LOG("%s: Applying relocations to %s\n", __FUNCTION__, base_name_);
292 374
293 ElfRelocations relocations; 375 ElfRelocations relocations;
294 376
295 if (!relocations.Init(&view_, error)) 377 if (!relocations.Init(&view_, error))
296 return false; 378 return false;
297 379
298 SharedLibraryResolver resolver(this, lib_list, dependencies); 380 SharedLibraryResolver resolver(this, lib_list, dependencies);
299 if (!relocations.ApplyAll(&symbols_, &resolver, error)) 381 if (!relocations.ApplyAll(&symbols_, &resolver, error))
300 return false; 382 return false;
301 383
384 #ifdef __arm__
385 // If present, also apply ARM packed relocations.
386 if (arm_packed_relocs_ &&
387 !relocations.ApplyArmPackedRelocs(arm_packed_relocs_, error))
388 return false;
rmcilroy 2014/06/19 10:49:43 I'm not sure the PackedRelocs really fits well in
simonb (inactive) 2014/06/23 14:51:32 Addressed by moving ApplyArmPackedRelocs() inside
389 #endif
390
302 LOG("%s: Relocations applied for %s\n", __FUNCTION__, base_name_); 391 LOG("%s: Relocations applied for %s\n", __FUNCTION__, base_name_);
303 return true; 392 return true;
304 } 393 }
305 394
306 const ELF::Sym* SharedLibrary::LookupSymbolEntry(const char* symbol_name) { 395 const ELF::Sym* SharedLibrary::LookupSymbolEntry(const char* symbol_name) {
307 return symbols_.LookupByName(symbol_name); 396 return symbols_.LookupByName(symbol_name);
308 } 397 }
309 398
310 void* SharedLibrary::FindAddressForSymbol(const char* symbol_name) { 399 void* SharedLibrary::FindAddressForSymbol(const char* symbol_name) {
311 return symbols_.LookupAddressByName(symbol_name, view_.load_bias()); 400 return symbols_.LookupAddressByName(symbol_name, view_.load_bias());
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 if (iter_.GetTag() == DT_NEEDED) { 530 if (iter_.GetTag() == DT_NEEDED) {
442 dep_name_ = symbols_->GetStringById(iter_.GetValue()); 531 dep_name_ = symbols_->GetStringById(iter_.GetValue());
443 iter_.GetNext(); 532 iter_.GetNext();
444 return true; 533 return true;
445 } 534 }
446 } 535 }
447 return false; 536 return false;
448 } 537 }
449 538
450 } // namespace crazy 539 } // 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