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>

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/scripts/check_rtime.pl
          +++ new/usr/src/tools/scripts/check_rtime.pl
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15  # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16  # If applicable, add the following below this CDDL HEADER, with the
  17   17  # fields enclosed by brackets "[]" replaced with your own identifying
  18   18  # information: Portions Copyright [yyyy] [name of copyright owner]
  19   19  #
  20   20  # CDDL HEADER END
  21   21  #
  22   22  
  23   23  #
  24   24  # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
       25 +# Copyright 2015, Nexenta Systems Inc.
  25   26  #
  26   27  
  27   28  #
  28   29  # Check ELF information.
  29   30  #
  30   31  # This script descends a directory hierarchy inspecting ELF dynamic executables
  31   32  # and shared objects.  The general theme is to verify that common Makefile rules
  32   33  # have been used to build these objects.  Typical failures occur when Makefile
  33   34  # rules are re-invented rather than being inherited from "cmd/lib" Makefiles.
  34   35  #
↓ open down ↓ 12 lines elided ↑ open up ↑
  47   48  # dependencies, and without using these newer objects an ldd(1) will produce
  48   49  # misleading error messages.  To compensate for this, the -D/-d options, or the
  49   50  # existence of the CODEMSG_WS/ROOT environment variables, cause the creation of
  50   51  # alternative dependency mappings via crle(1) configuration files that establish
  51   52  # any proto shared objects as alternatives to their base system location.  Thus
  52   53  # ldd(1) can be executed against these configuration files so that objects in a
  53   54  # proto area bind to their dependencies in the same proto area.
  54   55  
  55   56  
  56   57  # Define all global variables (required for strict)
  57      -use vars  qw($Prog $Env $Ena64 $Tmpdir);
       58 +use vars  qw($Prog $Env $Ena64 $Tmpdir $Adjunct $Proto);
  58   59  use vars  qw($LddNoU $Conf32 $Conf64);
  59   60  use vars  qw(%opt);
  60   61  use vars  qw($ErrFH $ErrTtl $InfoFH $InfoTtl $OutCnt1 $OutCnt2);
  61   62  
  62   63  # An exception file is used to specify regular expressions to match
  63   64  # objects. These directives specify special attributes of the object.
  64   65  # The regular expressions are read from the file and compiled into the
  65   66  # regular expression variables.
  66   67  #
  67   68  # The name of each regular expression variable is of the form
↓ open down ↓ 796 lines elided ↑ open up ↑
 864  865                  my ($item, $class, $type, $verdef, $obj) =
 865  866                      split(/\s+/, $line, 5);
 866  867  
 867  868                  ProcFile("$prefix/$obj", $obj, $class, $type, $verdef);
 868  869          }
 869  870  
 870  871          close FIND_ELF;
 871  872  }
 872  873  
 873  874  
 874      -## AltObjectConfig(file)
      875 +## AltObjectConfig(proto, adjunct)
 875  876  #
 876  877  # Recurse through a directory hierarchy looking for appropriate dependencies
 877  878  # to map from their standard system locations to the proto area via a crle
 878  879  # config file.
 879  880  #
 880  881  # entry:
 881      -#       file - File of ELF objects, in 'find_elf -r' format, to examine.
      882 +#       proto, adjunct - Files of ELF objects, in 'find_elf -r' format, to
      883 +#       examine.
 882  884  #
 883  885  # exit:
 884  886  #       Scripts are generated for the 32 and 64-bit cases to run crle
 885  887  #       and create runtime configuration files that will establish
 886  888  #       alternative dependency mappings for the objects identified.
 887  889  #
 888  890  #       $Env - Set to environment variable definitions that will cause
 889  891  #               the config files generated by this routine to be used
 890  892  #               by ldd.
 891  893  #       $Conf32, $Conf64 - Undefined, or set to the config files generated
↓ open down ↓ 2 lines elided ↑ open up ↑
 894  896  #
 895  897  sub AltObjectConfig {
 896  898          my $file = $_[0];
 897  899          my ($Crle32, $Crle64);
 898  900          my $line;
 899  901          my $LineNum;
 900  902          my $obj_path;
 901  903          my $obj_active = 0;
 902  904          my $obj_class;
 903  905  
 904      -        my $prefix = OpenFindElf($file, \*FIND_ELF);
      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: {
 905  913  
 906      -LINE:
 907      -        while ($line = onbld_elfmod::GetLine(\*FIND_ELF, \$LineNum)) {
 908      -              ITEM: {
      914 +                                if ($line =~ /^OBJECT\s/i) {
      915 +                                        my ($item, $class, $type, $verdef, $obj)
      916 +                                            = split(/\s+/, $line, 5);
 909  917  
 910      -                        if ($line =~ /^OBJECT\s/i) {
 911      -                                my ($item, $class, $type, $verdef, $obj) =
 912      -                                    split(/\s+/, $line, 5);
      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 +                                }
 913  928  
 914      -                                if ($type eq 'DYN') {
 915      -                                        $obj_active = 1;
      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);
 916  938                                          $obj_path = $obj;
 917      -                                        $obj_class = $class;
 918      -                                } else {
 919      -                                        # Only want sharable objects
 920      -                                        $obj_active = 0;
      939 +                                        last ITEM;
 921  940                                  }
 922      -                                last ITEM;
 923      -                        }
 924  941  
 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;
      942 +                                # Skip unrecognized item
      943 +                                next LINE;
 935  944                          }
 936  945  
 937      -                        # Skip unrecognized item
 938      -                        next LINE;
 939      -                }
      946 +                        next if !$obj_active;
 940  947  
 941      -                next if !$obj_active;
      948 +                        my $full = "$prefix/$obj_path";
 942  949  
 943      -                my $full = "$prefix/$obj_path";
      950 +                        next if defined($EXRE_nocrlealt) &&
      951 +                            ($obj_path =~ $EXRE_nocrlealt);
 944  952  
 945      -                next if defined($EXRE_nocrlealt) &&
 946      -                    ($obj_path =~ $EXRE_nocrlealt);
      953 +                        my $Dir = $full;
      954 +                        $Dir =~ s/^(.*)\/.*$/$1/;
 947  955  
 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";
      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";
 961  976                          }
 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      -        }
      977 +                }
 973  978  
 974      -        close FIND_ELF;
      979 +                close FIND_ELF;
      980 +                if ($file eq $_[0]) {
      981 +                        $file = $_[1];
      982 +                        next FILE;
      983 +                }
 975  984  
      985 +                last FILE;
      986 +        }
 976  987  
 977  988          # Now that the config scripts are complete, use them to generate
 978  989          # runtime linker config files.
      990 +        $Adjunct //= "";
      991 +
 979  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 +
 980  999                  $Conf64 = "$Tmpdir/$Prog.conf64.$$";
 981 1000                  print CRLE64 "\t-c $Conf64\n";
 982 1001  
 983 1002                  chmod 0755, $Crle64;
 984 1003                  close CRLE64;
 985 1004  
 986 1005                  undef $Conf64 if system($Crle64);
 987 1006  
 988 1007                  # Done with the script
 989 1008                  unlink $Crle64;
 990 1009          }
 991 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 +
 992 1014                  $Conf32 = "$Tmpdir/$Prog.conf32.$$";
 993 1015                  print CRLE32 "\t-c $Conf32\n";
 994 1016  
 995 1017                  chmod 0755, $Crle32;
 996 1018                  close CRLE32;
 997 1019  
 998 1020                  undef $Conf32 if system($Crle32);
 999 1021  
1000 1022                  # Done with the script
1001 1023                  unlink $Crle32;
↓ open down ↓ 42 lines elided ↑ open up ↑
1044 1066          if ($Isalist =~ /amd64/) {
1045 1067                  $Ena64 = "ok";
1046 1068          }
1047 1069  }
1048 1070  
1049 1071  # $Env is used with all calls to ldd. It is set by AltObjectConfig to
1050 1072  # cause an alternate object mapping runtime config file to be used.
1051 1073  $Env = '';
1052 1074  
1053 1075  # Check that we have arguments.
1054      -if ((getopts('D:d:E:e:f:I:imosvw:', \%opt) == 0) ||
     1076 +if ((getopts('A:a:D:d:E:e:f:I:imosvw:', \%opt) == 0) ||
1055 1077      (!$opt{f} && ($#ARGV == -1))) {
1056      -        print "usage: $Prog [-imosv] [-D depfile | -d depdir] [-E errfile]\n";
     1078 +        print "usage: $Prog [-imosv] [-A depfile | -a depdir ] [-D depfile | -d depdir] [-E errfile]\n";
1057 1079          print "\t\t[-e exfile] [-f listfile] [-I infofile] [-w outdir]\n";
1058 1080          print "\t\t[file | dir]...\n";
1059 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";
1060 1084          print "\t[-D depfile]\testablish dependencies from 'find_elf -r' file list\n";
1061 1085          print "\t[-d depdir]\testablish dependencies from under directory\n";
1062 1086          print "\t[-E errfile]\tdirect error output to file\n";
1063 1087          print "\t[-e exfile]\texceptions file\n";
1064 1088          print "\t[-f listfile]\tuse file list produced by find_elf -r\n";
1065 1089          print "\t[-I infofile]\tdirect informational output (-i, -v) to file\n";
1066 1090          print "\t[-i]\t\tproduce dynamic table entry information\n";
1067 1091          print "\t[-m]\t\tprocess mcs(1) comments\n";
1068 1092          print "\t[-o]\t\tproduce one-liner output (prefixed with pathname)\n";
1069 1093          print "\t[-s]\t\tprocess .stab and .symtab entries\n";
1070 1094          print "\t[-v]\t\tprocess version definition entries\n";
1071 1095          print "\t[-w outdir]\tinterpret all files relative to given directory\n";
1072 1096          exit 1;
1073 1097  }
1074 1098  
     1099 +die "$Prog: -A and -a options are mutually exclusive\n" if ($opt{A} && $opt{a});
1075 1100  die "$Prog: -D and -d options are mutually exclusive\n" if ($opt{D} && $opt{d});
1076 1101  
1077 1102  $Tmpdir = "/tmp" if (!($Tmpdir = $ENV{TMPDIR}) || (! -d $Tmpdir));
1078 1103  
1079 1104  # If -w, change working directory to given location
1080 1105  !$opt{w} || chdir($opt{w}) || die "$Prog: can't cd to $opt{w}";
1081 1106  
1082 1107  # Locate and process the exceptions file
1083 1108  onbld_elfmod::LoadExceptionsToEXRE('check_rtime');
1084 1109  
1085 1110  # Is there a proto area available, either via the -d option, or because
1086 1111  # we are part of an activated workspace?
1087      -my $Proto;
1088 1112  if ($opt{d}) {
1089 1113          # User specified dependency directory - make sure it exists.
1090 1114          -d $opt{d} || die "$Prog: $opt{d} is not a directory\n";
1091 1115          $Proto = $opt{d};
1092 1116  } elsif ($ENV{CODEMGR_WS}) {
1093 1117          my $Root;
1094 1118  
1095 1119          # Without a user specified dependency directory see if we're
1096 1120          # part of a codemanager workspace and if a proto area exists.
1097 1121          $Proto = $Root if ($Root = $ENV{ROOT}) && (-d $Root);
1098 1122  }
1099 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 +
1100 1139  # If we are basing this analysis off the sharable objects found in
1101 1140  # a proto area, then gather dependencies and construct an alternative
1102 1141  # dependency mapping via a crle(1) configuration file.
1103 1142  #
1104 1143  # To support alternative dependency mapping we'll need ldd(1)'s
1105 1144  # -e option.  This is relatively new (s81_30), so make sure
1106 1145  # ldd(1) is capable before gathering any dependency information.
1107      -if ($opt{D} || $Proto) {
     1146 +if ($opt{D} || $Proto || $Adjunct) {
1108 1147          if (system('ldd -e /usr/lib/lddstub 2> /dev/null')) {
1109 1148                  print "ldd: does not support -e, unable to ";
1110 1149                  print "create alternative dependency mappingings.\n";
1111 1150                  print "ldd: option added under 4390308 (s81_30).\n\n";
1112 1151          } else {
1113      -                # If -D was specified, it supplies a list of files in
     1152 +                # If -D or -A was specified, it supplies a list of files in
1114 1153                  # 'find_elf -r' format, and can use it directly. Otherwise,
1115 1154                  # we will run find_elf as a child process to find the
1116 1155                  # sharable objects found under $Proto.
1117      -                AltObjectConfig($opt{D} ? $opt{D} : "find_elf -frs $Proto|");
     1156 +                AltObjectConfig($opt{D} ? $opt{D} : "find_elf -frs $Proto|",
     1157 +                        $opt{A} ? $opt{A} : $Adjunct ? "find_elf -frs $Adjunct|" : "/dev/null");
1118 1158          }
1119 1159  }
1120 1160  
1121 1161  # To support unreferenced dependency detection we'll need ldd(1)'s -U
1122 1162  # option.  This is relatively new (4638070), and if not available we
1123 1163  # can still fall back to -u.  Even with this option, don't use -U with
1124 1164  # releases prior to 5.10 as the cleanup for -U use only got integrated
1125 1165  # into 5.10 under 4642023.  Note, that nightly doesn't typically set a
1126 1166  # RELEASE from the standard <env> files.  Users who wish to disable use
1127 1167  # of ldd(1)'s -U should set (or uncomment) RELEASE in their <env> file
↓ open down ↓ 62 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX