This is an archive of the discontinued LLVM Phabricator instance.

[MC] Change ELFOSABI_NONE to ELFOSABI_GNU for STB_GNU_UNIQUE
ClosedPublic

Authored by MaskRay on Aug 10 2021, 12:36 PM.

Details

Summary

Similar to D97976.
On Linux, most GCC installations are configured with
--enable-gnu-unique-object and such GCC emits @gnu_unique_object assembly.

The feature is highly controversial and disliked by many folks.
(On glibc DF_1_NODELETE is implicitly enabled and makes dlclose a no-op).

In llvm-project STB_GNU_UNIQUE is assembly only. Clang does not use STB_GNU_UNIQUE.

Use ELFOSABI_GNU to match GNU as behavior and avoid collision with other
OSABI binding values.

Diff Detail

Event Timeline

MaskRay created this revision.Aug 10 2021, 12:36 PM
MaskRay requested review of this revision.Aug 10 2021, 12:36 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 10 2021, 12:36 PM

@ro This is your request.

ro added a comment.Aug 14 2021, 4:22 PM

I'm on vacation for the next two weeks, so it may well take that long until I'm able to look into it.

MaskRay added a comment.EditedAug 26 2021, 3:34 PM

Thanks everyone!

joerg said "mildly in favor of that change" in IRC.
I don't expect that there will be any further feedback, so i plan on landing this tomorrow, unless there is further feedback before then.

TBH: When SHF_GNU_RETAIN used this mechanism, folks have expressed favor for STB_GNU_UNIQUE as well.
And the change is completely due to ro's request.

I'm concerned that this will turn ELFOSABI_FREEBSD objects into ELFOSABI_GNU ones, which can sometimes break things. This GNU extension is implemented by FreeBSD too so we shouldn't be forcing ELFOSABI_GNU, just avoiding ELFOSABI_NONE, and giving an error if you have a different ELFOSABI that doesn't support these things.

Which I note is true of SHF_GNU_RETAIN too; IMO that is currently wrong too

jrtc27 added a comment.EditedAug 26 2021, 4:29 PM

FWIW my proposed behaviour seems to be what binutils is doing for both STB_GNU_UNIQUE and SHF_GNU_RETAIN:

  if (elf_tdata (abfd)->has_gnu_osabi != 0)
    {
      if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE)
	i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
      else if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_GNU
	       && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
	{
	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind)
	    _bfd_error_handler (_("GNU_MBIND section is supported only by GNU "
				  "and FreeBSD targets"));
	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_ifunc)
	    _bfd_error_handler (_("symbol type STT_GNU_IFUNC is supported "
				  "only by GNU and FreeBSD targets"));
	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_unique)
	    _bfd_error_handler (_("symbol binding STB_GNU_UNIQUE is supported "
				  "only by GNU and FreeBSD targets"));
	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_retain)
	    _bfd_error_handler (_("GNU_RETAIN section is supported "
				  "only by GNU and FreeBSD targets"));
	  bfd_set_error (bfd_error_sorry);
	  return false;
	}
    }

(bfd/elf.c, _bfd_elf_final_write_processing)

I'm concerned that this will turn ELFOSABI_FREEBSD objects into ELFOSABI_GNU ones, which can sometimes break things. This GNU extension is implemented by FreeBSD too so we shouldn't be forcing ELFOSABI_GNU, just avoiding ELFOSABI_NONE, and giving an error if you have a different ELFOSABI that doesn't support these things.

This is not an issue. llvm-mc -triple=x86_64-freebsd sets ELFOSABI_FREEBSD. This overrides the implicit ELFOSABI_GNU.

On FreeBSD, the default triple is set to *-freebsd.

I'm concerned that this will turn ELFOSABI_FREEBSD objects into ELFOSABI_GNU ones, which can sometimes break things. This GNU extension is implemented by FreeBSD too so we shouldn't be forcing ELFOSABI_GNU, just avoiding ELFOSABI_NONE, and giving an error if you have a different ELFOSABI that doesn't support these things.

This is not an issue. llvm-mc -triple=x86_64-freebsd sets ELFOSABI_FREEBSD. This overrides the implicit ELFOSABI_GNU.

On FreeBSD, the default triple is set to *-freebsd.

Ah I managed to gloss over the OSABI == ELF::ELFOSABI_NONE check when looking at the sole user of seenGnuAbi. In which case I see no problem with this from a FreeBSD perspective, the only thing I can think of is we silently allow these GNU/FreeBSD extensions for other OSABIs, not that I personally care about any of them.

jrtc27 accepted this revision.Aug 26 2021, 4:46 PM
This revision is now accepted and ready to land.Aug 26 2021, 4:46 PM
MaskRay added a comment.EditedAug 26 2021, 4:48 PM

I'm concerned that this will turn ELFOSABI_FREEBSD objects into ELFOSABI_GNU ones, which can sometimes break things. This GNU extension is implemented by FreeBSD too so we shouldn't be forcing ELFOSABI_GNU, just avoiding ELFOSABI_NONE, and giving an error if you have a different ELFOSABI that doesn't support these things.

This is not an issue. llvm-mc -triple=x86_64-freebsd sets ELFOSABI_FREEBSD. This overrides the implicit ELFOSABI_GNU.

On FreeBSD, the default triple is set to *-freebsd.

Ah I managed to gloss over the OSABI == ELF::ELFOSABI_NONE check when looking at the sole user of seenGnuAbi. In which case I see no problem with this from a FreeBSD perspective, the only thing I can think of is we silently allow these GNU/FreeBSD extensions for other OSABIs, not that I personally care about any of them.

"the only thing I can think of is we silently allow these GNU/FreeBSD extensions for other OSABIs, not that I personally care about any of them" is exactly my thought with STT_GNU_IFUNC.
It has been adopted by sufficiently many OSABIs, so I am undecided what to do with it.

STB_GNU_UNIQUE is easy: Clang never emits @gnu_unique_object. It may be considered useless by many OSABIs.

I'm concerned that this will turn ELFOSABI_FREEBSD objects into ELFOSABI_GNU ones, which can sometimes break things. This GNU extension is implemented by FreeBSD too so we shouldn't be forcing ELFOSABI_GNU, just avoiding ELFOSABI_NONE, and giving an error if you have a different ELFOSABI that doesn't support these things.

This is not an issue. llvm-mc -triple=x86_64-freebsd sets ELFOSABI_FREEBSD. This overrides the implicit ELFOSABI_GNU.

On FreeBSD, the default triple is set to *-freebsd.

Ah I managed to gloss over the OSABI == ELF::ELFOSABI_NONE check when looking at the sole user of seenGnuAbi. In which case I see no problem with this from a FreeBSD perspective, the only thing I can think of is we silently allow these GNU/FreeBSD extensions for other OSABIs, not that I personally care about any of them.

"the only thing I can think of is we silently allow these GNU/FreeBSD extensions for other OSABIs, not that I personally care about any of them" is exactly my thought with STT_GNU_IFUNC.
It has been adopted by sufficiently many OSABIs, so I am undecided what to do with it.

Yeah... NetBSD for example supports it but I'm pretty sure binutils is going to give an error if you try to use it with ELFOSABI_NETBSD. No clue how things are working there for example... unless they don't use their OSABI any more.