@@ -45,21 +45,7 @@ class RISCV final : public TargetInfo {
45
45
uint64_t val) const override ;
46
46
void relocateAlloc (InputSectionBase &sec, uint8_t *buf) const override ;
47
47
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 ;
57
48
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;
63
49
};
64
50
65
51
} // end anonymous namespace
@@ -970,116 +956,6 @@ bool RISCV::relaxOnce(int pass) const {
970
956
return changed;
971
957
}
972
958
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
-
1083
959
void RISCV::finalizeRelax (int passes) const {
1084
960
llvm::TimeTraceScope timeScope (" Finalize RISC-V relaxation" );
1085
961
Log (ctx) << " relaxation passes: " << passes;
0 commit comments