OSDN Git Service

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