This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Handling GLIBC_2.10 symbol versions


Now development is happening towards glibc 2.10, there will at some
point be GLIBC_2.10 symbol versions.  (I'm working on a new port for
the ports add-on, using GLIBC_2.10 as the least symbol version since
it won't exist in any older release, and I expect such versions will
also be added to core libc before 2.10 is out.)

Using such versions runs into code in two scripts, firstversions.awk
and versions.awk, that uses textual sorting of symbol versions, which
e.g. wrongly orders GLIBC_2.10 as before GLIBC_2.2 (as noted in
comments in those scripts).  So when such versions are added it is
necessary to improve the sorting to handle them.

This patch implements such sorting improvements; something like this
will be needed when symbols start going in with such versions.  For
firstversions.awk, I added a version number sorting function cut down
from one included in GNU Autoconf.  versions.awk is written to pipe
through an external sort command; the simplest fix in that context
seemed to be to pad 2.x versions to 2.0x before passing to that
command and adjust the output back afterwards.

In addition to testing with the new port I tested with MIPS that the
maps created are the same before and after this patch; MIPS is a good
test because it is the only target using the feature of
firstversions.awk where multiple versions can be specified in
shlib-versions and intermediate symbol versions eliminated (in the
case of MIPS, 2.1 versions are mapped to 2.2 because there was no
working 2.1 release on MIPS, but there were working 2.0 and 2.2).

2008-11-18  Joseph Myers  <joseph@codesourcery.com>

	* scripts/firstversions.awk, scripts/versions.awk: Handle sorting
	GLIBC_2.dd versions.

Index: scripts/firstversions.awk
===================================================================
RCS file: /cvs/glibc/libc/scripts/firstversions.awk,v
retrieving revision 1.6
diff -u -r1.6 firstversions.awk
--- scripts/firstversions.awk	22 Aug 2002 07:21:49 -0000	1.6
+++ scripts/firstversions.awk	19 Nov 2008 16:54:56 -0000
@@ -21,14 +21,37 @@
   next;
 }
 
+# Return -1, 0 or 1 according to whether v1 is less than, equal to or
+# greater than v2 as a version string.  Simplified from GNU Autoconf
+# version; this one does not need to handle .0x fraction-style versions.
+function vers_compare (v1, v2)
+{
+  while (length(v1) && length(v2)) {
+    if (v1 ~ /^[0-9]/ && v2 ~ /^[0-9]/) {
+      for (len1 = 1; substr(v1, len1 + 1) ~ /^[0-9]/; len1++) continue;
+      for (len2 = 1; substr(v2, len2 + 1) ~ /^[0-9]/; len2++) continue;
+      d1 = substr(v1, 1, len1); v1 = substr(v1, len1 + 1);
+      d2 = substr(v2, 1, len2); v2 = substr(v2, len2 + 1);
+      d1 += 0;
+      d2 += 0;
+    } else {
+      d1 = substr(v1, 1, 1); v1 = substr(v1, 2);
+      d2 = substr(v2, 1, 1); v2 = substr(v2, 2);
+    }
+    if (d1 < d2) return -1;
+    if (d1 > d2) return 1;
+  }
+  if (length(v2)) return -1;
+  if (length(v1)) return 1;
+  return 0;
+}
+
 /GLIBC_PRIVATE/ { print; next }
 
 {
   if ((thislib, idx[thislib]) in firstversion) {
-    # XXX relative string comparison loses if we ever have multiple digits
-    # between dots in GLIBC_x.y[.z] names.
     f = v = firstversion[thislib, idx[thislib]];
-    while ($1 >= v) {
+    while (vers_compare($1, v) >= 0) {
       delete firstversion[thislib, idx[thislib]];
       idx[thislib]++;
       if ((thislib, idx[thislib]) in firstversion)
@@ -39,7 +62,7 @@
     if ($1 == v || $1 == f)
       # This version was the specified earliest version itself.
       print;
-    else if ($1 < v) {
+    else if (vers_compare($1, v) < 0) {
       # This version is older than the specified earliest version.
       print "  " $1, "=", v;
       # Record that V has been referred to, so we will be sure to emit it
Index: scripts/versions.awk
===================================================================
RCS file: /cvs/glibc/libc/scripts/versions.awk,v
retrieving revision 1.12
diff -u -r1.12 versions.awk
--- scripts/versions.awk	23 Mar 2005 01:46:29 -0000	1.12
+++ scripts/versions.awk	19 Nov 2008 16:54:56 -0000
@@ -28,10 +28,7 @@
   close(defsfile);
 
   tmpfile = buildroot "Versions.tmp";
-  # Note this sorting presumes only single digits between dots for proper
-  # numeric ordering.  sort -n doesn't do quite the right thing either,
-  # and in some non-GNU sort implementations does not sort at all.
-  sort = "sort > " tmpfile;
+  sort = "sort | sed -e s/GLIBC_2.0/GLIBC_2./ > " tmpfile;
 }
 
 # Remove comment lines.
@@ -69,6 +66,10 @@
   sortver=actver
   # Ensure GLIBC_ versions come always first
   sub(/^GLIBC_/," GLIBC_",sortver)
+  # Ensure GLIBC_2.d and GLIBC_2.d.d come before GLIBC_2.10 by
+  # adjusting here and converting back later.
+  if (sortver ~ /^ GLIBC_2\.[0-9](\.|$)/)
+    sub(/^ GLIBC_2\./, " GLIBC_2.0", sortver);
   printf("%s %s %s\n", actlib, sortver, $0) | sort;
 }
 

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]