This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Infer OSABI from input files for -m options without explicit OSABI
AbandonedPublic

Authored by arichardson on Jan 25 2021, 8:42 AM.

Details

Summary

Currently only -m *_fbsd and -m msp430elf explicitly specifiy the OSABI
field, all others set the value to zero.
FreeBSD expects the OSABI field to be set for all executables, but both
GCC and Clang pass -melf64lriscv to the linker. This causes all RISC-V
executables to have a SysV OSABI which confuses tools such as ldd.

This patch changes the behaviour to infer the OSABI from the first input
.o file for -m options that don't encode a specific OSABI.

Diff Detail

Event Timeline

arichardson created this revision.Jan 25 2021, 8:42 AM
arichardson requested review of this revision.Jan 25 2021, 8:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 25 2021, 8:42 AM

@bsdjhb has been intending to fix ldd to recognise the ELF note rather than requiring the OSABI be FreeBSD. The only reason to set the OSABI to FreeBSD is so that the various FOO_LOOS-FOO_HIOS can be interpreted correctly.

@bsdjhb has been intending to fix ldd to recognise the ELF note rather than requiring the OSABI be FreeBSD. The only reason to set the OSABI to FreeBSD is so that the various FOO_LOOS-FOO_HIOS can be interpreted correctly.

It'd be nice to get something in sooner rather than later to fix the immediate issue, though... we've got at least one person that's actively working to identify and fix ports issues that have cropped up with other tier-2 platforms that also apply to riscv64, but sqlite3 being unpackageable is a pretty big downer that blocks over a thousand ports from being examined.

Can you give links why this is needed to change in the linker?

Can you give links why this is needed to change in the linker?

For older FreeBSD ports, the emulation has always been foo_fbsd. For AArch64, it was for a long time just using the unsuffixed version. At some point a few years ago, GNU toolchains started to use the _fbsd-suffixed emulation, but Clang continues to pass the unsuffixed one. For RISC-V, neither the GNU toolchain nor Clang include the suffix.

It's debatable whether this should be done in the linker. But the .o's coming out of Clang have ELFOSABI_FREEBSD and the linker loses that information if you pass an explicit non-suffixed emulation (if you don't pass anything it defaults to the first file's).

It's all a bit strange, and differs from Linux where you almost always see ELFOSABI_NONE rather than ELFOSABI_LINUX. But I would like to see the significance of EI_OSABI be decreased such that it's only about the ELF extensions used and not about the OS it expects to run in, as we have much more expressive ELF notes for the latter.

Can you give links why this is needed to change in the linker?

For ld.lld we could obviously also drop the -m flag from the clang driver or add _fbsd. However, I believe that will break ld.bfd since it doesn't support the _fbsd variants.

$ ./ld.bfd -V
GNU ld (GNU Binutils) 2.33.1
  Supported emulations:
   elf64lriscv
   elf32lriscv
MaskRay added a subscriber: peter.smith.EditedJan 30 2021, 6:50 PM

GNU as and GNU ld by default emit ELFOSABI_NONE, but will promote ELFOSABI_NONE to ELFOSABI_GNU if certain GNU ABI ELF features are used.
The single value nature makes it difficult to encode more than one ABI flavors. In practice many OSABI platforms adopt some GNU extensions.
It is possible to use extensions from more than one osabi platforms and we treat ELFOSABI_GNU an overridable osabi value (can be overridden by ELFOSABI_FREEBSD).

In https://sourceware.org/bugzilla/show_bug.cgi?id=12913#c9

It may have been an unfortunate choice to use EI_OSABI for the meaning that ELFOSABI_GNU has. But it's already been done and it's too late now.

I think that is a good summary from a retrospective viewpoint. It would be nice if GNU extensions could be taken as need, used as mixins. A single osabi value does not encode this intention well.

inferMachineType infers ekind/e_machine/EI_OSABI. ekind/e_machine are good to infer but EI_OSABI is not.
This patch makes the logic smarter: skipping ELFOSABI_NONE, but I don't see it fundamentally improves things.

E.g. if the first few object files have osabi values of ELFOSABI_NONE, ELFOSABI_GNU, ELFOSABI_FREEBSD, ELFOSABI_FREEBSD, ...
Do we pick ELFOSABI_GNU as the output? It is not better than ELFOSABI_NONE as ELFOSABI_FREEBSD should be the correct one.

The problem, according to @kevans, is no fbsd specific -m is specified clang/lib/Driver/ToolChains/FreeBSD.cpp, and ultimately the problem is that GNU ld does not understand a FreeBSD flavor RISC-V emulation...
So seems that binutils should be fixed. If you can detect -fuse-ld=, you can pass the emulation...

Filed https://sourceware.org/bugzilla/show_bug.cgi?id=27296 and sent a patch.

This revision now requires changes to proceed.Feb 3 2021, 11:07 AM
arichardson abandoned this revision.Apr 8 2021, 1:31 AM

No longer necessary