@@ -102,6 +102,26 @@ static uint32_t setLO12_S(uint32_t insn, uint32_t imm) {
102
102
(extractBits (imm, 4 , 0 ) << 7 );
103
103
}
104
104
105
+ namespace {
106
+ struct SymbolAnchor {
107
+ uint64_t offset;
108
+ Defined *d;
109
+ bool end; // true for the anchor of st_value+st_size
110
+ };
111
+ } // namespace
112
+
113
+ struct elf ::RISCVRelaxAux {
114
+ // This records symbol start and end offsets which will be adjusted according
115
+ // to the nearest relocDeltas element.
116
+ SmallVector<SymbolAnchor, 0 > anchors;
117
+ // For relocations[i], the actual offset is
118
+ // r_offset - (i ? relocDeltas[i-1] : 0).
119
+ std::unique_ptr<uint32_t []> relocDeltas;
120
+ // For relocations[i], the actual type is relocTypes[i].
121
+ std::unique_ptr<RelType[]> relocTypes;
122
+ SmallVector<uint32_t , 0 > writes;
123
+ };
124
+
105
125
RISCV::RISCV () {
106
126
copyRel = R_RISCV_COPY;
107
127
pltRel = R_RISCV_JUMP_SLOT;
@@ -520,14 +540,19 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
520
540
}
521
541
}
522
542
543
+ static bool relaxable (ArrayRef<Relocation> relocs, size_t i) {
544
+ return i + 1 != relocs.size () && relocs[i + 1 ].type == R_RISCV_RELAX;
545
+ }
546
+
523
547
void RISCV::relocateAlloc (InputSectionBase &sec, uint8_t *buf) const {
524
548
uint64_t secAddr = sec.getOutputSection ()->addr ;
525
549
if (auto *s = dyn_cast<InputSection>(&sec))
526
550
secAddr += s->outSecOff ;
527
551
else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
528
552
secAddr += ehIn->getParent ()->outSecOff ;
529
- for (size_t i = 0 , size = sec.relocs ().size (); i != size; ++i) {
530
- const Relocation &rel = sec.relocs ()[i];
553
+ const ArrayRef<Relocation> relocs = sec.relocs ();
554
+ for (size_t i = 0 , size = relocs.size (); i != size; ++i) {
555
+ const Relocation &rel = relocs[i];
531
556
uint8_t *loc = buf + rel.offset ;
532
557
const uint64_t val =
533
558
sec.getRelocTargetVA (sec.file , rel.type , rel.addend ,
@@ -538,7 +563,7 @@ void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
538
563
break ;
539
564
case R_RISCV_LEB128:
540
565
if (i + 1 < size) {
541
- const Relocation &rel1 = sec. relocs () [i + 1 ];
566
+ const Relocation &rel1 = relocs[i + 1 ];
542
567
if (rel.type == R_RISCV_SET_ULEB128 &&
543
568
rel1.type == R_RISCV_SUB_ULEB128 && rel.offset == rel1.offset ) {
544
569
auto val = rel.sym ->getVA (rel.addend ) - rel1.sym ->getVA (rel1.addend );
@@ -560,26 +585,6 @@ void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
560
585
}
561
586
}
562
587
563
- namespace {
564
- struct SymbolAnchor {
565
- uint64_t offset;
566
- Defined *d;
567
- bool end; // true for the anchor of st_value+st_size
568
- };
569
- } // namespace
570
-
571
- struct elf ::RISCVRelaxAux {
572
- // This records symbol start and end offsets which will be adjusted according
573
- // to the nearest relocDeltas element.
574
- SmallVector<SymbolAnchor, 0 > anchors;
575
- // For relocations[i], the actual offset is r_offset - (i ? relocDeltas[i-1] :
576
- // 0).
577
- std::unique_ptr<uint32_t []> relocDeltas;
578
- // For relocations[i], the actual type is relocTypes[i].
579
- std::unique_ptr<RelType[]> relocTypes;
580
- SmallVector<uint32_t , 0 > writes;
581
- };
582
-
583
588
static void initSymbolAnchors () {
584
589
SmallVector<InputSection *, 0 > storage;
585
590
for (OutputSection *osec : outputSections) {
@@ -715,14 +720,15 @@ static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
715
720
716
721
static bool relax (InputSection &sec) {
717
722
const uint64_t secAddr = sec.getVA ();
723
+ const MutableArrayRef<Relocation> relocs = sec.relocs ();
718
724
auto &aux = *sec.relaxAux ;
719
725
bool changed = false ;
720
726
ArrayRef<SymbolAnchor> sa = ArrayRef (aux.anchors );
721
727
uint64_t delta = 0 ;
722
728
723
- std::fill_n (aux.relocTypes .get (), sec. relocs () .size (), R_RISCV_NONE);
729
+ std::fill_n (aux.relocTypes .get (), relocs.size (), R_RISCV_NONE);
724
730
aux.writes .clear ();
725
- for (auto [i, r] : llvm::enumerate (sec. relocs () )) {
731
+ for (auto [i, r] : llvm::enumerate (relocs)) {
726
732
const uint64_t loc = secAddr + r.offset - delta;
727
733
uint32_t &cur = aux.relocDeltas [i], remove = 0 ;
728
734
switch (r.type ) {
@@ -743,23 +749,20 @@ static bool relax(InputSection &sec) {
743
749
}
744
750
case R_RISCV_CALL:
745
751
case R_RISCV_CALL_PLT:
746
- if (i + 1 != sec.relocs ().size () &&
747
- sec.relocs ()[i + 1 ].type == R_RISCV_RELAX)
752
+ if (relaxable (relocs, i))
748
753
relaxCall (sec, i, loc, r, remove);
749
754
break ;
750
755
case R_RISCV_TPREL_HI20:
751
756
case R_RISCV_TPREL_ADD:
752
757
case R_RISCV_TPREL_LO12_I:
753
758
case R_RISCV_TPREL_LO12_S:
754
- if (i + 1 != sec.relocs ().size () &&
755
- sec.relocs ()[i + 1 ].type == R_RISCV_RELAX)
759
+ if (relaxable (relocs, i))
756
760
relaxTlsLe (sec, i, loc, r, remove);
757
761
break ;
758
762
case R_RISCV_HI20:
759
763
case R_RISCV_LO12_I:
760
764
case R_RISCV_LO12_S:
761
- if (i + 1 != sec.relocs ().size () &&
762
- sec.relocs ()[i + 1 ].type == R_RISCV_RELAX)
765
+ if (relaxable (relocs, i))
763
766
relaxHi20Lo12 (sec, i, loc, r, remove);
764
767
break ;
765
768
}
0 commit comments