diff libstdc++-v3/scripts/extract_symvers.pl @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libstdc++-v3/scripts/extract_symvers.pl	Fri Oct 27 22:46:09 2017 +0900
@@ -0,0 +1,139 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2010-2017 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
+# terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this library; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Extract symbol version information on Solaris 2.
+#
+# Sun ld doesn't record symbol versions in .dynsym entries and they cannot
+# easily be extracted from readelf --versions output, so use pvs instead.
+# This way, we don't require GNU binutils in the native case.  Also ensures
+# that baseline_symbols.txt is identical between native (pvs, elfdump) and
+# cross (readelf) cases.
+
+my $lib = shift;
+
+open PVS, "pvs -dsvo $lib |" or die $!;
+while (<PVS>) {
+    chomp;
+
+    # Remove trailing semicolon.
+    s/;$//;
+
+    # shared object, dash, version, symbol, [size]
+    (undef, undef, $version, $symbol, $size) = split;
+
+    # Remove colon separator from version field.
+    $version =~ s/:$//;
+    
+    # Record base version.  The [BASE] field was only added in Solaris 11,
+    # so simply use the first record instead.
+    if ($. == 1) {
+	$basever = $version;
+      	next;
+    }
+
+    # Skip version declarations.
+    next unless defined ($symbol);
+
+    # Ignore version dependencies.
+    next if ($symbol =~ /\{.*\}/);
+
+    # Emit objects.
+    if (defined ($size)) {
+	# Strip parens from object size.
+	$size =~ s/\((\d+)\)/$1/;
+
+	$type{$symbol} = "OBJECT";
+	$version{$symbol} = $version;
+	$size{$symbol} = $size;
+        next;
+    }
+
+    if ($version eq $symbol or $version eq $basever) {
+	# Emit versions or symbols bound to base versions as objects.
+	$type{$symbol} = "OBJECT";
+	if ($version eq $basever) {
+	    $version{$symbol} = $version;
+	} else {
+	    $version{$symbol} = $symbol;
+	}
+	$size{$symbol} = 0;
+    } else {
+	# Everything else without a size field is a function.
+	$type{$symbol} = "FUNC";
+	$version{$symbol} = $version;
+    }
+}
+close PVS or die "pvs error";
+
+# Only look at .dynsym table, like readelf in extract_symvers.
+# Ignore error output to avoid getting confused by
+# .gnu.version_r: zero sh_entsize information, expected 0x1
+# warning with Solaris 11 elfdump on gld-produced shared objects.
+open ELFDUMP, "/usr/ccs/bin/elfdump -s -N .dynsym $lib 2>/dev/null |" or die $!;
+while (<ELFDUMP>) {
+    chomp;
+
+    # Ignore empty lines.
+    next if (/^$/);
+
+    # Ignore object name header.
+    next if (/:$/);
+
+    # Ignore table header lines.
+    next if (/^Symbol Table Section:/);
+    next if (/index.*value.*size/);
+
+    # Split table.
+    (undef, undef, undef, $type, $bind, $oth, undef, $shndx, $name) = split;
+
+    # Error out for unknown input.
+    die "unknown input line:\n$_" unless defined($bind);
+
+    # Ignore local symbols.
+    next if ($bind eq "LOCL");
+    # Ignore hidden symbols.
+    next if ($oth eq "H");
+    # Ignore undefined symbols.
+    next if ($shndx eq "UNDEF");
+    # Error out for unhandled cases.   _GLOBAL_OFFSET_TABLE_ is P (protected).
+    die "unhandled symbol:\n$_" if ($bind !~ /^(GLOB|WEAK)/ or $oth !~ /[DP]/);
+
+    # Adapt to readelf type naming convention.
+    $type = "NOTYPE" if ($type eq "NOTY");
+    $type = "OBJECT" if ($type eq "OBJT");
+
+    # Use correct symbol type.
+    $type{$name} = $type if ($type{$name} ne $type);
+}
+close ELFDUMP or die "elfdump error";
+
+foreach $symbol (keys %type) {
+    if ($type{$symbol} eq "FUNC" || $type{$symbol} eq "NOTYPE") {
+	push @lines, "$type{$symbol}:$symbol\@\@$version{$symbol}\n";
+    } elsif ($type{$symbol} eq "OBJECT" and $size{$symbol} == 0) {
+	# Omit symbols bound to base version; details can differ depending
+	# on the toolchain used.
+	next if $version{$symbol} eq $basever;
+
+	push @lines, "$type{$symbol}:$size{$symbol}:$version{$symbol}\n";
+    } else {
+	push @lines, "$type{$symbol}:$size{$symbol}:$symbol\@\@$version{$symbol}\n";
+    }
+}
+print sort @lines;