#! /bin/csh # Make the Sun/IRAF shared library and associated objects. # Version for Solaris/IRAF, July 1994. Version 2.x compilers. #set echo unset noclobber set BMACH = `ls -l $iraf/bin | sed -e 's+^.*bin\.++'` set MACH = $BMACH set GCRT0 = crt0.o set PGLIB = "" if ($BMACH == ssun) then set LIB = /opt/SUNWspro/SC* set VER = 1 else if ($BMACH == sf2c) then set LIB = /opt/cygnus/lib/gcc-lib/sparc-sun-solaris2/cygnus-2.3.3 set VER = 1 endif if (! -e $LIB) then set LIB = /opt/SUNWspro/SC2.0.1 set VER = 1 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 = 0a000000 # default base address of shared region set PGSZ = 0x2000 # page size set FIOCOMSZ = 0x1560 # exported commons set XERCOMSZ = 0x158 set TOTCOMSZ = 0x16b8 if (`uname -m` == i386) then set FHSZ = 0xd0 # .e file header size else # set FHSZ = 0x20 # Sunos set FHSZ = 0x74 # Solaris endif # 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 = 0a000000 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/lib $iraf/unix/bin.ssol" else set dirs = "$iraf/lib $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 set lflags = "-dn -Bstatic -t -e _start -M mapfile" set lpath = "./:/opt/SUNWspro/lib:${LIB}:/usr/ccs/lib:/usr/lib" set objs = \ "V.o $LIB/crti.o $LIB/crt1.o $FLIB/__fstd.o $LIB/values-xt.o $OBJS" set hlibs = \ "-Y P,$lpath -lM77 -lF77 -lm -lsocket -lnsl -lintl -lc" 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 ( $PGSZ - $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.csh -a $ADDR -f mkshlib.csh -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