OSDN Git Service

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