OSDN Git Service

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