PATCH: PR libstdc++/45863: [4.6 regression] FAIL: libstdc++-abi/abi_check

Submitted by Rainer Orth on Oct. 5, 2010, 6:12 p.m.

Details

Message ID ydd4od0zexr.fsf@manam.CeBiTec.Uni-Bielefeld.DE
State New
Headers show

Commit Message

Rainer Orth Oct. 5, 2010, 6:12 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

>> diff -r fdb979422f7b libstdc++-v3/scripts/extract_symvers
>> --- a/libstdc++-v3/scripts/extract_symvers      Fri Oct 01 11:58:21 2010 +0000
>> +++ b/libstdc++-v3/scripts/extract_symvers      Mon Oct 04 19:59:51 2010 +0200
>> @@ -31,7 +31,11 @@
>>  if type pvs 2>&1 | grep 'not found' > /dev/null; then
>>     :
>>  else
>> -    pvs="pvs -dsvo"
>> +    # Linux may have a completely different pvs from LVM2, so make sure
>> +    # we've got the right one.
>> +    if pvs -dsvo ${lib} > /dev/null 2>&1; then
>> +       pvs="pvs -dsvo"
>> +    fi
>>  fi
>
> I think it is too fragile. Today, LVM2 pvs doesn't take -s. But it may change
> in the future. You should verify it is on Solaris before using Solaris pvs.

Everything can change in the future, and I have a hard time believing
that the LVM2 pvs does anything but error out if called with -dsvo
<shared object>, but I've seen too much bad error handling to argue.

How about the following patch?  It creates the same output for
libstdc++.so on Solaris 10/x86 as my previous script and output for
libc.so.6 on Linux/x86_64 is identical to the one currently on mainline.

I've created the patch with diff -wup to hide whitespace differences
from the changed indentation.

I'll fire off another i386-pc-solaris2.10 bootstrap to be extra sure
this works, maybe H.J. can test it on Linux?

Ok for mainline thereafter?

Thanks.
	Rainer


2010-10-04  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR libstdc++/45863
	* scripts/extract_symvers: Restore revision 164879.
	Only use pvs on SunOS.

Comments

Paolo Carlini Oct. 5, 2010, 7:06 p.m.
Hi,
> Everything can change in the future, and I have a hard time believing
> that the LVM2 pvs does anything but error out if called with -dsvo
> <shared object>, but I've seen too much bad error handling to argue.
>
> How about the following patch?  It creates the same output for
> libstdc++.so on Solaris 10/x86 as my previous script and output for
> libc.so.6 on Linux/x86_64 is identical to the one currently on mainline.
>
> I've created the patch with diff -wup to hide whitespace differences
> from the changed indentation.
>
> I'll fire off another i386-pc-solaris2.10 bootstrap to be extra sure
> this works, maybe H.J. can test it on Linux?
>
> Ok for mainline thereafter?
>   
this version seems pretty robust and safe to me as far as Linux is
concerned. Thus, again, I'm Ok with it, if regtesting is fine.

Thanks,
Paolo.
Ralf Wildenhues Oct. 5, 2010, 8:36 p.m.
Hello Rainer,

* Rainer Orth wrote on Tue, Oct 05, 2010 at 08:12:48PM CEST:
> 2010-10-04  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
> 
> 	PR libstdc++/45863
> 	* scripts/extract_symvers: Restore revision 164879.
> 	Only use pvs on SunOS.

> --- dist/libstdc++-v3/scripts/extract_symvers	2010-10-04 12:01:36.677996000 +0200
> +++ solaris/libstdc++-v3/scripts/extract_symvers	2010-10-05 19:42:07.370992600 +0200

> @@ -42,6 +34,56 @@ export LANG
>  
>  tmp=extract.$$
>  
> +case `uname -s` in
> +SunOS)

Is this cross-compile safe?  Does it need to be?

Thanks,
Ralf

> +  # Sun ld doesn't record symbol versions in .dynsym entries and they
> +  # cannot easily be extracted from readelf --versions output, so use pvs
> +  # instead.  Linux may have a completely different pvs from LVM2, so only
> +  # do this on SunOS.
> +  # Need to use nawk on Solaris 2 since Solaris 8/9 awk (oawk) cannot handle
> +  # sub.
> +  pvs -dsvo ${lib} | \
> +  nawk '# Remove colon separator from version field, trailing semicolon.
> +	{
> +	  sub (/:$/, "", $3);
> +	  sub (/;$/, "");
> +	}
> +	# Record base version.  The [BASE] field was only added in Solaris 11,
> +	# so simply use the first record instead.
> +	NR == 1 {
> +	  basever = $3;
> +	  next;
> +	}
> +	# Ignore version dependencies.
> +	$4 ~ /\{.*\}/ {
> +	  next;
> +	}
> +	NF == 4 {
> +	  if ($3 == $4 || $3 == basever)
> +	    # Emit versions or symbols bound to base versions as objects.
> +	    printf "OBJECT:0:%s\n", $4;
> +	  else
> +	    # Everything else without a size field is a function.
> +	    printf "FUNC:%s@@%s\n", $4, $3;
> +	  next;
> +	}
> +	# Emit objects.
> +	NF == 5 {
> +	  # Strip parens from object size.
> +	  sub (/^\(/, "", $5);
> +	  sub (/\)$/, "", $5);
> +	  printf "OBJECT:%s:%s@@%s\n", $5, $4, $3;
> +	  next;
> +	}' | sort | uniq > $tmp 2>&1
> +  ;;
> +*)
> +  # GNU binutils, somewhere after version 2.11.2, requires -W/--wide to
> +  # avoid default line truncation.  -W is not supported and truncation did
> +  # not occur by default before that point.
> +  readelf="readelf --symbols"
> +  if readelf --help | grep -- --wide > /dev/null; then
> +    readelf="$readelf --wide"
> +  fi
>  ${readelf} ${lib} |\
>  sed -e 's/ \[<other>: [A-Fa-f0-9]*\] //' -e '/\.dynsym/,/^$/p;d' |\
>  egrep -v ' (LOCAL|UND) ' |\
[...]
H.J. Lu Oct. 5, 2010, 11:29 p.m.
On Tue, Oct 5, 2010 at 12:06 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> Hi,
>> Everything can change in the future, and I have a hard time believing
>> that the LVM2 pvs does anything but error out if called with -dsvo
>> <shared object>, but I've seen too much bad error handling to argue.
>>
>> How about the following patch?  It creates the same output for
>> libstdc++.so on Solaris 10/x86 as my previous script and output for
>> libc.so.6 on Linux/x86_64 is identical to the one currently on mainline.
>>
>> I've created the patch with diff -wup to hide whitespace differences
>> from the changed indentation.
>>
>> I'll fire off another i386-pc-solaris2.10 bootstrap to be extra sure
>> this works, maybe H.J. can test it on Linux?
>>
>> Ok for mainline thereafter?
>>
> this version seems pretty robust and safe to me as far as Linux is
> concerned. Thus, again, I'm Ok with it, if regtesting is fine.
>

It looks good me too.

Thanks.
Rainer Orth Oct. 6, 2010, 4:57 p.m.
Hello Ralf,

>> @@ -42,6 +34,56 @@ export LANG
>>  
>>  tmp=extract.$$
>>  
>> +case `uname -s` in
>> +SunOS)
>
> Is this cross-compile safe?  Does it need to be?

I think it's ok as is: pvs is only available natively on Solaris, so a
cross from a non-Solaris build system would run readelf instead.  This
should work, since the cross would be using GNU ld, thus the
readelf-based method of determining the symbol versioning would work,
with one exception: as is, pvs cannot distinguish between TLS and OBJECT
in the symbol version info.  I'll ask Benjamin what to do about it.

To my astonishment, the readelf-based script seems to be cross-compile
safe: unlike other bfd-based commands, it seems to support foreign ELF
formats, as tested with readelf on Solaris 11/SPARC successfully reading
a Linux/x86_64 executable.

So I think we're set.

Thanks.
	Rainer
Rainer Orth Oct. 6, 2010, 5:02 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

>>> Ok for mainline thereafter?
>>>
>> this version seems pretty robust and safe to me as far as Linux is
>> concerned. Thus, again, I'm Ok with it, if regtesting is fine.
>
> It looks good me too.

Thanks for testing.  Based on this and my own testing, I've checked it
in.

	Rainer

Patch hide | download patch | download mbox

--- dist/libstdc++-v3/scripts/extract_symvers	2010-10-04 12:01:36.677996000 +0200
+++ solaris/libstdc++-v3/scripts/extract_symvers	2010-10-05 19:42:07.370992600 +0200
@@ -1,6 +1,6 @@ 
 #!/bin/sh
 
-# Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2009, 2010 Free Software Foundation, Inc.
 #
 # This file is part of the GNU ISO C++ Library.  This library is free
 # software; you can redistribute it and/or modify it under the
@@ -26,14 +26,6 @@  fi
 lib=$1
 output=$2
 
-# GNU binutils, somewhere after version 2.11.2, requires -W/--wide to avoid
-# default line truncation.  -W is not supported and truncation did not occur
-# by default before that point.
-readelf="readelf --symbols"
-if readelf --help | grep -- --wide > /dev/null; then
-    readelf="$readelf --wide"
-fi
-
 # This avoids weird sorting problems later.
 LC_ALL=C
 export LC_ALL
@@ -42,6 +34,56 @@  export LANG
 
 tmp=extract.$$
 
+case `uname -s` in
+SunOS)
+  # Sun ld doesn't record symbol versions in .dynsym entries and they
+  # cannot easily be extracted from readelf --versions output, so use pvs
+  # instead.  Linux may have a completely different pvs from LVM2, so only
+  # do this on SunOS.
+  # Need to use nawk on Solaris 2 since Solaris 8/9 awk (oawk) cannot handle
+  # sub.
+  pvs -dsvo ${lib} | \
+  nawk '# Remove colon separator from version field, trailing semicolon.
+	{
+	  sub (/:$/, "", $3);
+	  sub (/;$/, "");
+	}
+	# Record base version.  The [BASE] field was only added in Solaris 11,
+	# so simply use the first record instead.
+	NR == 1 {
+	  basever = $3;
+	  next;
+	}
+	# Ignore version dependencies.
+	$4 ~ /\{.*\}/ {
+	  next;
+	}
+	NF == 4 {
+	  if ($3 == $4 || $3 == basever)
+	    # Emit versions or symbols bound to base versions as objects.
+	    printf "OBJECT:0:%s\n", $4;
+	  else
+	    # Everything else without a size field is a function.
+	    printf "FUNC:%s@@%s\n", $4, $3;
+	  next;
+	}
+	# Emit objects.
+	NF == 5 {
+	  # Strip parens from object size.
+	  sub (/^\(/, "", $5);
+	  sub (/\)$/, "", $5);
+	  printf "OBJECT:%s:%s@@%s\n", $5, $4, $3;
+	  next;
+	}' | sort | uniq > $tmp 2>&1
+  ;;
+*)
+  # GNU binutils, somewhere after version 2.11.2, requires -W/--wide to
+  # avoid default line truncation.  -W is not supported and truncation did
+  # not occur by default before that point.
+  readelf="readelf --symbols"
+  if readelf --help | grep -- --wide > /dev/null; then
+    readelf="$readelf --wide"
+  fi
 ${readelf} ${lib} |\
 sed -e 's/ \[<other>: [A-Fa-f0-9]*\] //' -e '/\.dynsym/,/^$/p;d' |\
 egrep -v ' (LOCAL|UND) ' |\
@@ -51,7 +93,8 @@  awk '{ if ($4 == "FUNC" || $4 == "NOTYPE
          printf "%s:%s:%s\n", $4, $3, $8;
      }' | sort | uniq > $tmp 2>&1
 #       else printf "Huh?  What is %s?\n", $8;
-
+  ;;
+esac
 
 # I think we'll be doing some more with this file, but for now, dump.
 mv $tmp $output