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.
This commit is contained in:
parent
6777dece58
commit
50980ba351
9 changed files with 104 additions and 3 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
|
@ -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"
|
||||
|
|
18
ld/testsuite/ld-riscv-elf/pcgp-relax-01-norelaxgp.d
Normal file
18
ld/testsuite/ld-riscv-elf/pcgp-relax-01-norelaxgp.d
Normal file
|
@ -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]+
|
|
@ -1,6 +1,6 @@
|
|||
#source: pcgp-relax-02.s
|
||||
#as:
|
||||
#ld: --relax
|
||||
#ld: --relax --relax-gp
|
||||
#objdump: -d
|
||||
|
||||
.*:[ ]+file format .*
|
||||
|
|
Loading…
Add table
Reference in a new issue