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