From d0f744f970225f68460eb36a4975ae92a2e9495a Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 21 Feb 2017 21:56:57 -0800 Subject: [PATCH] bfd: RISC-V: relax to gp in more cases. bfd/ChangeLog: 2017-02-24 Andrew Waterman * elfnn-riscv.c (GP_NAME): New macro. (riscv_global_pointer_value): Use it. (_bfd_riscv_relax_lui): If symbol and global pointer are in same output section, consider only that section's alignment. --- bfd/ChangeLog | 7 +++++++ bfd/elfnn-riscv.c | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7435d5abdcf..7eda9630c90 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2017-02-24 Andrew Waterman + + * elfnn-riscv.c (GP_NAME): New macro. + (riscv_global_pointer_value): Use it. + (_bfd_riscv_relax_lui): If symbol and global pointer are in same + output section, consider only that section's alignment. + 2017-02-23 Maciej W. Rozycki * elfxx-mips.h (_bfd_mips_relax_section): Remove prototype. diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 6c14313310a..2ccfc5f08fb 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -52,6 +52,10 @@ #define ELF_MAXPAGESIZE 0x1000 #define ELF_COMMONPAGESIZE 0x1000 +/* The global pointer's symbol name. */ + +#define GP_NAME "__global_pointer$" + /* The RISC-V linker needs to keep track of the number of relocs that it decides to copy as dynamic relocs in check_relocs for each symbol. This is so that it can later discard them if they are found to be @@ -1463,7 +1467,7 @@ riscv_global_pointer_value (struct bfd_link_info *info) { struct bfd_link_hash_entry *h; - h = bfd_link_hash_lookup (info->hash, "__global_pointer$", FALSE, FALSE, TRUE); + h = bfd_link_hash_lookup (info->hash, GP_NAME, FALSE, FALSE, TRUE); if (h == NULL || h->type != bfd_link_hash_defined) return 0; @@ -2809,6 +2813,16 @@ _bfd_riscv_relax_lui (bfd *abfd, BFD_ASSERT (rel->r_offset + 4 <= sec->size); + if (gp) + { + /* If gp and the symbol are in the same output section, then + consider only that section's alignment. */ + struct bfd_link_hash_entry *h = + bfd_link_hash_lookup (link_info->hash, GP_NAME, FALSE, FALSE, TRUE); + if (h->u.def.section->output_section == sym_sec->output_section) + max_alignment = (bfd_vma) 1 << sym_sec->output_section->alignment_power; + } + /* Is the reference in range of x0 or gp? Valid gp range conservatively because of alignment issue. */ if (VALID_ITYPE_IMM (symval) -- 2.30.2