#!/usr/bin/perl -w

# Copyright (C) 2010-2026 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/;$//;

    if (/\[WEAK\]/) {
	# Allow for weak versions like
	# libstdc++.so.6.0.34 -	CXXABI_1.3.16 [WEAK]: {CXXABI_1.3.15};
	#
	# shared object, dash, version "[WEAK]", symbol, [size]
	(undef, undef, $version, undef, $symbol, $size) = split;
    } else {
	# libstdc++.so.6.0.34 -	CXXABI_1.3.16: {CXXABI_1.3.15};
	#
	# 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/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;
