[v2,04/16] Add libc ABI extension kludge for baseline-violating libdl symbols

Message ID 84f59adc6d3b0b84d2ce8ab94e91e1a08a33989e.1622469908.git.fweimer@redhat.com
State New
Headers show
Series
  • Move libdl into libc
Related show

Commit Message

Florian Weimer via Libc-alpha May 31, 2021, 2:11 p.m.
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 fixexd 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.
---
 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 +
 .../unix/sysv/linux/sparc/sparc64/Versions    |  1 +
 5 files changed, 29 insertions(+), 1 deletion(-)

-- 
2.31.1

Comments

Florian Weimer via Libc-alpha June 1, 2021, 7:31 p.m. | #1
On 31/05/2021 11:11, Florian Weimer via Libc-alpha wrote:
> 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 fixexd set of affected architectures, no generic


Typo 'fixexd'

> 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.


I guess this quite specific mismatched version issue justify this
ad-hoc solution. 

LGTM, thanks. There is only a small nit regarding the version tag
name used.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>


> ---

>  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 +

>  .../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 a7154480e3..1e8d8e4dc5 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_abi_extension/ {


Maybe use a different name like 'libc_compat_versions', the 'extension'
wording does not really fits in what it is providing.

> +    libc_abi_extension_active = 1;

> +}

> +

> +function libc_abi_extension() {

> +    # 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_abi_extension_active) {

> +	  veryoldver = libc_abi_extension();

> +      } else {

> +	  veryoldver = "";

> +      }

>        printf(" %s.map", oldlib);

>      }

>      if ($2 != oldver) {


Ok.

> 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 f6994151aa..7cac57a8e1 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 19ba1d8d91..fc89ff1c18 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

>
Florian Weimer via Libc-alpha June 1, 2021, 7:34 p.m. | #2
* Adhemerval Zanella:

>> +# 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/ {

>

> Maybe use a different name like 'libc_compat_versions', the 'extension'

> wording does not really fits in what it is providing.


It extends the version nodes below the actual baseline.  Maybe
libc_pre_versions?

Thanks,
Florian
Florian Weimer via Libc-alpha June 1, 2021, 7:38 p.m. | #3
On 01/06/2021 16:34, Florian Weimer wrote:
> * Adhemerval Zanella:

> 

>>> +# 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/ {

>>

>> Maybe use a different name like 'libc_compat_versions', the 'extension'

>> wording does not really fits in what it is providing.

> 

> It extends the version nodes below the actual baseline.  Maybe

> libc_pre_versions?


Good for me.

Patch

diff --git a/scripts/versions.awk b/scripts/versions.awk
index a7154480e3..1e8d8e4dc5 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_abi_extension/ {
+    libc_abi_extension_active = 1;
+}
+
+function libc_abi_extension() {
+    # 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_abi_extension_active) {
+	  veryoldver = libc_abi_extension();
+      } 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 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 f6994151aa..7cac57a8e1 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 19ba1d8d91..fc89ff1c18 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