1/* Collect static initialization info into data structures that can be
2   traversed by C++ initialization and finalization routines.
3   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5   Contributed by Chris Smith (csmith@convex.com).
6   Heavily modified by Michael Meissner (meissner@cygnus.com),
7   Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
8
9This file is part of GCC.
10
11GCC is free software; you can redistribute it and/or modify it under
12the terms of the GNU General Public License as published by the Free
13Software Foundation; either version 2, or (at your option) any later
14version.
15
16GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17WARRANTY; without even the implied warranty of MERCHANTABILITY or
18FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19for more details.
20
21You should have received a copy of the GNU General Public License
22along with GCC; see the file COPYING.  If not, write to the Free
23Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2402110-1301, USA.  */
25
26
27/* Build tables of static constructors and destructors and run ld.  */
28
29#include "config.h"
30#include "system.h"
31#include "coretypes.h"
32#include "tm.h"
33#include <signal.h>
34#if ! defined( SIGCHLD ) && defined( SIGCLD )
35#  define SIGCHLD SIGCLD
36#endif
37
38#ifndef LIBRARY_PATH_ENV
39#define LIBRARY_PATH_ENV "LIBRARY_PATH"
40#endif
41
42#define COLLECT
43
44#include "collect2.h"
45#include "demangle.h"
46#include "obstack.h"
47#include "intl.h"
48#include "version.h"
49
50/* On certain systems, we have code that works by scanning the object file
51   directly.  But this code uses system-specific header files and library
52   functions, so turn it off in a cross-compiler.  Likewise, the names of
53   the utilities are not correct for a cross-compiler; we have to hope that
54   cross-versions are in the proper directories.  */
55
56#ifdef CROSS_COMPILE
57#undef OBJECT_FORMAT_COFF
58#undef MD_EXEC_PREFIX
59#undef REAL_LD_FILE_NAME
60#undef REAL_NM_FILE_NAME
61#undef REAL_STRIP_FILE_NAME
62#endif
63
64/* If we cannot use a special method, use the ordinary one:
65   run nm to find what symbols are present.
66   In a cross-compiler, this means you need a cross nm,
67   but that is not quite as unpleasant as special headers.  */
68
69#if !defined (OBJECT_FORMAT_COFF)
70#define OBJECT_FORMAT_NONE
71#endif
72
73#ifdef OBJECT_FORMAT_COFF
74
75#include <a.out.h>
76#include <ar.h>
77
78#ifdef UMAX
79#include <sgs.h>
80#endif
81
82/* Many versions of ldfcn.h define these.  */
83#ifdef FREAD
84#undef FREAD
85#undef FWRITE
86#endif
87
88#include <ldfcn.h>
89
90/* Some systems have an ISCOFF macro, but others do not.  In some cases
91   the macro may be wrong.  MY_ISCOFF is defined in tm.h files for machines
92   that either do not have an ISCOFF macro in /usr/include or for those
93   where it is wrong.  */
94
95#ifndef MY_ISCOFF
96#define MY_ISCOFF(X) ISCOFF (X)
97#endif
98
99#endif /* OBJECT_FORMAT_COFF */
100
101#ifdef OBJECT_FORMAT_NONE
102
103/* Default flags to pass to nm.  */
104#ifndef NM_FLAGS
105#define NM_FLAGS "-n"
106#endif
107
108#endif /* OBJECT_FORMAT_NONE */
109
110/* Some systems use __main in a way incompatible with its use in gcc, in these
111   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
112   give the same symbol without quotes for an alternative entry point.  */
113#ifndef NAME__MAIN
114#define NAME__MAIN "__main"
115#endif
116
117/* This must match tree.h.  */
118#define DEFAULT_INIT_PRIORITY 65535
119
120#ifndef COLLECT_SHARED_INIT_FUNC
121#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
122  fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
123#endif
124#ifndef COLLECT_SHARED_FINI_FUNC
125#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
126  fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
127#endif
128
129#ifdef LDD_SUFFIX
130#define SCAN_LIBRARIES
131#endif
132
133#ifdef USE_COLLECT2
134int do_collecting = 1;
135#else
136int do_collecting = 0;
137#endif
138
139/* Nonzero if we should suppress the automatic demangling of identifiers
140   in linker error messages.  Set from COLLECT_NO_DEMANGLE.  */
141int no_demangle;
142
143/* Linked lists of constructor and destructor names.  */
144
145struct id
146{
147  struct id *next;
148  int sequence;
149  char name[1];
150};
151
152struct head
153{
154  struct id *first;
155  struct id *last;
156  int number;
157};
158
159/* Enumeration giving which pass this is for scanning the program file.  */
160
161enum pass {
162  PASS_FIRST,				/* without constructors */
163  PASS_OBJ,				/* individual objects */
164  PASS_LIB,				/* looking for shared libraries */
165  PASS_SECOND				/* with constructors linked in */
166};
167
168int vflag;				/* true if -v */
169static int rflag;			/* true if -r */
170static int strip_flag;			/* true if -s */
171static const char *demangle_flag;
172#ifdef COLLECT_EXPORT_LIST
173static int export_flag;                 /* true if -bE */
174static int aix64_flag;			/* true if -b64 */
175static int aixrtl_flag;			/* true if -brtl */
176#endif
177
178int debug;				/* true if -debug */
179
180static int shared_obj;			/* true if -shared */
181
182static const char *c_file;		/* <xxx>.c for constructor/destructor list.  */
183static const char *o_file;		/* <xxx>.o for constructor/destructor list.  */
184#ifdef COLLECT_EXPORT_LIST
185static const char *export_file;		/* <xxx>.x for AIX export list.  */
186#endif
187const char *ldout;			/* File for ld stdout.  */
188const char *lderrout;			/* File for ld stderr.  */
189static const char *output_file;		/* Output file for ld.  */
190static const char *nm_file_name;	/* pathname of nm */
191#ifdef LDD_SUFFIX
192static const char *ldd_file_name;	/* pathname of ldd (or equivalent) */
193#endif
194static const char *strip_file_name;		/* pathname of strip */
195const char *c_file_name;		/* pathname of gcc */
196static char *initname, *fininame;	/* names of init and fini funcs */
197
198static struct head constructors;	/* list of constructors found */
199static struct head destructors;		/* list of destructors found */
200#ifdef COLLECT_EXPORT_LIST
201static struct head exports;		/* list of exported symbols */
202#endif
203static struct head frame_tables;	/* list of frame unwind info tables */
204
205struct obstack temporary_obstack;
206char * temporary_firstobj;
207
208/* Structure to hold all the directories in which to search for files to
209   execute.  */
210
211struct prefix_list
212{
213  const char *prefix;         /* String to prepend to the path.  */
214  struct prefix_list *next;   /* Next in linked list.  */
215};
216
217struct path_prefix
218{
219  struct prefix_list *plist;  /* List of prefixes to try */
220  int max_len;                /* Max length of a prefix in PLIST */
221  const char *name;           /* Name of this list (used in config stuff) */
222};
223
224#ifdef COLLECT_EXPORT_LIST
225/* Lists to keep libraries to be scanned for global constructors/destructors.  */
226static struct head libs;                    /* list of libraries */
227static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
228static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
229static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
230					  &libpath_lib_dirs, NULL};
231#endif
232
233static void handler (int);
234static int is_ctor_dtor (const char *);
235static char *find_a_file (struct path_prefix *, const char *);
236static void add_prefix (struct path_prefix *, const char *);
237static void prefix_from_env (const char *, struct path_prefix *);
238static void prefix_from_string (const char *, struct path_prefix *);
239static void do_wait (const char *, struct pex_obj *);
240static void fork_execute (const char *, char **);
241static void maybe_unlink (const char *);
242static void add_to_list (struct head *, const char *);
243static int extract_init_priority (const char *);
244static void sort_ids (struct head *);
245static void write_list (FILE *, const char *, struct id *);
246#ifdef COLLECT_EXPORT_LIST
247static void dump_list (FILE *, const char *, struct id *);
248#endif
249#if 0
250static void dump_prefix_list (FILE *, const char *, struct prefix_list *);
251#endif
252static void write_list_with_asm (FILE *, const char *, struct id *);
253static void write_c_file (FILE *, const char *);
254static void write_c_file_stat (FILE *, const char *);
255#ifndef LD_INIT_SWITCH
256static void write_c_file_glob (FILE *, const char *);
257#endif
258static void scan_prog_file (const char *, enum pass);
259#ifdef SCAN_LIBRARIES
260static void scan_libraries (const char *);
261#endif
262#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
263static int is_in_args (const char *, const char **, const char **);
264#endif
265#ifdef COLLECT_EXPORT_LIST
266#if 0
267static int is_in_list (const char *, struct id *);
268#endif
269static void write_aix_file (FILE *, struct id *);
270static char *resolve_lib_name (const char *);
271#endif
272static char *extract_string (const char **);
273
274/* Delete tempfiles and exit function.  */
275
276void
277collect_exit (int status)
278{
279  if (c_file != 0 && c_file[0])
280    maybe_unlink (c_file);
281
282  if (o_file != 0 && o_file[0])
283    maybe_unlink (o_file);
284
285#ifdef COLLECT_EXPORT_LIST
286  if (export_file != 0 && export_file[0])
287    maybe_unlink (export_file);
288#endif
289
290  if (ldout != 0 && ldout[0])
291    {
292      dump_file (ldout, stdout);
293      maybe_unlink (ldout);
294    }
295
296  if (lderrout != 0 && lderrout[0])
297    {
298      dump_file (lderrout, stderr);
299      maybe_unlink (lderrout);
300    }
301
302  if (status != 0 && output_file != 0 && output_file[0])
303    maybe_unlink (output_file);
304
305  exit (status);
306}
307
308
309/* Notify user of a non-error.  */
310void
311notice (const char *cmsgid, ...)
312{
313  va_list ap;
314
315  va_start (ap, cmsgid);
316  vfprintf (stderr, _(cmsgid), ap);
317  va_end (ap);
318}
319
320/* Die when sys call fails.  */
321
322void
323fatal_perror (const char * cmsgid, ...)
324{
325  int e = errno;
326  va_list ap;
327
328  va_start (ap, cmsgid);
329  fprintf (stderr, "collect2: ");
330  vfprintf (stderr, _(cmsgid), ap);
331  fprintf (stderr, ": %s\n", xstrerror (e));
332  va_end (ap);
333
334  collect_exit (FATAL_EXIT_CODE);
335}
336
337/* Just die.  */
338
339void
340fatal (const char * cmsgid, ...)
341{
342  va_list ap;
343
344  va_start (ap, cmsgid);
345  fprintf (stderr, "collect2: ");
346  vfprintf (stderr, _(cmsgid), ap);
347  fprintf (stderr, "\n");
348  va_end (ap);
349
350  collect_exit (FATAL_EXIT_CODE);
351}
352
353/* Write error message.  */
354
355void
356error (const char * gmsgid, ...)
357{
358  va_list ap;
359
360  va_start (ap, gmsgid);
361  fprintf (stderr, "collect2: ");
362  vfprintf (stderr, _(gmsgid), ap);
363  fprintf (stderr, "\n");
364  va_end(ap);
365}
366
367/* In case obstack is linked in, and abort is defined to fancy_abort,
368   provide a default entry.  */
369
370void
371fancy_abort (const char *file, int line, const char *func)
372{
373  fatal ("internal gcc abort in %s, at %s:%d", func, file, line);
374}
375
376static void
377handler (int signo)
378{
379  if (c_file != 0 && c_file[0])
380    maybe_unlink (c_file);
381
382  if (o_file != 0 && o_file[0])
383    maybe_unlink (o_file);
384
385  if (ldout != 0 && ldout[0])
386    maybe_unlink (ldout);
387
388  if (lderrout != 0 && lderrout[0])
389    maybe_unlink (lderrout);
390
391#ifdef COLLECT_EXPORT_LIST
392  if (export_file != 0 && export_file[0])
393    maybe_unlink (export_file);
394#endif
395
396  signal (signo, SIG_DFL);
397  raise (signo);
398}
399
400
401int
402file_exists (const char *name)
403{
404  return access (name, R_OK) == 0;
405}
406
407/* Parse a reasonable subset of shell quoting syntax.  */
408
409static char *
410extract_string (const char **pp)
411{
412  const char *p = *pp;
413  int backquote = 0;
414  int inside = 0;
415
416  for (;;)
417    {
418      char c = *p;
419      if (c == '\0')
420	break;
421      ++p;
422      if (backquote)
423	obstack_1grow (&temporary_obstack, c);
424      else if (! inside && c == ' ')
425	break;
426      else if (! inside && c == '\\')
427	backquote = 1;
428      else if (c == '\'')
429	inside = !inside;
430      else
431	obstack_1grow (&temporary_obstack, c);
432    }
433
434  obstack_1grow (&temporary_obstack, '\0');
435  *pp = p;
436  return XOBFINISH (&temporary_obstack, char *);
437}
438
439void
440dump_file (const char *name, FILE *to)
441{
442  FILE *stream = fopen (name, "r");
443
444  if (stream == 0)
445    return;
446  while (1)
447    {
448      int c;
449      while (c = getc (stream),
450	     c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
451	obstack_1grow (&temporary_obstack, c);
452      if (obstack_object_size (&temporary_obstack) > 0)
453	{
454	  const char *word, *p;
455	  char *result;
456	  obstack_1grow (&temporary_obstack, '\0');
457	  word = XOBFINISH (&temporary_obstack, const char *);
458
459	  if (*word == '.')
460	    ++word, putc ('.', to);
461	  p = word;
462	  if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
463	    p += strlen (USER_LABEL_PREFIX);
464
465#ifdef HAVE_LD_DEMANGLE
466	  result = 0;
467#else
468	  if (no_demangle)
469	    result = 0;
470	  else
471	    result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
472#endif
473
474	  if (result)
475	    {
476	      int diff;
477	      fputs (result, to);
478
479	      diff = strlen (word) - strlen (result);
480	      while (diff > 0 && c == ' ')
481		--diff, putc (' ', to);
482	      while (diff < 0 && c == ' ')
483		++diff, c = getc (stream);
484
485	      free (result);
486	    }
487	  else
488	    fputs (word, to);
489
490	  fflush (to);
491	  obstack_free (&temporary_obstack, temporary_firstobj);
492	}
493      if (c == EOF)
494	break;
495      putc (c, to);
496    }
497  fclose (stream);
498}
499
500/* Decide whether the given symbol is: a constructor (1), a destructor
501   (2), a routine in a shared object that calls all the constructors
502   (3) or destructors (4), a DWARF exception-handling table (5), or
503   nothing special (0).  */
504
505static int
506is_ctor_dtor (const char *s)
507{
508  struct names { const char *const name; const int len; const int ret;
509    const int two_underscores; };
510
511  const struct names *p;
512  int ch;
513  const char *orig_s = s;
514
515  static const struct names special[] = {
516#ifndef NO_DOLLAR_IN_LABEL
517    { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
518    { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
519#else
520#ifndef NO_DOT_IN_LABEL
521    { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
522    { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
523#endif /* NO_DOT_IN_LABEL */
524#endif /* NO_DOLLAR_IN_LABEL */
525    { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
526    { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
527    { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
528    { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
529    { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
530    { NULL, 0, 0, 0 }
531  };
532
533  while ((ch = *s) == '_')
534    ++s;
535
536  if (s == orig_s)
537    return 0;
538
539  for (p = &special[0]; p->len > 0; p++)
540    {
541      if (ch == p->name[0]
542	  && (!p->two_underscores || ((s - orig_s) >= 2))
543	  && strncmp(s, p->name, p->len) == 0)
544	{
545	  return p->ret;
546	}
547    }
548  return 0;
549}
550
551/* We maintain two prefix lists: one from COMPILER_PATH environment variable
552   and one from the PATH variable.  */
553
554static struct path_prefix cpath, path;
555
556#ifdef CROSS_COMPILE
557/* This is the name of the target machine.  We use it to form the name
558   of the files to execute.  */
559
560static const char *const target_machine = TARGET_MACHINE;
561#endif
562
563/* Search for NAME using prefix list PPREFIX.  We only look for executable
564   files.
565
566   Return 0 if not found, otherwise return its name, allocated with malloc.  */
567
568static char *
569find_a_file (struct path_prefix *pprefix, const char *name)
570{
571  char *temp;
572  struct prefix_list *pl;
573  int len = pprefix->max_len + strlen (name) + 1;
574
575  if (debug)
576    fprintf (stderr, "Looking for '%s'\n", name);
577
578#ifdef HOST_EXECUTABLE_SUFFIX
579  len += strlen (HOST_EXECUTABLE_SUFFIX);
580#endif
581
582  temp = XNEWVEC (char, len);
583
584  /* Determine the filename to execute (special case for absolute paths).  */
585
586  if (*name == '/'
587#ifdef HAVE_DOS_BASED_FILE_SYSTEM
588      || (*name && name[1] == ':')
589#endif
590      )
591    {
592      if (access (name, X_OK) == 0)
593	{
594	  strcpy (temp, name);
595
596	  if (debug)
597	    fprintf (stderr, "  - found: absolute path\n");
598
599	  return temp;
600	}
601
602#ifdef HOST_EXECUTABLE_SUFFIX
603	/* Some systems have a suffix for executable files.
604	   So try appending that.  */
605      strcpy (temp, name);
606	strcat (temp, HOST_EXECUTABLE_SUFFIX);
607
608	if (access (temp, X_OK) == 0)
609	  return temp;
610#endif
611
612      if (debug)
613	fprintf (stderr, "  - failed to locate using absolute path\n");
614    }
615  else
616    for (pl = pprefix->plist; pl; pl = pl->next)
617      {
618	struct stat st;
619
620	strcpy (temp, pl->prefix);
621	strcat (temp, name);
622
623	if (stat (temp, &st) >= 0
624	    && ! S_ISDIR (st.st_mode)
625	    && access (temp, X_OK) == 0)
626	  return temp;
627
628#ifdef HOST_EXECUTABLE_SUFFIX
629	/* Some systems have a suffix for executable files.
630	   So try appending that.  */
631	strcat (temp, HOST_EXECUTABLE_SUFFIX);
632
633	if (stat (temp, &st) >= 0
634	    && ! S_ISDIR (st.st_mode)
635	    && access (temp, X_OK) == 0)
636	  return temp;
637#endif
638      }
639
640  if (debug && pprefix->plist == NULL)
641    fprintf (stderr, "  - failed: no entries in prefix list\n");
642
643  free (temp);
644  return 0;
645}
646
647/* Add an entry for PREFIX to prefix list PPREFIX.  */
648
649static void
650add_prefix (struct path_prefix *pprefix, const char *prefix)
651{
652  struct prefix_list *pl, **prev;
653  int len;
654
655  if (pprefix->plist)
656    {
657      for (pl = pprefix->plist; pl->next; pl = pl->next)
658	;
659      prev = &pl->next;
660    }
661  else
662    prev = &pprefix->plist;
663
664  /* Keep track of the longest prefix.  */
665
666  len = strlen (prefix);
667  if (len > pprefix->max_len)
668    pprefix->max_len = len;
669
670  pl = XNEW (struct prefix_list);
671  pl->prefix = xstrdup (prefix);
672
673  if (*prev)
674    pl->next = *prev;
675  else
676    pl->next = (struct prefix_list *) 0;
677  *prev = pl;
678}
679
680/* Take the value of the environment variable ENV, break it into a path, and
681   add of the entries to PPREFIX.  */
682
683static void
684prefix_from_env (const char *env, struct path_prefix *pprefix)
685{
686  const char *p;
687  GET_ENVIRONMENT (p, env);
688
689  if (p)
690    prefix_from_string (p, pprefix);
691}
692
693static void
694prefix_from_string (const char *p, struct path_prefix *pprefix)
695{
696  const char *startp, *endp;
697  char *nstore = XNEWVEC (char, strlen (p) + 3);
698
699  if (debug)
700    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
701
702  startp = endp = p;
703  while (1)
704    {
705      if (*endp == PATH_SEPARATOR || *endp == 0)
706	{
707	  strncpy (nstore, startp, endp-startp);
708	  if (endp == startp)
709	    {
710	      strcpy (nstore, "./");
711	    }
712	  else if (! IS_DIR_SEPARATOR (endp[-1]))
713	    {
714	      nstore[endp-startp] = DIR_SEPARATOR;
715	      nstore[endp-startp+1] = 0;
716	    }
717	  else
718	    nstore[endp-startp] = 0;
719
720	  if (debug)
721	    fprintf (stderr, "  - add prefix: %s\n", nstore);
722
723	  add_prefix (pprefix, nstore);
724	  if (*endp == 0)
725	    break;
726	  endp = startp = endp + 1;
727	}
728      else
729	endp++;
730    }
731}
732
733/* Main program.  */
734
735int
736main (int argc, char **argv)
737{
738  static const char *const ld_suffix	= "ld";
739  static const char *const real_ld_suffix = "real-ld";
740  static const char *const collect_ld_suffix = "collect-ld";
741  static const char *const nm_suffix	= "nm";
742  static const char *const gnm_suffix	= "gnm";
743#ifdef LDD_SUFFIX
744  static const char *const ldd_suffix	= LDD_SUFFIX;
745#endif
746  static const char *const strip_suffix = "strip";
747  static const char *const gstrip_suffix = "gstrip";
748
749#ifdef CROSS_COMPILE
750  /* If we look for a program in the compiler directories, we just use
751     the short name, since these directories are already system-specific.
752     But it we look for a program in the system directories, we need to
753     qualify the program name with the target machine.  */
754
755  const char *const full_ld_suffix =
756    concat(target_machine, "-", ld_suffix, NULL);
757  const char *const full_nm_suffix =
758    concat (target_machine, "-", nm_suffix, NULL);
759  const char *const full_gnm_suffix =
760    concat (target_machine, "-", gnm_suffix, NULL);
761#ifdef LDD_SUFFIX
762  const char *const full_ldd_suffix =
763    concat (target_machine, "-", ldd_suffix, NULL);
764#endif
765  const char *const full_strip_suffix =
766    concat (target_machine, "-", strip_suffix, NULL);
767  const char *const full_gstrip_suffix =
768    concat (target_machine, "-", gstrip_suffix, NULL);
769#else
770  const char *const full_ld_suffix	= ld_suffix;
771  const char *const full_nm_suffix	= nm_suffix;
772  const char *const full_gnm_suffix	= gnm_suffix;
773#ifdef LDD_SUFFIX
774  const char *const full_ldd_suffix	= ldd_suffix;
775#endif
776  const char *const full_strip_suffix	= strip_suffix;
777  const char *const full_gstrip_suffix	= gstrip_suffix;
778#endif /* CROSS_COMPILE */
779
780  const char *arg;
781  FILE *outf;
782#ifdef COLLECT_EXPORT_LIST
783  FILE *exportf;
784#endif
785  const char *ld_file_name;
786  const char *p;
787  char **c_argv;
788  const char **c_ptr;
789  char **ld1_argv;
790  const char **ld1;
791  char **ld2_argv;
792  const char **ld2;
793  char **object_lst;
794  const char **object;
795  int first_file;
796  int num_c_args	= argc+9;
797
798  no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
799
800  /* Suppress demangling by the real linker, which may be broken.  */
801  putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
802
803#if defined (COLLECT2_HOST_INITIALIZATION)
804  /* Perform system dependent initialization, if necessary.  */
805  COLLECT2_HOST_INITIALIZATION;
806#endif
807
808#ifdef SIGCHLD
809  /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
810     receive the signal.  A different setting is inheritable */
811  signal (SIGCHLD, SIG_DFL);
812#endif
813
814  /* Unlock the stdio streams.  */
815  unlock_std_streams ();
816
817  gcc_init_libintl ();
818
819  /* Do not invoke xcalloc before this point, since locale needs to be
820     set first, in case a diagnostic is issued.  */
821
822  ld1 = (const char **)(ld1_argv = xcalloc(sizeof (char *), argc+4));
823  ld2 = (const char **)(ld2_argv = xcalloc(sizeof (char *), argc+11));
824  object = (const char **)(object_lst = xcalloc(sizeof (char *), argc));
825
826#ifdef DEBUG
827  debug = 1;
828#endif
829
830  /* Parse command line early for instances of -debug.  This allows
831     the debug flag to be set before functions like find_a_file()
832     are called.  */
833  {
834    int i;
835
836    for (i = 1; argv[i] != NULL; i ++)
837      {
838	if (! strcmp (argv[i], "-debug"))
839	  debug = 1;
840      }
841    vflag = debug;
842  }
843
844#ifndef DEFAULT_A_OUT_NAME
845  output_file = "a.out";
846#else
847  output_file = DEFAULT_A_OUT_NAME;
848#endif
849
850  obstack_begin (&temporary_obstack, 0);
851  temporary_firstobj = obstack_alloc (&temporary_obstack, 0);
852
853#ifndef HAVE_LD_DEMANGLE
854  current_demangling_style = auto_demangling;
855#endif
856  p = getenv ("COLLECT_GCC_OPTIONS");
857  while (p && *p)
858    {
859      const char *q = extract_string (&p);
860      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
861	num_c_args++;
862    }
863  obstack_free (&temporary_obstack, temporary_firstobj);
864
865  /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
866     -fno-exceptions -w */
867  num_c_args += 5;
868
869  c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
870
871  if (argc < 2)
872    fatal ("no arguments");
873
874#ifdef SIGQUIT
875  if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
876    signal (SIGQUIT, handler);
877#endif
878  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
879    signal (SIGINT, handler);
880#ifdef SIGALRM
881  if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
882    signal (SIGALRM, handler);
883#endif
884#ifdef SIGHUP
885  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
886    signal (SIGHUP, handler);
887#endif
888  if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
889    signal (SIGSEGV, handler);
890#ifdef SIGBUS
891  if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
892    signal (SIGBUS, handler);
893#endif
894
895  /* Extract COMPILER_PATH and PATH into our prefix list.  */
896  prefix_from_env ("COMPILER_PATH", &cpath);
897  prefix_from_env ("PATH", &path);
898
899  /* Try to discover a valid linker/nm/strip to use.  */
900
901  /* Maybe we know the right file to use (if not cross).  */
902  ld_file_name = 0;
903#ifdef DEFAULT_LINKER
904  if (access (DEFAULT_LINKER, X_OK) == 0)
905    ld_file_name = DEFAULT_LINKER;
906  if (ld_file_name == 0)
907#endif
908#ifdef REAL_LD_FILE_NAME
909  ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
910  if (ld_file_name == 0)
911#endif
912  /* Search the (target-specific) compiler dirs for ld'.  */
913  ld_file_name = find_a_file (&cpath, real_ld_suffix);
914  /* Likewise for `collect-ld'.  */
915  if (ld_file_name == 0)
916    ld_file_name = find_a_file (&cpath, collect_ld_suffix);
917  /* Search the compiler directories for `ld'.  We have protection against
918     recursive calls in find_a_file.  */
919  if (ld_file_name == 0)
920    ld_file_name = find_a_file (&cpath, ld_suffix);
921  /* Search the ordinary system bin directories
922     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
923  if (ld_file_name == 0)
924    ld_file_name = find_a_file (&path, full_ld_suffix);
925
926#ifdef REAL_NM_FILE_NAME
927  nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
928  if (nm_file_name == 0)
929#endif
930  nm_file_name = find_a_file (&cpath, gnm_suffix);
931  if (nm_file_name == 0)
932    nm_file_name = find_a_file (&path, full_gnm_suffix);
933  if (nm_file_name == 0)
934    nm_file_name = find_a_file (&cpath, nm_suffix);
935  if (nm_file_name == 0)
936    nm_file_name = find_a_file (&path, full_nm_suffix);
937
938#ifdef LDD_SUFFIX
939  ldd_file_name = find_a_file (&cpath, ldd_suffix);
940  if (ldd_file_name == 0)
941    ldd_file_name = find_a_file (&path, full_ldd_suffix);
942#endif
943
944#ifdef REAL_STRIP_FILE_NAME
945  strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
946  if (strip_file_name == 0)
947#endif
948  strip_file_name = find_a_file (&cpath, gstrip_suffix);
949  if (strip_file_name == 0)
950    strip_file_name = find_a_file (&path, full_gstrip_suffix);
951  if (strip_file_name == 0)
952    strip_file_name = find_a_file (&cpath, strip_suffix);
953  if (strip_file_name == 0)
954    strip_file_name = find_a_file (&path, full_strip_suffix);
955
956  /* Determine the full path name of the C compiler to use.  */
957  c_file_name = getenv ("COLLECT_GCC");
958  if (c_file_name == 0)
959    {
960#ifdef CROSS_COMPILE
961      c_file_name = concat (target_machine, "-gcc", NULL);
962#else
963      c_file_name = "gcc";
964#endif
965    }
966
967  p = find_a_file (&cpath, c_file_name);
968
969  /* Here it should be safe to use the system search path since we should have
970     already qualified the name of the compiler when it is needed.  */
971  if (p == 0)
972    p = find_a_file (&path, c_file_name);
973
974  if (p)
975    c_file_name = p;
976
977  *ld1++ = *ld2++ = ld_file_name;
978
979  /* Make temp file names.  */
980  c_file = make_temp_file (".c");
981  o_file = make_temp_file (".o");
982#ifdef COLLECT_EXPORT_LIST
983  export_file = make_temp_file (".x");
984#endif
985  ldout = make_temp_file (".ld");
986  lderrout = make_temp_file (".le");
987  *c_ptr++ = c_file_name;
988  *c_ptr++ = "-x";
989  *c_ptr++ = "c";
990  *c_ptr++ = "-c";
991  *c_ptr++ = "-o";
992  *c_ptr++ = o_file;
993
994#ifdef COLLECT_EXPORT_LIST
995  /* Generate a list of directories from LIBPATH.  */
996  prefix_from_env ("LIBPATH", &libpath_lib_dirs);
997  /* Add to this list also two standard directories where
998     AIX loader always searches for libraries.  */
999  add_prefix (&libpath_lib_dirs, "/lib");
1000  add_prefix (&libpath_lib_dirs, "/usr/lib");
1001#endif
1002
1003  /* Get any options that the upper GCC wants to pass to the sub-GCC.
1004
1005     AIX support needs to know if -shared has been specified before
1006     parsing commandline arguments.  */
1007
1008  p = getenv ("COLLECT_GCC_OPTIONS");
1009  while (p && *p)
1010    {
1011      const char *q = extract_string (&p);
1012      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1013	*c_ptr++ = xstrdup (q);
1014      if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1015	*c_ptr++ = xstrdup (q);
1016      if (strcmp (q, "-shared") == 0)
1017	shared_obj = 1;
1018      if (*q == '-' && q[1] == 'B')
1019	{
1020	  *c_ptr++ = xstrdup (q);
1021	  if (q[2] == 0)
1022	    {
1023	      q = extract_string (&p);
1024	      *c_ptr++ = xstrdup (q);
1025	    }
1026	}
1027    }
1028  obstack_free (&temporary_obstack, temporary_firstobj);
1029  *c_ptr++ = "-fno-profile-arcs";
1030  *c_ptr++ = "-fno-test-coverage";
1031  *c_ptr++ = "-fno-branch-probabilities";
1032  *c_ptr++ = "-fno-exceptions";
1033  *c_ptr++ = "-w";
1034
1035  /* !!! When GCC calls collect2,
1036     it does not know whether it is calling collect2 or ld.
1037     So collect2 cannot meaningfully understand any options
1038     except those ld understands.
1039     If you propose to make GCC pass some other option,
1040     just imagine what will happen if ld is really ld!!!  */
1041
1042  /* Parse arguments.  Remember output file spec, pass the rest to ld.  */
1043  /* After the first file, put in the c++ rt0.  */
1044
1045  first_file = 1;
1046#ifdef HAVE_LD_DEMANGLE
1047  if (!demangle_flag && !no_demangle)
1048    demangle_flag = "--demangle";
1049  if (demangle_flag)
1050    *ld1++ = *ld2++ = demangle_flag;
1051#endif
1052  while ((arg = *++argv) != (char *) 0)
1053    {
1054      *ld1++ = *ld2++ = arg;
1055
1056      if (arg[0] == '-')
1057	{
1058	  switch (arg[1])
1059	    {
1060#ifdef COLLECT_EXPORT_LIST
1061	    /* We want to disable automatic exports on AIX when user
1062	       explicitly puts an export list in command line */
1063	    case 'b':
1064	      if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1065		export_flag = 1;
1066	      else if (arg[2] == '6' && arg[3] == '4')
1067		aix64_flag = 1;
1068	      else if (arg[2] == 'r' && arg[3] == 't' && arg[4] == 'l')
1069		aixrtl_flag = 1;
1070	      break;
1071#endif
1072
1073	    case 'd':
1074	      if (!strcmp (arg, "-debug"))
1075		{
1076		  /* Already parsed.  */
1077		  ld1--;
1078		  ld2--;
1079		}
1080	      if (!strcmp (arg, "-dynamic-linker") && argv[1])
1081		{
1082		  ++argv;
1083		  *ld1++ = *ld2++ = *argv;
1084		}
1085	      break;
1086
1087	    case 'l':
1088	      if (first_file)
1089		{
1090		  /* place o_file BEFORE this argument! */
1091		  first_file = 0;
1092		  ld2--;
1093		  *ld2++ = o_file;
1094		  *ld2++ = arg;
1095		}
1096#ifdef COLLECT_EXPORT_LIST
1097	      {
1098		/* Resolving full library name.  */
1099		const char *s = resolve_lib_name (arg+2);
1100
1101		/* Saving a full library name.  */
1102		add_to_list (&libs, s);
1103	      }
1104#endif
1105	      break;
1106
1107#ifdef COLLECT_EXPORT_LIST
1108	    /* Saving directories where to search for libraries.  */
1109	    case 'L':
1110	      add_prefix (&cmdline_lib_dirs, arg+2);
1111	      break;
1112#else
1113#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1114	    case 'L':
1115	      if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
1116		--ld1;
1117	      break;
1118#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1119#endif
1120
1121	    case 'o':
1122	      if (arg[2] == '\0')
1123		output_file = *ld1++ = *ld2++ = *++argv;
1124	      else if (1
1125#ifdef SWITCHES_NEED_SPACES
1126		       && ! strchr (SWITCHES_NEED_SPACES, arg[1])
1127#endif
1128		       )
1129
1130		output_file = &arg[2];
1131	      break;
1132
1133	    case 'r':
1134	      if (arg[2] == '\0')
1135		rflag = 1;
1136	      break;
1137
1138	    case 's':
1139	      if (arg[2] == '\0' && do_collecting)
1140		{
1141		  /* We must strip after the nm run, otherwise C++ linking
1142		     will not work.  Thus we strip in the second ld run, or
1143		     else with strip if there is no second ld run.  */
1144		  strip_flag = 1;
1145		  ld1--;
1146		}
1147	      break;
1148
1149	    case 'v':
1150	      if (arg[2] == '\0')
1151		vflag = 1;
1152	      break;
1153
1154	    case '-':
1155	      if (strcmp (arg, "--no-demangle") == 0)
1156		{
1157		  demangle_flag = arg;
1158		  no_demangle = 1;
1159		  ld1--;
1160		  ld2--;
1161		}
1162	      else if (strncmp (arg, "--demangle", 10) == 0)
1163		{
1164		  demangle_flag = arg;
1165		  no_demangle = 0;
1166#ifndef HAVE_LD_DEMANGLE
1167		  if (arg[10] == '=')
1168		    {
1169		      enum demangling_styles style
1170			= cplus_demangle_name_to_style (arg+11);
1171		      if (style == unknown_demangling)
1172			error ("unknown demangling style '%s'", arg+11);
1173		      else
1174			current_demangling_style = style;
1175		    }
1176#endif
1177		  ld1--;
1178		  ld2--;
1179		}
1180	      break;
1181	    }
1182	}
1183      else if ((p = strrchr (arg, '.')) != (char *) 0
1184	       && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1185		   || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1186		   || strcmp (p, ".obj") == 0))
1187	{
1188	  if (first_file)
1189	    {
1190	      first_file = 0;
1191	      if (p[1] == 'o')
1192		*ld2++ = o_file;
1193	      else
1194		{
1195		  /* place o_file BEFORE this argument! */
1196		  ld2--;
1197		  *ld2++ = o_file;
1198		  *ld2++ = arg;
1199		}
1200	    }
1201	  if (p[1] == 'o' || p[1] == 'l')
1202	    *object++ = arg;
1203#ifdef COLLECT_EXPORT_LIST
1204	  /* libraries can be specified directly, i.e. without -l flag.  */
1205	  else
1206	    {
1207	      /* Saving a full library name.  */
1208	      add_to_list (&libs, arg);
1209	    }
1210#endif
1211	}
1212    }
1213
1214#ifdef COLLECT_EXPORT_LIST
1215  /* This is added only for debugging purposes.  */
1216  if (debug)
1217    {
1218      fprintf (stderr, "List of libraries:\n");
1219      dump_list (stderr, "\t", libs.first);
1220    }
1221
1222  /* The AIX linker will discard static constructors in object files if
1223     nothing else in the file is referenced, so look at them first.  */
1224  {
1225      const char **export_object_lst = (const char **)object_lst;
1226
1227      while (export_object_lst < object)
1228	scan_prog_file (*export_object_lst++, PASS_OBJ);
1229  }
1230  {
1231    struct id *list = libs.first;
1232
1233    for (; list; list = list->next)
1234      scan_prog_file (list->name, PASS_FIRST);
1235  }
1236
1237  if (exports.first)
1238    {
1239      char *buf = concat ("-bE:", export_file, NULL);
1240
1241      *ld1++ = buf;
1242      *ld2++ = buf;
1243
1244      exportf = fopen (export_file, "w");
1245      if (exportf == (FILE *) 0)
1246	fatal_perror ("fopen %s", export_file);
1247      write_aix_file (exportf, exports.first);
1248      if (fclose (exportf))
1249	fatal_perror ("fclose %s", export_file);
1250    }
1251#endif
1252
1253  *c_ptr++ = c_file;
1254  *c_ptr = *ld1 = *object = (char *) 0;
1255
1256  if (vflag)
1257    {
1258      notice ("collect2 version %s", version_string);
1259#ifdef TARGET_VERSION
1260      TARGET_VERSION;
1261#endif
1262      fprintf (stderr, "\n");
1263    }
1264
1265  if (debug)
1266    {
1267      const char *ptr;
1268      fprintf (stderr, "ld_file_name        = %s\n",
1269	       (ld_file_name ? ld_file_name : "not found"));
1270      fprintf (stderr, "c_file_name         = %s\n",
1271	       (c_file_name ? c_file_name : "not found"));
1272      fprintf (stderr, "nm_file_name        = %s\n",
1273	       (nm_file_name ? nm_file_name : "not found"));
1274#ifdef LDD_SUFFIX
1275      fprintf (stderr, "ldd_file_name       = %s\n",
1276	       (ldd_file_name ? ldd_file_name : "not found"));
1277#endif
1278      fprintf (stderr, "strip_file_name     = %s\n",
1279	       (strip_file_name ? strip_file_name : "not found"));
1280      fprintf (stderr, "c_file              = %s\n",
1281	       (c_file ? c_file : "not found"));
1282      fprintf (stderr, "o_file              = %s\n",
1283	       (o_file ? o_file : "not found"));
1284
1285      ptr = getenv ("COLLECT_GCC_OPTIONS");
1286      if (ptr)
1287	fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1288
1289      ptr = getenv ("COLLECT_GCC");
1290      if (ptr)
1291	fprintf (stderr, "COLLECT_GCC         = %s\n", ptr);
1292
1293      ptr = getenv ("COMPILER_PATH");
1294      if (ptr)
1295	fprintf (stderr, "COMPILER_PATH       = %s\n", ptr);
1296
1297      ptr = getenv (LIBRARY_PATH_ENV);
1298      if (ptr)
1299	fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1300
1301      fprintf (stderr, "\n");
1302    }
1303
1304  /* Load the program, searching all libraries and attempting to provide
1305     undefined symbols from repository information.  */
1306
1307  /* On AIX we do this later.  */
1308#ifndef COLLECT_EXPORT_LIST
1309  do_tlink (ld1_argv, object_lst);
1310#endif
1311
1312  /* If -r or they will be run via some other method, do not build the
1313     constructor or destructor list, just return now.  */
1314  if (rflag
1315#ifndef COLLECT_EXPORT_LIST
1316      || ! do_collecting
1317#endif
1318      )
1319    {
1320#ifdef COLLECT_EXPORT_LIST
1321      /* Do the link we avoided above if we are exiting.  */
1322      do_tlink (ld1_argv, object_lst);
1323
1324      /* But make sure we delete the export file we may have created.  */
1325      if (export_file != 0 && export_file[0])
1326	maybe_unlink (export_file);
1327#endif
1328      maybe_unlink (c_file);
1329      maybe_unlink (o_file);
1330      return 0;
1331    }
1332
1333  /* Examine the namelist with nm and search it for static constructors
1334     and destructors to call.
1335     Write the constructor and destructor tables to a .s file and reload.  */
1336
1337  /* On AIX we already scanned for global constructors/destructors.  */
1338#ifndef COLLECT_EXPORT_LIST
1339  scan_prog_file (output_file, PASS_FIRST);
1340#endif
1341
1342#ifdef SCAN_LIBRARIES
1343  scan_libraries (output_file);
1344#endif
1345
1346  if (debug)
1347    {
1348      notice ("%d constructor(s) found\n", constructors.number);
1349      notice ("%d destructor(s)  found\n", destructors.number);
1350      notice ("%d frame table(s) found\n", frame_tables.number);
1351    }
1352
1353  if (constructors.number == 0 && destructors.number == 0
1354      && frame_tables.number == 0
1355#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1356      /* If we will be running these functions ourselves, we want to emit
1357	 stubs into the shared library so that we do not have to relink
1358	 dependent programs when we add static objects.  */
1359      && ! shared_obj
1360#endif
1361      )
1362    {
1363#ifdef COLLECT_EXPORT_LIST
1364      /* Do tlink without additional code generation.  */
1365      do_tlink (ld1_argv, object_lst);
1366#endif
1367      /* Strip now if it was requested on the command line.  */
1368      if (strip_flag)
1369	{
1370	  char **real_strip_argv = XCNEWVEC (char *, 3);
1371	  const char ** strip_argv = (const char **) real_strip_argv;
1372
1373	  strip_argv[0] = strip_file_name;
1374	  strip_argv[1] = output_file;
1375	  strip_argv[2] = (char *) 0;
1376	  fork_execute ("strip", real_strip_argv);
1377	}
1378
1379#ifdef COLLECT_EXPORT_LIST
1380      maybe_unlink (export_file);
1381#endif
1382      maybe_unlink (c_file);
1383      maybe_unlink (o_file);
1384      return 0;
1385    }
1386
1387  /* Sort ctor and dtor lists by priority.  */
1388  sort_ids (&constructors);
1389  sort_ids (&destructors);
1390
1391  maybe_unlink(output_file);
1392  outf = fopen (c_file, "w");
1393  if (outf == (FILE *) 0)
1394    fatal_perror ("fopen %s", c_file);
1395
1396  write_c_file (outf, c_file);
1397
1398  if (fclose (outf))
1399    fatal_perror ("fclose %s", c_file);
1400
1401  /* Tell the linker that we have initializer and finalizer functions.  */
1402#ifdef LD_INIT_SWITCH
1403#ifdef COLLECT_EXPORT_LIST
1404  *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
1405#else
1406  *ld2++ = LD_INIT_SWITCH;
1407  *ld2++ = initname;
1408  *ld2++ = LD_FINI_SWITCH;
1409  *ld2++ = fininame;
1410#endif
1411#endif
1412
1413#ifdef COLLECT_EXPORT_LIST
1414  if (shared_obj)
1415    {
1416      /* If we did not add export flag to link arguments before, add it to
1417	 second link phase now.  No new exports should have been added.  */
1418      if (! exports.first)
1419	*ld2++ = concat ("-bE:", export_file, NULL);
1420
1421#ifndef LD_INIT_SWITCH
1422      add_to_list (&exports, initname);
1423      add_to_list (&exports, fininame);
1424      add_to_list (&exports, "_GLOBAL__DI");
1425      add_to_list (&exports, "_GLOBAL__DD");
1426#endif
1427      exportf = fopen (export_file, "w");
1428      if (exportf == (FILE *) 0)
1429	fatal_perror ("fopen %s", export_file);
1430      write_aix_file (exportf, exports.first);
1431      if (fclose (exportf))
1432	fatal_perror ("fclose %s", export_file);
1433    }
1434#endif
1435
1436  /* End of arguments to second link phase.  */
1437  *ld2 = (char*) 0;
1438
1439  if (debug)
1440    {
1441      fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1442	       output_file, c_file);
1443      write_c_file (stderr, "stderr");
1444      fprintf (stderr, "========== end of c_file\n\n");
1445#ifdef COLLECT_EXPORT_LIST
1446      fprintf (stderr, "\n========== export_file = %s\n", export_file);
1447      write_aix_file (stderr, exports.first);
1448      fprintf (stderr, "========== end of export_file\n\n");
1449#endif
1450    }
1451
1452  /* Assemble the constructor and destructor tables.
1453     Link the tables in with the rest of the program.  */
1454
1455  fork_execute ("gcc",  c_argv);
1456#ifdef COLLECT_EXPORT_LIST
1457  /* On AIX we must call tlink because of possible templates resolution.  */
1458  do_tlink (ld2_argv, object_lst);
1459#else
1460  /* Otherwise, simply call ld because tlink is already done.  */
1461  fork_execute ("ld", ld2_argv);
1462
1463  /* Let scan_prog_file do any final mods (OSF/rose needs this for
1464     constructors/destructors in shared libraries.  */
1465  scan_prog_file (output_file, PASS_SECOND);
1466#endif
1467
1468  maybe_unlink (c_file);
1469  maybe_unlink (o_file);
1470
1471#ifdef COLLECT_EXPORT_LIST
1472  maybe_unlink (export_file);
1473#endif
1474
1475  return 0;
1476}
1477
1478
1479/* Wait for a process to finish, and exit if a nonzero status is found.  */
1480
1481int
1482collect_wait (const char *prog, struct pex_obj *pex)
1483{
1484  int status;
1485
1486  if (!pex_get_status (pex, 1, &status))
1487    fatal_perror ("can't get program status");
1488  pex_free (pex);
1489
1490  if (status)
1491    {
1492      if (WIFSIGNALED (status))
1493	{
1494	  int sig = WTERMSIG (status);
1495	  error ("%s terminated with signal %d [%s]%s",
1496		 prog, sig, strsignal(sig),
1497		 WCOREDUMP(status) ? ", core dumped" : "");
1498	  collect_exit (FATAL_EXIT_CODE);
1499	}
1500
1501      if (WIFEXITED (status))
1502	return WEXITSTATUS (status);
1503    }
1504  return 0;
1505}
1506
1507static void
1508do_wait (const char *prog, struct pex_obj *pex)
1509{
1510  int ret = collect_wait (prog, pex);
1511  if (ret != 0)
1512    {
1513      error ("%s returned %d exit status", prog, ret);
1514      collect_exit (ret);
1515    }
1516}
1517
1518
1519/* Execute a program, and wait for the reply.  */
1520
1521struct pex_obj *
1522collect_execute (const char *prog, char **argv, const char *outname,
1523		 const char *errname)
1524{
1525  struct pex_obj *pex;
1526  const char *errmsg;
1527  int err;
1528
1529  if (vflag || debug)
1530    {
1531      char **p_argv;
1532      const char *str;
1533
1534      if (argv[0])
1535	fprintf (stderr, "%s", argv[0]);
1536      else
1537	notice ("[cannot find %s]", prog);
1538
1539      for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1540	fprintf (stderr, " %s", str);
1541
1542      fprintf (stderr, "\n");
1543    }
1544
1545  fflush (stdout);
1546  fflush (stderr);
1547
1548  /* If we cannot find a program we need, complain error.  Do this here
1549     since we might not end up needing something that we could not find.  */
1550
1551  if (argv[0] == 0)
1552    fatal ("cannot find '%s'", prog);
1553
1554  pex = pex_init (0, "collect2", NULL);
1555  if (pex == NULL)
1556    fatal_perror ("pex_init failed");
1557
1558  errmsg = pex_run (pex, PEX_LAST | PEX_SEARCH, argv[0], argv, outname,
1559		    errname, &err);
1560  if (errmsg != NULL)
1561    {
1562      if (err != 0)
1563	{
1564	  errno = err;
1565	  fatal_perror ("%s", errmsg);
1566	}
1567      else
1568	fatal ("%s", errmsg);
1569    }
1570
1571  return pex;
1572}
1573
1574static void
1575fork_execute (const char *prog, char **argv)
1576{
1577  struct pex_obj *pex;
1578
1579  pex = collect_execute (prog, argv, NULL, NULL);
1580  do_wait (prog, pex);
1581}
1582
1583/* Unlink a file unless we are debugging.  */
1584
1585static void
1586maybe_unlink (const char *file)
1587{
1588  if (!debug)
1589    unlink_if_ordinary (file);
1590  else
1591    notice ("[Leaving %s]\n", file);
1592}
1593
1594
1595static long sequence_number = 0;
1596
1597/* Add a name to a linked list.  */
1598
1599static void
1600add_to_list (struct head *head_ptr, const char *name)
1601{
1602  struct id *newid = xcalloc (sizeof (struct id) + strlen (name), 1);
1603  struct id *p;
1604  strcpy (newid->name, name);
1605
1606  if (head_ptr->first)
1607    head_ptr->last->next = newid;
1608  else
1609    head_ptr->first = newid;
1610
1611  /* Check for duplicate symbols.  */
1612  for (p = head_ptr->first;
1613       strcmp (name, p->name) != 0;
1614       p = p->next)
1615    ;
1616  if (p != newid)
1617    {
1618      head_ptr->last->next = 0;
1619      free (newid);
1620      return;
1621    }
1622
1623  newid->sequence = ++sequence_number;
1624  head_ptr->last = newid;
1625  head_ptr->number++;
1626}
1627
1628/* Grab the init priority number from an init function name that
1629   looks like "_GLOBAL_.I.12345.foo".  */
1630
1631static int
1632extract_init_priority (const char *name)
1633{
1634  int pos = 0, pri;
1635
1636  while (name[pos] == '_')
1637    ++pos;
1638  pos += 10; /* strlen ("GLOBAL__X_") */
1639
1640  /* Extract init_p number from ctor/dtor name.  */
1641  pri = atoi (name + pos);
1642  return pri ? pri : DEFAULT_INIT_PRIORITY;
1643}
1644
1645/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1646   ctors will be run from right to left, dtors from left to right.  */
1647
1648static void
1649sort_ids (struct head *head_ptr)
1650{
1651  /* id holds the current element to insert.  id_next holds the next
1652     element to insert.  id_ptr iterates through the already sorted elements
1653     looking for the place to insert id.  */
1654  struct id *id, *id_next, **id_ptr;
1655
1656  id = head_ptr->first;
1657
1658  /* We don't have any sorted elements yet.  */
1659  head_ptr->first = NULL;
1660
1661  for (; id; id = id_next)
1662    {
1663      id_next = id->next;
1664      id->sequence = extract_init_priority (id->name);
1665
1666      for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1667	if (*id_ptr == NULL
1668	    /* If the sequence numbers are the same, we put the id from the
1669	       file later on the command line later in the list.  */
1670	    || id->sequence > (*id_ptr)->sequence
1671	    /* Hack: do lexical compare, too.
1672	    || (id->sequence == (*id_ptr)->sequence
1673		&& strcmp (id->name, (*id_ptr)->name) > 0) */
1674	    )
1675	  {
1676	    id->next = *id_ptr;
1677	    *id_ptr = id;
1678	    break;
1679	  }
1680    }
1681
1682  /* Now set the sequence numbers properly so write_c_file works.  */
1683  for (id = head_ptr->first; id; id = id->next)
1684    id->sequence = ++sequence_number;
1685}
1686
1687/* Write: `prefix', the names on list LIST, `suffix'.  */
1688
1689static void
1690write_list (FILE *stream, const char *prefix, struct id *list)
1691{
1692  while (list)
1693    {
1694      fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1695      list = list->next;
1696    }
1697}
1698
1699#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1700/* Given a STRING, return nonzero if it occurs in the list in range
1701   [ARGS_BEGIN,ARGS_END).  */
1702
1703static int
1704is_in_args (const char *string, const char **args_begin,
1705	    const char **args_end)
1706{
1707  const char **args_pointer;
1708  for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
1709    if (strcmp (string, *args_pointer) == 0)
1710      return 1;
1711  return 0;
1712}
1713#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1714
1715#ifdef COLLECT_EXPORT_LIST
1716/* This function is really used only on AIX, but may be useful.  */
1717#if 0
1718static int
1719is_in_list (const char *prefix, struct id *list)
1720{
1721  while (list)
1722    {
1723      if (!strcmp (prefix, list->name)) return 1;
1724      list = list->next;
1725    }
1726    return 0;
1727}
1728#endif
1729#endif /* COLLECT_EXPORT_LIST */
1730
1731/* Added for debugging purpose.  */
1732#ifdef COLLECT_EXPORT_LIST
1733static void
1734dump_list (FILE *stream, const char *prefix, struct id *list)
1735{
1736  while (list)
1737    {
1738      fprintf (stream, "%s%s,\n", prefix, list->name);
1739      list = list->next;
1740    }
1741}
1742#endif
1743
1744#if 0
1745static void
1746dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
1747{
1748  while (list)
1749    {
1750      fprintf (stream, "%s%s,\n", prefix, list->prefix);
1751      list = list->next;
1752    }
1753}
1754#endif
1755
1756static void
1757write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
1758{
1759  while (list)
1760    {
1761      fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1762	       prefix, list->sequence, list->name);
1763      list = list->next;
1764    }
1765}
1766
1767/* Write out the constructor and destructor tables statically (for a shared
1768   object), along with the functions to execute them.  */
1769
1770static void
1771write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
1772{
1773  const char *p, *q;
1774  char *prefix, *r;
1775  int frames = (frame_tables.number > 0);
1776
1777  /* Figure out name of output_file, stripping off .so version.  */
1778  p = strrchr (output_file, '/');
1779  if (p == 0)
1780    p = output_file;
1781  else
1782    p++;
1783  q = p;
1784  while (q)
1785    {
1786      q = strchr (q,'.');
1787      if (q == 0)
1788	{
1789	  q = p + strlen (p);
1790	  break;
1791	}
1792      else
1793	{
1794	  if (strncmp (q, ".so", 3) == 0)
1795	    {
1796	      q += 3;
1797	      break;
1798	    }
1799	  else
1800	    q++;
1801	}
1802    }
1803  /* q points to null at end of the string (or . of the .so version) */
1804  prefix = XNEWVEC (char, q - p + 1);
1805  strncpy (prefix, p, q - p);
1806  prefix[q - p] = 0;
1807  for (r = prefix; *r; r++)
1808    if (!ISALNUM ((unsigned char)*r))
1809      *r = '_';
1810  if (debug)
1811    notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1812	    output_file, prefix);
1813
1814  initname = concat ("_GLOBAL__FI_", prefix, NULL);
1815  fininame = concat ("_GLOBAL__FD_", prefix, NULL);
1816
1817  free (prefix);
1818
1819  /* Write the tables as C code.  */
1820
1821  fprintf (stream, "static int count;\n");
1822  fprintf (stream, "typedef void entry_pt();\n");
1823  write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1824
1825  if (frames)
1826    {
1827      write_list_with_asm (stream, "extern void *", frame_tables.first);
1828
1829      fprintf (stream, "\tstatic void *frame_table[] = {\n");
1830      write_list (stream, "\t\t&", frame_tables.first);
1831      fprintf (stream, "\t0\n};\n");
1832
1833      /* This must match what's in frame.h.  */
1834      fprintf (stream, "struct object {\n");
1835      fprintf (stream, "  void *pc_begin;\n");
1836      fprintf (stream, "  void *pc_end;\n");
1837      fprintf (stream, "  void *fde_begin;\n");
1838      fprintf (stream, "  void *fde_array;\n");
1839      fprintf (stream, "  __SIZE_TYPE__ count;\n");
1840      fprintf (stream, "  struct object *next;\n");
1841      fprintf (stream, "};\n");
1842
1843      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1844      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1845
1846      fprintf (stream, "static void reg_frame () {\n");
1847      fprintf (stream, "\tstatic struct object ob;\n");
1848      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1849      fprintf (stream, "\t}\n");
1850
1851      fprintf (stream, "static void dereg_frame () {\n");
1852      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1853      fprintf (stream, "\t}\n");
1854    }
1855
1856  fprintf (stream, "void %s() {\n", initname);
1857  if (constructors.number > 0 || frames)
1858    {
1859      fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1860      write_list (stream, "\t\t", constructors.first);
1861      if (frames)
1862	fprintf (stream, "\treg_frame,\n");
1863      fprintf (stream, "\t};\n");
1864      fprintf (stream, "\tentry_pt **p;\n");
1865      fprintf (stream, "\tif (count++ != 0) return;\n");
1866      fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1867      fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1868    }
1869  else
1870    fprintf (stream, "\t++count;\n");
1871  fprintf (stream, "}\n");
1872  write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1873  fprintf (stream, "void %s() {\n", fininame);
1874  if (destructors.number > 0 || frames)
1875    {
1876      fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1877      write_list (stream, "\t\t", destructors.first);
1878      if (frames)
1879	fprintf (stream, "\tdereg_frame,\n");
1880      fprintf (stream, "\t};\n");
1881      fprintf (stream, "\tentry_pt **p;\n");
1882      fprintf (stream, "\tif (--count != 0) return;\n");
1883      fprintf (stream, "\tp = dtors;\n");
1884      fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1885	       destructors.number + frames);
1886    }
1887  fprintf (stream, "}\n");
1888
1889  if (shared_obj)
1890    {
1891      COLLECT_SHARED_INIT_FUNC(stream, initname);
1892      COLLECT_SHARED_FINI_FUNC(stream, fininame);
1893    }
1894}
1895
1896/* Write the constructor/destructor tables.  */
1897
1898#ifndef LD_INIT_SWITCH
1899static void
1900write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
1901{
1902  /* Write the tables as C code.  */
1903
1904  int frames = (frame_tables.number > 0);
1905
1906  fprintf (stream, "typedef void entry_pt();\n\n");
1907
1908  write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1909
1910  if (frames)
1911    {
1912      write_list_with_asm (stream, "extern void *", frame_tables.first);
1913
1914      fprintf (stream, "\tstatic void *frame_table[] = {\n");
1915      write_list (stream, "\t\t&", frame_tables.first);
1916      fprintf (stream, "\t0\n};\n");
1917
1918      /* This must match what's in frame.h.  */
1919      fprintf (stream, "struct object {\n");
1920      fprintf (stream, "  void *pc_begin;\n");
1921      fprintf (stream, "  void *pc_end;\n");
1922      fprintf (stream, "  void *fde_begin;\n");
1923      fprintf (stream, "  void *fde_array;\n");
1924      fprintf (stream, "  __SIZE_TYPE__ count;\n");
1925      fprintf (stream, "  struct object *next;\n");
1926      fprintf (stream, "};\n");
1927
1928      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1929      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1930
1931      fprintf (stream, "static void reg_frame () {\n");
1932      fprintf (stream, "\tstatic struct object ob;\n");
1933      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1934      fprintf (stream, "\t}\n");
1935
1936      fprintf (stream, "static void dereg_frame () {\n");
1937      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1938      fprintf (stream, "\t}\n");
1939    }
1940
1941  fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1942  fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
1943  write_list (stream, "\t", constructors.first);
1944  if (frames)
1945    fprintf (stream, "\treg_frame,\n");
1946  fprintf (stream, "\t0\n};\n\n");
1947
1948  write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1949
1950  fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1951  fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
1952  write_list (stream, "\t", destructors.first);
1953  if (frames)
1954    fprintf (stream, "\tdereg_frame,\n");
1955  fprintf (stream, "\t0\n};\n\n");
1956
1957  fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1958  fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
1959}
1960#endif /* ! LD_INIT_SWITCH */
1961
1962static void
1963write_c_file (FILE *stream, const char *name)
1964{
1965  fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
1966#ifndef LD_INIT_SWITCH
1967  if (! shared_obj)
1968    write_c_file_glob (stream, name);
1969  else
1970#endif
1971    write_c_file_stat (stream, name);
1972  fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
1973}
1974
1975#ifdef COLLECT_EXPORT_LIST
1976static void
1977write_aix_file (FILE *stream, struct id *list)
1978{
1979  for (; list; list = list->next)
1980    {
1981      fputs (list->name, stream);
1982      putc ('\n', stream);
1983    }
1984}
1985#endif
1986
1987#ifdef OBJECT_FORMAT_NONE
1988
1989/* Generic version to scan the name list of the loaded program for
1990   the symbols g++ uses for static constructors and destructors.
1991
1992   The constructor table begins at __CTOR_LIST__ and contains a count
1993   of the number of pointers (or -1 if the constructors are built in a
1994   separate section by the linker), followed by the pointers to the
1995   constructor functions, terminated with a null pointer.  The
1996   destructor table has the same format, and begins at __DTOR_LIST__.  */
1997
1998static void
1999scan_prog_file (const char *prog_name, enum pass which_pass)
2000{
2001  void (*int_handler) (int);
2002#ifdef SIGQUIT
2003  void (*quit_handler) (int);
2004#endif
2005  char *real_nm_argv[4];
2006  const char **nm_argv = (const char **) real_nm_argv;
2007  int argc = 0;
2008  struct pex_obj *pex;
2009  const char *errmsg;
2010  int err;
2011  char *p, buf[1024];
2012  FILE *inf;
2013
2014  if (which_pass == PASS_SECOND)
2015    return;
2016
2017  /* If we do not have an `nm', complain.  */
2018  if (nm_file_name == 0)
2019    fatal ("cannot find 'nm'");
2020
2021  nm_argv[argc++] = nm_file_name;
2022  if (NM_FLAGS[0] != '\0')
2023    nm_argv[argc++] = NM_FLAGS;
2024
2025  nm_argv[argc++] = prog_name;
2026  nm_argv[argc++] = (char *) 0;
2027
2028  /* Trace if needed.  */
2029  if (vflag)
2030    {
2031      const char **p_argv;
2032      const char *str;
2033
2034      for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2035	fprintf (stderr, " %s", str);
2036
2037      fprintf (stderr, "\n");
2038    }
2039
2040  fflush (stdout);
2041  fflush (stderr);
2042
2043  pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2044  if (pex == NULL)
2045    fatal_perror ("pex_init failed");
2046
2047  errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, NULL, &err);
2048  if (errmsg != NULL)
2049    {
2050      if (err != 0)
2051	{
2052	  errno = err;
2053	  fatal_perror ("%s", errmsg);
2054	}
2055      else
2056	fatal ("%s", errmsg);
2057    }
2058
2059  int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
2060#ifdef SIGQUIT
2061  quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2062#endif
2063
2064  inf = pex_read_output (pex, 0);
2065  if (inf == NULL)
2066    fatal_perror ("can't open nm output");
2067
2068  if (debug)
2069    fprintf (stderr, "\nnm output with constructors/destructors.\n");
2070
2071  /* Read each line of nm output.  */
2072  while (fgets (buf, sizeof buf, inf) != (char *) 0)
2073    {
2074      int ch, ch2;
2075      char *name, *end;
2076
2077      /* If it contains a constructor or destructor name, add the name
2078	 to the appropriate list.  */
2079
2080      for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2081	if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2082	  break;
2083
2084      if (ch != '_')
2085	continue;
2086
2087      name = p;
2088      /* Find the end of the symbol name.
2089	 Do not include `|', because Encore nm can tack that on the end.  */
2090      for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2091	   end++)
2092	continue;
2093
2094
2095      *end = '\0';
2096      switch (is_ctor_dtor (name))
2097	{
2098	case 1:
2099	  if (which_pass != PASS_LIB)
2100	    add_to_list (&constructors, name);
2101	  break;
2102
2103	case 2:
2104	  if (which_pass != PASS_LIB)
2105	    add_to_list (&destructors, name);
2106	  break;
2107
2108	case 3:
2109	  if (which_pass != PASS_LIB)
2110	    fatal ("init function found in object %s", prog_name);
2111#ifndef LD_INIT_SWITCH
2112	  add_to_list (&constructors, name);
2113#endif
2114	  break;
2115
2116	case 4:
2117	  if (which_pass != PASS_LIB)
2118	    fatal ("fini function found in object %s", prog_name);
2119#ifndef LD_FINI_SWITCH
2120	  add_to_list (&destructors, name);
2121#endif
2122	  break;
2123
2124	case 5:
2125	  if (which_pass != PASS_LIB)
2126	    add_to_list (&frame_tables, name);
2127	  break;
2128
2129	default:		/* not a constructor or destructor */
2130	  continue;
2131	}
2132
2133      if (debug)
2134	fprintf (stderr, "\t%s\n", buf);
2135    }
2136
2137  if (debug)
2138    fprintf (stderr, "\n");
2139
2140  do_wait (nm_file_name, pex);
2141
2142  signal (SIGINT,  int_handler);
2143#ifdef SIGQUIT
2144  signal (SIGQUIT, quit_handler);
2145#endif
2146}
2147
2148#ifdef LDD_SUFFIX
2149
2150/* Use the List Dynamic Dependencies program to find shared libraries that
2151   the output file depends upon and their initialization/finalization
2152   routines, if any.  */
2153
2154static void
2155scan_libraries (const char *prog_name)
2156{
2157  static struct head libraries;		/* list of shared libraries found */
2158  struct id *list;
2159  void (*int_handler) (int);
2160#ifdef SIGQUIT
2161  void (*quit_handler) (int);
2162#endif
2163  char *real_ldd_argv[4];
2164  const char **ldd_argv = (const char **) real_ldd_argv;
2165  int argc = 0;
2166  struct pex_obj *pex;
2167  const char *errmsg;
2168  int err;
2169  char buf[1024];
2170  FILE *inf;
2171
2172  /* If we do not have an `ldd', complain.  */
2173  if (ldd_file_name == 0)
2174    {
2175      error ("cannot find 'ldd'");
2176      return;
2177    }
2178
2179  ldd_argv[argc++] = ldd_file_name;
2180  ldd_argv[argc++] = prog_name;
2181  ldd_argv[argc++] = (char *) 0;
2182
2183  /* Trace if needed.  */
2184  if (vflag)
2185    {
2186      const char **p_argv;
2187      const char *str;
2188
2189      for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2190	fprintf (stderr, " %s", str);
2191
2192      fprintf (stderr, "\n");
2193    }
2194
2195  fflush (stdout);
2196  fflush (stderr);
2197
2198  pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2199  if (pex == NULL)
2200    fatal_perror ("pex_init failed");
2201
2202  errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err);
2203  if (errmsg != NULL)
2204    {
2205      if (err != 0)
2206	{
2207	  errno = err;
2208	  fatal_perror (errmsg);
2209	}
2210      else
2211	fatal (errmsg);
2212    }
2213
2214  int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
2215#ifdef SIGQUIT
2216  quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2217#endif
2218
2219  inf = pex_read_output (pex, 0);
2220  if (inf == NULL)
2221    fatal_perror ("can't open ldd output");
2222
2223  if (debug)
2224    notice ("\nldd output with constructors/destructors.\n");
2225
2226  /* Read each line of ldd output.  */
2227  while (fgets (buf, sizeof buf, inf) != (char *) 0)
2228    {
2229      int ch2;
2230      char *name, *end, *p = buf;
2231
2232      /* Extract names of libraries and add to list.  */
2233      PARSE_LDD_OUTPUT (p);
2234      if (p == 0)
2235	continue;
2236
2237      name = p;
2238      if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2239	fatal ("dynamic dependency %s not found", buf);
2240
2241      /* Find the end of the symbol name.  */
2242      for (end = p;
2243	   (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2244	   end++)
2245	continue;
2246      *end = '\0';
2247
2248      if (access (name, R_OK) == 0)
2249	add_to_list (&libraries, name);
2250      else
2251	fatal ("unable to open dynamic dependency '%s'", buf);
2252
2253      if (debug)
2254	fprintf (stderr, "\t%s\n", buf);
2255    }
2256  if (debug)
2257    fprintf (stderr, "\n");
2258
2259  do_wait (ldd_file_name, pex);
2260
2261  signal (SIGINT,  int_handler);
2262#ifdef SIGQUIT
2263  signal (SIGQUIT, quit_handler);
2264#endif
2265
2266  /* Now iterate through the library list adding their symbols to
2267     the list.  */
2268  for (list = libraries.first; list; list = list->next)
2269    scan_prog_file (list->name, PASS_LIB);
2270}
2271
2272#endif /* LDD_SUFFIX */
2273
2274#endif /* OBJECT_FORMAT_NONE */
2275
2276
2277/*
2278 * COFF specific stuff.
2279 */
2280
2281#ifdef OBJECT_FORMAT_COFF
2282
2283#if defined (EXTENDED_COFF)
2284
2285#   define GCC_SYMBOLS(X)	(SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2286#   define GCC_SYMENT		SYMR
2287#   define GCC_OK_SYMBOL(X)	((X).st == stProc || (X).st == stGlobal)
2288#   define GCC_SYMINC(X)	(1)
2289#   define GCC_SYMZERO(X)	(SYMHEADER(X).isymMax)
2290#   define GCC_CHECK_HDR(X)	(PSYMTAB(X) != 0)
2291
2292#else
2293
2294#   define GCC_SYMBOLS(X)	(HEADER(ldptr).f_nsyms)
2295#   define GCC_SYMENT		SYMENT
2296#   if defined (C_WEAKEXT)
2297#     define GCC_OK_SYMBOL(X) \
2298       (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2299	((X).n_scnum > N_UNDEF) && \
2300	(aix64_flag \
2301	 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2302	     || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2303#     define GCC_UNDEF_SYMBOL(X) \
2304       (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2305	((X).n_scnum == N_UNDEF))
2306#   else
2307#     define GCC_OK_SYMBOL(X) \
2308       (((X).n_sclass == C_EXT) && \
2309	((X).n_scnum > N_UNDEF) && \
2310	(aix64_flag \
2311	 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2312	     || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2313#     define GCC_UNDEF_SYMBOL(X) \
2314       (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2315#   endif
2316#   define GCC_SYMINC(X)	((X).n_numaux+1)
2317#   define GCC_SYMZERO(X)	0
2318
2319/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2320#ifdef _AIX51
2321#   define GCC_CHECK_HDR(X) \
2322     ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2323      || (HEADER (X).f_magic == 0767 && aix64_flag))
2324#else
2325#   define GCC_CHECK_HDR(X) \
2326     ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2327      || (HEADER (X).f_magic == 0757 && aix64_flag))
2328#endif
2329
2330#endif
2331
2332#ifdef COLLECT_EXPORT_LIST
2333/* Array of standard AIX libraries which should not
2334   be scanned for ctors/dtors.  */
2335static const char *const aix_std_libs[] = {
2336  "/unix",
2337  "/lib/libc.a",
2338  "/lib/libm.a",
2339  "/lib/libc_r.a",
2340  "/lib/libm_r.a",
2341  "/usr/lib/libc.a",
2342  "/usr/lib/libm.a",
2343  "/usr/lib/libc_r.a",
2344  "/usr/lib/libm_r.a",
2345  "/usr/lib/threads/libc.a",
2346  "/usr/ccs/lib/libc.a",
2347  "/usr/ccs/lib/libm.a",
2348  "/usr/ccs/lib/libc_r.a",
2349  "/usr/ccs/lib/libm_r.a",
2350  NULL
2351};
2352
2353/* This function checks the filename and returns 1
2354   if this name matches the location of a standard AIX library.  */
2355static int ignore_library (const char *);
2356static int
2357ignore_library (const char *name)
2358{
2359  const char *const *p = &aix_std_libs[0];
2360  while (*p++ != NULL)
2361    if (! strcmp (name, *p)) return 1;
2362  return 0;
2363}
2364#endif /* COLLECT_EXPORT_LIST */
2365
2366#if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2367extern char *ldgetname (LDFILE *, GCC_SYMENT *);
2368#endif
2369
2370/* COFF version to scan the name list of the loaded program for
2371   the symbols g++ uses for static constructors and destructors.
2372
2373   The constructor table begins at __CTOR_LIST__ and contains a count
2374   of the number of pointers (or -1 if the constructors are built in a
2375   separate section by the linker), followed by the pointers to the
2376   constructor functions, terminated with a null pointer.  The
2377   destructor table has the same format, and begins at __DTOR_LIST__.  */
2378
2379static void
2380scan_prog_file (const char *prog_name, enum pass which_pass)
2381{
2382  LDFILE *ldptr = NULL;
2383  int sym_index, sym_count;
2384  int is_shared = 0;
2385
2386  if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2387    return;
2388
2389#ifdef COLLECT_EXPORT_LIST
2390  /* We do not need scanning for some standard C libraries.  */
2391  if (which_pass == PASS_FIRST && ignore_library (prog_name))
2392    return;
2393
2394  /* On AIX we have a loop, because there is not much difference
2395     between an object and an archive. This trick allows us to
2396     eliminate scan_libraries() function.  */
2397  do
2398    {
2399#endif
2400      /* Some platforms (e.g. OSF4) declare ldopen as taking a
2401	 non-const char * filename parameter, even though it will not
2402	 modify that string.  So we must cast away const-ness here,
2403	 which will cause -Wcast-qual to burp.  */
2404      if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
2405	{
2406	  if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2407	    fatal ("%s: not a COFF file", prog_name);
2408
2409	  if (GCC_CHECK_HDR (ldptr))
2410	    {
2411	      sym_count = GCC_SYMBOLS (ldptr);
2412	      sym_index = GCC_SYMZERO (ldptr);
2413
2414#ifdef COLLECT_EXPORT_LIST
2415	      /* Is current archive member a shared object?  */
2416	      is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2417#endif
2418
2419	      while (sym_index < sym_count)
2420		{
2421		  GCC_SYMENT symbol;
2422
2423		  if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2424		    break;
2425		  sym_index += GCC_SYMINC (symbol);
2426
2427		  if (GCC_OK_SYMBOL (symbol))
2428		    {
2429		      char *name;
2430
2431		      if ((name = ldgetname (ldptr, &symbol)) == NULL)
2432			continue;		/* Should never happen.  */
2433
2434#ifdef XCOFF_DEBUGGING_INFO
2435		      /* All AIX function names have a duplicate entry
2436			 beginning with a dot.  */
2437		      if (*name == '.')
2438			++name;
2439#endif
2440
2441		      switch (is_ctor_dtor (name))
2442			{
2443			case 1:
2444			  if (! is_shared)
2445			    add_to_list (&constructors, name);
2446#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2447			  if (which_pass == PASS_OBJ)
2448			    add_to_list (&exports, name);
2449#endif
2450			  break;
2451
2452			case 2:
2453			  if (! is_shared)
2454			    add_to_list (&destructors, name);
2455#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2456			  if (which_pass == PASS_OBJ)
2457			    add_to_list (&exports, name);
2458#endif
2459			  break;
2460
2461#ifdef COLLECT_EXPORT_LIST
2462			case 3:
2463#ifndef LD_INIT_SWITCH
2464			  if (is_shared)
2465			    add_to_list (&constructors, name);
2466#endif
2467			  break;
2468
2469			case 4:
2470#ifndef LD_INIT_SWITCH
2471			  if (is_shared)
2472			    add_to_list (&destructors, name);
2473#endif
2474			  break;
2475#endif
2476
2477			case 5:
2478			  if (! is_shared)
2479			    add_to_list (&frame_tables, name);
2480#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2481			  if (which_pass == PASS_OBJ)
2482			    add_to_list (&exports, name);
2483#endif
2484			  break;
2485
2486			default:	/* not a constructor or destructor */
2487#ifdef COLLECT_EXPORT_LIST
2488			  /* Explicitly export all global symbols when
2489			     building a shared object on AIX, but do not
2490			     re-export symbols from another shared object
2491			     and do not export symbols if the user
2492			     provides an explicit export list.  */
2493			  if (shared_obj && !is_shared
2494			      && which_pass == PASS_OBJ && !export_flag)
2495			    add_to_list (&exports, name);
2496#endif
2497			  continue;
2498			}
2499
2500		      if (debug)
2501#if !defined(EXTENDED_COFF)
2502			fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2503				 symbol.n_scnum, symbol.n_sclass,
2504				 (symbol.n_type ? "0" : ""), symbol.n_type,
2505				 name);
2506#else
2507			fprintf (stderr,
2508				 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2509				 symbol.iss, (long) symbol.value, symbol.index, name);
2510#endif
2511		    }
2512		}
2513	    }
2514#ifdef COLLECT_EXPORT_LIST
2515	  else
2516	    {
2517	      /* If archive contains both 32-bit and 64-bit objects,
2518		 we want to skip objects in other mode so mismatch normal.  */
2519	      if (debug)
2520		fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2521			 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2522	    }
2523#endif
2524	}
2525      else
2526	{
2527	  fatal ("%s: cannot open as COFF file", prog_name);
2528	}
2529#ifdef COLLECT_EXPORT_LIST
2530      /* On AIX loop continues while there are more members in archive.  */
2531    }
2532  while (ldclose (ldptr) == FAILURE);
2533#else
2534  /* Otherwise we simply close ldptr.  */
2535  (void) ldclose(ldptr);
2536#endif
2537}
2538#endif /* OBJECT_FORMAT_COFF */
2539
2540#ifdef COLLECT_EXPORT_LIST
2541/* Given a library name without "lib" prefix, this function
2542   returns a full library name including a path.  */
2543static char *
2544resolve_lib_name (const char *name)
2545{
2546  char *lib_buf;
2547  int i, j, l = 0;
2548  /* Library extensions for AIX dynamic linking.  */
2549  const char * const libexts[2] = {"a", "so"};
2550
2551  for (i = 0; libpaths[i]; i++)
2552    if (libpaths[i]->max_len > l)
2553      l = libpaths[i]->max_len;
2554
2555  lib_buf = xmalloc (l + strlen(name) + 10);
2556
2557  for (i = 0; libpaths[i]; i++)
2558    {
2559      struct prefix_list *list = libpaths[i]->plist;
2560      for (; list; list = list->next)
2561	{
2562	  /* The following lines are needed because path_prefix list
2563	     may contain directories both with trailing '/' and
2564	     without it.  */
2565	  const char *p = "";
2566	  if (list->prefix[strlen(list->prefix)-1] != '/')
2567	    p = "/";
2568	  for (j = 0; j < 2; j++)
2569	    {
2570	      sprintf (lib_buf, "%s%slib%s.%s",
2571		       list->prefix, p, name,
2572		       libexts[(j + aixrtl_flag) % 2]);
2573	      if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2574	      if (file_exists (lib_buf))
2575		{
2576		  if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2577		  return (lib_buf);
2578		}
2579	    }
2580	}
2581    }
2582  if (debug)
2583    fprintf (stderr, "not found\n");
2584  else
2585    fatal ("library lib%s not found", name);
2586  return (NULL);
2587}
2588#endif /* COLLECT_EXPORT_LIST */
2589