[gnu.gcc.bug] sun386 COFF encapsulation

eirik@labs.labs.tek.com (Eirik Fuller) (11/15/89)

I have bootstrapped gcc on a sun386 with the GNU assembler and linker,
using a modified robotussin.  Those diffs went to bug-gnu-utils
(gnu.utils.bug); you will need them for the code here to be useful.

The enclosed shell archive contains three files.  Two of them,
config.h and tm.h, are usually symlinks, but I haven't named them yet;
at some point they could go into gcc/config.  The other file, Make, is
a top level script which bootstraps gcc.  It would not work just to
say "make bootstrap" without some mods to the gcc Makefile; in a
sense, those mods are isolated in Make.

In order for this script to work, you need a few things.  You need
sources for gcc and gas where the make macros $(srcdir) and $(gas)
will find them.  You need robotussin.c, patched with my diffs.  You
need ld.c; I used the one from g++-1.36.1.  I'm not sure you need
malloc.c and getpagesize.h from emacs sources, but I've gotten in the
habit of using them.  You should probably not have "." first in $PATH,
since ar and ./ar are two different programs, and both are necessary.

There are reasons for most of the strangeness in this Make script.
For instance, the native cc seems incapable of building ar in such a
way that the gnulib2 target in the gcc Makefile gets built properly.
That's why ar gets built twice; it has to get built by the native cc
because gnulib, needed by gcc to build ar, can't get built without ar.
I use alloca.c, including the removal of "#define alloca" from ar.c
and ld.c, because stack space is apparently a rare commodity on a
sun386; I get segfaults otherwise.  After going through all of this,
I've convinced myself I'd never spend my own money on a sun386 ...

Feel free to ask me about any of this, if you need more information.


#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./Make`
then
echo "writing ./Make"
cat > ./Make << '\Rogue\Monster\'
#!/bin/make -f
mach=	i386
MF=	AR=./ar MALLOC=malloc.o
COFF=	-DPORTAR -DCOFF_ENCAPSULATE
OLDCC=cc
OPT=-O -finline-functions -fstrength-reduce -pipe -L.

final:	stage2
	./Make CC="../stage2/gcc -B../stage2/ $(OPT)." as
	rm -f ar
	./Make CC="stage2/gcc -Bstage2/ -pipe $(OPT)" ld ar
	make $(MF) "CC=stage2/gcc -Bstage2/ $(OPT)" all gnulib2
	for o in *.o gas/*.o; do cmp $$o stage2/$$o;done

stage2:	stage1
	./Make CC="../stage1/gcc -B../stage1/ -pipe $(OPT)." as
	./Make CC="stage1/gcc -Bstage1/ -pipe $(OPT)" ld
	make $(MF) "CC=stage1/gcc -Bstage1/ $(OPT)" all $@
	mkdir $@/gas ; mv gas/*.o $@/gas/
	mv -f ld as $@/
	-ln $@/crt0.o ./
	-ln libc.a $@/

stage1:	links config.status gnulib crt0.o libc.a libg.a
	./Make "CC=$(CC)" as ld
	make $(MF) all $@
	mkdir $@/gas ; mv gas/*.o $@/gas/
	mv -f ld as $@/
	-ln $@/crt0.o ./
	-ln libc.a $@/

ar:	ar.c alloca.c a.out.encap.h a.out.gnu.h 
	$(CC) $(COFF) -o $@ $@.c alloca.c

ld:	ld.o cplus-dem.o alloca.o ; $(CC) -o ld ld.o cplus-dem.o alloca.o
ld.o:	ld.c ; $(CC) $(COFF) -g -c ld.c

as:	$(GASDEP)
	cd gas ; make "CC=$(CC)" OPTIONS= a386
	mv -f gas/a386 as

gnulib:	libconvert robotussin ar
	make gnulib
	./libconvert gnulib gnulib.new
	mv -f gnulib.new gnulib

crt0.o:	robotussin robotussin.c ar.c
	./robotussin /lib/crt0.o crt0.o

libc.a:	robotussin libconvert
	./libconvert /lib/$@ $@

libg.a:	robotussin libconvert
	./libconvert /lib/$@ $@

robotussin:	robotussin.c a.out.encap.h a.out.gnu.h
	$(CC) -o $@ $@.c

gas=../gas
srcdir=../gcc
destdir=.
bin=	../binutils

robotussin.c: ; ln $(bin)/sun386-robotussin.c $@
a.out.encap.h a.out.gnu.h libconvert: ; ln $(bin)/$@ $(destdir)/

#	This hack enables the use of alloca.c with gcc
#	With a real stack, this would be unnecessary
ar.c:
	@sed -e 's/#define.alloca/#define Alloca/' $(bin)/$@ > $@

ld.c:
	@sed -e 's/#define.alloca/#define Alloca/' $(srcdir)/$@ > $@

Makefile:
	sed -e 's/^all:\(.*\) gnulib2/all:\1/' \
		-e '/ranlib gnulib/d' $(srcdir)/$@ > $@

config=	$(mach).md out-$(mach).c tm-sun386.h tm-i386.h tm-i386gas.h tm-bsd386.h

links =	alloca.c assert.h basic-block.h c-convert.c c-decl.c \
	c-parse.h c-parse.output c-parse.tab.c c-parse.y c-tree.h \
	c-typeck.c caller-save.c cccp.c cexp.c cexp.y combine.c \
	conditions.h cse.c dbranch.c dbxout.c emit-rtl.c explow.c \
	expmed.c expr.c expr.h final.c fixincludes flags.h flow.c \
	fold-const.c gcc.c gdbfiles.h gencodes.c genconfig.c genemit.c \
	genextract.c genflags.c genoutput.c genpeep.c genrecog.c \
	global-alloc.c gnulib.c gnulib2.c gvarargs.h hard-params.c \
	hard-reg-set.h input.h integrate.c jump.c limits.h \
	local-alloc.c loop.c machmode.def masm386.c math-68881.h \
	move-if-change obstack.c obstack.h optabs.c output.h \
	print-tree.c real.h recog.c recog.h regclass.c regs.h reload.c \
	reload.h reload1.c rtl.c rtl.def rtl.h rtlanal.c \
	sdbout.c stab.def stab.h stdarg.h stddef.h stmt.c \
	stor-layout.c stupid.c symout.c symseg.h toplev.c tree.c \
	tree.def tree.h typeclass.h varasm.c version.c \
	cplus-dem.c proto-gen.c protoize.c std.c

links: $(links) $(config) gas malloc.c getpagesize.h Makefile

$(links): ; @ln $(srcdir)/$@ $(destdir)/
$(config): ; @ln $(srcdir)/config/$@ $(destdir)/
malloc.c getpagesize.h: ; ln ../emacs/src/$@ $(destdir)/

gas:	
	@mkdir $@ && ln $(gas)/* $@/

config.status:	$(config) config.h aux-output.c md tm.h md
	> $@

aux-output.c: ; ln out-$(mach).c $@
md: ; ln $(mach).md $@
\Rogue\Monster\
else
  echo "will not over write ./Make"
fi
if [ `wc -c ./Make | awk '{printf $1}'` -ne 3391 ]
then
echo `wc -c ./Make | awk '{print "Got " $1 ", Expected " 3391}'`
else
chmod +x Make
fi
if `test ! -s ./config.h`
then
echo "writing ./config.h"
cat > ./config.h << '\Rogue\Monster\'
/* Configuration for GNU C-compiler for Intel 80386 running SunOS 4.0,
   using GAS and GNU ld (COFF encapsulation)
   Copyright (C) 1988 Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */


/* #defines that need visibility everywhere.  */
#define FALSE 0
#define TRUE 1

/* This describes the machine the compiler is hosted on.  */
#define HOST_BITS_PER_CHAR 8
#define HOST_BITS_PER_SHORT 16
#define HOST_BITS_PER_INT 32
#define HOST_BITS_PER_LONG 32

/* Arguments to use with `exit'.  */
#define SUCCESS_EXIT_CODE 0
#define FATAL_EXIT_CODE 33

#define USG

/* target machine dependencies.
   tm.h is a symbolic link to the actual target specific file.   */
#include "tm.h"

#define bcopy(a,b,c) memcpy (b,a,c)
#define bzero(a,b) memset (a,0,b)
#define bcmp(a,b,c) memcmp (a,b,c)

#ifdef __GNUC__
#define alloca(n) __builtin_alloca(n)
#endif
\Rogue\Monster\
else
  echo "will not over write ./config.h"
fi
if [ `wc -c ./config.h | awk '{printf $1}'` -ne 1502 ]
then
echo `wc -c ./config.h | awk '{print "Got " $1 ", Expected " 1502}'`
fi
if `test ! -s ./tm.h`
then
echo "writing ./tm.h"
cat > ./tm.h << '\Rogue\Monster\'
/* Definitions for Intel 386 running SunOS 4.0. with the GNU assembler
   Copyright (C) 1988 Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* Use the GNU assembler syntax.  */

#include "tm-i386gas.h"

/* By default, target has a 80387.  */

#define TARGET_DEFAULT 1

#define LIB_SPEC "%{!p:%{!pg:libc.a%s}}%{p:libc_p.a%s}%{pg:libc_p.a%s}\
%{sun386:}"
/* That last item is just to prevent a spurious error.  */

/* Specify predefined symbols in preprocessor.  */

#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Dunix -Di386 -Dsun386 -Dsun"
\Rogue\Monster\
else
  echo "will not over write ./tm.h"
fi
if [ `wc -c ./tm.h | awk '{printf $1}'` -ne 1205 ]
then
echo `wc -c ./tm.h | awk '{print "Got " $1 ", Expected " 1205}'`
fi
echo "Finished archive 1 of 1"
exit