#! /bin/sh
#
# Copyright (c) 1994 Berkeley Software Design, Inc. All rights reserved.
# The Berkeley Software Design Inc. software License Agreement specifies
# the terms and conditions for redistribution.
#
#	BSDI shlicc,v 2.3 1995/11/28 19:51:21 donn Exp
#

#
# A substitute for the C compiler that links against shared libraries.
#

IFS=''
PATH=/bin:/usr/bin

case "$0" in
*2|*++)	CC=/usr/bin/gcc2
	;;
*)
	CC=/usr/bin/cc
	;;
esac

SHLIB_MAP="${SHLIB_MAP:-/usr/lib/shlib.map}"
OBJECTS=__library_table.o
OUTPUT=a.out
NEEDCOMPILE=no

#
# strip our private options
#
ARGS=
SKIP=no
for a in "$@"
do
	case "$SKIP" in
	-map)
		SHLIB_MAP="$a"
		SKIP=no
		continue
		;;
	esac

	case $a in
	-map)
		SKIP="$a"
		;;
	*)
		ARGS="$ARGS$a"
		;;
	esac
done
set -- $ARGS
shift

case "$SHLIB_MAP" in
*/*)
	;;
*)
	SHLIB_MAP="/usr/lib/shlib.map.$SHLIB_MAP"
	;;
esac

#
# see if we need to compile anything
#
for a in "$@"
do
	case "$a" in
	-[cSEM]|-Bstatic)
		exec $CC "$@"
		;;
	-p|-pg)
		# don't use shared libraries when profiling
		exec $CC "$@"
		;;
	-*)	;;
	*.c)
		OBJECTS="$OBJECTS`basename "$a" .c`.o"
		NEEDCOMPILE=yes
		;;
	*.cc)
		OBJECTS="$OBJECTS`basename "$a" .cc`.o"
		NEEDCOMPILE=yes
		;;
	*.c++)
		OBJECTS="$OBJECTS`basename "$a" .c++`.o"
		NEEDCOMPILE=yes
		;;
	*.cxx)
		OBJECTS="$OBJECTS`basename "$a" .cxx`.o"
		NEEDCOMPILE=yes
		;;
	*.C)
		OBJECTS="$OBJECTS`basename "$a" .C`.o"
		NEEDCOMPILE=yes
		;;
	*.s)
		OBJECTS="$OBJECTS`basename "$a" .s`.o"
		NEEDCOMPILE=yes
		;;
	esac
done

trap "rm -f $OBJECTS; exit 1" 1 2 10

#
# if we need to compile, do the work
#
if [ $NEEDCOMPILE = yes ]
then
	CMD="$CC-c"
	SKIP=no

	for a in "$@"
	do
		if [ $SKIP = no ]
		then
			case "$a" in
			-l*|*.o|*.a)
				;;
			-o)
				SKIP=yes
				;;
			*)
				CMD="$CMD$a"
				;;
			esac
		else
			SKIP=no
		fi
	done
	$CMD
	STATUS=$?
	if [ $STATUS -ne 0 ]
	then
		rm -f $OBJECTS
		exit $STATUS
	fi
fi

#
# substitute shared libraries for the standard ones
#
CMD=
LIBTABLE=

stub() {
	awk -v LIB="$1" '
	/^[# 	]/ { next }
	$1 == LIB {
		sub(/^.*\/lib/, "", $5)
		print "-l" $5
		LIB = ""
		exit 0
	}
	END {
		if (LIB)
			print LIB
	}' "$SHLIB_MAP"
}

SKIP=no
for a in "$@" -lgcc -lc
do
	if [ $SKIP = no ]
	then
		case "$a" in
		-[DUI]*)
			;;
		-l*)
			STUB=`stub "$a"`
			if [ "X$STUB" = "X$a" ]
			then
				CMD="$CMD$a"
			else
				CMD="$CMD$STUB"
				LIBTABLE="$a$LIBTABLE"
			fi
			;;
		-o)
			SKIP=yes;
			;;
		-[abBCfgImOpvUwW]*|-[dDnt]?*)
			# strip cc(1) options
			;;
		*.c)
			CMD="$CMD`basename $a .c`.o"
			;;
		*.cc)
			CMD="$CMD`basename $a .cc`.o"
			;;
		*.c++)
			CMD="$CMD`basename $a .c++`.o"
			;;
		*.cxx)
			CMD="$CMD`basename $a .cxx`.o"
			;;
		*.C)
			CMD="$CMD`basename $a .C`.o"
			;;
		*.s)
			CMD="$CMD`basename $a .s`.o"
			;;
		*)
			CMD="$CMD$a"
			;;
		esac
	else
		OUTPUT="$a"
		SKIP=no
	fi
done
CMD="/usr/bin/ld-o$OUTPUT/usr/lib/shlicrt0.o__library_table.o$CMD"

#
# build the shared library initialization table
#
for l in $LIBTABLE
do
	echo "$l"
done |
	awk -v MAP="$SHLIB_MAP" '
	BEGIN {
		while (getline < MAP > 0) {
			if ($0 ~ /^[# 	]/) \
				continue
			addr[$1] = $2
			image[$1] = $5
		}
		print "	.text 0"
		print "	.globl ___LIBRARY_TABLE"
		print "___LIBRARY_TABLE:"
	}

	/^[# 	]/ { next }

	addr[$0] {
		print "	.text 0"
		print "	.long L" substr($0, 3)
		print "	.long 0x" addr[$0]
		print "	.text 1"
		print "L" substr($0, 3) ":"
		print "	.asciz \"" image[$0] "\""
		addr[$0] = ""
	}

	END {
		print "	.text 0"
		print "	.long 0"
	}
' |
	as -o __library_table.o

#
# do the link
#
$CMD
STATUS=$?

if [ $STATUS -eq 0 ]
then
	if [ `size $OUTPUT | awk 'NR == 2 { print $1 }'` -le 8192 ]
	then
		NCMD=
		for a in $CMD
		do
			NCMD="$NCMD${NCMD:+}$a"
			if [ "X$a" = "X/usr/bin/ld" ]
			then
				NCMD="$NCMD-n"
			fi
		done
		$NCMD
		STATUS=$?
	fi
fi

rm -f $OBJECTS

exit $STATUS
