diff options
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/elfnn-riscv.c | 16 | ||||
-rw-r--r-- | bfd/elfxx-riscv.h | 11 | ||||
-rw-r--r-- | ld/ChangeLog | 8 | ||||
-rw-r--r-- | ld/emultempl/riscvelf.em | 36 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/code-model-relax-medlow-01-norelaxgp.d | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/pcgp-relax-01-norelaxgp.d | 18 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/pcgp-relax-02.d | 2 |
9 files changed, 104 insertions, 3 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 *); diff --git a/ld/ChangeLog b/ld/ChangeLog index de9ed27..9f4ad7c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2023-02-23 Fangrui Song <i@maskray.me> + + * 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. + 2023-02-20 Nick Clifton <nickc@redhat.com> PR 30004 diff --git a/ld/emultempl/riscvelf.em b/ld/emultempl/riscvelf.em index b12d150..bb6298d 100644 --- a/ld/emultempl/riscvelf.em +++ b/ld/emultempl/riscvelf.em @@ -25,6 +25,40 @@ fragment <<EOF #include "elf/riscv.h" #include "elfxx-riscv.h" +static struct riscv_elf_params params = { .relax_gp = 1 }; +EOF + +# Define some shell vars to insert bits of code into the standard elf +# parse_args and list_options functions. */ +PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}' +enum risccv_opt +{ + OPTION_RELAX_GP = 321, + OPTION_NO_RELAX_GP, +}; +' + +PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}' + { "relax-gp", no_argument, NULL, OPTION_RELAX_GP }, + { "no-relax-gp", no_argument, NULL, OPTION_NO_RELAX_GP }, +' + +PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}' + fprintf (file, _(" --relax-gp Perform GP relaxation\n")); + fprintf (file, _(" --no-relax-gp Don'\''t perform GP relaxation\n")); +' + +PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}' + case OPTION_RELAX_GP: + params.relax_gp = 1; + break; + + case OPTION_NO_RELAX_GP: + params.relax_gp = 0; + break; +' + +fragment <<EOF static void riscv_elf_before_allocation (void) { @@ -96,6 +130,8 @@ riscv_create_output_section_statements (void) " whilst linking %s binaries\n"), "RISC-V"); return; } + + riscv_elf${ELFSIZE}_set_options (&link_info, ¶ms); } EOF diff --git a/ld/testsuite/ld-riscv-elf/code-model-relax-medlow-01-norelaxgp.d b/ld/testsuite/ld-riscv-elf/code-model-relax-medlow-01-norelaxgp.d new file mode 100644 index 0000000..8e40cc5 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/code-model-relax-medlow-01-norelaxgp.d @@ -0,0 +1,4 @@ +#source: code-model.s +#as: -march=rv64i -mabi=lp64 --defsym __medlow__=1 +#ld: -Tcode-model-01.ld -melf64lriscv --no-relax-gp --relax +#error: .*relocation truncated to fit: R_RISCV_HI20 against `symbolL' diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 0f7ccd9..5dd6144 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -122,6 +122,7 @@ if [istarget "riscv*-*-*"] { run_dump_test "align-small-region" run_dump_test "call-relax" run_dump_test "pcgp-relax-01" + run_dump_test "pcgp-relax-01-norelaxgp" run_dump_test "pcgp-relax-02" run_dump_test "c-lui" run_dump_test "c-lui-2" @@ -141,6 +142,7 @@ if [istarget "riscv*-*-*"] { run_dump_test "code-model-medany-weakref-01" run_dump_test "code-model-medany-weakref-02" run_dump_test "code-model-relax-medlow-01" + run_dump_test "code-model-relax-medlow-01-norelaxgp" run_dump_test "code-model-relax-medlow-02" run_dump_test "code-model-relax-medlow-weakref-01" run_dump_test "code-model-relax-medlow-weakref-02" diff --git a/ld/testsuite/ld-riscv-elf/pcgp-relax-01-norelaxgp.d b/ld/testsuite/ld-riscv-elf/pcgp-relax-01-norelaxgp.d new file mode 100644 index 0000000..d134457 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/pcgp-relax-01-norelaxgp.d @@ -0,0 +1,18 @@ +#source: pcgp-relax-01.s +#ld: --no-relax-gp --relax +#objdump: -d -Mno-aliases + +.*:[ ]+file format .* + + +Disassembly of section \.text: + +0+[0-9a-f]+ <_start>: +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+a0,a0,[0-9]+ +.*:[ ]+[0-9a-f]+[ ]+jal[ ]+ra,[0-9a-f]+ <_start> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+a1,0x[0-9a-f]+ +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+a1,a1,[0-9]+ # [0-9a-f]+ <data_g> +.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a2,0x[0-9a-f]+ +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+a2,a2,[0-9]+ # [0-9a-f]+ <data_g> +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+a3,tp,0 # 0 <data_t> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+a0,0x[0-9a-f]+ diff --git a/ld/testsuite/ld-riscv-elf/pcgp-relax-02.d b/ld/testsuite/ld-riscv-elf/pcgp-relax-02.d index 1248132..055f03e 100644 --- a/ld/testsuite/ld-riscv-elf/pcgp-relax-02.d +++ b/ld/testsuite/ld-riscv-elf/pcgp-relax-02.d @@ -1,6 +1,6 @@ #source: pcgp-relax-02.s #as: -#ld: --relax +#ld: --relax --relax-gp #objdump: -d .*:[ ]+file format .* |