#!/bin/sh
PATH=/usr/5bin:/usr/bin:/bin:/usr/ucb:$PATH
export PATH
# --------------------------------------------------------------------------
# Copyright 1993 by Forschungszentrum Informatik (FZI)
#
# You can use and distribute this software under the terms of the license
# version 1 you should have received along with this software.
# If not or if you want additional information, write to
# Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
# D-76131 Karlsruhe, Germany.
# --------------------------------------------------------------------------
# 'obst-ld_incremental - 27/2/93 - Dietmar Theobald'
#
# obst-ld_incremental <sym.old> <sym.new> <xtra> <addr> <path>
#		      <objs> <libs> <schemas>
#
# Performs the linking stage for the incremental linking facility of OBST.
#
# <sym.old> is the pathname of the file containing the symbol table of
# the running executable.
# <sym.new> is the pathname where the new symbol table is to be stored,
# after adding new code. Additionally <sym.new> will contain the code to
# be linked into the running executable.
#
# <xtra> is a additional argument which can be used to pass on options to
# this script. It is used here to specify which compiler was used to compile
# the object modules.
# Valid compiler specifications are:
#   GNUld      ... GNU g++ using GNU ld
#   GNUcollect ... GNU g++ using collect
#   ATTmunch   ... AT&T C++ using munch
#   ATTpatch   ... AT&T C++ using patch
#
# <addr> is the start address (in hex) where the added code is to be stored.
#
# <path> is the searchpath used by OBST to locate code files.
#
# <objs> and <libs> are the object files and libraries to be loaded, each
# passed as a single argument containing a whitespace separated list.
# Likewise, <schemas> is a single argument holding a whitespace separated
# list of the schemas (i.e. their names) to be loaded.
# 
# The result code is 0 on success, 1 on failure.
#
 self='obst-ld_incremental'
usage='<symfile.old> <symfile.new> <xtra> <addr> <path> <objs> <libs> <schemas>'

[ $# -eq 8 ] || { echo >&2 "*** $self: $usage"; exit 1; }

   sym_old="$1"
   sym_new="$2"
  xtra_arg="$3"
  loadaddr="$4"
searchpath="$5"
   objects="$6"
      libs="$7"
   schemas="$8"
   pass1_o="$sym_new"
  tmp_pref="`basename $pass1_o .o`_$$"

check_by_ld=
    ld_opts=-x

undefs=
for schema in $schemas
do
   undefs="$undefs -u __${schema}_init_obst"
done
libpath="-L$searchpath"

case "$xtra_arg" in
   GNUld)      gnuroot=/tools/gcc-1.40.3
	        ldprog=$gnuroot/lib/gcc-ld
	       stdlibs="-lg++ $gnuroot/lib/gcc-gnulib -lc"
	       check_by_ld=+
	       ;;
   GNUcollect)  gnulib=/tools/gcc-2.5/lib
	       version=/sparc-sun-sunos4.1.3/2.5.8
	        ldprog="$gnulib/gcc-lib$version/ld"
	       stdlibs="-lc"
	       ;;
   ATTpatch)    CCroot=/tools/C++_2.1
	        ldprog=ld
	       stdlibs="-L$CCroot/lib -lC"
	       ld_opts=-X
	       ;;
   ATTmunch)    CCroot=/tools/C++_3.0.1
	        ldprog=ld
	       stdlibs="-L$CCroot/lib -lC"
	       pass1_o="$tmp_pref.o"
	       ;;
   *) 	       echo >&2 "*** $self: unknown load option $xtra_arg"
	       exit 1
	       ;;
esac
umask 111
trap "rm -f $tmp_pref* $sym_new" 1 2 3 6 10 15 

cmd_err='echo >&2 "*** $self: incremental load failed [$cmd]"
	 rm -f $tmp_pref* $sym_new
	 exit 1'

args="$undefs $objects $libpath $libs"

cmd="$ldprog $ld_opts -N -A $sym_old -T $loadaddr -o $pass1_o $args $stdlibs"
#echo "[$cmd]"

eval "$cmd" || {
   [ "$check_by_ld" ] && {
      _cmd="ld $ld_opts -N -A $sym_old -T $loadaddr -o $pass1_o $args $stdlibs"
      eval "$_cmd"
   }
   eval "$cmd_err"
}

if [ "$xtra_arg" = "ATTmunch" ]; then
   cmd="nm -p $pass1_o | $CCroot/bin/munch > ${tmp_pref}_.c"
   eval "$cmd" || eval "$cmd_err"

   cmd="cc -c -o ${tmp_pref}_.o ${tmp_pref}_.c"
   eval "$cmd" || eval "$cmd_err"

   cmd="$ldprog -x -N -A $sym_old -T $loadaddr -o $sym_new $args ${tmp_pref}_.o $stdlibs"
   eval "$cmd" || eval "$cmd_err"
fi
rm -f ${tmp_pref}*

exit 0
