[RFC] RISC-V: Fix the 32-bit --enable-targets=all build breakage.

Nelson Chu nelson.chu@sifive.com
Fri Nov 12 08:38:08 GMT 2021


Hi Alan,

I see you have a gcc patch to fix the problem of libopcodes, so should
we still need this patch to fix the --target-all on the 32-bit host
machine?

Thanks
Nelson

On Fri, Nov 12, 2021 at 4:35 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>
> This should be the same problem as the commit,
> ba9b3ef5ee666467b67780e81f868c432f4fc56d.
>
> Generally, the elfxx-* file should be compiled both for 32-bit and 64-bit
> machine, since xx can be 32 and 64.  However, seems like the elfxx-riscv.c
> and elf32-riscv.c are missing for BFD32_BACKENDS_CFILES.
>
> This patch try to add the missing linker files for the BFD32_BACKENDS, but
> the dst_mask of R_RISCV_CALL may be overflow for the host 32-bit machine.
> Therefore, we rewrite the R_RISCV_CALL stuff in the perform_relocation, use
> the two 32-bit bfd_vma values to encode it, since the R_RISCV_CALL should be
> two instructions, rather than one address.
>
> bfd/
>         * Makefile.am: Added elfxx-riscv.* and elf32-riscv.* to
>         BFD32_BACKENDS and BFD32_BACKENDS_CFILES.
>         * Makefile.in: Regernated.
>         * elfnn-riscv.c (perform_relocation): Relocate the R_RISCV_CALL and
>         R_RISCV_CALL_PLT relocs by two bfd_vma values, since they are two
>         insturctions in fact.  So that the rv32 riscv toolchain built on
>         the host 32-bit machine should work.
>         * elfxx-riscv.c (howto_table): Let elfnn-riscv.c:perform_relocation
>         to handle the dst_mask of R_RISCV_CALL and R_RISCV_CALL_PLT specially.
>         Set dst_mask to MINUS_ONE.
> ---
>  bfd/Makefile.am   |  4 ++++
>  bfd/Makefile.in   |  4 ++++
>  bfd/elfnn-riscv.c | 24 +++++++++++++++++++++---
>  bfd/elfxx-riscv.c |  6 ++----
>  4 files changed, 31 insertions(+), 7 deletions(-)
>
> diff --git a/bfd/Makefile.am b/bfd/Makefile.am
> index 097177b..1a935d6 100644
> --- a/bfd/Makefile.am
> +++ b/bfd/Makefile.am
> @@ -336,6 +336,8 @@ BFD32_BACKENDS = \
>         elf32-pj.lo \
>         elf32-ppc.lo \
>         elf32-pru.lo \
> +       elf32-riscv.lo \
> +       elfxx-riscv.lo \
>         elf32-rl78.lo \
>         elf32-rx.lo \
>         elf32-s390.lo \
> @@ -469,6 +471,8 @@ BFD32_BACKENDS_CFILES = \
>         elf32-pj.c \
>         elf32-ppc.c \
>         elf32-pru.c \
> +       elf32-riscv.c \
> +       elfxx-riscv.c \
>         elf32-rl78.c \
>         elf32-rx.c \
>         elf32-s390.c \
> diff --git a/bfd/Makefile.in b/bfd/Makefile.in
> index a76b653..3817167 100644
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -762,6 +762,8 @@ BFD32_BACKENDS = \
>         elf32-pj.lo \
>         elf32-ppc.lo \
>         elf32-pru.lo \
> +       elf32-riscv.lo \
> +       elfxx-riscv.lo \
>         elf32-rl78.lo \
>         elf32-rx.lo \
>         elf32-s390.lo \
> @@ -895,6 +897,8 @@ BFD32_BACKENDS_CFILES = \
>         elf32-pj.c \
>         elf32-ppc.c \
>         elf32-pru.c \
> +       elf32-riscv.lo \
> +       elfxx-riscv.c \
>         elf32-rl78.c \
>         elf32-rx.c \
>         elf32-s390.c \
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index 36cbf1e..024dd32 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -1607,6 +1607,9 @@ perform_relocation (const reloc_howto_type *howto,
>                     bfd *input_bfd,
>                     bfd_byte *contents)
>  {
> +  bool handle_call_special = false;
> +  bfd_vma value_call_auipc, value_call_jalr;
> +
>    if (howto->pc_relative)
>      value -= sec_addr (input_section) + rel->r_offset;
>    value += rel->r_addend;
> @@ -1644,8 +1647,9 @@ perform_relocation (const reloc_howto_type *howto,
>      case R_RISCV_CALL_PLT:
>        if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
>         return bfd_reloc_overflow;
> -      value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value))
> -             | (ENCODE_ITYPE_IMM (value) << 32);
> +      value_call_auipc = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
> +      value_call_jalr = ENCODE_ITYPE_IMM (value);
> +      handle_call_special = true;
>        break;
>
>      case R_RISCV_JAL:
> @@ -1717,6 +1721,21 @@ perform_relocation (const reloc_howto_type *howto,
>        return bfd_reloc_notsupported;
>      }
>
> +  /* Handle R_RISCV_CALL and R_RISCV_CALL_PLT specially, in case the
> +     host machine is 32-bit.  */
> +  if (handle_call_special)
> +    {
> +      bfd_vma insn_auipc = riscv_get_insn (32, contents + rel->r_offset);
> +      bfd_vma insn_jalr = riscv_get_insn (32, contents + rel->r_offset + 0x4);
> +      bfd_vma dst_mask_auipc = ENCODE_UTYPE_IMM (-1U);
> +      bfd_vma dst_mask_jalr = ENCODE_ITYPE_IMM (-1U);
> +      insn_auipc = (insn_auipc & ~dst_mask_auipc) | (value_call_auipc & dst_mask_auipc);
> +      insn_jalr = (insn_jalr & ~dst_mask_jalr) | (value_call_jalr & dst_mask_jalr);
> +      riscv_put_insn (32, insn_auipc, contents + rel->r_offset);
> +      riscv_put_insn (32, insn_jalr, contents + rel->r_offset + 0x4);
> +      return bfd_reloc_ok;
> +    }
> +
>    bfd_vma word;
>    if (riscv_is_insn_reloc (howto))
>      word = riscv_get_insn (howto->bitsize, contents + rel->r_offset);
> @@ -1727,7 +1746,6 @@ perform_relocation (const reloc_howto_type *howto,
>      riscv_put_insn (howto->bitsize, word, contents + rel->r_offset);
>    else
>      bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
> -
>    return bfd_reloc_ok;
>  }
>
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index 3ffbaad..858d29e 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -264,8 +264,7 @@ static reloc_howto_type howto_table[] =
>          "R_RISCV_CALL",                /* name */
>          false,                         /* partial_inplace */
>          0,                             /* src_mask */
> -        ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
> -                                       /* dst_mask */
> +        MINUS_ONE,                     /* dst_mask */
>          true),                         /* pcrel_offset */
>
>    /* Like R_RISCV_CALL, but not locally binding.  */
> @@ -280,8 +279,7 @@ static reloc_howto_type howto_table[] =
>          "R_RISCV_CALL_PLT",            /* name */
>          false,                         /* partial_inplace */
>          0,                             /* src_mask */
> -        ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
> -                                       /* dst_mask */
> +        MINUS_ONE,                     /* dst_mask */
>          true),                         /* pcrel_offset */
>
>    /* High 20 bits of 32-bit PC-relative GOT access.  */
> --
> 2.7.4
>


More information about the Binutils mailing list