diff options
author | esaxe <none@none> | 2006-08-11 18:11:49 -0700 |
---|---|---|
committer | esaxe <none@none> | 2006-08-11 18:11:49 -0700 |
commit | 96ccc8cb05e8790fcc24931dcb155b76e810295c (patch) | |
tree | 56aca851486d7a2dd9066999fe275e83bcfc5891 | |
parent | 5988135d82ecba94b97669a9f2b7016b58ad691e (diff) | |
download | illumos-joyent-96ccc8cb05e8790fcc24931dcb155b76e810295c.tar.gz |
5016095 nightly should help determine what really changes from build to build
6404876 uses of __DATE__ / __TIME__ should be purged from ON
6404908 ON builds should employ a static globalization prefix
-rw-r--r-- | usr/src/Makefile.master | 17 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.bin/pppd/patchlevel.h | 13 | ||||
-rw-r--r-- | usr/src/cmd/fm/eversholt/common/eftwrite.c | 30 | ||||
-rw-r--r-- | usr/src/cmd/lp/cmd/lpsched/Makefile | 17 | ||||
-rw-r--r-- | usr/src/cmd/lp/cmd/lpsched/lpsched.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/mailx/Makefile | 23 | ||||
-rw-r--r-- | usr/src/cmd/mailx/main.c | 9 | ||||
-rw-r--r-- | usr/src/tools/Makefile.targ | 14 | ||||
-rw-r--r-- | usr/src/tools/Makefile.tools | 1 | ||||
-rw-r--r-- | usr/src/tools/README.tools | 7 | ||||
-rw-r--r-- | usr/src/tools/SUNWonbld/prototype_com | 2 | ||||
-rw-r--r-- | usr/src/tools/scripts/Makefile | 10 | ||||
-rw-r--r-- | usr/src/tools/scripts/nightly.1 | 10 | ||||
-rw-r--r-- | usr/src/tools/scripts/nightly.sh | 38 | ||||
-rw-r--r-- | usr/src/tools/scripts/wsdiff.1 | 178 | ||||
-rwxr-xr-x | usr/src/tools/scripts/wsdiff.py | 1216 | ||||
-rw-r--r-- | usr/src/uts/Makefile.uts | 1 | ||||
-rw-r--r-- | usr/src/uts/sparc/Makefile.sparc.shared | 1 | ||||
-rw-r--r-- | usr/src/uts/sun4u/Makefile.sun4u.shared | 1 | ||||
-rw-r--r-- | usr/src/uts/sun4u/starcat/io/dman.c | 1 | ||||
-rw-r--r-- | usr/src/uts/sun4v/Makefile.sun4v.shared | 1 |
21 files changed, 1507 insertions, 85 deletions
diff --git a/usr/src/Makefile.master b/usr/src/Makefile.master index 7518009d63..a9d5860eb9 100644 --- a/usr/src/Makefile.master +++ b/usr/src/Makefile.master @@ -383,6 +383,14 @@ COPTFLAG64= $($(MACH64)_COPTFLAG) # (gives them a unique prefix). Disable that. CNOGLOBAL= -W0,-noglobal +# Direct the Sun Studio compiler to use a static globalization prefix based on the +# name of the module rather than something unique. Otherwise, objects +# will not build deterministically, as subsequent compilations of identical +# source will yeild objects that always look different. +# +# In the same spirit, this will also remove the date from the N_OPT stab. +CGLOBALSTATIC= -W0,-xglobalstatic + # Normally, gcc uses indirect DWARF strings to save space. However, # this causes relocations that ctfconvert cannot handle. Disable this. CDWARFSTR= -_gcc=-fno-dwarf2-indirect-strings @@ -451,11 +459,14 @@ XREGSFLAG = $($(MACH)_XREGSFLAG) XREGSFLAG64 = $($(MACH64)_XREGSFLAG) CFLAGS= $(COPTFLAG) $($(MACH)_CFLAGS) $(SPACEFLAG) $(CCMODE) \ - $(ILDOFF) $(CERRWARN) $(C99MODE) $(CCUNBOUND) $(IROPTFLAG) + $(ILDOFF) $(CERRWARN) $(C99MODE) $(CCUNBOUND) $(IROPTFLAG) \ + $(CGLOBALSTATIC) CFLAGS64= $(COPTFLAG64) $($(MACH64)_CFLAGS) $(SPACEFLAG64) $(CCMODE64) \ - $(ILDOFF) $(CERRWARN) $(C99MODE) $(CCUNBOUND) $(IROPTFLAG64) + $(ILDOFF) $(CERRWARN) $(C99MODE) $(CCUNBOUND) $(IROPTFLAG64) \ + $(CGLOBALSTATIC) NATIVE_CFLAGS= $(COPTFLAG) $($(NATIVE_MACH)_CFLAGS) $(CCMODE) \ - $(ILDOFF) $(CERRWARN) $(C99MODE) $($(NATIVE_MACH)_CCUNBOUND) + $(ILDOFF) $(CERRWARN) $(C99MODE) $($(NATIVE_MACH)_CCUNBOUND) \ + $(CGLOBALSTATIC) DTEXTDOM=-DTEXT_DOMAIN=\"$(TEXT_DOMAIN)\" # For messaging. DTS_ERRNO=-D_TS_ERRNO diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/patchlevel.h b/usr/src/cmd/cmd-inet/usr.bin/pppd/patchlevel.h index 840a4dfd9c..7e01d94206 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/patchlevel.h +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/patchlevel.h @@ -1,12 +1,11 @@ /* - * Copyright (c) 2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ - #pragma ident "%Z%%M% %I% %E% SMI" #ifndef _PATCH_LEVEL_H -#define _PATCH_LEVEL_H +#define _PATCH_LEVEL_H #ifdef __cplusplus extern "C" { @@ -14,13 +13,11 @@ extern "C" { #define PATCHLEVEL 0 -#define VERSION "2.4" -#define IMPLEMENTATION \ - "b1 (Sun Microsystems, Inc., " __DATE__ " " __TIME__ ")" +#define VERSION "2.4" +#define IMPLEMENTATION "b1 (Sun Microsystems, Inc.)" #ifdef __cplusplus } #endif #endif /* _PATCH_LEVEL_H */ - diff --git a/usr/src/cmd/fm/eversholt/common/eftwrite.c b/usr/src/cmd/fm/eversholt/common/eftwrite.c index 5c7e733978..b768b1c8c6 100644 --- a/usr/src/cmd/fm/eversholt/common/eftwrite.c +++ b/usr/src/cmd/fm/eversholt/common/eftwrite.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * eftwrite.c -- routines for writing .eft files @@ -35,7 +34,6 @@ #include <stdio.h> #include <string.h> #include <strings.h> -#include <time.h> #include <unistd.h> #include <errno.h> #include "out.h" @@ -67,19 +65,6 @@ eftwrite_init(void) Outbytes = stats_new_counter("eftwrite.total", "bytes written", 1); } -static const char * -mygetlogin(void) -{ - const char *result = getlogin(); - static char id[100]; - - if (result != NULL) - return (result); - - (void) snprintf(id, 100, "uid:%ld", getuid()); - return (id); -} - /*ARGSUSED*/ static void ident_lencalc(const char *s, void *rhs, void *arg) @@ -121,7 +106,6 @@ eftwrite(const char *fname) #define BUFLEN 8192 char buf[BUFLEN]; int cc; - time_t clock; if ((tfp = tmpfile()) == NULL) out(O_DIE|O_SYS, "cannot create temporary file"); @@ -144,14 +128,10 @@ eftwrite(const char *fname) hdr.cminor = VERSION_MINOR; hdr.identlen = Identlen; hdr.dictlen = Dictlen; - (void) time(&clock); - if (gethostname(buf, BUFLEN) < 0) - out(O_DIE|O_SYS, "gethostname"); buf[BUFLEN - 1] = '\0'; (void) snprintf(hdr.comment, EFT_HDR_MAXCOMMENT, - "Built using esc-%d.%d by %s on %s at %s\tArgs: \"%s\"\n", - VERSION_MAJOR, VERSION_MINOR, mygetlogin(), buf, ctime(&clock), - Args); + "Built using esc-%d.%d\tArgs: \"%s\"\n", VERSION_MAJOR, + VERSION_MINOR, Args); if ((fp = fopen(fname, "w")) == NULL) out(O_DIE|O_SYS, "can't open output file: %s", fname); diff --git a/usr/src/cmd/lp/cmd/lpsched/Makefile b/usr/src/cmd/lp/cmd/lpsched/Makefile index 3d03c42a79..2afbf2377c 100644 --- a/usr/src/cmd/lp/cmd/lpsched/Makefile +++ b/usr/src/cmd/lp/cmd/lpsched/Makefile @@ -108,28 +108,16 @@ SYSLIBS= -lcurses -lgen -lcurses -lnsl -z lazyload \ LDLIBS += $(LPLIBS) $(SYSLIBS) -LPSCHED_VERSION_STRING = ($(ECHO) build info: \\\c; date +%D:%H:%M:%S) - POFILE= lp_cmd_lpsched.po .KEEP_STATE: all: $(PROG) -$(PROG): $(OBJS) $(LPLIBS) lpschedvers.o - $(LINK.c) $(OBJS) lpschedvers.o -o $@ $(LDLIBS) +$(PROG): $(OBJS) $(LPLIBS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) -lpschedvers.c: FRC - @-$(ECHO) "rebuilding lpschedvers.c" - @-( \ - $(ECHO) "/*" ; \ - $(ECHO) " * This file is derived from cmd/lpsched/lpsched/Makefile" ; \ - $(ECHO) " */\n" ; \ - $(ECHO) "#pragma\tident\t\"@(#)lpschedvers.c\tDERIVED\t96/2/1 SMI\"\n" ; \ - $(ECHO) "char *lpsched_buildinfo = \"`$(LPSCHED_VERSION_STRING)`\\\\n\";" ; \ - $(ECHO) "" ) > ./lpschedvers.c - $(PROG).pure: $(OBJS) $(LPLIBS) $(PURIFY) $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) @@ -142,7 +130,6 @@ check: $(CHKMANIFEST) clean: $(RM) $(OBJS) - $(RM) lpschedvers.c lpschedvers.o clobber: clean -$(RM) $(PROG) $(CLOBBERFILES) diff --git a/usr/src/cmd/lp/cmd/lpsched/lpsched.c b/usr/src/cmd/lp/cmd/lpsched/lpsched.c index 82d9a80204..2cbb82730e 100644 --- a/usr/src/cmd/lp/cmd/lpsched/lpsched.c +++ b/usr/src/cmd/lp/cmd/lpsched/lpsched.c @@ -67,7 +67,6 @@ static int signals = 0; #endif extern int errno; -extern char *lpsched_buildinfo; extern void shutdown_messages(); int am_in_background = 0; @@ -282,7 +281,6 @@ startup() init_memory(); - note (lpsched_buildinfo); note ("Print services started.\n"); Starting = 0; } diff --git a/usr/src/cmd/mailx/Makefile b/usr/src/cmd/mailx/Makefile index 3f74d721a1..858850236e 100644 --- a/usr/src/cmd/mailx/Makefile +++ b/usr/src/cmd/mailx/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -39,9 +38,6 @@ OBJS= myfopen.o aux.o cmd1.o cmd2.o cmd3.o \ SRCS= $(OBJS:.o=.c) -VEROBJ= version.o -VERSRC= $(VEROBJ:.o=.c) -MAILXVERSION= 5.0 MISC= misc include ../Makefile.cmd @@ -83,17 +79,10 @@ $(ROOTETCMAILD)/% : $(MISC)/% all: $(PROG) $(MAILXHELP) $(MAILXRC) $(UCBMAILRC) -$(PROG): $(OBJS) $(VEROBJ) $(LIBMAIL) - $(LINK.c) $(OBJS) $(VEROBJ) -o $@ $(LDLIBS) +$(PROG): $(OBJS) $(LIBMAIL) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) -$(VEROBJ): $(VERSRC) - $(COMPILE.c) $(VERSRC) - -# want to recreate version.c whenever (and only when) mailx needs to be rebuilt -$(VERSRC): $(OBJS) $(LIBMAIL) - $(ECHO) "const char *const version=\"mailx version $(MAILXVERSION) `date`\";" > $@ - install: all $(ROOTMAILXD) $(ROOTPROG) $(ROOTMAILXHELP) \ $(ROOTMAILXRC) $(ROOTUCBMAIL) $(ROOTUCBCAPMAIL) $(ROOTUCBMAILRC) @@ -111,7 +100,7 @@ $(POFILE): $(POFILES) cat $(POFILES) > $@ clean: - $(RM) $(OBJS) $(VEROBJS) version.c + $(RM) $(OBJS) lint: lint_SRCS diff --git a/usr/src/cmd/mailx/main.c b/usr/src/cmd/mailx/main.c index 350b81b0b2..35448ecf7c 100644 --- a/usr/src/cmd/mailx/main.c +++ b/usr/src/cmd/mailx/main.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 1998 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -56,6 +55,8 @@ static void hdrstop(int); static jmp_buf hdrjmp; +const char *const version = "mailx version 5.0"; + /* * Find out who the user is, copy his mail file (if exists) into * /tmp/Rxxxxx and set up the message pointers. Then, print out the diff --git a/usr/src/tools/Makefile.targ b/usr/src/tools/Makefile.targ index b3071a2212..b5f60df69f 100644 --- a/usr/src/tools/Makefile.targ +++ b/usr/src/tools/Makefile.targ @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,8 +21,8 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1998,2001 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # common target definitions for tool builds @@ -40,3 +39,8 @@ lint_SRCS: $(RM) $@ cat $< > $@ chmod +x $@ + +%: %.py + $(RM) $@ + cat $< > $@ + chmod +x $@ diff --git a/usr/src/tools/Makefile.tools b/usr/src/tools/Makefile.tools index 285f90c561..3dd154695f 100644 --- a/usr/src/tools/Makefile.tools +++ b/usr/src/tools/Makefile.tools @@ -62,6 +62,7 @@ ROOTONBLDMACHBINARIES= $(BINARIES:%=$(ROOTONBLDBINMACH)/%) ROOTONBLDENVFILES= $(ENVFILES:%=$(ROOTONBLDENV)/%) ROOTONBLDGKFILES= $(GKFILES:%=$(ROOTONBLDGK)/.%) ROOTONBLDPERLFILES= $(PERLFILES:%=$(ROOTONBLDBIN)/%) +ROOTONBLDPYFILES= $(PYFILES:%=$(ROOTONBLDBIN)/%) ROOTONBLDMAN1FILES= $(MAN1FILES:%=$(ROOTONBLDMAN1)/%) ROOTONBLDABIAUDITFILES= $(ABI_AUDITFILES:%=$(ROOTONBLDETCABI)/%) diff --git a/usr/src/tools/README.tools b/usr/src/tools/README.tools index 38c2fc9876..49c24ce066 100644 --- a/usr/src/tools/README.tools +++ b/usr/src/tools/README.tools @@ -258,6 +258,13 @@ webrev manually-generated list; knows how to use wx's active file for lists of checked-out files and proposed SCCS comments. +wsdiff + Detect object differences between two ON proto areas. Used by + nightly(1) to determine what changed between two builds. Handy + for identifying the set of built objects impacted by a given + source change. This information is needed for patch construction. + + How to do a full build ---------------------- diff --git a/usr/src/tools/SUNWonbld/prototype_com b/usr/src/tools/SUNWonbld/prototype_com index 8de73ead48..715825ca77 100644 --- a/usr/src/tools/SUNWonbld/prototype_com +++ b/usr/src/tools/SUNWonbld/prototype_com @@ -91,6 +91,7 @@ f none opt/onbld/bin/validate_paths 555 root bin f none opt/onbld/bin/wdiff 555 root bin f none opt/onbld/bin/webrev 555 root bin f none opt/onbld/bin/ws 555 root bin +f none opt/onbld/bin/wsdiff 555 root bin f none opt/onbld/bin/wx 555 root bin f none opt/onbld/bin/xref 555 root bin f none opt/onbld/bin/xref.mk 644 root bin @@ -131,5 +132,6 @@ f none opt/onbld/man/man1/sccsmv.1 644 root bin f none opt/onbld/man/man1/sccsrm.1 644 root bin f none opt/onbld/man/man1/webrev.1 644 root bin f none opt/onbld/man/man1/ws.1 644 root bin +f none opt/onbld/man/man1/wsdiff.1 644 root bin f none opt/onbld/man/man1/wx.1 644 root bin f none opt/onbld/man/man1/xref.1 644 root bin diff --git a/usr/src/tools/scripts/Makefile b/usr/src/tools/scripts/Makefile index fc1318b501..e9870ceb5a 100644 --- a/usr/src/tools/scripts/Makefile +++ b/usr/src/tools/scripts/Makefile @@ -65,6 +65,9 @@ PERLFILES= \ validate_paths \ wdiff +PYFILES= \ + wsdiff + MAN1FILES= \ Install.1 \ acr.1 \ @@ -84,13 +87,14 @@ MAN1FILES= \ sccsrm.1 \ webrev.1 \ ws.1 \ + wsdiff.1 \ wx.1 \ xref.1 MAKEFILES= \ xref.mk -CLEANFILES = $(SHFILES) $(PERLFILES) cddlchk.1 +CLEANFILES = $(SHFILES) $(PERLFILES) $(PYFILES) cddlchk.1 include ../Makefile.tools @@ -101,10 +105,10 @@ $(ROOTONBLDMAKEFILES) := FILEMODE= 644 .KEEP_STATE: -all: $(SHFILES) $(PERLFILES) $(MAN1FILES) $(MAKEFILES) +all: $(SHFILES) $(PERLFILES) $(PYFILES) $(MAN1FILES) $(MAKEFILES) install: all .WAIT $(ROOTONBLDSHFILES) $(ROOTONBLDPERLFILES) \ - $(ROOTONBLDMAN1FILES) $(ROOTONBLDMAKEFILES) + $(ROOTONBLDPYFILES) $(ROOTONBLDMAN1FILES) $(ROOTONBLDMAKEFILES) clean: $(RM) $(CLEANFILES) diff --git a/usr/src/tools/scripts/nightly.1 b/usr/src/tools/scripts/nightly.1 index 03a0479acd..9d99d486d4 100644 --- a/usr/src/tools/scripts/nightly.1 +++ b/usr/src/tools/scripts/nightly.1 @@ -75,6 +75,8 @@ check the ELF runtime attributes of all dynamic objects .TP check for unreferenced files .TP +report on which proto area objects have changed (since the last build) +.TP report the total build time .TP save a detailed log file for reference @@ -180,7 +182,13 @@ recommended, especially in conjunction with the \-p option) .TP .B \-W Do not report warnings (for freeware gate ONLY) - +.TP +.B \-w +Report which proto area objects differ between this and the last build. +See wsdiff(1) for details. Note that the proto areas used for comparison +are the last ones constructed as part of the build. As an example, if both +a non-debug and debug build are performed (in that order), then the debug +proto area will be used for comparison (which might not be what you want). .LP .B Groups of options .TP 10 diff --git a/usr/src/tools/scripts/nightly.sh b/usr/src/tools/scripts/nightly.sh index 92b295e6bc..63a3320e35 100644 --- a/usr/src/tools/scripts/nightly.sh +++ b/usr/src/tools/scripts/nightly.sh @@ -832,6 +832,7 @@ NIGHTLY_OPTIONS variable in the <env_file> as follows: -t build and use the tools in $SRC/tools -u update proto_list_$MACH and friends in the parent workspace; when used with -f, also build an unrefmaster.out in the parent + -w report on differences between previous and current proto areas -z compress cpio archives with gzip -W Do not report warnings (freeware gate ONLY) -S Build a variant of the source product @@ -870,6 +871,7 @@ V_FLAG=n M_FLAG=n N_FLAG=n z_FLAG=n +w_FLAG=n W_FLAG=n SE_FLAG=n SD_FLAG=n @@ -1040,7 +1042,7 @@ check_closed_tree # NIGHTLY_OPTIONS=-${NIGHTLY_OPTIONS#-} OPTIND=1 -while getopts ABDFNMPTCGIRafinlmoptuUxdrtzWS:X FLAG $NIGHTLY_OPTIONS +while getopts ABDFNMPTCGIRafinlmoptuUxdrtwzWS:X FLAG $NIGHTLY_OPTIONS do case $FLAG in A ) A_FLAG=y @@ -1094,6 +1096,8 @@ do ;; u ) u_FLAG=y ;; + w ) w_FLAG=y + ;; z ) z_FLAG=y ;; U ) @@ -1391,6 +1395,10 @@ logshuffle() { if [ "$build_ok" = "y" ]; then mv $ATLOG/proto_list_${MACH} $LLOG + + if [ -f $TMPDIR/wsdiff.results ]; then + mv $TMPDIR/wsdiff.results $LLOG + fi fi # @@ -1642,6 +1650,12 @@ if [ "$f_FLAG" = "y" ]; then fi fi +if [ "$w_FLAG" = "y" -a ! -d $ROOT ]; then + echo "WARNING: -w specified, but no pre-existing proto area found;" \ + "ignoring -w\n" | tee -a $mail_msg_file >> $LOGFILE + w_FLAG=n +fi + if [ "$t_FLAG" = "n" ]; then # # We're not doing a tools build, so make sure elfsign(1) is @@ -1749,6 +1763,14 @@ echo "\nBuild project: $build_project\nBuild taskid: $build_taskid" | \ echo "\n==== Build version ====\n" | tee -a $mail_msg_file >> $LOGFILE echo $VERSION | tee -a $mail_msg_file >> $LOGFILE +# Save the current proto area if we're comparing against the last build +if [ "$w_FLAG" = "y" -a -d "$ROOT" ]; then + if [ -d "$ROOT.prev" ]; then + rm -rf $ROOT.prev + fi + mv $ROOT $ROOT.prev +fi + # # Decide whether to clobber # @@ -1784,6 +1806,7 @@ if [ "$i_FLAG" = "n" -a -d "$SRC" ]; then rm -rf ${TOOLS_PROTO} mkdir -p ${TOOLS_PROTO} fi + rm -rf $ROOT # Get back to a clean workspace as much as possible to catch @@ -2229,6 +2252,19 @@ if [ "$M_FLAG" != "y" -a "$build_ok" = y ]; then done | sed -e 's:/pkginfo.tmpl$::' | sort -u ` >> $mail_msg_file fi +if [ "$w_FLAG" = "y" -a "$build_ok" = "y" ]; then + echo "\n==== Objects that differ since last build ====\n" | \ + tee -a $LOGFILE >> $mail_msg_file + + if [ "$t_FLAG" = "y" ]; then + wsdiff -t -r ${TMPDIR}/wsdiff.results $ROOT.prev $ROOT | \ + tee -a $LOGFILE >> $mail_msg_file + else + wsdiff -r ${TMPDIR}/wsdiff.results $ROOT.prev $ROOT | \ + tee -a $LOGFILE >> $mail_msg_file + fi +fi + END_DATE=`date` echo "==== Nightly $maketype build completed: $END_DATE ====" | \ tee -a $LOGFILE >> $build_time_file diff --git a/usr/src/tools/scripts/wsdiff.1 b/usr/src/tools/scripts/wsdiff.1 new file mode 100644 index 0000000000..a4f4e5e0d5 --- /dev/null +++ b/usr/src/tools/scripts/wsdiff.1 @@ -0,0 +1,178 @@ +.\" ident "%Z%%M% %I% %E% SMI" +.\" " CDDL HEADER START +.\" " +.\" " The contents of this file are subject to the terms of the +.\" " Common Development and Distribution License (the "License"). +.\" " You may not use this file except in compliance with the License. +.\" " +.\" " You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +.\" " or http://www.opensolaris.org/os/licensing. +.\" " See the License for the specific language governing permissions +.\" " and limitations under the License. +.\" " +.\" " When distributing Covered Code, include this CDDL HEADER in each +.\" " file and include the License file at usr/src/OPENSOLARIS.LICENSE. +.\" " If applicable, add the following below this CDDL HEADER, with the +.\" " fields enclosed by brackets "[]" replaced with your own identifying +.\" " information: Portions Copyright [yyyy] [name of copyright owner] +.\" " +.\" " CDDL HEADER END +.\" " +.\" "Copyright 2006 Sun Microsystems, Inc. All rights reserved. +.\" "Use is subject to license terms." +.TH wsdiff 1 "07 Jul 2006" +.I wsdiff +\- report differences between proto area objects +.SH SYNOPSIS +\fBwsdiff [-vVt] [-r \fIresults\fP] [-i \fIfilelist\fP] \fIold\fP \fInew\fP +.LP +.SH DESCRIPTION +.IX "OS-Net build tools" "wsdiff" "" "\fBwsdiff\fP" +.LP +The wsdiff utility detects and reports on object differences found between +two proto areas constructed from the same workspace. This can be useful +when trying to understand which objects have changed as a result of a particular +source change. +.LP +\fIold\fP specifies the baseline proto area constructed without the source +change. \fInew\fP specifies the proto area constructed with the source +change. Both \fIold\fP and \fInew\fP should be constructed from the same +workspace, otherwise wsdiff will find object differences not associated +with the source change. +.SH OPTIONS +.TP 10 +.B -v +Do not truncate the diffs logged to the results file. By default wsdiff +will truncate the length of a sufficiently long set of object diffs to preserve +the readability of the results file. -v can be used to override this behaviour. +.TP 10 +.B -V +Log observed differences for all ELF sections, rather than logging only the first +difference found. When wsdiff encounters an ELF section difference, by default +it will log the difference associated with that section only, and move on. -V forces +wsdiff to log all ELF section differences found between two objects, rather than +just the first. Because of the extra work involved, this may slow wsdiff down +considerably. +.TP 10 +.B -t +Look for the onbld tools in $SRC/tools rather than /opt/onbld/bin +.TP 10 +.B -r +Log results to the specified log file. The log file contains a list of new, deleted, +and changed objects, as well as diffs signifying what wsdiff found to be different. +.TP 10 +.B -i +Specify which objects should be compared by wsdiff via an input file list (See +EXAMPLES). +.LP +.SH OUTPUT +.LP +The list of objects appearing to differ between \fIold\fP and \fInew\fP is +printed to stdout. If -r was specified, the list of differing objects and +their differrences are logged to \fIresults\fP. +.LP +.SH EXAMPLES +.PP +\fBExample 1: Using wsdiff to determine patch deliverables\fR +.PP +The following example shows how to use wsdiff to determine the set of objects +requiring (re)delivery via patch as a result of a given source change: +.LP +Starting with a built workspace, move the existing proto area aside: +.LP +.nf +user@example$ ls +Codemgr_wsdata/ proto/ usr/ + +user@example$ mv proto proto.old +.fi +.LP +Next, integrate the source changes, rebuild, and invoke wsdiff specifying the +old and new proto areas: +.LP +.nf +user@example$ ls +Codemgr_wsdata/ proto/ proto.old/ usr/ + +user@example$ wsdiff proto.old proto +platform/SUNW,SPARC-Enterprise/kernel/sparcv9/unix +platform/SUNW,Sun-Fire-15000/kernel/sparcv9/unix +platform/sun4v/kernel/sparcv9/unix +platform/sun4u/kernel/sparcv9/unix +platform/SUNW,Ultra-Enterprise-10000/kernel/sparcv9/unix +platform/SUNW,Sun-Fire/kernel/sparcv9/unix +.fi +.PP +\fBExample 2: The wsdiff results file\fR +.PP +With the -r option, wsdiff will log the list of objects that appear different, as well +as a set of diffs highlighting the observed difference: +.LP +.nf +user@example$ wsdiff -r results proto.old proto +platform/SUNW,SPARC-Enterprise/kernel/sparcv9/unix +platform/SUNW,Sun-Fire-15000/kernel/sparcv9/unix +platform/sun4v/kernel/sparcv9/unix +platform/sun4u/kernel/sparcv9/unix +platform/SUNW,Ultra-Enterprise-10000/kernel/sparcv9/unix +platform/SUNW,Sun-Fire/kernel/sparcv9/unix + +user@example$ cat results +# This file was produced by wsdiff +# 2006/7/10 at 18:28:56 +Base proto area: proto.old/ +Patch (new) proto area: proto/ +Results file: results + +platform/SUNW,SPARC-Enterprise/kernel/sparcv9/unix +NOTE: ELF .text difference detected. + +89562,89567c89562,89567 +< lgrp_cpu_init+0x158: 9e 10 20 01 mov 0x1, %o7 +< lgrp_cpu_init+0x15c: b3 2b d0 1c sllx %o7, %i4, %i1 +< lgrp_cpu_init+0x160: 9a 12 40 19 or %o1, %i1, %o5 +< lgrp_cpu_init+0x164: da 76 a0 30 stx %o5, [%i2 + 0x30] +< lgrp_cpu_init+0x168: d8 04 e0 00 ld [%l3], %o4 +< lgrp_cpu_init+0x16c: 80 a3 20 00 cmp %o4, 0x0 +--- +> lgrp_cpu_init+0x158: 9a 10 20 01 mov 0x1, %o5 +> lgrp_cpu_init+0x15c: b3 2b 50 1c sllx %o5, %i4, %i1 +> lgrp_cpu_init+0x160: 98 12 00 19 or %o0, %i1, %o4 +> lgrp_cpu_init+0x164: d8 76 a0 30 stx %o4, [%i2 + 0x30] +> lgrp_cpu_init+0x168: d6 04 e0 00 ld [%l3], %o3 +> lgrp_cpu_init+0x16c: 80 a2 e0 00 cmp %o3, 0x0 + +... + +.fi +.PP +\fBExample 3: Using an input file list\fR +.PP +The -i option tells wsdiff to compare a specific list of objects. This can be useful +in conjunction with other options that direct wsdiff to log more verbosely, allowing +one to "drill down" into a particular object's differences: +.LP +.nf +user@example$ echo "usr/lib/mdb/kvm/sparcv9/genunix.so" > flist +user@example$ wsdiff -vV -r results -i flist proto.old proto +usr/lib/mdb/kvm/sparcv9/genunix.so + +user@example$ cat results +<... verbose differences only for genunix.so ...> +.fi +.PP +\fBExample 4: Invoking wsdiff through nightly(1)\fR +.PP +By specifying -w in NIGHTLY_OPTIONS, nightly(1) will use wsdiff(1) to determine +which objects look different, compared to the previous build. A pre-existing proto area +must exist for wsdiff(1) to compare against. nightly(1) will move aside the +pre-existing proto area (renaming it to $ROOT.prev under proto), and will +invoke wsdiff at the end of the build. The list of changed objects will be reported +in the nightly mail message, and a results file "wsdiff_results" will appear in the +nightly log area. +.LP +.SH SEE ALSO +.LP +.IR lintdump(1), +.IR nightly(1), +.IR elfdump(1), diff --git a/usr/src/tools/scripts/wsdiff.py b/usr/src/tools/scripts/wsdiff.py new file mode 100755 index 0000000000..113365475d --- /dev/null +++ b/usr/src/tools/scripts/wsdiff.py @@ -0,0 +1,1216 @@ +#!/usr/sfw/bin/python +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +# +# wsdiff(1) is a tool that can be used to determine which compiled objects +# have changed as a result of a given source change. Developers backporting +# new features, RFEs and bug fixes need to be able to identify the set of +# patch deliverables necessary for feature/fix realization on a patched system. +# +# The tool works by comparing objects in two trees/proto areas (one build with, +# and without the source changes. +# +# Using wsdiff(1) is fairly simple: +# - Bringover to a fresh workspace +# - Perform a full non-debug build (clobber if workspace isn't fresh) +# - Move the proto area aside, call it proto.old, or something. +# - Integrate your changes to the workspace +# - Perform another full non-debug clobber build. +# - Use wsdiff(1) to see what changed: +# $ wsdiff proto.old proto +# +# By default, wsdiff will print the list of changed objects / deliverables to +# stdout. If a results file is specified via -r, the list of differing objects, +# and details about why wsdiff(1) thinks they are different will be logged to +# the results file. +# +# By invoking nightly(1) with the -w option to NIGHTLY_FLAGS, nightly(1) will use +# wsdiff(1) to report on what objects changed since the last build. +# +# For patch deliverable purposes, it's advised to have nightly do a clobber, +# non-debug build. +# +# Think about the results. Was something flagged that you don't expect? Go look +# at the results file to see details about the differences. +# +# Use the -i option in conjunction with -v and -V to dive deeper and have wsdiff(1) +# report with more verbosity. +# +# Usage: wsdiff [-vVt] [-r results ] [-i filelist ] old new +# +# Where "old" is the path to the proto area build without the changes, and +# "new" is the path to the proto area built with the changes. The following +# options are supported: +# +# -v Do not truncate observed diffs in results +# -V Log *all* ELF sect diffs vs. logging the first diff found +# -t Use onbld tools in $SRC/tools +# -r Log results and observed differences +# -i Tell wsdiff which objects to compare via an input file list + +import datetime, fnmatch, getopt, profile, os, popen2, commands +import re, select, string, struct, sys, tempfile, time +from stat import * + +# Human readable diffs truncated by default if longer than this +# Specifying -v on the command line will override +diffs_sz_thresh = 4096 + +# Default search path for wsdiff +wsdiff_path = [ "/usr/bin", + "/usr/ccs/bin", + "/lib/svc/bin", + "/opt/onbld/bin" ] + +# These are objects that wsdiff will notice look different, but will not report. +# Existence of an exceptions list, and adding things here is *dangerous*, +# and therefore the *only* reasons why anything would be listed here is because +# the objects do not build deterministically, yet we *cannot* fix this. +# +# These perl libraries use __DATE__ and therefore always look different. +# Ideally, we would purge use the use of __DATE__ from the source, but because +# this is source we wish to distribute with Solaris "unchanged", we cannot modify. +# +wsdiff_exceptions = [ "usr/perl5/5.8.4/lib/sun4-solaris-64int/CORE/libperl.so.1", + "usr/perl5/5.6.1/lib/sun4-solaris-64int/CORE/libperl.so.1", + "usr/perl5/5.8.4/lib/i86pc-solaris-64int/CORE/libperl.so.1", + "usr/perl5/5.6.1/lib/i86pc-solaris-64int/CORE/libperl.so.1" + ] + +##### +# Logging routines +# + +# Informational message to be printed to the screen, and the log file +def info(msg) : + + print >> sys.stdout, msg + if logging : + print >> log, msg + sys.stdout.flush() + +# Error message to be printed to the screen, and the log file +def error(msg) : + + print >> sys.stderr, "ERROR:", msg + sys.stderr.flush() + if logging : + print >> log, "ERROR:", msg + log.flush() + +# Informational message to be printed only to the log, if there is one. +def v_info(msg) : + + if logging : + print >> log, msg + log.flush() + +# +# Flag a detected file difference +# Display the fileName to stdout, and log the difference +# +def difference(f, dtype, diffs) : + + if f in wsdiff_exceptions : + return + + print >> sys.stdout, f + sys.stdout.flush() + + log_difference(f, dtype, diffs) + +# +# Do the actual logging of the difference to the results file +# +def log_difference(f, dtype, diffs) : + if logging : + print >> log, f + print >> log, "NOTE:", dtype, "difference detected." + + difflen = len(diffs) + if difflen > 0 : + print >> log + + if not vdiffs and difflen > diffs_sz_thresh : + print >> log, diffs[:diffs_sz_thresh] + print >> log, \ + "... truncated due to length: " \ + "use -v to override ..." + else : + print >> log, diffs + print >> log, "\n" + log.flush() + + +##### +# diff generating routines +# + +# +# Return human readable diffs from two temporary files +# +def diffFileData(tmpf1, tmpf2) : + + # Filter the data through od(1) if the data is detected + # as being binary + if isBinary(tmpf1) or isBinary(tmpf2) : + tmp_od1 = tmpf1 + ".od" + tmp_od2 = tmpf2 + ".od" + + cmd = od_cmd + " -c -t x4" + " " + tmpf1 + " > " + tmp_od1 + os.system(cmd) + cmd = od_cmd + " -c -t x4" + " " + tmpf2 + " > " + tmp_od2 + os.system(cmd) + + tmpf1 = tmp_od1 + tmpf2 = tmp_od2 + + data = commands.getoutput(diff_cmd + " " + tmpf1 + " " + tmpf2) + + return data + +# +# Return human readable diffs betweeen two datasets +# +def diffData(d1, d2) : + + global tmpFile1 + global tmpFile2 + + try: + fd1 = open(tmpFile1, "w") + except: + error("failed to open: " + tmpFile1) + cleanup(1) + try: + fd2 = open(tmpFile2, "w") + except: + error("failed to open: " + tmpFile2) + cleanup(1) + + fd1.write(d1) + fd2.write(d2) + fd1.close() + fd2.close() + + return diffFileData(tmpFile1, tmpFile2) + +##### +# Misc utility functions +# + +# Prune off the leading prefix from string s +def str_prefix_trunc(s, prefix) : + snipLen = len(prefix) + return s[snipLen:] + +# +# Prune off leading proto path goo (if there is one) to yield +# the deliverable's eventual path relative to root +# e.g. proto.base/root_sparc/usr/src/cmd/prstat => usr/src/cmd/prstat +# +def fnFormat(fn) : + root_arch_str = "root_" + arch + + pos = fn.find(root_arch_str) + if pos == -1 : + return fn + + pos = fn.find("/", pos) + if pos == -1 : + return fn + + return fn[pos + 1:] + +##### +# Usage / argument processing +# + +# +# Display usage message +# +def usage() : + sys.stdout.flush() + print >> sys.stderr, """Usage: wsdiff [-vVt] [-r results ] [-i filelist ] old new + -v Do not truncate observed diffs in results + -V Log *all* ELF sect diffs vs. logging the first diff found + -t Use onbld tools in $SRC/tools + -r Log results and observed differences + -i Tell wsdiff which objects to compare via an input file list""" + sys.exit(1) + +# +# Process command line options +# +def args() : + + global logging + global vdiffs + global reportAllSects + + validOpts = 'i:r:vVt?' + + baseRoot = "" + ptchRoot = "" + fileNamesFile = "" + results = "" + localTools = False + + # getopt.getopt() returns: + # an option/value tuple + # a list of remaining non-option arguments + # + # A correct wsdiff invocation will have exactly two non option + # arguments, the paths to the base (old), ptch (new) proto areas + try: + optlist, args = getopt.getopt(sys.argv[1:], validOpts) + except getopt.error, val: + usage() + + if len(args) != 2 : + usage(); + + for opt,val in optlist : + if opt == '-i' : + fileNamesFile = val + elif opt == '-r' : + results = val + logging = True + elif opt == '-v' : + vdiffs = True + elif opt == '-V' : + reportAllSects = True + elif opt == '-t': + localTools = True + else: + usage() + + baseRoot = args[0] + ptchRoot = args[1] + + if len(baseRoot) == 0 or len(ptchRoot) == 0 : + usage() + + if logging and len(results) == 0 : + usage() + + if vdiffs and not logging : + error("The -v option requires a results file (-r)") + sys.exit(1) + + if reportAllSects and not logging : + error("The -V option requires a results file (-r)") + sys.exit(1) + + # alphabetical order + return baseRoot, fileNamesFile, localTools, ptchRoot, results + +##### +# File identification +# + +# +# Identify the file type. +# If it's not ELF, use the file extension to identify +# certain file types that require special handling to +# compare. Otherwise just return a basic "ASCII" type. +# +def getTheFileType(f) : + + extensions = { 'a' : 'ELF Object Archive', + 'jar' : 'Java Archive', + 'html' : 'HTML', + 'ln' : 'Lint Library', + 'db' : 'Sqlite Database' } + + if os.stat(f)[ST_SIZE] == 0 : + return 'ASCII' + + if isELF(f) == 1 : + return 'ELF' + + fnamelist = f.split('.') + if len(fnamelist) > 1 : # Test the file extension + extension = fnamelist[-1] + if extension in extensions.keys(): + return extensions[extension] + + return 'ASCII' + +# +# Return non-zero if "f" is an ELF file +# +elfmagic = '\177ELF' +def isELF(f) : + try: + fd = open(f) + except: + error("failed to open: " + f) + return 0 + magic = fd.read(len(elfmagic)) + fd.close() + + if magic == elfmagic : + return 1 + return 0 + +# +# Return non-zero is "f" is binary. +# Consider the file to be binary if it contains any null characters +# +def isBinary(f) : + try: + fd = open(f) + except: + error("failed to open: " + f) + return 0 + s = fd.read() + fd.close() + + if s.find('\0') == -1 : + return 0 + else : + return 1 + +##### +# Directory traversal and file finding +# + +# +# Return a sorted list of files found under the specified directory +# +def findFiles(d) : + for path, subdirs, files in os.walk(d) : + files.sort() + for name in files : + yield os.path.join(path, name) + +# +# Examine all files in base, ptch +# +# Return a list of files appearing in both proto areas, +# a list of new files (files found only in ptch) and +# a list of deleted files (files found only in base) +# +def protoCatalog(base, ptch) : + compFiles = [] # List of files in both proto areas + ptchList = [] # List of file in patch proto area + + newFiles = [] # New files detected + deletedFiles = [] # Deleted files + + baseFilesList = list(findFiles(base)) + baseStringLength = len(base) + + ptchFilesList = list(findFiles(ptch)) + ptchStringLength = len(ptch) + + # Inventory files in the base proto area + for fn in baseFilesList : + if os.path.islink(fn) : + continue + + fileName = fn[baseStringLength:] + compFiles.append(fileName) + + # Inventory files in the patch proto area + for fn in ptchFilesList : + if os.path.islink(fn) : + continue + + fileName = fn[ptchStringLength:] + ptchList.append(fileName) + + # Deleted files appear in the base area, but not the patch area + for fileName in compFiles : + if not fileName in ptchList : + deletedFiles.append(fileName) + + # Eliminate "deleted" files from the list of objects appearing + # in both the base and patch proto areas + for fileName in deletedFiles : + try: + compFiles.remove(fileName) + except: + error("filelist.remove() failed") + + # New files appear in the patch area, but not the base + for fileName in ptchList : + if not fileName in compFiles : + newFiles.append(fileName) + + return compFiles, newFiles, deletedFiles + +# +# Examine the files listed in the input file list +# +# Return a list of files appearing in both proto areas, +# a list of new files (files found only in ptch) and +# a list of deleted files (files found only in base) +# +def flistCatalog(base, ptch, flist) : + compFiles = [] # List of files in both proto areas + newFiles = [] # New files detected + deletedFiles = [] # Deleted files + + try: + fd = open(flist, "r") + except: + error("could not open: " + flist) + cleanup(1) + + files = [] + files = fd.readlines() + + for f in files : + ptch_present = True + base_present = True + + if f == '\n' : + continue + + # the fileNames have a trailing '\n' + f = f.rstrip() + + # The objects in the file list have paths relative + # to $ROOT or to the base/ptch directory specified on + # the command line. + # If it's relative to $ROOT, we'll need to add back the + # root_`uname -p` goo we stripped off in fnFormat() + if os.path.exists(base + f) : + fn = f; + elif os.path.exists(base + "root_" + arch + "/" + f) : + fn = "root_" + arch + "/" + f + else : + base_present = False + + if base_present : + if not os.path.exists(ptch + fn) : + ptch_present = False + else : + if os.path.exists(ptch + f) : + fn = f + elif os.path.exists(ptch + "root_" + arch + "/" + f) : + fn = "root_" + arch + "/" + f + else : + ptch_present = False + + if os.path.islink(base + fn) : # ignore links + base_present = False + if os.path.islink(ptch + fn) : + ptch_present = False + + if base_present and ptch_present : + compFiles.append(fn) + elif base_present : + deletedFiles.append(fn) + elif ptch_present : + newFiles.append(fn) + else : + if os.path.islink(base + fn) and os.path.islink(ptch + fn) : + continue + error(f + " in file list, but not in either tree. Skipping...") + + return compFiles, newFiles, deletedFiles + + +# +# Build a fully qualified path to an external tool/utility. +# Consider the default system locations. For onbld tools, if +# the -t option was specified, we'll try to use built tools in $SRC tools, +# and otherwise, we'll fall back on /opt/onbld/ +# +def find_tool(tool) : + + # First, check what was passed + if os.path.exists(tool) : + return tool + + # Next try in wsdiff path + for pdir in wsdiff_path : + location = pdir + "/" + tool + if os.path.exists(location) : + return location + " " + + location = pdir + "/" + arch + "/" + tool + if os.path.exists(location) : + return location + " " + + error("Could not find path to: " + tool); + sys.exit(1); + + +##### +# ELF file comparison helper routines +# + +# +# Return a dictionary of ELF section types keyed by section name +# +def get_elfheader(f) : + + header = {} + + hstring = commands.getoutput(elfdump_cmd + " -c " + f) + + if len(hstring) == 0 : + error("Failed to dump ELF header for " + f) + return + + # elfdump(1) dumps the section headers with the section name + # following "sh_name:", and the section type following "sh_type:" + sections = hstring.split("Section Header") + for sect in sections : + datap = sect.find("sh_name:"); + if datap == -1 : + continue + section = sect[datap:].split()[1] + datap = sect.find("sh_type:"); + if datap == -1 : + error("Could not get type for sect: " + section + \ + " in " + f) + sh_type = sect[datap:].split()[2] + header[section] = sh_type + + return header + +# +# Extract data in the specified ELF section from the given file +# +def extract_elf_section(f, section) : + + data = commands.getoutput(dump_cmd + " -sn " + section + " " + f) + + if len(data) == 0 : + error(cmd + " yielded no data") + return + + # dump(1) displays the file name to start... + # get past it to the data itself + dbegin = data.find(":") + 1 + data = data[dbegin:]; + + return (data) + +# +# Return a (hopefully meaningful) human readable set of diffs +# for the specified ELF section between f1 and f2 +# +# Depending on the section, various means for dumping and diffing +# the data may be employed. +# +text_sections = [ '.text', '.init', '.fini' ] +def diff_elf_section(f1, f2, section, sh_type) : + + if (sh_type == "SHT_RELA") : # sh_type == SHT_RELA + cmd1 = elfdump_cmd + " -r " + f1 + " > " + tmpFile1 + cmd2 = elfdump_cmd + " -r " + f2 + " > " + tmpFile2 + elif (section == ".group") : + cmd1 = elfdump_cmd + " -g " + f1 + " > " + tmpFile1 + cmd2 = elfdump_cmd + " -g " + f2 + " > " + tmpFile2 + elif (section == ".hash") : + cmd1 = elfdump_cmd + " -h " + f1 + " > " + tmpFile1 + cmd2 = elfdump_cmd + " -h " + f2 + " > " + tmpFile2 + elif (section == ".dynamic") : + cmd1 = elfdump_cmd + " -d " + f1 + " > " + tmpFile1 + cmd2 = elfdump_cmd + " -d " + f2 + " > " + tmpFile2 + elif (section == ".got") : + cmd1 = elfdump_cmd + " -G " + f1 + " > " + tmpFile1 + cmd2 = elfdump_cmd + " -G " + f2 + " > " + tmpFile2 + elif (section == ".SUNW_cap") : + cmd1 = elfdump_cmd + " -H " + f1 + " > " + tmpFile1 + cmd2 = elfdump_cmd + " -H " + f2 + " > " + tmpFile2 + elif (section == ".interp") : + cmd1 = elfdump_cmd + " -i " + f1 + " > " + tmpFile1 + cmd2 = elfdump_cmd + " -i " + f2 + " > " + tmpFile2 + elif (section == ".symtab" or section == ".dynsym") : + cmd1 = elfdump_cmd + " -s -N " + section + " " + f1 + " > " + tmpFile1 + cmd2 = elfdump_cmd + " -s -N " + section + " " + f2 + " > " + tmpFile2 + elif (section in text_sections) : + # dis sometimes complains when it hits something it doesn't + # know how to disassemble. Just ignore it, as the output + # being generated here is human readable, and we've already + # correctly flagged the difference. + cmd1 = dis_cmd + " -t " + section + " " + f1 + \ + " 2>/dev/null | grep -v disassembly > " + tmpFile1 + cmd2 = dis_cmd + " -t " + section + " " + f2 + \ + " 2>/dev/null | grep -v disassembly > " + tmpFile2 + else : + cmd1 = elfdump_cmd + " -w " + tmpFile1 + " -N " + \ + section + " " + f1 + cmd2 = elfdump_cmd + " -w " + tmpFile2 + " -N " + \ + section + " " + f2 + + os.system(cmd1) + os.system(cmd2) + + data = diffFileData(tmpFile1, tmpFile2) + + return (data) + +# +# compare the relevant sections of two ELF binaries +# and report any differences +# +# Returns: 1 if any differenes found +# 0 if no differences found +# -1 on error +# + +# Sections deliberately not considered when comparing two ELF +# binaries. Differences observed in these sections are not considered +# significant where patch deliverable identification is concerned. +sections_to_skip = [ ".SUNW_signature", + ".comment", + ".SUNW_ctf", + ".debug", + ".plt", + ".rela.bss", + ".rela.plt", + ".line", + ".note", + ] + +sections_preferred = [ ".rodata.str1.8", + ".rodata.str1.1", + ".rodata", + ".data1", + ".data", + ".text", + ] + +def compareElfs(base, ptch, quiet) : + + global logging + + base_header = get_elfheader(base) + sections = base_header.keys() + + ptch_header = get_elfheader(ptch) + e2_only_sections = ptch_header.keys() + + e1_only_sections = [] + + fileName = fnFormat(base) + + # Derive the list of ELF sections found only in + # either e1 or e2. + for sect in sections : + if not sect in e2_only_sections : + e1_only_sections.append(sect) + else : + e2_only_sections.remove(sect) + + if len(e1_only_sections) > 0 : + if quiet : + return 1 + info(fileName); + if not logging : + return 1 + + slist = "" + for sect in e1_only_sections : + slist = slist + sect + "\t" + v_info("\nELF sections found in " + \ + base + " but not in " + ptch) + v_info("\n" + slist) + return 1 + + if len(e2_only_sections) > 0 : + if quiet : + return 1 + + info(fileName); + if not logging : + return 1 + + slist = "" + for sect in e2_only_sections : + slist = slist + sect + "\t" + v_info("\nELF sections found in " + \ + ptch + " but not in " + base) + v_info("\n" + slist) + return 1 + + # Look for preferred sections, and put those at the + # top of the list of sections to compare + for psect in sections_preferred : + if psect in sections : + sections.remove(psect) + sections.insert(0, psect) + + # Compare ELF sections + first_section = True + for sect in sections : + + if sect in sections_to_skip : + continue + + s1 = extract_elf_section(base, sect); + s2 = extract_elf_section(ptch, sect); + + if len(s1) != len (s2) or s1 != s2: + if not quiet: + sh_type = base_header[sect] + data = diff_elf_section(base, ptch, sect, \ + sh_type) + + # If all ELF sections are being reported, then + # invoke difference() to flag the file name to + # stdout only once. Any other section differences + # should be logged to the results file directly + if not first_section : + log_difference(fileName, "ELF " + sect, data) + else : + difference(fileName, "ELF " + sect, data) + + if not reportAllSects : + return 1 + first_section = False + return 0 + +##### +# Archive object comparison +# +# Returns 1 if difference detected +# 0 if no difference detected +# -1 on error +# +def compareArchives(base, ptch, fileType) : + + fileName = fnFormat(base) + + # clear the temp directories + baseCmd = "rm -rf " + tmpDir1 + "*" + status, output = commands.getstatusoutput(baseCmd) + if status != 0 : + error(baseCmd + " failed: " + output) + return -1 + + ptchCmd = "rm -rf " + tmpDir2 + "*" + status, output = commands.getstatusoutput(ptchCmd) + if status != 0 : + error(ptchCmd + " failed: " + output) + return -1 + + # + # Be optimistic and first try a straight file compare + # as it will allow us to finish up quickly. + if compareBasic(base, ptch, True, fileType) == 0 : + return 0 + + # copy over the objects to the temp areas, and + # unpack them + baseCmd = "cp -fp " + base + " " + tmpDir1 + status, output = commands.getstatusoutput(baseCmd) + if status != 0 : + error(baseCmd + " failed: " + output) + return -1 + + ptchCmd = "cp -fp " + ptch + " " + tmpDir2 + status, output = commands.getstatusoutput(ptchCmd) + if status != 0 : + error(ptchCmd + " failed: " + output) + return -1 + + bname = string.split(fileName, '/')[-1] + if fileType == "Java Archive" : + baseCmd = "cd " + tmpDir1 + "; " + "jar xf " + bname + \ + "; rm -f " + bname + " META-INF/MANIFEST.MF" + ptchCmd = "cd " + tmpDir2 + "; " + "jar xf " + bname + \ + "; rm -f " + bname + " META-INF/MANIFEST.MF" + elif fileType == "ELF Object Archive" : + baseCmd = "cd " + tmpDir1 + "; " + "/usr/ccs/bin/ar x " + \ + bname + "; rm -f " + bname + ptchCmd = "cd " + tmpDir2 + "; " + "/usr/ccs/bin/ar x " + \ + bname + "; rm -f " + bname + else : + error("unexpected file type: " + fileType) + return -1 + + os.system(baseCmd) + os.system(ptchCmd) + + baseFlist = list(findFiles(tmpDir1)) + ptchFlist = list(findFiles(tmpDir2)) + + # Trim leading path off base/ptch file lists + flist = [] + for fn in baseFlist : + flist.append(str_prefix_trunc(fn, tmpDir1)) + baseFlist = flist + + flist = [] + for fn in ptchFlist : + flist.append(str_prefix_trunc(fn, tmpDir2)) + ptchFlist = flist + + for fn in ptchFlist : + if not fn in baseFlist : + difference(fileName, fileType, \ + fn + " added to " + fileName) + return 1 + + for fn in baseFlist : + if not fn in ptchFlist : + difference(fileName, fileType, \ + fn + " removed from " + fileName) + return 1 + + differs = compareOneFile((tmpDir1 + fn), (tmpDir2 + fn), True) + if differs : + difference(fileName, fileType, \ + fn + " in " + fileName + " differs") + return 1 + return 0 + +##### +# (Basic) file comparison +# +# There's some special case code here for Javadoc HTML files +# +# Returns 1 if difference detected +# 0 if no difference detected +# -1 on error +# +def compareBasic(base, ptch, quiet, fileType) : + + fileName = fnFormat(base); + + if quiet and os.stat(base)[ST_SIZE] != os.stat(ptch)[ST_SIZE] : + return 1 + + try: + baseFile = open(base) + except: + error("could not open " + base) + return -1 + try: + ptchFile = open(ptch) + except: + error("could not open " + ptch) + return -1 + + baseData = baseFile.read() + ptchData = ptchFile.read() + + baseFile.close() + ptchFile.close() + + needToSnip = False + if fileType == "HTML" : + needToSnip = True + toSnipBeginStr = "<!-- Generated by javadoc" + toSnipEndStr = "-->\n" + + if needToSnip : + toSnipBegin = string.find(baseData, toSnipBeginStr) + if toSnipBegin != -1 : + toSnipEnd = string.find(baseData[toSnipBegin:], \ + toSnipEndStr) + \ + len(toSnipEndStr) + baseData = baseData[:toSnipBegin] + \ + baseData[toSnipBegin + toSnipEnd:] + ptchData = ptchData[:toSnipBegin] + \ + ptchData[toSnipBegin + toSnipEnd:] + + if quiet : + if baseData != ptchData : + return 1 + else : + if len(baseData) != len(ptchData) or baseData != ptchData : + diffs = diffData(baseData, ptchData) + difference(fileName, fileType, diffs) + return 1 + return 0 + + +##### +# Compare two objects by producing a data dump from +# each object, and then comparing the dump data +# +# Returns: 1 if a difference is detected +# 0 if no difference detected +# -1 upon error +# +def compareByDumping(base, ptch, quiet, fileType) : + + fileName = fnFormat(base); + + if fileType == "Lint Library" : + baseCmd = lintdump_cmd + " -ir " + base + \ + " | grep -v LINTLIB:" + " > " + tmpFile1 + ptchCmd = lintdump_cmd + " -ir " + ptch + \ + " | grep -v LINTLIB:" + " > " + tmpFile2 + elif fileType == "Sqlite Database" : + baseCmd = "echo .dump | " + sqlite_cmd + base + " > " + \ + tmpFile1 + ptchCmd = "echo .dump | " + sqlite_cmd + ptch + " > " + \ + tmpFile2 + + os.system(baseCmd) + os.system(ptchCmd) + + try: + baseFile = open(tmpFile1) + except: + error("could not open: " + tmpFile1) + try: + ptchFile = open(tmpFile2) + except: + error("could not open: " + tmpFile2) + + baseData = baseFile.read() + ptchData = ptchFile.read() + + baseFile.close() + ptchFile.close() + + if len(baseData) != len(ptchData) or baseData != ptchData : + if not quiet : + data = diffFileData(tmpFile1, tmpFile2); + difference(fileName, fileType, data) + return 1 + return 0 + +##### +# Compare two objects. Detect type changes. +# Vector off to the appropriate type specific +# compare routine based on the type. +# +def compareOneFile(base, ptch, quiet) : + + # Verify the file types. + # If they are different, indicate this and move on + btype = getTheFileType(base) + ptype = getTheFileType(ptch) + + fileName = fnFormat(base) + + if (btype != ptype) : + difference(fileName, "file type", btype + " to " + ptype) + return 1 + else : + fileType = btype + + if (fileType == 'ELF') : + return compareElfs(base, ptch, quiet) + + elif (fileType == 'Java Archive' or fileType == 'ELF Object Archive') : + return compareArchives(base, ptch, fileType) + + elif (fileType == 'HTML') : + return compareBasic(base, ptch, quiet, fileType) + + elif ( fileType == 'Lint Library' ) : + return compareByDumping(base, ptch, quiet, fileType) + + elif ( fileType == 'Sqlite Database' ) : + return compareByDumping(base, ptch, quiet, fileType) + else : + # it has to be some variety of text file + return compareBasic(base, ptch, quiet, fileType) + +# Cleanup and self-terminate +def cleanup(ret) : + + if len(tmpDir1) > 0 and len(tmpDir2) > 0 : + + baseCmd = "rm -rf " + tmpDir1 + ptchCmd = "rm -rf " + tmpDir2 + + os.system(baseCmd) + os.system(ptchCmd) + + if logging : + log.close() + + sys.exit(ret) + +def main() : + + # Log file handle + global log + + # Globals relating to command line options + global logging, vdiffs, reportAllSects + + # Named temporary files / directories + global tmpDir1, tmpDir2, tmpFile1, tmpFile2 + + # Command paths + global lintdump_cmd, elfdump_cmd, dump_cmd, dis_cmd, od_cmd, diff_cmd, sqlite_cmd + + # Default search path + global wsdiff_path + + # Essentially "uname -p" + global arch + + # Some globals need to be initialized + logging = vdiffs = reportAllSects = False + + + # Process command line arguments + # Return values are returned from args() in alpha order + # (Yes, python functions can return multiple values (ewww)) + # Note that args() also set the globals: + # logging to True if verbose logging (to a file) was enabled + # vdiffs to True if logged differences aren't to be truncated + # reportAllSects to True if all ELF section differences are to be reported + # + baseRoot, fileNamesFile, localTools, ptchRoot, results = args() + + # + # Set up the results/log file + # + if logging : + try: + log = open(results, "w") + except: + logging = False + error("failed to open log file: " + log) + sys.exit(1) + + dateTimeStr= "# %d/%d/%d at %d:%d:%d" % time.localtime()[:6] + v_info("# This file was produced by wsdiff") + v_info(dateTimeStr) + + # + # Build paths to the tools required tools + # + # Try to look for tools in $SRC/tools if the "-t" option + # was specified + # + arch = commands.getoutput("uname -p") + if localTools : + try: + src = os.environ['SRC'] + except: + error("-t specified, but $SRC not set. Cannot find $SRC/tools") + src = "" + if len(src) > 0 : + wsdiff_path.insert(0, src + "/tools/proto/opt/onbld/bin") + + lintdump_cmd = find_tool("lintdump") + elfdump_cmd = find_tool("elfdump") + dump_cmd = find_tool("dump") + od_cmd = find_tool("od") + dis_cmd = find_tool("dis") + diff_cmd = find_tool("diff") + sqlite_cmd = find_tool("sqlite") + + # + # validate the base and patch paths + # + if baseRoot[-1] != '/' : + baseRoot += '/' + + if ptchRoot[-1] != '/' : + ptchRoot += '/' + + if not os.path.exists(baseRoot) : + error("old proto area: " + baseRoot + " does not exist") + sys.exit(1) + + if not os.path.exists(ptchRoot) : + error("new proto area: " + ptchRoot + \ + " does not exist") + sys.exit(1) + + # + # log some information identifying the run + # + v_info("Old proto area: " + baseRoot) + v_info("New proto area: " + ptchRoot) + v_info("Results file: " + results + "\n") + + # + # Set up the temporary directories / files + # Could use python's tmpdir routines, but these should + # be easier to identify / keep around for debugging + pid = os.getpid() + tmpDir1 = "/tmp/wsdiff_tmp1_" + str(pid) + "/" + tmpDir2 = "/tmp/wsdiff_tmp2_" + str(pid) + "/" + if not os.path.exists(tmpDir1) : + os.makedirs(tmpDir1) + if not os.path.exists(tmpDir2) : + os.makedirs(tmpDir2) + + tmpFile1 = tmpDir1 + "f1" + tmpFile2 = tmpDir2 + "f2" + + # Derive a catalog of new, deleted, and to-be-compared objects + # either from the specified base and patch proto areas, or from + # from an input file list + newOrDeleted = False + + if fileNamesFile != "" : + changedFiles, newFiles, deletedFiles = \ + flistCatalog(baseRoot, ptchRoot, fileNamesFile) + else : + changedFiles, newFiles, deletedFiles = protoCatalog(baseRoot, ptchRoot) + + if len(newFiles) > 0 : + newOrDeleted = True + info("\nNew objects found: ") + + for fn in newFiles : + info(fnFormat(fn)) + + if len(deletedFiles) > 0 : + newOrDeleted = True + info("\nObjects removed: ") + + for fn in deletedFiles : + info(fnFormat(fn)) + + if newOrDeleted : + info("\nChanged objects: "); + + + # Here's where all the heavy lifting happens + # Perform a comparison on each object appearing in + # both proto areas. compareOneFile will examine the + # file types of each object, and will vector off to + # the appropriate comparison routine, where the compare + # will happen, and any differences will be reported / logged + for fn in changedFiles : + base = baseRoot + fn + ptch = ptchRoot + fn + + compareOneFile(base, ptch, False) + + # We're done, cleanup. + cleanup(0) + +if __name__ == '__main__' : + try: + main() + except KeyboardInterrupt : + cleanup(1); + + diff --git a/usr/src/uts/Makefile.uts b/usr/src/uts/Makefile.uts index 0fdb7cc69d..0cc7ce9516 100644 --- a/usr/src/uts/Makefile.uts +++ b/usr/src/uts/Makefile.uts @@ -238,6 +238,7 @@ CFLAGS_uts += $(XAOPT) CFLAGS_uts += $(CTF_FLAGS) CFLAGS_uts += $(CERRWARN) CFLAGS_uts += $(C99_ENABLE) +CFLAGS_uts += $(CGLOBALSTATIC) CFLAGS_uts += $(EXTRA_CFLAGS) # diff --git a/usr/src/uts/sparc/Makefile.sparc.shared b/usr/src/uts/sparc/Makefile.sparc.shared index c7375d31bd..2d5b42389c 100644 --- a/usr/src/uts/sparc/Makefile.sparc.shared +++ b/usr/src/uts/sparc/Makefile.sparc.shared @@ -136,6 +136,7 @@ CFLAGS += $(CERRWARN) CFLAGS += $(CTF_FLAGS) CFLAGS += $(C99MODE) CFLAGS += $(CCUNBOUND) +CFLAGS += $(CGLOBALSTATIC) CFLAGS += $(CCSTATICSYM) CFLAGS += $(IROPTFLAG) CFLAGS += -xregs=no%float diff --git a/usr/src/uts/sun4u/Makefile.sun4u.shared b/usr/src/uts/sun4u/Makefile.sun4u.shared index 33044a374b..1dfc2fe6fb 100644 --- a/usr/src/uts/sun4u/Makefile.sun4u.shared +++ b/usr/src/uts/sun4u/Makefile.sun4u.shared @@ -205,6 +205,7 @@ CFLAGS += $(CERRWARN) CFLAGS += $(CTF_FLAGS) CFLAGS += $(C99MODE) CFLAGS += $(CCUNBOUND) +CFLAGS += $(CGLOBALSTATIC) CFLAGS += $(CCSTATICSYM) CFLAGS += $(IROPTFLAG) CFLAGS += -xregs=no%float diff --git a/usr/src/uts/sun4u/starcat/io/dman.c b/usr/src/uts/sun4u/starcat/io/dman.c index 6a1a5bc48b..4d2e65026d 100644 --- a/usr/src/uts/sun4u/starcat/io/dman.c +++ b/usr/src/uts/sun4u/starcat/io/dman.c @@ -744,7 +744,6 @@ _init(void) int status = DDI_FAILURE; MAN_DBG(MAN_INIT, ("_init:")); - MAN_DBG(MAN_INIT, ("_init: compiled %s at %s\n", __DATE__, __TIME__)); status = mod_install(&modlinkage); if (status != 0) { diff --git a/usr/src/uts/sun4v/Makefile.sun4v.shared b/usr/src/uts/sun4v/Makefile.sun4v.shared index a3e6a41e35..26ed893c1d 100644 --- a/usr/src/uts/sun4v/Makefile.sun4v.shared +++ b/usr/src/uts/sun4v/Makefile.sun4v.shared @@ -167,6 +167,7 @@ CFLAGS += $(CERRWARN) CFLAGS += $(CTF_FLAGS) CFLAGS += $(C99MODE) CFLAGS += $(CCUNBOUND) +CFLAGS += $(CGLOBALSTATIC) CFLAGS += $(CCSTATICSYM) CFLAGS += $(IROPTFLAG) CFLAGS += -xregs=no%float |