@@ -102,6 +102,26 @@ static uint32_t setLO12_S(uint32_t insn, uint32_t imm) {
102102 (extractBits (imm, 4 , 0 ) << 7 );
103103}
104104
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+
105125RISCV::RISCV () {
106126 copyRel = R_RISCV_COPY;
107127 pltRel = R_RISCV_JUMP_SLOT;
@@ -520,14 +540,19 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
520540 }
521541}
522542
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+
523547void RISCV::relocateAlloc (InputSectionBase &sec, uint8_t *buf) const {
524548 uint64_t secAddr = sec.getOutputSection ()->addr ;
525549 if (auto *s = dyn_cast<InputSection>(&sec))
526550 secAddr += s->outSecOff ;
527551 else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
528552 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];
531556 uint8_t *loc = buf + rel.offset ;
532557 const uint64_t val =
533558 sec.getRelocTargetVA (sec.file , rel.type , rel.addend ,
@@ -538,7 +563,7 @@ void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
538563 break ;
539564 case R_RISCV_LEB128:
540565 if (i + 1 < size) {
541- const Relocation &rel1 = sec. relocs () [i + 1 ];
566+ const Relocation &rel1 = relocs[i + 1 ];
542567 if (rel.type == R_RISCV_SET_ULEB128 &&
543568 rel1.type == R_RISCV_SUB_ULEB128 && rel.offset == rel1.offset ) {
544569 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 {
560585 }
561586}
562587
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-
583588static void initSymbolAnchors () {
584589 SmallVector<InputSection *, 0 > storage;
585590 for (OutputSection *osec : outputSections) {
@@ -715,14 +720,15 @@ static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
715720
716721static bool relax (InputSection &sec) {
717722 const uint64_t secAddr = sec.getVA ();
723+ const MutableArrayRef<Relocation> relocs = sec.relocs ();
718724 auto &aux = *sec.relaxAux ;
719725 bool changed = false ;
720726 ArrayRef<SymbolAnchor> sa = ArrayRef (aux.anchors );
721727 uint64_t delta = 0 ;
722728
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);
724730 aux.writes .clear ();
725- for (auto [i, r] : llvm::enumerate (sec. relocs () )) {
731+ for (auto [i, r] : llvm::enumerate (relocs)) {
726732 const uint64_t loc = secAddr + r.offset - delta;
727733 uint32_t &cur = aux.relocDeltas [i], remove = 0 ;
728734 switch (r.type ) {
@@ -743,23 +749,20 @@ static bool relax(InputSection &sec) {
743749 }
744750 case R_RISCV_CALL:
745751 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))
748753 relaxCall (sec, i, loc, r, remove);
749754 break ;
750755 case R_RISCV_TPREL_HI20:
751756 case R_RISCV_TPREL_ADD:
752757 case R_RISCV_TPREL_LO12_I:
753758 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))
756760 relaxTlsLe (sec, i, loc, r, remove);
757761 break ;
758762 case R_RISCV_HI20:
759763 case R_RISCV_LO12_I:
760764 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))
763766 relaxHi20Lo12 (sec, i, loc, r, remove);
764767 break ;
765768 }
0 commit comments