75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#!/usr/bin/perl -w
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# CDDL HEADER START
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# The contents of this file are subject to the terms of the
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Common Development and Distribution License (the "License").
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# You may not use this file except in compliance with the License.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# or http://www.opensolaris.org/os/licensing.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# See the License for the specific language governing permissions
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# and limitations under the License.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# When distributing Covered Code, include this CDDL HEADER in each
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# If applicable, add the following below this CDDL HEADER, with the
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# fields enclosed by brackets "[]" replaced with your own identifying
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# information: Portions Copyright [yyyy] [name of copyright owner]
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# CDDL HEADER END
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Check versioning information.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# This script descends a directory hierarchy inspecting ELF shared objects for
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# version definitions. The general theme is to verify that common versioning
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# rules have been used to build these objects.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# As always, a number of components don't follow the rules, or require
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# special handling. An exceptions file is used to specify these cases.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# By default any file that has conditions that should be reported is first
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# listed and then each condition follows. The -o (one-line) option produces a
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# more terse output which is better for sorting/diffing with "nightly".
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Besides the default operation of checking the files within a directory
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# hierarchy, a detailed analysis of each files versions can be created with the
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# -d option. The database created is useful for auditing the difference between
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# different builds, and for thus monitoring that versioning changes are made in
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# a compatible manner.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Define all global variables (required for strict)
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiuse vars qw($Prog $Intfdir);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiuse vars qw(%opt @SaveArgv $ErrFH $ObjCnt);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# An exception file is used to specify regular expressions to match
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# objects. These directives specify special attributes of the object.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# The regular expressions are read from the file and compiled into the
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# regular expression variables.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# The name of each regular expression variable is of the form
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# $EXRE_xxx
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# where xxx is the name of the exception in lower case. For example,
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# the regular expression variable for PLUGINS is $EXRE_plugins.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# onbld_elfmod::LoadExceptionsToEXRE() depends on this naming convention
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# to initialize the regular expression variables, and to detect invalid
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# exception names.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# If a given exception is not used in the exception file, its regular
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# expression variable will be undefined. Users of these variables must
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# test the variable with defined() prior to use:
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# defined($EXRE_plugins) && ($foo =~ $EXRE_plugins)
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# ----
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# The exceptions are:
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# NONSTD_VERNAME
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Objects are expected to use standard names for versions.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# This directive is used to relax that requirement.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# NOVERDEF
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Objects that are not required to have a versioned name. Note that
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# PLUGINS objects are implicitly NOVERDEF, so this directive is
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# for use with non-plugin objects.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# PLUGINS
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Plugin objects are not required to have a versioned name, and are
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# not required to be internally versioned.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiuse vars qw($EXRE_nonstd_vername $EXRE_noverdef $EXRE_plugin);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiuse strict;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiuse POSIX qw(getenv);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiuse Getopt::Std;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiuse File::Basename;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami## ProcFile(BasePath, RelPath, Class, Type, Verdef, Alias)
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Investigate runtime attributes of a sharable object
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# entry:
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# BasePath - Base path from which relative paths are taken
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# RelPath - Path of object taken relative to BasePath
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Class - ELFCLASS of object
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Type - ELF type of object
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Verdef - VERDEF if object defines versions, NOVERDEF otherwise
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Alias - Alias lines corresponding to the object, or an empty ('')
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# string if there are no aliases.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramisub ProcFile {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my($BasePath, $RelPath, $Class, $Type, $Verdef, $Alias) = @_;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my($File, $FullPath, %Vers, $VersCnt, %TopVer);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my($Val, $Ttl, $NotPlugin);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $FullPath = "$BasePath/$RelPath";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami @_ = split /\//, $RelPath;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $File = $_[$#_];
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $Ttl = 0;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # If this object is not a symlink, does not follow the runtime
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # versioned name convention, and it does not reside underneath
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # a directory identified as containing plugin objects intended
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # for use with dlopen() only, issue a warning.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami #
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # Note that it can only be a symlink if the user specified
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # a single file on the command line, because the use of
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # 'find_elf -a' is required for a symlink to be seen.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $NotPlugin = !defined($EXRE_plugin) || ($RelPath !~ $EXRE_plugin);
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami if (($File !~ /\.so\./) && $NotPlugin && (! -l $FullPath)) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami onbld_elfmod::OutMsg($ErrFH, \$Ttl, $RelPath,
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami "does not have a versioned name");
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # If there are no versions in the file we're done.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if ($Verdef eq 'NOVERDEF') {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # Report the lack of versioning, unless the object is
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # a known plugin, or is explicitly exempt.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if ($NotPlugin &&
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami (!defined($EXRE_noverdef) || ($RelPath !~ $EXRE_noverdef))) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami onbld_elfmod::OutMsg($ErrFH, \$Ttl, $RelPath,
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami "no versions found");
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami return;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # Get a hash of the top versions in the inheritance chains.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami %TopVer = ();
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami foreach my $Line (split(/\n/, `pvs -don $FullPath 2>&1`)) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $Line =~ s/^.*-\s*(.*);/$1/;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $TopVer{$Line} = 1;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # Determine the name used for the base version. It should match the
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # soname if the object has one, and the object basename otherwise.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami #
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # Note that elfedit writes an error to stderr if the object lacks an
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # soname, so we direct stderr to /dev/null.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami my $soname =
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami `elfedit -r -osimple -e 'dyn:value dt_soname' $FullPath 2>/dev/null`;
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami if ($soname eq '') {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami $soname = $File;
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami } else {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami chomp $soname;
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami }
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # First determine what versions exist that offer interfaces. pvs -dos
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # will list these. Note that other versions may exist, ones that
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # don't offer interfaces ... we'll get to those next.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami %Vers = ();
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $VersCnt = 0;
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami my %TopNumberedVers = ();
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami foreach my $Line (split(/\n/, `pvs -dos $FullPath 2>&1`)) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my($Ver) = $Line;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $Ver =~ s/^.*-\t(.*): .*/$1/; # isolate version
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # See if we've already caught this version name. We only look
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # at each version once.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami next if ($Vers{$Ver}) ;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # Note that the non-empty version has been seen
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $Vers{$Ver} = 1;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $VersCnt++;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # Identify the version type
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami my @Cat = onbld_elfmod_vertype::Category($Ver, $soname);
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # Numbered public versions have the form
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami #
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # <prefix>major.minor[.micro]
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami #
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # with 2 or three numeric values. We expect these versions to
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # use inheritance, so there should only be one top version for
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # each major number. It is possible, though rare, to have more
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # than one top version if the major numbers differ.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami #
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # %TopNumberedVers uses the prefix and major number as the
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # key. Each key holds a reference to an array which contains
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # the top versions with the same prefix and major number.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami if ($Cat[0] eq 'NUMBERED') {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami push @{$TopNumberedVers{"$Cat[2]$Cat[3]"}}, $Ver
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami if $TopVer{$Ver};
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami next;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # If it is a non-standard version, and there's not an
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # exception in place for it, report an error.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami if ($Cat[0] eq 'UNKNOWN') {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami if (!defined($EXRE_nonstd_vername) ||
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami ($RelPath !~ $EXRE_nonstd_vername)) {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami onbld_elfmod::OutMsg($ErrFH, \$Ttl, $RelPath,
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami "non-standard version name: $Ver");
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami }
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami next;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # If we are here, it is one of PLAIN, PRIVATE, or SONAME,
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # all of which we quietly accept.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami next;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # If this file has been scoped, but not versioned (i.e., a mapfile was
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # used to demote symbols but no version name was applied to the
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # global interfaces) then it's another non-standard case.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if ($VersCnt eq 0) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami onbld_elfmod::OutMsg($ErrFH, \$Ttl, $RelPath,
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami "scoped object contains no versions");
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami return;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # If this file has multiple inheritance chains starting with the
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # same prefix and major number, that's wrong.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami foreach my $Ver (sort keys %TopNumberedVers) {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami if (scalar(@{$TopNumberedVers{$Ver}}) > 1) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami onbld_elfmod::OutMsg($ErrFH, \$Ttl, $RelPath,
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami "multiple $Ver inheritance chains (missing " .
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami "inheritance?): " .
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami join(', ', @{$TopNumberedVers{$Ver}}));
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # Produce an interface description for the object.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # For each version, generate a VERSION declaration of the form:
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami #
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # [TOP_]VERSION version direct-count total-count
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # symname1
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # symname2
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # ...
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami #
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # We suppress base and private versions from this output.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # Everything else goes in, whether it's a version we recognize
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # or not. If an object only has base or private versions, we do
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # not produce an interface description for that object.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami #
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if ($opt{i}) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $header_done = 0;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # The use of 'pvs -v' is to identify the BASE version
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami foreach my $Line (split(/\n/, `pvs -dv $FullPath 2>&1`)) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # Skip base version
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami next if ($Line =~ /\[BASE\]/);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # Directly inherited versions follow the version name
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # in a comma separated list within {} brackets. Capture
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # that information, for use with our VERSION line.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $InheritVers = ($Line =~ /(\{.*\});$/) ? "\t$1" : '';
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # Extract the version name
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $Line =~ s/^\s*([^;: ]*).*/$1/;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # Skip version if it is in the SONAME or PRIVATE
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # categories.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami #
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # The above test for BASE should have caught the
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # SONAME already, but older versions of pvs have a
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # bug that prevents them from printing [BASE] on
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # the base version. In order to solidify things even
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # more, we also exclude versions that end with
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami # a '.so.*' suffix.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami my @Cat = onbld_elfmod_vertype::Category($Line, $soname);
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami if (($Cat[0] eq 'SONAME') ||
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami ($Cat[0] eq 'PRIVATE') ||
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami ($Line =~ /\.so\.\d+$/)) {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami next;
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # We want to output the symbols in sorted order, so
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # we gather them first, and then sort the results.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # An array would suffice, but we have observed objects
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # with odd inheritance chains in which the same
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # sub-version gets inherited more than once, leading
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # to the same symbol showing up more than once. Using
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # a hash instead of an array thins out the duplicates.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my %Syms = ();
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $symitem = $opt{I} ? 'NEW' : 'SYMBOL';
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $version_cnt = 0;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami foreach my $Sym
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami (split(/\n/, `pvs -ds -N $Line $FullPath 2>&1`)) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if ($Sym =~ /:$/) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $version_cnt++;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # If this is an inherited sub-version,
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # we don't need to continue unless
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # generating output in -I mode.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if ($version_cnt >= 2) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami last if !$opt{I};
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $symitem = 'INHERIT';
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami next;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $Sym =~ s/[ \t]*(.*);$/$1/;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $Sym =~ s/ .*$//; # remove any data size
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $Syms{$Sym} = $symitem;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if (!$header_done) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print INTFILE "\n" if !$opt{h} && ($ObjCnt != 0);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $ObjCnt++;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print INTFILE "OBJECT\t$RelPath\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print INTFILE "CLASS\tELFCLASS$Class\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print INTFILE "TYPE\tET_$Type\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print INTFILE $Alias if ($Alias ne '');
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $header_done = 1;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $item = $TopVer{$Line} ? 'TOP_VERSION' : 'VERSION';
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print INTFILE "$item\t$Line$InheritVers\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # Output symbols in sorted order
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami foreach my $Sym (sort keys %Syms) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print INTFILE "\t$Syms{$Sym}\t$Sym\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami}
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami## ProcFindElf(file)
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami#
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Open the specified file, which must be produced by "find_elf -r",
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# and process the files it describes.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramisub ProcFindElf {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $file = $_[0];
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $line;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $LineNum = 0;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $prefix;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my @ObjList = ();
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my %ObjToAlias = ();
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami open(FIND_ELF, $file) || die "$Prog: Unable to open $file";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # This script requires relative paths, created by the 'find_elf -r'
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # option. When this is done, the first non-comment line will always
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # be PREFIX. Obtain that line, or issue a fatal error.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami while ($line = onbld_elfmod::GetLine(\*FIND_ELF, \$LineNum)) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if ($line =~ /^PREFIX\s+(.*)$/) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $prefix = $1;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami last;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami die "$file: PREFIX expected on line $LineNum\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # Process the remainder of the file.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami while ($line = onbld_elfmod::GetLine(\*FIND_ELF, \$LineNum)) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if ($line =~ /^OBJECT\s/i) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami push @ObjList, $line;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami next;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if ($line =~ /^ALIAS\s/i) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my ($item, $obj, $alias) = split(/\s+/, $line, 3);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $str = "ALIAS\t$alias\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami if (defined($ObjToAlias{$obj})) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $ObjToAlias{$obj} .= $str;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami } else {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $ObjToAlias{$obj} = $str;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami foreach $line (@ObjList) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my ($item, $class, $type, $verdef, $obj) =
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami split(/\s+/, $line, 5);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami my $alias = defined($ObjToAlias{$obj}) ? $ObjToAlias{$obj} : '';
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # We are only interested in sharable objects. We may see
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # other file types if processing a list of objects
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # supplied via the -f option.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami next if ($type ne 'DYN');
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami ProcFile($prefix, $obj, $class, $type, $verdef, $alias);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami }
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami close FIND_ELF;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami}
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# -----------------------------------------------------------------------------
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Establish a program name for any error diagnostics.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramichomp($Prog = `basename $0`);
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Check that we have arguments.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami@SaveArgv = @ARGV;
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahramiif ((getopts('c:E:e:f:hIi:ow:', \%opt) == 0) || (!$opt{f} && ($#ARGV == -1))) {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami print "usage: $Prog [-hIo] [-c vtype_mod] [-E errfile] [-e exfile]\n";
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami print "\t\t[-f listfile] [-i intffile] [-w outdir] file | dir, ...\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print "\n";
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami print "\t[-c vtype_mod]\tsupply alternative version category module\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print "\t[-E errfile]\tdirect error output to file\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print "\t[-e exfile]\texceptions file\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print "\t[-f listfile]\tuse file list produced by find_elf -r\n";
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami print "\t[-h]\t\tdo not produce a CDDL/Copyright header comment\n";
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami print "\t[-I]\t\tExpand inheritance in -i output (debugging)\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print "\t[-i intffile]\tcreate interface description output file\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print "\t[-o]\t\tproduce one-liner output (prefixed with pathname)\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami print "\t[-w outdir]\tinterpret all files relative to given directory\n";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami exit 1;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami}
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# We depend on the onbld_elfmod and onbld_elfmod_vertype perl modules.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# Both modules are maintained in the same directory as this script,
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# and are installed in ../lib/perl. Use the local one if present,
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# and the installed one otherwise.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami#
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# The caller is allowed to supply an alternative implementation for
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# onbld_elfmod_vertype via the -c option. In this case, the alternative
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# implementation is expected to provide the same interface as the standard
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# copy, and is loaded instead.
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami#
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahramimy $moddir = my $vermoddir = dirname($0);
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami$moddir = "$moddir/../lib/perl" if ! -f "$moddir/onbld_elfmod.pm";
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahramirequire "$moddir/onbld_elfmod.pm";
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahramiif ($opt{c}) {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami require "$opt{c}";
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami} else {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami $vermoddir = "$vermoddir/../lib/perl"
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami if ! -f "$vermoddir/onbld_elfmod_vertype.pm";
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami require "$vermoddir/onbld_elfmod_vertype.pm";
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami}
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# If -w, change working directory to given location
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami!$opt{w} || chdir($opt{w}) || die "$Prog: can't cd to $opt{w}";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Error messages go to stdout unless -E is specified. $ErrFH is a
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# file handle reference that points at the file handle where error messages
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# are sent.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiif ($opt{E}) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami open(ERROR, ">$opt{E}") || die "$Prog: open failed: $opt{E}";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $ErrFH = \*ERROR;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami} else {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami $ErrFH = \*STDOUT;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami}
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Locate and process the exceptions file
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramionbld_elfmod::LoadExceptionsToEXRE('interface_check');
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# If creating an interface description output file, prepare it for use
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiif ($opt{i}) {
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami open (INTFILE, ">$opt{i}") ||
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami die "$Prog: Unable to create file: $opt{i}";
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami # Generate the output header
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami onbld_elfmod::Header(\*INTFILE, $0, \@SaveArgv) if !$opt{h};;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami}
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Number of OBJECTs output to INTFILE
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami$ObjCnt = 0;
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# If we were passed a file previously produced by 'find_elf -r', use it.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali BahramiProcFindElf($opt{f}) if $opt{f};
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# Process each argument: Run find_elf to find the files given by
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# $Arg. If the argument is a regular file (not a directory) then disable
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# find_elf's alias checking so that the file is processed whether or not
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami# it is a symlink.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiforeach my $Arg (@ARGV) {
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami my $flag_a = (-d $Arg) ? '' : '-a';
5253169e90b276216b53d82f9ba4c56334db5740Ali Bahrami ProcFindElf("find_elf -frs $flag_a $Arg|");
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami}
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami# Close any working output files.
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiclose INTFILE if $opt{i};
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiclose ERROR if $opt{E};
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahrami
75ce41a57ff334bd8fe2cb9ed51eea835892f944Ali Bahramiexit 0;