[gnu.g++] what and where are the COFF patches for GNU C++

ronald@ucdavis.edu (09/13/89)

In article <2559@ccncsu.ColoState.EDU> thorson@typhoon.atmos.colostate.edu writes:
>In article <299900002@uicsgva.csg.uiuc.edu> niermann@uicsgva.csg.uiuc.edu writes:
>>  I am trying to build g++-1.35.0 for an encore multimax ns3200.
>>While compiling newld.c I get a very large number of errors. The 
>>first few are:
>> 
>>newld.c:613: field `header' has incomplete type
>>newld.c: In function main:
>....Errors aplenty...
>>Tom
>>niermann@bach.csg.uiuc.edu
>
>I have the same problem on a Sun386i.
>
>Even the errors are exactly the same as Tom listed in his
>message.
>
>I've been trying to get this going all weekend.
>
>WE NEED HELP!

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               +----------------------------------------------------
"SCCS, the source motel! Programs check in and never check out!" - Ken Thompson

abair@turbinia.oakhill.uucp (Alan Bair) (09/13/89)

I am unfamiliar with many of the ld items discussed in the README you posted,
so I am going to ask if your code will help me.  I would like to try getting
g++ to work on our Apollos running SR10.1, which now supports COFF.  I have
seen no references to the Apollo in the gcc or g++ installation guides, so
I thought I would give your code a try.

Any chance it will help?

Alan Bair
SPS CAD  Austin, Texas
Motorola, Inc.
UUCP cs.utexas.edu!oakhill!turbinia!abair

grunwald@foobar.colorado.edu (Dirk Grunwald) (09/13/89)

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++.

vasta@apollo.HP.COM (John Vasta) (09/15/89)

In article <ABAIR.89Sep13000432@turbinia.oakhill.uucp> abair@turbinia.oakhill.uucp (Alan Bair) writes:
>I am unfamiliar with many of the ld items discussed in the README you posted,
>so I am going to ask if your code will help me.  I would like to try getting
>g++ to work on our Apollos running SR10.1, which now supports COFF.  I have
>seen no references to the Apollo in the gcc or g++ installation guides, so
>I thought I would give your code a try.
>
>Any chance it will help?
>
>Alan Bair
>SPS CAD  Austin, Texas
>Motorola, Inc.
>UUCP cs.utexas.edu!oakhill!turbinia!abair

It may help some, but it won't be enough. The problems in getting gcc/g++
running *usefully* on the Apollo are:

  1) No Apollo assembler, and the GNU assembler emits a.out files

  2) Until recently, incompatible function calling conventions, meaning
     you couldn't use Apollo libraries

  3) Syntax extensions in the C header files

The "COFF encapsulation" technique won't really work, either, because it's
not possible to convert the Apollo shared C libraries to a.out format libraries.

I got GCC running on the Apollo by

   1) Hacking GAS to emit COFF modules

   2) Adding configuration info to handle Apollo calling conventions
      (with RMS' help); this is now incorporated into the GCC release

   3) Modifying the GCC grammar to accept Apollo syntax extensions

I have not had time to get G++ running yet.

If you'd like my GCC changes for 1.35, let me know.
Also, dclemans.falcon@mntgfx.mentor.com (Dave Clemans) has gotten
both GCC and G++ running using a different technique; you may want
to check with him.
-- 
John Vasta                Apollo Computer (division of Hewlett Packard)
vasta@apollo.hp.com       M.S. CHA-01-LT
(508) 256-6600 x6362      330 Billerica Road, Chelmsford, MA 01824
UUCP: {decwrl!decvax, mit-eddie, attunix}!apollo!vasta