This is an archive of the discontinued LLVM Phabricator instance.

[MC] Support SHF_GNU_RETAIN as section flag 'R'
ClosedPublic

Authored by MaskRay on Jan 29 2021, 10:52 PM.

Details

Summary

On Linux target triples, GNU as sets EI_OSABI to ELFOSABI_GNU when SHF_GNU_RETAIN is used。
On *-*-freebsd, it usually sets EI_OSABI to ELFOSABI_FREEBSD.

GNU ld respects SHF_GNU_RETAIN only for ELFOSABI_FREEBSD/ELFOSABI_GNU.
https://sourceware.org/bugzilla/show_bug.cgi?id=27282

MC doesn't set ELFOSABI_GNU for SHF_GNU_RETAIN/STB_GNU_UNIQUE/STT_GNU_IFUNC.
MC assembled object files do not have special semantics in GNU ld.

Diff Detail

Event Timeline

MaskRay created this revision.Jan 29 2021, 10:52 PM
MaskRay requested review of this revision.Jan 29 2021, 10:52 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 29 2021, 10:52 PM
psmith accepted this revision.Jan 30 2021, 3:47 AM
psmith added a subscriber: psmith.

Code changes and test LGTM. The OSABI question is interesting, I don't have a particular good answer or suggestion, the whole area is a bit of a mess. Looking at what ELF says:

EI_OSABI
Byte e_ident[EI_OSABI] identifies the OS- or ABI-specific ELF extensions used by this file. Some fields in other ELF structures have flags and values that have operating system and/or ABI specific meanings; the interpretation of those fields is determined by the value of this byte. If the object file does not use any extensions, it is recommended that this byte be set to 0. If the value for this byte is 64 through 255, its meaning depends on the value of the e_machine header member. The ABI processor supplement for an architecture can define its own associated set of values for this byte in this range. If the processor supplement does not specify a set of values, one of the following values shall be used, where 0 can also be taken to mean unspecified.

The flag is in the OS specific range so it could clash with other OS specific flags, to be strictly compliant it should set an OSABI to avoid clashes. It is unfortunate that we can only set one value though. For example the Arm processor supplement defines a couple of OSABI flags. What is the combination of using a GNU OS specific flag? I think ELF is implying that OSABI should be set to GNU if there is no processor specific OSABI value, I guess a strictly compliant toolchain would not permit SHF_RETAIN if there is some other OSABI in action that doesn't also recognise SHF_RETAIN. Quite how practical that is, and how strictly it has been followed in the past is another matter though.

I guess if ELF were still active, then SHF_RETAIN could be a standard ELF flag not an OS specific one.

As to what the linker should do. I think that unless there is a clash with some other OS specific flag that needs disambiguating it seems like accepting SHF_RETAIN (which is more toolchain than OS) when OSABI is 0 seems reasonable.

This revision is now accepted and ready to land.Jan 30 2021, 3:47 AM
MaskRay added a comment.EditedJan 30 2021, 3:27 PM

Thanks for your insight!

I agree with the comment 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.

Is there any feature triggering ELFOSABI_ARM / ELFOSABI_ARM_AEABI? If there is and such an object file also uses STT_GNU_IFUNC, the single value EI_OSABI is indeed insufficient.
(I think such a combo is currently infeasible, because binutils-gdb bfd/elf.c _bfd_elf_final_write_processing does not allow ifunc on non-GNU-non-FREEBSD OSABI values. But this is may be a question for SHF_GNU_RETAIN.)

I can see arguments for using ELFOSABI_GNU if EI_OSABI is otherwise 0. It will require some refactoring in MC code and I don't want to hold off the patch on that.

The change looks fine to me, though I have some slightly nebulous concern that this could be a pain for any downstream toolchain which uses a different thing for that flag value (I have no knowledge of a specific one that does FWIW).

I don't think using a flag to auto-set an OS/ABI value is the right approach. That should come from other assembly directives or command-line options or similar in my opinion. Possibly if any such exist we should reject the flag if they don't set a compatible OS/ABI value?

Is there any feature triggering ELFOSABI_ARM / ELFOSABI_ARM_AEABI? If there is and such an object file also uses STT_GNU_IFUNC, the single value EI_OSABI is indeed insufficient.

I can't find any. It looks like ELFOSABI_ARM used to be for pre EABI objects, but that seems to not be the case anymore and 0 gets used instead in all versions of GCC that anyone is likely to have used in the past 10 years. There is a use of ELFOSABI_ARM_FDPIC for the FDPIC variant (Linux in a single address space), but that isn't supported in LLVM anyway.

ELFOSABI_ARM_FDPIC (65)The object uses relocations in the private range, with semantics defined by [FDPIC].

The ELFOSABI_ARM_EABI is documented as:

ELFOSABI_ARM_AEABI (64)The object contains symbol versioning extensions as described in Symbol Versioning.

where the extensions are the GNU extensions, which seem to be universally supported by Arm toolchains, so it is probably redundant now in practice.

The use of OSABI gnu seems to be relatively recent in GCC. My old GCC8 versions set the OSABI to 0 even when ifunc is used.

Anyway I don't think that we need to hold this up over OSABI. It can be done in a separate patch if need be.

MaskRay edited the summary of this revision. (Show Details)Feb 2 2021, 9:33 AM
This revision was landed with ongoing or failed builds.Feb 2 2021, 9:34 AM
This revision was automatically updated to reflect the committed changes.