diff mbox series

[02/14] Add libc ABI extension kludge for baseline-violating libdl symbols

Message ID d2383471b2a8f72a069ddca9f30ba4a58af56e64.1621953726.git.fweimer@redhat.com
State New
Headers show
Series Move libdl into libc | expand

Commit Message

Florian Weimer May 25, 2021, 2:44 p.m. UTC
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 of affected symbols and the essentially fixed set,
no generic mechanism is implemented, and instead the map file
fragment is hard-coded in scripts/versions.mk.  Listing not-yet-moved
symbols in this fragment does not change the libc ABI.

The compat_symbol macro already emits the appropriate version strings,
so no adjustments are needed there.
---
 scripts/versions.awk                          | 36 +++++++++++++++++--
 sysdeps/unix/sysv/linux/hppa/Versions         |  1 +
 sysdeps/unix/sysv/linux/ia64/Versions         |  1 +
 sysdeps/unix/sysv/linux/sh/Versions           |  1 +
 .../unix/sysv/linux/sparc/sparc64/Versions    |  1 +
 5 files changed, 38 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/scripts/versions.awk b/scripts/versions.awk
index 3291123666..3b829929c2 100644
--- a/scripts/versions.awk
+++ b/scripts/versions.awk
@@ -93,6 +93,33 @@  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_abi_extension/ {
+    libc_abi_extension_active = 1;
+}
+
+function libc_abi_extension() {
+    printf("\
+GLIBC_2.0 {\n\
+  global:\n\
+    dladdr;\n\
+    dlclose;\n\
+    dlerror;\n\
+    dlopen;\n\
+    dlsym;\n\
+  local:\n\
+    *;\n\
+};\n\
+GLIBC_2.1 {\n\
+  global:\n\
+    dlopen;\n\
+    dlvsym;\n\
+} GLIBC_2.0;\n\
+") > outfile;
+    return "GLIBC_2.1";
+}
 
 function closeversion(name, oldname) {
   if (firstinfile) {
@@ -157,8 +184,13 @@  END {
       oldlib = $1;
       real_outfile = buildroot oldlib ".map";
       outfile = real_outfile "T";
-      firstinfile = 1;
-      veryoldver = "";
+      if ($1 == "libc" && libc_abi_extension_active) {
+	  firstinfile = 0;
+	  veryoldver = libc_abi_extension();
+      } else {
+	  firstinfile = 1;
+	  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 9532d207fc..8969fc08af 100644
--- a/sysdeps/unix/sysv/linux/hppa/Versions
+++ b/sysdeps/unix/sysv/linux/hppa/Versions
@@ -1,3 +1,4 @@ 
+!libc_abi_extension
 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 214e6f9f1a..f56da206ea 100644
--- a/sysdeps/unix/sysv/linux/ia64/Versions
+++ b/sysdeps/unix/sysv/linux/ia64/Versions
@@ -1,3 +1,4 @@ 
+!libc_abi_extension
 libc {
   GLIBC_2.2 {
     ioperm; iopl;
diff --git a/sysdeps/unix/sysv/linux/sh/Versions b/sysdeps/unix/sysv/linux/sh/Versions
index e0938c4165..cc57722681 100644
--- a/sysdeps/unix/sysv/linux/sh/Versions
+++ b/sysdeps/unix/sysv/linux/sh/Versions
@@ -1,3 +1,4 @@ 
+!libc_abi_extension
 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 fbea1bb2ef..3059d56f80 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Versions
@@ -1,3 +1,4 @@ 
+!libc_abi_extension
 libc {
   GLIBC_2.0 {
     # Exception handling support functions from libgcc