OSDN Git Service

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