OSDN Git Service

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