]>
Commit | Line | Data |
---|---|---|
e1208a57 RO |
1 | #!/usr/bin/perl -w |
2 | ||
a5544970 | 3 | # Copyright (C) 2010-2019 Free Software Foundation, Inc. |
e1208a57 RO |
4 | # |
5 | # This file is part of the GNU ISO C++ Library. This library is free | |
6 | # software; you can redistribute it and/or modify it under the | |
7 | # terms of the GNU General Public License as published by the | |
8 | # Free Software Foundation; either version 3, or (at your option) | |
9 | # any later version. | |
10 | # | |
11 | # This library is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License along | |
17 | # with this library; see the file COPYING3. If not see | |
18 | # <http://www.gnu.org/licenses/>. | |
19 | ||
20 | # Extract symbol version information on Solaris 2. | |
21 | # | |
22 | # Sun ld doesn't record symbol versions in .dynsym entries and they cannot | |
23 | # easily be extracted from readelf --versions output, so use pvs instead. | |
24 | # This way, we don't require GNU binutils in the native case. Also ensures | |
25 | # that baseline_symbols.txt is identical between native (pvs, elfdump) and | |
26 | # cross (readelf) cases. | |
27 | ||
28 | my $lib = shift; | |
29 | ||
30 | open PVS, "pvs -dsvo $lib |" or die $!; | |
31 | while (<PVS>) { | |
32 | chomp; | |
33 | ||
34 | # Remove trailing semicolon. | |
35 | s/;$//; | |
36 | ||
37 | # shared object, dash, version, symbol, [size] | |
38 | (undef, undef, $version, $symbol, $size) = split; | |
39 | ||
40 | # Remove colon separator from version field. | |
41 | $version =~ s/:$//; | |
42 | ||
43 | # Record base version. The [BASE] field was only added in Solaris 11, | |
44 | # so simply use the first record instead. | |
45 | if ($. == 1) { | |
46 | $basever = $version; | |
47 | next; | |
48 | } | |
49 | ||
50 | # Skip version declarations. | |
51 | next unless defined ($symbol); | |
52 | ||
53 | # Ignore version dependencies. | |
54 | next if ($symbol =~ /\{.*\}/); | |
55 | ||
56 | # Emit objects. | |
57 | if (defined ($size)) { | |
58 | # Strip parens from object size. | |
59 | $size =~ s/\((\d+)\)/$1/; | |
60 | ||
61 | $type{$symbol} = "OBJECT"; | |
62 | $version{$symbol} = $version; | |
63 | $size{$symbol} = $size; | |
64 | next; | |
65 | } | |
66 | ||
67 | if ($version eq $symbol or $version eq $basever) { | |
68 | # Emit versions or symbols bound to base versions as objects. | |
69 | $type{$symbol} = "OBJECT"; | |
9ac0b841 RO |
70 | if ($version eq $basever) { |
71 | $version{$symbol} = $version; | |
72 | } else { | |
73 | $version{$symbol} = $symbol; | |
74 | } | |
e1208a57 RO |
75 | $size{$symbol} = 0; |
76 | } else { | |
77 | # Everything else without a size field is a function. | |
78 | $type{$symbol} = "FUNC"; | |
79 | $version{$symbol} = $version; | |
80 | } | |
81 | } | |
82 | close PVS or die "pvs error"; | |
83 | ||
84 | # Only look at .dynsym table, like readelf in extract_symvers. | |
eea6e989 RO |
85 | # Ignore error output to avoid getting confused by |
86 | # .gnu.version_r: zero sh_entsize information, expected 0x1 | |
87 | # warning with Solaris 11 elfdump on gld-produced shared objects. | |
88 | open ELFDUMP, "/usr/ccs/bin/elfdump -s -N .dynsym $lib 2>/dev/null |" or die $!; | |
e1208a57 RO |
89 | while (<ELFDUMP>) { |
90 | chomp; | |
91 | ||
92 | # Ignore empty lines. | |
93 | next if (/^$/); | |
94 | ||
95 | # Ignore object name header. | |
96 | next if (/:$/); | |
97 | ||
98 | # Ignore table header lines. | |
99 | next if (/^Symbol Table Section:/); | |
100 | next if (/index.*value.*size/); | |
101 | ||
102 | # Split table. | |
103 | (undef, undef, undef, $type, $bind, $oth, undef, $shndx, $name) = split; | |
104 | ||
105 | # Error out for unknown input. | |
106 | die "unknown input line:\n$_" unless defined($bind); | |
107 | ||
108 | # Ignore local symbols. | |
109 | next if ($bind eq "LOCL"); | |
110 | # Ignore hidden symbols. | |
111 | next if ($oth eq "H"); | |
112 | # Ignore undefined symbols. | |
113 | next if ($shndx eq "UNDEF"); | |
114 | # Error out for unhandled cases. _GLOBAL_OFFSET_TABLE_ is P (protected). | |
115 | die "unhandled symbol:\n$_" if ($bind !~ /^(GLOB|WEAK)/ or $oth !~ /[DP]/); | |
116 | ||
117 | # Adapt to readelf type naming convention. | |
64574d41 | 118 | $type = "NOTYPE" if ($type eq "NOTY"); |
e1208a57 RO |
119 | $type = "OBJECT" if ($type eq "OBJT"); |
120 | ||
121 | # Use correct symbol type. | |
122 | $type{$name} = $type if ($type{$name} ne $type); | |
123 | } | |
124 | close ELFDUMP or die "elfdump error"; | |
125 | ||
126 | foreach $symbol (keys %type) { | |
64574d41 | 127 | if ($type{$symbol} eq "FUNC" || $type{$symbol} eq "NOTYPE") { |
e1208a57 RO |
128 | push @lines, "$type{$symbol}:$symbol\@\@$version{$symbol}\n"; |
129 | } elsif ($type{$symbol} eq "OBJECT" and $size{$symbol} == 0) { | |
9ac0b841 RO |
130 | # Omit symbols bound to base version; details can differ depending |
131 | # on the toolchain used. | |
132 | next if $version{$symbol} eq $basever; | |
133 | ||
e1208a57 RO |
134 | push @lines, "$type{$symbol}:$size{$symbol}:$version{$symbol}\n"; |
135 | } else { | |
136 | push @lines, "$type{$symbol}:$size{$symbol}:$symbol\@\@$version{$symbol}\n"; | |
137 | } | |
138 | } | |
139 | print sort @lines; |