#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos720 src/bos/usr/ccs/bin/lorder/POWER/lorder.sh 1.7.1.10 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1989,1993 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)57        1.7.1.10  src/bos/usr/ccs/bin/lorder/POWER/lorder.sh, cmdaout, bos720 5/15/07 10:37:09
#  COMPONENT_NAME: CMDAOUT (lorder command)
#
#	COMMON LORDER
#

AWK=/usr/bin/awk
CAT=/usr/bin/cat
DSPMSG=/usr/bin/dspmsg
JOIN=/usr/bin/join
OD=/usr/bin/od
RM=/usr/bin/rm
SED=/usr/bin/sed
SORT=/usr/bin/sort

tmp=${TMPDIR-/tmp}
OBJ_FLAG=
trap "$RM -f $tmp/$$sym?ef $tmp/$$lorder.err $tmp/$$nm; exit 1" 1 2 13 15

set -- `/usr/bin/getopt X: $*`
while [ "$1" != -- ]
do
	case "$1" in
	        "")     $DSPMSG lorder.cat 1 \
                        "Usage: lorder [-X {32|64|32_64}] file ...\n"
		        exit 1
			;;
		-X)	OBJ_FLAG="$2"
			;;
	esac
	shift
done

#Throw away the '--' for consistency with other commands.
case "$1" in
	--)	shift
esac

#Verify the specified OBJECT mode
if [ "$OBJ_FLAG" != "" -a "$OBJ_FLAG" != "32"  \
     -a "$OBJ_FLAG" != "64" -a "$OBJ_FLAG" != "32_64" ]
then
    $DSPMSG lorder.cat 2 "The specified object mode is not valid.\n\
\tSpecify -X32, -X64, or -X32_64.\n"
    exit 1
fi

#
if [ $# -eq 0 ]; then
    $DSPMSG lorder.cat 1 "Usage: lorder [-X {32|64|32_64}] file ...\n"
    exit 1
fi

#If no -X given, look for OBJECT_MODE from environment
if [ "$OBJ_FLAG" = "" ]
then
    OBJ_FLAG=$OBJECT_MODE
    if [ "$OBJ_FLAG" != "" -a "$OBJ_FLAG" != "32"  \
         -a "$OBJ_FLAG" != "64" -a "$OBJ_FLAG" != "32_64" ]
    then
            $DSPMSG lorder.cat 3 "The OBJECT_MODE environment variable has an \
invalid setting.\n\tOBJECT_MODE must be 32, 64, or 32_64.\n"
        exit 1
    fi
fi

# Should only use the supplied nm for this command to ensure that the
#       sed script works correctly.
NM=/usr/bin/nm
BINNAME=`/usr/bin/dirname $0`
[ "$BINNAME" != "." -a -x $BINNAME/nm ] && NM=$BINNAME/nm

#	The following sed script is explained here.
#	The first two parts of the sed script put the pattern
#	(in this case the file name) into the hold space
#	and creates the "filename filename" lines and
#	writes them out. The first part is for .o files,
#	the second is for .o's in archives.
#	The next 3 sections of code are exactly alike but
#	they handle different external symbols, namely the
#	symbols that are defined in the text section, data section
#	or symbols that are referenced but not defined in this file.
#	A line containing the symbol (from the pattern space) and 
#	the file it is referenced in (from the hold space) is
#	put into the pattern space.
#	If it's text or data it is written out to the symbol definition
#	(symdef) file, otherwise it was referenced but not declared
#	in this file so it is written out to the symbol referenced
#	(symref) file.
#	Stderr is redirected to capture any error messages for printing
#	at the end.
#	Optimally, the ordering of 32-bit XCOFF files should be kept
#	together and separate from the ordering of 64-bit XCOFF files.
#	For this reason, the nm routine is called separately for each of
#	the two XCOFF modes.
function sed_lorder {
$SED '
	/\.o:$/{
		s/://
		s/^.* //
		h
		s/.*/& &/
		p
		d
	}
	/\.o ‚Å.*:$/{
		s/\.o ‚Å.*://
		s/.*/&.o/
		h
		s/.*/& &/
		p
		d
	}
	/\.o]:$/{
		s/]://
		s/^.*\[//
		h
		s/.*/& &/
		p
		d
	}
	/\.o] ‚Å.*:$/{
		s/\.o] ‚Å.*://
		s/^.*\[//
		s/.*/&.o/
		h
		s/.*/& &/
		p
		d
	}
	/ T /{
		s/ .*$//
		G
		s/\n/ /
		w '$tmp/$$symdef'
		d
	}
	/ D /{
		s/ .*$//
		G
		s/\n/ /
		w '$tmp/$$symdef'
		d
	}
	/ A /{
		s/ .*$//
		G
		s/\n/ /
		w '$tmp/$$symdef'
		d
	}
	s/ .*$//
	G
	s/\n/ /
	w '$tmp/$$symref'
	d
'

$SORT $tmp/$$symdef -o $tmp/$$symdef
$SORT $tmp/$$symref -o $tmp/$$symref
$JOIN $tmp/$$symref $tmp/$$symdef | $SED 's/[^ ]* *//'
}

# the following functions determines the exec mode of each input
# file and calls the appropriate version (32 or 64 bit) of nm to
# build one file which is then sent to sed_lorder.
function exec_nm_3264 {
COUNT=$#
while ((COUNT))
do      magic=$($OD -tx -N2 $1 | $AWK '/^/ { print $2; getline; }')
	case $magic in
	     01df0000) # 32 bit executable
		       echo "$1:" >>$tmp/$$nm
		       $NM -g -X32 $1 >>$tmp/$$nm 2>>$tmp/$$lorder.err 
		       ;;
             01ef0000|01f70000) #64 bit executable
		       echo "$1:" >>$tmp/$$nm
		       $NM -g -X64 $1 >>$tmp/$$nm 2>>$tmp/$$lorder.err
		       ;;
	     *)        # archive file
		       $NM -g -X32_64 $1 >>$tmp/$$nm 2>>$tmp/$$lorder.err 
		       ;;
	esac

	shift
	((COUNT-=1))
done

$CAT $tmp/$$nm | sed_lorder
}

magic=$($OD -tx -N2 $1 | $AWK '/^/ { print $2; getline; }')

if [ "$OBJ_FLAG" = "" -o "$OBJ_FLAG" = "32" ]
then
	if [[ $# = 1 && $magic = 01[de]f0000 ]]; then
	    set $1 $1
	fi
	$NM -g -X32 "$@" 2>>$tmp/$$lorder.err | sed_lorder
fi
if [ "$OBJ_FLAG" = "64" ]
then
	if [ $# = 1 ] 
	then 
	   if [ "$magic" = 01[de]f0000 -o "$magic" = 01f70000 ] 
	   then
             set $1 $1
	   fi
        fi
	$NM -g -X64 "$@" 2>>$tmp/$$lorder.err | sed_lorder
fi
if [ "$OBJ_FLAG" = "32_64" ]
then
	case $# in
	    1) #only 1 arg, so double it
               if [ "$magic" = 01[de]f0000 -o "$magic" = 01f70000 ]
	       then
                   set $1 $1
               fi
	       ;;
	    2) #if the args are of different executable types (32 v. 64)
	       #then double each one.
	       magic2=$($OD -tx -N2 $2 | $AWK '/^/ { print $2; getline; }')
	       if [[ $magic != $magic2 && $magic != 3c6[12]0000 && $magic2 != 3c6[12]0000 ]]
	       then
		   set $1 $1 $2 $2
  	       fi
	       ;;
	    *) #all other cases, do nothing
	       ;;
	esac
		   
	exec_nm_3264 "$@"
fi

# Display errors if any occurred
#  Note that we want to ignore error message 0654-210, which indicates
#  invalid XCOFF mode, because of the two-pass nm call.  We expect to
#  get this message if we did two passes because each object we see will
#  succeed in one pass and fail in the other.
#  (This only happens for object files on the command line.  In archives
#   files, only members of the desired type are seen.  lorder is most
#   commonly used with archives.)
#  If we did two passes, it had to be one or the other type --  unless it was
#  not an XCOFF file at all, in which case nm prints a different message.
#  The awk script below removes the 0654-210 message from the error file.
#  Note that if only one pass was made, 0654-210 is a valid error message
#  and is not removed.
if [ -s $tmp/$$lorder.err -a "$OBJ_FLAG" != "32_64" ] ; then
	$CAT $tmp/$$lorder.err | $SED 's/^nm:/lorder:/' >&2
	$DSPMSG lorder.cat 1 "Usage: lorder [-X {32|64|32_64}] file ...\n" >&2
	RET_CODE=1
elif [ -s $tmp/$$lorder.err -a "$OBJ_FLAG" = "32_64" ]; then
	$CAT $tmp/$$lorder.err | $AWK 'BEGIN {
    		while (getline) {
    			if ($1 == "0654-210") 
				getline
   			else
       				print $0
    		}
	}' > $tmp/$$lorder2.err 2>&1
	if [ -z $tmp/$$lorder2.err ] ; then
		$CAT $tmp/$$lorder2.err | $SED 's/^nm:/lorder:/' >&2
		$DSPMSG lorder.cat 1 "Usage: lorder [-X {32|64|32_64}] file ...\n" >&2
		RET_CODE=1
	else
		RET_CODE=0		#successful completion
	fi
else
	RET_CODE=0		#successful completion
fi

# Clean up and exit
$RM -f $tmp/$$sym?ef $tmp/$$lorder.err $tmp/$$lorder2.err $tmp/$$nm
exit $RET_CODE