@@ -4085,6 +4085,11 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
40854085 return false;
40864086}
40874087
4088+ /* Enabled relaxation features to use. */
4089+ #define RISCV_RELAX_RVC 0x01U
4090+ #define RISCV_RELAX_GP 0x02U
4091+ #define RISCV_RELAX_PIC 0x04U
4092+
40884093/* A second format for recording PC-relative hi relocations. This stores the
40894094 information required to relax them to GP-relative addresses. */
40904095
@@ -4471,7 +4476,8 @@ typedef bool (*relax_func_t) (bfd *, asection *, asection *,
44714476 Elf_Internal_Rela * ,
44724477 bfd_vma , bfd_vma , bfd_vma , bool * ,
44734478 riscv_pcgp_relocs * ,
4474- bool undefined_weak );
4479+ bool undefined_weak ,
4480+ unsigned relax_features );
44754481
44764482/* Relax AUIPC + JALR into JAL. */
44774483
@@ -4484,13 +4490,15 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
44844490 bfd_vma reserve_size ATTRIBUTE_UNUSED ,
44854491 bool * again ,
44864492 riscv_pcgp_relocs * pcgp_relocs ,
4487- bool undefined_weak ATTRIBUTE_UNUSED )
4493+ bool undefined_weak ATTRIBUTE_UNUSED ,
4494+ unsigned relax_features )
44884495{
44894496 bfd_byte * contents = elf_section_data (sec )-> this_hdr .contents ;
44904497 bfd_vma foff = symval - (sec_addr (sec ) + rel -> r_offset );
44914498 bool near_zero = (symval + RISCV_IMM_REACH / 2 ) < RISCV_IMM_REACH ;
4499+ bool rvc = (relax_features & RISCV_RELAX_RVC ) != 0 ;
44924500 bfd_vma auipc , jalr ;
4493- int rd , r_type , len = 4 , rvc = elf_elfheader ( abfd ) -> e_flags & EF_RISCV_RVC ;
4501+ int rd , r_type , len = 4 ;
44944502
44954503 /* If the call crosses section boundaries, an alignment directive could
44964504 cause the PC-relative offset to later increase, so we need to add in the
@@ -4505,7 +4513,8 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
45054513 }
45064514
45074515 /* See if this function call can be shortened. */
4508- if (!VALID_JTYPE_IMM (foff ) && !(!bfd_link_pic (link_info ) && near_zero ))
4516+ if (!VALID_JTYPE_IMM (foff )
4517+ && !(!(relax_features & RISCV_RELAX_PIC ) && near_zero ))
45094518 return true;
45104519
45114520 /* Shorten the function call. */
@@ -4590,15 +4599,16 @@ _bfd_riscv_relax_lui (bfd *abfd,
45904599 bfd_vma reserve_size ,
45914600 bool * again ,
45924601 riscv_pcgp_relocs * pcgp_relocs ,
4593- bool undefined_weak )
4602+ bool undefined_weak ,
4603+ unsigned relax_features )
45944604{
45954605 struct riscv_elf_link_hash_table * htab = riscv_elf_hash_table (link_info );
45964606 bfd_byte * contents = elf_section_data (sec )-> this_hdr .contents ;
45974607 /* Can relax to x0 even when gp relaxation is disabled. */
4598- bfd_vma gp = htab -> params -> relax_gp
4608+ bfd_vma gp = ( relax_features & RISCV_RELAX_GP ) != 0
45994609 ? riscv_global_pointer_value (link_info )
46004610 : 0 ;
4601- int use_rvc = elf_elfheader ( abfd ) -> e_flags & EF_RISCV_RVC ;
4611+ bool use_rvc = ( relax_features & RISCV_RELAX_RVC ) != 0 ;
46024612
46034613 BFD_ASSERT (rel -> r_offset + 4 <= sec -> size );
46044614
@@ -4703,7 +4713,8 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
47034713 bfd_vma reserve_size ATTRIBUTE_UNUSED ,
47044714 bool * again ,
47054715 riscv_pcgp_relocs * pcgp_relocs ,
4706- bool undefined_weak ATTRIBUTE_UNUSED )
4716+ bool undefined_weak ATTRIBUTE_UNUSED ,
4717+ unsigned relax_features ATTRIBUTE_UNUSED )
47074718{
47084719 /* See if this symbol is in range of tp. */
47094720 if (RISCV_CONST_HIGH_PART (tpoff (link_info , symval )) != 0 )
@@ -4745,7 +4756,8 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
47454756 bfd_vma reserve_size ATTRIBUTE_UNUSED ,
47464757 bool * again ATTRIBUTE_UNUSED ,
47474758 riscv_pcgp_relocs * pcgp_relocs ATTRIBUTE_UNUSED ,
4748- bool undefined_weak ATTRIBUTE_UNUSED )
4759+ bool undefined_weak ATTRIBUTE_UNUSED ,
4760+ unsigned relax_features ATTRIBUTE_UNUSED )
47494761{
47504762 bfd_byte * contents = elf_section_data (sec )-> this_hdr .contents ;
47514763 bfd_vma alignment = 1 , pos ;
@@ -4805,11 +4817,12 @@ _bfd_riscv_relax_pc (bfd *abfd ATTRIBUTE_UNUSED,
48054817 bfd_vma reserve_size ,
48064818 bool * again ,
48074819 riscv_pcgp_relocs * pcgp_relocs ,
4808- bool undefined_weak )
4820+ bool undefined_weak ,
4821+ unsigned relax_features )
48094822{
48104823 struct riscv_elf_link_hash_table * htab = riscv_elf_hash_table (link_info );
48114824 /* Can relax to x0 even when gp relaxation is disabled. */
4812- bfd_vma gp = htab -> params -> relax_gp
4825+ bfd_vma gp = ( relax_features & RISCV_RELAX_GP ) != 0
48134826 ? riscv_global_pointer_value (link_info )
48144827 : 0 ;
48154828
@@ -4965,6 +4978,15 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
49654978 bfd_vma max_alignment , reserve_size = 0 ;
49664979 riscv_pcgp_relocs pcgp_relocs ;
49674980 static asection * first_section = NULL ;
4981+ unsigned relax_features = 0 ;
4982+
4983+ /* Detect available/enabled relaxation features. */
4984+ if (elf_elfheader (abfd )-> e_flags & EF_RISCV_RVC )
4985+ relax_features |= RISCV_RELAX_RVC ;
4986+ if (htab -> params -> relax_gp )
4987+ relax_features |= RISCV_RELAX_GP ;
4988+ if (bfd_link_pic (info ))
4989+ relax_features |= RISCV_RELAX_PIC ;
49684990
49694991 * again = false;
49704992
@@ -5032,7 +5054,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
50325054 || type == R_RISCV_TPREL_LO12_I
50335055 || type == R_RISCV_TPREL_LO12_S )
50345056 relax_func = _bfd_riscv_relax_tls_le ;
5035- else if (!bfd_link_pic ( info )
5057+ else if (!( relax_features & RISCV_RELAX_PIC )
50365058 && (type == R_RISCV_PCREL_HI20
50375059 || type == R_RISCV_PCREL_LO12_I
50385060 || type == R_RISCV_PCREL_LO12_S ))
@@ -5145,7 +5167,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
51455167
51465168 /* This line has to match the check in riscv_elf_relocate_section
51475169 in the R_RISCV_CALL[_PLT] case. */
5148- if (bfd_link_pic ( info ) && h -> plt .offset != MINUS_ONE )
5170+ if (( relax_features & RISCV_RELAX_PIC ) && h -> plt .offset != MINUS_ONE )
51495171 {
51505172 sym_sec = htab -> elf .splt ;
51515173 symval = h -> plt .offset ;
@@ -5208,7 +5230,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
52085230
52095231 if (!relax_func (abfd , sec , sym_sec , info , rel , symval ,
52105232 max_alignment , reserve_size , again ,
5211- & pcgp_relocs , undefined_weak ))
5233+ & pcgp_relocs , undefined_weak , relax_features ))
52125234 goto fail ;
52135235 }
52145236
0 commit comments