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

Side by Side Diff: third_party/android_crazy_linker/src/src/crazy_linker_elf_relocations.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
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_elf_relocations.h" 5 #include "crazy_linker_elf_relocations.h"
6 6
7 #include <assert.h>
7 #include <errno.h> 8 #include <errno.h>
8 9
9 #include "crazy_linker_debug.h" 10 #include "crazy_linker_debug.h"
10 #include "crazy_linker_elf_symbols.h" 11 #include "crazy_linker_elf_symbols.h"
11 #include "crazy_linker_elf_view.h" 12 #include "crazy_linker_elf_view.h"
12 #include "crazy_linker_error.h" 13 #include "crazy_linker_error.h"
13 #include "crazy_linker_leb128.h" 14 #include "crazy_linker_leb128.h"
14 #include "crazy_linker_system.h" 15 #include "crazy_linker_system.h"
15 #include "crazy_linker_util.h" 16 #include "crazy_linker_util.h"
16 #include "linker_phdr.h" 17 #include "linker_phdr.h"
17 18
18 #define DEBUG_RELOCATIONS 0 19 #define DEBUG_RELOCATIONS 0
19 20
20 #define RLOG(...) LOG_IF(DEBUG_RELOCATIONS, __VA_ARGS__) 21 #define RLOG(...) LOG_IF(DEBUG_RELOCATIONS, __VA_ARGS__)
21 #define RLOG_ERRNO(...) LOG_ERRNO_IF(DEBUG_RELOCATIONS, __VA_ARGS__) 22 #define RLOG_ERRNO(...) LOG_ERRNO_IF(DEBUG_RELOCATIONS, __VA_ARGS__)
22 23
23 #ifndef DF_SYMBOLIC 24 #ifndef DF_SYMBOLIC
24 #define DF_SYMBOLIC 2 25 #define DF_SYMBOLIC 2
25 #endif 26 #endif
26 27
27 #ifndef DF_TEXTREL 28 #ifndef DF_TEXTREL
28 #define DF_TEXTREL 4 29 #define DF_TEXTREL 4
29 #endif 30 #endif
30 31
31 #ifndef DT_FLAGS 32 #ifndef DT_FLAGS
32 #define DT_FLAGS 30 33 #define DT_FLAGS 30
33 #endif 34 #endif
34 35
36 // Extension dynamic tags for Android packed relocations.
37 #ifndef DT_LOOS
38 #define DT_LOOS 0x6000000d
39 #endif
40 #ifndef DT_ANDROID_REL
41 #define DT_ANDROID_REL (DT_LOOS + 2)
42 #endif
43 #ifndef DT_ANDROID_RELSZ
44 #define DT_ANDROID_RELSZ (DT_LOOS + 3)
45 #endif
46 #ifndef DT_ANDROID_RELA
47 #define DT_ANDROID_RELA (DT_LOOS + 4)
48 #endif
49 #ifndef DT_ANDROID_RELASZ
50 #define DT_ANDROID_RELASZ (DT_LOOS + 5)
51 #endif
52
35 // Processor-specific relocation types supported by the linker. 53 // Processor-specific relocation types supported by the linker.
36 #ifdef __arm__ 54 #ifdef __arm__
37 55
38 /* arm32 relocations */ 56 /* arm32 relocations */
39 #define R_ARM_ABS32 2 57 #define R_ARM_ABS32 2
40 #define R_ARM_REL32 3 58 #define R_ARM_REL32 3
41 #define R_ARM_GLOB_DAT 21 59 #define R_ARM_GLOB_DAT 21
42 #define R_ARM_JUMP_SLOT 22 60 #define R_ARM_JUMP_SLOT 22
43 #define R_ARM_COPY 20 61 #define R_ARM_COPY 20
44 #define R_ARM_RELATIVE 23 62 #define R_ARM_RELATIVE 23
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 179 }
162 } 180 }
163 181
164 } // namespace 182 } // namespace
165 183
166 bool ElfRelocations::Init(const ElfView* view, Error* error) { 184 bool ElfRelocations::Init(const ElfView* view, Error* error) {
167 // Save these for later. 185 // Save these for later.
168 phdr_ = view->phdr(); 186 phdr_ = view->phdr();
169 phdr_count_ = view->phdr_count(); 187 phdr_count_ = view->phdr_count();
170 load_bias_ = view->load_bias(); 188 load_bias_ = view->load_bias();
171 #if defined(__arm__) || defined(__aarch64__)
172 packed_relocations_ = view->packed_relocations();
173 #endif
174 189
175 // We handle only Rel or Rela, but not both. If DT_RELA or DT_RELASZ 190 // We handle only Rel or Rela, but not both. If DT_RELA or DT_RELASZ
176 // then we require DT_PLTREL to agree. 191 // then we require DT_PLTREL to agree.
177 bool has_rela_relocations = false; 192 bool has_rela_relocations = false;
178 bool has_rel_relocations = false; 193 bool has_rel_relocations = false;
179 194
180 // Parse the dynamic table. 195 // Parse the dynamic table.
181 ElfView::DynamicIterator dyn(view); 196 ElfView::DynamicIterator dyn(view);
182 for (; dyn.HasNext(); dyn.GetNext()) { 197 for (; dyn.HasNext(); dyn.GetNext()) {
183 ELF::Addr dyn_value = dyn.GetValue(); 198 ELF::Addr dyn_value = dyn.GetValue();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 if (relocations_size_) { 239 if (relocations_size_) {
225 *error = "Unsupported DT_RELASZ/DT_RELSZ combination in dyn section"; 240 *error = "Unsupported DT_RELASZ/DT_RELSZ combination in dyn section";
226 return false; 241 return false;
227 } 242 }
228 relocations_size_ = dyn_value; 243 relocations_size_ = dyn_value;
229 if (tag == DT_RELASZ) 244 if (tag == DT_RELASZ)
230 has_rela_relocations = true; 245 has_rela_relocations = true;
231 else 246 else
232 has_rel_relocations = true; 247 has_rel_relocations = true;
233 break; 248 break;
249 case DT_ANDROID_RELA:
250 case DT_ANDROID_REL:
251 RLOG(" %s addr=%p\n",
252 (tag == DT_ANDROID_RELA) ? "DT_ANDROID_RELA" : "DT_ANDROID_REL",
253 dyn_addr);
254 if (android_relocations_) {
255 *error = "Unsupported DT_ANDROID_RELA/DT_ANDROID_REL "
256 "combination in dynamic section";
257 return false;
258 }
259 android_relocations_ = reinterpret_cast<uint8_t*>(dyn_addr);
260 if (tag == DT_ANDROID_RELA)
261 has_rela_relocations = true;
262 else
263 has_rel_relocations = true;
264 break;
265 case DT_ANDROID_RELASZ:
266 case DT_ANDROID_RELSZ:
267 RLOG(" %s size=%d\n",
268 (tag == DT_ANDROID_RELASZ)
269 ? "DT_ANDROID_RELASZ" : "DT_ANDROID_RELSZ", dyn_addr);
270 if (android_relocations_size_) {
271 *error = "Unsupported DT_ANDROID_RELASZ/DT_ANDROID_RELSZ "
272 "combination in dyn section";
273 return false;
274 }
275 android_relocations_size_ = dyn_value;
276 if (tag == DT_ANDROID_RELASZ)
277 has_rela_relocations = true;
278 else
279 has_rel_relocations = true;
280 break;
234 case DT_PLTGOT: 281 case DT_PLTGOT:
235 // Only used on MIPS currently. Could also be used on other platforms 282 // Only used on MIPS currently. Could also be used on other platforms
236 // when lazy binding (i.e. RTLD_LAZY) is implemented. 283 // when lazy binding (i.e. RTLD_LAZY) is implemented.
237 RLOG(" DT_PLTGOT addr=%p\n", dyn_addr); 284 RLOG(" DT_PLTGOT addr=%p\n", dyn_addr);
238 plt_got_ = reinterpret_cast<ELF::Addr*>(dyn_addr); 285 plt_got_ = reinterpret_cast<ELF::Addr*>(dyn_addr);
239 break; 286 break;
240 case DT_TEXTREL: 287 case DT_TEXTREL:
241 RLOG(" DT_TEXTREL\n"); 288 RLOG(" DT_TEXTREL\n");
242 has_text_relocations_ = true; 289 has_text_relocations_ = true;
243 break; 290 break;
244 case DT_SYMBOLIC: 291 case DT_SYMBOLIC:
245 RLOG(" DT_SYMBOLIC\n"); 292 RLOG(" DT_SYMBOLIC\n");
246 has_symbolic_ = true; 293 has_symbolic_ = true;
247 break; 294 break;
248 case DT_FLAGS: 295 case DT_FLAGS:
249 if (dyn_value & DF_TEXTREL) 296 if (dyn_value & DF_TEXTREL)
250 has_text_relocations_ = true; 297 has_text_relocations_ = true;
251 if (dyn_value & DF_SYMBOLIC) 298 if (dyn_value & DF_SYMBOLIC)
252 has_symbolic_ = true; 299 has_symbolic_ = true;
253 RLOG(" DT_FLAGS has_text_relocations=%s has_symbolic=%s\n", 300 RLOG(" DT_FLAGS has_text_relocations=%s has_symbolic=%s\n",
254 has_text_relocations_ ? "true" : "false", 301 has_text_relocations_ ? "true" : "false",
255 has_symbolic_ ? "true" : "false"); 302 has_symbolic_ ? "true" : "false");
256 break; 303 break;
257 #if defined(__mips__) 304 #if defined(__mips__)
258 case DT_MIPS_SYMTABNO: 305 case DT_MIPS_SYMTABNO:
259 RLOG(" DT_MIPS_SYMTABNO value=%d\n", dyn_value); 306 RLOG(" DT_MIPS_SYMTABNO value=%d\n", dyn_value);
260 mips_symtab_count_ = dyn_value; 307 mips_symtab_count_ = dyn_value;
261 break; 308 break;
262 309
263 case DT_MIPS_LOCAL_GOTNO: 310 case DT_MIPS_LOCAL_GOTNO:
264 RLOG(" DT_MIPS_LOCAL_GOTNO value=%d\n", dyn_value); 311 RLOG(" DT_MIPS_LOCAL_GOTNO value=%d\n", dyn_value);
265 mips_local_got_count_ = dyn_value; 312 mips_local_got_count_ = dyn_value;
266 break; 313 break;
267 314
268 case DT_MIPS_GOTSYM: 315 case DT_MIPS_GOTSYM:
269 RLOG(" DT_MIPS_GOTSYM value=%d\n", dyn_value); 316 RLOG(" DT_MIPS_GOTSYM value=%d\n", dyn_value);
270 mips_gotsym_ = dyn_value; 317 mips_gotsym_ = dyn_value;
271 break; 318 break;
272 #endif 319 #endif
273 default: 320 default:
274 ; 321 ;
275 } 322 }
276 } 323 }
277 324
278 if (has_rel_relocations && has_rela_relocations) { 325 if (has_rel_relocations && has_rela_relocations) {
279 *error = "Combining DT_REL and DT_RELA is not currently supported"; 326 *error = "Combining relocations with and without addends is not "
327 "currently supported";
280 return false; 328 return false;
281 } 329 }
282 330
283 // If DT_PLTREL did not explicitly assign relocations_type_, set it 331 // If DT_PLTREL did not explicitly assign relocations_type_, set it
284 // here based on the type of relocations found. 332 // here based on the type of relocations found.
285 if (relocations_type_ != DT_REL && relocations_type_ != DT_RELA) { 333 if (relocations_type_ != DT_REL && relocations_type_ != DT_RELA) {
286 if (has_rel_relocations) 334 if (has_rel_relocations)
287 relocations_type_ = DT_REL; 335 relocations_type_ = DT_REL;
288 else if (has_rela_relocations) 336 else if (has_rela_relocations)
289 relocations_type_ = DT_RELA; 337 relocations_type_ = DT_RELA;
290 } 338 }
291 339
292 if (relocations_type_ == DT_REL && has_rela_relocations) { 340 if (relocations_type_ == DT_REL && has_rela_relocations) {
293 *error = "Found DT_RELA in dyn section, but DT_PLTREL is DT_REL"; 341 *error = "Found relocations with addends in dyn section, "
342 "but DT_PLTREL is DT_REL";
294 return false; 343 return false;
295 } 344 }
296 if (relocations_type_ == DT_RELA && has_rel_relocations) { 345 if (relocations_type_ == DT_RELA && has_rel_relocations) {
297 *error = "Found DT_REL in dyn section, but DT_PLTREL is DT_RELA"; 346 *error = "Found relocations without addends in dyn section, "
347 "but DT_PLTREL is DT_RELA";
298 return false; 348 return false;
299 } 349 }
300 350
301 return true; 351 return true;
302 } 352 }
303 353
304 bool ElfRelocations::ApplyAll(const ElfSymbols* symbols, 354 bool ElfRelocations::ApplyAll(const ElfSymbols* symbols,
305 SymbolResolver* resolver, 355 SymbolResolver* resolver,
306 Error* error) { 356 Error* error) {
307 LOG("%s: Enter\n", __FUNCTION__); 357 LOG("%s: Enter\n", __FUNCTION__);
308 358
309 if (has_text_relocations_) { 359 if (has_text_relocations_) {
310 if (phdr_table_unprotect_segments(phdr_, phdr_count_, load_bias_) < 0) { 360 if (phdr_table_unprotect_segments(phdr_, phdr_count_, load_bias_) < 0) {
311 error->Format("Can't unprotect loadable segments: %s", strerror(errno)); 361 error->Format("Can't unprotect loadable segments: %s", strerror(errno));
312 return false; 362 return false;
313 } 363 }
314 } 364 }
315 365
316 #if defined(__arm__) || defined(__aarch64__) 366 if (!ApplyAndroidRelocations(symbols, resolver, error))
317 if (!ApplyPackedRelocations(error))
318 return false; 367 return false;
319 #endif
320 368
321 if (relocations_type_ == DT_REL) { 369 if (relocations_type_ == DT_REL) {
322 if (!ApplyRelRelocs(reinterpret_cast<ELF::Rel*>(relocations_), 370 if (!ApplyRelRelocs(reinterpret_cast<ELF::Rel*>(relocations_),
323 relocations_size_ / sizeof(ELF::Rel), 371 relocations_size_ / sizeof(ELF::Rel),
324 symbols, 372 symbols,
325 resolver, 373 resolver,
326 error)) 374 error))
327 return false; 375 return false;
328 if (!ApplyRelRelocs(reinterpret_cast<ELF::Rel*>(plt_relocations_), 376 if (!ApplyRelRelocs(reinterpret_cast<ELF::Rel*>(plt_relocations_),
329 plt_relocations_size_ / sizeof(ELF::Rel), 377 plt_relocations_size_ / sizeof(ELF::Rel),
(...skipping 27 matching lines...) Expand all
357 if (phdr_table_protect_segments(phdr_, phdr_count_, load_bias_) < 0) { 405 if (phdr_table_protect_segments(phdr_, phdr_count_, load_bias_) < 0) {
358 error->Format("Can't reprotect loadable segments: %s", strerror(errno)); 406 error->Format("Can't reprotect loadable segments: %s", strerror(errno));
359 return false; 407 return false;
360 } 408 }
361 } 409 }
362 410
363 LOG("%s: Done\n", __FUNCTION__); 411 LOG("%s: Done\n", __FUNCTION__);
364 return true; 412 return true;
365 } 413 }
366 414
367 #if defined(__arm__) || defined(__aarch64__) 415 // Helper class for Android packed relocations. Encapsulates the packing
416 // flags used by Android for packed relocation groups.
417 class AndroidPackedRelocationGroupFlags {
418 public:
419 explicit AndroidPackedRelocationGroupFlags(size_t flags) : flags_(flags) { }
368 420
369 bool ElfRelocations::ForEachPackedRel(const uint8_t* packed_relocations, 421 bool is_relocation_grouped_by_info() const {
370 RelRelocationHandler handler, 422 return hasFlag(RELOCATION_GROUPED_BY_INFO_FLAG);
371 void* opaque) { 423 }
372 Leb128Decoder decoder(packed_relocations); 424 bool is_relocation_grouped_by_offset_delta() const {
373 425 return hasFlag(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG);
374 // Find the count of pairs and the start address. 426 }
375 size_t pairs = decoder.Dequeue(); 427 bool is_relocation_grouped_by_addend() const {
376 const ELF::Addr start_address = decoder.Dequeue(); 428 return hasFlag(RELOCATION_GROUPED_BY_ADDEND_FLAG);
377 429 }
378 // Emit initial relative relocation. 430 bool is_relocation_group_has_addend() const {
379 ELF::Rel relocation; 431 return hasFlag(RELOCATION_GROUP_HAS_ADDEND_FLAG);
380 relocation.r_offset = start_address;
381 relocation.r_info = ELF_R_INFO(0, RELATIVE_RELOCATION_CODE);
382 const ELF::Addr sym_addr = 0;
383 const bool resolved = false;
384 if (!handler(this, &relocation, opaque))
385 return false;
386
387 size_t unpacked_count = 1;
388
389 // Emit relocations for each count-delta pair.
390 while (pairs) {
391 size_t count = decoder.Dequeue();
392 const size_t delta = decoder.Dequeue();
393
394 // Emit count relative relocations with delta offset.
395 while (count) {
396 relocation.r_offset += delta;
397 if (!handler(this, &relocation, opaque))
398 return false;
399 unpacked_count++;
400 count--;
401 }
402 pairs--;
403 } 432 }
404 433
405 RLOG("%s: unpacked_count=%d\n", __FUNCTION__, unpacked_count); 434 private:
435 bool hasFlag(size_t flag) const { return (flags_ & flag) != 0; }
436
437 static const size_t RELOCATION_GROUPED_BY_INFO_FLAG = 1 << 0;
438 static const size_t RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG = 1 << 1;
439 static const size_t RELOCATION_GROUPED_BY_ADDEND_FLAG = 1 << 2;
440 static const size_t RELOCATION_GROUP_HAS_ADDEND_FLAG = 1 << 3;
441
442 const size_t flags_;
443 };
444
445 bool ElfRelocations::ForEachAndroidRelocation(RelocationHandler handler,
446 void* opaque) {
447 // Skip over the "APS2" signature.
448 Sleb128Decoder decoder(android_relocations_ + 4,
449 android_relocations_size_ - 4);
450
451 // Unpacking into a relocation with addend, both for REL and RELA, is
452 // convenient at this point. If REL, the handler needs to take care of
453 // any conversion before use.
454 ELF::Rela relocation;
455 memset(&relocation, 0, sizeof(relocation));
456
457 // Read the relocation count and initial offset.
458 const size_t relocation_count = decoder.pop_front();
459 relocation.r_offset = decoder.pop_front();
460
461 LOG("%s: relocation_count=%d, initial r_offset=%p\n",
462 __FUNCTION__,
463 relocation_count,
464 relocation.r_offset);
465
466 size_t relocations_handled = 0;
467 while (relocations_handled < relocation_count) {
468 // Read the start of the group header to obtain its size and flags.
469 const size_t group_size = decoder.pop_front();
470 AndroidPackedRelocationGroupFlags group_flags(decoder.pop_front());
471
472 // Read other group header fields, depending on the flags read above.
473 size_t group_r_offset_delta = 0;
474 if (group_flags.is_relocation_grouped_by_offset_delta())
475 group_r_offset_delta = decoder.pop_front();
476
477 if (group_flags.is_relocation_grouped_by_info())
478 relocation.r_info = decoder.pop_front();
479
480 if (group_flags.is_relocation_group_has_addend() &&
481 group_flags.is_relocation_grouped_by_addend())
482 relocation.r_addend += decoder.pop_front();
483 else if (!group_flags.is_relocation_group_has_addend())
484 relocation.r_addend = 0;
485
486 // Expand the group into individual relocations.
487 for (size_t group_index = 0; group_index < group_size; group_index++) {
488 if (group_flags.is_relocation_grouped_by_offset_delta())
489 relocation.r_offset += group_r_offset_delta;
490 else
491 relocation.r_offset += decoder.pop_front();
492
493 if (!group_flags.is_relocation_grouped_by_info())
494 relocation.r_info = decoder.pop_front();
495
496 if (group_flags.is_relocation_group_has_addend() &&
497 !group_flags.is_relocation_grouped_by_addend())
498 relocation.r_addend += decoder.pop_front();
499
500 // Pass the relocation to the supplied handler function. If the handler
501 // returns false we view this as failure and return false to our caller.
502 if (!handler(this, &relocation, opaque)) {
503 LOG("%s: failed handling relocation %d\n",
504 __FUNCTION__,
505 relocations_handled);
506 return false;
507 }
508
509 relocations_handled++;
510 }
511 }
512
513 LOG("%s: relocations_handled=%d\n", __FUNCTION__, relocations_handled);
406 return true; 514 return true;
407 } 515 }
408 516
409 bool ElfRelocations::ForEachPackedRela(const uint8_t* packed_relocations, 517 namespace {
410 RelaRelocationHandler handler,
411 void* opaque) {
412 Sleb128Decoder decoder(packed_relocations);
413 518
414 // Find the count of pairs. 519 // Validate the Android packed relocations signature.
415 size_t pairs = decoder.Dequeue(); 520 bool IsValidAndroidPackedRelocations(const uint8_t* android_relocations,
521 size_t android_relocations_size) {
522 if (android_relocations_size < 4)
523 return false;
416 524
417 ELF::Addr offset = 0; 525 // Check for an initial APS2 Android packed relocations header.
418 ELF::Sxword addend = 0; 526 return (android_relocations[0] == 'A' &&
527 android_relocations[1] == 'P' &&
528 android_relocations[2] == 'S' &&
529 android_relocations[3] == '2');
530 }
419 531
420 const ELF::Addr sym_addr = 0; 532 // Narrow a Rela to its equivalent Rel. The r_addend field in the input
421 const bool resolved = false; 533 // Rela must be zero.
534 void ConvertRelaToRel(const ELF::Rela* rela, ELF::Rel* rel) {
535 assert(rela->r_addend == 0);
536 rel->r_offset = rela->r_offset;
537 rel->r_info = rela->r_info;
538 }
422 539
423 size_t unpacked_count = 0; 540 } // namespace
424 541
425 // Emit relocations for each deltas pair. 542 // Args for ApplyAndroidRelocation handler function.
426 while (pairs) { 543 struct ApplyAndroidRelocationArgs {
427 offset += decoder.Dequeue(); 544 ELF::Addr relocations_type;
428 addend += decoder.Dequeue(); 545 const ElfSymbols* symbols;
546 ElfRelocations::SymbolResolver* resolver;
547 Error* error;
548 };
429 549
430 ELF::Rela relocation; 550 // Static ForEachAndroidRelocation() handler.
431 relocation.r_offset = offset; 551 bool ElfRelocations::ApplyAndroidRelocation(ElfRelocations* relocations,
432 relocation.r_info = ELF_R_INFO(0, RELATIVE_RELOCATION_CODE); 552 const ELF::Rela* relocation,
433 relocation.r_addend = addend; 553 void* opaque) {
434 if (!handler(this, &relocation, opaque)) 554 // Unpack args from opaque.
435 return false; 555 ApplyAndroidRelocationArgs* args =
436 unpacked_count++; 556 reinterpret_cast<ApplyAndroidRelocationArgs*>(opaque);
437 pairs--; 557 const ELF::Addr relocations_type = args->relocations_type;
558 const ElfSymbols* symbols = args->symbols;
559 ElfRelocations::SymbolResolver* resolver = args->resolver;
560 Error* error = args->error;
561
562 // For REL relocations, convert from RELA to REL and apply the conversion.
563 // For RELA relocations, apply RELA directly.
564 if (relocations_type == DT_REL) {
565 ELF::Rel converted;
566 ConvertRelaToRel(relocation, &converted);
567 return relocations->ApplyRelReloc(&converted, symbols, resolver, error);
438 } 568 }
439 569
440 RLOG("%s: unpacked_count=%d\n", __FUNCTION__, unpacked_count); 570 if (relocations_type == DT_RELA)
571 return relocations->ApplyRelaReloc(relocation, symbols, resolver, error);
572
441 return true; 573 return true;
442 } 574 }
443 575
444 bool ElfRelocations::ApplyPackedRel(ElfRelocations* relocations, 576 bool ElfRelocations::ApplyAndroidRelocations(const ElfSymbols* symbols,
445 const ELF::Rel* relocation, 577 SymbolResolver* resolver,
446 void* opaque) { 578 Error* error) {
447 Error* error = reinterpret_cast<Error*>(opaque); 579 if (!android_relocations_)
448 const ELF::Addr sym_addr = 0; 580 return true;
449 const bool resolved = false; 581
450 return relocations->ApplyRelReloc(relocation, sym_addr, resolved, error); 582 if (!IsValidAndroidPackedRelocations(android_relocations_,
583 android_relocations_size_))
584 return false;
585
586 ApplyAndroidRelocationArgs args;
587 args.relocations_type = relocations_type_;
588 args.symbols = symbols;
589 args.resolver = resolver;
590 args.error = error;
591 return ForEachAndroidRelocation(&ApplyAndroidRelocation, &args);
451 } 592 }
452 593
453 bool ElfRelocations::ApplyPackedRels(const uint8_t* packed_relocations, 594 bool ElfRelocations::ApplyResolvedRelaReloc(const ELF::Rela* rela,
454 Error* error) { 595 ELF::Addr sym_addr,
455 void* opaque = error; 596 bool resolved CRAZY_UNUSED,
456 return ForEachPackedRel(packed_relocations, &ApplyPackedRel, opaque); 597 Error* error) {
457 }
458
459 bool ElfRelocations::ApplyPackedRela(ElfRelocations* relocations,
460 const ELF::Rela* relocation,
461 void* opaque) {
462 Error* error = reinterpret_cast<Error*>(opaque);
463 const ELF::Addr sym_addr = 0;
464 const bool resolved = false;
465 return relocations->ApplyRelaReloc(relocation, sym_addr, resolved, error);
466 }
467
468 bool ElfRelocations::ApplyPackedRelas(const uint8_t* packed_relocations,
469 Error* error) {
470 void* opaque = error;
471 return ForEachPackedRela(packed_relocations, &ApplyPackedRela, opaque);
472 }
473
474 bool ElfRelocations::ApplyPackedRelocations(Error* error) {
475 if (!packed_relocations_)
476 return true;
477
478 // Check for an initial APR1 header, packed relocations.
479 if (packed_relocations_[0] == 'A' &&
480 packed_relocations_[1] == 'P' &&
481 packed_relocations_[2] == 'R' &&
482 packed_relocations_[3] == '1') {
483 return ApplyPackedRels(packed_relocations_ + 4, error);
484 }
485
486 // Check for an initial APA1 header, packed relocations with addend.
487 if (packed_relocations_[0] == 'A' &&
488 packed_relocations_[1] == 'P' &&
489 packed_relocations_[2] == 'A' &&
490 packed_relocations_[3] == '1') {
491 return ApplyPackedRelas(packed_relocations_ + 4, error);
492 }
493
494 error->Format("Bad packed relocations ident, expected APR1 or APA1");
495 return false;
496 }
497 #endif // __arm__ || __aarch64__
498
499 bool ElfRelocations::ApplyRelaReloc(const ELF::Rela* rela,
500 ELF::Addr sym_addr,
501 bool resolved CRAZY_UNUSED,
502 Error* error) {
503 const ELF::Word rela_type = ELF_R_TYPE(rela->r_info); 598 const ELF::Word rela_type = ELF_R_TYPE(rela->r_info);
504 const ELF::Word CRAZY_UNUSED rela_symbol = ELF_R_SYM(rela->r_info); 599 const ELF::Word CRAZY_UNUSED rela_symbol = ELF_R_SYM(rela->r_info);
505 const ELF::Sword CRAZY_UNUSED addend = rela->r_addend; 600 const ELF::Sword CRAZY_UNUSED addend = rela->r_addend;
506 601
507 const ELF::Addr reloc = static_cast<ELF::Addr>(rela->r_offset + load_bias_); 602 const ELF::Addr reloc = static_cast<ELF::Addr>(rela->r_offset + load_bias_);
508 603
509 RLOG(" rela reloc=%p offset=%p type=%d addend=%p\n", 604 RLOG(" rela reloc=%p offset=%p type=%d addend=%p\n",
510 reloc, 605 reloc,
511 rela->r_offset, 606 rela->r_offset,
512 rela_type, 607 rela_type,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 #endif // __x86_64__ 679 #endif // __x86_64__
585 680
586 default: 681 default:
587 error->Format("Invalid relocation type (%d)", rela_type); 682 error->Format("Invalid relocation type (%d)", rela_type);
588 return false; 683 return false;
589 } 684 }
590 685
591 return true; 686 return true;
592 } 687 }
593 688
594 bool ElfRelocations::ApplyRelReloc(const ELF::Rel* rel, 689 bool ElfRelocations::ApplyResolvedRelReloc(const ELF::Rel* rel,
595 ELF::Addr sym_addr, 690 ELF::Addr sym_addr,
596 bool resolved CRAZY_UNUSED, 691 bool resolved CRAZY_UNUSED,
597 Error* error) { 692 Error* error) {
598 const ELF::Word rel_type = ELF_R_TYPE(rel->r_info); 693 const ELF::Word rel_type = ELF_R_TYPE(rel->r_info);
599 const ELF::Word CRAZY_UNUSED rel_symbol = ELF_R_SYM(rel->r_info); 694 const ELF::Word CRAZY_UNUSED rel_symbol = ELF_R_SYM(rel->r_info);
600 695
601 const ELF::Addr reloc = static_cast<ELF::Addr>(rel->r_offset + load_bias_); 696 const ELF::Addr reloc = static_cast<ELF::Addr>(rel->r_offset + load_bias_);
602 697
603 RLOG(" rel reloc=%p offset=%p type=%d\n", reloc, rel->r_offset, rel_type); 698 RLOG(" rel reloc=%p offset=%p type=%d\n", reloc, rel->r_offset, rel_type);
604 699
605 // Apply the relocation. 700 // Apply the relocation.
606 ELF::Addr* CRAZY_UNUSED target = reinterpret_cast<ELF::Addr*>(reloc); 701 ELF::Addr* CRAZY_UNUSED target = reinterpret_cast<ELF::Addr*>(reloc);
607 switch (rel_type) { 702 switch (rel_type) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 return true; 840 return true;
746 } 841 }
747 842
748 error->Format( 843 error->Format(
749 "Invalid weak relocation type (%d) for unknown symbol '%s'", 844 "Invalid weak relocation type (%d) for unknown symbol '%s'",
750 r, 845 r,
751 sym_name); 846 sym_name);
752 return false; 847 return false;
753 } 848 }
754 849
850 bool ElfRelocations::ApplyRelReloc(const ELF::Rel* rel,
851 const ElfSymbols* symbols,
852 SymbolResolver* resolver,
853 Error* error) {
854 const ELF::Word rel_type = ELF_R_TYPE(rel->r_info);
855 const ELF::Word rel_symbol = ELF_R_SYM(rel->r_info);
856
857 ELF::Addr sym_addr = 0;
858 ELF::Addr reloc = static_cast<ELF::Addr>(rel->r_offset + load_bias_);
859 RLOG(" reloc=%p offset=%p type=%d symbol=%d\n",
860 reloc,
861 rel->r_offset,
862 rel_type,
863 rel_symbol);
864
865 if (rel_type == 0)
866 return true;
867
868 bool resolved = false;
869
870 // If this is a symbolic relocation, compute the symbol's address.
871 if (__builtin_expect(rel_symbol != 0, 0)) {
872 if (!ResolveSymbol(rel_type,
873 rel_symbol,
874 symbols,
875 resolver,
876 reloc,
877 &sym_addr,
878 error)) {
879 return false;
880 }
881 resolved = true;
882 }
883
884 return ApplyResolvedRelReloc(rel, sym_addr, resolved, error);
885 }
886
755 bool ElfRelocations::ApplyRelRelocs(const ELF::Rel* rel, 887 bool ElfRelocations::ApplyRelRelocs(const ELF::Rel* rel,
756 size_t rel_count, 888 size_t rel_count,
757 const ElfSymbols* symbols, 889 const ElfSymbols* symbols,
758 SymbolResolver* resolver, 890 SymbolResolver* resolver,
759 Error* error) { 891 Error* error) {
760 RLOG("%s: rel=%p rel_count=%d\n", __FUNCTION__, rel, rel_count); 892 RLOG("%s: rel=%p rel_count=%d\n", __FUNCTION__, rel, rel_count);
761 893
762 if (!rel) 894 if (!rel)
763 return true; 895 return true;
764 896
765 for (size_t rel_n = 0; rel_n < rel_count; rel++, rel_n++) { 897 for (size_t rel_n = 0; rel_n < rel_count; rel++, rel_n++) {
766 const ELF::Word rel_type = ELF_R_TYPE(rel->r_info); 898 RLOG(" Relocation %d of %d:\n", rel_n + 1, rel_count);
767 const ELF::Word rel_symbol = ELF_R_SYM(rel->r_info);
768 899
769 ELF::Addr sym_addr = 0; 900 if (!ApplyRelReloc(rel, symbols, resolver, error))
770 ELF::Addr reloc = static_cast<ELF::Addr>(rel->r_offset + load_bias_);
771 RLOG(" %d/%d reloc=%p offset=%p type=%d symbol=%d\n",
772 rel_n + 1,
773 rel_count,
774 reloc,
775 rel->r_offset,
776 rel_type,
777 rel_symbol);
778
779 if (rel_type == 0)
780 continue;
781
782 bool resolved = false;
783
784 // If this is a symbolic relocation, compute the symbol's address.
785 if (__builtin_expect(rel_symbol != 0, 0)) {
786 if (!ResolveSymbol(rel_type,
787 rel_symbol,
788 symbols,
789 resolver,
790 reloc,
791 &sym_addr,
792 error)) {
793 return false;
794 }
795 resolved = true;
796 }
797
798 if (!ApplyRelReloc(rel, sym_addr, resolved, error))
799 return false; 901 return false;
800 } 902 }
801 903
802 return true; 904 return true;
803 } 905 }
804 906
907 bool ElfRelocations::ApplyRelaReloc(const ELF::Rela* rela,
908 const ElfSymbols* symbols,
909 SymbolResolver* resolver,
910 Error* error) {
911 const ELF::Word rel_type = ELF_R_TYPE(rela->r_info);
912 const ELF::Word rel_symbol = ELF_R_SYM(rela->r_info);
913
914 ELF::Addr sym_addr = 0;
915 ELF::Addr reloc = static_cast<ELF::Addr>(rela->r_offset + load_bias_);
916 RLOG(" reloc=%p offset=%p type=%d symbol=%d\n",
917 reloc,
918 rela->r_offset,
919 rel_type,
920 rel_symbol);
921
922 if (rel_type == 0)
923 return true;
924
925 bool resolved = false;
926
927 // If this is a symbolic relocation, compute the symbol's address.
928 if (__builtin_expect(rel_symbol != 0, 0)) {
929 if (!ResolveSymbol(rel_type,
930 rel_symbol,
931 symbols,
932 resolver,
933 reloc,
934 &sym_addr,
935 error)) {
936 return false;
937 }
938 resolved = true;
939 }
940
941 return ApplyResolvedRelaReloc(rela, sym_addr, resolved, error);
942 }
943
805 bool ElfRelocations::ApplyRelaRelocs(const ELF::Rela* rela, 944 bool ElfRelocations::ApplyRelaRelocs(const ELF::Rela* rela,
806 size_t rela_count, 945 size_t rela_count,
807 const ElfSymbols* symbols, 946 const ElfSymbols* symbols,
808 SymbolResolver* resolver, 947 SymbolResolver* resolver,
809 Error* error) { 948 Error* error) {
810 RLOG("%s: rela=%p rela_count=%d\n", __FUNCTION__, rela, rela_count); 949 RLOG("%s: rela=%p rela_count=%d\n", __FUNCTION__, rela, rela_count);
811 950
812 if (!rela) 951 if (!rela)
813 return true; 952 return true;
814 953
815 for (size_t rel_n = 0; rel_n < rela_count; rela++, rel_n++) { 954 for (size_t rel_n = 0; rel_n < rela_count; rela++, rel_n++) {
816 const ELF::Word rel_type = ELF_R_TYPE(rela->r_info); 955 RLOG(" Relocation %d of %d:\n", rel_n + 1, rela_count);
817 const ELF::Word rel_symbol = ELF_R_SYM(rela->r_info);
818 956
819 ELF::Addr sym_addr = 0; 957 if (!ApplyRelaReloc(rela, symbols, resolver, error))
820 ELF::Addr reloc = static_cast<ELF::Addr>(rela->r_offset + load_bias_);
821 RLOG(" %d/%d reloc=%p offset=%p type=%d symbol=%d\n",
822 rel_n + 1,
823 rela_count,
824 reloc,
825 rela->r_offset,
826 rel_type,
827 rel_symbol);
828
829 if (rel_type == 0)
830 continue;
831
832 bool resolved = false;
833
834 // If this is a symbolic relocation, compute the symbol's address.
835 if (__builtin_expect(rel_symbol != 0, 0)) {
836 if (!ResolveSymbol(rel_type,
837 rel_symbol,
838 symbols,
839 resolver,
840 reloc,
841 &sym_addr,
842 error)) {
843 return false;
844 }
845 resolved = true;
846 }
847
848 if (!ApplyRelaReloc(rela, sym_addr, resolved, error))
849 return false; 958 return false;
850 } 959 }
851 960
852 return true; 961 return true;
853 } 962 }
854 963
855 #ifdef __mips__ 964 #ifdef __mips__
856 bool ElfRelocations::RelocateMipsGot(const ElfSymbols* symbols, 965 bool ElfRelocations::RelocateMipsGot(const ElfSymbols* symbols,
857 SymbolResolver* resolver, 966 SymbolResolver* resolver,
858 Error* error) { 967 Error* error) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 #ifdef __mips__ 1043 #ifdef __mips__
935 case R_MIPS_REL32: 1044 case R_MIPS_REL32:
936 *dst_ptr += map_delta; 1045 *dst_ptr += map_delta;
937 break; 1046 break;
938 #endif 1047 #endif
939 default: 1048 default:
940 ; 1049 ;
941 } 1050 }
942 } 1051 }
943 1052
944 #if defined(__arm__) || defined(__aarch64__) 1053 void ElfRelocations::AdjustAndroidRelocation(const ELF::Rela* relocation,
1054 size_t src_addr,
1055 size_t dst_addr,
1056 size_t map_addr,
1057 size_t size) {
1058 // Add this value to each source address to get the corresponding
1059 // destination address.
1060 const size_t dst_delta = dst_addr - src_addr;
1061 const size_t map_delta = map_addr - src_addr;
945 1062
946 struct AdjustRelocationArgs { 1063 const ELF::Word rel_type = ELF_R_TYPE(relocation->r_info);
1064 const ELF::Word rel_symbol = ELF_R_SYM(relocation->r_info);
1065 ELF::Addr src_reloc =
1066 static_cast<ELF::Addr>(relocation->r_offset + load_bias_);
1067
1068 if (rel_type == 0 || rel_symbol != 0) {
1069 // Ignore empty and symbolic relocations
1070 return;
1071 }
1072
1073 if (src_reloc < src_addr || src_reloc >= src_addr + size) {
1074 // Ignore entries that don't relocate addresses inside the source section.
1075 return;
1076 }
1077
1078 AdjustRelocation(rel_type, src_reloc, dst_delta, map_delta);
1079 }
1080
1081 // Args for ApplyAndroidRelocation handler function.
1082 struct RelocateAndroidRelocationArgs {
947 size_t src_addr; 1083 size_t src_addr;
948 size_t dst_addr; 1084 size_t dst_addr;
949 size_t map_addr; 1085 size_t map_addr;
950 size_t size; 1086 size_t size;
951 }; 1087 };
952 1088
953 template<typename Rel> 1089 // Static ForEachAndroidRelocation() handler.
954 bool ElfRelocations::RelocatePackedRelocation(ElfRelocations* relocations, 1090 bool ElfRelocations::RelocateAndroidRelocation(ElfRelocations* relocations,
955 const Rel* rel, 1091 const ELF::Rela* relocation,
956 void* opaque) { 1092 void* opaque) {
957 AdjustRelocationArgs* args = reinterpret_cast<AdjustRelocationArgs*>(opaque); 1093 // Unpack args from opaque, to obtain addrs and size;
1094 RelocateAndroidRelocationArgs* args =
1095 reinterpret_cast<RelocateAndroidRelocationArgs*>(opaque);
958 const size_t src_addr = args->src_addr; 1096 const size_t src_addr = args->src_addr;
959 const size_t dst_addr = args->dst_addr; 1097 const size_t dst_addr = args->dst_addr;
960 const size_t map_addr = args->map_addr; 1098 const size_t map_addr = args->map_addr;
961 const size_t size = args->size; 1099 const size_t size = args->size;
962 1100
963 const size_t load_bias = relocations->load_bias_; 1101 // Relocate the given relocation. Because the r_addend field is ignored
964 1102 // in relocating RELA relocations we do not need to convert from REL to
965 const size_t dst_delta = dst_addr - src_addr; 1103 // RELA and supply alternative relocator functions; instead we can work
966 const size_t map_delta = map_addr - src_addr; 1104 // here directly on the RELA supplied by ForEachAndroidRelocation(), even
967 1105 // on REL architectures.
968 const ELF::Word rel_type = ELF_R_TYPE(rel->r_info); 1106 relocations->AdjustAndroidRelocation(relocation,
969 const ELF::Word rel_symbol = ELF_R_SYM(rel->r_info); 1107 src_addr,
970 ELF::Addr src_reloc = static_cast<ELF::Addr>(rel->r_offset + load_bias); 1108 dst_addr,
971 1109 map_addr,
972 if (rel_type == 0 || rel_symbol != 0) { 1110 size);
973 // Ignore empty and symbolic relocations
974 return true;
975 }
976
977 if (src_reloc < src_addr || src_reloc >= src_addr + size) {
978 // Ignore entries that don't relocate addresses inside the source section.
979 return true;
980 }
981
982 relocations->AdjustRelocation(rel_type, src_reloc, dst_delta, map_delta);
983 return true; 1111 return true;
984 } 1112 }
985 1113
986 template bool ElfRelocations::RelocatePackedRelocation<ELF::Rel>( 1114 void ElfRelocations::RelocateAndroidRelocations(size_t src_addr,
987 ElfRelocations* relocations, const ELF::Rel* rel, void* opaque); 1115 size_t dst_addr,
1116 size_t map_addr,
1117 size_t size) {
1118 if (!android_relocations_)
1119 return;
988 1120
989 template bool ElfRelocations::RelocatePackedRelocation<ELF::Rela>( 1121 assert(IsValidAndroidPackedRelocations(android_relocations_,
990 ElfRelocations* relocations, const ELF::Rela* rel, void* opaque); 1122 android_relocations_size_));
991 1123
992 void ElfRelocations::RelocatePackedRels(const uint8_t* packed_relocations, 1124 RelocateAndroidRelocationArgs args;
993 size_t src_addr,
994 size_t dst_addr,
995 size_t map_addr,
996 size_t size) {
997 AdjustRelocationArgs args;
998 args.src_addr = src_addr; 1125 args.src_addr = src_addr;
999 args.dst_addr = dst_addr; 1126 args.dst_addr = dst_addr;
1000 args.map_addr = map_addr; 1127 args.map_addr = map_addr;
1001 args.size = size; 1128 args.size = size;
1002 ForEachPackedRel(packed_relocations, 1129 ForEachAndroidRelocation(&RelocateAndroidRelocation, &args);
1003 &RelocatePackedRelocation<ELF::Rel>, &args);
1004 } 1130 }
1005 1131
1006 void ElfRelocations::RelocatePackedRelas(const uint8_t* packed_relocations, 1132 template<typename Rel>
1007 size_t src_addr, 1133 void ElfRelocations::RelocateRelocations(size_t src_addr,
1008 size_t dst_addr, 1134 size_t dst_addr,
1009 size_t map_addr, 1135 size_t map_addr,
1010 size_t size) { 1136 size_t size) {
1011 AdjustRelocationArgs args;
1012 args.src_addr = src_addr;
1013 args.dst_addr = dst_addr;
1014 args.map_addr = map_addr;
1015 args.size = size;
1016 ForEachPackedRela(packed_relocations,
1017 &RelocatePackedRelocation<ELF::Rela>, &args);
1018 }
1019
1020 void ElfRelocations::RelocatePackedRelocations(size_t src_addr,
1021 size_t dst_addr,
1022 size_t map_addr,
1023 size_t size) {
1024 if (!packed_relocations_)
1025 return;
1026
1027 // Check for an initial APR1 header, packed relocations.
1028 if (packed_relocations_[0] == 'A' &&
1029 packed_relocations_[1] == 'P' &&
1030 packed_relocations_[2] == 'R' &&
1031 packed_relocations_[3] == '1') {
1032 RelocatePackedRels(packed_relocations_ + 4,
1033 src_addr, dst_addr, map_addr, size);
1034 }
1035
1036 // Check for an initial APA1 header, packed relocations with addend.
1037 if (packed_relocations_[0] == 'A' &&
1038 packed_relocations_[1] == 'P' &&
1039 packed_relocations_[2] == 'A' &&
1040 packed_relocations_[3] == '1') {
1041 RelocatePackedRelas(packed_relocations_ + 4,
1042 src_addr, dst_addr, map_addr, size);
1043 }
1044 }
1045
1046 #endif // __arm__ || __aarch64__
1047
1048 template<typename Rel>
1049 void ElfRelocations::RelocateRelocation(size_t src_addr,
1050 size_t dst_addr,
1051 size_t map_addr,
1052 size_t size) {
1053 // Add this value to each source address to get the corresponding 1137 // Add this value to each source address to get the corresponding
1054 // destination address. 1138 // destination address.
1055 const size_t dst_delta = dst_addr - src_addr; 1139 const size_t dst_delta = dst_addr - src_addr;
1056 const size_t map_delta = map_addr - src_addr; 1140 const size_t map_delta = map_addr - src_addr;
1057 1141
1058 // Ignore PLT relocations, which all target symbols (ignored here). 1142 // Ignore PLT relocations, which all target symbols (ignored here).
1059 const Rel* rel = reinterpret_cast<Rel*>(relocations_); 1143 const Rel* rel = reinterpret_cast<Rel*>(relocations_);
1060 const size_t relocations_count = relocations_size_ / sizeof(Rel); 1144 const size_t relocations_count = relocations_size_ / sizeof(Rel);
1061 const Rel* rel_limit = rel + relocations_count; 1145 const Rel* rel_limit = rel + relocations_count;
1062 1146
1063 for (; rel < rel_limit; ++rel) { 1147 for (; rel < rel_limit; ++rel) {
1064 const ELF::Word rel_type = ELF_R_TYPE(rel->r_info); 1148 const ELF::Word rel_type = ELF_R_TYPE(rel->r_info);
1065 const ELF::Word rel_symbol = ELF_R_SYM(rel->r_info); 1149 const ELF::Word rel_symbol = ELF_R_SYM(rel->r_info);
1066 ELF::Addr src_reloc = static_cast<ELF::Addr>(rel->r_offset + load_bias_); 1150 ELF::Addr src_reloc = static_cast<ELF::Addr>(rel->r_offset + load_bias_);
1067 1151
1068 if (rel_type == 0 || rel_symbol != 0) { 1152 if (rel_type == 0 || rel_symbol != 0) {
1069 // Ignore empty and symbolic relocations 1153 // Ignore empty and symbolic relocations
1070 continue; 1154 continue;
1071 } 1155 }
1072 1156
1073 if (src_reloc < src_addr || src_reloc >= src_addr + size) { 1157 if (src_reloc < src_addr || src_reloc >= src_addr + size) {
1074 // Ignore entries that don't relocate addresses inside the source section. 1158 // Ignore entries that don't relocate addresses inside the source section.
1075 continue; 1159 continue;
1076 } 1160 }
1077 1161
1078 AdjustRelocation(rel_type, src_reloc, dst_delta, map_delta); 1162 AdjustRelocation(rel_type, src_reloc, dst_delta, map_delta);
1079 } 1163 }
1080 } 1164 }
1081 1165
1082 template void ElfRelocations::RelocateRelocation<ELF::Rel>( 1166 template void ElfRelocations::RelocateRelocations<ELF::Rel>(
1083 size_t src_addr, size_t dst_addr, size_t map_addr, size_t size); 1167 size_t src_addr, size_t dst_addr, size_t map_addr, size_t size);
1084 1168
1085 template void ElfRelocations::RelocateRelocation<ELF::Rela>( 1169 template void ElfRelocations::RelocateRelocations<ELF::Rela>(
1086 size_t src_addr, size_t dst_addr, size_t map_addr, size_t size); 1170 size_t src_addr, size_t dst_addr, size_t map_addr, size_t size);
1087 1171
1088 void ElfRelocations::CopyAndRelocate(size_t src_addr, 1172 void ElfRelocations::CopyAndRelocate(size_t src_addr,
1089 size_t dst_addr, 1173 size_t dst_addr,
1090 size_t map_addr, 1174 size_t map_addr,
1091 size_t size) { 1175 size_t size) {
1092 // First, a straight copy. 1176 // First, a straight copy.
1093 ::memcpy(reinterpret_cast<void*>(dst_addr), 1177 ::memcpy(reinterpret_cast<void*>(dst_addr),
1094 reinterpret_cast<void*>(src_addr), 1178 reinterpret_cast<void*>(src_addr),
1095 size); 1179 size);
1096 1180
1097 #if defined(__arm__) || defined(__aarch64__) 1181 // Relocate android relocations.
1098 // Relocate packed relative relocations. 1182 RelocateAndroidRelocations(src_addr, dst_addr, map_addr, size);
1099 RelocatePackedRelocations(src_addr, dst_addr, map_addr, size);
1100 #endif
1101 1183
1102 // Relocate relocations. 1184 // Relocate relocations.
1103 if (relocations_type_ == DT_REL) 1185 if (relocations_type_ == DT_REL)
1104 RelocateRelocation<ELF::Rel>(src_addr, dst_addr, map_addr, size); 1186 RelocateRelocations<ELF::Rel>(src_addr, dst_addr, map_addr, size);
1105 1187
1106 if (relocations_type_ == DT_RELA) 1188 if (relocations_type_ == DT_RELA)
1107 RelocateRelocation<ELF::Rela>(src_addr, dst_addr, map_addr, size); 1189 RelocateRelocations<ELF::Rela>(src_addr, dst_addr, map_addr, size);
1108 1190
1109 #ifdef __mips__ 1191 #ifdef __mips__
1110 // Add this value to each source address to get the corresponding 1192 // Add this value to each source address to get the corresponding
1111 // destination address. 1193 // destination address.
1112 const size_t dst_delta = dst_addr - src_addr; 1194 const size_t dst_delta = dst_addr - src_addr;
1113 const size_t map_delta = map_addr - src_addr; 1195 const size_t map_delta = map_addr - src_addr;
1114 1196
1115 // Only relocate local GOT entries. 1197 // Only relocate local GOT entries.
1116 ELF::Addr* got = plt_got_; 1198 ELF::Addr* got = plt_got_;
1117 if (got) { 1199 if (got) {
1118 for (ELF::Addr n = 2; n < mips_local_got_count_; ++n) { 1200 for (ELF::Addr n = 2; n < mips_local_got_count_; ++n) {
1119 size_t got_addr = reinterpret_cast<size_t>(&got[n]); 1201 size_t got_addr = reinterpret_cast<size_t>(&got[n]);
1120 if (got_addr < src_addr || got_addr >= src_addr + size) 1202 if (got_addr < src_addr || got_addr >= src_addr + size)
1121 continue; 1203 continue;
1122 ELF::Addr* dst_ptr = reinterpret_cast<ELF::Addr*>(got_addr + dst_delta); 1204 ELF::Addr* dst_ptr = reinterpret_cast<ELF::Addr*>(got_addr + dst_delta);
1123 *dst_ptr += map_delta; 1205 *dst_ptr += map_delta;
1124 } 1206 }
1125 } 1207 }
1126 #endif 1208 #endif
1127 } 1209 }
1128 1210
1129 } // namespace crazy 1211 } // namespace crazy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698