From c44838ebf8b8da0795d56e05b477c5d2b37b4a19 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 2 Jun 2021 07:32:19 +0200 Subject: Add libc ABI extension kludge for baseline-violating libdl symbols Some targets have a GLIBC_2.0 baseline for libdl, while using GLIBC_2.2 for libc. This means that the generated libc.map file does not have any version nodes for GLIBC_2.0 or GLIBC_2.1. However, moving symbols from libdl into libc needs such version nodes. (Future symbol moves from librt will need this as well.) This kludge is only necessary for symbols predating GLIBC_2.2 because the affected targets use GLIBC_2.2 as the baseline for libc. Given the small number and fixed set of affected architectures, no generic mechanism is implemented, and instead the map file fragment is hard-coded in scripts/versions.mk. The compat_symbol macro already emits the appropriate version strings, so no adjustments are needed there. Reviewed-by: Adhemerval Zanella --- scripts/versions.awk | 26 +++++++++++++++++++++++++- sysdeps/unix/sysv/linux/hppa/Versions | 1 + sysdeps/unix/sysv/linux/ia64/Versions | 1 + sysdeps/unix/sysv/linux/sh/Versions | 1 + sysdeps/unix/sysv/linux/sparc/sparc64/Versions | 1 + 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/scripts/versions.awk b/scripts/versions.awk index a715448..565233e 100644 --- a/scripts/versions.awk +++ b/scripts/versions.awk @@ -93,6 +93,26 @@ function ord(c) { printf("%s %s %s\n", actlib, sortver, $0) | sort; } +# Some targets do not set the ABI baseline for libdl. As a result, +# symbols originally in libdl need to be moved under historic symbol +# versions, without altering the baseline version for libc itself. +/^ *!libc_pre_versions/ { + libc_pre_versions_active = 1; +} + +function libc_pre_versions() { + # No local: * here, so that we do not have to update this script + # if symbols are moved into libc. The abilist files and the other + # targets (with a real GLIBC_2.0 baseline) provide testing + # coverage. + printf("\ +GLIBC_2.0 {\n\ +};\n\ +GLIBC_2.1 {\n\ +} GLIBC_2.0;\n\ +") > outfile; + return "GLIBC_2.1"; +} function closeversion(name, oldname) { printf(" local:\n *;\n") > outfile; @@ -154,7 +174,11 @@ END { oldlib = $1; real_outfile = buildroot oldlib ".map"; outfile = real_outfile "T"; - veryoldver = ""; + if ($1 == "libc" && libc_pre_versions_active) { + veryoldver = libc_pre_versions(); + } else { + veryoldver = ""; + } printf(" %s.map", oldlib); } if ($2 != oldver) { diff --git a/sysdeps/unix/sysv/linux/hppa/Versions b/sysdeps/unix/sysv/linux/hppa/Versions index 9532d20..357c68a 100644 --- a/sysdeps/unix/sysv/linux/hppa/Versions +++ b/sysdeps/unix/sysv/linux/hppa/Versions @@ -1,3 +1,4 @@ +!libc_pre_versions libc { GLIBC_2.1 { _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; diff --git a/sysdeps/unix/sysv/linux/ia64/Versions b/sysdeps/unix/sysv/linux/ia64/Versions index 54e7723..f438b12 100644 --- a/sysdeps/unix/sysv/linux/ia64/Versions +++ b/sysdeps/unix/sysv/linux/ia64/Versions @@ -1,3 +1,4 @@ +!libc_pre_versions libc { GLIBC_2.2 { ioperm; iopl; diff --git a/sysdeps/unix/sysv/linux/sh/Versions b/sysdeps/unix/sysv/linux/sh/Versions index 19ba1d8..9c734ff 100644 --- a/sysdeps/unix/sysv/linux/sh/Versions +++ b/sysdeps/unix/sysv/linux/sh/Versions @@ -1,3 +1,4 @@ +!libc_pre_versions libc { GLIBC_2.2 { # functions used in other libraries diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Versions b/sysdeps/unix/sysv/linux/sparc/sparc64/Versions index fbea1bb..33b6779 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/Versions +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Versions @@ -1,3 +1,4 @@ +!libc_pre_versions libc { GLIBC_2.0 { # Exception handling support functions from libgcc -- cgit v1.1