1*1fd5a2e1SPrashanth Swaminathan#!/usr/bin/perl -w 2*1fd5a2e1SPrashanth Swaminathan 3*1fd5a2e1SPrashanth Swaminathan# make_sunver.pl 4*1fd5a2e1SPrashanth Swaminathan# 5*1fd5a2e1SPrashanth Swaminathan# This script takes at least two arguments, a GNU style version script and 6*1fd5a2e1SPrashanth Swaminathan# a list of object and archive files, and generates a corresponding Sun 7*1fd5a2e1SPrashanth Swaminathan# style version script as follows: 8*1fd5a2e1SPrashanth Swaminathan# 9*1fd5a2e1SPrashanth Swaminathan# Each glob pattern, C++ mangled pattern or literal in the input script is 10*1fd5a2e1SPrashanth Swaminathan# matched against all global symbols in the input objects, emitting those 11*1fd5a2e1SPrashanth Swaminathan# that matched (or nothing if no match was found). 12*1fd5a2e1SPrashanth Swaminathan# A comment with the original pattern and its type is left in the output 13*1fd5a2e1SPrashanth Swaminathan# file to make it easy to understand the matches. 14*1fd5a2e1SPrashanth Swaminathan# 15*1fd5a2e1SPrashanth Swaminathan# It uses elfdump when present (native), GNU readelf otherwise. 16*1fd5a2e1SPrashanth Swaminathan# It depends on the GNU version of c++filt, since it must understand the 17*1fd5a2e1SPrashanth Swaminathan# GNU mangling style. 18*1fd5a2e1SPrashanth Swaminathan 19*1fd5a2e1SPrashanth Swaminathanuse FileHandle; 20*1fd5a2e1SPrashanth Swaminathanuse IPC::Open2; 21*1fd5a2e1SPrashanth Swaminathan 22*1fd5a2e1SPrashanth Swaminathan# Enforce C locale. 23*1fd5a2e1SPrashanth Swaminathan$ENV{'LC_ALL'} = "C"; 24*1fd5a2e1SPrashanth Swaminathan$ENV{'LANG'} = "C"; 25*1fd5a2e1SPrashanth Swaminathan 26*1fd5a2e1SPrashanth Swaminathan# Input version script, GNU style. 27*1fd5a2e1SPrashanth Swaminathanmy $symvers = shift; 28*1fd5a2e1SPrashanth Swaminathan 29*1fd5a2e1SPrashanth Swaminathan########## 30*1fd5a2e1SPrashanth Swaminathan# Get all the symbols from the library, match them, and add them to a hash. 31*1fd5a2e1SPrashanth Swaminathan 32*1fd5a2e1SPrashanth Swaminathanmy %sym_hash = (); 33*1fd5a2e1SPrashanth Swaminathan 34*1fd5a2e1SPrashanth Swaminathan# List of objects and archives to process. 35*1fd5a2e1SPrashanth Swaminathanmy @OBJECTS = (); 36*1fd5a2e1SPrashanth Swaminathan 37*1fd5a2e1SPrashanth Swaminathan# List of shared objects to omit from processing. 38*1fd5a2e1SPrashanth Swaminathanmy @SHAREDOBJS = (); 39*1fd5a2e1SPrashanth Swaminathan 40*1fd5a2e1SPrashanth Swaminathan# Filter out those input archives that have corresponding shared objects to 41*1fd5a2e1SPrashanth Swaminathan# avoid adding all symbols matched in the archive to the output map. 42*1fd5a2e1SPrashanth Swaminathanforeach $file (@ARGV) { 43*1fd5a2e1SPrashanth Swaminathan if (($so = $file) =~ s/\.a$/.so/ && -e $so) { 44*1fd5a2e1SPrashanth Swaminathan printf STDERR "omitted $file -> $so\n"; 45*1fd5a2e1SPrashanth Swaminathan push (@SHAREDOBJS, $so); 46*1fd5a2e1SPrashanth Swaminathan } else { 47*1fd5a2e1SPrashanth Swaminathan push (@OBJECTS, $file); 48*1fd5a2e1SPrashanth Swaminathan } 49*1fd5a2e1SPrashanth Swaminathan} 50*1fd5a2e1SPrashanth Swaminathan 51*1fd5a2e1SPrashanth Swaminathan# We need to detect and ignore hidden symbols. Solaris nm can only detect 52*1fd5a2e1SPrashanth Swaminathan# this in the harder to parse default output format, and GNU nm not at all, 53*1fd5a2e1SPrashanth Swaminathan# so use elfdump -s in the native case and GNU readelf -s otherwise. 54*1fd5a2e1SPrashanth Swaminathan# GNU objdump -t cannot be used since it produces a variable number of 55*1fd5a2e1SPrashanth Swaminathan# columns. 56*1fd5a2e1SPrashanth Swaminathan 57*1fd5a2e1SPrashanth Swaminathan# The path to elfdump. 58*1fd5a2e1SPrashanth Swaminathanmy $elfdump = "/usr/ccs/bin/elfdump"; 59*1fd5a2e1SPrashanth Swaminathan 60*1fd5a2e1SPrashanth Swaminathanif (-f $elfdump) { 61*1fd5a2e1SPrashanth Swaminathan open ELFDUMP,$elfdump.' -s '.(join ' ',@OBJECTS).'|' or die $!; 62*1fd5a2e1SPrashanth Swaminathan my $skip_arsym = 0; 63*1fd5a2e1SPrashanth Swaminathan 64*1fd5a2e1SPrashanth Swaminathan while (<ELFDUMP>) { 65*1fd5a2e1SPrashanth Swaminathan chomp; 66*1fd5a2e1SPrashanth Swaminathan 67*1fd5a2e1SPrashanth Swaminathan # Ignore empty lines. 68*1fd5a2e1SPrashanth Swaminathan if (/^$/) { 69*1fd5a2e1SPrashanth Swaminathan # End of archive symbol table, stop skipping. 70*1fd5a2e1SPrashanth Swaminathan $skip_arsym = 0 if $skip_arsym; 71*1fd5a2e1SPrashanth Swaminathan next; 72*1fd5a2e1SPrashanth Swaminathan } 73*1fd5a2e1SPrashanth Swaminathan 74*1fd5a2e1SPrashanth Swaminathan # Keep skipping until end of archive symbol table. 75*1fd5a2e1SPrashanth Swaminathan next if ($skip_arsym); 76*1fd5a2e1SPrashanth Swaminathan 77*1fd5a2e1SPrashanth Swaminathan # Ignore object name header for individual objects and archives. 78*1fd5a2e1SPrashanth Swaminathan next if (/:$/); 79*1fd5a2e1SPrashanth Swaminathan 80*1fd5a2e1SPrashanth Swaminathan # Ignore table header lines. 81*1fd5a2e1SPrashanth Swaminathan next if (/^Symbol Table Section:/); 82*1fd5a2e1SPrashanth Swaminathan next if (/index.*value.*size/); 83*1fd5a2e1SPrashanth Swaminathan 84*1fd5a2e1SPrashanth Swaminathan # Start of archive symbol table: start skipping. 85*1fd5a2e1SPrashanth Swaminathan if (/^Symbol Table: \(archive/) { 86*1fd5a2e1SPrashanth Swaminathan $skip_arsym = 1; 87*1fd5a2e1SPrashanth Swaminathan next; 88*1fd5a2e1SPrashanth Swaminathan } 89*1fd5a2e1SPrashanth Swaminathan 90*1fd5a2e1SPrashanth Swaminathan # Split table. 91*1fd5a2e1SPrashanth Swaminathan (undef, undef, undef, undef, $bind, $oth, undef, $shndx, $name) = split; 92*1fd5a2e1SPrashanth Swaminathan 93*1fd5a2e1SPrashanth Swaminathan # Error out for unknown input. 94*1fd5a2e1SPrashanth Swaminathan die "unknown input line:\n$_" unless defined($bind); 95*1fd5a2e1SPrashanth Swaminathan 96*1fd5a2e1SPrashanth Swaminathan # Ignore local symbols. 97*1fd5a2e1SPrashanth Swaminathan next if ($bind eq "LOCL"); 98*1fd5a2e1SPrashanth Swaminathan # Ignore hidden symbols. 99*1fd5a2e1SPrashanth Swaminathan next if ($oth eq "H"); 100*1fd5a2e1SPrashanth Swaminathan # Ignore undefined symbols. 101*1fd5a2e1SPrashanth Swaminathan next if ($shndx eq "UNDEF"); 102*1fd5a2e1SPrashanth Swaminathan # Error out for unhandled cases. 103*1fd5a2e1SPrashanth Swaminathan if ($bind !~ /^(GLOB|WEAK)/ or $oth ne "D") { 104*1fd5a2e1SPrashanth Swaminathan die "unhandled symbol:\n$_"; 105*1fd5a2e1SPrashanth Swaminathan } 106*1fd5a2e1SPrashanth Swaminathan 107*1fd5a2e1SPrashanth Swaminathan # Remember symbol. 108*1fd5a2e1SPrashanth Swaminathan $sym_hash{$name}++; 109*1fd5a2e1SPrashanth Swaminathan } 110*1fd5a2e1SPrashanth Swaminathan close ELFDUMP or die "$elfdump error"; 111*1fd5a2e1SPrashanth Swaminathan} else { 112*1fd5a2e1SPrashanth Swaminathan open READELF, 'readelf -s -W '.(join ' ',@OBJECTS).'|' or die $!; 113*1fd5a2e1SPrashanth Swaminathan # Process each symbol. 114*1fd5a2e1SPrashanth Swaminathan while (<READELF>) { 115*1fd5a2e1SPrashanth Swaminathan chomp; 116*1fd5a2e1SPrashanth Swaminathan 117*1fd5a2e1SPrashanth Swaminathan # Ignore empty lines. 118*1fd5a2e1SPrashanth Swaminathan next if (/^$/); 119*1fd5a2e1SPrashanth Swaminathan 120*1fd5a2e1SPrashanth Swaminathan # Ignore object name header. 121*1fd5a2e1SPrashanth Swaminathan next if (/^File: .*$/); 122*1fd5a2e1SPrashanth Swaminathan 123*1fd5a2e1SPrashanth Swaminathan # Ignore table header lines. 124*1fd5a2e1SPrashanth Swaminathan next if (/^Symbol table.*contains.*:/); 125*1fd5a2e1SPrashanth Swaminathan next if (/Num:.*Value.*Size/); 126*1fd5a2e1SPrashanth Swaminathan 127*1fd5a2e1SPrashanth Swaminathan # Split table. 128*1fd5a2e1SPrashanth Swaminathan (undef, undef, undef, undef, $bind, $vis, $ndx, $name) = split; 129*1fd5a2e1SPrashanth Swaminathan 130*1fd5a2e1SPrashanth Swaminathan # Error out for unknown input. 131*1fd5a2e1SPrashanth Swaminathan die "unknown input line:\n$_" unless defined($bind); 132*1fd5a2e1SPrashanth Swaminathan 133*1fd5a2e1SPrashanth Swaminathan # Ignore local symbols. 134*1fd5a2e1SPrashanth Swaminathan next if ($bind eq "LOCAL"); 135*1fd5a2e1SPrashanth Swaminathan # Ignore hidden symbols. 136*1fd5a2e1SPrashanth Swaminathan next if ($vis eq "HIDDEN"); 137*1fd5a2e1SPrashanth Swaminathan # Ignore undefined symbols. 138*1fd5a2e1SPrashanth Swaminathan next if ($ndx eq "UND"); 139*1fd5a2e1SPrashanth Swaminathan # Error out for unhandled cases. 140*1fd5a2e1SPrashanth Swaminathan if ($bind !~ /^(GLOBAL|WEAK)/ or $vis ne "DEFAULT") { 141*1fd5a2e1SPrashanth Swaminathan die "unhandled symbol:\n$_"; 142*1fd5a2e1SPrashanth Swaminathan } 143*1fd5a2e1SPrashanth Swaminathan 144*1fd5a2e1SPrashanth Swaminathan # Remember symbol. 145*1fd5a2e1SPrashanth Swaminathan $sym_hash{$name}++; 146*1fd5a2e1SPrashanth Swaminathan } 147*1fd5a2e1SPrashanth Swaminathan close READELF or die "readelf error"; 148*1fd5a2e1SPrashanth Swaminathan} 149*1fd5a2e1SPrashanth Swaminathan 150*1fd5a2e1SPrashanth Swaminathan########## 151*1fd5a2e1SPrashanth Swaminathan# The various types of glob patterns. 152*1fd5a2e1SPrashanth Swaminathan# 153*1fd5a2e1SPrashanth Swaminathan# A glob pattern that is to be applied to the demangled name: 'cxx'. 154*1fd5a2e1SPrashanth Swaminathan# A glob patterns that applies directly to the name in the .o files: 'glob'. 155*1fd5a2e1SPrashanth Swaminathan# This pattern is ignored; used for local variables (usually just '*'): 'ign'. 156*1fd5a2e1SPrashanth Swaminathan 157*1fd5a2e1SPrashanth Swaminathan# The type of the current pattern. 158*1fd5a2e1SPrashanth Swaminathanmy $glob = 'glob'; 159*1fd5a2e1SPrashanth Swaminathan 160*1fd5a2e1SPrashanth Swaminathan# We're currently inside `extern "C++"', which Sun ld doesn't understand. 161*1fd5a2e1SPrashanth Swaminathanmy $in_extern = 0; 162*1fd5a2e1SPrashanth Swaminathan 163*1fd5a2e1SPrashanth Swaminathan# The c++filt command to use. This *must* be GNU c++filt; the Sun Studio 164*1fd5a2e1SPrashanth Swaminathan# c++filt doesn't handle the GNU mangling style. 165*1fd5a2e1SPrashanth Swaminathanmy $cxxfilt = $ENV{'CXXFILT'} || "c++filt"; 166*1fd5a2e1SPrashanth Swaminathan 167*1fd5a2e1SPrashanth Swaminathan# The current version name. 168*1fd5a2e1SPrashanth Swaminathanmy $current_version = ""; 169*1fd5a2e1SPrashanth Swaminathan 170*1fd5a2e1SPrashanth Swaminathan# Was there any attempt to match a symbol to this version? 171*1fd5a2e1SPrashanth Swaminathanmy $matches_attempted; 172*1fd5a2e1SPrashanth Swaminathan 173*1fd5a2e1SPrashanth Swaminathan# The number of versions which matched this symbol. 174*1fd5a2e1SPrashanth Swaminathanmy $matched_symbols; 175*1fd5a2e1SPrashanth Swaminathan 176*1fd5a2e1SPrashanth Swaminathanopen F,$symvers or die $!; 177*1fd5a2e1SPrashanth Swaminathan 178*1fd5a2e1SPrashanth Swaminathan# Print information about generating this file 179*1fd5a2e1SPrashanth Swaminathanprint "# This file was generated by make_sunver.pl. DO NOT EDIT!\n"; 180*1fd5a2e1SPrashanth Swaminathanprint "# It was generated by:\n"; 181*1fd5a2e1SPrashanth Swaminathanprintf "# %s %s %s\n", $0, $symvers, (join ' ',@ARGV); 182*1fd5a2e1SPrashanth Swaminathanprintf "# Omitted archives with corresponding shared libraries: %s\n", 183*1fd5a2e1SPrashanth Swaminathan (join ' ', @SHAREDOBJS) if $#SHAREDOBJS >= 0; 184*1fd5a2e1SPrashanth Swaminathanprint "#\n\n"; 185*1fd5a2e1SPrashanth Swaminathan 186*1fd5a2e1SPrashanth Swaminathanwhile (<F>) { 187*1fd5a2e1SPrashanth Swaminathan # Lines of the form '};' 188*1fd5a2e1SPrashanth Swaminathan if (/^([ \t]*)(\}[ \t]*;[ \t]*)$/) { 189*1fd5a2e1SPrashanth Swaminathan $glob = 'glob'; 190*1fd5a2e1SPrashanth Swaminathan if ($in_extern) { 191*1fd5a2e1SPrashanth Swaminathan $in_extern--; 192*1fd5a2e1SPrashanth Swaminathan print "$1##$2\n"; 193*1fd5a2e1SPrashanth Swaminathan } else { 194*1fd5a2e1SPrashanth Swaminathan print; 195*1fd5a2e1SPrashanth Swaminathan } 196*1fd5a2e1SPrashanth Swaminathan next; 197*1fd5a2e1SPrashanth Swaminathan } 198*1fd5a2e1SPrashanth Swaminathan 199*1fd5a2e1SPrashanth Swaminathan # Lines of the form '} SOME_VERSION_NAME_1.0;' 200*1fd5a2e1SPrashanth Swaminathan if (/^[ \t]*\}[ \tA-Z0-9_.a-z]+;[ \t]*$/) { 201*1fd5a2e1SPrashanth Swaminathan $glob = 'glob'; 202*1fd5a2e1SPrashanth Swaminathan # We tried to match symbols agains this version, but none matched. 203*1fd5a2e1SPrashanth Swaminathan # Emit dummy hidden symbol to avoid marking this version WEAK. 204*1fd5a2e1SPrashanth Swaminathan if ($matches_attempted && $matched_symbols == 0) { 205*1fd5a2e1SPrashanth Swaminathan print " hidden:\n"; 206*1fd5a2e1SPrashanth Swaminathan print " .force_WEAK_off_$current_version = DATA S0x0 V0x0;\n"; 207*1fd5a2e1SPrashanth Swaminathan } 208*1fd5a2e1SPrashanth Swaminathan print; next; 209*1fd5a2e1SPrashanth Swaminathan } 210*1fd5a2e1SPrashanth Swaminathan 211*1fd5a2e1SPrashanth Swaminathan # Comment and blank lines 212*1fd5a2e1SPrashanth Swaminathan if (/^[ \t]*\#/) { print; next; } 213*1fd5a2e1SPrashanth Swaminathan if (/^[ \t]*$/) { print; next; } 214*1fd5a2e1SPrashanth Swaminathan 215*1fd5a2e1SPrashanth Swaminathan # Lines of the form '{' 216*1fd5a2e1SPrashanth Swaminathan if (/^([ \t]*){$/) { 217*1fd5a2e1SPrashanth Swaminathan if ($in_extern) { 218*1fd5a2e1SPrashanth Swaminathan print "$1##{\n"; 219*1fd5a2e1SPrashanth Swaminathan } else { 220*1fd5a2e1SPrashanth Swaminathan print; 221*1fd5a2e1SPrashanth Swaminathan } 222*1fd5a2e1SPrashanth Swaminathan next; 223*1fd5a2e1SPrashanth Swaminathan } 224*1fd5a2e1SPrashanth Swaminathan 225*1fd5a2e1SPrashanth Swaminathan # Lines of the form 'SOME_VERSION_NAME_1.1 {' 226*1fd5a2e1SPrashanth Swaminathan if (/^([A-Z0-9_.]+)[ \t]+{$/) { 227*1fd5a2e1SPrashanth Swaminathan # Record version name. 228*1fd5a2e1SPrashanth Swaminathan $current_version = $1; 229*1fd5a2e1SPrashanth Swaminathan # Reset match attempts, #matched symbols for this version. 230*1fd5a2e1SPrashanth Swaminathan $matches_attempted = 0; 231*1fd5a2e1SPrashanth Swaminathan $matched_symbols = 0; 232*1fd5a2e1SPrashanth Swaminathan print; 233*1fd5a2e1SPrashanth Swaminathan next; 234*1fd5a2e1SPrashanth Swaminathan } 235*1fd5a2e1SPrashanth Swaminathan 236*1fd5a2e1SPrashanth Swaminathan # Ignore 'global:' 237*1fd5a2e1SPrashanth Swaminathan if (/^[ \t]*global:$/) { print; next; } 238*1fd5a2e1SPrashanth Swaminathan 239*1fd5a2e1SPrashanth Swaminathan # After 'local:', globs should be ignored, they won't be exported. 240*1fd5a2e1SPrashanth Swaminathan if (/^[ \t]*local:$/) { 241*1fd5a2e1SPrashanth Swaminathan $glob = 'ign'; 242*1fd5a2e1SPrashanth Swaminathan print; 243*1fd5a2e1SPrashanth Swaminathan next; 244*1fd5a2e1SPrashanth Swaminathan } 245*1fd5a2e1SPrashanth Swaminathan 246*1fd5a2e1SPrashanth Swaminathan # After 'extern "C++"', globs are C++ patterns 247*1fd5a2e1SPrashanth Swaminathan if (/^([ \t]*)(extern \"C\+\+\"[ \t]*)$/) { 248*1fd5a2e1SPrashanth Swaminathan $in_extern++; 249*1fd5a2e1SPrashanth Swaminathan $glob = 'cxx'; 250*1fd5a2e1SPrashanth Swaminathan # Need to comment, Sun ld cannot handle this. 251*1fd5a2e1SPrashanth Swaminathan print "$1##$2\n"; next; 252*1fd5a2e1SPrashanth Swaminathan } 253*1fd5a2e1SPrashanth Swaminathan 254*1fd5a2e1SPrashanth Swaminathan # Chomp newline now we're done with passing through the input file. 255*1fd5a2e1SPrashanth Swaminathan chomp; 256*1fd5a2e1SPrashanth Swaminathan 257*1fd5a2e1SPrashanth Swaminathan # Catch globs. Note that '{}' is not allowed in globs by this script, 258*1fd5a2e1SPrashanth Swaminathan # so only '*' and '[]' are available. 259*1fd5a2e1SPrashanth Swaminathan if (/^([ \t]*)([^ \t;{}#]+);?[ \t]*$/) { 260*1fd5a2e1SPrashanth Swaminathan my $ws = $1; 261*1fd5a2e1SPrashanth Swaminathan my $ptn = $2; 262*1fd5a2e1SPrashanth Swaminathan # Turn the glob into a regex by replacing '*' with '.*', '?' with '.'. 263*1fd5a2e1SPrashanth Swaminathan # Keep $ptn so we can still print the original form. 264*1fd5a2e1SPrashanth Swaminathan ($pattern = $ptn) =~ s/\*/\.\*/g; 265*1fd5a2e1SPrashanth Swaminathan $pattern =~ s/\?/\./g; 266*1fd5a2e1SPrashanth Swaminathan 267*1fd5a2e1SPrashanth Swaminathan if ($glob eq 'ign') { 268*1fd5a2e1SPrashanth Swaminathan # We're in a local: * section; just continue. 269*1fd5a2e1SPrashanth Swaminathan print "$_\n"; 270*1fd5a2e1SPrashanth Swaminathan next; 271*1fd5a2e1SPrashanth Swaminathan } 272*1fd5a2e1SPrashanth Swaminathan 273*1fd5a2e1SPrashanth Swaminathan # Print the glob commented for human readers. 274*1fd5a2e1SPrashanth Swaminathan print "$ws##$ptn ($glob)\n"; 275*1fd5a2e1SPrashanth Swaminathan # We tried to match a symbol to this version. 276*1fd5a2e1SPrashanth Swaminathan $matches_attempted++; 277*1fd5a2e1SPrashanth Swaminathan 278*1fd5a2e1SPrashanth Swaminathan if ($glob eq 'glob') { 279*1fd5a2e1SPrashanth Swaminathan my %ptn_syms = (); 280*1fd5a2e1SPrashanth Swaminathan 281*1fd5a2e1SPrashanth Swaminathan # Match ptn against symbols in %sym_hash. 282*1fd5a2e1SPrashanth Swaminathan foreach my $sym (keys %sym_hash) { 283*1fd5a2e1SPrashanth Swaminathan # Maybe it matches one of the patterns based on the symbol in 284*1fd5a2e1SPrashanth Swaminathan # the .o file. 285*1fd5a2e1SPrashanth Swaminathan $ptn_syms{$sym}++ if ($sym =~ /^$pattern$/); 286*1fd5a2e1SPrashanth Swaminathan } 287*1fd5a2e1SPrashanth Swaminathan 288*1fd5a2e1SPrashanth Swaminathan foreach my $sym (sort keys(%ptn_syms)) { 289*1fd5a2e1SPrashanth Swaminathan $matched_symbols++; 290*1fd5a2e1SPrashanth Swaminathan print "$ws$sym;\n"; 291*1fd5a2e1SPrashanth Swaminathan } 292*1fd5a2e1SPrashanth Swaminathan } elsif ($glob eq 'cxx') { 293*1fd5a2e1SPrashanth Swaminathan my %dem_syms = (); 294*1fd5a2e1SPrashanth Swaminathan 295*1fd5a2e1SPrashanth Swaminathan # Verify that we're actually using GNU c++filt. Other versions 296*1fd5a2e1SPrashanth Swaminathan # most likely cannot handle GNU style symbol mangling. 297*1fd5a2e1SPrashanth Swaminathan my $cxxout = `$cxxfilt --version 2>&1`; 298*1fd5a2e1SPrashanth Swaminathan $cxxout =~ m/GNU/ or die "$0 requires GNU c++filt to function"; 299*1fd5a2e1SPrashanth Swaminathan 300*1fd5a2e1SPrashanth Swaminathan # Talk to c++filt through a pair of file descriptors. 301*1fd5a2e1SPrashanth Swaminathan # Need to start a fresh instance per pattern, otherwise the 302*1fd5a2e1SPrashanth Swaminathan # process grows to 500+ MB. 303*1fd5a2e1SPrashanth Swaminathan my $pid = open2(*FILTIN, *FILTOUT, $cxxfilt) or die $!; 304*1fd5a2e1SPrashanth Swaminathan 305*1fd5a2e1SPrashanth Swaminathan # Match ptn against symbols in %sym_hash. 306*1fd5a2e1SPrashanth Swaminathan foreach my $sym (keys %sym_hash) { 307*1fd5a2e1SPrashanth Swaminathan # No? Well, maybe its demangled form matches one of those 308*1fd5a2e1SPrashanth Swaminathan # patterns. 309*1fd5a2e1SPrashanth Swaminathan printf FILTOUT "%s\n",$sym; 310*1fd5a2e1SPrashanth Swaminathan my $dem = <FILTIN>; 311*1fd5a2e1SPrashanth Swaminathan chomp $dem; 312*1fd5a2e1SPrashanth Swaminathan $dem_syms{$sym}++ if ($dem =~ /^$pattern$/); 313*1fd5a2e1SPrashanth Swaminathan } 314*1fd5a2e1SPrashanth Swaminathan 315*1fd5a2e1SPrashanth Swaminathan close FILTOUT or die "c++filt error"; 316*1fd5a2e1SPrashanth Swaminathan close FILTIN or die "c++filt error"; 317*1fd5a2e1SPrashanth Swaminathan # Need to wait for the c++filt process to avoid lots of zombies. 318*1fd5a2e1SPrashanth Swaminathan waitpid $pid, 0; 319*1fd5a2e1SPrashanth Swaminathan 320*1fd5a2e1SPrashanth Swaminathan foreach my $sym (sort keys(%dem_syms)) { 321*1fd5a2e1SPrashanth Swaminathan $matched_symbols++; 322*1fd5a2e1SPrashanth Swaminathan print "$ws$sym;\n"; 323*1fd5a2e1SPrashanth Swaminathan } 324*1fd5a2e1SPrashanth Swaminathan } else { 325*1fd5a2e1SPrashanth Swaminathan # No? Well, then ignore it. 326*1fd5a2e1SPrashanth Swaminathan } 327*1fd5a2e1SPrashanth Swaminathan next; 328*1fd5a2e1SPrashanth Swaminathan } 329*1fd5a2e1SPrashanth Swaminathan # Important sanity check. This script can't handle lots of formats 330*1fd5a2e1SPrashanth Swaminathan # that GNU ld can, so be sure to error out if one is seen! 331*1fd5a2e1SPrashanth Swaminathan die "strange line `$_'"; 332*1fd5a2e1SPrashanth Swaminathan} 333*1fd5a2e1SPrashanth Swaminathanclose F; 334