Print this page
NEX-5205 adjunct support for check_rtime
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>


   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 
  23 #
  24 # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.

  25 #
  26 
  27 #
  28 # Check ELF information.
  29 #
  30 # This script descends a directory hierarchy inspecting ELF dynamic executables
  31 # and shared objects.  The general theme is to verify that common Makefile rules
  32 # have been used to build these objects.  Typical failures occur when Makefile
  33 # rules are re-invented rather than being inherited from "cmd/lib" Makefiles.
  34 #
  35 # As always, a number of components don't follow the rules, and these are
  36 # excluded to reduce this scripts output.
  37 #
  38 # By default any file that has conditions that should be reported is first
  39 # listed and then each condition follows.  The -o (one-line) option produces a
  40 # more terse output which is better for sorting/diffing with "nightly".
  41 #
  42 # NOTE: missing dependencies, symbols or versions are reported by running the
  43 # file through ldd(1).  As objects within a proto area are built to exist in a
  44 # base system, standard use of ldd(1) will bind any objects to dependencies
  45 # that exist in the base system.  It is frequently the case that newer objects
  46 # exist in the proto area that are required to satisfy other objects
  47 # dependencies, and without using these newer objects an ldd(1) will produce
  48 # misleading error messages.  To compensate for this, the -D/-d options, or the
  49 # existence of the CODEMSG_WS/ROOT environment variables, cause the creation of
  50 # alternative dependency mappings via crle(1) configuration files that establish
  51 # any proto shared objects as alternatives to their base system location.  Thus
  52 # ldd(1) can be executed against these configuration files so that objects in a
  53 # proto area bind to their dependencies in the same proto area.
  54 
  55 
  56 # Define all global variables (required for strict)
  57 use vars  qw($Prog $Env $Ena64 $Tmpdir);
  58 use vars  qw($LddNoU $Conf32 $Conf64);
  59 use vars  qw(%opt);
  60 use vars  qw($ErrFH $ErrTtl $InfoFH $InfoTtl $OutCnt1 $OutCnt2);
  61 
  62 # An exception file is used to specify regular expressions to match
  63 # objects. These directives specify special attributes of the object.
  64 # The regular expressions are read from the file and compiled into the
  65 # regular expression variables.
  66 #
  67 # The name of each regular expression variable is of the form
  68 #
  69 #       $EXRE_xxx
  70 #
  71 # where xxx is the name of the exception in lower case. For example,
  72 # the regular expression variable for EXEC_STACK is $EXRE_exec_stack.
  73 #
  74 # onbld_elfmod::LoadExceptionsToEXRE() depends on this naming convention
  75 # to initialize the regular expression variables, and to detect invalid
  76 # exception names.
  77 #


 854 sub ProcFindElf {
 855         my $file = $_[0];
 856         my $line;
 857         my $LineNum;
 858 
 859         my $prefix = OpenFindElf($file, \*FIND_ELF, \$LineNum);
 860 
 861         while ($line = onbld_elfmod::GetLine(\*FIND_ELF, \$LineNum)) {
 862                 next if !($line =~ /^OBJECT\s/i);
 863 
 864                 my ($item, $class, $type, $verdef, $obj) =
 865                     split(/\s+/, $line, 5);
 866 
 867                 ProcFile("$prefix/$obj", $obj, $class, $type, $verdef);
 868         }
 869 
 870         close FIND_ELF;
 871 }
 872 
 873 
 874 ## AltObjectConfig(file)
 875 #
 876 # Recurse through a directory hierarchy looking for appropriate dependencies
 877 # to map from their standard system locations to the proto area via a crle
 878 # config file.
 879 #
 880 # entry:
 881 #       file - File of ELF objects, in 'find_elf -r' format, to examine.

 882 #
 883 # exit:
 884 #       Scripts are generated for the 32 and 64-bit cases to run crle
 885 #       and create runtime configuration files that will establish
 886 #       alternative dependency mappings for the objects identified.
 887 #
 888 #       $Env - Set to environment variable definitions that will cause
 889 #               the config files generated by this routine to be used
 890 #               by ldd.
 891 #       $Conf32, $Conf64 - Undefined, or set to the config files generated
 892 #               by this routine. If defined, the caller is responsible for
 893 #               unlinking the files before exiting.
 894 #
 895 sub AltObjectConfig {
 896         my $file = $_[0];
 897         my ($Crle32, $Crle64);
 898         my $line;
 899         my $LineNum;
 900         my $obj_path;
 901         my $obj_active = 0;
 902         my $obj_class;
 903 
 904         my $prefix = OpenFindElf($file, \*FIND_ELF);


 905 
 906 LINE:
 907         while ($line = onbld_elfmod::GetLine(\*FIND_ELF, \$LineNum)) {
 908               ITEM: {
 909 
 910                         if ($line =~ /^OBJECT\s/i) {
 911                                 my ($item, $class, $type, $verdef, $obj) =
 912                                     split(/\s+/, $line, 5);
 913 
 914                                 if ($type eq 'DYN') {
 915                                         $obj_active = 1;
 916                                         $obj_path = $obj;
 917                                         $obj_class = $class;
 918                                 } else {
 919                                         # Only want sharable objects
 920                                         $obj_active = 0;
 921                                 }
 922                                 last ITEM;
 923                         }
 924 
 925                         # We need to follow links to sharable objects so
 926                         # that any dependencies are expressed in all their
 927                         # available forms. We depend on ALIAS lines directly
 928                         # following the object they alias, so if we have
 929                         # a current object, this alias belongs to it.

 930                         if ($obj_active && ($line =~ /^ALIAS\s/i)) {
 931                                 my ($item, $real_obj, $obj) =
 932                                     split(/\s+/, $line, 3);
 933                                 $obj_path = $obj;
 934                                 last ITEM;
 935                         }
 936 
 937                         # Skip unrecognized item
 938                         next LINE;
 939                 }
 940 
 941                 next if !$obj_active;
 942 
 943                 my $full = "$prefix/$obj_path";
 944 
 945                 next if defined($EXRE_nocrlealt) &&
 946                     ($obj_path =~ $EXRE_nocrlealt);
 947 
 948                 my $Dir = $full;
 949                 $Dir =~ s/^(.*)\/.*$/$1/;
 950 
 951                 # Create a crle(1) script for the dependency we've found.
 952                 # We build separate scripts for the 32 and 64-bit cases.
 953                 # We create and initialize each script when we encounter
 954                 # the first object that needs it.
 955                 if ($obj_class == 32) {
 956                         if (!$Crle32) {
 957                                 $Crle32 = "$Tmpdir/$Prog.crle32.$$";
 958                                 open(CRLE32, "> $Crle32") ||
 959                                     die "$Prog: open failed: $Crle32: $!";
 960                                 print CRLE32 "#!/bin/sh\ncrle \\\n";
 961                         }
 962                         print CRLE32 "\t-o $Dir -a /$obj_path \\\n";
 963                 } elsif ($Ena64) {
 964                         if (!$Crle64) {
 965                                 $Crle64 = "$Tmpdir/$Prog.crle64.$$";
 966                                 open(CRLE64, "> $Crle64") ||
 967                                     die "$Prog: open failed: $Crle64: $!";
 968                                 print CRLE64 "#!/bin/sh\ncrle -64\\\n";
 969                         }
 970                         print CRLE64 "\t-o $Dir -a /$obj_path \\\n";
 971                 }
 972         }
 973 
 974         close FIND_ELF;




 975 


 976 
 977         # Now that the config scripts are complete, use them to generate
 978         # runtime linker config files.


 979         if ($Crle64) {






 980                 $Conf64 = "$Tmpdir/$Prog.conf64.$$";
 981                 print CRLE64 "\t-c $Conf64\n";
 982 
 983                 chmod 0755, $Crle64;
 984                 close CRLE64;
 985 
 986                 undef $Conf64 if system($Crle64);
 987 
 988                 # Done with the script
 989                 unlink $Crle64;
 990         }
 991         if ($Crle32) {



 992                 $Conf32 = "$Tmpdir/$Prog.conf32.$$";
 993                 print CRLE32 "\t-c $Conf32\n";
 994 
 995                 chmod 0755, $Crle32;
 996                 close CRLE32;
 997 
 998                 undef $Conf32 if system($Crle32);
 999 
1000                 # Done with the script
1001                 unlink $Crle32;
1002         }
1003 
1004         # Set $Env so that we will use the config files generated above
1005         # when we run ldd.
1006         if ($Crle64 && $Conf64 && $Crle32 && $Conf32) {
1007                 $Env = "-e LD_FLAGS=config_64=$Conf64,config_32=$Conf32";
1008         } elsif ($Crle64 && $Conf64) {
1009                 $Env = "-e LD_FLAGS=config_64=$Conf64";
1010         } elsif ($Crle32 && $Conf32) {
1011                 $Env = "-e LD_FLAGS=config_32=$Conf32";


1034 require "$moddir/onbld_elfmod.pm";
1035 
1036 # Determine what machinery is available.
1037 my $Mach = `uname -p`;
1038 my$Isalist = `isalist`;
1039 if ($Mach =~ /sparc/) {
1040         if ($Isalist =~ /sparcv9/) {
1041                 $Ena64 = "ok";
1042         }
1043 } elsif ($Mach =~ /i386/) {
1044         if ($Isalist =~ /amd64/) {
1045                 $Ena64 = "ok";
1046         }
1047 }
1048 
1049 # $Env is used with all calls to ldd. It is set by AltObjectConfig to
1050 # cause an alternate object mapping runtime config file to be used.
1051 $Env = '';
1052 
1053 # Check that we have arguments.
1054 if ((getopts('D:d:E:e:f:I:imosvw:', \%opt) == 0) ||
1055     (!$opt{f} && ($#ARGV == -1))) {
1056         print "usage: $Prog [-imosv] [-D depfile | -d depdir] [-E errfile]\n";
1057         print "\t\t[-e exfile] [-f listfile] [-I infofile] [-w outdir]\n";
1058         print "\t\t[file | dir]...\n";
1059         print "\n";


1060         print "\t[-D depfile]\testablish dependencies from 'find_elf -r' file list\n";
1061         print "\t[-d depdir]\testablish dependencies from under directory\n";
1062         print "\t[-E errfile]\tdirect error output to file\n";
1063         print "\t[-e exfile]\texceptions file\n";
1064         print "\t[-f listfile]\tuse file list produced by find_elf -r\n";
1065         print "\t[-I infofile]\tdirect informational output (-i, -v) to file\n";
1066         print "\t[-i]\t\tproduce dynamic table entry information\n";
1067         print "\t[-m]\t\tprocess mcs(1) comments\n";
1068         print "\t[-o]\t\tproduce one-liner output (prefixed with pathname)\n";
1069         print "\t[-s]\t\tprocess .stab and .symtab entries\n";
1070         print "\t[-v]\t\tprocess version definition entries\n";
1071         print "\t[-w outdir]\tinterpret all files relative to given directory\n";
1072         exit 1;
1073 }
1074 

1075 die "$Prog: -D and -d options are mutually exclusive\n" if ($opt{D} && $opt{d});
1076 
1077 $Tmpdir = "/tmp" if (!($Tmpdir = $ENV{TMPDIR}) || (! -d $Tmpdir));
1078 
1079 # If -w, change working directory to given location
1080 !$opt{w} || chdir($opt{w}) || die "$Prog: can't cd to $opt{w}";
1081 
1082 # Locate and process the exceptions file
1083 onbld_elfmod::LoadExceptionsToEXRE('check_rtime');
1084 
1085 # Is there a proto area available, either via the -d option, or because
1086 # we are part of an activated workspace?
1087 my $Proto;
1088 if ($opt{d}) {
1089         # User specified dependency directory - make sure it exists.
1090         -d $opt{d} || die "$Prog: $opt{d} is not a directory\n";
1091         $Proto = $opt{d};
1092 } elsif ($ENV{CODEMGR_WS}) {
1093         my $Root;
1094 
1095         # Without a user specified dependency directory see if we're
1096         # part of a codemanager workspace and if a proto area exists.
1097         $Proto = $Root if ($Root = $ENV{ROOT}) && (-d $Root);
1098 }
1099 















1100 # If we are basing this analysis off the sharable objects found in
1101 # a proto area, then gather dependencies and construct an alternative
1102 # dependency mapping via a crle(1) configuration file.
1103 #
1104 # To support alternative dependency mapping we'll need ldd(1)'s
1105 # -e option.  This is relatively new (s81_30), so make sure
1106 # ldd(1) is capable before gathering any dependency information.
1107 if ($opt{D} || $Proto) {
1108         if (system('ldd -e /usr/lib/lddstub 2> /dev/null')) {
1109                 print "ldd: does not support -e, unable to ";
1110                 print "create alternative dependency mappingings.\n";
1111                 print "ldd: option added under 4390308 (s81_30).\n\n";
1112         } else {
1113                 # If -D was specified, it supplies a list of files in
1114                 # 'find_elf -r' format, and can use it directly. Otherwise,
1115                 # we will run find_elf as a child process to find the
1116                 # sharable objects found under $Proto.
1117                 AltObjectConfig($opt{D} ? $opt{D} : "find_elf -frs $Proto|");

1118         }
1119 }
1120 
1121 # To support unreferenced dependency detection we'll need ldd(1)'s -U
1122 # option.  This is relatively new (4638070), and if not available we
1123 # can still fall back to -u.  Even with this option, don't use -U with
1124 # releases prior to 5.10 as the cleanup for -U use only got integrated
1125 # into 5.10 under 4642023.  Note, that nightly doesn't typically set a
1126 # RELEASE from the standard <env> files.  Users who wish to disable use
1127 # of ldd(1)'s -U should set (or uncomment) RELEASE in their <env> file
1128 # if using nightly, or otherwise establish it in their environment.
1129 if (system('ldd -U /usr/lib/lddstub 2> /dev/null')) {
1130         $LddNoU = 1;
1131 } else {
1132         my($Release);
1133 
1134         if (($Release = $ENV{RELEASE}) && (cmp_os_ver($Release, "<", "5.10"))) {
1135                 $LddNoU = 1;
1136         } else {
1137                 $LddNoU = 0;




   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 
  23 #
  24 # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  25 # Copyright 2015, Nexenta Systems Inc.
  26 #
  27 
  28 #
  29 # Check ELF information.
  30 #
  31 # This script descends a directory hierarchy inspecting ELF dynamic executables
  32 # and shared objects.  The general theme is to verify that common Makefile rules
  33 # have been used to build these objects.  Typical failures occur when Makefile
  34 # rules are re-invented rather than being inherited from "cmd/lib" Makefiles.
  35 #
  36 # As always, a number of components don't follow the rules, and these are
  37 # excluded to reduce this scripts output.
  38 #
  39 # By default any file that has conditions that should be reported is first
  40 # listed and then each condition follows.  The -o (one-line) option produces a
  41 # more terse output which is better for sorting/diffing with "nightly".
  42 #
  43 # NOTE: missing dependencies, symbols or versions are reported by running the
  44 # file through ldd(1).  As objects within a proto area are built to exist in a
  45 # base system, standard use of ldd(1) will bind any objects to dependencies
  46 # that exist in the base system.  It is frequently the case that newer objects
  47 # exist in the proto area that are required to satisfy other objects
  48 # dependencies, and without using these newer objects an ldd(1) will produce
  49 # misleading error messages.  To compensate for this, the -D/-d options, or the
  50 # existence of the CODEMSG_WS/ROOT environment variables, cause the creation of
  51 # alternative dependency mappings via crle(1) configuration files that establish
  52 # any proto shared objects as alternatives to their base system location.  Thus
  53 # ldd(1) can be executed against these configuration files so that objects in a
  54 # proto area bind to their dependencies in the same proto area.
  55 
  56 
  57 # Define all global variables (required for strict)
  58 use vars  qw($Prog $Env $Ena64 $Tmpdir $Adjunct $Proto);
  59 use vars  qw($LddNoU $Conf32 $Conf64);
  60 use vars  qw(%opt);
  61 use vars  qw($ErrFH $ErrTtl $InfoFH $InfoTtl $OutCnt1 $OutCnt2);
  62 
  63 # An exception file is used to specify regular expressions to match
  64 # objects. These directives specify special attributes of the object.
  65 # The regular expressions are read from the file and compiled into the
  66 # regular expression variables.
  67 #
  68 # The name of each regular expression variable is of the form
  69 #
  70 #       $EXRE_xxx
  71 #
  72 # where xxx is the name of the exception in lower case. For example,
  73 # the regular expression variable for EXEC_STACK is $EXRE_exec_stack.
  74 #
  75 # onbld_elfmod::LoadExceptionsToEXRE() depends on this naming convention
  76 # to initialize the regular expression variables, and to detect invalid
  77 # exception names.
  78 #


 855 sub ProcFindElf {
 856         my $file = $_[0];
 857         my $line;
 858         my $LineNum;
 859 
 860         my $prefix = OpenFindElf($file, \*FIND_ELF, \$LineNum);
 861 
 862         while ($line = onbld_elfmod::GetLine(\*FIND_ELF, \$LineNum)) {
 863                 next if !($line =~ /^OBJECT\s/i);
 864 
 865                 my ($item, $class, $type, $verdef, $obj) =
 866                     split(/\s+/, $line, 5);
 867 
 868                 ProcFile("$prefix/$obj", $obj, $class, $type, $verdef);
 869         }
 870 
 871         close FIND_ELF;
 872 }
 873 
 874 
 875 ## AltObjectConfig(proto, adjunct)
 876 #
 877 # Recurse through a directory hierarchy looking for appropriate dependencies
 878 # to map from their standard system locations to the proto area via a crle
 879 # config file.
 880 #
 881 # entry:
 882 #       proto, adjunct - Files of ELF objects, in 'find_elf -r' format, to
 883 #       examine.
 884 #
 885 # exit:
 886 #       Scripts are generated for the 32 and 64-bit cases to run crle
 887 #       and create runtime configuration files that will establish
 888 #       alternative dependency mappings for the objects identified.
 889 #
 890 #       $Env - Set to environment variable definitions that will cause
 891 #               the config files generated by this routine to be used
 892 #               by ldd.
 893 #       $Conf32, $Conf64 - Undefined, or set to the config files generated
 894 #               by this routine. If defined, the caller is responsible for
 895 #               unlinking the files before exiting.
 896 #
 897 sub AltObjectConfig {
 898         my $file = $_[0];
 899         my ($Crle32, $Crle64);
 900         my $line;
 901         my $LineNum;
 902         my $obj_path;
 903         my $obj_active = 0;
 904         my $obj_class;
 905 
 906         my $prefix;
 907 FILE:
 908         while ($prefix = OpenFindElf($file, \*FIND_ELF)) {
 909         
 910         LINE:
 911                 while ($line = onbld_elfmod::GetLine(\*FIND_ELF, \$LineNum)) {
 912                       ITEM: {
 913 
 914                                 if ($line =~ /^OBJECT\s/i) {
 915                                         my ($item, $class, $type, $verdef, $obj)
 916                                             = split(/\s+/, $line, 5);
 917 
 918                                         if ($type eq 'DYN') {
 919                                                 $obj_active = 1;
 920                                                 $obj_path = $obj;
 921                                                 $obj_class = $class;
 922                                         } else {
 923                                                 # Only want sharable objects
 924                                                 $obj_active = 0;
 925                                         }
 926                                         last ITEM;
 927                                 }
 928 
 929                                 # We need to follow links to sharable objects
 930                                 # so that any dependencies are expressed in all
 931                                 # their available forms. We depend on ALIAS
 932                                 # lines directly following the object they
 933                                 # alias, so if we have a current object, this
 934                                 # alias belongs to it.
 935                                 if ($obj_active && ($line =~ /^ALIAS\s/i)) {
 936                                         my ($item, $real_obj, $obj) =
 937                                             split(/\s+/, $line, 3);
 938                                         $obj_path = $obj;
 939                                         last ITEM;
 940                                 }
 941 
 942                                 # Skip unrecognized item
 943                                 next LINE;
 944                         }
 945 
 946                         next if !$obj_active;
 947 
 948                         my $full = "$prefix/$obj_path";
 949 
 950                         next if defined($EXRE_nocrlealt) &&
 951                             ($obj_path =~ $EXRE_nocrlealt);
 952 
 953                         my $Dir = $full;
 954                         $Dir =~ s/^(.*)\/.*$/$1/;
 955 
 956                         # Create a crle(1) script for the dependency we've
 957                         # found. We build separate scripts for the 32 and 64-bit
 958                         # cases. We create and initialize each script when we
 959                         # encounter the first object that needs it.
 960                         if ($obj_class == 32) {
 961                                 if (!$Crle32) {
 962                                         $Crle32 = "$Tmpdir/$Prog.crle32.$$";
 963                                         open(CRLE32, "> $Crle32") || die
 964                                             "$Prog: open failed: $Crle32: $!";
 965                                         print CRLE32 "#!/bin/sh\ncrle \\\n";
 966                                 }
 967                                 print CRLE32 "\t-o $Dir -a /$obj_path \\\n";
 968                         } elsif ($Ena64) {
 969                                 if (!$Crle64) {
 970                                         $Crle64 = "$Tmpdir/$Prog.crle64.$$";
 971                                         open(CRLE64, "> $Crle64") || die
 972                                             "$Prog: open failed: $Crle64: $!";
 973                                         print CRLE64 "#!/bin/sh\ncrle -64\\\n";
 974                                 }
 975                                 print CRLE64 "\t-o $Dir -a /$obj_path \\\n";
 976                         }
 977                 }
 978 
 979                 close FIND_ELF;
 980                 if ($file eq $_[0]) {
 981                         $file = $_[1];
 982                         next FILE;
 983                 }
 984 
 985                 last FILE;
 986         }
 987 
 988         # Now that the config scripts are complete, use them to generate
 989         # runtime linker config files.
 990         $Adjunct //= "";
 991 
 992         if ($Crle64) {
 993                 print CRLE64
 994                         "\t-l ${Proto}/lib/64:${Proto}/usr/lib/64 \\\n";
 995 
 996                 print CRLE64
 997                     "\t-l ${Adjunct}/lib/64:${Adjunct}/usr/lib/64 \\\n";
 998 
 999                 $Conf64 = "$Tmpdir/$Prog.conf64.$$";
1000                 print CRLE64 "\t-c $Conf64\n";
1001 
1002                 chmod 0755, $Crle64;
1003                 close CRLE64;
1004 
1005                 undef $Conf64 if system($Crle64);
1006 
1007                 # Done with the script
1008                 unlink $Crle64;
1009         }
1010         if ($Crle32) {
1011                 print CRLE32 "\t-l ${Proto}/lib:${Proto}/usr/lib \\\n";
1012                 print CRLE32 "\t-l ${Adjunct}/lib:${Adjunct}/usr/lib \\\n";
1013 
1014                 $Conf32 = "$Tmpdir/$Prog.conf32.$$";
1015                 print CRLE32 "\t-c $Conf32\n";
1016 
1017                 chmod 0755, $Crle32;
1018                 close CRLE32;
1019 
1020                 undef $Conf32 if system($Crle32);
1021 
1022                 # Done with the script
1023                 unlink $Crle32;
1024         }
1025 
1026         # Set $Env so that we will use the config files generated above
1027         # when we run ldd.
1028         if ($Crle64 && $Conf64 && $Crle32 && $Conf32) {
1029                 $Env = "-e LD_FLAGS=config_64=$Conf64,config_32=$Conf32";
1030         } elsif ($Crle64 && $Conf64) {
1031                 $Env = "-e LD_FLAGS=config_64=$Conf64";
1032         } elsif ($Crle32 && $Conf32) {
1033                 $Env = "-e LD_FLAGS=config_32=$Conf32";


1056 require "$moddir/onbld_elfmod.pm";
1057 
1058 # Determine what machinery is available.
1059 my $Mach = `uname -p`;
1060 my$Isalist = `isalist`;
1061 if ($Mach =~ /sparc/) {
1062         if ($Isalist =~ /sparcv9/) {
1063                 $Ena64 = "ok";
1064         }
1065 } elsif ($Mach =~ /i386/) {
1066         if ($Isalist =~ /amd64/) {
1067                 $Ena64 = "ok";
1068         }
1069 }
1070 
1071 # $Env is used with all calls to ldd. It is set by AltObjectConfig to
1072 # cause an alternate object mapping runtime config file to be used.
1073 $Env = '';
1074 
1075 # Check that we have arguments.
1076 if ((getopts('A:a:D:d:E:e:f:I:imosvw:', \%opt) == 0) ||
1077     (!$opt{f} && ($#ARGV == -1))) {
1078         print "usage: $Prog [-imosv] [-A depfile | -a depdir ] [-D depfile | -d depdir] [-E errfile]\n";
1079         print "\t\t[-e exfile] [-f listfile] [-I infofile] [-w outdir]\n";
1080         print "\t\t[file | dir]...\n";
1081         print "\n";
1082         print "\t[-A depfile]\testablish adjunct dependencies from 'find_elf -r' file list\n";
1083         print "\t[-a depdir]\testablish adjunct dependencies from under directory\n";
1084         print "\t[-D depfile]\testablish dependencies from 'find_elf -r' file list\n";
1085         print "\t[-d depdir]\testablish dependencies from under directory\n";
1086         print "\t[-E errfile]\tdirect error output to file\n";
1087         print "\t[-e exfile]\texceptions file\n";
1088         print "\t[-f listfile]\tuse file list produced by find_elf -r\n";
1089         print "\t[-I infofile]\tdirect informational output (-i, -v) to file\n";
1090         print "\t[-i]\t\tproduce dynamic table entry information\n";
1091         print "\t[-m]\t\tprocess mcs(1) comments\n";
1092         print "\t[-o]\t\tproduce one-liner output (prefixed with pathname)\n";
1093         print "\t[-s]\t\tprocess .stab and .symtab entries\n";
1094         print "\t[-v]\t\tprocess version definition entries\n";
1095         print "\t[-w outdir]\tinterpret all files relative to given directory\n";
1096         exit 1;
1097 }
1098 
1099 die "$Prog: -A and -a options are mutually exclusive\n" if ($opt{A} && $opt{a});
1100 die "$Prog: -D and -d options are mutually exclusive\n" if ($opt{D} && $opt{d});
1101 
1102 $Tmpdir = "/tmp" if (!($Tmpdir = $ENV{TMPDIR}) || (! -d $Tmpdir));
1103 
1104 # If -w, change working directory to given location
1105 !$opt{w} || chdir($opt{w}) || die "$Prog: can't cd to $opt{w}";
1106 
1107 # Locate and process the exceptions file
1108 onbld_elfmod::LoadExceptionsToEXRE('check_rtime');
1109 
1110 # Is there a proto area available, either via the -d option, or because
1111 # we are part of an activated workspace?

1112 if ($opt{d}) {
1113         # User specified dependency directory - make sure it exists.
1114         -d $opt{d} || die "$Prog: $opt{d} is not a directory\n";
1115         $Proto = $opt{d};
1116 } elsif ($ENV{CODEMGR_WS}) {
1117         my $Root;
1118 
1119         # Without a user specified dependency directory see if we're
1120         # part of a codemanager workspace and if a proto area exists.
1121         $Proto = $Root if ($Root = $ENV{ROOT}) && (-d $Root);
1122 }
1123 
1124 # Is there an adjunct proto area available, either via the -a option,
1125 # or because we are part of an activated workspace?
1126 if ($opt{a}) {
1127         # User specified dependency directory - make sure it exists.
1128         -d $opt{a} || die "$Prog: $opt{a} is not a directory\n";
1129         $Adjunct = $opt{a};
1130 } elsif ($ENV{CODEMGR_WS}) {
1131         my $Root;
1132 
1133         # Without a user specified dependency directory see if we're
1134         # part of a codemanager workspace and if an adjunct proto area
1135         # exists.
1136         $Adjunct = $Root if ($Root = $ENV{ADJUNCT_PROTO}) && (-d $Root);
1137 }
1138 
1139 # If we are basing this analysis off the sharable objects found in
1140 # a proto area, then gather dependencies and construct an alternative
1141 # dependency mapping via a crle(1) configuration file.
1142 #
1143 # To support alternative dependency mapping we'll need ldd(1)'s
1144 # -e option.  This is relatively new (s81_30), so make sure
1145 # ldd(1) is capable before gathering any dependency information.
1146 if ($opt{D} || $Proto || $Adjunct) {
1147         if (system('ldd -e /usr/lib/lddstub 2> /dev/null')) {
1148                 print "ldd: does not support -e, unable to ";
1149                 print "create alternative dependency mappingings.\n";
1150                 print "ldd: option added under 4390308 (s81_30).\n\n";
1151         } else {
1152                 # If -D or -A was specified, it supplies a list of files in
1153                 # 'find_elf -r' format, and can use it directly. Otherwise,
1154                 # we will run find_elf as a child process to find the
1155                 # sharable objects found under $Proto.
1156                 AltObjectConfig($opt{D} ? $opt{D} : "find_elf -frs $Proto|",
1157                         $opt{A} ? $opt{A} : $Adjunct ? "find_elf -frs $Adjunct|" : "/dev/null");
1158         }
1159 }
1160 
1161 # To support unreferenced dependency detection we'll need ldd(1)'s -U
1162 # option.  This is relatively new (4638070), and if not available we
1163 # can still fall back to -u.  Even with this option, don't use -U with
1164 # releases prior to 5.10 as the cleanup for -U use only got integrated
1165 # into 5.10 under 4642023.  Note, that nightly doesn't typically set a
1166 # RELEASE from the standard <env> files.  Users who wish to disable use
1167 # of ldd(1)'s -U should set (or uncomment) RELEASE in their <env> file
1168 # if using nightly, or otherwise establish it in their environment.
1169 if (system('ldd -U /usr/lib/lddstub 2> /dev/null')) {
1170         $LddNoU = 1;
1171 } else {
1172         my($Release);
1173 
1174         if (($Release = $ENV{RELEASE}) && (cmp_os_ver($Release, "<", "5.10"))) {
1175                 $LddNoU = 1;
1176         } else {
1177                 $LddNoU = 0;