OSDN Git Service

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