aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2023-02-23 22:11:14 -0800
committerFangrui Song <i@maskray.me>2023-02-23 22:11:14 -0800
commit50980ba351856dff75bb0743bfca62f4c3ab19ff (patch)
tree57293555d30735da578d765d9d4058b46d237df9 /bfd
parent6777dece58127236db900215857f9070ad63e0bf (diff)
downloadbinutils-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/ChangeLog10
-rw-r--r--bfd/elfnn-riscv.c16
-rw-r--r--bfd/elfxx-riscv.h11
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 *);