1 #!/bin/bash
   2 #
   3 # Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
   4 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 #
   6 # This code is free software; you can redistribute it and/or modify it
   7 # under the terms of the GNU General Public License version 2 only, as
   8 # published by the Free Software Foundation.
   9 #
  10 # This code is distributed in the hope that it will be useful, but WITHOUT
  11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13 # version 2 for more details (a copy is included in the LICENSE file that
  14 # accompanied this code).
  15 #
  16 # You should have received a copy of the GNU General Public License version
  17 # 2 along with this work; if not, write to the Free Software Foundation,
  18 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19 #
  20 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21 # or visit www.oracle.com if you need additional information or have any
  22 # questions.
  23 #
  24 
  25 if [ $# -lt 2 ] 
  26 then
  27   echo "Diff two executables. Return codes:"
  28   echo "0 - no diff"
  29   echo "1 - Identical symbols AND size, BUT not bytewise identical"
  30   echo "2 - Identical symbols BUT NEW size"
  31   echo "3 - Differences, content BUT SAME size"
  32   echo "4 - Differences, content AND size"
  33   echo "10 - Could not perform diff"
  34   echo "Use 'quiet' to disable any output."
  35   echo "Syntax: $0 file1 file2 [quiet]"
  36   exit 10
  37 fi
  38 
  39 if [ ! -f $1 ]
  40 then
  41   echo $1 does not exist
  42   exit 10
  43 fi
  44 
  45 if [ ! -f $2 ]
  46 then
  47   echo $2 does not exist
  48   exit 10
  49 fi
  50 
  51 if [ "`uname`" == "SunOS" ]; then
  52     if [ -f "`which nm`" ]; then
  53         NM=nm
  54     elif [ -f "`which gnm`" ]; then
  55         NM=gnm
  56     else
  57         echo "No nm command found"
  58         exit 10
  59     fi
  60     LDD=ldd
  61 elif [ $OSTYPE == "cygwin" ]; then
  62     NM="$VS100COMNTOOLS/../../VC/bin/amd64/dumpbin.exe"
  63     NM_ARGS=/exports
  64     LDD=
  65 elif [ "`uname`" == "Darwin" ]; then
  66     NM=nm
  67     LDD="otool -L"
  68 else
  69     NM=nm
  70     LDD=ldd
  71 fi
  72 
  73 # Should the differences be viewed?
  74 VIEW=
  75 # You can do export DIFF=meld to view
  76 # any differences using meld instead.
  77 if [ -n "$DIFF" ]; then
  78     DIFF="$DIFF"
  79 else
  80     DIFF=diff
  81 fi
  82 OLD=$(cd $(dirname $1) && pwd)/$(basename $1)
  83 NEW=$(cd $(dirname $2) && pwd)/$(basename $2)
  84 
  85 OLD_SIZE=$(ls -l "$OLD" | awk '{ print $5 }')
  86 NEW_SIZE=$(ls -l "$NEW" | awk '{ print $5 }')
  87 
  88 if [ $# -gt 3 ]
  89 then
  90     ROOT1=$(cd $3 && pwd)
  91     ROOT2=$(cd $4 && pwd)
  92     OLD_NAME=$(echo $OLD | sed "s|$ROOT1/||")
  93     NEW_NAME=$(echo $NEW | sed "s|$ROOT2/||")
  94     if [ "x$5" == "xview" ]; then VIEW=view; fi
  95 else
  96     ROOT1=$(dirname $OLD)/
  97     ROOT2=$(dirname $NEW)/
  98     OLD_NAME=$OLD
  99     NEW_NAME=$NEW
 100     if [ "x$3" == "xview" ]; then VIEW=view; fi
 101 fi
 102 
 103 if cmp $OLD $NEW > /dev/null
 104 then
 105     # The files were bytewise identical.
 106     echo Identical: $OLD_NAME
 107     exit 0
 108 fi
 109 
 110 OLD_SYMBOLS=$COMPARE_ROOT/$OLD_NAME.old
 111 NEW_SYMBOLS=$COMPARE_ROOT/$NEW_NAME.new
 112 
 113 mkdir -p $(dirname $OLD_SYMBOLS)
 114 mkdir -p $(dirname $NEW_SYMBOLS)
 115 
 116 if [ $OSTYPE == "cygwin" ]; then
 117     "$NM" $NM_ARGS $OLD | grep " = " > $OLD_SYMBOLS
 118     "$NM" $NM_ARGS $NEW | grep " = " > $NEW_SYMBOLS
 119     "$NM" $NM_ARGS $OLD > $OLD_SYMBOLS.full
 120     "$NM" $NM_ARGS $NEW > $NEW_SYMBOLS.full
 121 else
 122     # Strip the addresses, just compare the ordering of the symbols.
 123     $NM $OLD | cut -f 2- -d ' ' > $OLD_SYMBOLS
 124     $NM $NEW | cut -f 2- -d ' ' > $NEW_SYMBOLS
 125     # But store the full information for easy diff access.
 126     $NM $OLD  > $OLD_SYMBOLS.full
 127     $NM $NEW  > $NEW_SYMBOLS.full
 128 fi
 129 
 130 DIFFS=$(LANG=C diff $OLD_SYMBOLS $NEW_SYMBOLS)
 131 
 132 if [ "${LDD}" ]
 133 then
 134     NAME=`basename $OLD`
 135     TMP=$COMPARE_ROOT/ldd/ldd.${NAME}
 136     rm -rf "${TMP}"
 137     mkdir -p "${TMP}"
 138 
 139     (cd "${TMP}" && cp $OLD . && ${LDD} ${NAME} | awk '{ print $1;}' | sort | tee dep.old | uniq > dep.uniq.old)
 140     (cd "${TMP}" && cp $NEW . && ${LDD} ${NAME} | awk '{ print $1;}' | sort | tee dep.new | uniq > dep.uniq.new)
 141     (cd "${TMP}" && rm -f ${NAME})
 142     
 143     DIFFS_DEP=$(LANG=C diff "${TMP}/dep.old" "${TMP}/dep.new")
 144     DIFFS_UNIQ_DEP=$(LANG=C diff "${TMP}/dep.uniq.old" "${TMP}/dep.uniq.new")
 145     
 146     DEP_MSG=
 147     if [ -z "${DIFFS_UNIQ_DEP}" -a -z "${DIFFS_DEP}" ]; then
 148        DEP_MSG="Identical dependencies"
 149     elif [ -z "${DIFFS_UNIQ_DEP}" ]; then
 150        DEP_MSG="Redundant duplicate dependencies added"
 151        RES=1
 152     else
 153        DEP_MSG="DIFFERENT dependencies"
 154        RES=1
 155     fi
 156 fi
 157 
 158 RESULT=0
 159 
 160 if [ -n "$DIFFS" ]; then
 161    if [ $OLD_SIZE -ne $NEW_SIZE ]
 162    then
 163        echo Differences, content AND size     : $DEP_MSG : $OLD_NAME 
 164        RESULT=4
 165    else
 166        echo Differences, content BUT SAME size: $DEP_MSG : $OLD_NAME 
 167        RESULT=3
 168    fi
 169    if [ "x$VIEW" == "xview" ]; then
 170        LANG=C $DIFF $OLD_SYMBOLS $NEW_SYMBOLS
 171    fi
 172 else
 173    if [ $OLD_SIZE -ne $NEW_SIZE ]
 174    then
 175        echo Identical symbols BUT NEW size    : $DEP_MSG : $OLD_NAME 
 176        RESULT=2
 177    else
 178        echo Identical symbols AND size, BUT not bytewise identical: $DEP_MSG : $OLD_NAME 
 179        RESULT=1
 180    fi
 181 fi
 182 
 183 exit $RESULT
 184 
 185 
 186