[gnu.gcc] Gcc up and running on Altos 3068 w/ SVR2

jkp%cs.hut.fi@MITVMA.MIT.EDU (Jyrki Kuoppala) (02/12/89)

This is a description how I bootstrapped the GNU C compiler on Altos
3068 machines (Motorola 68020, SysVR2.2, Coff).  Gcc is version 1.33
and gas and binutils the newest which were available at the time 1.33
was released.  Gcc and friends on the Altos machines use the coff
encapsulation stuff.  They compile themselves well. I also have
compiled many other programs with the gcc setup.  Generally, gcc seems
to work quite well.  However, when compiling some programs with -O cc1
gets a fatal signal 6.  I'll look into that later and send more
accurate information; when the -O is omitted these programs
compile and work right.

The Altos-provided C compiler has some nasty bugs in it which bite you
quite often when compiling GNU programs.  For example, && and || don't
work right when used outside `if', `while' or `for' constructs; the whole
expression is always evaluated.  So, your safest bet is probably to
make a cross-compiler environment in some other machine (a Sun will do
fine, but others should, too) and compile gcc, gas and the GNU ld and
binutils there, link the binaries and copy all the stuff to the Altos
and recompile the whole stuff with itself.  That's how I did it; only
gnulib was compiled with Altos CC.

The cross compiler environment consists of gcc and gas targeted for
the m68k environment.  I had some trouble with floating point
instructions, so I compiled some of the files with sun cc; this is not
necessary if gcc doesn't generate floating point instructions [ You
should use -msoft-float with gcc; this does not produce floating point
instructions].  Also, you need a version of the gnu linker which is
patched to make things look right for the Altos kernel.  You should
also -D and -U the same things which Altos cc does; and don't forget
to -U all the stuff gcc otherwise defines when it thinks the target
machine is a sun or something.  Copy the Altos include files to your
development machine (use -I/some/weird/path -nostdinc) and compile and
link the gcc, gas and binutils there.  You need to copy the Altos
libraries over and convert them to GNU format with libconvert /
robotussin.  I used -traditional -fwritable-strings just to be sure;
after you recompile the stuff with itself you can change these.  It
seems you should, too, for gcc.

If you don't have another machine to compile gcc on, the Altos
binaries are available for anonymous ftp in host sauna.hut.fi
(128.214.3.119) under the directory pub/gnu/altos.

The changes that had to be made were quite small.  Gas didn't need
any; I made tm-altos3068.h and xm-altos3068.h for gcc and added altos
to config.gcc.  Binutils needed some hacking, namely ld.c required
some major magic.  The context diffs are available in the directory
pub/gnu/altos in sauna.hut.fi.  There are also some other diffs fro
GNU utilities.

I expect gdb to be at least partly working with Altos machines soon;
also I don't think G++ should be much of a problem now.  Now I have a
version whhich reads COFF (well, not very well) and which isn't very
useful for other than disassembling programs.

Binutils diffs still has many many bugs I need to sort out; it is not
`clean' yet.  I'll send a more sensible version to the binutils
mailing list whhen it's ready.  As of now, I haven't looked at others
than ld and robotussin very much.  However, I'm sending out the stuff
now because it gets gcc working.

Please, tell me if ANYONE else out there still uses these machines.
You know, I feel so lonely ;-).

A shar file with the diffs for gcc and binutils follows (use your
favourite alloca(), mine is in -lizard):

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#    GCCDIFFS
#    BINUTDIFFS
# This archive created: Sat Feb 11 21:41:43 1989
export PATH; PATH=/bin:$PATH
if test -f 'GCCDIFFS'
then
    echo shar: will not over-write existing file "'GCCDIFFS'"
else
cat << \SHAR_EOF > 'GCCDIFFS'
diff -cr2N gcc-1.33/config.gcc gcc-1.33.altos/config.gcc
*** gcc-1.33/config.gcc    Sat Feb 11 20:44:20 1989
--- gcc-1.33.altos/config.gcc    Sat Feb 11 20:44:00 1989
***************
*** 153,156 ****
--- 153,160 ----
          cpu_type=m68k
          ;;
+     altos | altos3068)        # Altos 3068 with gnu as, ld and gdb
+         cpu_type=m68k
+         configuration-file=xm-altos3068.h
+         target_machine=tm-altos3068.h
      3b1)
          cpu_type=m68k
diff -cr2N gcc-1.33/tm-altos3068.h gcc-1.33.altos/tm-altos3068.h
*** gcc-1.33/tm-altos3068.h    Thu Jan  1 02:00:00 1970
--- gcc-1.33.altos/tm-altos3068.h    Sat Feb 11 20:43:48 1989
***************
*** 0 ****
--- 1,103 ----
+ /* Definitions of target machine for GNU compiler.  Altos 3068 68020 version.
+    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
+
+ Written by Jyrki Kuoppala <jkp@cs.hut.fi>
+ Last modified: Sat Feb 11 20:33:41 1989
+
+ This file is part of GNU CC.
+
+ GNU CC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY.  No author or distributor
+ accepts responsibility to anyone for the consequences of using it
+ or for whether it serves any particular purpose or works at all,
+ unless he says so in writing.  Refer to the GNU CC General Public
+ License for full details.
+
+ Everyone is granted permission to copy, modify and redistribute
+ GNU CC, but only under the conditions described in the
+ GNU CC General Public License.   A copy of this license is
+ supposed to have been given to you along with GNU CC so you
+ can know your rights and responsibilities.  It should be in a
+ file named COPYING.  Among other things, the copyright notice
+ and this notice must be preserved on all copies.  */
+
+
+ #include "tm-m68k.h"
+
+ /* See tm-m68k.h.  7 means 68020 with 68881.  */
+ /* 5 is without 68881 */
+
+ #undef TARGET_DEFAULT
+
+ #define TARGET_DEFAULT 5
+
+
+ /* Define __HAVE_FPA__ or __HAVE_68881__ in preprocessor,
+    according to the -m flags.
+    This will control the use of inline 68881 insns in certain macros.
+    Also inform the program which CPU this is for.  */
+
+ #if TARGET_DEFAULT & 02
+
+ /* -m68881 is the default */
+ #define CPP_SPEC \
+ "%{!msoft-float:%{mfpa:-D__HAVE_FPA__ }%{!mfpa:-D__HAVE_68881__ }}\
+ %{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}
}}"
+
+ #else
+ #if TARGET_DEFAULT & 0100
+
+ /* -mfpa is the default */
+ #define CPP_SPEC \
+ "%{!msoft-float:%{m68881:-D__HAVE_68881__ }%{!m68881:-D__HAVE_FPA__ }}\
+ %{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}
}}"
+
+ #else
+
+ /* -msoft-float is the default */
+ #define CPP_SPEC \
+ "%{m68881:-D__HAVE_68881__ }%{mfpa:-D__HAVE_FPA__ }\
+ %{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}
}}"
+
+ #endif
+ #endif
+
+
+ /* -m68000 requires special flags to the assembler.  */
+
+ #define ASM_SPEC \
+  "%{m68000:-mc68010}%{mc68000:-mc68010}%{!mc68000:%{!m68000:-mc68020}}"
+
+ /* Names to predefine in the preprocessor for this target machine.  */
+
+ #define CPP_PREDEFINES "-Dmc68000 -Dmc68020 -DPORTAR -Dm68k32 -Uvax -Dm68k
 -Dunix"
+
+ /* Every structure or union's size must be a multiple of 2 bytes.  */
+
+ #define STRUCTURE_SIZE_BOUNDARY 16
+
+ /* We use gnu assembler, linker and gdb, so we want DBX format.  */
+
+ #define DBX_DEBUGGING_INFO
+
+ /* This is how to output an assembler line defining a `double' constant.  */
+
+ #undef ASM_OUTPUT_DOUBLE
+ #define ASM_OUTPUT_DOUBLE(FILE,VALUE)                    \
+      fprintf (FILE, "\t.double 0r%.20e\n", (VALUE))
+
+ /* This is how to output an assembler line defining a `float' constant.  */
+
+ #undef ASM_OUTPUT_FLOAT
+ #define ASM_OUTPUT_FLOAT(FILE,VALUE)                    \
+      fprintf (FILE, "\t.single 0r%.20e\n", (VALUE))
+
+ #undef ASM_OUTPUT_FLOAT_OPERAND
+ #define ASM_OUTPUT_FLOAT_OPERAND(FILE,VALUE)                \
+      fprintf (FILE, "#0r%.9g", (VALUE))
+
+ #undef ASM_OUTPUT_DOUBLE_OPERAND
+ #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE)                \
+      fprintf (FILE, "#0r%.20g", (VALUE))
+
+ #define USE_GAS
diff -cr2N gcc-1.33/xm-altos3068.h gcc-1.33.altos/xm-altos3068.h
*** gcc-1.33/xm-altos3068.h    Thu Jan  1 02:00:00 1970
--- gcc-1.33.altos/xm-altos3068.h    Sat Feb 11 20:43:35 1989
***************
*** 0 ****
--- 1,7 ----
+ #define USG
+
+ #include "xm-m68k.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)
SHAR_EOF
fi # end of overwriting check
if test -f 'BINUTDIFFS'
then
    echo shar: will not over-write existing file "'BINUTDIFFS'"
else
cat << \SHAR_EOF > 'BINUTDIFFS'
Author: Jyrki Kuoppala (jkp@hutcs.hut.fi)
Last modified: Sat Feb 11 21:34:15 1989

Problems: object files compiled with 'cc -g' confuse robotussin.

It seems that files produced with the GNU linker didn't work the first
time they are run; but right after that, they work.  This was so for
some files; others worked just fine.  One file for which it failed had
0x407F8 as the start address for data, one other 0x40FF8.  Seems
likely that the entry address 0xa8 is hard-coded somewhere in the
kernel; gld uses 0xc8 as the entry address.  I fixed the problem with
a hack to add some padding if the end of text / start of data comes
too near the 0x800 page end.  Seems to work now.

For big files, ld puts the data area somewhere else than 0x400000.
I chose it to step the address up by 0x400000.

Strip doesn't work (core dumps).

Ranlib doesn't work (corrupts the archive)

diff -cr binutils/a.out.encap.h binutils.work/a.out.encap.h
*** binutils/a.out.encap.h    Mon Jan 23 22:20:29 1989
--- binutils.work/a.out.encap.h    Sat Feb 11 03:52:58 1989
***************
*** 65,72 ****
  #ifdef i386
  #define COFF_MAGIC 0514 /* I386MAGIC */
  #endif

! #if defined(i386)
  short __header_offset_temp;
  #define HEADER_OFFSET(f) \
      (__header_offset_temp = 0, \
--- 65,75 ----
  #ifdef i386
  #define COFF_MAGIC 0514 /* I386MAGIC */
  #endif
+ #ifdef m68k
+ #define COFF_MAGIC 0520 /* MC68MAGIC */
+ #endif

! #if defined(i386) || defined(m68k)
  short __header_offset_temp;
  #define HEADER_OFFSET(f) \
      (__header_offset_temp = 0, \
***************
*** 84,90 ****
  #else
  #define HEADER_OFFSET(f) 0
  #define HEADER_OFFSET_FD(fd) 0
! #endif

  #define HEADER_SEEK(f) (fseek ((f), HEADER_OFFSET((f)), 1))
  #define HEADER_SEEK_FD(fd) (lseek ((fd), HEADER_OFFSET_FD((fd)), 1))
--- 87,93 ----
  #else
  #define HEADER_OFFSET(f) 0
  #define HEADER_OFFSET_FD(fd) 0
! #endif /* i386 || m68k */

  #define HEADER_SEEK(f) (fseek ((f), HEADER_OFFSET((f)), 1))
  #define HEADER_SEEK_FD(fd) (lseek ((fd), HEADER_OFFSET_FD((fd)), 1))
***************
*** 104,110 ****
  #define N_TXTADDR(x) \
      ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
       sizeof (struct coffheader) + sizeof (struct exec) : 0)
!
  #define SEGMENT_SIZE 0x400000
  #define N_DATADDR(x) \
      ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
--- 107,116 ----
  #define N_TXTADDR(x) \
      ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
       sizeof (struct coffheader) + sizeof (struct exec) : 0)
! /*
!  * I think this is wrong for Altos 3068's,
!  *  but I wonder what program uses it ?
!  */
  #define SEGMENT_SIZE 0x400000
  #define N_DATADDR(x) \
      ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
Only in binutils.work: a.out.encap.h.
diff -cr binutils/ld.c binutils.work/ld.c
*** binutils/ld.c    Thu Jan 26 20:52:06 1989
--- binutils.work/ld.c    Sat Feb 11 04:43:24 1989
***************
*** 930,936 ****
--- 930,940 ----
      text_start = N_TXTADDR (outheader);

    /* The text-start address is normally this far past a page boundary.  */
+ #ifdef ALTOS
+   text_start_alignment = 0;
+ #else
    text_start_alignment = text_start % page_size;
+ #endif

    /* Load symbols of all input files.
       Also search all libraries and decide which library members to load.  */
***************
*** 2227,2235 ****
--- 2231,2259 ----

    if (magic == NMAGIC || magic == ZMAGIC)
      {
+ #ifdef ALTOS
+       /* Altos wants alignment on long word boundary */
+       text_pad = 4 - (text_size % 4);
+       if (text_pad == 4)
+     text_pad = 0;
+       /* This is gross hack and I'm not quite sure what it does ;-) */
+       /* Seems to help, though.  Read LUPU for details        */
+       /* It seems that the entry address 0xa8 is hard-coded */
+       /* somewhere in the kernel, and now when the GNU linker */
+       /* uses 0xc8 things go crazy when thhe page boundary  */
+       /* is at the wrong place.  This is to get around that.*/
+       /* we just stay far away from page boundaries.        */
+       /* Of course I could RTFS, but it gives me indigestion.  //jkp */
+
+       if (((text_size + text_start) % 0x800) > 0x780
+       || ((text_size + text_start) % 0x800) < 0x80)
+        text_pad += 0x100;
+       text_size += text_pad;
+ #else
        int text_end = text_size + N_TXTOFF (outheader);
        text_pad = ((text_end + page_size - 1) & (- page_size)) - text_end;
        text_size += text_pad;
+ #endif
      }

    outheader.a_text = text_size;
***************
*** 2236,2243 ****
--- 2260,2276 ----

    /* Make the data segment address start in memory on a suitable boundary.  */

+ #ifdef ALTOS
+   if (! Tdata_flag_specified) {
+        /* The Altos 3068 system wants a big gap between text and data. */
+        /* Heavy magic.  I don't understand this, I just work here.
+       Causes cancer in rats. */
+        data_start = ((text_start + text_size + 0x2000) / 0x40000 + 1) *
 0x40000 + (text_start + text_size) % 0x2000;
+   }
+ #else
    if (! Tdata_flag_specified)
      data_start = N_DATADDR (outheader) + text_start - N_TXTADDR (outheader);
+ #endif

    /* Set up the set element vector */

diff -cr binutils/nm.c binutils.work/nm.c
*** binutils/nm.c    Tue Jan 10 06:03:35 1989
--- binutils.work/nm.c    Sat Feb 11 03:46:17 1989
***************
*** 140,146 ****

  #ifdef USG
  #include <string.h>
! #include <sys/fcntl.h>
  #else
  #include <strings.h>
  #endif
--- 140,146 ----

  #ifdef USG
  #include <string.h>
! #include <fcntl.h>
  #else
  #include <strings.h>
  #endif
diff -cr binutils/robotussin.c binutils.work/robotussin.c
*** binutils/robotussin.c    Mon Jan  9 17:32:36 1989
--- binutils.work/robotussin.c    Sat Feb 11 18:24:12 1989
***************
*** 128,134 ****
--- 128,140 ----
  #endif

  /* Customization for a particular machine.  */
+ #ifdef i386
  #define INPUT_MAGIC I386MAGIC
+ #else /* i386 */
+ #if defined (m68k) || defined (mc68000)
+ #define INPUT_MAGIC MC68MAGIC
+ #endif
+ #endif /* i386 */

  #include <stdio.h>
  #include <varargs.h>
***************
*** 548,553 ****
--- 554,565 ----
        reloc_infop->r_pcrel = 0;
        reloc_infop->r_length = 2;
        break;
+ #ifdef ALTOS
+     case R_RELLONG:
+       reloc_infop->r_pcrel = 0;
+       reloc_infop->r_length = 2;
+       break;
+ #endif
      default:
        error ("can't handle coff reloction type 0%o", coff_reloc.r_type);
      }
SHAR_EOF
fi # end of overwriting check
#    End of shell archive
exit 0
--
Jyrki Kuoppala    Helsinki University of Technology, Finland.
Internet :        jkp@cs.hut.fi jkp%finhut.bitnet@cunyvm.cuny.edu
BITNET :          jkp@finhut.bitnet        Gravity is a myth, the Earth sucks!