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  if (pledge ("stdio rpath wpath cpath proc exec", NULL) == -1) {
801      error ("cannot pledge");
802      collect_exit (1);
803  }
804
805  /* Suppress demangling by the real linker, which may be broken.  */
806  putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
807
808#if defined (COLLECT2_HOST_INITIALIZATION)
809  /* Perform system dependent initialization, if necessary.  */
810  COLLECT2_HOST_INITIALIZATION;
811#endif
812
813#ifdef SIGCHLD
814  /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
815     receive the signal.  A different setting is inheritable */
816  signal (SIGCHLD, SIG_DFL);
817#endif
818
819  /* Unlock the stdio streams.  */
820  unlock_std_streams ();
821
822  gcc_init_libintl ();
823
824  /* Do not invoke xcalloc before this point, since locale needs to be
825     set first, in case a diagnostic is issued.  */
826
827  ld1 = (const char **)(ld1_argv = xcalloc(sizeof (char *), argc+4));
828  ld2 = (const char **)(ld2_argv = xcalloc(sizeof (char *), argc+11));
829  object = (const char **)(object_lst = xcalloc(sizeof (char *), argc));
830
831#ifdef DEBUG
832  debug = 1;
833#endif
834
835  /* Parse command line early for instances of -debug.  This allows
836     the debug flag to be set before functions like find_a_file()
837     are called.  */
838  {
839    int i;
840
841    for (i = 1; argv[i] != NULL; i ++)
842      {
843	if (! strcmp (argv[i], "-debug"))
844	  debug = 1;
845      }
846    vflag = debug;
847  }
848
849#ifndef DEFAULT_A_OUT_NAME
850  output_file = "a.out";
851#else
852  output_file = DEFAULT_A_OUT_NAME;
853#endif
854
855  obstack_begin (&temporary_obstack, 0);
856  temporary_firstobj = obstack_alloc (&temporary_obstack, 0);
857
858#ifndef HAVE_LD_DEMANGLE
859  current_demangling_style = auto_demangling;
860#endif
861  p = getenv ("COLLECT_GCC_OPTIONS");
862  while (p && *p)
863    {
864      const char *q = extract_string (&p);
865      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
866	num_c_args++;
867    }
868  obstack_free (&temporary_obstack, temporary_firstobj);
869
870  /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
871     -fno-exceptions -w */
872  num_c_args += 5;
873
874  c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
875
876  if (argc < 2)
877    fatal ("no arguments");
878
879#ifdef SIGQUIT
880  if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
881    signal (SIGQUIT, handler);
882#endif
883  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
884    signal (SIGINT, handler);
885#ifdef SIGALRM
886  if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
887    signal (SIGALRM, handler);
888#endif
889#ifdef SIGHUP
890  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
891    signal (SIGHUP, handler);
892#endif
893  if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
894    signal (SIGSEGV, handler);
895#ifdef SIGBUS
896  if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
897    signal (SIGBUS, handler);
898#endif
899#ifdef SIGPIPE
900  if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
901    signal (SIGPIPE, handler);
902#endif
903
904  /* Extract COMPILER_PATH and PATH into our prefix list.  */
905  prefix_from_env ("COMPILER_PATH", &cpath);
906  prefix_from_env ("PATH", &path);
907
908  /* Try to discover a valid linker/nm/strip to use.  */
909
910  /* Maybe we know the right file to use (if not cross).  */
911  ld_file_name = 0;
912#ifdef DEFAULT_LINKER
913  if (access (DEFAULT_LINKER, X_OK) == 0)
914    ld_file_name = DEFAULT_LINKER;
915  if (ld_file_name == 0)
916#endif
917#ifdef REAL_LD_FILE_NAME
918  ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
919  if (ld_file_name == 0)
920#endif
921  /* Search the (target-specific) compiler dirs for ld'.  */
922  ld_file_name = find_a_file (&cpath, real_ld_suffix);
923  /* Likewise for `collect-ld'.  */
924  if (ld_file_name == 0)
925    ld_file_name = find_a_file (&cpath, collect_ld_suffix);
926  /* Search the compiler directories for `ld'.  We have protection against
927     recursive calls in find_a_file.  */
928  if (ld_file_name == 0)
929    ld_file_name = find_a_file (&cpath, ld_suffix);
930  /* Search the ordinary system bin directories
931     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
932  if (ld_file_name == 0)
933    ld_file_name = find_a_file (&path, full_ld_suffix);
934
935#ifdef REAL_NM_FILE_NAME
936  nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
937  if (nm_file_name == 0)
938#endif
939  nm_file_name = find_a_file (&cpath, gnm_suffix);
940  if (nm_file_name == 0)
941    nm_file_name = find_a_file (&path, full_gnm_suffix);
942  if (nm_file_name == 0)
943    nm_file_name = find_a_file (&cpath, nm_suffix);
944  if (nm_file_name == 0)
945    nm_file_name = find_a_file (&path, full_nm_suffix);
946
947#ifdef LDD_SUFFIX
948  ldd_file_name = find_a_file (&cpath, ldd_suffix);
949  if (ldd_file_name == 0)
950    ldd_file_name = find_a_file (&path, full_ldd_suffix);
951#endif
952
953#ifdef REAL_STRIP_FILE_NAME
954  strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
955  if (strip_file_name == 0)
956#endif
957  strip_file_name = find_a_file (&cpath, gstrip_suffix);
958  if (strip_file_name == 0)
959    strip_file_name = find_a_file (&path, full_gstrip_suffix);
960  if (strip_file_name == 0)
961    strip_file_name = find_a_file (&cpath, strip_suffix);
962  if (strip_file_name == 0)
963    strip_file_name = find_a_file (&path, full_strip_suffix);
964
965  /* Determine the full path name of the C compiler to use.  */
966  c_file_name = getenv ("COLLECT_GCC");
967  if (c_file_name == 0)
968    {
969#ifdef CROSS_COMPILE
970      c_file_name = concat (target_machine, "-gcc", NULL);
971#else
972      c_file_name = "gcc";
973#endif
974    }
975
976  p = find_a_file (&cpath, c_file_name);
977
978  /* Here it should be safe to use the system search path since we should have
979     already qualified the name of the compiler when it is needed.  */
980  if (p == 0)
981    p = find_a_file (&path, c_file_name);
982
983  if (p)
984    c_file_name = p;
985
986  *ld1++ = *ld2++ = ld_file_name;
987
988  /* Make temp file names.  */
989  c_file = make_temp_file (".c");
990  o_file = make_temp_file (".o");
991#ifdef COLLECT_EXPORT_LIST
992  export_file = make_temp_file (".x");
993#endif
994  ldout = make_temp_file (".ld");
995  lderrout = make_temp_file (".le");
996  *c_ptr++ = c_file_name;
997  *c_ptr++ = "-x";
998  *c_ptr++ = "c";
999  *c_ptr++ = "-c";
1000  *c_ptr++ = "-o";
1001  *c_ptr++ = o_file;
1002
1003#ifdef COLLECT_EXPORT_LIST
1004  /* Generate a list of directories from LIBPATH.  */
1005  prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1006  /* Add to this list also two standard directories where
1007     AIX loader always searches for libraries.  */
1008  add_prefix (&libpath_lib_dirs, "/lib");
1009  add_prefix (&libpath_lib_dirs, "/usr/lib");
1010#endif
1011
1012  /* Get any options that the upper GCC wants to pass to the sub-GCC.
1013
1014     AIX support needs to know if -shared has been specified before
1015     parsing commandline arguments.  */
1016
1017  p = getenv ("COLLECT_GCC_OPTIONS");
1018  while (p && *p)
1019    {
1020      const char *q = extract_string (&p);
1021      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1022	*c_ptr++ = xstrdup (q);
1023      if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1024	*c_ptr++ = xstrdup (q);
1025      if (strcmp (q, "-shared") == 0)
1026	shared_obj = 1;
1027      if (*q == '-' && q[1] == 'B')
1028	{
1029	  *c_ptr++ = xstrdup (q);
1030	  if (q[2] == 0)
1031	    {
1032	      q = extract_string (&p);
1033	      *c_ptr++ = xstrdup (q);
1034	    }
1035	}
1036    }
1037  obstack_free (&temporary_obstack, temporary_firstobj);
1038  *c_ptr++ = "-fno-profile-arcs";
1039  *c_ptr++ = "-fno-test-coverage";
1040  *c_ptr++ = "-fno-branch-probabilities";
1041  *c_ptr++ = "-fno-exceptions";
1042  *c_ptr++ = "-w";
1043
1044  /* !!! When GCC calls collect2,
1045     it does not know whether it is calling collect2 or ld.
1046     So collect2 cannot meaningfully understand any options
1047     except those ld understands.
1048     If you propose to make GCC pass some other option,
1049     just imagine what will happen if ld is really ld!!!  */
1050
1051  /* Parse arguments.  Remember output file spec, pass the rest to ld.  */
1052  /* After the first file, put in the c++ rt0.  */
1053
1054  first_file = 1;
1055#ifdef HAVE_LD_DEMANGLE
1056  if (!demangle_flag && !no_demangle)
1057    demangle_flag = "--demangle";
1058  if (demangle_flag)
1059    *ld1++ = *ld2++ = demangle_flag;
1060#endif
1061  while ((arg = *++argv) != (char *) 0)
1062    {
1063      *ld1++ = *ld2++ = arg;
1064
1065      if (arg[0] == '-')
1066	{
1067	  switch (arg[1])
1068	    {
1069#ifdef COLLECT_EXPORT_LIST
1070	    /* We want to disable automatic exports on AIX when user
1071	       explicitly puts an export list in command line */
1072	    case 'b':
1073	      if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1074		export_flag = 1;
1075	      else if (arg[2] == '6' && arg[3] == '4')
1076		aix64_flag = 1;
1077	      else if (arg[2] == 'r' && arg[3] == 't' && arg[4] == 'l')
1078		aixrtl_flag = 1;
1079	      break;
1080#endif
1081
1082	    case 'd':
1083	      if (!strcmp (arg, "-debug"))
1084		{
1085		  /* Already parsed.  */
1086		  ld1--;
1087		  ld2--;
1088		}
1089	      if (!strcmp (arg, "-dynamic-linker") && argv[1])
1090		{
1091		  ++argv;
1092		  *ld1++ = *ld2++ = *argv;
1093		}
1094	      break;
1095
1096	    case 'l':
1097	      if (first_file)
1098		{
1099		  /* place o_file BEFORE this argument! */
1100		  first_file = 0;
1101		  ld2--;
1102		  *ld2++ = o_file;
1103		  *ld2++ = arg;
1104		}
1105#ifdef COLLECT_EXPORT_LIST
1106	      {
1107		/* Resolving full library name.  */
1108		const char *s = resolve_lib_name (arg+2);
1109
1110		/* Saving a full library name.  */
1111		add_to_list (&libs, s);
1112	      }
1113#endif
1114	      break;
1115
1116#ifdef COLLECT_EXPORT_LIST
1117	    /* Saving directories where to search for libraries.  */
1118	    case 'L':
1119	      add_prefix (&cmdline_lib_dirs, arg+2);
1120	      break;
1121#else
1122#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1123	    case 'L':
1124	      if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
1125		--ld1;
1126	      break;
1127#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1128#endif
1129
1130	    case 'o':
1131	      if (arg[2] == '\0')
1132		output_file = *ld1++ = *ld2++ = *++argv;
1133	      else if (1
1134#ifdef SWITCHES_NEED_SPACES
1135		       && ! strchr (SWITCHES_NEED_SPACES, arg[1])
1136#endif
1137		       )
1138
1139		output_file = &arg[2];
1140	      break;
1141
1142	    case 'r':
1143	      if (arg[2] == '\0')
1144		rflag = 1;
1145	      break;
1146
1147	    case 's':
1148	      if (arg[2] == '\0' && do_collecting)
1149		{
1150		  /* We must strip after the nm run, otherwise C++ linking
1151		     will not work.  Thus we strip in the second ld run, or
1152		     else with strip if there is no second ld run.  */
1153		  strip_flag = 1;
1154		  ld1--;
1155		}
1156	      break;
1157
1158	    case 'v':
1159	      if (arg[2] == '\0')
1160		vflag = 1;
1161	      break;
1162
1163	    case '-':
1164	      if (strcmp (arg, "--no-demangle") == 0)
1165		{
1166		  demangle_flag = arg;
1167		  no_demangle = 1;
1168		  ld1--;
1169		  ld2--;
1170		}
1171	      else if (strncmp (arg, "--demangle", 10) == 0)
1172		{
1173		  demangle_flag = arg;
1174		  no_demangle = 0;
1175#ifndef HAVE_LD_DEMANGLE
1176		  if (arg[10] == '=')
1177		    {
1178		      enum demangling_styles style
1179			= cplus_demangle_name_to_style (arg+11);
1180		      if (style == unknown_demangling)
1181			error ("unknown demangling style '%s'", arg+11);
1182		      else
1183			current_demangling_style = style;
1184		    }
1185#endif
1186		  ld1--;
1187		  ld2--;
1188		}
1189	      break;
1190	    }
1191	}
1192      else if ((p = strrchr (arg, '.')) != (char *) 0
1193	       && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1194		   || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1195		   || strcmp (p, ".obj") == 0))
1196	{
1197	  if (first_file)
1198	    {
1199	      first_file = 0;
1200	      if (p[1] == 'o')
1201		*ld2++ = o_file;
1202	      else
1203		{
1204		  /* place o_file BEFORE this argument! */
1205		  ld2--;
1206		  *ld2++ = o_file;
1207		  *ld2++ = arg;
1208		}
1209	    }
1210	  if (p[1] == 'o' || p[1] == 'l')
1211	    *object++ = arg;
1212#ifdef COLLECT_EXPORT_LIST
1213	  /* libraries can be specified directly, i.e. without -l flag.  */
1214	  else
1215	    {
1216	      /* Saving a full library name.  */
1217	      add_to_list (&libs, arg);
1218	    }
1219#endif
1220	}
1221    }
1222
1223#ifdef COLLECT_EXPORT_LIST
1224  /* This is added only for debugging purposes.  */
1225  if (debug)
1226    {
1227      fprintf (stderr, "List of libraries:\n");
1228      dump_list (stderr, "\t", libs.first);
1229    }
1230
1231  /* The AIX linker will discard static constructors in object files if
1232     nothing else in the file is referenced, so look at them first.  */
1233  {
1234      const char **export_object_lst = (const char **)object_lst;
1235
1236      while (export_object_lst < object)
1237	scan_prog_file (*export_object_lst++, PASS_OBJ);
1238  }
1239  {
1240    struct id *list = libs.first;
1241
1242    for (; list; list = list->next)
1243      scan_prog_file (list->name, PASS_FIRST);
1244  }
1245
1246  if (exports.first)
1247    {
1248      char *buf = concat ("-bE:", export_file, NULL);
1249
1250      *ld1++ = buf;
1251      *ld2++ = buf;
1252
1253      exportf = fopen (export_file, "w");
1254      if (exportf == (FILE *) 0)
1255	fatal_perror ("fopen %s", export_file);
1256      write_aix_file (exportf, exports.first);
1257      if (fclose (exportf))
1258	fatal_perror ("fclose %s", export_file);
1259    }
1260#endif
1261
1262  *c_ptr++ = c_file;
1263  *c_ptr = *ld1 = *object = (char *) 0;
1264
1265  if (vflag)
1266    {
1267      notice ("collect2 version %s", version_string);
1268#ifdef TARGET_VERSION
1269      TARGET_VERSION;
1270#endif
1271      fprintf (stderr, "\n");
1272    }
1273
1274  if (debug)
1275    {
1276      const char *ptr;
1277      fprintf (stderr, "ld_file_name        = %s\n",
1278	       (ld_file_name ? ld_file_name : "not found"));
1279      fprintf (stderr, "c_file_name         = %s\n",
1280	       (c_file_name ? c_file_name : "not found"));
1281      fprintf (stderr, "nm_file_name        = %s\n",
1282	       (nm_file_name ? nm_file_name : "not found"));
1283#ifdef LDD_SUFFIX
1284      fprintf (stderr, "ldd_file_name       = %s\n",
1285	       (ldd_file_name ? ldd_file_name : "not found"));
1286#endif
1287      fprintf (stderr, "strip_file_name     = %s\n",
1288	       (strip_file_name ? strip_file_name : "not found"));
1289      fprintf (stderr, "c_file              = %s\n",
1290	       (c_file ? c_file : "not found"));
1291      fprintf (stderr, "o_file              = %s\n",
1292	       (o_file ? o_file : "not found"));
1293
1294      ptr = getenv ("COLLECT_GCC_OPTIONS");
1295      if (ptr)
1296	fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1297
1298      ptr = getenv ("COLLECT_GCC");
1299      if (ptr)
1300	fprintf (stderr, "COLLECT_GCC         = %s\n", ptr);
1301
1302      ptr = getenv ("COMPILER_PATH");
1303      if (ptr)
1304	fprintf (stderr, "COMPILER_PATH       = %s\n", ptr);
1305
1306      ptr = getenv (LIBRARY_PATH_ENV);
1307      if (ptr)
1308	fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1309
1310      fprintf (stderr, "\n");
1311    }
1312
1313  /* Load the program, searching all libraries and attempting to provide
1314     undefined symbols from repository information.  */
1315
1316  /* On AIX we do this later.  */
1317#ifndef COLLECT_EXPORT_LIST
1318  do_tlink (ld1_argv, object_lst);
1319#endif
1320
1321  /* If -r or they will be run via some other method, do not build the
1322     constructor or destructor list, just return now.  */
1323  if (rflag
1324#ifndef COLLECT_EXPORT_LIST
1325      || ! do_collecting
1326#endif
1327      )
1328    {
1329#ifdef COLLECT_EXPORT_LIST
1330      /* Do the link we avoided above if we are exiting.  */
1331      do_tlink (ld1_argv, object_lst);
1332
1333      /* But make sure we delete the export file we may have created.  */
1334      if (export_file != 0 && export_file[0])
1335	maybe_unlink (export_file);
1336#endif
1337      maybe_unlink (c_file);
1338      maybe_unlink (o_file);
1339      return 0;
1340    }
1341
1342  /* Examine the namelist with nm and search it for static constructors
1343     and destructors to call.
1344     Write the constructor and destructor tables to a .s file and reload.  */
1345
1346  /* On AIX we already scanned for global constructors/destructors.  */
1347#ifndef COLLECT_EXPORT_LIST
1348  scan_prog_file (output_file, PASS_FIRST);
1349#endif
1350
1351#ifdef SCAN_LIBRARIES
1352  scan_libraries (output_file);
1353#endif
1354
1355  if (debug)
1356    {
1357      notice ("%d constructor(s) found\n", constructors.number);
1358      notice ("%d destructor(s)  found\n", destructors.number);
1359      notice ("%d frame table(s) found\n", frame_tables.number);
1360    }
1361
1362  if (constructors.number == 0 && destructors.number == 0
1363      && frame_tables.number == 0
1364#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1365      /* If we will be running these functions ourselves, we want to emit
1366	 stubs into the shared library so that we do not have to relink
1367	 dependent programs when we add static objects.  */
1368      && ! shared_obj
1369#endif
1370      )
1371    {
1372#ifdef COLLECT_EXPORT_LIST
1373      /* Do tlink without additional code generation.  */
1374      do_tlink (ld1_argv, object_lst);
1375#endif
1376      /* Strip now if it was requested on the command line.  */
1377      if (strip_flag)
1378	{
1379	  char **real_strip_argv = XCNEWVEC (char *, 3);
1380	  const char ** strip_argv = (const char **) real_strip_argv;
1381
1382	  strip_argv[0] = strip_file_name;
1383	  strip_argv[1] = output_file;
1384	  strip_argv[2] = (char *) 0;
1385	  fork_execute ("strip", real_strip_argv);
1386	}
1387
1388#ifdef COLLECT_EXPORT_LIST
1389      maybe_unlink (export_file);
1390#endif
1391      maybe_unlink (c_file);
1392      maybe_unlink (o_file);
1393      return 0;
1394    }
1395
1396  /* Sort ctor and dtor lists by priority.  */
1397  sort_ids (&constructors);
1398  sort_ids (&destructors);
1399
1400  maybe_unlink(output_file);
1401  outf = fopen (c_file, "w");
1402  if (outf == (FILE *) 0)
1403    fatal_perror ("fopen %s", c_file);
1404
1405  write_c_file (outf, c_file);
1406
1407  if (fclose (outf))
1408    fatal_perror ("fclose %s", c_file);
1409
1410  /* Tell the linker that we have initializer and finalizer functions.  */
1411#ifdef LD_INIT_SWITCH
1412#ifdef COLLECT_EXPORT_LIST
1413  *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
1414#else
1415  *ld2++ = LD_INIT_SWITCH;
1416  *ld2++ = initname;
1417  *ld2++ = LD_FINI_SWITCH;
1418  *ld2++ = fininame;
1419#endif
1420#endif
1421
1422#ifdef COLLECT_EXPORT_LIST
1423  if (shared_obj)
1424    {
1425      /* If we did not add export flag to link arguments before, add it to
1426	 second link phase now.  No new exports should have been added.  */
1427      if (! exports.first)
1428	*ld2++ = concat ("-bE:", export_file, NULL);
1429
1430#ifndef LD_INIT_SWITCH
1431      add_to_list (&exports, initname);
1432      add_to_list (&exports, fininame);
1433      add_to_list (&exports, "_GLOBAL__DI");
1434      add_to_list (&exports, "_GLOBAL__DD");
1435#endif
1436      exportf = fopen (export_file, "w");
1437      if (exportf == (FILE *) 0)
1438	fatal_perror ("fopen %s", export_file);
1439      write_aix_file (exportf, exports.first);
1440      if (fclose (exportf))
1441	fatal_perror ("fclose %s", export_file);
1442    }
1443#endif
1444
1445  /* End of arguments to second link phase.  */
1446  *ld2 = (char*) 0;
1447
1448  if (debug)
1449    {
1450      fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1451	       output_file, c_file);
1452      write_c_file (stderr, "stderr");
1453      fprintf (stderr, "========== end of c_file\n\n");
1454#ifdef COLLECT_EXPORT_LIST
1455      fprintf (stderr, "\n========== export_file = %s\n", export_file);
1456      write_aix_file (stderr, exports.first);
1457      fprintf (stderr, "========== end of export_file\n\n");
1458#endif
1459    }
1460
1461  /* Assemble the constructor and destructor tables.
1462     Link the tables in with the rest of the program.  */
1463
1464  fork_execute ("gcc",  c_argv);
1465#ifdef COLLECT_EXPORT_LIST
1466  /* On AIX we must call tlink because of possible templates resolution.  */
1467  do_tlink (ld2_argv, object_lst);
1468#else
1469  /* Otherwise, simply call ld because tlink is already done.  */
1470  fork_execute ("ld", ld2_argv);
1471
1472  /* Let scan_prog_file do any final mods (OSF/rose needs this for
1473     constructors/destructors in shared libraries.  */
1474  scan_prog_file (output_file, PASS_SECOND);
1475#endif
1476
1477  maybe_unlink (c_file);
1478  maybe_unlink (o_file);
1479
1480#ifdef COLLECT_EXPORT_LIST
1481  maybe_unlink (export_file);
1482#endif
1483
1484  return 0;
1485}
1486
1487
1488/* Wait for a process to finish, and exit if a nonzero status is found.  */
1489
1490int
1491collect_wait (const char *prog, struct pex_obj *pex)
1492{
1493  int status;
1494
1495  if (!pex_get_status (pex, 1, &status))
1496    fatal_perror ("can't get program status");
1497  pex_free (pex);
1498
1499  if (status)
1500    {
1501      if (WIFSIGNALED (status))
1502	{
1503	  int sig = WTERMSIG (status);
1504	  error ("%s terminated with signal %d [%s]%s",
1505		 prog, sig, strsignal(sig),
1506		 WCOREDUMP(status) ? ", core dumped" : "");
1507	  collect_exit (FATAL_EXIT_CODE);
1508	}
1509
1510      if (WIFEXITED (status))
1511	return WEXITSTATUS (status);
1512    }
1513  return 0;
1514}
1515
1516static void
1517do_wait (const char *prog, struct pex_obj *pex)
1518{
1519  int ret = collect_wait (prog, pex);
1520  if (ret != 0)
1521    {
1522      error ("%s returned %d exit status", prog, ret);
1523      collect_exit (ret);
1524    }
1525}
1526
1527
1528/* Execute a program, and wait for the reply.  */
1529
1530struct pex_obj *
1531collect_execute (const char *prog, char **argv, const char *outname,
1532		 const char *errname)
1533{
1534  struct pex_obj *pex;
1535  const char *errmsg;
1536  int err;
1537
1538  if (vflag || debug)
1539    {
1540      char **p_argv;
1541      const char *str;
1542
1543      if (argv[0])
1544	fprintf (stderr, "%s", argv[0]);
1545      else
1546	notice ("[cannot find %s]", prog);
1547
1548      for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1549	fprintf (stderr, " %s", str);
1550
1551      fprintf (stderr, "\n");
1552    }
1553
1554  fflush (stdout);
1555  fflush (stderr);
1556
1557  /* If we cannot find a program we need, complain error.  Do this here
1558     since we might not end up needing something that we could not find.  */
1559
1560  if (argv[0] == 0)
1561    fatal ("cannot find '%s'", prog);
1562
1563  pex = pex_init (0, "collect2", NULL);
1564  if (pex == NULL)
1565    fatal_perror ("pex_init failed");
1566
1567  errmsg = pex_run (pex, PEX_LAST | PEX_SEARCH, argv[0], argv, outname,
1568		    errname, &err);
1569  if (errmsg != NULL)
1570    {
1571      if (err != 0)
1572	{
1573	  errno = err;
1574	  fatal_perror (errmsg);
1575	}
1576      else
1577	fatal (errmsg);
1578    }
1579
1580  return pex;
1581}
1582
1583static void
1584fork_execute (const char *prog, char **argv)
1585{
1586  struct pex_obj *pex;
1587
1588  pex = collect_execute (prog, argv, NULL, NULL);
1589  do_wait (prog, pex);
1590}
1591
1592/* Unlink a file unless we are debugging.  */
1593
1594static void
1595maybe_unlink (const char *file)
1596{
1597  if (!debug)
1598    unlink_if_ordinary (file);
1599  else
1600    notice ("[Leaving %s]\n", file);
1601}
1602
1603
1604static long sequence_number = 0;
1605
1606/* Add a name to a linked list.  */
1607
1608static void
1609add_to_list (struct head *head_ptr, const char *name)
1610{
1611  struct id *newid = xcalloc (sizeof (struct id) + strlen (name), 1);
1612  struct id *p;
1613  strcpy (newid->name, name);
1614
1615  if (head_ptr->first)
1616    head_ptr->last->next = newid;
1617  else
1618    head_ptr->first = newid;
1619
1620  /* Check for duplicate symbols.  */
1621  for (p = head_ptr->first;
1622       strcmp (name, p->name) != 0;
1623       p = p->next)
1624    ;
1625  if (p != newid)
1626    {
1627      head_ptr->last->next = 0;
1628      free (newid);
1629      return;
1630    }
1631
1632  newid->sequence = ++sequence_number;
1633  head_ptr->last = newid;
1634  head_ptr->number++;
1635}
1636
1637/* Grab the init priority number from an init function name that
1638   looks like "_GLOBAL_.I.12345.foo".  */
1639
1640static int
1641extract_init_priority (const char *name)
1642{
1643  int pos = 0, pri;
1644
1645  while (name[pos] == '_')
1646    ++pos;
1647  pos += 10; /* strlen ("GLOBAL__X_") */
1648
1649  /* Extract init_p number from ctor/dtor name.  */
1650  pri = atoi (name + pos);
1651  return pri ? pri : DEFAULT_INIT_PRIORITY;
1652}
1653
1654/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1655   ctors will be run from right to left, dtors from left to right.  */
1656
1657static void
1658sort_ids (struct head *head_ptr)
1659{
1660  /* id holds the current element to insert.  id_next holds the next
1661     element to insert.  id_ptr iterates through the already sorted elements
1662     looking for the place to insert id.  */
1663  struct id *id, *id_next, **id_ptr;
1664
1665  id = head_ptr->first;
1666
1667  /* We don't have any sorted elements yet.  */
1668  head_ptr->first = NULL;
1669
1670  for (; id; id = id_next)
1671    {
1672      id_next = id->next;
1673      id->sequence = extract_init_priority (id->name);
1674
1675      for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1676	if (*id_ptr == NULL
1677	    /* If the sequence numbers are the same, we put the id from the
1678	       file later on the command line later in the list.  */
1679	    || id->sequence > (*id_ptr)->sequence
1680	    /* Hack: do lexical compare, too.
1681	    || (id->sequence == (*id_ptr)->sequence
1682		&& strcmp (id->name, (*id_ptr)->name) > 0) */
1683	    )
1684	  {
1685	    id->next = *id_ptr;
1686	    *id_ptr = id;
1687	    break;
1688	  }
1689    }
1690
1691  /* Now set the sequence numbers properly so write_c_file works.  */
1692  for (id = head_ptr->first; id; id = id->next)
1693    id->sequence = ++sequence_number;
1694}
1695
1696/* Write: `prefix', the names on list LIST, `suffix'.  */
1697
1698static void
1699write_list (FILE *stream, const char *prefix, struct id *list)
1700{
1701  while (list)
1702    {
1703      fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1704      list = list->next;
1705    }
1706}
1707
1708#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1709/* Given a STRING, return nonzero if it occurs in the list in range
1710   [ARGS_BEGIN,ARGS_END).  */
1711
1712static int
1713is_in_args (const char *string, const char **args_begin,
1714	    const char **args_end)
1715{
1716  const char **args_pointer;
1717  for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
1718    if (strcmp (string, *args_pointer) == 0)
1719      return 1;
1720  return 0;
1721}
1722#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1723
1724#ifdef COLLECT_EXPORT_LIST
1725/* This function is really used only on AIX, but may be useful.  */
1726#if 0
1727static int
1728is_in_list (const char *prefix, struct id *list)
1729{
1730  while (list)
1731    {
1732      if (!strcmp (prefix, list->name)) return 1;
1733      list = list->next;
1734    }
1735    return 0;
1736}
1737#endif
1738#endif /* COLLECT_EXPORT_LIST */
1739
1740/* Added for debugging purpose.  */
1741#ifdef COLLECT_EXPORT_LIST
1742static void
1743dump_list (FILE *stream, const char *prefix, struct id *list)
1744{
1745  while (list)
1746    {
1747      fprintf (stream, "%s%s,\n", prefix, list->name);
1748      list = list->next;
1749    }
1750}
1751#endif
1752
1753#if 0
1754static void
1755dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
1756{
1757  while (list)
1758    {
1759      fprintf (stream, "%s%s,\n", prefix, list->prefix);
1760      list = list->next;
1761    }
1762}
1763#endif
1764
1765static void
1766write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
1767{
1768  while (list)
1769    {
1770      fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1771	       prefix, list->sequence, list->name);
1772      list = list->next;
1773    }
1774}
1775
1776/* Write out the constructor and destructor tables statically (for a shared
1777   object), along with the functions to execute them.  */
1778
1779static void
1780write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
1781{
1782  const char *p, *q;
1783  char *prefix, *r;
1784  int frames = (frame_tables.number > 0);
1785
1786  /* Figure out name of output_file, stripping off .so version.  */
1787  p = strrchr (output_file, '/');
1788  if (p == 0)
1789    p = output_file;
1790  else
1791    p++;
1792  q = p;
1793  while (q)
1794    {
1795      q = strchr (q,'.');
1796      if (q == 0)
1797	{
1798	  q = p + strlen (p);
1799	  break;
1800	}
1801      else
1802	{
1803	  if (strncmp (q, ".so", 3) == 0)
1804	    {
1805	      q += 3;
1806	      break;
1807	    }
1808	  else
1809	    q++;
1810	}
1811    }
1812  /* q points to null at end of the string (or . of the .so version) */
1813  prefix = XNEWVEC (char, q - p + 1);
1814  strncpy (prefix, p, q - p);
1815  prefix[q - p] = 0;
1816  for (r = prefix; *r; r++)
1817    if (!ISALNUM ((unsigned char)*r))
1818      *r = '_';
1819  if (debug)
1820    notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1821	    output_file, prefix);
1822
1823  initname = concat ("_GLOBAL__FI_", prefix, NULL);
1824  fininame = concat ("_GLOBAL__FD_", prefix, NULL);
1825
1826  free (prefix);
1827
1828  /* Write the tables as C code.  */
1829
1830  fprintf (stream, "static int count;\n");
1831  fprintf (stream, "typedef void entry_pt();\n");
1832  write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1833
1834  if (frames)
1835    {
1836      write_list_with_asm (stream, "extern void *", frame_tables.first);
1837
1838      fprintf (stream, "\tstatic void *frame_table[] = {\n");
1839      write_list (stream, "\t\t&", frame_tables.first);
1840      fprintf (stream, "\t0\n};\n");
1841
1842      /* This must match what's in frame.h.  */
1843      fprintf (stream, "struct object {\n");
1844      fprintf (stream, "  void *pc_begin;\n");
1845      fprintf (stream, "  void *pc_end;\n");
1846      fprintf (stream, "  void *fde_begin;\n");
1847      fprintf (stream, "  void *fde_array;\n");
1848      fprintf (stream, "  __SIZE_TYPE__ count;\n");
1849      fprintf (stream, "  struct object *next;\n");
1850      fprintf (stream, "};\n");
1851
1852      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1853      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1854
1855      fprintf (stream, "static void reg_frame () {\n");
1856      fprintf (stream, "\tstatic struct object ob;\n");
1857      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1858      fprintf (stream, "\t}\n");
1859
1860      fprintf (stream, "static void dereg_frame () {\n");
1861      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1862      fprintf (stream, "\t}\n");
1863    }
1864
1865  fprintf (stream, "void %s() {\n", initname);
1866  if (constructors.number > 0 || frames)
1867    {
1868      fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1869      write_list (stream, "\t\t", constructors.first);
1870      if (frames)
1871	fprintf (stream, "\treg_frame,\n");
1872      fprintf (stream, "\t};\n");
1873      fprintf (stream, "\tentry_pt **p;\n");
1874      fprintf (stream, "\tif (count++ != 0) return;\n");
1875      fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1876      fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1877    }
1878  else
1879    fprintf (stream, "\t++count;\n");
1880  fprintf (stream, "}\n");
1881  write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1882  fprintf (stream, "void %s() {\n", fininame);
1883  if (destructors.number > 0 || frames)
1884    {
1885      fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1886      write_list (stream, "\t\t", destructors.first);
1887      if (frames)
1888	fprintf (stream, "\tdereg_frame,\n");
1889      fprintf (stream, "\t};\n");
1890      fprintf (stream, "\tentry_pt **p;\n");
1891      fprintf (stream, "\tif (--count != 0) return;\n");
1892      fprintf (stream, "\tp = dtors;\n");
1893      fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1894	       destructors.number + frames);
1895    }
1896  fprintf (stream, "}\n");
1897
1898  if (shared_obj)
1899    {
1900      COLLECT_SHARED_INIT_FUNC(stream, initname);
1901      COLLECT_SHARED_FINI_FUNC(stream, fininame);
1902    }
1903}
1904
1905/* Write the constructor/destructor tables.  */
1906
1907#ifndef LD_INIT_SWITCH
1908static void
1909write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
1910{
1911  /* Write the tables as C code.  */
1912
1913  int frames = (frame_tables.number > 0);
1914
1915  fprintf (stream, "typedef void entry_pt();\n\n");
1916
1917  write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1918
1919  if (frames)
1920    {
1921      write_list_with_asm (stream, "extern void *", frame_tables.first);
1922
1923      fprintf (stream, "\tstatic void *frame_table[] = {\n");
1924      write_list (stream, "\t\t&", frame_tables.first);
1925      fprintf (stream, "\t0\n};\n");
1926
1927      /* This must match what's in frame.h.  */
1928      fprintf (stream, "struct object {\n");
1929      fprintf (stream, "  void *pc_begin;\n");
1930      fprintf (stream, "  void *pc_end;\n");
1931      fprintf (stream, "  void *fde_begin;\n");
1932      fprintf (stream, "  void *fde_array;\n");
1933      fprintf (stream, "  __SIZE_TYPE__ count;\n");
1934      fprintf (stream, "  struct object *next;\n");
1935      fprintf (stream, "};\n");
1936
1937      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1938      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1939
1940      fprintf (stream, "static void reg_frame () {\n");
1941      fprintf (stream, "\tstatic struct object ob;\n");
1942      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1943      fprintf (stream, "\t}\n");
1944
1945      fprintf (stream, "static void dereg_frame () {\n");
1946      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1947      fprintf (stream, "\t}\n");
1948    }
1949
1950  fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1951  fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
1952  write_list (stream, "\t", constructors.first);
1953  if (frames)
1954    fprintf (stream, "\treg_frame,\n");
1955  fprintf (stream, "\t0\n};\n\n");
1956
1957  write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1958
1959  fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1960  fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
1961  write_list (stream, "\t", destructors.first);
1962  if (frames)
1963    fprintf (stream, "\tdereg_frame,\n");
1964  fprintf (stream, "\t0\n};\n\n");
1965
1966  fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1967  fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
1968}
1969#endif /* ! LD_INIT_SWITCH */
1970
1971static void
1972write_c_file (FILE *stream, const char *name)
1973{
1974  fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
1975#ifndef LD_INIT_SWITCH
1976  if (! shared_obj)
1977    write_c_file_glob (stream, name);
1978  else
1979#endif
1980    write_c_file_stat (stream, name);
1981  fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
1982}
1983
1984#ifdef COLLECT_EXPORT_LIST
1985static void
1986write_aix_file (FILE *stream, struct id *list)
1987{
1988  for (; list; list = list->next)
1989    {
1990      fputs (list->name, stream);
1991      putc ('\n', stream);
1992    }
1993}
1994#endif
1995
1996#ifdef OBJECT_FORMAT_NONE
1997
1998/* Generic version to scan the name list of the loaded program for
1999   the symbols g++ uses for static constructors and destructors.
2000
2001   The constructor table begins at __CTOR_LIST__ and contains a count
2002   of the number of pointers (or -1 if the constructors are built in a
2003   separate section by the linker), followed by the pointers to the
2004   constructor functions, terminated with a null pointer.  The
2005   destructor table has the same format, and begins at __DTOR_LIST__.  */
2006
2007static void
2008scan_prog_file (const char *prog_name, enum pass which_pass)
2009{
2010  void (*int_handler) (int);
2011#ifdef SIGQUIT
2012  void (*quit_handler) (int);
2013#endif
2014  char *real_nm_argv[4];
2015  const char **nm_argv = (const char **) real_nm_argv;
2016  int argc = 0;
2017  struct pex_obj *pex;
2018  const char *errmsg;
2019  int err;
2020  char *p, buf[1024];
2021  FILE *inf;
2022
2023  if (which_pass == PASS_SECOND)
2024    return;
2025
2026  /* If we do not have an `nm', complain.  */
2027  if (nm_file_name == 0)
2028    fatal ("cannot find 'nm'");
2029
2030  nm_argv[argc++] = nm_file_name;
2031  if (NM_FLAGS[0] != '\0')
2032    nm_argv[argc++] = NM_FLAGS;
2033
2034  nm_argv[argc++] = prog_name;
2035  nm_argv[argc++] = (char *) 0;
2036
2037  /* Trace if needed.  */
2038  if (vflag)
2039    {
2040      const char **p_argv;
2041      const char *str;
2042
2043      for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2044	fprintf (stderr, " %s", str);
2045
2046      fprintf (stderr, "\n");
2047    }
2048
2049  fflush (stdout);
2050  fflush (stderr);
2051
2052  pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2053  if (pex == NULL)
2054    fatal_perror ("pex_init failed");
2055
2056  errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, NULL, &err);
2057  if (errmsg != NULL)
2058    {
2059      if (err != 0)
2060	{
2061	  errno = err;
2062	  fatal_perror (errmsg);
2063	}
2064      else
2065	fatal (errmsg);
2066    }
2067
2068  int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
2069#ifdef SIGQUIT
2070  quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2071#endif
2072
2073  inf = pex_read_output (pex, 0);
2074  if (inf == NULL)
2075    fatal_perror ("can't open nm output");
2076
2077  if (debug)
2078    fprintf (stderr, "\nnm output with constructors/destructors.\n");
2079
2080  /* Read each line of nm output.  */
2081  while (fgets (buf, sizeof buf, inf) != (char *) 0)
2082    {
2083      int ch, ch2;
2084      char *name, *end;
2085
2086      /* If it contains a constructor or destructor name, add the name
2087	 to the appropriate list.  */
2088
2089      for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2090	if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2091	  break;
2092
2093      if (ch != '_')
2094	continue;
2095
2096      name = p;
2097      /* Find the end of the symbol name.
2098	 Do not include `|', because Encore nm can tack that on the end.  */
2099      for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2100	   end++)
2101	continue;
2102
2103
2104      *end = '\0';
2105      switch (is_ctor_dtor (name))
2106	{
2107	case 1:
2108	  if (which_pass != PASS_LIB)
2109	    add_to_list (&constructors, name);
2110	  break;
2111
2112	case 2:
2113	  if (which_pass != PASS_LIB)
2114	    add_to_list (&destructors, name);
2115	  break;
2116
2117	case 3:
2118	  if (which_pass != PASS_LIB)
2119	    fatal ("init function found in object %s", prog_name);
2120#ifndef LD_INIT_SWITCH
2121	  add_to_list (&constructors, name);
2122#endif
2123	  break;
2124
2125	case 4:
2126	  if (which_pass != PASS_LIB)
2127	    fatal ("fini function found in object %s", prog_name);
2128#ifndef LD_FINI_SWITCH
2129	  add_to_list (&destructors, name);
2130#endif
2131	  break;
2132
2133	case 5:
2134	  if (which_pass != PASS_LIB)
2135	    add_to_list (&frame_tables, name);
2136	  break;
2137
2138	default:		/* not a constructor or destructor */
2139	  continue;
2140	}
2141
2142      if (debug)
2143	fprintf (stderr, "\t%s\n", buf);
2144    }
2145
2146  if (debug)
2147    fprintf (stderr, "\n");
2148
2149  do_wait (nm_file_name, pex);
2150
2151  signal (SIGINT,  int_handler);
2152#ifdef SIGQUIT
2153  signal (SIGQUIT, quit_handler);
2154#endif
2155}
2156
2157#ifdef LDD_SUFFIX
2158
2159/* Use the List Dynamic Dependencies program to find shared libraries that
2160   the output file depends upon and their initialization/finalization
2161   routines, if any.  */
2162
2163static void
2164scan_libraries (const char *prog_name)
2165{
2166  static struct head libraries;		/* list of shared libraries found */
2167  struct id *list;
2168  void (*int_handler) (int);
2169#ifdef SIGQUIT
2170  void (*quit_handler) (int);
2171#endif
2172  char *real_ldd_argv[4];
2173  const char **ldd_argv = (const char **) real_ldd_argv;
2174  int argc = 0;
2175  struct pex_obj *pex;
2176  const char *errmsg;
2177  int err;
2178  char buf[1024];
2179  FILE *inf;
2180
2181  /* If we do not have an `ldd', complain.  */
2182  if (ldd_file_name == 0)
2183    {
2184      error ("cannot find 'ldd'");
2185      return;
2186    }
2187
2188  ldd_argv[argc++] = ldd_file_name;
2189  ldd_argv[argc++] = prog_name;
2190  ldd_argv[argc++] = (char *) 0;
2191
2192  /* Trace if needed.  */
2193  if (vflag)
2194    {
2195      const char **p_argv;
2196      const char *str;
2197
2198      for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2199	fprintf (stderr, " %s", str);
2200
2201      fprintf (stderr, "\n");
2202    }
2203
2204  fflush (stdout);
2205  fflush (stderr);
2206
2207  pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2208  if (pex == NULL)
2209    fatal_perror ("pex_init failed");
2210
2211  errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err);
2212  if (errmsg != NULL)
2213    {
2214      if (err != 0)
2215	{
2216	  errno = err;
2217	  fatal_perror (errmsg);
2218	}
2219      else
2220	fatal (errmsg);
2221    }
2222
2223  int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
2224#ifdef SIGQUIT
2225  quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2226#endif
2227
2228  inf = pex_read_output (pex, 0);
2229  if (inf == NULL)
2230    fatal_perror ("can't open ldd output");
2231
2232  if (debug)
2233    notice ("\nldd output with constructors/destructors.\n");
2234
2235  /* Read each line of ldd output.  */
2236  while (fgets (buf, sizeof buf, inf) != (char *) 0)
2237    {
2238      int ch2;
2239      char *name, *end, *p = buf;
2240
2241      /* Extract names of libraries and add to list.  */
2242      PARSE_LDD_OUTPUT (p);
2243      if (p == 0)
2244	continue;
2245
2246      name = p;
2247      if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2248	fatal ("dynamic dependency %s not found", buf);
2249
2250      /* Find the end of the symbol name.  */
2251      for (end = p;
2252	   (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2253	   end++)
2254	continue;
2255      *end = '\0';
2256
2257      if (access (name, R_OK) == 0)
2258	add_to_list (&libraries, name);
2259      else
2260	fatal ("unable to open dynamic dependency '%s'", buf);
2261
2262      if (debug)
2263	fprintf (stderr, "\t%s\n", buf);
2264    }
2265  if (debug)
2266    fprintf (stderr, "\n");
2267
2268  do_wait (ldd_file_name, pex);
2269
2270  signal (SIGINT,  int_handler);
2271#ifdef SIGQUIT
2272  signal (SIGQUIT, quit_handler);
2273#endif
2274
2275  /* Now iterate through the library list adding their symbols to
2276     the list.  */
2277  for (list = libraries.first; list; list = list->next)
2278    scan_prog_file (list->name, PASS_LIB);
2279}
2280
2281#endif /* LDD_SUFFIX */
2282
2283#endif /* OBJECT_FORMAT_NONE */
2284
2285
2286/*
2287 * COFF specific stuff.
2288 */
2289
2290#ifdef OBJECT_FORMAT_COFF
2291
2292#if defined (EXTENDED_COFF)
2293
2294#   define GCC_SYMBOLS(X)	(SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2295#   define GCC_SYMENT		SYMR
2296#   define GCC_OK_SYMBOL(X)	((X).st == stProc || (X).st == stGlobal)
2297#   define GCC_SYMINC(X)	(1)
2298#   define GCC_SYMZERO(X)	(SYMHEADER(X).isymMax)
2299#   define GCC_CHECK_HDR(X)	(PSYMTAB(X) != 0)
2300
2301#else
2302
2303#   define GCC_SYMBOLS(X)	(HEADER(ldptr).f_nsyms)
2304#   define GCC_SYMENT		SYMENT
2305#   if defined (C_WEAKEXT)
2306#     define GCC_OK_SYMBOL(X) \
2307       (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2308	((X).n_scnum > N_UNDEF) && \
2309	(aix64_flag \
2310	 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2311	     || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2312#     define GCC_UNDEF_SYMBOL(X) \
2313       (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2314	((X).n_scnum == N_UNDEF))
2315#   else
2316#     define GCC_OK_SYMBOL(X) \
2317       (((X).n_sclass == C_EXT) && \
2318	((X).n_scnum > N_UNDEF) && \
2319	(aix64_flag \
2320	 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2321	     || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2322#     define GCC_UNDEF_SYMBOL(X) \
2323       (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2324#   endif
2325#   define GCC_SYMINC(X)	((X).n_numaux+1)
2326#   define GCC_SYMZERO(X)	0
2327
2328/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2329#ifdef _AIX51
2330#   define GCC_CHECK_HDR(X) \
2331     ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2332      || (HEADER (X).f_magic == 0767 && aix64_flag))
2333#else
2334#   define GCC_CHECK_HDR(X) \
2335     ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2336      || (HEADER (X).f_magic == 0757 && aix64_flag))
2337#endif
2338
2339#endif
2340
2341#ifdef COLLECT_EXPORT_LIST
2342/* Array of standard AIX libraries which should not
2343   be scanned for ctors/dtors.  */
2344static const char *const aix_std_libs[] = {
2345  "/unix",
2346  "/lib/libc.a",
2347  "/lib/libm.a",
2348  "/lib/libc_r.a",
2349  "/lib/libm_r.a",
2350  "/usr/lib/libc.a",
2351  "/usr/lib/libm.a",
2352  "/usr/lib/libc_r.a",
2353  "/usr/lib/libm_r.a",
2354  "/usr/lib/threads/libc.a",
2355  "/usr/ccs/lib/libc.a",
2356  "/usr/ccs/lib/libm.a",
2357  "/usr/ccs/lib/libc_r.a",
2358  "/usr/ccs/lib/libm_r.a",
2359  NULL
2360};
2361
2362/* This function checks the filename and returns 1
2363   if this name matches the location of a standard AIX library.  */
2364static int ignore_library (const char *);
2365static int
2366ignore_library (const char *name)
2367{
2368  const char *const *p = &aix_std_libs[0];
2369  while (*p++ != NULL)
2370    if (! strcmp (name, *p)) return 1;
2371  return 0;
2372}
2373#endif /* COLLECT_EXPORT_LIST */
2374
2375#if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2376extern char *ldgetname (LDFILE *, GCC_SYMENT *);
2377#endif
2378
2379/* COFF version to scan the name list of the loaded program for
2380   the symbols g++ uses for static constructors and destructors.
2381
2382   The constructor table begins at __CTOR_LIST__ and contains a count
2383   of the number of pointers (or -1 if the constructors are built in a
2384   separate section by the linker), followed by the pointers to the
2385   constructor functions, terminated with a null pointer.  The
2386   destructor table has the same format, and begins at __DTOR_LIST__.  */
2387
2388static void
2389scan_prog_file (const char *prog_name, enum pass which_pass)
2390{
2391  LDFILE *ldptr = NULL;
2392  int sym_index, sym_count;
2393  int is_shared = 0;
2394
2395  if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2396    return;
2397
2398#ifdef COLLECT_EXPORT_LIST
2399  /* We do not need scanning for some standard C libraries.  */
2400  if (which_pass == PASS_FIRST && ignore_library (prog_name))
2401    return;
2402
2403  /* On AIX we have a loop, because there is not much difference
2404     between an object and an archive. This trick allows us to
2405     eliminate scan_libraries() function.  */
2406  do
2407    {
2408#endif
2409      /* Some platforms (e.g. OSF4) declare ldopen as taking a
2410	 non-const char * filename parameter, even though it will not
2411	 modify that string.  So we must cast away const-ness here,
2412	 which will cause -Wcast-qual to burp.  */
2413      if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
2414	{
2415	  if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2416	    fatal ("%s: not a COFF file", prog_name);
2417
2418	  if (GCC_CHECK_HDR (ldptr))
2419	    {
2420	      sym_count = GCC_SYMBOLS (ldptr);
2421	      sym_index = GCC_SYMZERO (ldptr);
2422
2423#ifdef COLLECT_EXPORT_LIST
2424	      /* Is current archive member a shared object?  */
2425	      is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2426#endif
2427
2428	      while (sym_index < sym_count)
2429		{
2430		  GCC_SYMENT symbol;
2431
2432		  if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2433		    break;
2434		  sym_index += GCC_SYMINC (symbol);
2435
2436		  if (GCC_OK_SYMBOL (symbol))
2437		    {
2438		      char *name;
2439
2440		      if ((name = ldgetname (ldptr, &symbol)) == NULL)
2441			continue;		/* Should never happen.  */
2442
2443#ifdef XCOFF_DEBUGGING_INFO
2444		      /* All AIX function names have a duplicate entry
2445			 beginning with a dot.  */
2446		      if (*name == '.')
2447			++name;
2448#endif
2449
2450		      switch (is_ctor_dtor (name))
2451			{
2452			case 1:
2453			  if (! is_shared)
2454			    add_to_list (&constructors, 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			case 2:
2462			  if (! is_shared)
2463			    add_to_list (&destructors, name);
2464#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2465			  if (which_pass == PASS_OBJ)
2466			    add_to_list (&exports, name);
2467#endif
2468			  break;
2469
2470#ifdef COLLECT_EXPORT_LIST
2471			case 3:
2472#ifndef LD_INIT_SWITCH
2473			  if (is_shared)
2474			    add_to_list (&constructors, name);
2475#endif
2476			  break;
2477
2478			case 4:
2479#ifndef LD_INIT_SWITCH
2480			  if (is_shared)
2481			    add_to_list (&destructors, name);
2482#endif
2483			  break;
2484#endif
2485
2486			case 5:
2487			  if (! is_shared)
2488			    add_to_list (&frame_tables, name);
2489#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2490			  if (which_pass == PASS_OBJ)
2491			    add_to_list (&exports, name);
2492#endif
2493			  break;
2494
2495			default:	/* not a constructor or destructor */
2496#ifdef COLLECT_EXPORT_LIST
2497			  /* Explicitly export all global symbols when
2498			     building a shared object on AIX, but do not
2499			     re-export symbols from another shared object
2500			     and do not export symbols if the user
2501			     provides an explicit export list.  */
2502			  if (shared_obj && !is_shared
2503			      && which_pass == PASS_OBJ && !export_flag)
2504			    add_to_list (&exports, name);
2505#endif
2506			  continue;
2507			}
2508
2509		      if (debug)
2510#if !defined(EXTENDED_COFF)
2511			fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2512				 symbol.n_scnum, symbol.n_sclass,
2513				 (symbol.n_type ? "0" : ""), symbol.n_type,
2514				 name);
2515#else
2516			fprintf (stderr,
2517				 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2518				 symbol.iss, (long) symbol.value, symbol.index, name);
2519#endif
2520		    }
2521		}
2522	    }
2523#ifdef COLLECT_EXPORT_LIST
2524	  else
2525	    {
2526	      /* If archive contains both 32-bit and 64-bit objects,
2527		 we want to skip objects in other mode so mismatch normal.  */
2528	      if (debug)
2529		fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2530			 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2531	    }
2532#endif
2533	}
2534      else
2535	{
2536	  fatal ("%s: cannot open as COFF file", prog_name);
2537	}
2538#ifdef COLLECT_EXPORT_LIST
2539      /* On AIX loop continues while there are more members in archive.  */
2540    }
2541  while (ldclose (ldptr) == FAILURE);
2542#else
2543  /* Otherwise we simply close ldptr.  */
2544  (void) ldclose(ldptr);
2545#endif
2546}
2547#endif /* OBJECT_FORMAT_COFF */
2548
2549#ifdef COLLECT_EXPORT_LIST
2550/* Given a library name without "lib" prefix, this function
2551   returns a full library name including a path.  */
2552static char *
2553resolve_lib_name (const char *name)
2554{
2555  char *lib_buf;
2556  int i, j, l = 0;
2557  /* Library extensions for AIX dynamic linking.  */
2558  const char * const libexts[2] = {"a", "so"};
2559
2560  for (i = 0; libpaths[i]; i++)
2561    if (libpaths[i]->max_len > l)
2562      l = libpaths[i]->max_len;
2563
2564  lib_buf = xmalloc (l + strlen(name) + 10);
2565
2566  for (i = 0; libpaths[i]; i++)
2567    {
2568      struct prefix_list *list = libpaths[i]->plist;
2569      for (; list; list = list->next)
2570	{
2571	  /* The following lines are needed because path_prefix list
2572	     may contain directories both with trailing '/' and
2573	     without it.  */
2574	  const char *p = "";
2575	  if (list->prefix[strlen(list->prefix)-1] != '/')
2576	    p = "/";
2577	  for (j = 0; j < 2; j++)
2578	    {
2579	      sprintf (lib_buf, "%s%slib%s.%s",
2580		       list->prefix, p, name,
2581		       libexts[(j + aixrtl_flag) % 2]);
2582	      if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2583	      if (file_exists (lib_buf))
2584		{
2585		  if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2586		  return (lib_buf);
2587		}
2588	    }
2589	}
2590    }
2591  if (debug)
2592    fprintf (stderr, "not found\n");
2593  else
2594    fatal ("library lib%s not found", name);
2595  return (NULL);
2596}
2597#endif /* COLLECT_EXPORT_LIST */
2598