[comp.sys.apollo] Version 0.6 of gnu2coff converter; part 1 of 4

dclemans@mentor.com (Dave Clemans @ APD x1292) (06/15/89)

Here's version 0.6 of gnu2coff; a number of bug fixes, and it has
been tested on more source (in particular I'm used to build an
Apollo version of the latest release of CNEWS).

I'm resending the whole package because a number of people complained
about not receiving everything last time.  It is my intention to switch
to diffs for any future general postings.

dgc

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 4)."
# Contents:  Makefile README c++patch.c exit.s g++.sh gcc.sh gnu2coff.h
#   main.c malloc.c tm-apollo.h
# Wrapped by dclemans@dclemans on Wed Jun 14 14:59:41 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(616 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X#   Make gnu2coff
X#
X
XCFLAGS  = -g -O
XLFLAGS  = -g
XFILES   = main.o a_out.o coff.o symbolic.o undefined.o convert.o malloc.o
X
Xall:    gnu2coff c++patch patchlib
X
Xgnu2coff:   $(FILES)
X	cc $(LFLAGS) -o $@ $(FILES)
X
Xc++patch:   c++patch.o
X	cc $(LFLAGS) -o $@ c++patch.o
X
Xpatchlib:   exit.o
X	ar rv patchlib exit.o
X
Xexit.o:     exit.s
X	gcc -c -o exit.o exit.s
X
Xmain.o:         main.c gnu2coff.h
Xa_out.o:        a_out.c gnu2coff.h
Xcoff.o:         coff.c gnu2coff.h
Xsymbolic.o:     symbolic.c gnu2coff.h
Xundefined.o:    undefined.c gnu2coff.h
Xconvert.o:      convert.c
Xmalloc.o:       malloc.c
X
Xc++patch.o:     c++patch.c
END_OF_FILE
if test 616 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(8277 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XObject file format converter: a.out format (GNU like) -> Apollo coff format
X    Dave Clemans
X    dclemans@pdx.mentor.com
X    3/89 -> 5/89
X
X    So far, this is the only documentation.  Oh well....
X
X********************
X
XVersion 0.6 changes (June 1989):
X
X    Some "unusual" relocation entries should now get translated correctly
X        (These were found while trying to get gdb 3.1.2 compiled, using
X        the "COFF_FORMAT" configuration. The current status of my gdb efforts
X        is that the main command loop works fine, but there are still problems
X        with the ptrace hooks to sub-processes).
X
X    Some shared library references that weren't handled correctly before now work.
X
X    Unless the "-g" switch is given to gnu2coff, symbolic debugging symbol
X    table entries are ignored.
X
X    gnu2coff now has a "-R" switch to dump out the final coff format relocation table.
X
X    Put more version information into the Apollo MIR table.
X
X********************
X
XThis is for Apollo systems using M68020 or greater cpu's, with hardware floating point.
XThis will not work for the DN10000.
XThis is for SR10 only (and note that all testing has been done using sr10.1).
X
XNote that gnu2coff has only about a third of the code necessary to convert gnu/a.out format
Xsymbolic debugging info to "standard" coff debugging info; that code subset can get confused
Xeasily.  Thus if you specify "-g" when compiling, you most likely will get warning messages.
XThese messages can be ignored; they won't hurt the object code.
X
XYou should also note that Apollo systems ignore "standard" coff symbolic debugging info;
XApollo tools look for their own private structures.  Thus even if the code for symbolic
Xdebugging in gnu2coff was complete, you would still not be able to use dde (and probably
XApollo's version of dbx).
X    The alternatives for symbolic debugging support are:
X        Either finish what's there (or re-write from scratch) code to convert
X        the a.out entries to coff entries, and then
X            convert those to Apollo format (if you can find that out), or
X            find a coff debugging tool that runs on Apollo's, or
X            (go directly from a.out entries to Apollo entries...)
X        Or do the minimal translation necessary to stick the a.out entries into the
X        regular coff symbol table, and modify gdb to initialize itself from a regular
X        coff file (NOT an encapsulated coff file), and to get its symbol table info
X        from the coff symbol table
X
XBasic "what to do" to get all this working:
X    copy tm-apollo.h to appropriate place, and modify config.gcc to have an apollo case
X    (basically the tm- link goes to tm-apollo.h; all others to the m68k cases)
X
X    Compile gcc/gas using the Apollo C compiler (setting the appropriate flags in the
X    makefile; see existing comments in the GCC makefile).  You may also have to play
X    around with includes of <sys/file.h>, and some strange function pointer references
X    in gcc/stmt.c; but all changes should be relatively obvious.  None of the changes
X    (except for the <sys/file.h> ones) has to be permanent once you have a gcc/gas binary.
X
X    Decide where you want things to go; put the gcc/gas binaries there.  Modify the
X    gcc.sh/g++.sh scripts and put them in an appropriate place.
X
X    Make gnu2coff and put it in the desired place
X
X    Make the rest of the gnu2coff stuff and install it in the correct place
X
X    Now try rebuilding gcc/gas from scratch using what was built in the previous steps;
X    everything should work.  Replace the gcc/gas from previous steps with what you build here.
X
X    Now build up the g++ link directory, copy tm-apollo.h over, modify config.g++ appropriately,
X    and run it.  You should now be able to build g++.  (Note that the make will abort when
X    building newld; ignore that.  None of the g++ crt* stuff, newld, and anything built after
X    that point is used.  The only important files from the g++ build are the g++ and cc1plus).
X
XA side note:  When installing cc1/a68/cc1plus, you probably should bump its stacksize up
X    by using "ld -A stacksize,100000 <file>", and then move the resulting a.out file to the
X    actual installed location.
X
Xtm-apollo.h
X    The gcc "configuration" file that I'm using for apollo's; basically it's a tweaked
X    sun3 configuration.
X
XMakefile
X    builds gnu2coff, c++patch, patchlib
X
Xa_out.c
X    reads in a.out files
X
Xc++patch.c
X    links together static constructor/destructor structures in a fully linked binary
X    so that the initialization/termination that runs these routines can find them
X
Xcoff.c
X    maintain the in-memory coff "file"; do necessary relocations; allocate patch space
X    and write out the file when complete.  The patching to mark a "main" routine for
X    the Apollo is handled here (basically crt0 sets up registers and calls the entry
X    point of this patch; this patch then gets the address of the real main routine
X    and calls the arg vector setup code in the Apollo shared library with that address).
X
X    Relocation to Apollo page boundaries is also done here.
X
Xconvert.c
X    This is a simple in-memory disassembler used for debugging
X
Xexit.s
X    this becomes the actual "exit()" routine for C++; calls necessary destructors,
X    calls the stdio cleanup routine and then calls _exit
X
X    assembled using gas
X
Xg++.sh
X    Shell file that's a front end to the G++ "front end"; manages calling converters,
X    patch routines, etc. appropriately.  Set paths here.
X
Xgcc.sh
X    Shell file that's a front end to the GCC "front end"; manages calling converters,
X    etc. appropriately.  Set paths here.
X
Xgnu2coff.h
X    Basic global #defines for gnu2coff
X
Xmain.c
X    Main entry point
X    Usage:
X        gnu2coff [-args] file
X
X        the input object file is converted and written out to a file named either:
X            a. if input file name ends in "*.o", the output file is "*_coff.o"
X            b. else the output file name is just the input file name appended with "_coff"
X
X    Flags:  (mainly for debugging)
X        -v  print version message
X        -h  print headers of input a.out file
X        -s  print symbol table of input a.out file
X        -r  print relocation table of input a.out file
X        -i  disassemble and print code from input a.out file
X        -I  disassemble and print code after all patching is complete
X        -S <num> Set the apollo stacksize as <num>K.  For example,
X            a one megabyte stacksize would be requested as -S 1024.
X        -+  Generate C++ static constructor/destructor linkage blocks
X        -R  print relocation table of output coff file
X        -g  pay attention to symbolic debugging symbol table entries
X
Xmalloc.c
X    I use this malloc because the version of realloc in the standard Apollo 10.1 library
X    seems to have a bug.  Instead of using this version of malloc, you could also use
X    the "debugging" version in /usr/apollo/lib on 10.1.
X
Xundefined.c
X    This file contains the patching heuristics that connects converted code to the
X    Apollo shared library system.  It works in cooperation with the code in coff.c.
X    Notes:
X        the table that controls what routines are patched to have compatible calling
X        sequences for Apollo floating point currently only has the names "ldexp" and "atof",
X        as those are the only floating point functions used by the examples I've tried.
X        Every function you use from the Apollo shared library that returns a floating
X        point number needs to be in this table.  Note that it is possible for GCC/G++ to
X        generate floating point calls that this patch code can't fix.  The best thing
X        to do would be to just junk this and have the compiler generate the right code
X        in the first place.  (Or if all usages of floating point are confined within GNU
X        code, then you don't have to worry about this problem at all).
X
X        the big case statement that handles patching "data" like references is not guaranteed
X        to be complete; though it does handle all examples so far.  It should print a
X        warning message if it finds a reference it can't handle.  If you get one of those
X        messages, look up the instruction format in a Motorola manual and figure out which
X        case statement it should be added to.
X
END_OF_FILE
if test 8277 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'c++patch.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'c++patch.c'\"
else
echo shar: Extracting \"'c++patch.c'\" \(6804 characters\)
sed "s/^X//" >'c++patch.c' <<'END_OF_FILE'
X/*
X * Link together C++ static constructors/destructors in a fully linked binary
X */
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X#include <a.out.h>
X
Xextern char *malloc();
X
Xint debugmode = 0;
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X    register int i;
X    register char *p;
X
X    for (i = 1; i < argc; i++)
X    {   /* for each argument */
X        if (argv[i][0] == '-')
X        {   /* process any flags */
X            for (p = &argv[i][1]; *p; p++) switch(*p)
X            {   /* which flag? */
X                case 'd':
X                    debugmode++;
X                    break;
X                case 'v':
X                    fprintf(stderr,"c++patch: C++ static constructor/destructor patching: Version 0.5\n");
X                    break;
X                default:
X                    fprintf(stderr,"c++patch: unknown argument: '%s'\n",argv[i]);
X                    exit(1);
X            }
X        }
X        else
X        {   /* a filename */
X            patch(argv[i]);
X        }
X    }
X    exit(0);
X}   /* end of main */
X
Xpatch(file)
Xchar *file;
X{
X    register FILE *fp;
X    register int i,j;
X    FILHDR file_header;
X    AOUTHDR optional_header;
X    SCNHDR section_header;
X    SYMENT symbol;
X    AUXENT auxiliary;
X    char *data_section;
X    long str_length;
X    char *strings;
X    char name[SYMNMLEN+1];
X    char *symname;
X    long addr,addr1st,*ptr;
X
X    fp = fopen(file,"r");
X    if (fp == (FILE *)NULL)
X    {   /* did we get the file? */
X        fprintf(stderr,"c++patch: can't open file '%s'\n",file);
X        exit(1);
X    }
X
X    fread(&file_header, sizeof file_header, 1, fp);
X    if (file_header.f_opthdr > 0)
X    {   /* get optional header too... */
X        fseek(fp,(long)FILHSZ,0);
X        fread(&optional_header, sizeof optional_header, 1, fp);
X    }
X    addr = FILHSZ + file_header.f_opthdr;
X
X    for (i = 0; i < file_header.f_nscns; i++)
X    {   /* look for .data */
X        fseek(fp,addr,0);
X        fread(&section_header, sizeof section_header, 1, fp);
X        addr += SCNHSZ;
X
X        if (strcmp(section_header.s_name,".data") == 0)
X            break;
X    }
X    if (i >= file_header.f_nscns)
X    {   /* found .data? */
X        fprintf(stderr,"c++patch: can't find data section in '%s'\n",file);
X        exit(1);
X    }
X    data_section = (char *)malloc(section_header.s_size);
X    if (data_section == (char *)NULL)
X    {   /* enough memory? */
X        fprintf(stderr,"c++patch: no memory for data section of '%s'\n",file);
X        exit(1);
X    }
X    fseek(fp,section_header.s_scnptr,0);
X    fread(data_section, section_header.s_size, 1, fp);
X
X    strings = (char *)NULL;
X    fseek(fp,(long)(file_header.f_symptr + SYMESZ*file_header.f_nsyms),0);
X    fread(&str_length, sizeof str_length, 1, fp);
X    if (str_length != 0)
X    {   /* get the string table */
X        str_length -= 4;
X        strings = (char *)malloc(str_length);
X        if (strings == (char *)NULL)
X        {   /* enough memory? */
X            fprintf(stderr,"c++patch: out of memory for strings of '%s'\n",file);
X            exit(1);
X        }
X        fread(strings, str_length, 1, fp);
X    }
X
X    addr = addr1st = -1;
X    fseek(fp,file_header.f_symptr,0);
X    for (i = 0; i < file_header.f_nsyms; i++)
X    {   /* scan the symbol table looking for "special" names */
X        fread(&symbol, SYMESZ, 1, fp);
X        if (symbol.n_zeroes)
X        {   /* if name in symbol body */
X            strncpy(name,symbol.n_name,SYMNMLEN);
X            for (j = 0; j <= SYMNMLEN; j++)
X                if (!isascii(name[j]))
X                    name[j] = ' ';
X            j = SYMNMLEN;
X            while (j > 0 && name[j] == ' ')
X                name[j] = '\0';
X            symname = name;
X        }
X        else symname = &strings[symbol.n_offset-sizeof str_length];
X        if (strncmp("_GLOBAL_$$",symname,9) == 0)
X        {   /* if a name we might need to take a look at */
X            if (strcmp("_GLOBAL_$$LINK",symname) == 0)
X            {   /* patch up a link structure */
X                if (addr != -1)
X                {   /* if know something previous to patch */
X                    ptr = (long *)&data_section[addr-section_header.s_vaddr];
X                    if (debugmode)
X                        fprintf(stderr,"c++patch: zap link struct: addr=0x%08x, oldval=0x%08x, newval=0x%08x\n",
X                            addr,*ptr,symbol.n_value);
X                    *ptr = symbol.n_value;
X                }
X                else
X                {   /* found initial link */
X                    if (debugmode)
X                        fprintf(stderr,"c++patch: 1st link struct: addr=0x%08x\n",symbol.n_value);
X                    addr1st = symbol.n_value;
X                }
X                addr = symbol.n_value;
X            }
X        }
X        for (j = 0; j < symbol.n_numaux; j++)
X        {   /* any auxiliary entries? */
X            fread(&auxiliary, AUXESZ, 1, fp);
X        }
X        i += j;
X    }
X    fseek(fp,file_header.f_symptr,0);
X    for (i = 0; i < file_header.f_nsyms; i++)
X    {   /* scan the symbol table looking for "special" names */
X        fread(&symbol, SYMESZ, 1, fp);
X        if (symbol.n_zeroes)
X        {   /* if name in symbol body */
X            strncpy(name,symbol.n_name,SYMNMLEN);
X            for (j = 0; j <= SYMNMLEN; j++)
X                if (!isascii(name[j]))
X                    name[j] = ' ';
X            j = SYMNMLEN;
X            while (j > 0 && name[j] == ' ')
X                name[j] = '\0';
X            symname = name;
X        }
X        else symname = &strings[symbol.n_offset-sizeof str_length];
X        if (strncmp("_GLOBAL_$$",symname,9) == 0)
X        {   /* if a name we might need to take a look at */
X            if (strcmp("_GLOBAL_$$HEADER",symname) == 0)
X            {   /* patch the header */
X                ptr = (long *)&data_section[symbol.n_value-section_header.s_vaddr];
X                if (addr1st != -1)
X                {   /* set up initial link */
X                    if (debugmode)
X                        fprintf(stderr,"c++patch: zap header link: addr=0x%08x, oldval=0x%08x, newval=0x%08x\n",
X                            symbol.n_value,*ptr,addr1st);
X                    *ptr = addr1st;
X                }
X            }
X        }
X        for (j = 0; j < symbol.n_numaux; j++)
X        {   /* any auxiliary entries? */
X            fread(&auxiliary, AUXESZ, 1, fp);
X        }
X        i += j;
X    }
X
X    fclose(fp);
X    i = open(file,1);
X    if (i < 0)
X    {   /* did we get the file again? */
X        fprintf(stderr,"c++patch: can't reopen file for writing: '%s'\n",file);
X        exit(1);
X    }
X    lseek(i,section_header.s_scnptr,0);
X    if (write(i,data_section,section_header.s_size) != section_header.s_size)
X        fprintf(stderr,"c++patch: write of patched data section failed in '%s'\n",file);
X    lseek(i,0L,2);
X    close(i);
X}   /* end of patch */
END_OF_FILE
if test 6804 -ne `wc -c <'c++patch.c'`; then
    echo shar: \"'c++patch.c'\" unpacked with wrong size!
fi
# end of 'c++patch.c'
fi
if test -f 'exit.s' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'exit.s'\"
else
echo shar: Extracting \"'exit.s'\" \(244 characters\)
sed "s/^X//" >'exit.s' <<'END_OF_FILE'
X    .globl  exit
Xexit:
X    movel   __GLOBAL_$$HEADER,a5
X    tstl    a5
X    beq     0f
X4:  moveal  a5@(8),a0
X    tstl    a0
X    beq     5f
X    jsr     a0@
X5:  movel   a5@,a5
X    tstl    a5
X    bne     4b
X0:  jsr     __cleanup
X    jmp     __exit
END_OF_FILE
if test 244 -ne `wc -c <'exit.s'`; then
    echo shar: \"'exit.s'\" unpacked with wrong size!
fi
# end of 'exit.s'
fi
if test -f 'g++.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'g++.sh'\"
else
echo shar: Extracting \"'g++.sh'\" \(5695 characters\)
sed "s/^X//" >'g++.sh' <<'END_OF_FILE'
X#!/bin/sh
X#
X#   "Fake" g++ front-end for running on Apollo's with
X#       the gnu2coff object file converter
X#
X#   This will not work for DN10000's
X#
XGCC_EXEC_PREFIX=//dclemans/gnu/bin/
Xexport GCC_EXEC_PREFIX
Xvendor_cpu_os=apollo.mc68000.sys5.
Xexport vendor_cpu_os
X#STDINC=-I/user/apd_rls/cplusplus/ver/include
XSTDINC="-I//dclemans/gnu/src/libg++/g++-include -I//dclemans/gnu/include -I/usr/include"
XSTDLIB=//dclemans/gnu/bin/libg++.a
XGNU2COFF=//dclemans/local_user/dclemans/src/gnu2coff/gnu2coff
XCPATCH=//dclemans/local_user/dclemans/src/gnu2coff/c++patch
XPATCHLIB=//dclemans/local_user/dclemans/src/gnu2coff/patchlib
X
X#compargs=-D_BFMT__COFF=1
Xcompargs=
Xlinkargs=
Xtolink=
Xoutfile=a.out
Xversion=
X
Xdocomp=yes
Xdoasm=yes
Xdolink=yes
X
Xfor i
Xdo
X    if [ "$tolink" = "yes" ]
X    then
X        outfile=$i
X        linkargs="$linkargs $i"
X        tolink=no
X        continue
X    fi
X    case "$i" in
X        -ansi)
X            compargs="$compargs $i"
X            ;;
X        -a*)
X            compargs="$compargs $i"
X            ;;
X        -B*)
X            compargs="$compargs $i"
X            ;;
X        -c)
X            dolink=no
X            ;;
X        -C)
X            compargs="$compargs $i"
X            ;;
X        -d*)
X            compargs="$compargs $i"
X            ;;
X        -D*)
X            compargs="$compargs '$i'"
X            ;;
X        -E)
X            docomp=no
X            compargs="$compargs $i"
X            ;;
X        -f*)
X            compargs="$compargs $i"
X            ;;
X        -g*)
X            compargs="$compargs $i"
X            linkargs="$linkargs $i"
X            ;;
X        -I*)
X            compargs="$compargs $i"
X            ;;
X        -l*)
X            linkargs="$linkargs $i"
X            ;;
X        -L*)
X            linkargs="$linkargs $i"
X            ;;
X        -m*)
X            compargs="$compargs $i"
X            ;;
X        -M)
X            compargs="$compargs $i"
X            ;;
X        -nostdinc)
X            compargs="$compargs $i"
X            ;;
X        -nostdlib)
X            linkargs="$linkargs $i"
X            ;;
X        -o)
X            linkargs="$linkargs $i"
X            tolink=yes
X            ;;
X        -O)
X            compargs="$compargs $i"
X            ;;
X        -pedantic)
X            compargs="$compargs $i"
X            ;;
X        -pipe)
X            compargs="$compargs $i"
X            ;;
X        -p*)
X            compargs="$compargs $i"
X            ;;
X        -S)
X            doasm=no
X            compargs="$compargs $i"
X            ;;
X        -traditional)
X            compargs="$compargs $i"
X            ;;
X        -trigraphs)
X            compargs="$compargs $i"
X            ;;
X        -U*)
X            compargs="$compargs $i"
X            ;;
X        -v)
X            compargs="$compargs $i"
X            version=-v
X            ;;
X        -w)
X            compargs="$compargs $i"
X            ;;
X        -W*)
X            compargs="$compargs $i"
X            ;;
X        *.a)
X            linkargs="$linkargs $i"
X            ;;
X        *.c )
X            name=`basename "$i" .c`
X            linkargs="$linkargs $name.o"
X            `eval ${GCC_EXEC_PREFIX}g++ -c -nostdinc "$compargs" $STDINC $i`
X            rc=$?
X            if [ $rc != 0 ]
X            then
X                exit $rc
X            fi
X            if [ $docomp = yes -a $doasm = yes ]
X            then
X                $GNU2COFF $version -+ $name.o
X                rc=$?
X                if [ $rc != 0 ]
X                then
X                    rm -f ${name}_coff.o
X                    exit $rc
X                fi
X                mv ${name}_coff.o $name.o
X            fi
X            ;;
X        *.cc )
X            name=`basename "$i" .cc`
X            linkargs="$linkargs $name.o"
X            `eval ${GCC_EXEC_PREFIX}g++ -c -nostdinc "$compargs" $STDINC $i`
X            rc=$?
X            if [ $rc != 0 ]
X            then
X                exit $rc
X            fi
X            if [ $docomp = yes -a $doasm = yes ]
X            then
X                $GNU2COFF $version -+ $name.o
X                rc=$?
X                if [ $rc != 0 ]
X                then
X                    rm -f ${name}_coff.o
X                    exit $rc
X                fi
X                mv ${name}_coff.o $name.o
X            fi
X            ;;
X        *.cxx )
X            name=`basename "$i" .cxx`
X            linkargs="$linkargs $name.o"
X            `eval ${GCC_EXEC_PREFIX}g++ -c -nostdinc "$compargs" $STDINC $i`
X            rc=$?
X            if [ $rc != 0 ]
X            then
X                exit $rc
X            fi
X            if [ $docomp = yes -a $doasm = yes ]
X            then
X                $GNU2COFF $version -+ $name.o
X                rc=$?
X                if [ $rc != 0 ]
X                then
X                    rm -f ${name}_coff.o
X                    exit $rc
X                fi
X                mv ${name}_coff.o $name.o
X            fi
X            ;;
X        *.o)
X            linkargs="$linkargs $i"
X            ;;
X        *.s)
X            name=`basename "$i" .s`
X            linkargs="$linkargs $name.o"
X            if [ $doasm = yes ]
X            then
X                ${GCC_EXEC_PREFIX}a68 -o $name.o $i
X                rc = $?
X                if [ $rc != 0 ]
X                then
X                    exit $rc
X                fi
X                $GNU2COFF $version -+ $name.o
X                rc=$?
X                if [ $rc != 0 ]
X                then
X                    rm -f ${name}_coff.o
X                    exit $rc
X                fi
X                mv ${name}_coff.o $name.o
X            fi
X            ;;
X    esac
Xdone
X
Xif [ $docomp = no -o $doasm = no -o $dolink = no ]
Xthen
X    exit 0
Xfi
X
Xcc $linkargs $STDLIB ${GCC_EXEC_PREFIX}gnulib $PATCHLIB
Xrc=$?
Xif [ $rc != 0 ]
Xthen
X    exit $rc
Xfi
X$CPATCH $version $outfile
X
Xexit $?
END_OF_FILE
if test 5695 -ne `wc -c <'g++.sh'`; then
    echo shar: \"'g++.sh'\" unpacked with wrong size!
fi
chmod +x 'g++.sh'
# end of 'g++.sh'
fi
if test -f 'gcc.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gcc.sh'\"
else
echo shar: Extracting \"'gcc.sh'\" \(3972 characters\)
sed "s/^X//" >'gcc.sh' <<'END_OF_FILE'
X#!/bin/sh
X#
X#   "Fake" gcc front-end for running on Apollo's with
X#       the gnu2coff object file converter
X#
X#   This will not work for DN10000's
X#
XGCC_EXEC_PREFIX=//dclemans/gnu/bin/
XGNU2COFF=//dclemans/local_user/dclemans/src/gnu2coff/gnu2coff
Xexport GCC_EXEC_PREFIX
X
Xcompargs="-D_BFMT__COFF=1 -I//dclemans/gnu/include"
Xlinkargs=
Xtolink=
Xversion=
X
Xdocomp=yes
Xdoasm=yes
Xdolink=yes
X
Xfor i
Xdo
X    if [ "$tolink" = "yes" ]
X    then
X        linkargs="$linkargs $i"
X        tolink=no
X        continue
X    fi
X    case "$i" in
X        -ansi)
X            compargs="$compargs $i"
X            ;;
X        -a*)
X            compargs="$compargs $i"
X            ;;
X        -B*)
X            compargs="$compargs $i"
X            ;;
X        -c)
X            dolink=no
X            ;;
X        -C)
X            compargs="$compargs $i"
X            ;;
X        -d*)
X            compargs="$compargs $i"
X            ;;
X        -D*)
X            compargs="$compargs '$i'"
X            ;;
X        -E)
X            docomp=no
X            compargs="$compargs $i"
X            ;;
X        -f*)
X            compargs="$compargs $i"
X            ;;
X        -g*)
X            compargs="$compargs $i"
X            linkargs="$linkargs $i"
X            ;;
X        -I*)
X            compargs="$compargs $i"
X            ;;
X        -l*)
X            linkargs="$linkargs $i"
X            ;;
X        -L*)
X            linkargs="$linkargs $i"
X            ;;
X        -m*)
X            compargs="$compargs $i"
X            ;;
X        -M)
X            compargs="$compargs $i"
X            ;;
X        -nostdinc)
X            compargs="$compargs $i"
X            ;;
X        -nostdlib)
X            linkargs="$linkargs $i"
X            ;;
X        -o)
X            linkargs="$linkargs $i"
X            tolink=yes
X            ;;
X        -O)
X            compargs="$compargs $i"
X            ;;
X        -pedantic)
X            compargs="$compargs $i"
X            ;;
X        -pipe)
X            compargs="$compargs $i"
X            ;;
X        -p*)
X            compargs="$compargs $i"
X            ;;
X        -S)
X            doasm=no
X            compargs="$compargs $i"
X            ;;
X        -traditional)
X            compargs="$compargs $i"
X            ;;
X        -trigraphs)
X            compargs="$compargs $i"
X            ;;
X        -U*)
X            compargs="$compargs $i"
X            ;;
X        -v)
X            compargs="$compargs $i"
X            version=-v
X            ;;
X        -w)
X            compargs="$compargs $i"
X            ;;
X        -W*)
X            compargs="$compargs $i"
X            ;;
X        *.a)
X            linkargs="$linkargs $i"
X            ;;
X        *.c)
X            name=`basename "$i" .c`
X            linkargs="$linkargs $name.o"
X            `eval ${GCC_EXEC_PREFIX}gcc -c "$compargs" $i`
X            rc=$?
X            if [ $rc != 0 ]
X            then
X                exit $rc
X            fi
X            if [ $docomp = yes -a $doasm = yes ]
X            then
X                $GNU2COFF $version $name.o
X                rc=$?
X                if [ $rc != 0 ]
X                then
X                    rm -f ${name}_coff.o
X                    exit $rc
X                fi
X                mv ${name}_coff.o $name.o
X            fi
X            ;;
X        *.o)
X            linkargs="$linkargs $i"
X            ;;
X        *.s)
X            name=`basename "$i" .s`
X            linkargs="$linkargs $name.o"
X            if [ $doasm = yes ]
X            then
X                ${GCC_EXEC_PREFIX}a68 -o $name.o $i
X                rc=$?
X                if [ $rc != 0 ]
X                then
X                    exit $rc
X                fi
X                $GNU2COFF $version $name.o
X                rc=$?
X                if [ $rc != 0 ]
X                then
X                    rm -f ${name}_coff.o
X                    exit $rc
X                fi
X                mv ${name}_coff.o $name.o
X            fi
X            ;;
X    esac
Xdone
X
Xif [ $docomp = no -o $doasm = no -o $dolink = no ]
Xthen
X    exit 0
Xfi
X
Xcc $linkargs ${GCC_EXEC_PREFIX}gnulib
X
Xexit $?
END_OF_FILE
if test 3972 -ne `wc -c <'gcc.sh'`; then
    echo shar: \"'gcc.sh'\" unpacked with wrong size!
fi
chmod +x 'gcc.sh'
# end of 'gcc.sh'
fi
if test -f 'gnu2coff.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gnu2coff.h'\"
else
echo shar: Extracting \"'gnu2coff.h'\" \(9327 characters\)
sed "s/^X//" >'gnu2coff.h' <<'END_OF_FILE'
X/*
X * GNU->COFF support definitions
X */
X
Xextern int     show_headers;
Xextern int     show_symbols;
Xextern int     show_relocation;
Xextern int     show_code;
Xextern int     show_func_structure;
Xextern int     show_coff_code;
Xextern int     show_coff_relocation;
Xextern int     try_sym_conversion;
Xextern int     cplusplus_mode;
Xextern int     cplusplus_main;
Xextern long    gen_stack_size;
Xextern char    *version;
X
Xextern long    cplusplus_ctor;
Xextern long    cplusplus_dtor;
X
X/*
X * The order we write out COFF sections
X */
X#define STEXT   1
X#define SDATA   2
X#define SAPTV   3
X#define SBSS    4
X#define SSRI    5
X#define SMIR    6
X#define S_COUNT 6
X
X#define SGLOBAL 1000
Xextern long     cplusplus_gsym;
X
X/* m68k specific */
X
X#define JUMP_INSTR      0x4ef9              
X#define BSR_INSTR       0x61ff
X#define JSR_INSTR       0x4eb9
X#define PEA_INSTR       0x4879
X#define BTST_INSTR      0x0839
X#define MOVEIL_INSTR    0x23fc
X#define CMPIL_INSTR     0x0cb9
X#define CMPIL6_INSTR    0x0cae
X#define CLR_INSTR       0x42b9
X#define MOVEMM0_INSTR   0x23f9
X#define TSTW_INSTR      0x4a79
X#define TST_INSTR       0x4ab9
X#define ANDW_INSTR      0x0279
X#define MOVEDL_INSTR    0x23f2
X#define MOVEAL_INSTR    0x23f0
X
X#define LEA0_INSTR      0x41f9              /* lea  name,a? */
X#define LEA1_INSTR      0x43f9
X#define LEA2_INSTR      0x45f9
X#define LEA3_INSTR      0x47f9
X#define LEA4_INSTR      0x49f9
X#define LEA5_INSTR      0x4bf9
X#define LEA6_INSTR      0x4df9
X#define LEA7_INSTR      0x4ff9
X
X#define MOVE0_INSTR     0x2039              /* move.l   name,d? */
X#define MOVE1_INSTR     0x2239
X#define MOVE2_INSTR     0x2439
X#define MOVE3_INSTR     0x2639
X#define MOVE4_INSTR     0x2839
X#define MOVE5_INSTR     0x2a39
X#define MOVE6_INSTR     0x2c39
X#define MOVE7_INSTR     0x2e39
X#define MOVEA0_INSTR    0x2079              /* move.l   name,a? */
X#define MOVEA1_INSTR    0x2279
X#define MOVEA2_INSTR    0x2479
X#define MOVEA3_INSTR    0x2679
X#define MOVEA4_INSTR    0x2879
X#define MOVEA5_INSTR    0x2a79
X#define MOVEA6_INSTR    0x2c79
X#define MOVEA7_INSTR    0x2e79
X#define MOVEMA0_INSTR   0x2139              /* move.l   name,-(a?) */
X#define MOVEMA1_INSTR   0x2339
X#define MOVEMA2_INSTR   0x2539
X#define MOVEMA3_INSTR   0x2739
X#define MOVEMA4_INSTR   0x2939
X#define MOVEMA5_INSTR   0x2b39
X#define MOVEMA6_INSTR   0x2d39
X#define MOVEMA7_INSTR   0x2f39
X#define MOVEAA0_INSTR   0x23c8              /* move.l   a?,name */
X#define MOVEAA1_INSTR   0x23c9
X#define MOVEAA2_INSTR   0x23ca
X#define MOVEAA3_INSTR   0x23cb
X#define MOVEAA4_INSTR   0x23cc
X#define MOVEAA5_INSTR   0x23cd
X#define MOVEAA6_INSTR   0x23ce
X#define MOVEAA7_INSTR   0x23cf
X#define MOVED0_INSTR    0x23c0              /* move.l   d?,name */
X#define MOVED1_INSTR    0x23c1
X#define MOVED2_INSTR    0x23c2
X#define MOVED3_INSTR    0x23c3
X#define MOVED4_INSTR    0x23c4
X#define MOVED5_INSTR    0x23c5
X#define MOVED6_INSTR    0x23c6
X#define MOVED7_INSTR    0x23c7
X#define MOVEDI0_INSTR   0x203c              /* move.l   #name,d? */
X#define MOVEDI1_INSTR   0x223c
X#define MOVEDI2_INSTR   0x243c
X#define MOVEDI3_INSTR   0x263c
X#define MOVEDI4_INSTR   0x283c
X#define MOVEDI5_INSTR   0x2a3c
X#define MOVEDI6_INSTR   0x2c3c
X#define MOVEDI7_INSTR   0x2e3c
X#define MOVEWD0_INSTR   0x3039              /* move.w   name,d? */
X#define MOVEWD1_INSTR   0x3239
X#define MOVEWD2_INSTR   0x3439
X#define MOVEWD3_INSTR   0x3639
X#define MOVEWD4_INSTR   0x3839
X#define MOVEWD5_INSTR   0x3a39
X#define MOVEWD6_INSTR   0x3c39
X#define MOVEWD7_INSTR   0x3e39
X#define MOVEWA0_INSTR   0x3079              /* move.w   name,a? */
X#define MOVEWA1_INSTR   0x3279
X#define MOVEWA2_INSTR   0x3479
X#define MOVEWA3_INSTR   0x3679
X#define MOVEWA4_INSTR   0x3879
X#define MOVEWA5_INSTR   0x3a79
X#define MOVEWA6_INSTR   0x3c79
X#define MOVEWA7_INSTR   0x3e79
X
X#define CMP0_INSTR      0xb0b9              /* cmp.l    name,d? */
X#define CMP1_INSTR      0xb2b9
X#define CMP2_INSTR      0xb4b9
X#define CMP3_INSTR      0xb6b9
X#define CMP4_INSTR      0xb8b9
X#define CMP5_INSTR      0xbab9
X#define CMP6_INSTR      0xbcb9
X#define CMP7_INSTR      0xbeb9
X#define CMPA0_INSTR     0xb1fc              /* cmpa.l   #name,a? */
X#define CMPA1_INSTR     0xb3fc
X#define CMPA2_INSTR     0xb5fc
X#define CMPA3_INSTR     0xb7fc
X#define CMPA4_INSTR     0xb9fc
X#define CMPA5_INSTR     0xbbfc
X#define CMPA6_INSTR     0xbdfc
X#define CMPA7_INSTR     0xbffc
X#define CMPAA0_INSTR    0xb1f9              /* cmpa.l   name,a? */
X#define CMPAA1_INSTR    0xb3f9
X#define CMPAA2_INSTR    0xb5f9
X#define CMPAA3_INSTR    0xb7f9
X#define CMPAA4_INSTR    0xb9f9
X#define CMPAA5_INSTR    0xbbf9
X#define CMPAA6_INSTR    0xbdf9
X#define CMPAA7_INSTR    0xbff9
X
X#define ADDQ0_INSTR     0x5079              /* addq.w   #data,name */
X#define ADDQ1_INSTR     0x5279
X#define ADDQ2_INSTR     0x5479
X#define ADDQ3_INSTR     0x5679
X#define ADDQ4_INSTR     0x5879
X#define ADDQ5_INSTR     0x5a79
X#define ADDQ6_INSTR     0x5c79
X#define ADDQ7_INSTR     0x5e79
X#define SUBQ0_INSTR     0x5179              /* subq.w   #data,name */
X#define SUBQ1_INSTR     0x5379
X#define SUBQ2_INSTR     0x5579
X#define SUBQ3_INSTR     0x5779
X#define SUBQ4_INSTR     0x5979
X#define SUBQ5_INSTR     0x5b79
X#define SUBQ6_INSTR     0x5d79
X#define SUBQ7_INSTR     0x5f79
X#define ADDQL0_INSTR    0x50b9              /* addq.l   #data,name */
X#define ADDQL1_INSTR    0x52b9
X#define ADDQL2_INSTR    0x54b9
X#define ADDQL3_INSTR    0x56b9
X#define ADDQL4_INSTR    0x58b9
X#define ADDQL5_INSTR    0x5ab9
X#define ADDQL6_INSTR    0x5cb9
X#define ADDQL7_INSTR    0x5eb9
X#define SUBQL0_INSTR    0x51b9              /* subq.l   #data,name */
X#define SUBQL1_INSTR    0x53b9
X#define SUBQL2_INSTR    0x55b9
X#define SUBQL3_INSTR    0x57b9
X#define SUBQL4_INSTR    0x59b9
X#define SUBQL5_INSTR    0x5bb9
X#define SUBQL6_INSTR    0x5db9
X#define SUBQL7_INSTR    0x5fb9
X
X#define ADD0_INSTR      0xd0b9              /* add.l    ... */
X#define ADD1_INSTR      0xd2b9
X#define ADD2_INSTR      0xd4b9
X#define ADD3_INSTR      0xd6b9
X#define ADD4_INSTR      0xd8b9
X#define ADD5_INSTR      0xdab9
X#define ADD6_INSTR      0xdcb9
X#define ADD7_INSTR      0xdeb9
X#define ADDR0_INSTR     0xd1b9
X#define ADDR1_INSTR     0xd3b9
X#define ADDR2_INSTR     0xd5b9
X#define ADDR3_INSTR     0xd7b9
X#define ADDR4_INSTR     0xd9b9
X#define ADDR5_INSTR     0xdbb9
X#define ADDR6_INSTR     0xddb9
X#define ADDR7_INSTR     0xdfb9
X
X#define SUB0_INSTR      0x90b9              /* sub.l    ... */
X#define SUB1_INSTR      0x92b9
X#define SUB2_INSTR      0x94b9
X#define SUB3_INSTR      0x96b9
X#define SUB4_INSTR      0x98b9
X#define SUB5_INSTR      0x9ab9
X#define SUB6_INSTR      0x9cb9
X#define SUB7_INSTR      0x9eb9
X#define SUBR0_INSTR     0x91b9
X#define SUBR1_INSTR     0x93b9
X#define SUBR2_INSTR     0x95b9
X#define SUBR3_INSTR     0x97b9
X#define SUBR4_INSTR     0x99b9
X#define SUBR5_INSTR     0x9bb9
X#define SUBR6_INSTR     0x9db9
X#define SUBR7_INSTR     0x9fb9
X
X#define ADDI0_INSTR     0x0680              /* addi.l   #data,d? */
X#define ADDI1_INSTR     0x0681
X#define ADDI2_INSTR     0x0682
X#define ADDI3_INSTR     0x0683
X#define ADDI4_INSTR     0x0684
X#define ADDI5_INSTR     0x0685
X#define ADDI6_INSTR     0x0686
X#define ADDI7_INSTR     0x0687
X
X#define SUBI0_INSTR     0x0480              /* subi.l   #data,d? */
X#define SUBI1_INSTR     0x0481
X#define SUBI2_INSTR     0x0482
X#define SUBI3_INSTR     0x0483
X#define SUBI4_INSTR     0x0484
X#define SUBI5_INSTR     0x0485
X#define SUBI6_INSTR     0x0486
X#define SUBI7_INSTR     0x0487
X
X#define CMPID0_INSTR    0x0c80              /* cmpi.l   #data,d? */
X#define CMPID1_INSTR    0x0c81
X#define CMPID2_INSTR    0x0c82
X#define CMPID3_INSTR    0x0c83
X#define CMPID4_INSTR    0x0c84
X#define CMPID5_INSTR    0x0c85
X#define CMPID6_INSTR    0x0c86
X#define CMPID7_INSTR    0x0c87
X#define CMPIA0_INSTR    0x0c90              /* cmpi.l   #data,a? */
X#define CMPIA1_INSTR    0x0c91
X#define CMPIA2_INSTR    0x0c92
X#define CMPIA3_INSTR    0x0c93
X#define CMPIA4_INSTR    0x0c94
X#define CMPIA5_INSTR    0x0c95
X#define CMPIA6_INSTR    0x0c96
X#define CMPIA7_INSTR    0x0c97
X
X#define MOVEAI0_INSTR   0x21b9              /* move.l   name,x(a?) */
X#define MOVEAI1_INSTR   0x23b9
X#define MOVEAI2_INSTR   0x25b9
X#define MOVEAI3_INSTR   0x27b9
X#define MOVEAI4_INSTR   0x29b9
X#define MOVEAI5_INSTR   0x2bb9
X#define MOVEAI6_INSTR   0x2db9
X#define MOVEAI7_INSTR   0x2fb9
X#define MOVEAAI0_INSTR  0x2179
X#define MOVEAAI1_INSTR  0x2379
X#define MOVEAAI2_INSTR  0x2579
X#define MOVEAAI3_INSTR  0x2779
X#define MOVEAAI4_INSTR  0x2979
X#define MOVEAAI5_INSTR  0x2b79
X#define MOVEAAI6_INSTR  0x2d79
X#define MOVEAAI7_INSTR  0x2f79
X#define MOVEWAAI0_INSTR 0x3179
X#define MOVEWAAI1_INSTR 0x3379
X#define MOVEWAAI2_INSTR 0x3579
X#define MOVEWAAI3_INSTR 0x3779
X#define MOVEWAAI4_INSTR 0x3979
X#define MOVEWAAI5_INSTR 0x3b79
X#define MOVEWAAI6_INSTR 0x3d79
X#define MOVEWAAI7_INSTR 0x3f79
X#define MOVEIA0_INSTR   0x217c              /* move.l   #name,x(a?) */
X#define MOVEIA1_INSTR   0x237c
X#define MOVEIA2_INSTR   0x257c
X#define MOVEIA3_INSTR   0x277c
X#define MOVEIA4_INSTR   0x297c
X#define MOVEIA5_INSTR   0x2b7c
X#define MOVEIA6_INSTR   0x2d7c
X#define MOVEIA7_INSTR   0x2f7c
X#define MOVEMAI0_INSTR  0x23e8              /* move.l   x(a?),name */
X#define MOVEMAI1_INSTR  0x23e9
X#define MOVEMAI2_INSTR  0x23ea
X#define MOVEMAI3_INSTR  0x23eb
X#define MOVEMAI4_INSTR  0x23ec
X#define MOVEMAI5_INSTR  0x23ed
X#define MOVEMAI6_INSTR  0x23ee
X#define MOVEMAI7_INSTR  0x23ef
END_OF_FILE
if test 9327 -ne `wc -c <'gnu2coff.h'`; then
    echo shar: \"'gnu2coff.h'\" unpacked with wrong size!
fi
# end of 'gnu2coff.h'
fi
if test -f 'main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'main.c'\"
else
echo shar: Extracting \"'main.c'\" \(2745 characters\)
sed "s/^X//" >'main.c' <<'END_OF_FILE'
X/*
X * Convert A.OUT (GNU) format files to Apollo COFF format files
X */
X#include <stdio.h>
X
Xint     show_headers = 0;
Xint     show_symbols = 0;
Xint     show_relocation = 0;
Xint     show_code = 0;
Xint     show_coff_code = 0;
Xint     show_coff_relocation = 0;
Xint     show_func_structure = 0;
Xint     try_sym_conversion = 0;
Xint     cplusplus_mode = 0;
Xint     cplusplus_main = 0;
Xlong    cplusplus_ctor = 0;
Xlong    cplusplus_dtor = 0;
Xlong    cplusplus_gsym = 0;
Xlong    gen_stack_size = 512L * 1024L;
Xchar    *version = "GNU->COFF object file conversion: version 0.6";
X
Xextern char *coff_findsym();
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X    register int i;
X    register char *p;
X
X    for (i = 1; i < argc; i++)
X    {   /* go through our args */
X        if (argv[i][0] == '-') for (p = &argv[i][1]; *p; p++)
X        {   /* if a switch, what switch? */
X            switch (*p)
X            {   /* find out */
X                case '+':
X                    cplusplus_mode++;
X                    break;
X                case 'g':
X                    try_sym_conversion++;
X                    break;
X                case 'h':
X                    show_headers++;
X                    break;
X                case 's':
X                    show_symbols++;
X                    break;
X                case 'r':
X                    show_relocation++;
X                    break;
X                case 'R':
X                    show_coff_relocation++;
X                    break;
X                case 'i':
X                    show_code++;
X                    break;
X                case 'f':
X                    show_func_structure++;
X                    break;
X                case 'I':
X                    show_coff_code++;
X                    break;
X                case 'S':
X                    gen_stack_size = (long)atoi(argv[++i]) * 1024L;
X                    break;
X                case 'v':
X                    fprintf(stderr,"gnu2coff: %s\n",version);
X                    break;
X                default:
X                    fprintf(stderr,"gnu2coff: unknown switch: argv[i]=%s\n",argv[i]);
X                    exit(1);
X            }
X        }
X        else    doConversion(argv[i]);
X    }
X
X    exit(0);
X}   /* end of main */
X
Xdisasm(msg,memstart,memsize,viraddr)
Xchar *msg;
Xchar *memstart;
Xlong memsize;
Xlong viraddr;
X{
X    register long i;
X    register char *p;
X
X    printf("\n** %s\n",msg);
X    for (i = 0; i < memsize; )
X    {   /* while instrs to print */
X        p = coff_findsym(viraddr+i);
X        if (p != (char *)NULL)
X        {   /* also print the symbol */
X            printf("%08X                   %s:\n",viraddr+i,p);
X        }
X        i += decode(&memstart[i],&memstart[memsize],viraddr+i) * sizeof(short);
X    }
X}   /* end of disasm */
END_OF_FILE
if test 2745 -ne `wc -c <'main.c'`; then
    echo shar: \"'main.c'\" unpacked with wrong size!
fi
# end of 'main.c'
fi
if test -f 'malloc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'malloc.c'\"
else
echo shar: Extracting \"'malloc.c'\" \(8278 characters\)
sed "s/^X//" >'malloc.c' <<'END_OF_FILE'
X/*
X * Dynamic Memory Allocation Routines
X *
X *  malloc  - allocate a block of memory
X *      char *malloc(unsigned size);
X *  char *lmalloc(unsigned long size);
X *
X *  calloc  - allocate a block of memory, clearing it to zero first
X *      char *calloc(unsigned unitsize,unsigned nunits);
X *  char *lcalloc(unsigned long unitsize,unsigned long nunits);
X *
X *  realloc - reallocate a block of memory, making it smaller or larger
X *  char *realloc(char *ptr,unsigned size);
X *  char *lrealloc(char *ptr,unsigned long size);
X *
X *  free    - free a block of memory
X *      free(char *ptr);
X *
X * Dave Clemans, 1/88
X *
X * $Id: malloc.c,v 1.3 89/02/20 20:09:31 dclemans Exp $
X *
X * $Log:	malloc.c,v $
X * Revision 1.3  89/02/20  20:09:31  dclemans
X * Add RCS identifiers
X * 
X */
X#include <stdio.h>
X#ifndef unix
X#include <osbind.h>
X#endif
X
X#ifdef  unix
Xextern char *sbrk();
X#endif
X
Xextern char *malloc(),*lmalloc();
Xextern char *calloc(),*lcalloc();
Xextern char *realloc(),*lrealloc();
Xextern free();
X
X/*
X * Set up the arena we work in
X */
X#define HUNK    (18L*1024L)         /* basic hunk size for allocation */
X
Xstruct memblock
X{
X    long    size;
X    struct memblock *next;
X};
X
Xstatic struct memblock *arena = (struct memblock *)NULL;
Xstatic struct memblock *arenaTail = (struct memblock *)NULL;
Xlong poolSize = 0;
Xlong mallocTotal = 0;
Xlong mallocHighWater = 0;
X
X/*
X * The user-visible routines are merely shells; they get memory
X * by calling the following routines.  They are declared as
X * "long *" because they guarantee returning a memory block
X * with a starting address suitable for storing a long.
X */
Xstatic long *memget();
Xstatic memput();
X
X/*
X * Get a block of memory
X */
Xchar *malloc(size)
Xunsigned size;
X{
X    return lmalloc((unsigned long)size);
X}   /* end of malloc */
X
Xchar *lmalloc(size)
Xunsigned long size;
X{
X    register long *mem;
X    register long rsize;
X
X    rsize = size + sizeof(long);
X    rsize = ((rsize + (long)sizeof(long) - 1L) / (long)sizeof(long)) * (long)sizeof(long);
X    mem = memget(rsize);
X    if (mem == (long *)NULL)
X        return (char *)NULL;
X    *mem++ = rsize;
X    mallocTotal += rsize;
X    if (mallocTotal > mallocHighWater)
X        mallocHighWater = mallocTotal;
X    return (char *)mem;
X}   /* end of lmalloc */
X
X/*
X * Get a block of memory, clearing it to nulls
X */
Xchar *calloc(unitsize,nunits)
Xunsigned unitsize;
Xunsigned nunits;
X{
X    return lcalloc((unsigned long)unitsize,(unsigned long)nunits);
X}   /* end of calloc */
X
Xchar *lcalloc(unitsize,nunits)
Xunsigned long unitsize;
Xunsigned long nunits;
X{
X    register long rsize,size;
X    register char *ptr;
X    register long *mem;
X
X    size = (long)unitsize * (long)nunits;
X    rsize = size + sizeof(long);
X    rsize = ((rsize + (long)sizeof(long) - 1L) / (long)sizeof(long)) * (long)sizeof(long);
X    mem = memget(rsize);
X    ptr = (char *)mem;
X    if (mem == (long *)NULL)
X        return (char *)NULL;
X    while (size--)
X        *ptr++ = '\0';
X    *mem++ = rsize;
X    mallocTotal += rsize;
X    if (mallocTotal > mallocHighWater)
X        mallocHighWater = mallocTotal;
X    return (char *)mem;
X}   /* end of lcalloc */
X
X/*
X * Reallocate a block of memory
X */
Xchar *realloc(ptr,size)
Xchar *ptr;
Xunsigned size;
X{
X    return lrealloc(ptr,(unsigned long)size);
X}   /* end of realloc */
X
Xchar *lrealloc(ptr,size)
Xchar *ptr;
Xunsigned long size;
X{
X    long *mem;
X    register long actual_size;
X    register char *newptr;
X    register char *to,*from;
X
X    mem = (long *)ptr;
X    size = ((size + (long)sizeof(long) - 1L) / (long)sizeof(long)) * (long)sizeof(long);
X    actual_size = *--mem;
X
X    if ((size + sizeof(long) + sizeof(struct memblock)) < actual_size)
X    {   /* if the block is being shrunk */
X        newptr = ptr + size;
X        memput(newptr,actual_size - size - sizeof(long));
X        mallocTotal -= (actual_size - size - sizeof(long));
X        *mem = size + sizeof(long);
X        return ptr;
X    }
X    else
X    {   /* the block is being expanded */
X        newptr = (char *)memget(size + (long)sizeof(long));
X        if (newptr == (char *)NULL)
X            return newptr;
X        mallocTotal += size + sizeof(long);
X        if (mallocTotal > mallocHighWater)
X            mallocHighWater = mallocTotal;
X        actual_size -= sizeof(long);
X        to = newptr + sizeof(long);
X        from = ptr;
X        while (actual_size--)
X            *to++ = *from++;
X        free(ptr);
X        mem = (long *)newptr;
X        *mem++ = size + (long)sizeof(long);
X        return (char *)mem;
X    }
X}   /* end of lrealloc */
X
X/*
X * Free a block of memory
X */
Xfree(ptr)
Xchar *ptr;
X{
X    register long *mem;
X    register long size;
X
X    mem = (long *)ptr;
X    size = *--mem;
X    memput((long *)mem,size);
X    mallocTotal -= size;
X}   /* end of free */
X
X/*
X * Finally! we reach the heart of this memory allocation package
X */
X
X/*
X * Allocate a block of memory
X */
Xstatic long *memget(size)
Xlong size;
X{
X    register struct memblock *mem,*memp;
X    register char *fptr;
X    register long toAlloc;
X    long *ptr;
X
X    if (size < sizeof(struct memblock))
X        size = sizeof(struct memblock);
X
X    memp = (struct memblock *)NULL;
X    for (mem = arena; mem != (struct memblock *)NULL; mem = mem->next)
X    {   /* look for a block with enough space */
X        if (mem->size == size || mem->size >= (size + sizeof(struct memblock)))
X        {   /* we've found some memory; unlink and return it */
X            if (memp == (struct memblock *)NULL)
X                arena = mem->next;
X            else
X                memp->next = mem->next;
X            if (mem == arenaTail)
X                arenaTail = memp;
X            if (mem->size > size)
X            {   /* if we need to split this block */
X                fptr = (char *)mem;
X                fptr += size;
X                memput((long *)fptr,mem->size - size);
X            }
X            return (long *)mem;
X        }
X        memp = mem;
X    }
X
X    /* no block with enough space; try to get more memory from system */
X    /* if that fails, we signal no memory */
X
X    toAlloc = (size < HUNK) ? HUNK : (((size + HUNK - 1L) / HUNK) * HUNK);
X#ifdef  unix
X    ptr = (long *)sbrk(toAlloc);
X#else
X    ptr = (long *)Malloc(toAlloc);
X#endif
X    if (ptr == (long *)NULL)
X        return (long *)NULL;
X    poolSize += toAlloc;
X    memput(ptr,toAlloc);
X    return memget(size);
X}   /* end of memget */
X
X/*
X * Free a block of memory
X */
Xstatic memput(ptr,size)
Xlong *ptr;
Xlong size;
X{
X    register struct memblock *mem,*memp;
X    register struct memblock *new;
X
X    if (size < sizeof(struct memblock))
X        size = sizeof(struct memblock);
X
X    memp = (struct memblock *)NULL;
X    for (mem = arena; mem != (struct memblock *)NULL; mem = mem->next)
X    {   /* look for place to put this freed block */
X        if (ptr < (long *)mem)
X        {   /* then we put the block before this block */
X            new = (struct memblock *)ptr;
X            new->size = size;
X            new->next = mem;
X            if (mem == arena)
X                arena = new;
X            else
X                memp->next = new;
X            /* now try to compact new block backwards and forwards */
X            if ((char *)new + size == (char *)mem)
X            {   /* forwards compaction */
X                new->size += mem->size;
X                new->next = mem->next;
X        if (arenaTail == mem)
X            arenaTail = new;
X            }
X            if (memp != (struct memblock *)NULL &&
X               ((char *)memp + memp->size == (char *)new))
X            {   /* backwards compaction */
X                memp->size += new->size;
X                memp->next = new->next;
X                if (arenaTail == new)
X                    arenaTail = memp;
X            }
X            return;
X        }
X        memp = mem;
X    }
X
X    /* if reach here, just tack block to end of list */
X    mem = (struct memblock *)ptr;
X    mem->size = size;
X    mem->next = (struct memblock *)NULL;
X    if (arena == (struct memblock *)NULL)
X        arena = arenaTail = mem;
X    else
X    {   /* tack onto end */
X        /* try compacting first */
X        if ((char *)arenaTail + arenaTail->size == (char *)mem)
X            arenaTail->size += mem->size;
X        else
X        {   /* really tack onto end */
X            arenaTail->next = mem;
X            arenaTail = mem;
X        }
X    }
X}   /* end of memput */
END_OF_FILE
if test 8278 -ne `wc -c <'malloc.c'`; then
    echo shar: \"'malloc.c'\" unpacked with wrong size!
fi
# end of 'malloc.c'
fi
if test -f 'tm-apollo.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tm-apollo.h'\"
else
echo shar: Extracting \"'tm-apollo.h'\" \(3347 characters\)
sed "s/^X//" >'tm-apollo.h' <<'END_OF_FILE'
X/* Definitions of target machine for GNU compiler.  Apollo 68000/68020 version.
X   Copyright (C) 1987, 1988 Free Software Foundation, Inc.
X
XThis file is part of GNU CC.
X
XGNU CC is free software; you can redistribute it and/or modify
Xit under the terms of the GNU General Public License as published by
Xthe Free Software Foundation; either version 1, or (at your option)
Xany later version.
X
XGNU CC is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
XGNU General Public License for more details.
X
XYou should have received a copy of the GNU General Public License
Xalong with GNU CC; see the file COPYING.  If not, write to
Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
X
X#define DOLLARS_IN_IDENTIFIERS 1
X
X#include "tm-m68k.h"
X#define USG_TARGET
X
X#define NO_GNU_LD
X
X#ifdef CPLUSPLUS
X#define CTORS_SECTION_ASM_OP	".section\t.ctors,\"x\""
X#define DTORS_SECTION_ASM_OP	".section\t.dtors,\"x\""
X#endif
X
X/* Use crtn+.o as a closing file and use the special linker.def file as a linker
X   directives file.
X
X   Note that standard System V COFF linkers treat the first input file which
X   seems to be a text file as a "linker directives" file.  If this doesn't
X   seem to work, check your linker manual to see if there is some other
X   convention for specifying the linker directives file.
X*/
X
X#ifndef CPLUSPLUS
X
X/* All system V systems can use crt1.o as a start file and crtn.o as a end file.  */
X
X#ifndef apollo
X#define STARTFILE_SPEC  \
X  "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
X
X#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} crtn.o%s"
X#else
X#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}"
X#define LIB_SPEC ""
X#endif
X
X#else
X
X/* Use crt1+.o as a startup file and crtn+.o as a closing file.  */
X
X#define STARTFILE_SPEC  \
X  "linker.def%s %{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1+.o%s}}"
X
X#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} crtn+.o%s"
X
X#endif
X/* See tm-m68k.h.  7 means 68020 with 68881.  */
X
X#ifndef TARGET_DEFAULT
X#define TARGET_DEFAULT 7
X#endif
X
X/* Define __HAVE_FPA__ or __HAVE_68881__ in preprocessor,
X   according to the -m flags.
X   This will control the use of inline 68881 insns in certain macros.
X   Also inform the program which CPU this is for.  */
X
X#if TARGET_DEFAULT & 02
X
X/* -m68881 is the default */
X#define CPP_SPEC \
X"%{!msoft-float:%{mfpa:-D__HAVE_FPA__ }%{!mfpa:-D__HAVE_68881__ }}\
X%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
X
X#else
X#if TARGET_DEFAULT & 0100
X
X/* -mfpa is the default */
X#define CPP_SPEC \
X"%{!msoft-float:%{m68881:-D__HAVE_68881__ }%{!m68881:-D__HAVE_FPA__ }}\
X%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
X
X#else
X
X/* -msoft-float is the default */
X#define CPP_SPEC \
X"%{m68881:-D__HAVE_68881__ }%{mfpa:-D__HAVE_FPA__ }\
X%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
X
X#endif
X#endif
X
X/* Names to predefine in the preprocessor for this target machine.  */
X
X#define CPP_PREDEFINES "-Dm68k -Dapollo -Dunix"
X
X/* Every structure or union's size must be a multiple of 2 bytes.  */
X
X#define STRUCTURE_SIZE_BOUNDARY 16
X
X/* This is BSD, so it wants DBX format.  */
X
X#define DBX_DEBUGGING_INFO
X
END_OF_FILE
if test 3347 -ne `wc -c <'tm-apollo.h'`; then
    echo shar: \"'tm-apollo.h'\" unpacked with wrong size!
fi
chmod +x 'tm-apollo.h'
# end of 'tm-apollo.h'
fi
echo shar: End of archive 1 \(of 4\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0