[gnu.g++.bug] collect, gcc, tm-mips.h patches for new gcc.xtar.Z

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

The following shar contains patches that work with the new gcc.xtar.Z to
allow you to compile & run G++ on the DECstation-3100. The version of
collect.c and tm-mips.h is the same that I sent out last time. Diffs
to gcc.c have changed a little.

If anyone makes this version of collect.c work correctly with, e.g.,
the Encore multimax, sun i386 or whatever, please send me diffs & I'll
put them in this version. Hopefully, it will eventually be shipped
with 1.36.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Patches/collect.c Patches/config Patches/gcc.c.diff
# Wrapped by grunwald@foobar on Wed Oct 11 13:21:39 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Patches/collect.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Patches/collect.c'\"
else
echo shar: Extracting \"'Patches/collect.c'\" \(15902 characters\)
sed "s/^X//" >'Patches/collect.c' <<'END_OF_FILE'
X/* Output tables which say what global initializers need
X   to be called at program startup, and what global destructors
X   need to be called at program termination, for GNU C++ compiler.
X   Copyright (C) 1987 Free Software Foundation, Inc.
X   Hacked by Michael Tiemann (tiemann@mcc.com)
X   COFF Changes by Dirk Grunwald (grunwald@flute.cs.uiuc.edu)
X
XThis file is part of GNU CC.
X
XGNU CC is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY.  No author or distributor
Xaccepts responsibility to anyone for the consequences of using it
Xor for whether it serves any particular purpose or works at all,
Xunless he says so in writing.  Refer to the GNU CC General Public
XLicense for full details.
X
XEveryone is granted permission to copy, modify and redistribute
XGNU CC, but only under the conditions described in the
XGNU CC General Public License.   A copy of this license is
Xsupposed to have been given to you along with GNU CC so you
Xcan know your rights and responsibilities.  It should be in a
Xfile named COPYING.  Among other things, the copyright notice
Xand this notice must be preserved on all copies.  */
X
X
X/* This file contains all the code needed for the program `collect'.
X
X   `collect' is run on all object files that are processed
X   by GNU C++, to create a list of all the file-level
X   initialization and destruction that need to be performed.
X   It generates an assembly file which holds the tables
X   which are walked by the global init and delete routines.
X   The format of the tables are an integer length,
X   followed by the list of function pointers for the
X   routines to be called.
X
X   Constructors are called in the order they are laid out
X   in the table.  Destructors are called in the reverse order
X   of the way they lie in the table.  */
X
X#include "config.h"
Xint target_flags;	/* satisfy dependency in config.h */
X
X#ifndef USE_COLLECT
Xmain()
X{
X  exit(0);
X}
X
X#else
X
X
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#include <stdio.h>
X#include <a.out.h>
X#include <ar.h>
X
X#ifdef UMAX
X#include <sgs.h>
X#endif
X
X/*
X *	Define various output routines in terms on ASM_INT_OP,
X *	which should be defined in config.h -- if it's not, add it
X *	as the marker used to allocate an int on your architecture.
X */
X
X#ifndef ASM_OUTPUT_INT_CONST
X#define ASM_OUTPUT_INT_CONST(FILE,VALUE)	\
X  fprintf(FILE,"\t%s %d\n", ASM_INT_OP, VALUE)
X#endif
X
X#ifndef ASM_OUTPUT_LABELREF_AS_INT
X#define ASM_OUTPUT_LABELREF_AS_INT(FILE,NAME)	\
X  (fprintf(FILE,"\t%s", ASM_INT_OP), \
X   ASM_OUTPUT_LABELREF(FILE,NAME), \
X   fprintf(FILE,"\n"))
X#endif
X
X#ifndef ASM_OUTPUT_PTR_INT_SUM
X#define ASM_OUTPUT_PTR_INT_SUM(FILE,NAME,VALUE)	\
X  (fprintf(FILE,"\t%s", ASM_INT_OP), \
X   ASM_OUTPUT_LABELREF(FILE,NAME), \
X   fprintf(FILE,"+%d\n", VALUE))
X#endif
X
X#ifndef ASM_OUTPUT_SOURCE_FILENAME
X#define ASM_OUTPUT_SOURCE_FILENAME(FILE,NAME)\
X  fprintf (FILE, "\t.file\t\"%s\"\n", NAME);
X#endif
X
Xextern int xmalloc ();
Xextern void free ();
X
X#ifndef CTOR_TABLE_NAME
X#define CTOR_TABLE_NAME "__CTOR_LIST__"
X#endif
X
X#ifndef DTOR_TABLE_NAME
X#define DTOR_TABLE_NAME "__DTOR_LIST__"
X#endif
X
X/*	Define or undef this in your config.h. Should be defined for
X *	MIPS & Sun-386i.
X */
X
X#ifdef NO_UNDERSCORES
X#  ifndef CTOR_DTOR_MARKER_NAME
X#    define CTOR_DTOR_MARKER_NAME "_GLOBAL_$"
X#    define CTOR_DTOR_MARKER_LENGTH 9
X#    define CTOR_DTOR_MARKER_OFFSET 0
X#  endif
X#else
X#  ifndef CTOR_DTOR_MARKER_NAME
X#    define CTOR_DTOR_MARKER_NAME "__GLOBAL_$"
X#    define CTOR_DTOR_MARKER_LENGTH 10
X#    define CTOR_DTOR_MARKER_OFFSET 1
X#  endif
X#endif
X
Xenum error_code { OK, BAD_MAGIC, NO_NAMELIST,
X		  FOPEN_ERROR, FREAD_ERROR, FWRITE_ERROR,
X		  RANDOM_ERROR, };
X
Xenum error_code process ();
Xenum error_code process_a (), process_o ();
Xenum error_code output_ctor_dtor_table ();
Xvoid assemble_name ();
X
X/* Files for holding the assembly code for table of constructor
X   function pointer addresses and list of destructor
X   function pointer addresses.  */
Xstatic FILE *outfile;
X
X/* Default outfile name, or take name from argv with -o option.  */
Xstatic char *outfile_name = "a.out";
X
X/* For compatibility with toplev.c and tm-sun386.h  */
Xchar *dump_base_name;
Xint optimize = 0;
Xchar *language_string = "GNU C++";
X
X/*
X * The list of constructors & destructors. We process all files & then
X * spit these out in output_ctor_dtor_table(), because we need to know
X *  the length of the list.
X */
X
Xstruct ctor_dtor_list_elem
X{
X  struct ctor_dtor_list_elem *next;
X  char *name;
X} *dtor_chain, *ctor_chain;
X
Xint dtor_chain_length = 0;
Xint ctor_chain_length = 0;
X
Xmain (argc, argv)
X     int argc;
X     char *argv[];
X{
X  int i, nerrs = 0;
X  enum error_code code;
X  FILE *fp;
X  char *main_input_filename;
X
X  if (argc > 2 && !strcmp (argv[1], "-o"))
X    {
X      outfile_name = argv[2];
X      i = 3;
X    }
X  else
X    i = 1;
X
X  if ((outfile = fopen (outfile_name, "w")) == NULL)
X    {
X      perror ("collect");
X      exit (-1);
X    }
X
X  dump_base_name = main_input_filename = outfile_name;
X  for (; i < argc; i++)
X    {
X      char buf[80];
X
X      /* This is a library, skip it.  */
X      if (argv[i][0] == '-' && argv[i][1] == 'l')
X	continue;
X
X      if ((fp = fopen (argv[i], "r")) == NULL)
X	{
X	  sprintf (buf, "collect `%s'", argv[i]);
X	  perror (buf);
X	  exit (-1);
X	}
X
X      switch (code = process (fp, argv[i]))
X	{
X	case OK:
X	  break;
X
X	case BAD_MAGIC:
X	  fprintf (stderr, "file `%s' has a bad magic number for collect\n",
X		   argv[i]);
X	  exit (-1);
X
X	case NO_NAMELIST:
X	  fprintf (stderr, "file `%s' has a no namelist for collect\n",
X		   argv[i]);
X	  exit (-1);
X
X	case RANDOM_ERROR:
X	  fprintf (stderr, "random error while processing file `%s':\n",
X		   argv[i]);
X	  perror ("collect");
X	  exit (-1);
X
X	case FOPEN_ERROR:
X	  fprintf (stderr, "fopen(3S) error while processing file `%s' in collect\n",
X		   argv[i]);
X	  exit (-1);
X
X	case FREAD_ERROR:
X	  fprintf (stderr, "fread(3S) error while processing file `%s' in collect\n",
X		   argv[i]);
X	  exit (-1);
X
X	case FWRITE_ERROR:
X	  fprintf (stderr, "fwrite(3S) error while processing file `%s' in collect\n",
X		   argv[i]);
X	  exit (-1);
X
X	default:
X	  abort ();
X	}
X
X      fclose (fp);
X
X    }
X
X  switch (code = output_ctor_dtor_table ())
X    {
X    case OK:
X      fclose (outfile);
X      exit (0);
X    case FREAD_ERROR:
X      perror ("fread(3S) failed in collect, at end");
X      break;
X    case FWRITE_ERROR:
X      perror ("fwrite(3S) failed in collect, at end");
X      break;
X    case FOPEN_ERROR:
X      perror ("fopen(3S) failed in collect, at end");
X      break;
X    case RANDOM_ERROR:
X      fprintf (stderr, "random error in collect, at end");
X      break;
X    }
X  exit (-1);
X}
X
Xvoid
X  add_ctor_dtor_elem(symbol_name)
Xchar *symbol_name;
X{
X  /*
X   *	In EXTENDED_COFF systems, it's possible to
X   *	have multiple occurances of symbols ( or so it
X   *	appears) in the symbol table. Sooo, we scan to
X   *	eliminate duplicate entries. This can never hurt,
X   *	and helps EXTENDED_COFF.
X   */
X  int exists;
X  int is_ctor = (symbol_name[CTOR_DTOR_MARKER_LENGTH] == 'I');
X  
X  struct ctor_dtor_list_elem *p
X    = ((is_ctor) ? ctor_chain : dtor_chain);
X  
X  exists = 0;
X  while (p) {
X    if (strcmp( symbol_name, p -> name ) == 0 ) {
X      exists = 1;
X      break;
X    }
X    p = p -> next;
X  }
X  if ( ! exists ) {
X    
X    struct ctor_dtor_list_elem *new = (struct ctor_dtor_list_elem *)
X      xmalloc(sizeof(struct ctor_dtor_list_elem));
X    
X    new->name = (char *)xmalloc (strlen (symbol_name)
X				 + CTOR_DTOR_MARKER_OFFSET + 2);
X    
X    strcpy(new -> name, symbol_name + CTOR_DTOR_MARKER_OFFSET);
X    
X    if ( is_ctor ) {
X      new -> next = ctor_chain;
X      ctor_chain = new;
X      ctor_chain_length++;
X    }
X    else {
X      new->next = dtor_chain;
X      dtor_chain = new;
X      dtor_chain_length++;
X    }
X  }
X}
X
X
Xenum error_code
Xoutput_ctor_dtor_table ()
X{
X  int dtor_offset;
X
X  /* Write out the CTOR tabel */
X  ASM_FILE_START(outfile);
X
X  fprintf (outfile, "%s\n", TEXT_SECTION_ASM_OP);
X  ASM_GLOBALIZE_LABEL (outfile, CTOR_TABLE_NAME);
X  ASM_OUTPUT_LABEL (outfile, CTOR_TABLE_NAME);
X  ASM_OUTPUT_INT_CONST(outfile,ctor_chain_length);
X  while ( ctor_chain ) {
X    ASM_OUTPUT_LABELREF_AS_INT (outfile, ctor_chain->name);
X    ctor_chain = ctor_chain -> next;
X  }
X  /* NULL-terminate the list of constructors.  -- not needed, but keep it */
X  ASM_OUTPUT_INT_CONST (outfile, 0);
X
X  /*
X   * Now, lay out the destructors
X   */
X
X  fprintf (outfile, "%s\n", DATA_SECTION_ASM_OP);
X  ASM_GLOBALIZE_LABEL (outfile, DTOR_TABLE_NAME);
X  ASM_OUTPUT_LABEL (outfile, DTOR_TABLE_NAME);
X  ASM_OUTPUT_INT_CONST(outfile,dtor_chain_length);
X  while (dtor_chain)
X    {
X      ASM_OUTPUT_LABELREF_AS_INT (outfile, dtor_chain->name);
X      dtor_chain = dtor_chain->next;
X    }
X  ASM_OUTPUT_INT_CONST (outfile, 0);
X  ASM_OUTPUT_INT_CONST (outfile, 0);
X
X  fclose (outfile);
X  return OK;
X}
X
X
X/*****************************************************************************
X *	
X *		COFF & EXTENDED COFF
X *	
X ****************************************************************************/
X#if defined(COFF) || defined(EXTENDED_COFF)
X
X#include <ldfcn.h>
X
X#if defined(EXTENDED_COFF)
X#   define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax+SYMHEADER(X).iextMax)
X#   define GCC_SYMENT SYMR
X#   define GCC_OK_SYMBOL(X) ((X).st == stProc &&  (X).sc == scText)
X#   define GCC_SYMINC(X) (1)
X#else
X#   define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
X#   define GCC_SYMENT SYMENT
X#   define GCC_OK_SYMBOL(X) (!(((X).n_type & N_TMASK) != (DT_NON << N_BTSHFT))
X#   define GCC_SYMINC(X) ((X).n_numaux+1)
X#endif
X
Xenum error_code
X  process (fp, filename)
XFILE *fp;
Xchar *filename;
X{
X  LDFILE *ldptr = NULL;
X  do {
X    if ((ldptr = ldopen(filename, ldptr)) != NULL ) {
X      
X      if (!ISCOFF( HEADER(ldptr).f_magic ) ) {
X	return BAD_MAGIC;
X      }
X      else {
X	
X	int symbols = GCC_SYMBOLS(ldptr);
X	int symindex;
X	
X	for (symindex = 0;
X	     symindex < symbols;
X	     ) {
X	  
X	  GCC_SYMENT symbol;
X	  
X	  char *symbol_name;
X	  extern char *ldgetname();
X	  int returnCode;
X	  
X	  returnCode = ldtbread(ldptr, symindex, &symbol);
X	  
X	  if ( returnCode <= 0 ) {
X	    break;
X	  }
X	  
X	  symindex += GCC_SYMINC(symbol);
X	  
X	  if (! GCC_OK_SYMBOL(symbol)) continue;
X	  symbol_name = ldgetname(ldptr, &symbol);
X	  
X	  /* Check to see if we have a CTOR/DTOR marker  */
X
X	  if (! strncmp (CTOR_DTOR_MARKER_NAME, symbol_name,
X			 CTOR_DTOR_MARKER_LENGTH))
X	    add_ctor_dtor_elem(symbol_name);
X	}
X      }
X    }
X    else {
X      return( RANDOM_ERROR );
X    }
X  } while ( ldclose(ldptr) == FAILURE ) ;
X  return ( OK );
X}
X
X/****** taken from sdbout.c ******/
X
X
X/* Tell the assembler the source file name.
X   On systems that use SDB, this is done whether or not -g,
X   so it is called by ASM_FILE_START.
X
X   ASM_FILE is the assembler code output file,
X   INPUT_NAME is the name of the main input file.  */
X
X/* void */
Xsdbout_filename (asm_file, input_name)
X     FILE *asm_file;
X     char *input_name;
X{
X  int len = strlen (input_name);
X  char *na = input_name + len;
X
X  /* NA gets INPUT_NAME sans directory names.  */
X  while (na > input_name)
X    {
X      if (na[-1] == '/')
X	break;
X      na--;
X    }
X
X  ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
X}
X
X#else
X
X/*****************************************************************************
X *	
X *		BSD SYMBOL TABLES
X *	
X *****************************************************************************/
X
X/* Figure out the type of file we need to process.
X   Currently, only .o and .a formats are acceptable.  */
Xenum error_code
Xprocess (fp, filename)
X     FILE *fp;
X     char *filename;
X{
X  struct stat file_stat;
X  union
X    {
X      char ar_form[SARMAG];
X      struct exec a_out_form;
X    } header;
X  int size;
X
X  if (fstat (fp->_file, &file_stat))
X    return RANDOM_ERROR;
X
X  size = file_stat.st_size;
X
X  if (fread (header.ar_form, SARMAG, 1, fp) < 1)
X    return RANDOM_ERROR;
X
X  if (strncmp (ARMAG, header.ar_form, SARMAG))
X    {
X      fseek (fp, 0, 0);
X      if (fread (&header.a_out_form, sizeof (struct exec), 1, fp) < 1)
X	return RANDOM_ERROR;
X
X      if (N_BADMAG (header.a_out_form))
X	return BAD_MAGIC;
X
X      return process_o (fp, &header.a_out_form, size);
X    }
X  return process_a (fp);
X}
X
Xenum error_code
Xprocess_o (fp, header, size)
X     FILE *fp;
X     struct exec *header;
X     int size;
X{
X  int symoff, symend;
X#ifndef hp9000s300
X  struct nlist *nelem, *nelems, *nend;
X  char *strtab;
X#else
X  struct nlist_ *nelem, *nelems, *nend;
X#endif /* hp9000s300 */
X
X  if (N_BADMAG (*header))
X    return BAD_MAGIC;
X
X#ifndef hp9000s300
X  symoff = N_SYMOFF (*header);
X  symend = N_STROFF (*header);
X#else
X  symoff = LESYM_OFFSET (*header);
X  symend = DNTT_OFFSET (*header);
X#endif /* hp9000s300 */
X  if (symoff == symend)
X    return NO_NAMELIST;
X  fseek (fp, symoff - sizeof (struct exec), 1);
X#ifndef hp9000s300
X  nelems = (struct nlist *)alloca (symend - symoff);
X#else
X  nelems = (struct nlist_ *)alloca (symend - symoff);
X#endif /* hp9000s300 */
X  if (fread (nelems, sizeof (char), symend - symoff, fp) < symend - symoff)
X    return FREAD_ERROR;
X
X#ifndef hp9000s300
X  strtab = (char *)alloca ((char *)size - (char *)symend);
X  if (fread (strtab, sizeof (char), (char *)size - (char *)symend, fp)
X      < ((char *)size - (char *)symend) * sizeof (char))
X    return FREAD_ERROR;
X
X  nend = (struct nlist *)((char *)nelems + symend - symoff);
X  for (nelem = nelems; nelem < nend; nelem++)
X#else
X  nend = (struct nlist_ *)((char *)nelems + symend - symoff);
X  for (nelem = nelems; nelem < nend; )
X#endif /* hp9000s300 */
X    {
X#ifndef hp9000s300
X      int strindex = nelem->n_un.n_strx;
X#else
X      int symlen = nelem->n_length;
X      char p[255];
X      memcpy(p, (char *) (++nelem), symlen);
X      p[symlen]='\0';
X     
X      /* printf("'%s'\n",p);   */
X#endif /* hp9000s300 */
X
X#ifndef hp9000s300
X      if (strindex)
X#else
X      nelem   = (struct nlist_ *)((char *)nelem + symlen);
X      
X      if (symlen)
X#endif /* hp9000s300 */
X	{
X#ifndef hp9000s300
X	  char *p = strtab+strindex;
X#endif /* hp9000s300 */
X
X	  if (! strncmp ("__GLOBAL_$", p, 10))
X	    add_ctor_dtor_elem(p);
X	}
X    }
X  return OK;
X}
X
Xenum error_code
Xprocess_a (fp)
X     FILE *fp;
X{
X  struct ar_hdr header;
X  struct exec exec_header;
X  int size;
X  enum error_code code;
X
X  while (! feof (fp))
X    {
X      char c;
X#ifdef hp9000s300
X      int curpos;
X#endif /* hp9000s300 */
X
X      if (fread (&header, sizeof (struct ar_hdr), 1, fp) < 1)
X	return RANDOM_ERROR;
X
X      size = atoi (header.ar_size);
X#ifdef hp9000s300
X      curpos = ftell(fp);
X#endif /* hp9000s300 */
X
X#ifndef hp9000s300
X      if (fread (&exec_header, sizeof (struct exec), 1, fp) < 1)
X	return RANDOM_ERROR;
X#else
X      /* if the name starts with /, it's an index file */
X      if (header.ar_name[0] != '/') {
X      
X        if (fread (&exec_header, sizeof (struct exec), 1, fp) < 1)
X	  return RANDOM_ERROR;
X#endif /* hp9000s300 */
X
X      code = process_o (fp, &exec_header, size);
X      if (code != OK)
X	return code;
X#ifdef hp9000s300
X      } 
X      
X      if (fseek(fp,(long) curpos + size,0))
X	return RANDOM_ERROR;
X#endif /* hp9000s300 */
X      if ((c = getc (fp)) == '\n')
X	;
X      else
X	ungetc (c, fp);
X      c = getc (fp);
X      if (c != EOF)
X	ungetc (c, fp);
X    }
X  return OK;
X}
X#endif
X
X/* Output to FILE a reference to the assembler name of a C-level name NAME.
X   If NAME starts with a *, the rest of NAME is output verbatim.
X   Otherwise NAME is transformed in an implementation-defined way
X   (usually by the addition of an underscore).
X   Many macros in the tm file are defined to call this function.
X
X   Swiped from `varasm.c'  */
X
Xvoid
Xassemble_name (file, name)
X     FILE *file;
X     char *name;
X{
X  if (name[0] == '*')
X    fputs (&name[1], file);
X  else
X#ifdef NO_UNDERSCORES
X    fprintf (file, "%s", name);
X#else
X    fprintf (file, "_%s", name);
X#endif
X}
X
Xint
Xxmalloc (size)
X     int size;
X{
X  int result = malloc (size);
X  if (! result)
X    {
X      fprintf (stderr, "Virtual memory exhausted\n");
X      exit (-1);
X    }
X  return result;
X}
X#endif
END_OF_FILE
if test 15902 -ne `wc -c <'Patches/collect.c'`; then
    echo shar: \"'Patches/collect.c'\" unpacked with wrong size!
fi
# end of 'Patches/collect.c'
fi
if test ! -d 'Patches/config' ; then
    echo shar: Creating directory \"'Patches/config'\"
    mkdir 'Patches/config'
fi
if test -f 'Patches/gcc.c.diff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Patches/gcc.c.diff'\"
else
echo shar: Extracting \"'Patches/gcc.c.diff'\" \(2191 characters\)
sed "s/^X//" >'Patches/gcc.c.diff' <<'END_OF_FILE'
X*** /tmp/,RCSt1a13254	Wed Oct 11 11:50:09 1989
X--- gcc.c	Wed Oct 11 11:48:06 1989
X***************
X*** 297,307 ****
X    {0, 0}
X  };
X  
X! /* Here is the spec for running the linker, after compiling all files.  */
X! char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld %{o*} %l\
X!  %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
X!  %{y*} %{!nostdlib:%S} \
X!  %{L*} %o %{!nostdlib:gnulib%s %{g:-lg} -lg++ %L}\n }}}}";
X  
X  /* Accumulate a command (program name and args), and run it.  */
X  
X--- 297,324 ----
X    {0, 0}
X  };
X  
X! #ifdef USE_COLLECT
X!     /* C++: Here is the spec for collecting global ctor and dtor
X!        requirements.  */
X!     char *collect_spec =
X!       "%{!c:%{!M*:%{!E:%{!S:collect -o %g.S %g.R\n\
X!     as %g.S -o %g.O\n\
X!     ld %{o*} %g.R %g.O\n\
X!     }}}}";
X!     
X!     /* Here is the spec for running the linker, after compiling all files.  */
X!     char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld -r -o %g.R %l\
X!      %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
X!      %{y*} %{!nostdlib:%S} \
X!      %{L*} %o %{!nostdlib:gnulib%s %{g:-lg} -lg++ %L}\n }}}}";
X! 
X! #else
X!     /* Here is the spec for running the linker, after compiling all files.  */
X!     char *link_spec = "%{!c:%{!M*:%{!E:%{!S:ld %{o*} %l\
X!      %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\
X!      %{y*} %{!nostdlib:%S} \
X!      %{L*} %o %{!nostdlib:gnulib%s %{g:-lg} -lg++ %L}\n }}}}";
X! #endif
X  
X  /* Accumulate a command (program name and args), and run it.  */
X  
X***************
X*** 1796,1801 ****
X--- 1813,1833 ----
X    if (error_count == 0)
X      {
X        int tmp = execution_count;
X+ 
X+ #ifdef USE_COLLECT
X+   /* C++: now collect all the requirements for
X+      calling global constructors and destructors,
X+      and write them to a file.  We will link this file
X+      in when we run.  */
X+   if (linker_was_run && ! error_count)
X+     {
X+       int tmp = execution_count;
X+       value = do_spec (collect_spec);
X+       if (value < 0)
X+ 	error_count = 1;
X+       linker_was_run &= (tmp != execution_count);
X+     }
X+ #endif
X        value = do_spec (link_spec);
X        if (value < 0)
X  	error_count = 1;
END_OF_FILE
if test 2191 -ne `wc -c <'Patches/gcc.c.diff'`; then
    echo shar: \"'Patches/gcc.c.diff'\" unpacked with wrong size!
fi
# end of 'Patches/gcc.c.diff'
fi
echo shar: End of shell archive.
exit 0