[PATCH] Add GNU_PROPERTY_1_GLIBC_2_NEEDED

Motivations:

1. Some binaries which require new ELF features, like DT_RELR, only
work with the new glibc binary. They crash at run-time with the older
glibc binaries.
2. Somes binaries compiled with the new language features, like C2X
printf specifiers, only generate correct results with the new glibc
binary. Since we don't add new glibc versions to the printf function
family, they generate incorrect results at run-time with the older
glibc binaries.

Here is a proposal to encode glibc version dependencies in relocatable
objects:

/* The glibc 2 minor versions needed by the object file. */
#define GNU_PROPERTY_1_GLIBC_2_NEEDED (GNU_PROPERTY_UINT32_OR_LO + 1)

/* The lowest glibc 2 minor version. */
#define GNU_PROPERTY_1_GLIBC_2_NEEDED_MINOR_BASE 35

/* Set if the object file requires glibc 2 minor version M. */
#define GNU_PROPERTY_1_GLIBC_2_NEEDED_MINOR_VERSION(m) \
  (1U << ((m) - GNU_PROPERTY_1_GLIBC_2_NEEDED_MINOR_BASE))

Linker adds glibc versions in GNU_PROPERTY_1_GLIBC_2_NEEDED to the
.gnu.version_r section and removes GNU_PROPERTY_1_GLIBC_2_NEEDED note
when generating shared libraries and executables.

[hjl@gnu-cfl-2 elfvers-1]$ ./readelf -n x.o

Displaying notes found in: .note.gnu.property
  Owner Data size Description
  GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
      Properties: x86 ISA used:
  x86 feature used: x86
[hjl@gnu-cfl-2 elfvers-1]$ ./readelf -n glibc-2-minor-1.o

Displaying notes found in: .note.gnu.property
  Owner Data size Description
  GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
      Properties: 1_glibc_2_needed: 2.35, 2.38
  GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
      Properties: x86 ISA used:
  x86 feature used: x86
[hjl@gnu-cfl-2 elfvers-1]$ make x
gcc -B./ -o x x.o glibc-2-minor-1.o
[hjl@gnu-cfl-2 elfvers-1]$ ./readelf -n --version-info x
Version symbols section '.gnu.version' contains 4 entries:
Addr: 0x00000000004004ae Offset: 0x0004ae Link: 6 (.dynsym)
  000: 0 (*local*) 2 (GLIBC_2.34) 3 (GLIBC_2.2.5) 1 (*global*)

Version needs section '.gnu.version_r' contains 1 entry:
Addr: 0x00000000004004b8 Offset: 0x0004b8 Link: 7 (.dynstr)
  000000: Version: 1 File: libc.so.6 Cnt: 4
  0x0010: Name: GLIBC_2.38 Flags: none Version: 5
  0x0020: Name: GLIBC_2.35 Flags: none Version: 4
  0x0030: Name: GLIBC_2.2.5 Flags: none Version: 3
  0x0040: Name: GLIBC_2.34 Flags: none Version: 2
...
[hjl@gnu-cfl-2 elfvers-1]$ ./x
./x: /lib64/libc.so.6: version `GLIBC_2.38' not found (required by ./x)
./x: /lib64/libc.so.6: version `GLIBC_2.35' not found (required by ./x)
[hjl@gnu-cfl-2 elfvers-1]$

* H. J. Lu via llvm-dev:

1. Some binaries which require new ELF features, like DT_RELR, only
work with the new glibc binary. They crash at run-time with the older
glibc binaries.
2. Somes binaries compiled with the new language features, like C2X
printf specifiers, only generate correct results with the new glibc
binary. Since we don't add new glibc versions to the printf function
family, they generate incorrect results at run-time with the older
glibc binaries.

Solaris uses SHT_SUNW_verneed sections for this, not a property note.
Property notes seem the wrong approach for this. And there is no reason
to make this specific to glibc.

However, I still very much dislike this proposal.

Thanks,
Florian

Can you share your concerns?

Thanks.

* H. J. Lu:

OK. Let's resolve it in the glibc community first.

Thanks.

Note that there is no guarantee that a new glibc version actually has any
symbols in libc at the corresponding symbol version (there are no
GLIBC_2.20 symbols in any ABI test baseline for any architecture, for
example). If it happens not to, will the symbol version exist at all to
satisfy this check?

Then we need to add a new glibc version if it happens.