[PATCH] ld: Add elf{32,64}[lb]riscv_fbsd emulations and riscv{32,64}{,be}-*-freebsd* triples
Nelson Chu
nelson.chu@sifive.com
Mon Feb 1 06:14:07 GMT 2021
Hi Maskray
Thanks for adding this support, I have some thoughts and suggestions.
On Sun, Jan 31, 2021 at 3:07 PM Fangrui Song <maskray@google.com> wrote:
>
> Relax an ABI compatibility check so that ELFOSABI_FREEBSD output can
> subsume ELFOSABI_NONE/ELFOSABI_GNU input object files.
>
> PR 27296
> bfd/
> * config.bfd: Add riscvbe-*-freebsd*, riscv32be-*-freebsd*,
> riscv-*-freebsd*, riscv32*-*-freebsd*, riscv64be-*-freebsd*,
> riscv64*-*-freebsd*.
> * configure.ac: Add riscv_elf32_fbsd_vec, riscv_elf32_fbsd_vec,
> riscv_elf32_fbsd_vec, riscv_elf32_fbsd_vec.
> * elfnn-riscv.c (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME,
> TARGET_BIG_SYM, TARGET_BIG_NAME, ELF_OSABI, elf32_bed, elf64_bed):
> Define for freebsd.
> * targets.c (riscv_elf32_fbsd_vec, riscv_elf32_fbsd_vec,
> riscv_elf32_fbsd_vec, riscv_elf32_fbsd_vec): Declare.
> (_bfd_target_vector): Add them.
> * configure: Regenerate.
> ld/
> * Makefile.am (ALL_EMULATION_SOURCES): Add eelf32lriscv_fbsd.c and
> eelf32briscv_fbsd.c.
> (ALL_64_EMULATION_SOURCES): Add eelf64lriscv_fbsd.c and
> eelf64briscv_fbsd.c.
> Include $(DEPDIR)/eelf*lriscv_fbsd* files.
> * configure.tgt: Add riscvbe-*-freebsd*, riscv32be-*-freebsd*,
> riscv-*-freebsd*, riscv32*-*-freebsd*, riscv64be-*-freebsd*,
> riscv64*-*-freebsd*.
> * emulparams/elf32lriscv_bsd.sh: New file.
> * emulparams/elf32briscv_bsd.sh: New file.
> * emulparams/elf64lriscv_bsd.sh: New file.
> * emulparams/elf64briscv_bsd.sh: New file.
> * Makefile.in: Regenerate.
> * po/BLD-POTFILES.in: Regenerate.
I think we also need to add the FreeBSD support for RISC-V assembler.
After scanning other targets' code quickly, we can set the em=freebsd
in the gas/configure.tgt for target riscv*-*-freebsd*, then the
TE_FreeBSD will be defined, and we should update the
riscv_target_format (gas/config/tc-riscv.c) to output the right format
name. You can refer to what MIPS did in their mips_target_format
(gas/config/tc-mips.c).
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index b2ec6a29fbf..98918b29f4e 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -3786,15 +3786,6 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
> if (!is_riscv_elf (ibfd) || !is_riscv_elf (obfd))
> return TRUE;
>
> - if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
> - {
> - (*_bfd_error_handler)
> - (_("%pB: ABI is incompatible with that of the selected emulation:\n"
> - " target emulation `%s' does not match `%s'"),
> - ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
> - return FALSE;
> - }
> -
> if (!_bfd_elf_merge_object_attributes (ibfd, info))
> return FALSE;
>
> @@ -3811,6 +3802,18 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
> return TRUE;
> }
>
> + if (elf_elfheader (ibfd)->e_ident[EI_CLASS]
> + != elf_elfheader (obfd)->e_ident[EI_CLASS]
> + || elf_elfheader (ibfd)->e_ident[EI_DATA]
> + != elf_elfheader (obfd)->e_ident[EI_DATA])
Indent needs to be fixed, it's minor
> + {
> + (*_bfd_error_handler)
> + (_("%pB: ABI is incompatible with that of the selected emulation:\n"
> + " target emulation `%s' does not match `%s'"),
> + ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
> + return FALSE;
> + }
> +
This change broke the GNU linker, I get lots of errors as follows when
just compiling a simple HelloWorld,
/scratch/nelsonc/build-upstream/rv32i-elf/build-install/lib/gcc/riscv32-unknown-elf/10.2.0/../../../../riscv32-unknown-elf/bin/ld:
/scratch/nelsonc/build-upstream/rv32i-elf/build-install/lib/gcc/riscv32-unknown-elf/10.2.0/crtbegin.o:
ABI is incompatible with that of the selected emulation:
target emulation `elf32-littleriscv' does not match `elf32-littleriscv'
/scratch/nelsonc/build-upstream/rv32i-elf/build-install/lib/gcc/riscv32-unknown-elf/10.2.0/../../../../riscv32-unknown-elf/bin/ld:
failed to merge target specific data of file
/scratch/nelsonc/build-upstream/rv32i-elf/build-install/lib/gcc/riscv32-unknown-elf/10.2.0/crtbegin.o
/scratch/nelsonc/build-upstream/rv32i-elf/build-install/lib/gcc/riscv32-unknown-elf/10.2.0/../../../../riscv32-unknown-elf/bin/ld:
/tmp/ccY5Ib0n.o: ABI is incompatible with that of the selected
emulation:
target emulation `elf32-littleriscv' does not match `elf32-littleriscv'
The problem is that we just handle/copy the e_flags here when
elf_flags_init (obfd) is FALSE, the correct elf header CLASS/DATA are
set until _bfd_elf_init_file_header in bfd/elf.c, not here.
Therefore, you are comparing an uninitialized elf header CLASS/DATA
from the output bfd with the input bfd which is aleady set. I suppose
you should remain the original check in the
_bfd_riscv_elf_merge_private_bfd_data. Adding the related FreeBSD
support in the assembler should let linker can get the correct
elf32-littleriscv-freebsd target name by bfd_get_target, rather than
get the elf32-littleriscv for freebsd. Besides, we also need to
update the riscv_elf_object_p, to recognize the freebsd targets.
Otherwise, this patch should be fine and won't affect our current
elf/linux toolchains. I have tested the rv32i-newlib and rv64gc-glibc
toolchains quickly, the gcc/binutils regressions look fine so far.
For safety, I hope we can pass the whole riscv-gnu-toolchain
regressions for the later fixed patches.
Thanks
Nelson
More information about the Binutils
mailing list