Page MenuHomeFreeBSD

csu: Move ABI note from crt1+crti to crtbegin
Needs ReviewPublic

Authored by jrtc27 on Jul 27 2021, 4:03 PM.

Details

Reviewers
jhb
kib
Summary

The primary problem with the existing approach is that --gc-sections
will only regard non-COMDAT notes as GC roots, and so will happily GC
our ABI note, which happens when building base's LLVM. The use of COMDAT
was chosen in the first place to allow crti to be optional, but crt1 is
only used for executables, so shared libraries that don't use crti still
end up lacking an ABI note, which is precisely what the original commit
was trying to solve. Notably, for CHERI's CheriABI, we don't provide a
crti, as we fully remove support for legacy _init/_fini; we could
provide a dummy crti, but the motivation for using COMDAT in the first
place was to allow crti to be optional, so this seems silly.

Instead, just put the ELF note in crtbegin (and its S and T variants),
as this file is included in all of PDEs, PIEs and DSOs.

Note: other operating systems are in disagreement about what the right
approach is. OpenBSD puts the note in crtbegin, like this commit. NetBSD
puts the note in crti, like we could do if we made crti mandatory (and
provided it for CheriABI downstream), but doesn't seem to have any
benefit over crtbegin. Linux's glibc puts the note in crt1, which is
what we used to do, and means only executables get notes, and not shared
libraries.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 40695
Build 37584: arc lint + arc unit

Event Timeline

No, this is not going to work. For instance, it breaks gcc-built binaries.

crtbegin/crtend is really a compiler-supplied stuff. Move from crt1 to crti is not ideal, but all compilers use system-supplied crti, at least.

There was a recent thread on elf-abi list about gc roots for static linker. AFAIR they mentioned SHF_GNU_RETAIN flag as a way to mark the section to be gc root. Not sure how wide is it supported by ld.bfd/ld.gold/ld.lld.

In D31323#705479, @kib wrote:

No, this is not going to work. For instance, it breaks gcc-built binaries.

crtbegin/crtend is really a compiler-supplied stuff. Move from crt1 to crti is not ideal, but all compilers use system-supplied crti, at least.

Ew, why is GCC not using our crtbegin/crtend... but yes it seems you're right, ugh.

There was a recent thread on elf-abi list about gc roots for static linker. AFAIR they mentioned SHF_GNU_RETAIN flag as a way to mark the section to be gc root. Not sure how wide is it supported by ld.bfd/ld.gold/ld.lld.

Yes, that exists, but support in all of bfd, gold and lld is less than a year old (and you need an assembler that understands the syntax too for buildworld, so the in-tree LLVM will work but older external toolchains, both LLVM and GCC, will be unable to build FreeBSD), so every single binary would have to be built with a recent linker.

As it stands, --gc-sections is broken, and cannot be fixed without picking a single object file for the note to live in unless you want to have a very aggressive flag day for supported toolchains, both buildworld and every single other third-party binary, be it ports or random user binaries. So I guess that means we have to go with just crti like NetBSD? That's rather sad, it means for CheriABI downstream we have to ship a crti despite the fact that we have no _init/_fini and never will, but I guess we have no choice.