... |
... |
@@ -64,7 +64,7 @@ static bool fitsBits(size_t bits, int64_t value); |
64
|
64
|
static int64_t decodeAddend(ObjectCode * oc, Section * section,
|
65
|
65
|
MachORelocationInfo * ri);
|
66
|
66
|
static void encodeAddend(ObjectCode * oc, Section * section,
|
67
|
|
- MachORelocationInfo * ri, int64_t addend);
|
|
67
|
+ MachORelocationInfo * ri, int64_t addend, MachOSymbol * symbol);
|
68
|
68
|
|
69
|
69
|
/* Global Offset Table logic */
|
70
|
70
|
static bool isGotLoad(MachORelocationInfo * ri);
|
... |
... |
@@ -361,15 +361,21 @@ fitsBits(size_t bits, int64_t value) { |
361
|
361
|
|
362
|
362
|
static void
|
363
|
363
|
encodeAddend(ObjectCode * oc, Section * section,
|
364
|
|
- MachORelocationInfo * ri, int64_t addend) {
|
|
364
|
+ MachORelocationInfo * ri, int64_t addend, MachOSymbol * symbol) {
|
365
|
365
|
uint32_t * p = (uint32_t*)((uint8_t*)section->start + ri->r_address);
|
366
|
366
|
|
367
|
367
|
checkProddableBlock(&oc->proddables, (void*)p, 1 << ri->r_length);
|
368
|
368
|
|
|
369
|
+ const char *symbol_name = symbol && symbol->name ? (char*)symbol->name : "<unknown>";
|
|
370
|
+ const char *file_name = oc->fileName ? (char*)oc->fileName : "<unknown>";
|
|
371
|
+
|
369
|
372
|
switch (ri->r_type) {
|
370
|
373
|
case ARM64_RELOC_UNSIGNED: {
|
371
|
|
- if(!fitsBits(8 << ri->r_length, addend))
|
372
|
|
- barf("Relocation out of range for UNSIGNED");
|
|
374
|
+ if(!fitsBits(8 << ri->r_length, addend)) {
|
|
375
|
+ const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
376
|
+ barf("Relocation out of range for UNSIGNED in %s: symbol '%s', addend 0x%llx, address 0x%llx, library: %s",
|
|
377
|
+ file_name, symbol_name, (long long)addend, (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
378
|
+ }
|
373
|
379
|
switch (ri->r_length) {
|
374
|
380
|
case 0: *(uint8_t*)p = (uint8_t)addend; break;
|
375
|
381
|
case 1: *(uint16_t*)p = (uint16_t)addend; break;
|
... |
... |
@@ -382,8 +388,11 @@ encodeAddend(ObjectCode * oc, Section * section, |
382
|
388
|
return;
|
383
|
389
|
}
|
384
|
390
|
case ARM64_RELOC_SUBTRACTOR: {
|
385
|
|
- if(!fitsBits(8 << ri->r_length, addend))
|
386
|
|
- barf("Relocation out of range for SUBTRACTOR");
|
|
391
|
+ if(!fitsBits(8 << ri->r_length, addend)) {
|
|
392
|
+ const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
393
|
+ barf("Relocation out of range for SUBTRACTOR in %s: symbol '%s', addend 0x%llx, address 0x%llx, library: %s",
|
|
394
|
+ file_name, symbol_name, (long long)addend, (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
395
|
+ }
|
387
|
396
|
switch (ri->r_length) {
|
388
|
397
|
case 0: *(uint8_t*)p = (uint8_t)addend; break;
|
389
|
398
|
case 1: *(uint16_t*)p = (uint16_t)addend; break;
|
... |
... |
@@ -400,8 +409,11 @@ encodeAddend(ObjectCode * oc, Section * section, |
400
|
409
|
* do not need the last two bits of the value. If the value >> 2
|
401
|
410
|
* still exceeds 26bits, we won't be able to reach it.
|
402
|
411
|
*/
|
403
|
|
- if(!fitsBits(26, addend >> 2))
|
404
|
|
- barf("Relocation target for BRACH26 out of range.");
|
|
412
|
+ if(!fitsBits(26, addend >> 2)) {
|
|
413
|
+ const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
414
|
+ barf("Relocation target for BRANCH26 out of range in %s: symbol '%s', addend 0x%llx (0x%llx >> 2), address 0x%llx, library: %s",
|
|
415
|
+ file_name, symbol_name, (long long)addend, (long long)(addend >> 2), (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
416
|
+ }
|
405
|
417
|
*p = (*p & 0xFC000000) | ((uint32_t)(addend >> 2) & 0x03FFFFFF);
|
406
|
418
|
return;
|
407
|
419
|
}
|
... |
... |
@@ -412,8 +424,12 @@ encodeAddend(ObjectCode * oc, Section * section, |
412
|
424
|
* with the PAGEOFF12 relocation allows to address a relative range
|
413
|
425
|
* of +-4GB.
|
414
|
426
|
*/
|
415
|
|
- if(!fitsBits(21, addend >> 12))
|
416
|
|
- barf("Relocation target for PAGE21 out of range.");
|
|
427
|
+ if(!fitsBits(21, addend >> 12)) {
|
|
428
|
+ const char *reloc_type = (ri->r_type == ARM64_RELOC_PAGE21) ? "PAGE21" : "GOT_LOAD_PAGE21";
|
|
429
|
+ const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
430
|
+ barf("Relocation target for %s out of range in %s: symbol '%s', addend 0x%llx (0x%llx >> 12), address 0x%llx, library: %s",
|
|
431
|
+ reloc_type, file_name, symbol_name, (long long)addend, (long long)(addend >> 12), (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
432
|
+ }
|
417
|
433
|
*p = (*p & 0x9F00001F) | (uint32_t)((addend << 17) & 0x60000000)
|
418
|
434
|
| (uint32_t)((addend >> 9) & 0x00FFFFE0);
|
419
|
435
|
return;
|
... |
... |
@@ -423,8 +439,11 @@ encodeAddend(ObjectCode * oc, Section * section, |
423
|
439
|
/* Store an offset into a page (4k). Depending on the instruction
|
424
|
440
|
* the bits are stored at slightly different positions.
|
425
|
441
|
*/
|
426
|
|
- if(!fitsBits(12, addend))
|
427
|
|
- barf("Relocation target for PAGEOFF12 out or range.");
|
|
442
|
+ if(!fitsBits(12, addend)) {
|
|
443
|
+ const char *library_info = OC_INFORMATIVE_FILENAME(oc);
|
|
444
|
+ barf("Relocation target for PAGEOFF12 out of range in %s: symbol '%s', addend 0x%llx, address 0x%llx, library: %s",
|
|
445
|
+ file_name, symbol_name, (long long)addend, (long long)ri->r_address, library_info ? (char*)library_info : "<unknown>");
|
|
446
|
+ }
|
428
|
447
|
|
429
|
448
|
int shift = 0;
|
430
|
449
|
if(isLoadStore(p)) {
|
... |
... |
@@ -589,7 +608,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
589
|
608
|
MachOSymbol* symbol = &oc->info->macho_symbols[ri->r_symbolnum];
|
590
|
609
|
int64_t addend = decodeAddend(oc, section, ri);
|
591
|
610
|
uint64_t value = symbol_value(oc, symbol);
|
592
|
|
- encodeAddend(oc, section, ri, value + addend);
|
|
611
|
+ encodeAddend(oc, section, ri, value + addend, symbol);
|
593
|
612
|
break;
|
594
|
613
|
}
|
595
|
614
|
case ARM64_RELOC_SUBTRACTOR:
|
... |
... |
@@ -623,7 +642,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
623
|
642
|
|
624
|
643
|
// combine with addend and store
|
625
|
644
|
int64_t addend = decodeAddend(oc, section, ri);
|
626
|
|
- encodeAddend(oc, section, ri, addend - sub_value + add_value);
|
|
645
|
+ encodeAddend(oc, section, ri, addend - sub_value + add_value, symbol1);
|
627
|
646
|
|
628
|
647
|
// skip next relocation: we've already handled it
|
629
|
648
|
i += 1;
|
... |
... |
@@ -664,7 +683,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
664
|
683
|
}
|
665
|
684
|
}
|
666
|
685
|
}
|
667
|
|
- encodeAddend(oc, section, ri, value - pc + addend);
|
|
686
|
+ encodeAddend(oc, section, ri, value - pc + addend, symbol);
|
668
|
687
|
break;
|
669
|
688
|
}
|
670
|
689
|
case ARM64_RELOC_PAGE21:
|
... |
... |
@@ -676,7 +695,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
676
|
695
|
uint64_t pc = (uint64_t)section->start + ri->r_address;
|
677
|
696
|
uint64_t value = (uint64_t)(isGotLoad(ri) ? symbol->got_addr : symbol->addr);
|
678
|
697
|
ASSERT(!isGotLoad(ri) || (symbol->got_addr != 0));
|
679
|
|
- encodeAddend(oc, section, ri, ((value + addend + explicit_addend) & (-4096)) - (pc & (-4096)));
|
|
698
|
+ encodeAddend(oc, section, ri, ((value + addend + explicit_addend) & (-4096)) - (pc & (-4096)), symbol);
|
680
|
699
|
|
681
|
700
|
// reset, just in case.
|
682
|
701
|
explicit_addend = 0;
|
... |
... |
@@ -690,7 +709,7 @@ relocateSectionAarch64(ObjectCode * oc, Section * section) |
690
|
709
|
barf("explicit_addend and addend can't be set at the same time.");
|
691
|
710
|
uint64_t value = (uint64_t)(isGotLoad(ri) ? symbol->got_addr : symbol->addr);
|
692
|
711
|
ASSERT(!isGotLoad(ri) || (symbol->got_addr != 0));
|
693
|
|
- encodeAddend(oc, section, ri, 0xFFF & (value + addend + explicit_addend));
|
|
712
|
+ encodeAddend(oc, section, ri, 0xFFF & (value + addend + explicit_addend), symbol);
|
694
|
713
|
|
695
|
714
|
// reset, just in case.
|
696
|
715
|
explicit_addend = 0;
|