1*0Sstevel@tonic-gate#!/bin/perl -w 2*0Sstevel@tonic-gate# 3*0Sstevel@tonic-gate# CDDL HEADER START 4*0Sstevel@tonic-gate# 5*0Sstevel@tonic-gate# The contents of this file are subject to the terms of the 6*0Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only 7*0Sstevel@tonic-gate# (the "License"). You may not use this file except in compliance 8*0Sstevel@tonic-gate# with the License. 9*0Sstevel@tonic-gate# 10*0Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11*0Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 12*0Sstevel@tonic-gate# See the License for the specific language governing permissions 13*0Sstevel@tonic-gate# and limitations under the License. 14*0Sstevel@tonic-gate# 15*0Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 16*0Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17*0Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 18*0Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 19*0Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 20*0Sstevel@tonic-gate# 21*0Sstevel@tonic-gate# CDDL HEADER END 22*0Sstevel@tonic-gate# 23*0Sstevel@tonic-gate# 24*0Sstevel@tonic-gate# ident "%Z%%M% %I% %E% SMI" 25*0Sstevel@tonic-gate# 26*0Sstevel@tonic-gate# Copyright 2002 Sun Microsystems, Inc. All rights reserved. 27*0Sstevel@tonic-gate# Use is subject to license terms. 28*0Sstevel@tonic-gate# 29*0Sstevel@tonic-gate# ctfcvtptbl [-o outfile] patch-makeup-table 30*0Sstevel@tonic-gate# 31*0Sstevel@tonic-gate# Given a path to a patch makeup table, this script converts that table to 32*0Sstevel@tonic-gate# machine-optimal format and deposits it in the file specified by the -o option 33*0Sstevel@tonic-gate# or on stdout depending on whether or not -o is specified. 34*0Sstevel@tonic-gate# 35*0Sstevel@tonic-gate# The user-supplied patch makeup table is in the following format: 36*0Sstevel@tonic-gate# 37*0Sstevel@tonic-gate# # 38*0Sstevel@tonic-gate# # comment 39*0Sstevel@tonic-gate# # 40*0Sstevel@tonic-gate# 41*0Sstevel@tonic-gate# genunix_archive=/path/to/genunix/archive 42*0Sstevel@tonic-gate# 43*0Sstevel@tonic-gate# patch 100001-01 kureq 100002-01 44*0Sstevel@tonic-gate# usr/src/uts/sparc/sd/debug32/sd 45*0Sstevel@tonic-gate# module2 46*0Sstevel@tonic-gate# 47*0Sstevel@tonic-gate# patch 100003-08 48*0Sstevel@tonic-gate# module3 49*0Sstevel@tonic-gate# 50*0Sstevel@tonic-gate# The machine-optimal format for the above looks like this: 51*0Sstevel@tonic-gate# 52*0Sstevel@tonic-gate# GENUNIX_ARCHIVE=/path/to/genunix/archive 53*0Sstevel@tonic-gate# module1 100001-01 100002-01 54*0Sstevel@tonic-gate# module2 100001-01 100002-01 55*0Sstevel@tonic-gate# module3 100003-08 56*0Sstevel@tonic-gate# 57*0Sstevel@tonic-gate# 58*0Sstevel@tonic-gate# Macros and other time-savers: 59*0Sstevel@tonic-gate# 60*0Sstevel@tonic-gate# * $RELEASE and $MACH in the genunix archive path will be replaced by the 61*0Sstevel@tonic-gate# values of the RELEASE and MACH environment variables, respectively, as 62*0Sstevel@tonic-gate# set by the program calling this one. 63*0Sstevel@tonic-gate# 64*0Sstevel@tonic-gate# * BUILD, BUILD32, and BUILD64 will, when used in the path for the module, 65*0Sstevel@tonic-gate# will be match as follows: 66*0Sstevel@tonic-gate# 67*0Sstevel@tonic-gate# BUILD debug32, debug64, obj32, obj64 68*0Sstevel@tonic-gate# BUILD32 debug32, obj32 69*0Sstevel@tonic-gate# BUILD64 debug64, obj64 70*0Sstevel@tonic-gate# 71*0Sstevel@tonic-gate# * The presence of `usr/src' at the beginning of each module path will be 72*0Sstevel@tonic-gate# assumed, and is not required to be specified. 73*0Sstevel@tonic-gate# 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gateuse strict; 76*0Sstevel@tonic-gateuse Getopt::Std; 77*0Sstevel@tonic-gateuse File::Basename; 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gatemy $PROGNAME = basename($0); 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gatemy $genunix_archive; 82*0Sstevel@tonic-gatemy %moddata; 83*0Sstevel@tonic-gatemy %typehash = ( 84*0Sstevel@tonic-gate BUILD => [ "debug32", "debug64", "obj32", "obj64" ], 85*0Sstevel@tonic-gate BUILD32 => [ "debug32", "obj32" ], 86*0Sstevel@tonic-gate BUILD64 => [ "debug64", "obj64" ] 87*0Sstevel@tonic-gate); 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gatemy %opts; 90*0Sstevel@tonic-gatemy $err = 0; 91*0Sstevel@tonic-gate$err = 1 unless getopts("ho:", \%opts); 92*0Sstevel@tonic-gateif ($opts{"o"}) { 93*0Sstevel@tonic-gate close(STDOUT); 94*0Sstevel@tonic-gate open(STDOUT, ">" . $opts{"o"}) || do { 95*0Sstevel@tonic-gate print STDERR "Couldn't open " . $opts{"o"} . ": $!\n"; 96*0Sstevel@tonic-gate exit(1); 97*0Sstevel@tonic-gate } 98*0Sstevel@tonic-gate} 99*0Sstevel@tonic-gateif ($opts{"h"}) { 100*0Sstevel@tonic-gate &usage; 101*0Sstevel@tonic-gate exit(2); 102*0Sstevel@tonic-gate} 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gateif (@ARGV != 1) { 105*0Sstevel@tonic-gate $err = 1; 106*0Sstevel@tonic-gate} 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gateif ($err) { 109*0Sstevel@tonic-gate &usage; 110*0Sstevel@tonic-gate exit(2); 111*0Sstevel@tonic-gate} 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate$::table = $ARGV[0]; 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gateif (!open(TABLE, "<$::table")) { 116*0Sstevel@tonic-gate print STDERR "Couldn't open $::table: $!\n"; 117*0Sstevel@tonic-gate exit(1); 118*0Sstevel@tonic-gate} 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gateif (!&read_table) { 121*0Sstevel@tonic-gate exit(1); 122*0Sstevel@tonic-gate} 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate&sub_vars; 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate&dump_table; 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gateexit(0); 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gatesub usage { 131*0Sstevel@tonic-gate print STDERR "Usage: $PROGNAME [-o outfile] table\n"; 132*0Sstevel@tonic-gate} 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gatesub read_table { 135*0Sstevel@tonic-gate my $patchid = ""; 136*0Sstevel@tonic-gate my $kureq = ""; 137*0Sstevel@tonic-gate my $kuprev = ""; 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate $genunix_archive = ""; 140*0Sstevel@tonic-gate undef %moddata; 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate while (<TABLE>) { 143*0Sstevel@tonic-gate chop; 144*0Sstevel@tonic-gate s/\#.*$//; # Strip comments 145*0Sstevel@tonic-gate s/^\s+//; 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate if (!$patchid && /^genunix_archive=(\S+)\s*$/) { 148*0Sstevel@tonic-gate $genunix_archive = $1; 149*0Sstevel@tonic-gate next; 150*0Sstevel@tonic-gate } 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gate while ($_) { 153*0Sstevel@tonic-gate if (s/^patch\s+(\d{6}-\d{2}) 154*0Sstevel@tonic-gate (\s+ku(req|prev)\s+(\d{6}-\d{2}|fcs))?//x && 155*0Sstevel@tonic-gate (!$_ || /^\s/)) { 156*0Sstevel@tonic-gate $patchid = $1; 157*0Sstevel@tonic-gate $kureq = (defined $4 ? $4 : "fcs"); 158*0Sstevel@tonic-gate $kuprev = (defined $3 && $3 eq "prev" ? 1 : 0); 159*0Sstevel@tonic-gate } elsif ($patchid && s/^(\S+)//) { 160*0Sstevel@tonic-gate my $module = $1; 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate if (($module =~ m:/genunix/:) && !$kuprev) { 163*0Sstevel@tonic-gate &parseerror("No kuprev supplied " . 164*0Sstevel@tonic-gate "for entry including genunix"); 165*0Sstevel@tonic-gate } 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate if (($module !~ m:^usr/src/:)) { 168*0Sstevel@tonic-gate $module = "usr/src/" . $module; 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate if (($module =~ 172*0Sstevel@tonic-gate m:^(.*)\$(BUILD|BUILD32|BUILD64)(/.*)$:)) { 173*0Sstevel@tonic-gate foreach my $type (@{$typehash{$2}}) { 174*0Sstevel@tonic-gate $moddata{$1 . $type . $3} = 175*0Sstevel@tonic-gate [$patchid, $kureq]; 176*0Sstevel@tonic-gate } 177*0Sstevel@tonic-gate } else { 178*0Sstevel@tonic-gate $moddata{$module} = [$patchid, $kureq]; 179*0Sstevel@tonic-gate } 180*0Sstevel@tonic-gate } else { 181*0Sstevel@tonic-gate &parseerror("Cannot parse table"); 182*0Sstevel@tonic-gate } 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate s/^\s+//; 185*0Sstevel@tonic-gate } 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate if (!$genunix_archive) { 189*0Sstevel@tonic-gate print STDERR "No genunix_archive line in table\n"; 190*0Sstevel@tonic-gate return (0); 191*0Sstevel@tonic-gate } 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate if (!%moddata) { 194*0Sstevel@tonic-gate print STDERR "No module information read\n"; 195*0Sstevel@tonic-gate return (0); 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate return (1); 199*0Sstevel@tonic-gate} 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gatesub parseerror { 202*0Sstevel@tonic-gate my $msg = $_[0]; 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate print STDERR "$msg at line $.\n"; 205*0Sstevel@tonic-gate exit(1); 206*0Sstevel@tonic-gate} 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gatesub sub_vars { 209*0Sstevel@tonic-gate my $release = $ENV{"RELEASE"}; 210*0Sstevel@tonic-gate my $mach = $ENV{"MACH"}; 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate $genunix_archive =~ s/\$RELEASE/$release/ if defined $release; 213*0Sstevel@tonic-gate $genunix_archive =~ s/\$MACH/$mach/ if defined $mach; 214*0Sstevel@tonic-gate} 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gatesub dump_table { 217*0Sstevel@tonic-gate print "GENUNIX_ARCHIVE=" . $genunix_archive . "\n"; 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate foreach my $mod (sort keys %moddata) { 220*0Sstevel@tonic-gate print join(" ", ($mod, @{$moddata{$mod}})) . "\n"; 221*0Sstevel@tonic-gate } 222*0Sstevel@tonic-gate} 223