1*7c478bd9Sstevel@tonic-gate#!/usr/perl5/bin/perl -w 2*7c478bd9Sstevel@tonic-gate# 3*7c478bd9Sstevel@tonic-gate# CDDL HEADER START 4*7c478bd9Sstevel@tonic-gate# 5*7c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the 6*7c478bd9Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only 7*7c478bd9Sstevel@tonic-gate# (the "License"). You may not use this file except in compliance 8*7c478bd9Sstevel@tonic-gate# with the License. 9*7c478bd9Sstevel@tonic-gate# 10*7c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11*7c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 12*7c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions 13*7c478bd9Sstevel@tonic-gate# and limitations under the License. 14*7c478bd9Sstevel@tonic-gate# 15*7c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 16*7c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17*7c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 18*7c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 19*7c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 20*7c478bd9Sstevel@tonic-gate# 21*7c478bd9Sstevel@tonic-gate# CDDL HEADER END 22*7c478bd9Sstevel@tonic-gate# 23*7c478bd9Sstevel@tonic-gate# 24*7c478bd9Sstevel@tonic-gate# ident "%Z%%M% %I% %E% SMI" 25*7c478bd9Sstevel@tonic-gate# 26*7c478bd9Sstevel@tonic-gate# Copyright 2004 Sun Microsystems, Inc. All rights reserved. 27*7c478bd9Sstevel@tonic-gate# Use is subject to license terms. 28*7c478bd9Sstevel@tonic-gate# 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate# 31*7c478bd9Sstevel@tonic-gate# This utility program reads the contents file to extract Solaris ELF 32*7c478bd9Sstevel@tonic-gate# libraries, and then runs pvs(1) on them to find the library versioning 33*7c478bd9Sstevel@tonic-gate# information (if any). This info is printed to stdout in an index file 34*7c478bd9Sstevel@tonic-gate# format. 35*7c478bd9Sstevel@tonic-gate# 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gaterequire 5.005; 38*7c478bd9Sstevel@tonic-gateuse strict; 39*7c478bd9Sstevel@tonic-gateuse locale; 40*7c478bd9Sstevel@tonic-gateuse POSIX qw(locale_h); 41*7c478bd9Sstevel@tonic-gateuse Sun::Solaris::Utils qw(textdomain gettext); 42*7c478bd9Sstevel@tonic-gateuse File::Basename; 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gateuse vars qw( 45*7c478bd9Sstevel@tonic-gate @liblist 46*7c478bd9Sstevel@tonic-gate %symlink 47*7c478bd9Sstevel@tonic-gate %inode_hash 48*7c478bd9Sstevel@tonic-gate %fileoutput 49*7c478bd9Sstevel@tonic-gate %didlib 50*7c478bd9Sstevel@tonic-gate); 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gatesetlocale(LC_ALL, ""); 53*7c478bd9Sstevel@tonic-gatetextdomain(TEXT_DOMAIN); 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate# parameters for what types of libraries to list out: 56*7c478bd9Sstevel@tonic-gatemy $must_be_versioned = 0; 57*7c478bd9Sstevel@tonic-gatemy $must_be_public = 0; 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate# paths to skip outright. 60*7c478bd9Sstevel@tonic-gatemy @skip_list = qw( 61*7c478bd9Sstevel@tonic-gate /etc 62*7c478bd9Sstevel@tonic-gate /usr/4lib 63*7c478bd9Sstevel@tonic-gate /usr/perl5 64*7c478bd9Sstevel@tonic-gate); 65*7c478bd9Sstevel@tonic-gatemy $path_skip = join('|', @skip_list); 66*7c478bd9Sstevel@tonic-gate$path_skip = qr/^($path_skip)/; 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate# find library names: 69*7c478bd9Sstevel@tonic-gate# 70*7c478bd9Sstevel@tonic-gate# We have to use pkgchk -l output (even though it is much slower than 71*7c478bd9Sstevel@tonic-gate# parsing /var/sadm/install/contents ourselves) because the contents 72*7c478bd9Sstevel@tonic-gate# file will go away or change incompatibly at some point. 73*7c478bd9Sstevel@tonic-gate# 74*7c478bd9Sstevel@tonic-gatemy $old = $ENV{'LC_ALL'}; 75*7c478bd9Sstevel@tonic-gate$ENV{'LC_ALL'} = 'C'; 76*7c478bd9Sstevel@tonic-gatemy $contents_fh = do { local *FH; *FH }; 77*7c478bd9Sstevel@tonic-gateopen($contents_fh, "/usr/sbin/pkgchk -l|") || die "$!\n"; 78*7c478bd9Sstevel@tonic-gateif (defined($old)) { 79*7c478bd9Sstevel@tonic-gate $ENV{'LC_ALL'} = $old; 80*7c478bd9Sstevel@tonic-gate} else { 81*7c478bd9Sstevel@tonic-gate delete($ENV{'LC_ALL'}); 82*7c478bd9Sstevel@tonic-gate} 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gatemy $pathname = ''; 85*7c478bd9Sstevel@tonic-gatemy $type = ''; 86*7c478bd9Sstevel@tonic-gatemy $link = ''; 87*7c478bd9Sstevel@tonic-gatemy $pkgs = ''; 88*7c478bd9Sstevel@tonic-gatemy $status = ''; 89*7c478bd9Sstevel@tonic-gatemy $inpkgs = 0; 90*7c478bd9Sstevel@tonic-gatewhile (<$contents_fh>) { 91*7c478bd9Sstevel@tonic-gate next if (/^Ex/); 92*7c478bd9Sstevel@tonic-gate chomp; 93*7c478bd9Sstevel@tonic-gate if (/^Pathname:\s*/i) { 94*7c478bd9Sstevel@tonic-gate $pathname = $'; 95*7c478bd9Sstevel@tonic-gate $type = ''; 96*7c478bd9Sstevel@tonic-gate $link = ''; 97*7c478bd9Sstevel@tonic-gate $status = ''; 98*7c478bd9Sstevel@tonic-gate $pkgs = ''; 99*7c478bd9Sstevel@tonic-gate $inpkgs = 0; 100*7c478bd9Sstevel@tonic-gate next; 101*7c478bd9Sstevel@tonic-gate } elsif (/^Type:\s*/i) { 102*7c478bd9Sstevel@tonic-gate $type = $'; 103*7c478bd9Sstevel@tonic-gate next; 104*7c478bd9Sstevel@tonic-gate } elsif (/^Source of link:\s*/i) { 105*7c478bd9Sstevel@tonic-gate $link = $'; 106*7c478bd9Sstevel@tonic-gate next; 107*7c478bd9Sstevel@tonic-gate } elsif (/^Referenced by/i) { 108*7c478bd9Sstevel@tonic-gate $inpkgs = 1; 109*7c478bd9Sstevel@tonic-gate } elsif (/^Current status:\s*/i) { 110*7c478bd9Sstevel@tonic-gate $status = $'; 111*7c478bd9Sstevel@tonic-gate $inpkgs = 0; 112*7c478bd9Sstevel@tonic-gate next; 113*7c478bd9Sstevel@tonic-gate } elsif (/^\s*$/) { 114*7c478bd9Sstevel@tonic-gate next unless ($pathname =~ m,\.so,); 115*7c478bd9Sstevel@tonic-gate next unless ($pathname =~ m,/lib,); 116*7c478bd9Sstevel@tonic-gate next unless ($pathname =~ m,/lib[^/]*\.so\b,); 117*7c478bd9Sstevel@tonic-gate next unless ($type =~ /regular file|symbolic link/i); 118*7c478bd9Sstevel@tonic-gate next unless ($status =~ /^\s*installed\s*$/); 119*7c478bd9Sstevel@tonic-gate $pathname = trim($pathname); 120*7c478bd9Sstevel@tonic-gate $link = trim($link); 121*7c478bd9Sstevel@tonic-gate filter($pathname, $link, $pkgs); 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate if ($inpkgs) { 124*7c478bd9Sstevel@tonic-gate $pkgs .= $_ . ' '; 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate} 127*7c478bd9Sstevel@tonic-gateclose($contents_fh); 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate# run pvs(1) on the libraries found: 130*7c478bd9Sstevel@tonic-gatemy $batch = 30; # batch size to use (running in batches is faster). 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gatemy @list = (); 133*7c478bd9Sstevel@tonic-gatefor (my $i = 1; $i <= scalar(@liblist); $i++) { 134*7c478bd9Sstevel@tonic-gate push(@list, $liblist[$i-1]); 135*7c478bd9Sstevel@tonic-gate if ($i % $batch == 0) { 136*7c478bd9Sstevel@tonic-gate do_pvs(@list) if (@list); 137*7c478bd9Sstevel@tonic-gate @list = (); 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate} 140*7c478bd9Sstevel@tonic-gatedo_pvs(@list) if (@list); # finish any remainder. 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gateexit 0; 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate# 145*7c478bd9Sstevel@tonic-gate# Take a pkgchk -l entry and decide if it corresponds to a Solaris 146*7c478bd9Sstevel@tonic-gate# library. If so, save it in the list @liblist, and record info in 147*7c478bd9Sstevel@tonic-gate# %symlink & %inode_hash associative arrays as appropriate. 148*7c478bd9Sstevel@tonic-gate# 149*7c478bd9Sstevel@tonic-gatesub filter 150*7c478bd9Sstevel@tonic-gate{ 151*7c478bd9Sstevel@tonic-gate my ($path, $link, $pkgs) = @_; 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate # consider only SUNW packages: 155*7c478bd9Sstevel@tonic-gate return unless ($pkgs =~ /\bSUNW\S+/); 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate my $basename; 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate $basename = basename($path); 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate if ($link ne '') { 162*7c478bd9Sstevel@tonic-gate # include developer build-time symlinks: 163*7c478bd9Sstevel@tonic-gate return unless ($basename =~ /^lib.*\.so[\.\d]*$/); 164*7c478bd9Sstevel@tonic-gate } else { 165*7c478bd9Sstevel@tonic-gate return unless ($basename =~ /^lib.*\.so\.[\.\d]+$/); 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate return if ($path =~ /$path_skip/); 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate return unless (-f $path); 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate # inode is used to identify what file a symlink point to: 172*7c478bd9Sstevel@tonic-gate my $inode; 173*7c478bd9Sstevel@tonic-gate $inode = (stat($path))[1]; 174*7c478bd9Sstevel@tonic-gate return unless (defined($inode)); 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate if ($link ne '') { 177*7c478bd9Sstevel@tonic-gate # record info about symlinks: 178*7c478bd9Sstevel@tonic-gate if (exists($symlink{$inode})) { 179*7c478bd9Sstevel@tonic-gate $symlink{$inode} .= ":" . $path; 180*7c478bd9Sstevel@tonic-gate } else { 181*7c478bd9Sstevel@tonic-gate $symlink{$inode} = ":" . $path; 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate } else { 184*7c478bd9Sstevel@tonic-gate # ordinary file case: 185*7c478bd9Sstevel@tonic-gate $inode_hash{$path} = $inode; 186*7c478bd9Sstevel@tonic-gate push(@liblist, $path); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate} 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate# 191*7c478bd9Sstevel@tonic-gate# Run pvs(1) on a list of libraries. More than one is done at a time to 192*7c478bd9Sstevel@tonic-gate# speed things up. 193*7c478bd9Sstevel@tonic-gate# 194*7c478bd9Sstevel@tonic-gate# Extracts the version information and passes it to the output() routine 195*7c478bd9Sstevel@tonic-gate# for final processing. 196*7c478bd9Sstevel@tonic-gate# 197*7c478bd9Sstevel@tonic-gatesub do_pvs 198*7c478bd9Sstevel@tonic-gate{ 199*7c478bd9Sstevel@tonic-gate my (@list) = @_; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate my (%list, $paths, $path, $cnt); 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate # 204*7c478bd9Sstevel@tonic-gate # record info about the library paths and construct the list of 205*7c478bd9Sstevel@tonic-gate # files for the pvs command line. 206*7c478bd9Sstevel@tonic-gate # 207*7c478bd9Sstevel@tonic-gate $cnt = 0; 208*7c478bd9Sstevel@tonic-gate $paths = ''; 209*7c478bd9Sstevel@tonic-gate foreach $path (@list) { 210*7c478bd9Sstevel@tonic-gate $list{$path} = 1; 211*7c478bd9Sstevel@tonic-gate $paths .= ' ' if ($paths ne ''); 212*7c478bd9Sstevel@tonic-gate # 213*7c478bd9Sstevel@tonic-gate # $path should never have single quote in it in 214*7c478bd9Sstevel@tonic-gate # all normal usage. Make sure this is so: 215*7c478bd9Sstevel@tonic-gate # 216*7c478bd9Sstevel@tonic-gate next if ($path =~ /'/); 217*7c478bd9Sstevel@tonic-gate # 218*7c478bd9Sstevel@tonic-gate # quote the filename in case it has meta-characters 219*7c478bd9Sstevel@tonic-gate # (which should never happen in all normal usage) 220*7c478bd9Sstevel@tonic-gate # 221*7c478bd9Sstevel@tonic-gate $paths .= "'$path'"; 222*7c478bd9Sstevel@tonic-gate $cnt++; 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate return if ($cnt == 0); 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate # set locale to C for running command, since we interpret the output: 228*7c478bd9Sstevel@tonic-gate my $old = $ENV{'LC_ALL'}; 229*7c478bd9Sstevel@tonic-gate $ENV{'LC_ALL'} = 'C'; 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate # get the file(1) output for each item: 232*7c478bd9Sstevel@tonic-gate my $file_fh = do { local *FH; *FH }; 233*7c478bd9Sstevel@tonic-gate open($file_fh, "/usr/bin/file $paths 2>&1 |") || die "$!\n"; 234*7c478bd9Sstevel@tonic-gate my ($file, $out); 235*7c478bd9Sstevel@tonic-gate while (<$file_fh>) { 236*7c478bd9Sstevel@tonic-gate ($file, $out) = split(/:/, $_, 2); 237*7c478bd9Sstevel@tonic-gate if ($list{$file} && $out =~ /\bELF\b/) { 238*7c478bd9Sstevel@tonic-gate $fileoutput{$file} = $out; 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate close($file_fh); 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate # 244*7c478bd9Sstevel@tonic-gate # in the case of only 1 item, we place it on the command line 245*7c478bd9Sstevel@tonic-gate # twice to induce pvs(1) to indicate which file it is reporting 246*7c478bd9Sstevel@tonic-gate # on. 247*7c478bd9Sstevel@tonic-gate # 248*7c478bd9Sstevel@tonic-gate if ($cnt == 1) { 249*7c478bd9Sstevel@tonic-gate $paths .= " $paths"; 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate # 253*7c478bd9Sstevel@tonic-gate # $paths are entries from /var/sadm/install/contents and 254*7c478bd9Sstevel@tonic-gate # so should not contain spaces or meta characters: 255*7c478bd9Sstevel@tonic-gate # 256*7c478bd9Sstevel@tonic-gate my $pvs_fh = do { local *FH; *FH }; 257*7c478bd9Sstevel@tonic-gate open($pvs_fh, "/usr/bin/pvs -dn $paths 2>&1 |") || die "$!\n"; 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate # reset LC_ALL, if there was any: 260*7c478bd9Sstevel@tonic-gate if (defined($old)) { 261*7c478bd9Sstevel@tonic-gate $ENV{'LC_ALL'} = $old; 262*7c478bd9Sstevel@tonic-gate } else { 263*7c478bd9Sstevel@tonic-gate delete($ENV{'LC_ALL'}); 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate my ($pub, $pri, $obs, $evo, $vers, $new_path); 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate undef($path); 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate # initialize strings used below for appending info to: 271*7c478bd9Sstevel@tonic-gate $pub = ''; 272*7c478bd9Sstevel@tonic-gate $pri = ''; 273*7c478bd9Sstevel@tonic-gate $obs = ''; 274*7c478bd9Sstevel@tonic-gate $evo = ''; 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate while (<$pvs_fh>) { 277*7c478bd9Sstevel@tonic-gate $_ =~ s/\s*$//; 278*7c478bd9Sstevel@tonic-gate if (m,^([^:]+):$,) { 279*7c478bd9Sstevel@tonic-gate # a new pvs file header, e.g. "/usr/lib/libc.so.1:" 280*7c478bd9Sstevel@tonic-gate if ($list{$1}) { 281*7c478bd9Sstevel@tonic-gate $new_path = $1; 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate # output the previous one and reset accumulators: 284*7c478bd9Sstevel@tonic-gate if (defined($path)) { 285*7c478bd9Sstevel@tonic-gate output($path, $pub, $pri, $obs, $evo); 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate $pub = ''; 288*7c478bd9Sstevel@tonic-gate $pri = ''; 289*7c478bd9Sstevel@tonic-gate $obs = ''; 290*7c478bd9Sstevel@tonic-gate $evo = ''; 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate $path = $new_path; 293*7c478bd9Sstevel@tonic-gate next; # done with pvs header case 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate # extract SUNW version head end: 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate $vers = trim($_); 300*7c478bd9Sstevel@tonic-gate $vers =~ s/;//g; 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate # handle the various non-standard cases in Solaris libraries: 303*7c478bd9Sstevel@tonic-gate if ($vers =~ /^(SUNW.*private|SUNW_XIL_GPI)/i) { 304*7c478bd9Sstevel@tonic-gate $pri .= $vers . ":"; 305*7c478bd9Sstevel@tonic-gate } elsif ($vers =~ /^(SUNW_\d|SYSVABI|SISCD)/) { 306*7c478bd9Sstevel@tonic-gate $pub .= $vers . ":"; 307*7c478bd9Sstevel@tonic-gate } elsif ($vers =~ /^(SUNW\.\d|SUNW_XIL)/) { 308*7c478bd9Sstevel@tonic-gate $pub .= $vers . ":"; 309*7c478bd9Sstevel@tonic-gate } elsif ($vers =~ /^SUNWobsolete/) { 310*7c478bd9Sstevel@tonic-gate $obs .= $vers . ":"; 311*7c478bd9Sstevel@tonic-gate } elsif ($vers =~ /^SUNWevolving/) { 312*7c478bd9Sstevel@tonic-gate $evo .= $vers . ":"; 313*7c478bd9Sstevel@tonic-gate } else { 314*7c478bd9Sstevel@tonic-gate next; 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate close($pvs_fh); 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate # output the last one (if any): 320*7c478bd9Sstevel@tonic-gate if (defined($path)) { 321*7c478bd9Sstevel@tonic-gate output($path, $pub, $pri, $obs, $evo); 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate} 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate# 326*7c478bd9Sstevel@tonic-gate# Take the raw library versioning information and process it into index 327*7c478bd9Sstevel@tonic-gate# file format and then print it out. 328*7c478bd9Sstevel@tonic-gate# 329*7c478bd9Sstevel@tonic-gatesub output 330*7c478bd9Sstevel@tonic-gate{ 331*7c478bd9Sstevel@tonic-gate my ($path, $pub, $pri, $obs, $evo) = @_; 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate return if ($didlib{$path}); # skip repeating a library 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate # trim off any trailing separators: 336*7c478bd9Sstevel@tonic-gate $pub =~ s/:$//; 337*7c478bd9Sstevel@tonic-gate $pri =~ s/:$//; 338*7c478bd9Sstevel@tonic-gate $obs =~ s/:$//; 339*7c478bd9Sstevel@tonic-gate $evo =~ s/:$//; 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate # work out the type of library: 342*7c478bd9Sstevel@tonic-gate my $type; 343*7c478bd9Sstevel@tonic-gate my $defn; 344*7c478bd9Sstevel@tonic-gate my $n; 345*7c478bd9Sstevel@tonic-gate if ($pri && ! $pub && ! $obs && ! $evo) { 346*7c478bd9Sstevel@tonic-gate $type = 'INTERNAL'; 347*7c478bd9Sstevel@tonic-gate $defn = 'NO_PUBLIC_SYMS'; 348*7c478bd9Sstevel@tonic-gate } elsif ($obs) { 349*7c478bd9Sstevel@tonic-gate $type = 'OBSOLETE'; 350*7c478bd9Sstevel@tonic-gate $defn = $obs; 351*7c478bd9Sstevel@tonic-gate } elsif ($pub) { 352*7c478bd9Sstevel@tonic-gate $type = 'PUBLIC'; 353*7c478bd9Sstevel@tonic-gate $defn = $pub; 354*7c478bd9Sstevel@tonic-gate if ($defn =~ /:/) { 355*7c478bd9Sstevel@tonic-gate $defn =~ s/:/,/g; 356*7c478bd9Sstevel@tonic-gate $defn = "PUBLIC=$defn"; 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate } elsif ($evo) { 359*7c478bd9Sstevel@tonic-gate $type = 'EVOLVING'; 360*7c478bd9Sstevel@tonic-gate $defn = $evo; 361*7c478bd9Sstevel@tonic-gate } elsif (! $pri && ! $pub && ! $obs && ! $evo) { 362*7c478bd9Sstevel@tonic-gate $type = 'UNVERSIONED'; 363*7c478bd9Sstevel@tonic-gate $defn = '-'; 364*7c478bd9Sstevel@tonic-gate } else { 365*7c478bd9Sstevel@tonic-gate return; 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate # return if instructed to skip either of these cases: 369*7c478bd9Sstevel@tonic-gate if ($must_be_versioned && $type eq 'UNVERSIONED') { 370*7c478bd9Sstevel@tonic-gate return; 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate if ($must_be_public && $type eq 'INTERNAL') { 373*7c478bd9Sstevel@tonic-gate return; 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate # prepare the output line, including any symlink information: 378*7c478bd9Sstevel@tonic-gate my $inode = $inode_hash{$path}; 379*7c478bd9Sstevel@tonic-gate my $links; 380*7c478bd9Sstevel@tonic-gate if ($inode && exists($symlink{$inode})) { 381*7c478bd9Sstevel@tonic-gate $links = "${path}$symlink{$inode}"; 382*7c478bd9Sstevel@tonic-gate } else { 383*7c478bd9Sstevel@tonic-gate $links = "$path"; 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate # count the total number of references: 387*7c478bd9Sstevel@tonic-gate my (@n) = split(/:/, $links); 388*7c478bd9Sstevel@tonic-gate $n = scalar(@n); 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate # determine the abi to which the library file belongs: 391*7c478bd9Sstevel@tonic-gate my ($fout, $abi); 392*7c478bd9Sstevel@tonic-gate $abi = 'unknown'; 393*7c478bd9Sstevel@tonic-gate $fout = $fileoutput{$path}; 394*7c478bd9Sstevel@tonic-gate if ($fout =~ /\bSPARCV9\b/) { 395*7c478bd9Sstevel@tonic-gate $abi = 'sparcv9'; 396*7c478bd9Sstevel@tonic-gate } elsif ($fout =~ /\bSPARC/) { 397*7c478bd9Sstevel@tonic-gate $abi = 'sparc'; 398*7c478bd9Sstevel@tonic-gate } elsif ($fout =~ /\bAMD64\b/ || $fout =~ /\bELF\s+64-bit\s+LSB\b/) { 399*7c478bd9Sstevel@tonic-gate $abi = 'amd64'; 400*7c478bd9Sstevel@tonic-gate } elsif ($fout =~ /\b80386\b/) { 401*7c478bd9Sstevel@tonic-gate $abi = 'i386'; 402*7c478bd9Sstevel@tonic-gate } 403*7c478bd9Sstevel@tonic-gate print STDOUT "$abi|$path|$defn|$n|$links\n"; 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate # record that we did this library so we do not process it a second time. 406*7c478bd9Sstevel@tonic-gate $didlib{$path} = 1; 407*7c478bd9Sstevel@tonic-gate} 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate# 410*7c478bd9Sstevel@tonic-gate# Remove leading and trailing spaces. 411*7c478bd9Sstevel@tonic-gate# 412*7c478bd9Sstevel@tonic-gatesub trim 413*7c478bd9Sstevel@tonic-gate{ 414*7c478bd9Sstevel@tonic-gate my ($x) = @_; 415*7c478bd9Sstevel@tonic-gate $x =~ s/^\s*//; 416*7c478bd9Sstevel@tonic-gate $x =~ s/\s*$//; 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate return $x; 419*7c478bd9Sstevel@tonic-gate} 420