Skip to content

Commit f94a0a1

Browse files
committed
RISC-V: Group linker relaxation features
It does not only deduplicate multiple relaxation feature detection, but enable more complex features so that querying the feature availability will get too slow if we perform it per-relocation (not per-section). Even if that wouldn't happen any time soon, it will improve the maintainability around the linker relaxation code. bfd/ChangeLog: * elfnn-riscv.c (RISCV_RELAX_RVC, RISCV_RELAX_GP): New. (relax_func_t): Add new relax_features argument. (_bfd_riscv_relax_call): Likewise. Move feature detection to _bfd_riscv_relax_section. Use bool for simplicity. (_bfd_riscv_relax_lui): Likewise. Move feature detection to _bfd_riscv_relax_section. (_bfd_riscv_relax_tls_le): Likewise but features are not used. (_bfd_riscv_relax_align): Likewise but features are not used. (_bfd_riscv_relax_pc): Likewise. Move feature detection to _bfd_riscv_relax_section. (_bfd_riscv_relax_section): Detect relaxation-related features and pass the flags to each relaxation function. Use the PIC feature flag generated by itself.
1 parent d08515a commit f94a0a1

File tree

1 file changed

+36
-14
lines changed

1 file changed

+36
-14
lines changed

bfd/elfnn-riscv.c

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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))
@@ -5151,7 +5173,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
51515173

51525174
/* This line has to match the check in riscv_elf_relocate_section
51535175
in the R_RISCV_CALL[_PLT] case. */
5154-
if (bfd_link_pic (info) && h->plt.offset != MINUS_ONE)
5176+
if ((relax_features & RISCV_RELAX_PIC) && h->plt.offset != MINUS_ONE)
51555177
{
51565178
sym_sec = htab->elf.splt;
51575179
symval = h->plt.offset;
@@ -5214,7 +5236,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
52145236

52155237
if (!relax_func (abfd, sec, sym_sec, info, rel, symval,
52165238
max_alignment, reserve_size, again,
5217-
&pcgp_relocs, undefined_weak))
5239+
&pcgp_relocs, undefined_weak, relax_features))
52185240
goto fail;
52195241
}
52205242

0 commit comments

Comments
 (0)