#! /bin/csh # Make the Sun/IRAF shared library and associated objects. # Version for Solaris/IRAF, July 1994, Apr 95. # Updated Mon Mar 25 13:19:03 MST 1996 for Solaris 2.5. # Version 3.x and 4.x compilers, Solaris 2.4/2.5. #set echo unset noclobber set BMACH = `ls -l $iraf/bin | sed -e 's+^.*bin\.++'` set MACH = $BMACH set DEFARCH = ssun set GCRT0 = crt0.o set PGLIB = "" set VER = 1 setarch: if ($BMACH == ssun) then set dir = /opt/SUNWspro; pushd $dir set SC3LIB = `find . -name "SC3*" -print` set SC4LIB = `find . -name "SC4*" -print` set SC5LIB = `find . -name "SC5*" -print` if ($SC5LIB != "") then set LIB = ${dir}/${SC5LIB}/lib set VER = 5 else if ($SC4LIB != "") then set LIB = ${dir}/${SC4LIB}/lib set VER = 4 else if ($SC3LIB != "") then set LIB = ${dir}/${SC3LIB}/lib set VER = 3 endif popd else if ($BMACH == sf2c) then set LIB = /opt/cygnus/lib/gcc-lib/sparc-sun-solaris2/cygnus-2.3.3 else echo "Warning: the iraf system architecture is set to $BMACH" echo "building for architecture $DEFARCH..." set BMACH = $DEFARCH set MACH = $BMACH goto setarch endif if (! -e $LIB) then set LIB = /opt/SUNWspro/SC3.0.1/lib endif if ($BMACH == pg) then set MACH = sf2c set GCRT0 = gcrt0.o set PGLIB = -lc_p endif if (`uname -m` == sun3) then setenv FLOAT_OPTION $MACH endif # Use name server if installed? if ($MACH != i386 && -e /lib/libresolv.a) then set RESOLV = -lresolv else set RESOLV = "" endif set PROC = S.e set SNML = S.nm.$BMACH set SVER = S.ver.$BMACH set OMIT = omit.$BMACH set EXCL = "zshlib.o zzstrt.o" set ADDR = 10000000 # default base address of shared region set PGSZ = 0x2000 # maximum page size set CMSZ = 0x26000 # common area (must be N*PGSZ > TOTCOMSZ) set FIOCOMSZ = 0x24660 # exported commons set XERCOMSZ = 0x810 set TOTCOMSZ = 0x24e70 if (`uname -m` == i386) then set FHSZ = 0xd0 # .e file header size else # set FHSZ = 0x20 # Sunos set FHSZ = 0x78 # Solaris endif ######### #exit # Process command line options. while ("$1" != "") switch ($1) case "-a": # set base address of shared library shift set ADDR = $1 # I couldn't get a direct !~ csh pattern match test to work here. if ("`echo $ADDR | grep '[0-9][0-9a-f]*'`" == "") then set ADDR = 10000000 echo -n "Warning: shared library base address not given," echo " defaults to $ADDR" endif breaksw case "-as": set PROC = assemble # assemble S.s, V.s breaksw case "-c": # delete any temporary files set PROC = clean breaksw case "-f": set PROC = files set version = `cat $SVER` breaksw case "-l": # merely relink the shared library set PROC = link breaksw case "-nm": set PROC = names breaksw case "-rl": # merely relink the shared library set PROC = relink breaksw case "-p": set PROC = patch breaksw endsw shift end set TB = `echo 0x$ADDR+$FHSZ=X | adb` set libs = "libos.a libex.a libsys.a libvops.a" if ($?IRAFULIB) then if ($PROC == S.e) then echo "Warning: user library IRAFULIB=$IRAFULIB will be searched" endif set dirs = "$IRAFULIB $iraf/bin.ssun $iraf/unix/bin.ssol" else set dirs = "$iraf/bin.ssun $iraf/unix/bin.ssol" endif # In the following, the object V.o must be the first object to be linked, # as we require it to be at a fixed and predictable address. set OBJS = "Slib.o Malloc.o lib*.o zzzend.o" switch ($MACH) case ssun: set FLIB = $LIB/cg89 echo "text = V0x$TB A0x2000;" > mapfile echo "data = A0x2000;" >> mapfile set lflags = "-dn -Bstatic -t -e _start -M mapfile" set lpath = "./:/opt/SUNWspro/lib:${LIB}:/usr/ccs/lib:/usr/lib" if ($VER == 5) then set objs = \ "V.o $LIB/crti.o $LIB/crt1.o $LIB/values-xi.o $OBJS" else if ($VER == 4) then set objs = \ "V.o $LIB/crti.o $LIB/crt1.o $LIB/values-xi.o $OBJS" else set objs = \ "V.o $LIB/crti.o $LIB/crt1.o $FLIB/__fstd.o $LIB/values-xt.o $OBJS" endif set hlibs = \ "-Y P,$lpath -lM77 -lF77 -lsunmath -lm -lsocket -lnsl -lintl -lc $hbin/libcompat.a $LIB/crtn.o" set mcode = 5 breaksw case sparc: set FLIB = $LIB/cg87 if ($VER == 0) then set lflags = "-Bstatic -d -dc -dp -e start -X -T $TB" set objs = "V.o $LIB/crt0.o $FLIB/_crt1.o -L$LIB $OBJS" else set lflags = "-Bstatic -d -dc -dp -e start -X -T $TB" set objs = "V.o $LIB/crt0.o $FLIB/_crt1.o -L$FLIB -L$LIB $OBJS" endif set hlibs = "$RESOLV -lF77 -lm -lc" set mcode = 1 breaksw case i386: # The following has NOT been modified for use with the new Sun Fortran # compiler, as we don't have this on our 386i. set lflags = "-Bstatic -d -dc -dp -e _start -X -T $TB" set objs = "V.o /lib/crt0.o $OBJS" set hlibs = "$RESOLV -lm -lF77 -lI77 -lm -lc" set mcode = 2 breaksw case f68881: set FLIB = $LIB/f68881 set lflags = "-Bstatic -d -dc -dp -e start -X -T $TB" set objs = "V.o $LIB/$GCRT0 $FLIB/_crt1.o -L$FLIB -L$LIB $OBJS" set hlibs = "$RESOLV -lF77 -lm -lc" set mcode = 3 breaksw case ffpa: set FLIB = $LIB/ffpa set lflags = "-Bstatic -d -dc -dp -e start -X -T $TB" set objs = "V.o $LIB/$GCRT0 $FLIB/_crt1.o -L$FLIB -L$LIB $OBJS" set hlibs = "$RESOLV -lF77 -lm -lc" set mcode = 4 breaksw default: set FLIB = $LIB/fsoft set lflags = "-Bstatic -d -dc -dp -e start -X -T $TB" set objs = "V.o $LIB/$GCRT0 $FLIB/_crt1.o -L$FLIB -L$LIB $OBJS" set hlibs = "$RESOLV -lF77 -lm -lc" set mcode = 0 endsw alias link "ld -o S.e $lflags $objs $hlibs $PGLIB |& grep -v 'has differing types' |& grep -v 'file V.o type=NOTY' |& grep -v 'V.o definition taken'" alias names "(nm -p S.e | egrep 'T [_]?[a-z0-9]+_"'$'"' | fgrep -v -f $OMIT | sed -e 's+^.* ++' | sort)" goto $PROC # Build the shared library and associated runtime files. # -------------- S.e: link: # Initialize the `objs' working directory. echo "initialize the 'objs' working directory" if (-e objs) then rm -rf objs endif mkdir objs # Recompile the shlib support objects if necessary. if (! -e Slib.o) cc -c $HSI_CF Slib.c if (! -e zzzend.o) cc -c $HSI_CF zzzend.c # Construct private version of MALLOC etc. for S.e run standalone; # extract standard object and edit the symbol table. if (! -e Malloc.o) then if (! -e medit.e) then if (`uname -m` == sun3) then cc -fsoft medit.c -o medit.e else cc $HSI_CF medit.c -o medit.e endif endif ar x /usr/lib/libc.a malloc.o; mv malloc.o Malloc.o medit.e Malloc.o malloc Malloc realloc Realloc free Free \ __Malloc_lock __malloc_lock endif if (! -e $OMIT) then echo "Warning: $OMIT file not found" echo "fiocom" >> $OMIT echo "onenty" >> $OMIT echo "ushlib" >> $OMIT echo "vshend" >> $OMIT echo "vshlib" >> $OMIT echo "xercom" >> $OMIT echo "zcall" >> $OMIT echo "zfunc" >> $OMIT echo "zgtenv" >> $OMIT echo "zzstop" >> $OMIT echo "zzstrt" >> $OMIT endif # Create a dummy transfer vector V.o for linking purposes. if (! -e V.o) then echo "vshlib_(){}vshend_(){}" > V.c cc -c V.c; rm V.c endif # Link a new shared library. Custom IRAFULIB libraries are supported. cd objs set noclobber foreach i ($libs) foreach j ($dirs) set file = $j/$i if (-e $file) then break endif end echo "prelink $file" ar x $file if (-e __.SYMDEF) then rm __.SYMDEF endif foreach j ($EXCL) if (-e $j) rm $j end ld -r -t -o ../$i.o *.o rm *.o end unset noclobber cd .. echo "link the shared library" link; if ($PROC == "link") exit 0 names: # Generate the external names list for the new shared library. echo "generate the name list for the new shared library" names > S.nm.new if (-e $SNML) then sort $SNML > S.nm.old else cp S.nm.new $SNML cp S.nm.new S.nm.old endif # If any externals present in the old library have been deleted, # increment the shlib version number to indicate that old executables # much be relinked. If any new symbols have been added, append these # to the end of the name list so that the order of the existing # externals is not changed, allowing old executables to be used with # the new shared library without relinking. if (! -e $SVER) then echo "1" > $SVER endif set new_version = no set version = `cat $SVER` comm -23 S.nm.old S.nm.new > S.nm.deleted comm -13 S.nm.old S.nm.new > S.nm.added if ($PROC == "names") then exit 0 endif if ("`head -1 S.nm.deleted`" != "") then set version = `expr $version + 1` echo $version > $SVER echo "shlib version incremented to $version" echo "deleted externals: `cat S.nm.deleted`" set new_version = yes cp S.nm.new $SNML else if ("`head -1 S.nm.added`" != "") then set number = `cat S.nm.added | wc -l` echo "$number new externals added:" head -200 S.nm.added cat S.nm.added >> $SNML endif files: if (-e S.s) rm S.s if (-e V.s) rm V.s # Get the number of symbols in the name list. foreach i (`wc $SNML`) set nsymbols = $i break end # Write out the shared library transfer vector module. Each external # in the shared library has a fixed offset in the transfer vector; # the instruction at that offset is a jump to the actual procedure. # Memory is allocated as follows: 0x20 byte file header, 0x14 byte # transfer vector header, FIO common storage, and then the transfer # vector. The FIO common is allocated the entire first page (8192 # bytes) of the mapped file. This first page will be mapped RW even # though it is technically part of the text area. The transfer vector # and the remainder of the text area are mapped RO. The FIO common # and the MEM common need to be located at absolute addresses (MEM is # at zero) so that they may be referenced in both the client process # and in the shared library. echo "create the V.s file" echo ' .seg "text"' >> V.s echo " .common mem_,8" >> V.s echo " mem_ = 0" >> V.s echo " .common fiocom_,$FIOCOMSZ" >> V.s echo "fiocom_:" >> V.s echo " .skip $FIOCOMSZ" >> V.s echo " .common xercom_,$XERCOMSZ" >> V.s echo "xercom_:" >> V.s echo " .skip $XERCOMSZ" >> V.s echo " .skip ( $CMSZ - $FHSZ - $TOTCOMSZ )" >> V.s echo " .global vshlib_" >> V.s echo "vshlib_:" >> V.s echo " .long $version" >> V.s echo " .long 0x$ADDR" >> V.s echo " .long _etext" >> V.s echo " .long _edata" >> V.s echo " .long _end" >> V.s echo " .long $nsymbols" >> V.s echo " .long $mcode" >> V.s echo " .long 8" >> V.s sed -e 's+.*+ set &, %g1; jmp %g1; nop+' < $SNML >> V.s echo " .global vshend_" >> V.s echo "vshend_:" >> V.s # Write out the shared library object containing the names of all # shared library externals, to be linked into each applications # program. Each external is represented in the object (S.o) by the # address (i.e., as a symbol) of the corresponding jmp instruction # in the transfer vector in the shared library. if (-e S.e) then set fiocom_addr = `nm -p -x S.e | grep fiocom | cut -f1 -d \ ` set xercom_addr = `nm -p -x S.e | grep xercom | cut -f1 -d \ ` set vshlib_addr = `nm -p -x S.e | grep vshlib | cut -f1 -d \ ` set vshend_addr = `nm -p -x S.e | grep vshend | cut -f1 -d \ ` else set fiocom_addr = $ADDR set xercom_addr = $ADDR set vshlib_addr = $ADDR set vshend_addr = $ADDR endif echo "create the S.s file" set LOC = `echo $vshlib_addr+0x20=D | adb` echo ' .seg "data"' >> S.s echo " .global sh_debug" >> S.s echo "sh_debug:" >> S.s echo " .long 0" >> S.s echo ' .seg "text"' >> S.s echo " .global ushlib_" >> S.s echo "ushlib_:" >> S.s echo " .long $version" >> S.s echo " .long 0x$ADDR" >> S.s echo " .long $vshlib_addr" >> S.s echo " .long $vshend_addr" >> S.s echo " .long 0" >> S.s echo " .long $nsymbols" >> S.s echo " .long $mcode" >> S.s echo " .long 8" >> S.s echo ' .seg "text"' >> S.s echo " .common mem_,8" >> S.s echo " mem_ = 0" >> S.s echo " .common fiocom_,$FIOCOMSZ" >> S.s echo " fiocom_ = ( $fiocom_addr )" >> S.s echo " .common xercom_,$XERCOMSZ" >> S.s echo " xercom_ = ( $xercom_addr )" >> S.s echo " .global vshlib_" >> S.s echo " vshlib_ = ( $vshlib_addr )" >> S.s awk "BEGIN { s = $LOC }"' { printf ("\t.global %s; %s = 0x%x\n", $1, $1, s); s += 16 }' S.nm.ssun >> S.s echo " .global vshend_" >> S.s echo "vshend_:" >> S.s if ($PROC == "files") then exit 0 endif assemble: if (`uname -p` == sparc) then echo "assemble V.s"; as V.s -o V.o echo "assemble S.s"; as S.s -o S.o else echo "assemble V.s"; as V.s -o V.o echo "assemble S.s"; as S.s -o S.o endif if ($PROC == "assemble") exit 0 relink: # Relink the shared library with the new transfer vector. echo "relink the shared library with the new transfer vector" link; if ($PROC == "relink") exit 0 patch: # Need to rebuild S.o to pick up the final vshlib, vshend. echo "rebuild S.o" mkshlib.ssol -a $ADDR -f mkshlib.ssol -a $ADDR -as if ($PROC == "patch") exit 0 # All done with build S.e sequence. echo "delete the 'objs' working directory" rm -rf objs exit 0 # Utilities. # ------------------- clean: # Delete all intermediate files. if (-e objs) then rm -rf objs endif foreach i (V.s S.s S.nm.added S.nm.deleted S.nm.old S.nm.new) if (-e $i) then rm -f $i endif end if ("`find . -name '*.[aoe]' -print | head -1`" != "") then rm -f *.[aoe] endif exit 0