@@ -45,21 +45,7 @@ class RISCV final : public TargetInfo {
4545 uint64_t val) const override ;
4646 void relocateAlloc (InputSectionBase &sec, uint8_t *buf) const override ;
4747 bool relaxOnce (int pass) const override ;
48- template <class ELFT , class RelTy >
49- bool synthesizeAlignForInput (uint64_t &dot, InputSection *sec,
50- Relocs<RelTy> rels);
51- template <class ELFT , class RelTy >
52- void finalizeSynthesizeAligns (uint64_t &dot, InputSection *sec,
53- Relocs<RelTy> rels);
54- template <class ELFT >
55- bool synthesizeAlignAux (uint64_t &dot, InputSection *sec);
56- bool synthesizeAlign (uint64_t &dot, InputSection *sec) override ;
5748 void finalizeRelax (int passes) const override ;
58-
59- // The following two variables are used by synthesized ALIGN relocations.
60- InputSection *baseSec = nullptr ;
61- // r_offset and r_addend pairs.
62- SmallVector<std::pair<uint64_t , uint64_t >, 0 > synthesizedAligns;
6349};
6450
6551} // end anonymous namespace
@@ -970,116 +956,6 @@ bool RISCV::relaxOnce(int pass) const {
970956 return changed;
971957}
972958
973- // If the section alignment is >= 4, advance `dot` to insert NOPs and synthesize
974- // an ALIGN relocation. Otherwise, return false to use default handling.
975- template <class ELFT , class RelTy >
976- bool RISCV::synthesizeAlignForInput (uint64_t &dot, InputSection *sec,
977- Relocs<RelTy> rels) {
978- if (!baseSec) {
979- // Record the first input section with RELAX relocations. We will synthesize
980- // ALIGN relocations here.
981- for (auto rel : rels) {
982- if (rel.getType (false ) == R_RISCV_RELAX) {
983- baseSec = sec;
984- break ;
985- }
986- }
987- } else if (sec->addralign >= 4 ) {
988- // If the alignment is >= 4 and the section does not start with an ALIGN
989- // relocation, synthesize one.
990- bool hasAlignRel = llvm::any_of (rels, [](const RelTy &rel) {
991- return rel.r_offset == 0 && rel.getType (false ) == R_RISCV_ALIGN;
992- });
993- if (!hasAlignRel) {
994- synthesizedAligns.emplace_back (dot - baseSec->getVA (),
995- sec->addralign - 2 );
996- dot += sec->addralign - 2 ;
997- return true ;
998- }
999- }
1000- return false ;
1001- }
1002-
1003- // Finalize the relocation section by appending synthesized ALIGN relocations
1004- // after processing all input sections.
1005- template <class ELFT , class RelTy >
1006- void RISCV::finalizeSynthesizeAligns (uint64_t &dot, InputSection *sec,
1007- Relocs<RelTy> rels) {
1008- auto *f = cast<ObjFile<ELFT>>(baseSec->file );
1009- auto shdr = f->template getELFShdrs <ELFT>()[baseSec->relSecIdx ];
1010- // Create a copy of InputSection.
1011- sec = make<InputSection>(*f, shdr, baseSec->name );
1012- auto *baseRelSec = cast<InputSection>(f->getSections ()[baseSec->relSecIdx ]);
1013- *sec = *baseRelSec;
1014- baseSec = nullptr ;
1015-
1016- // Allocate buffer for original and synthesized relocations in RELA format.
1017- // If CREL is used, OutputSection::finalizeNonAllocCrel will convert RELA to
1018- // CREL.
1019- auto newSize = rels.size () + synthesizedAligns.size ();
1020- auto *relas = makeThreadLocalN<typename ELFT::Rela>(newSize);
1021- sec->size = newSize * sizeof (typename ELFT::Rela);
1022- sec->content_ = reinterpret_cast <uint8_t *>(relas);
1023- sec->type = SHT_RELA;
1024- // Copy original relocations to the new buffer, potentially converting CREL to
1025- // RELA.
1026- for (auto [i, r] : llvm::enumerate (rels)) {
1027- relas[i].r_offset = r.r_offset ;
1028- relas[i].setSymbolAndType (r.getSymbol (0 ), r.getType (0 ), false );
1029- if constexpr (RelTy::HasAddend)
1030- relas[i].r_addend = r.r_addend ;
1031- }
1032- // Append synthesized ALIGN relocations to the buffer.
1033- for (auto [i, r] : llvm::enumerate (synthesizedAligns)) {
1034- auto &rela = relas[rels.size () + i];
1035- rela.r_offset = r.first ;
1036- rela.setSymbolAndType (0 , R_RISCV_ALIGN, false );
1037- rela.r_addend = r.second ;
1038- }
1039- // Replace the old relocation section with the new one in the output section.
1040- // addOrphanSections ensures that the output relocation section is processed
1041- // after osec.
1042- for (SectionCommand *cmd : sec->getParent ()->commands ) {
1043- auto *isd = dyn_cast<InputSectionDescription>(cmd);
1044- if (!isd)
1045- continue ;
1046- for (auto *&isec : isd->sections )
1047- if (isec == baseRelSec)
1048- isec = sec;
1049- }
1050- }
1051-
1052- template <class ELFT >
1053- bool RISCV::synthesizeAlignAux (uint64_t &dot, InputSection *sec) {
1054- bool ret = false ;
1055- if (sec) {
1056- invokeOnRelocs (*sec, ret = synthesizeAlignForInput<ELFT>, dot, sec);
1057- } else if (baseSec) {
1058- invokeOnRelocs (*baseSec, finalizeSynthesizeAligns<ELFT>, dot, sec);
1059- }
1060- return ret;
1061- }
1062-
1063- // Without linker relaxation enabled for a particular relocatable file or
1064- // section, the assembler will not generate R_RISCV_ALIGN relocations for
1065- // alignment directives. This becomes problematic in a two-stage linking
1066- // process: ld -r a.o b.o -o ab.o; ld ab.o -o ab. This function synthesizes an
1067- // R_RISCV_ALIGN relocation at section start when needed.
1068- //
1069- // When called with an input section (`sec` is not null): If the section
1070- // alignment is >= 4, advance `dot` to insert NOPs and synthesize an ALIGN
1071- // relocation.
1072- //
1073- // When called after all input sections are processed (`sec` is null): The
1074- // output relocation section is updated with all the newly synthesized ALIGN
1075- // relocations.
1076- bool RISCV::synthesizeAlign (uint64_t &dot, InputSection *sec) {
1077- assert (ctx.arg .relocatable );
1078- if (ctx.arg .is64 )
1079- return synthesizeAlignAux<ELF64LE>(dot, sec);
1080- return synthesizeAlignAux<ELF32LE>(dot, sec);
1081- }
1082-
1083959void RISCV::finalizeRelax (int passes) const {
1084960 llvm::TimeTraceScope timeScope (" Finalize RISC-V relaxation" );
1085961 Log (ctx) << " relaxation passes: " << passes;
0 commit comments