[comp.sys.encore] G++ under Umax 4.2

dcourte@eve.wright.edu (Dale Emery Courte) (11/28/89)

I am attempting to put GNU c++ (g++) up on our Multimax here, and have
run into a snag. While compiling the file newld.c (g++-1.36) or ld.c
(g++-1.34) I get numerous errors having to do with COFF format. It seems
the header files, being a.out.h and all that it includes, don't define
an important struct definition, called 'exec'. Also, due to the #if's
in a.out.h and the fact that n16 is defined as 1 on the Mutimax, a
number of referenced constants (N_TEXT, N_BSS, ...) are not #defined.
The way a.out.h is defined under Umax 4.2 is quite different than on
SUN's and Ultrix VAXes I have access to, while the SUN-OS and Ultrix
versions seem quite similar to each other. Is Encore's a.out.h
'nonstandard' in some sense? I'm just curious here, I know next to
nothing about COFF files.

I saw some postings about g++ and libg++ a while back, but had not yet
encountered this problem and was busy with other things. If this problem
was addressed, could someone please send me a summary?

If anyone knows, please tell me what I might be doing wrong. I assume
g++ will compile on the Multimax, as there is an encore config option
which is specifically for BSD and not Umax V.

Thank You.

-----------------------------       -------------------------------------
Dale Courte                         CSNET: dcourte@eve.wright.edu
University Computing Services       BITNET: dcourte@wsu
Wright State University             UUCP: ..!uunet!ncrlink!wright!dcourte
Dayton, Ohio 45435                  phone: (513) 873-4030
-----------------------------       -------------------------------------

pierson@xenna.encore.com (Dan Pierson) (11/28/89)

Dale Emery Courte writes:
 > I am attempting to put GNU c++ (g++) up on our Multimax here, and have
 > run into a snag. While compiling the file newld.c (g++-1.36) or ld.c
 > (g++-1.34) I get numerous errors having to do with COFF format. It seems
 > the header files, being a.out.h and all that it includes, don't define
 > an important struct definition, called 'exec'. Also, due to the #if's
 > in a.out.h and the fact that n16 is defined as 1 on the Mutimax, a
 > number of referenced constants (N_TEXT, N_BSS, ...) are not #defined.
 > The way a.out.h is defined under Umax 4.2 is quite different than on
 > SUN's and Ultrix VAXes I have access to, while the SUN-OS and Ultrix
 > versions seem quite similar to each other. Is Encore's a.out.h
 > 'nonstandard' in some sense? I'm just curious here, I know next to
 > nothing about COFF files.

COFF format is very different from a.out format.  Unfortunately, FSF
doesn't support COFF directly and there are at least two competing
solutions.  Messages describing both solutions follow.  There has been
a good deal of discussion about this in gnu.g++; I'd suggest following
that group (and maybe gnu.g++.bugs) if you plan to use g++.

Now, the disclaimer: neither of the FSF compilers are supported by
Encore; some of us here have played with them from time to time but we
have neither the expertise nor time to be truely useful consultants.
While I'd like to see G++ easily and reliably available on our
machines, I'm much to busy dealing with languages with less syntax and
more parentheses to spend much time on it.  Finally, I'd like to thank
Dirk and Ron for spending a lot of their own time and energy making
G++ work on COFF machines such as ours.

    From: csusac!cvms!ronald@ucdavis.edu
    Subject: what and where are the COFF patches for GNU C++
    Date: 12 Sep 89 19:40:39 GMT

    For this last year, I have been providing a set of patches for GNU C++
    to better integrate with COFF tools.  Apparently, these patches are still
    little known about.  Perhaps Michael Tiemann will see fit to mention in
    his next release that these are available from me and that I am
    independently supporting them.

    Patches starting from release 1.32.0 are available via anonymous
    ftp from cindy.csuchico.edu [132.241.0.35].  In the pub directory
    find the "g++-coff" and "libg++-sysv" directories.  Under those
    are the appropriate patches for the appropriate releases.

    Here is the latest README.COFF from the patches so you can decide for
    yourself if these patches are for you.

    ---------------------------- cut here --------------------------------

    This is the file README.COFF.  It contains notes on bringing up
    the GNU C++ compiler (g++) to generate COFF format executables for
    UNIX System V and it's COFFing cousins.

    The tricky part about getting GNU C++ running under System V is
    the need to have some agent which causes the initialization and
    finalization (i.e. construction and destruction) of all global
    static (i.e. file-level) class objects.

    The current implementation of g++ creates one routine per
    source/object file which will execute all of the constructors for
    all of the initialized global static class objects (if any such
    constructors are needed).  These per-file super-constructors
    always have names like:

	    _GLOBAL.I.sourcefilename_cc

    Likewise (if needed) G++ also creates one super-destructor per
    file with a name like:

	    _GLOBAL.D.sourcefilename_cc

    At run-time, the crt1+.o routine must call each of the
    super-constructors for each of the objects files of the whole
    program in turn.  It then must call main().  Finally, it must call
    each of the super-destructors in turn.  (Note that the exit()
    library routine should also be setup to invoke all of the
    super-destructors.)

    In order to do its job, crt1+.o must have two contiguous lists of
    addresses which it can traverse.  One list is a list of addresses
    of all of the super- constructors, the other is a list of
    addresses of all of the super-destructors.

    On BSD UNIX systems, these two lists (called __CTOR_LIST__ &
    __DTOR_LIST__) are created by a modified form of the GNU linker
    called ld++.  Since ld++ assumes that input files are in "a.out"
    object format and not in System V COFF format, this approach just
    doesn't port well to System V.

    Fortunately, as of System V Release 2 (and possibly even before),
    standard COFF linkers, accept so called "user-defined" sections,
    and they even have a special language for directing "ld" as to
    what to do with such sections.

    Just like the familiar ".text", ".data", and ".bss" sections,
    these "user- defined" sections allow one to cause otherwise
    unrelated chunks of object "stuff" to be collected into one
    contiguous region of a process's run-time address space.

    Thus, on my system, I modified g++ to output ".section" assembler
    directives for two "user-defined" sections.  One called ".ctors"
    and another one called ".dtors".  For each source/object file, I
    also arranged for g++ to place one 32-bit address word into the
    ".ctors" section and another into the ".dtors" section.  (Each of
    these is only done if needed).

    In each case, the single address placed in these sections is the
    address of the super-constructor (or super-destructor) for the
    current source/object file.

    At link time, my COFF linker places all of the ".ctors" address
    words into consecutive words in the output file.  Likewise, it
    places all of the ".dtors" address words into a separate set of
    consecutive words.  Thus the two "super" address lists are
    constructed at link-time.

    Note that for optimal results you should use a linker directives
    file that contains something which looks somewhat like the
    following:

	    SECTIONS
	    {
		.text <sizeof_headers>:
			{ *(.init) *(.text) *(.ctors) *(.dtors) *(.fini) }
		GROUP BIND(ADDR(.text) + SIZEOF(.text) + NEXT(<align_value>)):
			{ .data : { } .bss : { } }
	    }

    This will force the .ctors and .dtors sections to be joined to the
    tail end of the .text section and placed in read-only memory in
    the linked output file.  (You probably don't even need the
    specifications of "*(.init)" and "*(.fini)" in there, but if you
    are mixing languages, you may need it.)

    See your system's ld(1) man page and the linker section in the
    "Support Tools Guide" for more information about "linker
    directives" files.

    In order to allow crt1+.o to find the beginnings of each of the
    two super lists, two symbols are defined as residing at the
    beginning of the .ctors and .dtors sections (respectively) in the
    crt1+.o file.  These symbols are "__CTOR_LIST__" and
    "__DTOR_LIST__" respectively.  These are the same labels used to
    mark the list heads in the BSD version of g++.

    To find the ends of the lists, the "g++" driver program (System V
    version) passes the normal list of arguments to the system (COFF)
    linker, followed by the name of a special file called crtn+.o.
    This file defines the two symbols "__CTORS_END__" and
    "__DTORS_END__" as residing at the ends of each of the two super
    lists in the .ctors and .dtors sections (respectively).

    It is particularly important to be able to find the end of the
    DTORS list because the language rules call for this list to be
    traversed IN REVERSE ORDER relative to the order in which the
    CTORS list was traversed.  Thus, traversal must start from the END
    of the DTORS list and work backwards up to the beginning.  The
    crt1+.o code does exactly that.
    ---------------------------- cut here --------------------------------

    --
    Ronald Cole               | uucp: cvms!ronald       voice: +1 916 895 8321
    Senior Software Engineer  | internet: csusac!cvms!ronald@ucdavis.edu
    CVM Systems               +----------------------------------------------


    From: grunwald@foobar.colorado.edu (Dirk Grunwald)
    Subject: Re: what and where are the COFF patches for GNU C++
    Date: 13 Sep 89 16:22:19 GMT

    I still disagree that this is the way to go --- the entire problem is
    the Makefile isn't automatically configured. Inserting COFF patches that
    make use of ifiles is, IMHO, over complicated and needless. Yes, ifiles
    are nice. But do all coff-like loaders support ifiles? no - for example,
    the DECstation-3100 and other MIPS-derived machines. They use ecoff,
    which is compatible with COFF at the level of ``collect,'' but not at
    the level of ifiles.

    Using collect is simple, and easier to maintain. I've been using collect
    on a COFF speaking Encore for over a year. It works just fine.

    Rather than go though installing these coff changes, we we really need to
    do is clean up the Makefile to make configuration automatic.

    This means:

	    + Machines needing collect need to define NO_GNU_LD in their
	      tm.h files

	    + Files using COFF need an explicit symbol in their tm.h files
	      (USES_COFF?) NOTE THAT SVID or whatever isn't always correct.
	      this should be an explicit symbol.

	    + The options needed to compile collect (i.e. -DUMAX) and to
	      compiler crt0+.c and crt1+.c need to be moved into to tm.h

	    + collect.c and ld.c should always be built and installed. ld
	      may not do anything if e.g., NO_GNU_LD is defined, but it
	      simplifies the installation.

	    + whatever changes are needed for e.g., sun3-os4+.h should
	      also be in the tm.h files.

    Getting these changes in before 1.36 would be tres useful and would end
    much of the discussion of COFF support for g++.