diff options
author | Fangrui Song <i@maskray.me> | 2023-02-23 22:11:14 -0800 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2023-02-23 22:11:14 -0800 |
commit | 50980ba351856dff75bb0743bfca62f4c3ab19ff (patch) | |
tree | 57293555d30735da578d765d9d4058b46d237df9 /bfd | |
parent | 6777dece58127236db900215857f9070ad63e0bf (diff) | |
download | binutils-50980ba351856dff75bb0743bfca62f4c3ab19ff.zip binutils-50980ba351856dff75bb0743bfca62f4c3ab19ff.tar.gz binutils-50980ba351856dff75bb0743bfca62f4c3ab19ff.tar.bz2 |
RISC-V: Add --[no-]relax-gp to ld
--relax enables all relaxations. --no-relax-gp disables GP relaxation to
allow measuring its effect.
The option can test effectiveness of GP relaxation and support some ABI
variants that use GP for other purposes.
Link: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/298
bfd/
* elfnn-riscv.c (struct riscv_elf_link_hash_table): Add params.
(riscv_elfNN_set_options): New.
(riscv_info_to_howto_rela): Check relax_gp.
(_bfd_riscv_relax_section): Likewise.
* elfxx-riscv.h (struct riscv_elf_params): New.
(riscv_elf32_set_options): New.
(riscv_elf64_set_options): New.
ld/
* emultempl/riscvelf.em: Add option parsing.
* testsuite/ld-riscv-elf/code-model-relax-medlow-01-norelaxgp.d: New.
* testsuite/ld-riscv-elf/pcgp-relax-01-norelaxgp.d: New.
* testsuite/ld-riscv-elf/pcgp-relax-02.d: Test --relax --relax-gp can be
used together.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/elfnn-riscv.c | 16 | ||||
-rw-r--r-- | bfd/elfxx-riscv.h | 11 |
3 files changed, 35 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b7c03c1..50e1e17 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2023-02-23 Fangrui Song <i@maskray.me> + + * elfnn-riscv.c (struct riscv_elf_link_hash_table): Add params. + (riscv_elfNN_set_options): New. + (riscv_info_to_howto_rela): Check relax_gp. + (_bfd_riscv_relax_section): Likewise. + * elfxx-riscv.h (struct riscv_elf_params): New. + (riscv_elf32_set_options): New. + (riscv_elf64_set_options): New. + 2023-02-23 Nick Clifton <nickc@redhat.com> Alan Modra <amodra@gmail.com> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 355ddb2..1200e6b 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -118,6 +118,9 @@ struct riscv_elf_link_hash_table { struct elf_link_hash_table elf; + /* Various options and other info passed from the linker. */ + struct riscv_elf_params *params; + /* Short-cuts to get to dynamic linker sections. */ asection *sdyntdata; @@ -157,6 +160,13 @@ struct riscv_elf_link_hash_table && elf_hash_table_id (elf_hash_table (p)) == RISCV_ELF_DATA) \ ? (struct riscv_elf_link_hash_table *) (p)->hash : NULL) +void +riscv_elfNN_set_options (struct bfd_link_info *link_info, + struct riscv_elf_params *params) +{ + riscv_elf_hash_table (link_info)->params = params; +} + static bool riscv_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, @@ -4389,7 +4399,9 @@ _bfd_riscv_relax_lui (bfd *abfd, bool undefined_weak) { bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; - bfd_vma gp = riscv_global_pointer_value (link_info); + bfd_vma gp = riscv_elf_hash_table (link_info)->params->relax_gp + ? riscv_global_pointer_value (link_info) + : 0; int use_rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC; BFD_ASSERT (rel->r_offset + 4 <= sec->size); @@ -4834,7 +4846,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec, || type == R_RISCV_TPREL_LO12_I || type == R_RISCV_TPREL_LO12_S) relax_func = _bfd_riscv_relax_tls_le; - else if (!bfd_link_pic (info) + else if (!bfd_link_pic (info) && htab->params->relax_gp && (type == R_RISCV_PCREL_HI20 || type == R_RISCV_PCREL_LO12_I || type == R_RISCV_PCREL_LO12_S)) diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h index 5e1bdae..abcb409 100644 --- a/bfd/elfxx-riscv.h +++ b/bfd/elfxx-riscv.h @@ -27,6 +27,17 @@ #define RISCV_UNKNOWN_VERSION -1 +struct riscv_elf_params +{ + /* Whether to relax code sequences to GP-relative addressing. */ + bool relax_gp; +}; + +extern void riscv_elf32_set_options (struct bfd_link_info *, + struct riscv_elf_params *); +extern void riscv_elf64_set_options (struct bfd_link_info *, + struct riscv_elf_params *); + extern reloc_howto_type * riscv_reloc_name_lookup (bfd *, const char *); |