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