[gnu.g++] Please describe how to use g++/gdb with COFF

rjk@sequent.UUCP (Robert Kelley) (10/21/89)

I know that there are several approaches for using g++ and gdb with COFF.
One could modify g++ to generate assembler directives suitable for a COFF
assembler.  One could translate assembler directives from a.out style to
COFF style.  One could translate object files from a.out to COFF.  There
are probably many other approaches.  The ones that I would consider viable
would retain the ability to debug g++ programs with gdb.

I would like to hear about any work in this area.  Discussion of the relative
advantages and disadvantages of each approach would be particularly welcome.

rfg@ICS.UCI.EDU (10/22/89)

In a recent posting, rjk@sequent.UUCP (Robert Kelley) writes:

>I know that there are several approaches for using g++ and gdb with COFF.
>One could modify g++ to generate assembler directives suitable for a COFF
>assembler.  One could translate assembler directives from a.out style to
>COFF style.  One could translate object files from a.out to COFF.  There
>are probably many other approaches.  The ones that I would consider viable
>would retain the ability to debug g++ programs with gdb.
>
>I would like to hear about any work in this area.  Discussion of the relative
>advantages and disadvantages of each approach would be particularly welcome.

Actually, there appear to be two primary means of targeting the G++ compiler
to a COFF based system, and zero (implemented) ways of getting gdb to
fully understand the resulting executable files (but I may be wrong about this).

The "AT&T linker" Approach
--------------------------
As far a G++ targeting for COFF, I implemented one (simple?) method about a
year ago.  When I was working on the problem, I was targeting for NS32xxx
processor.  At that time, there was no implementation of either GAS or
GNU ld available for the NS32xxx processors.  Thus, in order to avoid
having to port these tools myself, I decided to use the "native" assembler
and linker (if possible).  This is exactly the way most ports of GCC started
life, i.e. most GCC ports started out assuming the use of a "native"
assembler and linker.

Because there was already a set of GCC configurations files for the NS32xxx
processors (developed by Michael Tiemann, with minor patches specific to
NSC's Genix OS added by me) the first cut of the G++ port was easy and
(mostly) worked well.  There was one important gotcha however.

The "gotcha" was that my global objects were not being constructed before
"main()" was called.  Likewise, these objects were not being destructed
upon program exit.

I managed to figure out exactly why this problem occured, and I also
managed to trick my (standard AT&T style) COFF linker into doing the
tricky things that needed to be done to get the global constructors
and destructor to execute.  I (and others) have since managed to use
the exact same techniques to get other standard AT&T COFF linkers
(on several other machines and architectures) to do the same magic.

Ron Cole (cvms!ronald@ucdavis.edu) has been distributing and maintaining
my patches (for the "AT&T linker" approach) for some time now.  He
currently has complete patch kits for several recent versions of G++
(up to 1.35.1).  I am now trying to bring up G++ 1.36.0- on the iPSC2
(aka Intel HyperCube) using this "AT&T linker" approach, and I will
gladly make the revised patch set available as soon as they appear to
be working.

For more technical details regarding this approach, get the patches from
Ron Cole (or via ananymous FTP from cindy.csuchico.edu in the ~ftp/pub
directory) and read the file README.COFF (contained in the patch kit).

The "GNU Linker" Approach
-------------------------
A very different means of getting g++ up on COFF systems has been implemented
primarily by Dirk Grunwald (grunwald@cs.colorado.edu).  I appologize if there
were other people (in particular, MDT) who also worked on this, and who I
have failed to give proper credit to.  In any case, the "GNU Linker"
approach is prefered by Michael Tiemann and by the FSF because it uses
fewer non-free software tools.  This approach relies on a program called
"collect" which does some of the magic which the standard linker does
in the "AT&T Linker" approach.  It also requires the GNU assembler (aka GAS)
which creates only a.out style object files.  Finally, this approach relies
on another program called "robotussin" (aka COFF medicine) which does a thing
called COFF ENCAPSULATION.  This turns a.out style object files into COFF
object files.  I cannot comment in too much detail on this approach because...
well... I have never really used it.  Perhaps Dirk will give us a short
overview here.


Pro's & Con's
-------------
Fow awhile there, Dirk, and Ron Cole, and I and (to a lesser extent)
Michael Tiemann were arguing back and forth in these newsgroups about
which method is better.  I believe that this discussion ultimately
disintegrated into a "tastes great... less filling... tastes great...
less filling...." type of argument.  Nobody was being convinced of the
validity of anybody else's point of view, so I (for one) decided not
to bother anymore.

Now, I would like to just make the point that (believe it or not) different
people have different needs.  Some people want a total GNU environment
and they are willing to do all the porting work necessary to get there.
Other people just want to bring up g++ (on their COFF based systems) with
a minimum of muss and fuss.  Both sets of needs are valid and, IMHO
both sets of needs should be accomodated.

As far as pros and cons of each approach, well, I feel that the AT&T Linker
approach can be ported more easily (actually quite trivially) to most
standard COFF based systems (there are one or two exceptions where individual
manufacturers have strayed from the path of the one true COFF).  I'm sure
that Dirk will disagree with my statement, and claim that collect is more
portable.  If you have time, I suggest that you try both (and report your
results here of course).

Regarding support, Dirk G., Michael Tiemann, and the FSF are supporting the
GNU linker approach.  Ron Cole is trying his best to make the patches
for the AT&T linker approach available to all who want them.  Since
Michael Tiemann has technical reservations about this approach, he is
naturally unwilling to fully embrace the patches which implement it.

Since it seems unlikely that MDT will incorporate these patches (ever)
Ron Cole may get tired of hasseling with them at some point in time, and
may decide to kiss it off.  Thus, if you are worried about the very long
haul, I suggest that you use the GNU linker approach.

If, on the other hand, you want a quick (and not so dirty) implementation
of G++ on your (standard) COFF system, I suggest that you try the AT&T Linker
route.

One final point.  The last time I heard, the GNU linker could not
yet deal with COFF shared libraries.  If you need to use such libraries
in your G++ programs, perhaps you had better use an AT&T linker.

GDB Debugging
-------------
Regarding the use of GDB on a COFF system for symbolically debugging G++
programs, if you can find anybody who has implemented this, I would very
much like to hear about it!!!!  As far as I know, this has simply never
been implemented yet.

// rfg

tiemann@LURCH.STANFORD.EDU (Michael Tiemann) (10/22/89)

    The "GNU Linker" Approach
    -------------------------
    A very different means of getting g++ up on COFF systems has been implemented
    primarily by Dirk Grunwald (grunwald@cs.colorado.edu).  I appologize if there
    were other people (in particular, MDT) who also worked on this, and who I
    have failed to give proper credit to.  In any case, the "GNU Linker"
    approach is prefered by Michael Tiemann and by the FSF because it uses
    fewer non-free software tools.  This approach relies on a program called

Another reason I prefer this approach is because linking need only be
performed once.  Using other approaches require the link to be
performed at least twice: once to figure out what is needed, and once
to then link in code which performs the initialization.  But I suppose
if you are afflicted with COFF (or its related diseases), the time
spent linking is among the least of your overall computer problems.

Michael

rfg@ICS.UCI.EDU (10/22/89)

MDT writes:

         The "GNU Linker" Approach
         -------------------------
         A very different means of getting g++ up on COFF systems has been implemented
         primarily by Dirk Grunwald (grunwald@cs.colorado.edu).  I appologize if there
         were other people (in particular, MDT) who also worked on this, and who I
         have failed to give proper credit to.  In any case, the "GNU Linker"
         approach is prefered by Michael Tiemann and by the FSF because it uses
         fewer non-free software tools.  This approach relies on a program call
	  ed

     Another reason I prefer this approach is because linking need only be
     performed once.  Using other approaches require the link to be
     performed at least twice: once to figure out what is needed, and once
     to then link in code which performs the initialization.

Which "other approaches" are you refering to?  The "AT&T Linker" approach
I described only does *one* link step.  Are there yet more approaches that
I should have mentioned also?

     But I suppose
     if you are afflicted with COFF (or its related diseases), the time
     spent linking is among the least of your overall computer problems.

I cannot (and do not) disagree that COFF is a "disease".  I do prefer
a less drastic "cure" however. :-)

P.S.  Can you comment on the shared library problem?  Is there really a
problem there, or was that just a rumor?

// rfg

grunwald@foobar.colorado.edu (Dirk Grunwald) (10/23/89)

Ron asks ``are there other alternatives that I didn't mention'' & the
answer is `yes'.

Namely, collect & native assembler/linker. In this combination, you
compile your programs using g++ & assemble using your native linker.
The g++ frontend is changed to do two links. The first link builds a
relocatable binary. You then run ``collect'' over this binary to
generate a .s file containing the ctor/dtor list. This file is
assembled & your original (mostly resolved) binary is linked with the
final .s file.

You now have a complete binary with ctor/dtor information. This is
similar the `munch' approach used in AT&T C++.

The advantages of this over e.g., using the COFF link directives file
is that it's more portable. You can use the same mechanism on the MIPS
assembler/linker, where it's not clear if you *have* linker files
(ifiles, I think they're called). The disadvantage is you link twice,
but that hasn't appeared to be much of a bottleneck.

Mark Linton uses a similar approach, but uses an `awk' script and `nm'
to get the output.

btw, collect.c was recently modified - someone is trying to get it work
on the 386i -- if anyone else has gotten this to work, please mail me
patches. I think I know what needs doing, but don't have a 386i. In any
case, look for patches on monday.

Dirk Grunwald -- Univ. of Colorado at Boulder	(grunwald@foobar.colorado.edu)

pell@isy.liu.se (P{r Emanuelsson) (10/23/89)

Dirk Grunwald:
>The disadvantage is you link twice,
>but that hasn't appeared to be much of a bottleneck.

Actually, in my case it was.  But (and this is ugly!) I knew I didn't have
any globally constructed objects, so I used the Sun ld. Compile with g++
and link once with the standard ld. Works fine.

>btw, collect.c was recently modified - someone is trying to get it work
>on the 386i -- if anyone else has gotten this to work, please mail me
>patches. I think I know what needs doing, but don't have a 386i. In any
>case, look for patches on monday.

I did the porting of collect in 1.35.1- to the 386i. Michael said he had
applied my patches to 1.36, but I haven't had the time to check it out.
If there are any problems, I'd like to hear about them.

      /Pell
--
Dept. of Electrical Engineering	                         pell@isy.liu.se
University of Linkoping, Sweden	                    ...!uunet!isy.liu.se!pell

lrs@indetech.com (Lynn Slater) (10/23/89)

> btw, collect.c was recently modified - someone is trying to get it work
> on the 386i -- if anyone else has gotten this to work, please mail me

Here are the patches I use to get collect to run on the sun4/os4. I suspect
that they would apply universally.

Notes: You must also edit Makefile to make collect and to install it as
       ?/lib/gcc-collect.

       You will probably have to edit yoru machines tm.h to define
       ASM_INT_OP. As a rule of thumb, I would suggest placing it right
       after the #define of DATA_SECTION_ASM_OP and make it output the same
       thing as used by ASM_OUTPUT_INT. I.e. If your machine in
       ASM_OUTPUT_INT uses "\t.word", then 
       #define ASM_INT_OP ".word"

       I have printf statements in collect.c that should not remain in the
       ultimate system. However, they are good for peace of mind.

       These changes seem to work on the sun4 and on the pyramid.

Why use this?
  Only use this if you really want to use the system supplied loader. Reasons:
       A. gnu ld is not available on your machine
       B. your machine ld has some quark not exactly matched by gnu ld but
          significant to the non c++ libraries you load in.
       C. You fiddle with shared memory in a way gnu ld does not yet handle.

diff -c g++-configured ~/dist/g++-1.36.0
diff -c g++-configured/collect.c /home/lrs/dist/g++-1.36.0/collect.c
*** g++-configured/collect.c	Mon Oct 23 08:35:02 1989
--- /home/lrs/dist/g++-1.36.0/collect.c	Thu Oct 12 08:47:23 1989
***************
*** 74,80 ****
  
  #ifndef ASM_OUTPUT_LABELREF_AS_INT
  #define ASM_OUTPUT_LABELREF_AS_INT(FILE,NAME)	\
!   (fprintf(FILE,"\t%s ", ASM_INT_OP), \
     ASM_OUTPUT_LABELREF(FILE,NAME), \
     fprintf(FILE,"\n"))
  #endif
--- 74,80 ----
  
  #ifndef ASM_OUTPUT_LABELREF_AS_INT
  #define ASM_OUTPUT_LABELREF_AS_INT(FILE,NAME)	\
!   (fprintf(FILE,"\t%s", ASM_INT_OP), \
     ASM_OUTPUT_LABELREF(FILE,NAME), \
     fprintf(FILE,"\n"))
  #endif
***************
*** 280,286 ****
    
    exists = 0;
    while (p) {
!     if (strcmp( symbol_name+1, p -> name ) == 0 ) {
        exists = 1;
        break;
      }
--- 280,286 ----
    
    exists = 0;
    while (p) {
!     if (strcmp( symbol_name, p -> name ) == 0 ) {
        exists = 1;
        break;
      }
***************
*** 298,310 ****
      
      if ( is_ctor ) {
        new -> next = ctor_chain;
-       printf("  Will call constructor %s\n", symbol_name);
        ctor_chain = new;
        ctor_chain_length++;
      }
      else {
        new->next = dtor_chain;
-       printf("  Will call destructor  %s\n", symbol_name);
        dtor_chain = new;
        dtor_chain_length++;
      }
--- 298,308 ----
diff -c g++-configured/gcc.c /home/lrs/dist/g++-1.36.0/gcc.c
*** g++-configured/gcc.c	Mon Oct 23 08:35:00 1989
--- /home/lrs/dist/g++-1.36.0/gcc.c	Mon Oct 16 17:56:38 1989
***************
*** 1,13 ****
- /*                        -*- Mode: C; C-Style: C++ -*- 
-  * gcc.c -- distributed copy modified to better use collect
-  * 
-  * AFSID           : $__Header$
-  * Created On      : Wed Oct 18 16:43:24 1989
-  * Last Modified By: Lynn Slater
-  * Last Modified On: Mon Oct 23 08:35:00 1989
-  * Update Count    : 5
-  */
- 
  /* Compiler driver program that can handle many languages.
     Copyright (C) 1987,1989 Free Software Foundation, Inc.
  
--- 1,3 ----
***************
*** 308,334 ****
  };
  
  #ifdef USE_COLLECT
! /* Here is the spec for running the linker, BEFORE doing a collect.  
!    No entry point is specified and no crt0 file is specified
!  */
! char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld -r -o %g.R \
!  %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
!  %{y*}  \
!  %{L*} %o %{!nostdlib:-lg++}\n\
! }}}}";
! 
! /* C++: Here is the spec for "collect"ing global ctor and dtor requirements.  
!    and then running a master load of everything.
!  */
  char *collect_spec =
    "%{!c:%{!M*:%{!E:%{!S:collect -o %g.S %g.R\n\
  as %g.S -o %g.O\n\
! ld %{o*} %l\
!  %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
!  %{y*} %{!nostdlib:%S} %g.R %g.O\
!  %{L*} %{!nostdlib:-lg++ gnulib%s %{g:-lg} %L}\n\
  }}}}";
  
  #else
  /* Here is the spec for running the linker, after compiling all files.  */
  char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld %{o*} %l\
--- 298,316 ----
  };
  
  #ifdef USE_COLLECT
! /* C++: Here is the spec for collecting global ctor and dtor
!    requirements.  */
  char *collect_spec =
    "%{!c:%{!M*:%{!E:%{!S:collect -o %g.S %g.R\n\
  as %g.S -o %g.O\n\
! ld %{o*} %g.R %g.O\n\
  }}}}";
  
+ /* Here is the spec for running the linker, after compiling all files.  */
+ char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld -r -o %g.R %l\
+  %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
+  %{y*} %{!nostdlib:%S} \
+  %{L*} %o %{!nostdlib:-lg++ gnulib%s %{g:-lg} %L}\n }}}}";
  #else
  /* Here is the spec for running the linker, after compiling all files.  */
  char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld %{o*} %l\
***************
*** 1831,1842 ****
      {
        int tmp = execution_count;
  
-       value = do_spec (link_spec);
-       if (value < 0)
- 	error_count = 1;
-       linker_was_run = (tmp != execution_count);
-     }
- 
  #ifdef USE_COLLECT
        /* C++: now collect all the requirements for
  	 calling global constructors and destructors,
--- 1813,1818 ----
***************
*** 1851,1856 ****
--- 1827,1838 ----
  	  linker_was_run &= (tmp != execution_count);
  	}
  #endif
+       value = do_spec (link_spec);
+       if (value < 0)
+ 	error_count = 1;
+       linker_was_run = (tmp != execution_count);
+     }
+ 
    /* If options said don't run linker,
       complain about input files to be given to the linker.  */
  
-- Thanks for all the good work, -- Lynn
-- 
===============================================================
Lynn Slater -- lrs@indetech.com or {sun, ames, pacbell}!indetech!lrs
42075 Lawrence Place, Fremont Ca 94538
Office (415) 438-2048; Home (415) 796-4149; Fax (415) 438-2034

pcg@aber-cs.UUCP (Piercarlo Grandi) (10/23/89)

In article <20941.625010978@ics.uci.edu> rfg@ICS.UCI.EDU writes:
    
             The "GNU Linker" Approach
             -------------------------
	     A very different means of getting g++ up on COFF systems
	     has been implemented primarily by Dirk Grunwald
	     (grunwald@cs.colorado.edu).  I appologize if there were
	     other people (in particular, MDT) who also worked on this,
	     and who I have failed to give proper credit to.  In any
	     case, the "GNU Linker" approach is prefered by Michael
	     Tiemann and by the FSF because it uses fewer non-free
	     software tools.  This approach relies on a program call ed
    
MDT writes:

	 Another reason I prefer this approach is because linking need
	 only be performed once.  Using other approaches require the
	 link to be performed at least twice: once to figure out what
	 is needed, and once to then link in code which performs the
	 initialization.

rfg comments:

    Which "other approaches" are you refering to?  The "AT&T Linker"
    approach I described only does *one* link step.  Are there yet more
    approaches that I should have mentioned also?

Ron Guilmette described TWO approaches; actually there are FOUR, of which THREE
are used with COFF:


AOUT with the GNU ld++

	The GNU ld++ will scan the .o files as it links them and will
	generate the proper magic to activate the constructor and
	destructor lists.

COFF with the GNU ld++

	You must use gas and robotussin to generate COFF encapsulation
	.o files, that is files that have a COFF header but an AOUT
	body; gas will do the trick from .s files, robotussin from
	existing .o and .a files; once this has done you can still use
	GNU ld++, that will essentially ignore the COFF header and only
	deal with the AOUT body, reducing the problem to the previous one.

COFF with collect

	You generate .o files using the native System V assembler in
	COFF format; you link them with their C++ libraries, and scan
	them collect that will generate the appropriate
	contructor/destructor lists, then you link these with the
	result of the previous link and with the C libraries.

COFF with .ini .fini

	The System V linker can generate two sections of object, .ini
	and .fini, that contain initialization/termination code for the
	executable. You can modify G++ so that it puts static
	constructor/destructor calls in these sections, and then the
	standard System V assembler, linker and crt?.o will take care
	of everything.


These are orthogonal to the problem of symbol table style (there are
three, DBX, GDB, SDB), which is what mainly holds back GDB (as
apparently GDB can scan happily both COFF and AOUT objects)..

	 But I suppose if you are afflicted with COFF (or its related
	 diseases), the time spent linking is among the least of your
	 overall computer problems.

    I cannot (and do not) disagree that COFF is a "disease".  I do
    prefer a less drastic "cure" however. :-)

There are two executable file formats: traditional AOUT and COFF. For
some reason RMS has decided that GNU will use AOUT. COFF is actually
vastly more flexible. There are also several alternative symbol table
formats, as well. Time to link is a damn nuisance. COFF is a *good
thing*.

    P.S.  Can you comment on the shared library problem?  Is there
    really a problem there, or was that just a rumor?

The problem is that shared libraries under System V do have their own
constructors and destructors; that is why COFF has .ini/.fini
sections.  If you use the stock crt?.c file as in the G++ distribution,
it will not activate these sections, and shared libraries will not
work. It is actually fairly easy to add to the crt?.c file the required
magic.

In the patches to G++ for SystemV/386 I posted some weeks ago there are
ways to use the 'COFF with collect' way of doing things (I would have
preferred doing the .ini/.fini trick, but that meant altering the
compiler, as compared to altering the collect program, and I would not
want to do that before the full 2.0 mods were done by MDT), and updates
to crt?.c and System V ld scripts to support both shared libraries and
its -z option (unmapping of the first 20K of virtual mem to catch stray
null pointer dereferencing).

Apparently they have found in part their way into 1.36 (which I don't
have yet, so I don't know for sure).
-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

piet@cs.ruu.nl (Piet van Oostrum) (10/24/89)

Has anybody g++ working on HP 9000/300 series workstations with HP/UX 6.5
using the HP/UX assembler and linker, and with all global constructors and
destructors (even those in library modules) being called ??
-- 
Piet van Oostrum, Dept of Computer Science, University of Utrecht
Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht,  The Netherlands.
Telephone: +31-30-531806      Internet: piet@cs.ruu.nl
Telefax:   +31-30-513791      Uucp: uunet!mcsun!hp4nl!ruuinf!piet

prc@erbe.se (Robert Claeson) (10/25/89)

In article <1444@aber-cs.UUCP> pcg@cs.aber.ac.uk (Piercarlo Grandi) writes:

>There are two executable file formats: traditional AOUT and COFF. For
>some reason RMS has decided that GNU will use AOUT. COFF is actually
>vastly more flexible. There are also several alternative symbol table
>formats, as well. Time to link is a damn nuisance. COFF is a *good
>thing*.

Actually, there are even more of them -- SCO Xenix uses something that
they call x.out, and System V, Release 4.0 is supposed to use yet another
object file format (called Extended Object Format or something similar).
And I suspect there are some that I don't know about.

-- 
          Robert Claeson      E-mail: rclaeson@erbe.se
	  ERBE DATA AB

tiemann@LURCH.STANFORD.EDU (Michael Tiemann) (10/26/89)

    >if you are afflicted with COFF (or its related diseases), the time
    >spent linking is among the least of your overall computer problems.

    I believe that the disease is not in COFF itself, but in the way ATT has
    chosen to make use of it. As pointed out by someone else, it is much more
    flexible than the other object file formats, as shown by the ease in which
    someone else in this newsgroup was able to use it for calling constructors
    and destructors.

The person to whom you are referring, Ron Guilmette, did manage to get
something working, but his way of getting it working was equivalent to
hacking stabs the way that GNU does, so COFF gets no extra there.  On
the other hand, COFF hard-wires its type representation system to a
four-bit encoding, all of which just happen to be taken by C.  This
lack of extensibility precludes its use as a representation for
symbolic information of C++ programs, since it is impossible to
represent things like virtual function, base classes, destructors,
member functions, pointers to members, etc.  COFF is an intrinsic
botch, so it is unfair to blame AT&T for more than just using it.

    I've been thinking of adding ".help" sections to my builds using coff
    and modifying tcsh to read these. Sort of a quick way of making programs
    be self-documenting.  (I haven't figured out the format for these help sections
    yet, but I intend that it should be able to handle both positional
    and keyword arguments.)
    I don't know any way to do something this with the Berkeley
    loader without also having to change the man page (that is without
    changing it's specification).

How about reading the definition of how stabs are used, and building
extensions upon that?  If you understood how stabs was extended to
handle constructors and destructors, you could see how to extend it to
handle a ".help" section.

Michael

rfg@ics.uci.edu (Ron Guilmette) (10/28/89)

In article <13058@boulder.Colorado.EDU> grunwald@foobar.colorado.edu writes:
>
>Ron asks ``are there other alternatives that I didn't mention'' & the
>answer is `yes'.
>
>Namely, collect & native assembler/linker. In this combination, you...

>The advantages of this over e.g., using the COFF link directives file
>is that it's more portable.
         ^^^^^^^^^^^^^^^^^^

You have been saying this for a long time, Dirk, but what evidence do you
base this opinion on?

>You can use the same mechanism on the MIPS
>assembler/linker, where it's not clear if you *have* linker files
                         ^^^^^^^^^^^^^^
>(ifiles, I think they're called).

That's a rather non-commitial statement if I ever heard one!  You have got one
of the PMAX beasts don't you, Dirk?   So look in the manual and tell us the
whole true story.  Do these things that use MIPS chips support COFF extra
sections or don't they?  Do they support "ifiles" or don't they?

Inquiring minds want to know!

// rfg

rfg@ics.uci.edu (Ron Guilmette) (10/28/89)

In article <1444@aber-cs.UUCP> pcg@cs.aber.ac.uk (Piercarlo Grandi) writes:
>
>Ron Guilmette described TWO approaches; actually there are FOUR, of which THREE
>are used with COFF:

I was speaking only of the number of approaches to get G++ up *only* on COFF
based systems.  So the correct number is three.  In any case, I stand corrected.

>COFF with the GNU ld++

>COFF with collect

>COFF with .init/.fini sections  (this is the AT&T linker approach)

>    P.S.  Can you comment on the shared library problem?  Is there
>    really a problem there, or was that just a rumor?
>
>The problem is that shared libraries under System V do have their own
>constructors and destructors; that is why COFF has .ini/.fini
>sections.  If you use the stock crt?.c file as in the G++ distribution,
>it will not activate these sections, and shared libraries will not
>work. It is actually fairly easy to add to the crt?.c file the required
>magic.

Right.  I have already done so to my version of crt0.c for G++.

>In the patches to G++ for SystemV/386 I posted some weeks ago there are
>ways to use the 'COFF with collect' way of doing things (I would have
>preferred doing the .ini/.fini trick, but that meant altering the
>compiler, as compared to altering the collect program, and I would not
>want to do that before the full 2.0 mods were done by MDT)...

The compiler changes are very minor and probably do not affect the parts
of the compiler that MDT is now working on.

>...and updates
>to crt?.c and System V ld scripts to support both shared libraries and
>its -z option (unmapping of the first 20K of virtual mem to catch stray
>null pointer dereferencing).

Changing crt0/1.c and adding a linker directives file are both trivial
(especially when the changes are already tested and available).  Most
linker directives files are only about 8 lines long.

Arguing that the AT&T linker approach involves too many changes is just plain
silly.  C'mon people!  We are only talking about a hundred lines or less of
patches!  This is getting ridiculous.  I guess that *anything* can be
characterized as being "too complicated" or "too risky" so long as you
don't really *want* to consider anybody's solution other than your own.

rfg@ics.uci.edu (Ron Guilmette) (10/28/89)

In article <8910261603.AA05478@lurch.Stanford.EDU> tiemann@lurch.stanford.edu writes:
>
>The person to whom you are referring, Ron Guilmette, did manage to get
>something working, but his way of getting it working was equivalent to
>hacking stabs the way that GNU does, so COFF gets no extra there. 
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^

The (only) notable advantage that COFF has over a.out is that COFF format
allows for the possibility of "extra" user-defined sections (i.e. above and
beyond the normal .text, .data, and .bss sections).  I can think of
a couple of zillion uses for this particular feature.  It allows you to
get the linker to amalgamate little chucks of stuff for several input
(object) files into single big chunks in the output (executable) files.
This can be damn useful, not only for shared-library initialization,
but also (as I have demonstrated) for construction & destruction of
global objects.

>On the other hand, COFF hard-wires its type representation system to a
>four-bit encoding, all of which just happen to be taken by C.  This
>lack of extensibility precludes its use as a representation for
>symbolic information of C++ programs, since it is impossible to
>represent things like virtual function, base classes, destructors,
>member functions, pointers to members, etc.

Absolutely true.  The debugging information in COFF is a disaster!!!
Due to the fixed fields and lack of expandability, the COFF debug
stuff cannot even handle full ANSI-C (which requires up to 12-levels
of "pointer-ness" for data types), let alone all of the "data type"
information required to support C++ (e.g. "reference-ness").

If only we could (a) add extra sections onto a.out, and (b) get all the
kernels to accept a.out for executable files, I could die a happy man.

// rfg

grunwald@foobar.colorado.edu (Dirk Grunwald) (10/29/89)

The man page for `ld' says something about putting test in a .init
section; however, this doesn't sound like the ifile option. The other
documentation I have on this is relatively moot.

cDoPortability extends to the class of machines that have 4.3ish headers
but can't, for one reason or another, use gnu ld. There's lots of
#ifdefs in collect.c for this case. Thus, a single common tool handles
the problems with out modification of the cc1plus itself.

prc@erbe.se (Robert Claeson) (10/30/89)

In article <1989Oct27.195605.26334@paris.ics.uci.edu> Ron Guilmette <rfg@ics.uci.edu> writes:

>Due to the fixed fields and lack of expandability, the COFF debug
>stuff cannot even handle full ANSI-C (which requires up to 12-levels
>of "pointer-ness" for data types), let alone all of the "data type"
>information required to support C++ (e.g. "reference-ness").

I believe that AT&T has recognized that COFF isn't exactly the best object
file format and is switching over to some new format in Release 4.0 of
System V. The AT&T guy that I spoke to said that it will be a much more
useful format for things like C++.

-- 
          Robert Claeson      E-mail: rclaeson@erbe.se
	  ERBE DATA AB

rfg@ics.uci.edu (Ron Guilmette) (11/13/89)

In article <4115@dell.dell.com> james@raid.dell.com (James Van Artsdalen) writes:
>In <PCG.89Oct31193848@emerald.cs.aber.ac.uk>, pcg@emerald.cs.aber.ac.uk (Piercarlo Grandi) wrote:
>
>> All we need now is to persuade MDT that the .init/.fini sections
>> handling, and the rest of the System V.3.2 paraphernalia, should
>> be put into the mainline G++ setup,
>
>I do not think .init sections are necessarily a good idea.  Any code
>placed in a .init section should probably not call malloc(3c), since
>malloc(3c) will not have been initialized yet (in the shared library
>case).  collect may be a hack, but the issue of when constructors and
>destructors are run seems much more controllable than with .init.

James,

You are correct.  When I used extra sections to bring up g++, I created
two new sections called .ctors and .dtors.

Note however that the problem that you have described is a *general* problem
with the C++ language, i.e. the order in which global objects get
initialized (i.e. constructed) is not defined.  Thus, your *own*
constructors (when used for global objects) cannot reliably call
library routines (of any kind, but especially if the routines to be
called are themselves hunks of C++ code that rely on prior "initialization"
of their own globals for proper operation).

P.S.  Please send me my diskettes!

// rfg