PATCH: Fix the oldest ABI
H. J. Lu
hjl@lucon.org
Sat Nov 16 20:05:00 GMT 2002
Here is a patch to fix --enable-oldest-abi=ABI. I tested it on i686
with --enable-oldest-abi=2.2.3. The resulting libraries seem compatible
with glibc built without --enable-oldest-abi=2.2.3.
H.J.
-------------- next part --------------
2002-11-16 H.J. Lu <hjl@gnu.org>
* scripts/abi-versions.awk: Use gsub instead of sub.
2002-08-28 H.J. Lu <hjl@gnu.org>
* Makeconfig ($(common-objpfx)soversions.i): Add the default
version and the oldest version.
($(common-objpfx)soversions.mk): Updated.
* Makerules ($(common-objpfx)abi-versions.h): Pass soversions.i
to scripts/abi-versions.awk. Don't pass $(oldest_abi).
($(common-objpfx)Versions.all): Updated for new soversions.i.
($(common-objpfx)sysd-versions): Pass soversions.i to
scripts/versions.awk.
* scripts/abi-versions.awk: Remove oldest_abi. Take soversions.
* scripts/versions.awk: Take soversions. Fix the oldest ABI
support.
2002-08-23 H.J. Lu <hjl@gnu.org>
* sysdeps/unix/make-syscalls.sh: Support the oldest ABI.
* sysdeps/unix/sysv/linux/i386/syscalls.list: Add GLIBC_2.2 as
the current ABI for getrlimit and setrlimit.
--- libc/Makeconfig.oldest Fri Nov 15 17:47:31 2002
+++ libc/Makeconfig Sat Nov 16 11:13:46 2002
@@ -762,11 +762,15 @@ $(common-objpfx)shlib-versions.v.i: \
$(add-ons) \
$(subdirs)))
$(common-objpfx)soversions.i: $(common-objpfx)shlib-versions.v
- default_setname='$(filter-out %_default,$(oldest-abi:%=GLIBC_%))'; \
+ oldest_setname='$(filter-out %_default,$(oldest-abi:%=GLIBC_%))'; \
+ if test "x$$oldest_setname" = x; then \
+ oldest_setname=default; \
+ fi; \
while read conf version setname; do \
test -n "$$version" && \
test `expr '$(config-machine)-$(config-vendor)-$(config-os)' \
: "$$conf"` != 0 || continue; \
+ default_setname=none; \
if test "x$$version" = xDEFAULT; then \
default_setname="$$setname"; \
else \
@@ -775,13 +779,13 @@ $(common-objpfx)soversions.i: $(common-o
if eval test -z "\$${versioned_$${lib}}"; then \
eval versioned_$${lib}=yes; \
number=`echo $$version | sed "s/^.*=//"`; \
- echo $$lib $$number $${setname:-$${default_setname}}; \
+ echo $$lib $$number $${setname:-$${default_setname}} $$oldest_setname; \
fi; \
fi; \
done < $< > $@T; exit 0
mv -f $@T $@
$(common-objpfx)soversions.mk: $(common-objpfx)soversions.i
- (while read lib number setname; do \
+ (while read lib number default_setname oldest_setname; do \
case $$number in \
[0-9]*) echo "$$lib.so-version=.$$number"; \
echo "all-sonames+=$$lib=$$lib.so\$$($$lib.so-version)";;\
--- libc/Makerules.oldest Fri Nov 15 17:47:31 2002
+++ libc/Makerules Sat Nov 16 11:13:46 2002
@@ -114,8 +114,10 @@ ifeq ($(versioning),yes)
ifndef avoid-generated
before-compile := $(common-objpfx)abi-versions.h $(before-compile)
$(common-objpfx)abi-versions.h: $(..)scripts/abi-versions.awk \
+ $(common-objpfx)soversions.i \
$(common-objpfx)Versions.all
- LC_ALL=C $(AWK) -v oldest_abi=$(oldest-abi) -f $^ > $@T
+ LC_ALL=C $(AWK) -v soversions=$(word 2,$^) \
+ -f $(word 1,$^) $(word 3,$^) > $@T
mv -f $@T $@
$(common-objpfx)%.latest: $(common-objpfx)abi-versions.h
@@ -320,8 +322,8 @@ $(common-objpfx)Versions.def.v.i: $(..)V
$(common-objpfx)Versions.all: $(..)scripts/firstversions.awk \
$(common-objpfx)soversions.i \
$(common-objpfx)Versions.def.v
- { while read lib version setname; do \
- test -z "$$setname" || echo "$$lib : $$setname"; \
+ { while read lib version default_setname oldest_setname; do \
+ test "$$default_setname" == none || echo "$$lib : $$default_setname"; \
done < $(word 2,$^); \
cat $(word 3,$^); \
} | LC_ALL=C $(AWK) -f $< > $@T
@@ -333,12 +335,14 @@ $(common-objpfx)Versions.v.i: $(wildcard
$(sysd-versions-force)
$(common-objpfx)sysd-versions: $(common-objpfx)Versions.all \
$(common-objpfx)Versions.v \
+ $(common-objpfx)soversions.i \
$(..)scripts/versions.awk
( echo 'sysd-versions-subdirs = $(all-subdirs) $(config-sysdirs)' ; \
cat $(word 2,$^) \
| LC_ALL=C $(AWK) -v buildroot=$(common-objpfx) -v defsfile=$< \
+ -v soversions=$(word 3,$^) \
-v move_if_change='$(move-if-change)' \
- -f $(word 3,$^); \
+ -f $(word 4,$^); \
) > $@T
mv -f $@T $@
endif # avoid-generated
--- libc/scripts/abi-versions.awk.oldest Wed Mar 7 08:57:54 2001
+++ libc/scripts/abi-versions.awk Sat Nov 16 17:21:40 2002
@@ -2,12 +2,27 @@
# See include/shlib-compat.h comments for explanation.
# This script expects the following variables to be defined:
-# oldest_abi the oldest ABI supported
+# soversions name of soversions.i file.
BEGIN {
print "/* This file is automatically generated by abi-versions.awk.";
print " It defines symbols used by shlib-compat.h, which see. */";
print "\n#ifndef _ABI_VERSIONS_H\n#define _ABI_VERSIONS_H";
+ while (getline < soversions) {
+ lib=$1
+ version=$2
+ default_setname=$3
+ oldest_setname=$4
+ if (default_setname != "none") {
+ gsub(/[^A-Za-z0-9_ ]/, "_", default_setname);
+ default_setnames [lib] = default_setname
+ }
+ if (oldest_setname != "default") {
+ gsub(/[^A-Za-z0-9_ ]/, "_", oldest_setname);
+ oldest_setnames [lib] = oldest_setname
+ }
+ }
+ close (soversions)
}
NF == 2 && $2 == "{" {
@@ -29,7 +44,22 @@ $2 == "=" {
oldid = $1; newid = $3;
printf "#define ABI_%s_%s\tABI_%s_%s\n", libid, oldid, libid, newid;
- printf "#define VERSION_%s_%s\t%s\n", libid, oldid, new;
+ if (!oldest_setnames [libid]) {
+ # We don't have the oldest ABI defined. Rename it.
+ printf "#define VERSION_%s_%s\t%s\n", libid, oldid, new;
+ }
+ else {
+ # It is very tricky here. We have the oldest ABI defined. We need
+ # to figure out if we should change symbol version name or not.
+ if (default_setnames [libid] && default_setnames [libid] > oldid) {
+ # We rename the symbol version name only if the old version is
+ # older than the default.
+ printf "#define VERSION_%s_%s\t%s\n", libid, oldid, new;
+ }
+ else {
+ printf "#define VERSION_%s_%s\t%s\n", libid, oldid, old;
+ }
+ }
next;
}
@@ -40,9 +70,9 @@ $2 == "=" {
printf "#define ABI_%s_%s\t%d\t/* support %s */\n", libid, versid, ++n, vers;
printf "#define VERSION_%s_%s\t%s\n", libid, versid, vers;
- if ("GLIBC_" oldest_abi == vers)
+ if (oldest_setnames [libid] == versid)
start = 1;
- if (start == 0 && oldest_abi != "default")
+ if (start == 0 && oldest_setnames [libid])
--n;
next;
}
--- libc/scripts/versions.awk.oldest Sat Apr 6 22:39:11 2002
+++ libc/scripts/versions.awk Sat Nov 16 11:13:46 2002
@@ -4,22 +4,39 @@
# This script expects the following variables to be defined:
# defsfile name of Versions.def file
+# soversions name of soversions.i file.
# buildroot name of build directory with trailing slash
# move_if_change move-if-change command
# Read definitions for the versions.
BEGIN {
+ while (getline < soversions) {
+ lib=$1
+ version=$2
+ default_setname=$3
+ oldest_setname=$4
+ if (default_setname != "none") {
+ default_setnames [lib] = default_setname
+ }
+ }
+ close (soversions)
+
nlibs=0;
while (getline < defsfile) {
if (/^[a-zA-Z0-9_.]+ \{/) {
libs[$1] = 1;
curlib = $1;
while (getline < defsfile && ! /^}/) {
- if ($2 == "=") {
+ if ($1 ~ /^GLIBC_[0-9]/)
+ allglibcversions[$1] = 1
+ if ($2 == "=") {
renamed[curlib "::" $1] = $3;
- }
- else
+ }
+ else {
versions[$1] = 1;
+ if ($1 ~ /^GLIBC_[0-9]/)
+ supprtedglibcversions[$1] = 1
+ }
}
}
}
@@ -27,6 +44,38 @@ BEGIN {
tmpfile = buildroot "Versions.tmp";
sort = "sort -n > " tmpfile;
+
+ # Sort all glibc versions.
+ numallglibcversions = 0;
+ for (v in allglibcversions) {
+ sortedallglibcversions[numallglibcversions] = v
+ numallglibcversions++;
+ }
+ for (i = 0; i < numallglibcversions; i++) {
+ for (j = i + 1; j < numallglibcversions; j++) {
+ if (sortedallglibcversions[i] > sortedallglibcversions[j]) {
+ t = sortedallglibcversions[j]
+ sortedallglibcversions[j] = sortedallglibcversions[i]
+ sortedallglibcversions[i] = t
+ }
+ }
+ }
+
+ # Sort supprted glibc versions.
+ numsupprtedglibcversions = 0;
+ for (v in supprtedglibcversions) {
+ sortedsupprtedglibcversions[numsupprtedglibcversions] = v
+ numsupprtedglibcversions++;
+ }
+ for (i = 0; i < numsupprtedglibcversions; i++) {
+ for (j = i + 1; j < numsupprtedglibcversions; j++) {
+ if (sortedsupprtedglibcversions[i] > sortedsupprtedglibcversions[j]) {
+ t = sortedsupprtedglibcversions[j]
+ sortedsupprtedglibcversions[j] = sortedsupprtedglibcversions[i]
+ sortedsupprtedglibcversions[i] = t
+ }
+ }
+ }
}
# Remove comment lines.
@@ -46,8 +95,17 @@ BEGIN {
# This matches the beginning of a new version for the current library.
/^ [A-Za-z_]/ {
- if (renamed[actlib "::" $1])
- actver = renamed[actlib "::" $1];
+ renamedver = renamed[actlib "::" $1];
+ if (renamedver) {
+ # We do rename only for the default version.
+ if (default_setnames [actlib] == renamedver) {
+ actver = renamedver
+ }
+ else {
+ firstver = renamedver
+ actver = $1;
+ }
+ }
else if (!versions[$1]) {
printf("version %s not defined for %s\n", $1, actlib) > "/dev/stderr";
exit 1;
@@ -90,6 +148,74 @@ function close_and_move(name, real_name)
# Now print the accumulated information.
END {
close(sort);
+
+ # First collect all the symbol information.
+ while (getline < tmpfile) {
+ lib = $1;
+ version = $2;
+ for (n = 3; n <= NF; ++n) {
+ symbol = $n;
+ sub (/;/, "", symbol);
+ symbols[lib, symbol, version] = 1;
+ }
+ }
+ close(tmpfile)
+
+ if (firstver) {
+ # Check versions in all libraries.
+ for (l in libs) {
+ last = ""
+ # For each symbol in all libraries.
+ for (combined in symbols) {
+ split(combined, separate, SUBSEP);
+ lib = separate[1]
+ # Check the current library.
+ if (lib != l)
+ continue
+ # All symbols from the same library are consecutive.
+ if (last != "" && lib != l)
+ break
+ # The first symbol in the library.
+ if (last == "")
+ last = l
+ version = separate[3]
+ # Ignore none glibc versions and versions newer then the first
+ # version.
+ if (version !~ /^GLIBC_[0-9]/ || version >= firstver)
+ continue;
+ symbol = separate[2]
+ # We check if there is any definition after the first version.
+ for (i = 0; i < numsupprtedglibcversions; i++) {
+ v = sortedsupprtedglibcversions[i];
+ if (symbols[lib, symbol, v]) {
+ # Found one. Delete the previous version.
+ delete symbols[lib, symbol, version]
+ first = 1
+ break
+ }
+ }
+ if (i == numsupprtedglibcversions) {
+ # We didn't found any definition after the first version. We
+ # check if there are multiple definitions. We only keep the
+ # latest one.
+ last = numallglibcversions
+ for (i = numallglibcversions - 1; i >= 0 ; i--) {
+ v = sortedallglibcversions[i];
+ if (symbols[lib, symbol, v]) {
+ if (last != numallglibcversions) {
+ # Found an older version. Delete it.
+ delete symbols[lib, symbol, v]
+ }
+ else {
+ # Found the latest one before the first version.
+ last = i
+ }
+ }
+ }
+ }
+ }
+ }
+ }
oldlib = "";
oldver = "";
printf("version-maps =");
@@ -116,8 +242,15 @@ END {
oldver = $2;
}
printf(" ") > outfile;
+ lib = $1;
+ version = $2;
for (n = 3; n <= NF; ++n) {
- printf(" %s", $n) > outfile;
+ symbol = $n;
+ sub (/;/, "", symbol);
+ if (symbols[lib, symbol, version]) {
+ delete symbols[lib, symbol, version]
+ printf(" %s", $n) > outfile;
+ }
}
printf("\n") > outfile;
}
--- libc/sysdeps/unix/make-syscalls.sh.oldest Fri Nov 15 17:47:59 2002
+++ libc/sysdeps/unix/make-syscalls.sh Sat Nov 16 11:13:46 2002
@@ -118,6 +118,23 @@ while read file srcfile caller syscall a
echo "unix-syscalls += $file"
test x$caller = x- || echo "unix-extra-syscalls += $file"
+ # Find the first verion and the version which obsoletes it.
+ introduced=
+ obsoleted=
+ for name in $weak; do
+ name=`echo $name | sed 's/\./_/g'`
+ case $name in
+ *@@*)
+ ;;
+ *@*)
+ introduced=`echo $name | sed 's/.*@//'`
+ ;;
+ GLIBC_*)
+ obsoleted=$name
+ ;;
+ esac
+ done
+
# Emit a compilation rule for this syscall.
case $weak in
*@*)
@@ -143,10 +160,17 @@ shared-only-routines += $file
echo "\
\$(make-target-directory)
(echo '#include <sysdep.h>'; \\
+ if test x != x"$introduced" && test x != x"$obsoleted"; then \\
+ echo '#include <shlib-compat.h>'; \\
+ echo '#if SHLIB_COMPAT (libc, $introduced, $obsoleted)'; \\
+ fi; \\
echo 'PSEUDO ($strong, $syscall, $nargs)'; \\
echo ' ret'; \\
echo 'PSEUDO_END($strong)'; \\
- echo 'libc_hidden_def ($strong)'; \\"
+ echo 'libc_hidden_def ($strong)'; \\
+ if test x != x"$introduced" && test x != x"$obsoleted"; then \\
+ echo '#endif'; \\
+ fi; \\"
;;
esac
@@ -158,6 +182,8 @@ shared-only-routines += $file
for name in $weak; do
case $name in
+ GLIBC_*)
+ ;;
*@@*)
base=`echo $name | sed 's/@@.*//'`
ver=`echo $name | sed 's/.*@@//'`
--- libc/sysdeps/unix/sysv/linux/i386/syscalls.list.oldest Tue Jul 4 10:44:33 2000
+++ libc/sysdeps/unix/sysv/linux/i386/syscalls.list Sat Nov 16 11:13:46 2002
@@ -2,5 +2,5 @@
modify_ldt EXTRA modify_ldt i:ipi __modify_ldt modify_ldt
vm86 - vm86 i:p __vm86 vm86
-oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0
-oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0
+oldgetrlimit EXTRA getrlimit i:ip __old_getrlimit getrlimit@GLIBC_2.0 GLIBC_2.2
+oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0 GLIBC_2.2
More information about the Libc-alpha
mailing list