]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/collect2.c
* output.h (__gcc_host_wide_int__): Move to hwint.h.
[thirdparty/gcc.git] / gcc / collect2.c
CommitLineData
af4ae74b 1/* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
ca628a86 3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
5641963c 4 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
cfaf579d 5 Free Software Foundation, Inc.
832f2315 6 Contributed by Chris Smith (csmith@convex.com).
809e4ea4 7 Heavily modified by Michael Meissner (meissner@cygnus.com),
832f2315 8 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
9
f12b58b3 10This file is part of GCC.
832f2315 11
f12b58b3 12GCC is free software; you can redistribute it and/or modify it under
13the terms of the GNU General Public License as published by the Free
8c4c00c1 14Software Foundation; either version 3, or (at your option) any later
f12b58b3 15version.
832f2315 16
f12b58b3 17GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18WARRANTY; without even the implied warranty of MERCHANTABILITY or
19FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20for more details.
832f2315 21
22You should have received a copy of the GNU General Public License
8c4c00c1 23along with GCC; see the file COPYING3. If not see
24<http://www.gnu.org/licenses/>. */
832f2315 25
26
a92771b8 27/* Build tables of static constructors and destructors and run ld. */
832f2315 28
de61b97c 29#include "config.h"
405711de 30#include "system.h"
805e22b2 31#include "coretypes.h"
32#include "tm.h"
82715bcd 33#include "filenames.h"
832f2315 34
a2beb429 35/* TARGET_64BIT may be defined to use driver specific functionality. */
36#undef TARGET_64BIT
37#define TARGET_64BIT TARGET_64BIT_DEFAULT
38
397f1574 39#ifndef LIBRARY_PATH_ENV
40#define LIBRARY_PATH_ENV "LIBRARY_PATH"
41#endif
42
de61b97c 43#define COLLECT
44
1ae13971 45#include "collect2.h"
cabc7147 46#include "collect2-aix.h"
11091b4d 47#include "diagnostic.h"
de61b97c 48#include "demangle.h"
49#include "obstack.h"
be2828ce 50#include "intl.h"
56fc5f02 51#include "version.h"
22f0924c 52\f
53/* On certain systems, we have code that works by scanning the object file
54 directly. But this code uses system-specific header files and library
e533c428 55 functions, so turn it off in a cross-compiler. Likewise, the names of
d1058090 56 the utilities are not correct for a cross-compiler; we have to hope that
e533c428 57 cross-versions are in the proper directories. */
22f0924c 58
29d774d0 59#ifdef CROSS_DIRECTORY_STRUCTURE
cabc7147 60#ifndef CROSS_AIX_SUPPORT
22f0924c 61#undef OBJECT_FORMAT_COFF
cabc7147 62#endif
e533c428 63#undef MD_EXEC_PREFIX
64#undef REAL_LD_FILE_NAME
65#undef REAL_NM_FILE_NAME
66#undef REAL_STRIP_FILE_NAME
22f0924c 67#endif
68
d1058090 69/* If we cannot use a special method, use the ordinary one:
22f0924c 70 run nm to find what symbols are present.
71 In a cross-compiler, this means you need a cross nm,
d1058090 72 but that is not quite as unpleasant as special headers. */
22f0924c 73
4bfa9136 74#if !defined (OBJECT_FORMAT_COFF)
22f0924c 75#define OBJECT_FORMAT_NONE
76#endif
77
78#ifdef OBJECT_FORMAT_COFF
79
cabc7147 80#ifndef CROSS_DIRECTORY_STRUCTURE
22f0924c 81#include <a.out.h>
82#include <ar.h>
83
84#ifdef UMAX
85#include <sgs.h>
86#endif
87
2dbf77ee 88/* Many versions of ldfcn.h define these. */
89#ifdef FREAD
22f0924c 90#undef FREAD
91#undef FWRITE
92#endif
93
94#include <ldfcn.h>
cabc7147 95#endif
22f0924c 96
f1ec03c4 97/* Some systems have an ISCOFF macro, but others do not. In some cases
98 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
89a1f620 99 that either do not have an ISCOFF macro in /usr/include or for those
f1ec03c4 100 where it is wrong. */
101
afc39df4 102#ifndef MY_ISCOFF
103#define MY_ISCOFF(X) ISCOFF (X)
104#endif
105
22f0924c 106#endif /* OBJECT_FORMAT_COFF */
107
22f0924c 108#ifdef OBJECT_FORMAT_NONE
109
832f2315 110/* Default flags to pass to nm. */
111#ifndef NM_FLAGS
9bc65db1 112#define NM_FLAGS "-n"
832f2315 113#endif
114
22f0924c 115#endif /* OBJECT_FORMAT_NONE */
b0b9762f 116
117/* Some systems use __main in a way incompatible with its use in gcc, in these
118 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
7cdd3716 119 give the same symbol without quotes for an alternative entry point. */
b0b9762f 120#ifndef NAME__MAIN
121#define NAME__MAIN "__main"
b0b9762f 122#endif
123
69988048 124/* This must match tree.h. */
125#define DEFAULT_INIT_PRIORITY 65535
126
2f9e77d1 127#ifndef COLLECT_SHARED_INIT_FUNC
128#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
129 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
130#endif
131#ifndef COLLECT_SHARED_FINI_FUNC
132#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
133 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
134#endif
135
5219c73b 136#ifdef LDD_SUFFIX
b7c87ff2 137#define SCAN_LIBRARIES
138#endif
d2f0b724 139
1ba3a590 140#ifndef SHLIB_SUFFIX
141#define SHLIB_SUFFIX ".so"
142#endif
143
d2f0b724 144#ifdef USE_COLLECT2
145int do_collecting = 1;
146#else
147int do_collecting = 0;
148#endif
402eb8ac 149
912df756 150/* Cook up an always defined indication of whether we proceed the
151 "EXPORT_LIST" way. */
152
153#ifdef COLLECT_EXPORT_LIST
154#define DO_COLLECT_EXPORT_LIST 1
155#else
156#define DO_COLLECT_EXPORT_LIST 0
157#endif
158
402eb8ac 159/* Nonzero if we should suppress the automatic demangling of identifiers
160 in linker error messages. Set from COLLECT_NO_DEMANGLE. */
161int no_demangle;
832f2315 162\f
a92771b8 163/* Linked lists of constructor and destructor names. */
832f2315 164
89a1f620 165struct id
832f2315 166{
167 struct id *next;
168 int sequence;
169 char name[1];
170};
171
172struct head
173{
174 struct id *first;
175 struct id *last;
176 int number;
177};
178
2bd5037b 179bool vflag; /* true if -v or --version */
832f2315 180static int rflag; /* true if -r */
8989da5d 181static int strip_flag; /* true if -s */
d1058090 182#ifdef COLLECT_EXPORT_LIST
183static int export_flag; /* true if -bE */
9ae139a2 184static int aix64_flag; /* true if -b64 */
07090bac 185static int aixrtl_flag; /* true if -brtl */
d1058090 186#endif
832f2315 187
7bfefa9d 188enum lto_mode_d {
189 LTO_MODE_NONE, /* Not doing LTO. */
190 LTO_MODE_LTO, /* Normal LTO. */
191 LTO_MODE_WHOPR /* WHOPR. */
192};
193
194/* Current LTO mode. */
195static enum lto_mode_d lto_mode = LTO_MODE_NONE;
196
2bd5037b 197bool debug; /* true if -debug */
198bool helpflag; /* true if --help */
832f2315 199
a0c938f0 200static int shared_obj; /* true if -shared */
b7c87ff2 201
e504db4a 202static const char *c_file; /* <xxx>.c for constructor/destructor list. */
203static const char *o_file; /* <xxx>.o for constructor/destructor list. */
d1058090 204#ifdef COLLECT_EXPORT_LIST
a0c938f0 205static const char *export_file; /* <xxx>.x for AIX export list. */
d1058090 206#endif
7bfefa9d 207static char **lto_o_files; /* Output files for LTO. */
d6b5203d 208const char *ldout; /* File for ld stdout. */
209const char *lderrout; /* File for ld stderr. */
e504db4a 210static const char *output_file; /* Output file for ld. */
211static const char *nm_file_name; /* pathname of nm */
579f88d2 212#ifdef LDD_SUFFIX
e504db4a 213static const char *ldd_file_name; /* pathname of ldd (or equivalent) */
579f88d2 214#endif
e504db4a 215static const char *strip_file_name; /* pathname of strip */
a0c938f0 216const char *c_file_name; /* pathname of gcc */
a9b00323 217static char *initname, *fininame; /* names of init and fini funcs */
832f2315 218
219static struct head constructors; /* list of constructors found */
220static struct head destructors; /* list of destructors found */
d1058090 221#ifdef COLLECT_EXPORT_LIST
a9b00323 222static struct head exports; /* list of exported symbols */
d1058090 223#endif
d757b8c9 224static struct head frame_tables; /* list of frame unwind info tables */
832f2315 225
c159e0b7 226static bool at_file_supplied; /* Whether to use @file arguments */
227static char *response_file; /* Name of any current response file */
228
d2f0b724 229struct obstack temporary_obstack;
d2f0b724 230char * temporary_firstobj;
231
ef6fd54f 232/* A string that must be prepended to a target OS path in order to find
233 it on the host system. */
234#ifdef TARGET_SYSTEM_ROOT
235static const char *target_system_root = TARGET_SYSTEM_ROOT;
236#else
237static const char *target_system_root = "";
238#endif
239
2b98e22b 240/* Whether we may unlink the output file, which should be set as soon as we
241 know we have successfully produced it. This is typically useful to prevent
242 blindly attempting to unlink a read-only output that the target linker
243 would leave untouched. */
244bool may_unlink_output_file = false;
245
3d082955 246/* Structure to hold all the directories in which to search for files to
247 execute. */
248
249struct prefix_list
250{
e504db4a 251 const char *prefix; /* String to prepend to the path. */
a92771b8 252 struct prefix_list *next; /* Next in linked list. */
3d082955 253};
254
255struct path_prefix
256{
257 struct prefix_list *plist; /* List of prefixes to try */
258 int max_len; /* Max length of a prefix in PLIST */
e504db4a 259 const char *name; /* Name of this list (used in config stuff) */
3d082955 260};
261
d1058090 262#ifdef COLLECT_EXPORT_LIST
2c0e001b 263/* Lists to keep libraries to be scanned for global constructors/destructors. */
d1058090 264static struct head libs; /* list of libraries */
265static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
266static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
267static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
268 &libpath_lib_dirs, NULL};
d1058090 269#endif
270
7bfefa9d 271/* List of names of object files containing LTO information.
272 These are a subset of the object file names appearing on the
273 command line, and must be identical, in the sense of pointer
274 equality, with the names passed to maybe_run_lto_and_relink(). */
275
276struct lto_object
277{
278 const char *name; /* Name of object file. */
279 struct lto_object *next; /* Next in linked list. */
280};
281
282struct lto_object_list
283{
284 struct lto_object *first; /* First list element. */
285 struct lto_object *last; /* Last list element. */
286};
287
288static struct lto_object_list lto_objects;
289
efc8f8d6 290/* Special kinds of symbols that a name may denote. */
291
292typedef enum {
293 SYM_REGULAR = 0, /* nothing special */
294
295 SYM_CTOR = 1, /* constructor */
296 SYM_DTOR = 2, /* destructor */
297 SYM_INIT = 3, /* shared object routine that calls all the ctors */
298 SYM_FINI = 4, /* shared object routine that calls all the dtors */
299 SYM_DWEH = 5 /* DWARF exception handling table */
300} symkind;
301
302static symkind is_ctor_dtor (const char *);
303
89a1f620 304static void handler (int);
89a1f620 305static char *find_a_file (struct path_prefix *, const char *);
306static void add_prefix (struct path_prefix *, const char *);
307static void prefix_from_env (const char *, struct path_prefix *);
308static void prefix_from_string (const char *, struct path_prefix *);
6e24b140 309static void do_wait (const char *, struct pex_obj *);
89a1f620 310static void fork_execute (const char *, char **);
311static void maybe_unlink (const char *);
7bfefa9d 312static void maybe_unlink_list (char **);
89a1f620 313static void add_to_list (struct head *, const char *);
314static int extract_init_priority (const char *);
315static void sort_ids (struct head *);
316static void write_list (FILE *, const char *, struct id *);
0e93a6ac 317#ifdef COLLECT_EXPORT_LIST
89a1f620 318static void dump_list (FILE *, const char *, struct id *);
0e93a6ac 319#endif
320#if 0
89a1f620 321static void dump_prefix_list (FILE *, const char *, struct prefix_list *);
e504db4a 322#endif
89a1f620 323static void write_list_with_asm (FILE *, const char *, struct id *);
324static void write_c_file (FILE *, const char *);
325static void write_c_file_stat (FILE *, const char *);
e504db4a 326#ifndef LD_INIT_SWITCH
89a1f620 327static void write_c_file_glob (FILE *, const char *);
0e93a6ac 328#endif
99c14947 329#ifdef SCAN_LIBRARIES
89a1f620 330static void scan_libraries (const char *);
99c14947 331#endif
d1058090 332#ifdef COLLECT_EXPORT_LIST
0c87a39e 333#if 0
89a1f620 334static int is_in_list (const char *, struct id *);
0c87a39e 335#endif
89a1f620 336static void write_aix_file (FILE *, struct id *);
337static char *resolve_lib_name (const char *);
d1058090 338#endif
89a1f620 339static char *extract_string (const char **);
3f5e90a3 340static void post_ld_pass (bool);
341static void process_args (int *argcp, char **argv);
912df756 342
343/* Enumerations describing which pass this is for scanning the
344 program file ... */
345
346typedef enum {
347 PASS_FIRST, /* without constructors */
348 PASS_OBJ, /* individual objects */
349 PASS_LIB, /* looking for shared libraries */
7bfefa9d 350 PASS_SECOND, /* with constructors linked in */
351 PASS_LTOINFO /* looking for objects with LTO info */
912df756 352} scanpass;
353
354/* ... and which kinds of symbols are to be considered. */
355
356enum scanfilter_masks {
357 SCAN_NOTHING = 0,
358
48e1416a 359 SCAN_CTOR = 1 << SYM_CTOR,
912df756 360 SCAN_DTOR = 1 << SYM_DTOR,
361 SCAN_INIT = 1 << SYM_INIT,
362 SCAN_FINI = 1 << SYM_FINI,
363 SCAN_DWEH = 1 << SYM_DWEH,
364 SCAN_ALL = ~0
365};
366
367/* This type is used for parameters and variables which hold
368 combinations of the flags in enum scanfilter_masks. */
369typedef int scanfilter;
370
371/* Scan the name list of the loaded program for the symbols g++ uses for
372 static constructors and destructors.
373
374 The SCANPASS argument tells which collect processing pass this is for and
375 the SCANFILTER argument tells which kinds of symbols to consider in this
376 pass. Symbols of a special kind not in the filter mask are considered as
377 regular ones.
378
379 The constructor table begins at __CTOR_LIST__ and contains a count of the
380 number of pointers (or -1 if the constructors are built in a separate
381 section by the linker), followed by the pointers to the constructor
382 functions, terminated with a null pointer. The destructor table has the
383 same format, and begins at __DTOR_LIST__. */
384
385static void scan_prog_file (const char *, scanpass, scanfilter);
386
832f2315 387\f
832f2315 388/* Delete tempfiles and exit function. */
389
d2f0b724 390void
89a1f620 391collect_exit (int status)
832f2315 392{
22f0924c 393 if (c_file != 0 && c_file[0])
832f2315 394 maybe_unlink (c_file);
395
22f0924c 396 if (o_file != 0 && o_file[0])
832f2315 397 maybe_unlink (o_file);
398
d1058090 399#ifdef COLLECT_EXPORT_LIST
a9b00323 400 if (export_file != 0 && export_file[0])
401 maybe_unlink (export_file);
d1058090 402#endif
403
7bfefa9d 404 if (lto_o_files)
405 maybe_unlink_list (lto_o_files);
406
d2f0b724 407 if (ldout != 0 && ldout[0])
408 {
b5369b7d 409 dump_ld_file (ldout, stdout);
d2f0b724 410 maybe_unlink (ldout);
411 }
412
d6b5203d 413 if (lderrout != 0 && lderrout[0])
414 {
b5369b7d 415 dump_ld_file (lderrout, stderr);
d6b5203d 416 maybe_unlink (lderrout);
417 }
418
131353cd 419 if (status != 0 && output_file != 0 && output_file[0])
420 maybe_unlink (output_file);
421
c159e0b7 422 if (response_file)
423 maybe_unlink (response_file);
424
832f2315 425 exit (status);
426}
427
428\f
be2828ce 429/* Notify user of a non-error. */
430void
380c6697 431notice (const char *cmsgid, ...)
be2828ce 432{
ee582a61 433 va_list ap;
89a1f620 434
380c6697 435 va_start (ap, cmsgid);
436 vfprintf (stderr, _(cmsgid), ap);
ee582a61 437 va_end (ap);
be2828ce 438}
439
70da6ffe 440/* Notify user of a non-error, without translating the format string. */
441void
442notice_translated (const char *cmsgid, ...)
443{
444 va_list ap;
445
446 va_start (ap, cmsgid);
447 vfprintf (stderr, cmsgid, ap);
448 va_end (ap);
449}
832f2315 450\f
451static void
89a1f620 452handler (int signo)
832f2315 453{
7fad41d4 454 if (c_file != 0 && c_file[0])
832f2315 455 maybe_unlink (c_file);
456
7fad41d4 457 if (o_file != 0 && o_file[0])
832f2315 458 maybe_unlink (o_file);
459
d2f0b724 460 if (ldout != 0 && ldout[0])
461 maybe_unlink (ldout);
462
d6b5203d 463 if (lderrout != 0 && lderrout[0])
464 maybe_unlink (lderrout);
465
d1058090 466#ifdef COLLECT_EXPORT_LIST
70fd963a 467 if (export_file != 0 && export_file[0])
468 maybe_unlink (export_file);
d1058090 469#endif
470
7bfefa9d 471 if (lto_o_files)
472 maybe_unlink_list (lto_o_files);
473
c159e0b7 474 if (response_file)
475 maybe_unlink (response_file);
476
832f2315 477 signal (signo, SIG_DFL);
6e24b140 478 raise (signo);
832f2315 479}
480
481\f
d2f0b724 482int
89a1f620 483file_exists (const char *name)
d2f0b724 484{
485 return access (name, R_OK) == 0;
832f2315 486}
487
7802b788 488/* Parse a reasonable subset of shell quoting syntax. */
489
490static char *
89a1f620 491extract_string (const char **pp)
7802b788 492{
e504db4a 493 const char *p = *pp;
7802b788 494 int backquote = 0;
495 int inside = 0;
496
497 for (;;)
498 {
499 char c = *p;
500 if (c == '\0')
501 break;
502 ++p;
503 if (backquote)
504 obstack_1grow (&temporary_obstack, c);
505 else if (! inside && c == ' ')
506 break;
507 else if (! inside && c == '\\')
508 backquote = 1;
509 else if (c == '\'')
510 inside = !inside;
511 else
512 obstack_1grow (&temporary_obstack, c);
513 }
514
251341d1 515 obstack_1grow (&temporary_obstack, '\0');
7802b788 516 *pp = p;
4fac984f 517 return XOBFINISH (&temporary_obstack, char *);
7802b788 518}
22f0924c 519\f
d2f0b724 520void
b5369b7d 521dump_ld_file (const char *name, FILE *to)
d2f0b724 522{
523 FILE *stream = fopen (name, "r");
d2f0b724 524
525 if (stream == 0)
526 return;
527 while (1)
528 {
529 int c;
530 while (c = getc (stream),
66a33570 531 c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
d2f0b724 532 obstack_1grow (&temporary_obstack, c);
533 if (obstack_object_size (&temporary_obstack) > 0)
534 {
e504db4a 535 const char *word, *p;
536 char *result;
d2f0b724 537 obstack_1grow (&temporary_obstack, '\0');
4fac984f 538 word = XOBFINISH (&temporary_obstack, const char *);
d2f0b724 539
540 if (*word == '.')
d6b5203d 541 ++word, putc ('.', to);
d2f0b724 542 p = word;
65e49ff1 543 if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
544 p += strlen (USER_LABEL_PREFIX);
d2f0b724 545
9c948bc2 546#ifdef HAVE_LD_DEMANGLE
547 result = 0;
548#else
d2f0b724 549 if (no_demangle)
550 result = 0;
551 else
c6d86b63 552 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
9c948bc2 553#endif
d2f0b724 554
555 if (result)
556 {
557 int diff;
d6b5203d 558 fputs (result, to);
d2f0b724 559
560 diff = strlen (word) - strlen (result);
402eb8ac 561 while (diff > 0 && c == ' ')
d6b5203d 562 --diff, putc (' ', to);
8698b7cf 563 if (diff < 0 && c == ' ')
564 {
565 while (diff < 0 && c == ' ')
566 ++diff, c = getc (stream);
567 if (!ISSPACE (c))
568 {
569 /* Make sure we output at least one space, or
570 the demangled symbol name will run into
571 whatever text follows. */
572 putc (' ', to);
573 }
574 }
d2f0b724 575
576 free (result);
577 }
578 else
d6b5203d 579 fputs (word, to);
d2f0b724 580
d6b5203d 581 fflush (to);
d2f0b724 582 obstack_free (&temporary_obstack, temporary_firstobj);
583 }
584 if (c == EOF)
585 break;
d6b5203d 586 putc (c, to);
d2f0b724 587 }
af4ae74b 588 fclose (stream);
d2f0b724 589}
590\f
efc8f8d6 591/* Return the kind of symbol denoted by name S. */
22f0924c 592
efc8f8d6 593static symkind
89a1f620 594is_ctor_dtor (const char *s)
22f0924c 595{
bc620c5c 596 struct names { const char *const name; const int len; symkind ret;
e99c3a1d 597 const int two_underscores; };
22f0924c 598
33b57a7b 599 const struct names *p;
19cb6b50 600 int ch;
601 const char *orig_s = s;
22f0924c 602
33b57a7b 603 static const struct names special[] = {
212c6484 604#ifndef NO_DOLLAR_IN_LABEL
efc8f8d6 605 { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, SYM_CTOR, 0 },
606 { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, SYM_DTOR, 0 },
212c6484 607#else
608#ifndef NO_DOT_IN_LABEL
efc8f8d6 609 { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, SYM_CTOR, 0 },
610 { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, SYM_DTOR, 0 },
212c6484 611#endif /* NO_DOT_IN_LABEL */
612#endif /* NO_DOLLAR_IN_LABEL */
efc8f8d6 613 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, SYM_CTOR, 0 },
614 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, SYM_DTOR, 0 },
615 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, SYM_DWEH, 0 },
616 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, SYM_INIT, 0 },
617 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, SYM_FINI, 0 },
618 { NULL, 0, SYM_REGULAR, 0 }
22f0924c 619 };
620
621 while ((ch = *s) == '_')
622 ++s;
623
624 if (s == orig_s)
efc8f8d6 625 return SYM_REGULAR;
22f0924c 626
627 for (p = &special[0]; p->len > 0; p++)
628 {
629 if (ch == p->name[0]
630 && (!p->two_underscores || ((s - orig_s) >= 2))
631 && strncmp(s, p->name, p->len) == 0)
632 {
633 return p->ret;
634 }
635 }
efc8f8d6 636 return SYM_REGULAR;
22f0924c 637}
e533c428 638\f
e533c428 639/* We maintain two prefix lists: one from COMPILER_PATH environment variable
640 and one from the PATH variable. */
641
642static struct path_prefix cpath, path;
643
29d774d0 644#ifdef CROSS_DIRECTORY_STRUCTURE
e533c428 645/* This is the name of the target machine. We use it to form the name
646 of the files to execute. */
647
e504db4a 648static const char *const target_machine = TARGET_MACHINE;
e533c428 649#endif
efba5f69 650
e533c428 651/* Search for NAME using prefix list PPREFIX. We only look for executable
89a1f620 652 files.
e533c428 653
a92771b8 654 Return 0 if not found, otherwise return its name, allocated with malloc. */
e533c428 655
656static char *
89a1f620 657find_a_file (struct path_prefix *pprefix, const char *name)
e533c428 658{
659 char *temp;
660 struct prefix_list *pl;
661 int len = pprefix->max_len + strlen (name) + 1;
662
e8d8647e 663 if (debug)
664 fprintf (stderr, "Looking for '%s'\n", name);
89a1f620 665
10f57222 666#ifdef HOST_EXECUTABLE_SUFFIX
667 len += strlen (HOST_EXECUTABLE_SUFFIX);
e533c428 668#endif
669
4c36ffe6 670 temp = XNEWVEC (char, len);
e533c428 671
672 /* Determine the filename to execute (special case for absolute paths). */
673
f3340cb8 674 if (IS_ABSOLUTE_PATH (name))
e533c428 675 {
d6d40f04 676 if (access (name, X_OK) == 0)
e533c428 677 {
678 strcpy (temp, name);
e8d8647e 679
680 if (debug)
681 fprintf (stderr, " - found: absolute path\n");
89a1f620 682
e533c428 683 return temp;
684 }
e8d8647e 685
10f57222 686#ifdef HOST_EXECUTABLE_SUFFIX
79b23a1e 687 /* Some systems have a suffix for executable files.
688 So try appending that. */
689 strcpy (temp, name);
10f57222 690 strcat (temp, HOST_EXECUTABLE_SUFFIX);
89a1f620 691
79b23a1e 692 if (access (temp, X_OK) == 0)
693 return temp;
694#endif
695
e8d8647e 696 if (debug)
697 fprintf (stderr, " - failed to locate using absolute path\n");
e533c428 698 }
699 else
700 for (pl = pprefix->plist; pl; pl = pl->next)
701 {
4d5a901b 702 struct stat st;
703
e533c428 704 strcpy (temp, pl->prefix);
705 strcat (temp, name);
89a1f620 706
4d5a901b 707 if (stat (temp, &st) >= 0
708 && ! S_ISDIR (st.st_mode)
709 && access (temp, X_OK) == 0)
0c787992 710 return temp;
e533c428 711
10f57222 712#ifdef HOST_EXECUTABLE_SUFFIX
e533c428 713 /* Some systems have a suffix for executable files.
714 So try appending that. */
10f57222 715 strcat (temp, HOST_EXECUTABLE_SUFFIX);
89a1f620 716
4d5a901b 717 if (stat (temp, &st) >= 0
718 && ! S_ISDIR (st.st_mode)
719 && access (temp, X_OK) == 0)
0c787992 720 return temp;
721#endif
e533c428 722 }
723
e8d8647e 724 if (debug && pprefix->plist == NULL)
725 fprintf (stderr, " - failed: no entries in prefix list\n");
726
e533c428 727 free (temp);
728 return 0;
729}
730
731/* Add an entry for PREFIX to prefix list PPREFIX. */
732
733static void
89a1f620 734add_prefix (struct path_prefix *pprefix, const char *prefix)
e533c428 735{
736 struct prefix_list *pl, **prev;
737 int len;
738
739 if (pprefix->plist)
740 {
741 for (pl = pprefix->plist; pl->next; pl = pl->next)
742 ;
743 prev = &pl->next;
744 }
745 else
746 prev = &pprefix->plist;
747
2358393e 748 /* Keep track of the longest prefix. */
e533c428 749
750 len = strlen (prefix);
751 if (len > pprefix->max_len)
752 pprefix->max_len = len;
753
4c36ffe6 754 pl = XNEW (struct prefix_list);
c96e0786 755 pl->prefix = xstrdup (prefix);
e533c428 756
757 if (*prev)
758 pl->next = *prev;
759 else
760 pl->next = (struct prefix_list *) 0;
761 *prev = pl;
762}
763\f
764/* Take the value of the environment variable ENV, break it into a path, and
765 add of the entries to PPREFIX. */
766
767static void
89a1f620 768prefix_from_env (const char *env, struct path_prefix *pprefix)
e533c428 769{
e504db4a 770 const char *p;
967958e4 771 p = getenv (env);
e533c428 772
773 if (p)
a9b00323 774 prefix_from_string (p, pprefix);
775}
e533c428 776
a9b00323 777static void
89a1f620 778prefix_from_string (const char *p, struct path_prefix *pprefix)
a9b00323 779{
e504db4a 780 const char *startp, *endp;
4c36ffe6 781 char *nstore = XNEWVEC (char, strlen (p) + 3);
a9b00323 782
e8d8647e 783 if (debug)
784 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
89a1f620 785
a9b00323 786 startp = endp = p;
787 while (1)
788 {
789 if (*endp == PATH_SEPARATOR || *endp == 0)
e533c428 790 {
a9b00323 791 strncpy (nstore, startp, endp-startp);
792 if (endp == startp)
e533c428 793 {
a9b00323 794 strcpy (nstore, "./");
795 }
01a88289 796 else if (! IS_DIR_SEPARATOR (endp[-1]))
a9b00323 797 {
01a88289 798 nstore[endp-startp] = DIR_SEPARATOR;
a9b00323 799 nstore[endp-startp+1] = 0;
e533c428 800 }
801 else
a9b00323 802 nstore[endp-startp] = 0;
803
e8d8647e 804 if (debug)
805 fprintf (stderr, " - add prefix: %s\n", nstore);
89a1f620 806
a9b00323 807 add_prefix (pprefix, nstore);
808 if (*endp == 0)
809 break;
810 endp = startp = endp + 1;
e533c428 811 }
a9b00323 812 else
813 endp++;
e533c428 814 }
5a30047c 815 free (nstore);
e533c428 816}
7bfefa9d 817
43ccfa36 818#ifdef OBJECT_FORMAT_NONE
819
7bfefa9d 820/* Add an entry for the object file NAME to object file list LIST.
821 New entries are added at the end of the list. The original pointer
822 value of NAME is preserved, i.e., no string copy is performed. */
823
824static void
825add_lto_object (struct lto_object_list *list, const char *name)
826{
827 struct lto_object *n = XNEW (struct lto_object);
828 n->name = name;
829 n->next = NULL;
830
831 if (list->last)
832 list->last->next = n;
833 else
834 list->first = n;
835
836 list->last = n;
837}
43ccfa36 838#endif /* OBJECT_FORMAT_NONE */
7bfefa9d 839
840
841/* Perform a link-time recompilation and relink if any of the object
842 files contain LTO info. The linker command line LTO_LD_ARGV
843 represents the linker command that would produce a final executable
844 without the use of LTO. OBJECT_LST is a vector of object file names
9d75589a 845 appearing in LTO_LD_ARGV that are to be considered for link-time
7bfefa9d 846 recompilation, where OBJECT is a pointer to the last valid element.
847 (This awkward convention avoids an impedance mismatch with the
848 usage of similarly-named variables in main().) The elements of
849 OBJECT_LST must be identical, i.e., pointer equal, to the
850 corresponding arguments in LTO_LD_ARGV.
851
852 Upon entry, at least one linker run has been performed without the
853 use of any LTO info that might be present. Any recompilations
854 necessary for template instantiations have been performed, and
855 initializer/finalizer tables have been created if needed and
856 included in the linker command line LTO_LD_ARGV. If any of the
857 object files contain LTO info, we run the LTO back end on all such
858 files, and perform the final link with the LTO back end output
859 substituted for the LTO-optimized files. In some cases, a final
860 link with all link-time generated code has already been performed,
861 so there is no need to relink if no LTO info is found. In other
862 cases, our caller has not produced the final executable, and is
863 relying on us to perform the required link whether LTO info is
864 present or not. In that case, the FORCE argument should be true.
865 Note that the linker command line argument LTO_LD_ARGV passed into
866 this function may be modified in place. */
867
868static void
869maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
870 const char **object, bool force)
871{
872 const char **object_file = CONST_CAST2 (const char **, char **, object_lst);
873
874 int num_lto_c_args = 1; /* Allow space for the terminating NULL. */
875
876 while (object_file < object)
877 {
878 /* If file contains LTO info, add it to the list of LTO objects. */
879 scan_prog_file (*object_file++, PASS_LTOINFO, SCAN_ALL);
880
881 /* Increment the argument count by the number of object file arguments
882 we will add. An upper bound suffices, so just count all of the
883 object files regardless of whether they contain LTO info. */
884 num_lto_c_args++;
885 }
886
887 if (lto_objects.first)
888 {
7bfefa9d 889 char **lto_c_argv;
890 const char **lto_c_ptr;
5121a10d 891 char **p;
892 char **lto_o_ptr;
7bfefa9d 893 struct lto_object *list;
894 char *lto_wrapper = getenv ("COLLECT_LTO_WRAPPER");
895 struct pex_obj *pex;
896 const char *prog = "lto-wrapper";
5121a10d 897 int lto_ld_argv_size = 0;
898 char **out_lto_ld_argv;
899 int out_lto_ld_argv_size;
900 size_t num_files;
7bfefa9d 901
902 if (!lto_wrapper)
11091b4d 903 fatal_error ("COLLECT_LTO_WRAPPER must be set");
7bfefa9d 904
c8c65e07 905 num_lto_c_args++;
906
7bfefa9d 907 /* There is at least one object file containing LTO info,
5121a10d 908 so we need to run the LTO back end and relink.
909
910 To do so we build updated ld arguments with first
911 LTO object replaced by all partitions and other LTO
912 objects removed. */
7bfefa9d 913
7bfefa9d 914 lto_c_argv = (char **) xcalloc (sizeof (char *), num_lto_c_args);
915 lto_c_ptr = CONST_CAST2 (const char **, char **, lto_c_argv);
916
917 *lto_c_ptr++ = lto_wrapper;
7bfefa9d 918
919 /* Add LTO objects to the wrapper command line. */
920 for (list = lto_objects.first; list; list = list->next)
921 *lto_c_ptr++ = list->name;
922
923 *lto_c_ptr = NULL;
924
7bfefa9d 925 /* Run the LTO back end. */
926 pex = collect_execute (prog, lto_c_argv, NULL, NULL, PEX_SEARCH);
927 {
928 int c;
929 FILE *stream;
5121a10d 930 size_t i;
7bfefa9d 931 char *start, *end;
932
933 stream = pex_read_output (pex, 0);
934 gcc_assert (stream);
935
936 num_files = 0;
937 while ((c = getc (stream)) != EOF)
938 {
939 obstack_1grow (&temporary_obstack, c);
940 if (c == '\n')
941 ++num_files;
942 }
943
944 lto_o_files = XNEWVEC (char *, num_files + 1);
945 lto_o_files[num_files] = NULL;
946 start = XOBFINISH (&temporary_obstack, char *);
947 for (i = 0; i < num_files; ++i)
948 {
949 end = start;
950 while (*end != '\n')
951 ++end;
952 *end = '\0';
953
954 lto_o_files[i] = xstrdup (start);
955
956 start = end + 1;
957 }
958
959 obstack_free (&temporary_obstack, temporary_firstobj);
960 }
961 do_wait (prog, pex);
962 pex = NULL;
963
5121a10d 964 /* Compute memory needed for new LD arguments. At most number of original arguemtns
965 plus number of partitions. */
966 for (lto_ld_argv_size = 0; lto_ld_argv[lto_ld_argv_size]; lto_ld_argv_size++)
967 ;
968 out_lto_ld_argv = XCNEWVEC(char *, num_files + lto_ld_argv_size + 1);
969 out_lto_ld_argv_size = 0;
970
7bfefa9d 971 /* After running the LTO back end, we will relink, substituting
972 the LTO output for the object files that we submitted to the
973 LTO. Here, we modify the linker command line for the relink. */
7bfefa9d 974
5121a10d 975 /* Copy all arguments until we find first LTO file. */
976 p = lto_ld_argv;
7bfefa9d 977 while (*p != NULL)
978 {
979 for (list = lto_objects.first; list; list = list->next)
5121a10d 980 if (*p == list->name) /* Note test for pointer equality! */
981 break;
982 if (list)
983 break;
984 out_lto_ld_argv[out_lto_ld_argv_size++] = *p++;
7bfefa9d 985 }
986
5121a10d 987 /* Now insert all LTO partitions. */
988 lto_o_ptr = lto_o_files;
989 while (*lto_o_ptr)
990 out_lto_ld_argv[out_lto_ld_argv_size++] = *lto_o_ptr++;
991
992 /* ... and copy the rest. */
993 while (*p != NULL)
994 {
995 for (list = lto_objects.first; list; list = list->next)
996 if (*p == list->name) /* Note test for pointer equality! */
997 break;
998 if (!list)
999 out_lto_ld_argv[out_lto_ld_argv_size++] = *p;
1000 p++;
1001 }
1002 out_lto_ld_argv[out_lto_ld_argv_size++] = 0;
7bfefa9d 1003
1004 /* Run the linker again, this time replacing the object files
1005 optimized by the LTO with the temporary file generated by the LTO. */
5121a10d 1006 fork_execute ("ld", out_lto_ld_argv);
3f5e90a3 1007 post_ld_pass (true);
5121a10d 1008 free (lto_ld_argv);
7bfefa9d 1009
1010 maybe_unlink_list (lto_o_files);
1011 }
1012 else if (force)
1013 {
1014 /* Our caller is relying on us to do the link
1015 even though there is no LTO back end work to be done. */
3f5e90a3 1016 fork_execute ("ld", lto_ld_argv);
1017 post_ld_pass (false);
7bfefa9d 1018 }
1019}
832f2315 1020\f
a92771b8 1021/* Main program. */
832f2315 1022
1023int
89a1f620 1024main (int argc, char **argv)
832f2315 1025{
0d95286f 1026 static const char *const ld_suffix = "ld";
61f41b94 1027 static const char *const plugin_ld_suffix = PLUGIN_LD_SUFFIX;
0d95286f 1028 static const char *const real_ld_suffix = "real-ld";
1029 static const char *const collect_ld_suffix = "collect-ld";
1030 static const char *const nm_suffix = "nm";
0d95286f 1031 static const char *const gnm_suffix = "gnm";
b7c87ff2 1032#ifdef LDD_SUFFIX
0d95286f 1033 static const char *const ldd_suffix = LDD_SUFFIX;
e504db4a 1034#endif
0d95286f 1035 static const char *const strip_suffix = "strip";
0d95286f 1036 static const char *const gstrip_suffix = "gstrip";
47950139 1037
29d774d0 1038#ifdef CROSS_DIRECTORY_STRUCTURE
47950139 1039 /* If we look for a program in the compiler directories, we just use
1040 the short name, since these directories are already system-specific.
1041 But it we look for a program in the system directories, we need to
1042 qualify the program name with the target machine. */
1043
1044 const char *const full_ld_suffix =
1045 concat(target_machine, "-", ld_suffix, NULL);
a93e9832 1046 const char *const full_plugin_ld_suffix =
1047 concat(target_machine, "-", plugin_ld_suffix, NULL);
47950139 1048 const char *const full_nm_suffix =
1049 concat (target_machine, "-", nm_suffix, NULL);
1050 const char *const full_gnm_suffix =
1051 concat (target_machine, "-", gnm_suffix, NULL);
1052#ifdef LDD_SUFFIX
1053 const char *const full_ldd_suffix =
1054 concat (target_machine, "-", ldd_suffix, NULL);
1055#endif
1056 const char *const full_strip_suffix =
1057 concat (target_machine, "-", strip_suffix, NULL);
1058 const char *const full_gstrip_suffix =
1059 concat (target_machine, "-", gstrip_suffix, NULL);
1060#else
1061 const char *const full_ld_suffix = ld_suffix;
a93e9832 1062 const char *const full_plugin_ld_suffix = plugin_ld_suffix;
47950139 1063 const char *const full_nm_suffix = nm_suffix;
1064 const char *const full_gnm_suffix = gnm_suffix;
1065#ifdef LDD_SUFFIX
1066 const char *const full_ldd_suffix = ldd_suffix;
1067#endif
1068 const char *const full_strip_suffix = strip_suffix;
1069 const char *const full_gstrip_suffix = gstrip_suffix;
29d774d0 1070#endif /* CROSS_DIRECTORY_STRUCTURE */
47950139 1071
e504db4a 1072 const char *arg;
d1058090 1073 FILE *outf;
1074#ifdef COLLECT_EXPORT_LIST
1075 FILE *exportf;
d1058090 1076#endif
e504db4a 1077 const char *ld_file_name;
1078 const char *p;
22f0924c 1079 char **c_argv;
e504db4a 1080 const char **c_ptr;
be2828ce 1081 char **ld1_argv;
e504db4a 1082 const char **ld1;
a93e9832 1083 bool use_plugin = false;
48e1416a 1084
912df756 1085 /* The kinds of symbols we will have to consider when scanning the
1086 outcome of a first pass link. This is ALL to start with, then might
1087 be adjusted before getting to the first pass link per se, typically on
1088 AIX where we perform an early scan of objects and libraries to fetch
1089 the list of global ctors/dtors and make sure they are not garbage
1090 collected. */
1091 scanfilter ld1_filter = SCAN_ALL;
1092
be2828ce 1093 char **ld2_argv;
e504db4a 1094 const char **ld2;
be2828ce 1095 char **object_lst;
e504db4a 1096 const char **object;
f22216ac 1097#ifdef TARGET_AIX_VERSION
a5e27f17 1098 int object_nbr = argc;
f22216ac 1099#endif
832f2315 1100 int first_file;
c159e0b7 1101 int num_c_args;
1102 char **old_argv;
1103
11091b4d 1104 p = argv[0] + strlen (argv[0]);
1105 while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
1106 --p;
1107 progname = p;
1108
1109 xmalloc_set_program_name (progname);
1110
c159e0b7 1111 old_argv = argv;
1112 expandargv (&argc, &argv);
1113 if (argv != old_argv)
1114 at_file_supplied = 1;
1115
3f5e90a3 1116 process_args (&argc, argv);
1117
c159e0b7 1118 num_c_args = argc + 9;
832f2315 1119
73caa9f3 1120#ifndef HAVE_LD_DEMANGLE
402eb8ac 1121 no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
1122
1123 /* Suppress demangling by the real linker, which may be broken. */
73caa9f3 1124 putenv (xstrdup ("COLLECT_NO_DEMANGLE=1"));
1125#endif
402eb8ac 1126
b6749968 1127#if defined (COLLECT2_HOST_INITIALIZATION)
dd5b4b36 1128 /* Perform system dependent initialization, if necessary. */
b6749968 1129 COLLECT2_HOST_INITIALIZATION;
3b774709 1130#endif
1131
6b917287 1132#ifdef SIGCHLD
1133 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
1134 receive the signal. A different setting is inheritable */
1135 signal (SIGCHLD, SIG_DFL);
1136#endif
1137
4367c81f 1138 /* Unlock the stdio streams. */
9c8f076b 1139 unlock_std_streams ();
4367c81f 1140
eb718689 1141 gcc_init_libintl ();
be2828ce 1142
11091b4d 1143 diagnostic_initialize (global_dc, 0);
1144
be2828ce 1145 /* Do not invoke xcalloc before this point, since locale needs to be
1146 set first, in case a diagnostic is issued. */
1147
402ba866 1148 ld1_argv = XCNEWVEC (char *, argc + 4);
1149 ld1 = CONST_CAST2 (const char **, char **, ld1_argv);
1150 ld2_argv = XCNEWVEC (char *, argc + 11);
1151 ld2 = CONST_CAST2 (const char **, char **, ld2_argv);
1152 object_lst = XCNEWVEC (char *, argc);
1153 object = CONST_CAST2 (const char **, char **, object_lst);
be2828ce 1154
832f2315 1155#ifdef DEBUG
1156 debug = 1;
832f2315 1157#endif
1158
e8d8647e 1159 /* Parse command line early for instances of -debug. This allows
1160 the debug flag to be set before functions like find_a_file()
cbcf2791 1161 are called. We also look for the -flto or -flto-partition=none flag to know
7bfefa9d 1162 what LTO mode we are in. */
e8d8647e 1163 {
1164 int i;
cbcf2791 1165 bool no_partition = false;
89a1f620 1166
e8d8647e 1167 for (i = 1; argv[i] != NULL; i ++)
ff2185fb 1168 {
1169 if (! strcmp (argv[i], "-debug"))
2bd5037b 1170 debug = true;
cbcf2791 1171 else if (! strcmp (argv[i], "-flto-partition=none"))
1172 no_partition = true;
1173 else if ((! strncmp (argv[i], "-flto=", 6)
1174 || ! strcmp (argv[i], "-flto")) && ! use_plugin)
6453a826 1175 lto_mode = LTO_MODE_WHOPR;
489113a1 1176 else if (!strncmp (argv[i], "-fno-lto", 8))
1177 lto_mode = LTO_MODE_NONE;
7bfefa9d 1178 else if (! strcmp (argv[i], "-plugin"))
1179 {
1180 use_plugin = true;
1181 lto_mode = LTO_MODE_NONE;
1182 }
06fb2419 1183#ifdef COLLECT_EXPORT_LIST
1184 /* since -brtl, -bexport, -b64 are not position dependent
1185 also check for them here */
1186 if ((argv[i][0] == '-') && (argv[i][1] == 'b'))
1187 {
1188 arg = argv[i];
1189 /* We want to disable automatic exports on AIX when user
1190 explicitly puts an export list in command line */
1191 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1192 export_flag = 1;
1193 else if (arg[2] == '6' && arg[3] == '4')
1194 aix64_flag = 1;
1195 else if (arg[2] == 'r' && arg[3] == 't' && arg[4] == 'l')
1196 aixrtl_flag = 1;
1197 }
1198#endif
ff2185fb 1199 }
e8d8647e 1200 vflag = debug;
bcac4551 1201 if (no_partition && lto_mode == LTO_MODE_WHOPR)
cbcf2791 1202 lto_mode = LTO_MODE_LTO;
e8d8647e 1203 }
1204
5258bbff 1205#ifndef DEFAULT_A_OUT_NAME
131353cd 1206 output_file = "a.out";
5258bbff 1207#else
1208 output_file = DEFAULT_A_OUT_NAME;
1209#endif
131353cd 1210
d2f0b724 1211 obstack_begin (&temporary_obstack, 0);
25a1c410 1212 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
aefe5019 1213
9c948bc2 1214#ifndef HAVE_LD_DEMANGLE
4d327eac 1215 current_demangling_style = auto_demangling;
9c948bc2 1216#endif
405711de 1217 p = getenv ("COLLECT_GCC_OPTIONS");
7802b788 1218 while (p && *p)
1219 {
e504db4a 1220 const char *q = extract_string (&p);
7802b788 1221 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1222 num_c_args++;
1223 }
1224 obstack_free (&temporary_obstack, temporary_firstobj);
6d6bf148 1225
cc4faf12 1226 /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
48e61da9 1227 -fno-exceptions -w -fno-whole-program */
1228 num_c_args += 6;
22f0924c 1229
402ba866 1230 c_argv = XCNEWVEC (char *, num_c_args);
1231 c_ptr = CONST_CAST2 (const char **, char **, c_argv);
22f0924c 1232
832f2315 1233 if (argc < 2)
11091b4d 1234 fatal_error ("no arguments");
832f2315 1235
3a0eb8c2 1236#ifdef SIGQUIT
003f6bf5 1237 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1238 signal (SIGQUIT, handler);
3a0eb8c2 1239#endif
003f6bf5 1240 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1241 signal (SIGINT, handler);
3a0eb8c2 1242#ifdef SIGALRM
003f6bf5 1243 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1244 signal (SIGALRM, handler);
3a0eb8c2 1245#endif
1246#ifdef SIGHUP
003f6bf5 1247 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1248 signal (SIGHUP, handler);
3a0eb8c2 1249#endif
003f6bf5 1250 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1251 signal (SIGSEGV, handler);
3a0eb8c2 1252#ifdef SIGBUS
003f6bf5 1253 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1254 signal (SIGBUS, handler);
3a0eb8c2 1255#endif
832f2315 1256
e533c428 1257 /* Extract COMPILER_PATH and PATH into our prefix list. */
1258 prefix_from_env ("COMPILER_PATH", &cpath);
1259 prefix_from_env ("PATH", &path);
832f2315 1260
e533c428 1261 /* Try to discover a valid linker/nm/strip to use. */
1262
6f73c4a6 1263 /* Maybe we know the right file to use (if not cross). */
84539f59 1264 ld_file_name = 0;
f07251bc 1265#ifdef DEFAULT_LINKER
1266 if (access (DEFAULT_LINKER, X_OK) == 0)
1267 ld_file_name = DEFAULT_LINKER;
1268 if (ld_file_name == 0)
1269#endif
6f73c4a6 1270#ifdef REAL_LD_FILE_NAME
1271 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1272 if (ld_file_name == 0)
1273#endif
d2f0b724 1274 /* Search the (target-specific) compiler dirs for ld'. */
1275 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1276 /* Likewise for `collect-ld'. */
e533c428 1277 if (ld_file_name == 0)
d2f0b724 1278 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
d8dc9bd6 1279 /* Search the compiler directories for `ld'. We have protection against
1280 recursive calls in find_a_file. */
2fd139da 1281 if (ld_file_name == 0)
a93e9832 1282 ld_file_name = find_a_file (&cpath,
1283 use_plugin
1284 ? plugin_ld_suffix
1285 : ld_suffix);
e533c428 1286 /* Search the ordinary system bin directories
f17a8f4e 1287 for `ld' (if native linking) or `TARGET-ld' (if cross). */
e533c428 1288 if (ld_file_name == 0)
a93e9832 1289 ld_file_name = find_a_file (&path,
1290 use_plugin
1291 ? full_plugin_ld_suffix
1292 : full_ld_suffix);
e533c428 1293
6f73c4a6 1294#ifdef REAL_NM_FILE_NAME
1295 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1296 if (nm_file_name == 0)
1297#endif
e533c428 1298 nm_file_name = find_a_file (&cpath, gnm_suffix);
1299 if (nm_file_name == 0)
1300 nm_file_name = find_a_file (&path, full_gnm_suffix);
1301 if (nm_file_name == 0)
1302 nm_file_name = find_a_file (&cpath, nm_suffix);
e533c428 1303 if (nm_file_name == 0)
1304 nm_file_name = find_a_file (&path, full_nm_suffix);
1305
b7c87ff2 1306#ifdef LDD_SUFFIX
1307 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1308 if (ldd_file_name == 0)
1309 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1310#endif
1311
6f73c4a6 1312#ifdef REAL_STRIP_FILE_NAME
1313 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1314 if (strip_file_name == 0)
1315#endif
e533c428 1316 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1317 if (strip_file_name == 0)
1318 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1319 if (strip_file_name == 0)
1320 strip_file_name = find_a_file (&cpath, strip_suffix);
e533c428 1321 if (strip_file_name == 0)
1322 strip_file_name = find_a_file (&path, full_strip_suffix);
832f2315 1323
8989da5d 1324 /* Determine the full path name of the C compiler to use. */
22f0924c 1325 c_file_name = getenv ("COLLECT_GCC");
e77396ba 1326 if (c_file_name == 0)
832f2315 1327 {
29d774d0 1328#ifdef CROSS_DIRECTORY_STRUCTURE
e504db4a 1329 c_file_name = concat (target_machine, "-gcc", NULL);
832f2315 1330#else
e533c428 1331 c_file_name = "gcc";
8989da5d 1332#endif
8989da5d 1333 }
1334
e533c428 1335 p = find_a_file (&cpath, c_file_name);
1336
1337 /* Here it should be safe to use the system search path since we should have
1338 already qualified the name of the compiler when it is needed. */
1339 if (p == 0)
1340 p = find_a_file (&path, c_file_name);
1341
1342 if (p)
1343 c_file_name = p;
832f2315 1344
f375f2ce 1345 *ld1++ = *ld2++ = ld_file_name;
832f2315 1346
a92771b8 1347 /* Make temp file names. */
e8b04076 1348 c_file = make_temp_file (".c");
1349 o_file = make_temp_file (".o");
d1058090 1350#ifdef COLLECT_EXPORT_LIST
e8b04076 1351 export_file = make_temp_file (".x");
d1058090 1352#endif
e8b04076 1353 ldout = make_temp_file (".ld");
d6b5203d 1354 lderrout = make_temp_file (".le");
22f0924c 1355 *c_ptr++ = c_file_name;
7e897ee0 1356 *c_ptr++ = "-x";
1357 *c_ptr++ = "c";
832f2315 1358 *c_ptr++ = "-c";
1359 *c_ptr++ = "-o";
1360 *c_ptr++ = o_file;
1361
d1058090 1362#ifdef COLLECT_EXPORT_LIST
1363 /* Generate a list of directories from LIBPATH. */
1364 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1365 /* Add to this list also two standard directories where
1366 AIX loader always searches for libraries. */
1367 add_prefix (&libpath_lib_dirs, "/lib");
1368 add_prefix (&libpath_lib_dirs, "/usr/lib");
1369#endif
1370
89a1f620 1371 /* Get any options that the upper GCC wants to pass to the sub-GCC.
d1058090 1372
1373 AIX support needs to know if -shared has been specified before
1374 parsing commandline arguments. */
1375
405711de 1376 p = getenv ("COLLECT_GCC_OPTIONS");
d1058090 1377 while (p && *p)
1378 {
e504db4a 1379 const char *q = extract_string (&p);
d1058090 1380 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
92192583 1381 *c_ptr++ = xstrdup (q);
35241897 1382 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
92192583 1383 *c_ptr++ = xstrdup (q);
625bfde6 1384 if (strcmp (q, "-shared") == 0)
d1058090 1385 shared_obj = 1;
d647a767 1386 if (*q == '-' && q[1] == 'B')
1387 {
92192583 1388 *c_ptr++ = xstrdup (q);
d647a767 1389 if (q[2] == 0)
1390 {
1391 q = extract_string (&p);
92192583 1392 *c_ptr++ = xstrdup (q);
d647a767 1393 }
1394 }
d1058090 1395 }
1396 obstack_free (&temporary_obstack, temporary_firstobj);
cc4faf12 1397 *c_ptr++ = "-fno-profile-arcs";
1398 *c_ptr++ = "-fno-test-coverage";
1399 *c_ptr++ = "-fno-branch-probabilities";
d1058090 1400 *c_ptr++ = "-fno-exceptions";
6d6bf148 1401 *c_ptr++ = "-w";
48e61da9 1402 *c_ptr++ = "-fno-whole-program";
d1058090 1403
22f0924c 1404 /* !!! When GCC calls collect2,
1405 it does not know whether it is calling collect2 or ld.
1406 So collect2 cannot meaningfully understand any options
1407 except those ld understands.
1408 If you propose to make GCC pass some other option,
1409 just imagine what will happen if ld is really ld!!! */
1410
a92771b8 1411 /* Parse arguments. Remember output file spec, pass the rest to ld. */
22f0924c 1412 /* After the first file, put in the c++ rt0. */
1413
832f2315 1414 first_file = 1;
a92771b8 1415 while ((arg = *++argv) != (char *) 0)
832f2315 1416 {
1417 *ld1++ = *ld2++ = arg;
1418
1419 if (arg[0] == '-')
f314c55f 1420 {
832f2315 1421 switch (arg[1])
1422 {
1423 case 'd':
1424 if (!strcmp (arg, "-debug"))
1425 {
e8d8647e 1426 /* Already parsed. */
832f2315 1427 ld1--;
1428 ld2--;
1429 }
0f7571bb 1430 if (!strcmp (arg, "-dynamic-linker") && argv[1])
a0c938f0 1431 {
0f7571bb 1432 ++argv;
1433 *ld1++ = *ld2++ = *argv;
1434 }
832f2315 1435 break;
1436
7bfefa9d 1437 case 'f':
cbcf2791 1438 if (strncmp (arg, "-flto", 5) == 0)
7bfefa9d 1439 {
1440#ifdef ENABLE_LTO
1441 /* Do not pass LTO flag to the linker. */
1442 ld1--;
1443 ld2--;
1444#else
1445 error ("LTO support has not been enabled in this "
1446 "configuration");
1447#endif
1448 }
a5e27f17 1449#ifdef TARGET_AIX_VERSION
1450 else
1451 {
1452 /* File containing a list of input files to process. */
1453
1454 FILE *stream;
1455 char buf[MAXPATHLEN + 2];
1456 /* Number of additionnal object files. */
1457 int add_nbr = 0;
1458 /* Maximum of additionnal object files before vector
1459 expansion. */
1460 int add_max = 0;
1461 const char *list_filename = arg + 2;
1462
1463 /* Accept -fFILENAME and -f FILENAME. */
1464 if (*list_filename == '\0' && argv[1])
1465 {
1466 ++argv;
1467 list_filename = *argv;
1468 *ld1++ = *ld2++ = *argv;
1469 }
1470
1471 stream = fopen (list_filename, "r");
1472 if (stream == NULL)
1473 fatal_error ("can't open %s: %m", list_filename);
1474
1475 while (fgets (buf, sizeof buf, stream) != NULL)
1476 {
1477 /* Remove end of line. */
1478 int len = strlen (buf);
1479 if (len >= 1 && buf[len - 1] =='\n')
1480 buf[len - 1] = '\0';
1481
1482 /* Put on object vector.
1483 Note: we only expanse vector here, so we must keep
1484 extra space for remaining arguments. */
1485 if (add_nbr >= add_max)
1486 {
e4e4eb40 1487 int pos =
1488 object - CONST_CAST2 (const char **, char **,
1489 object_lst);
a5e27f17 1490 add_max = (add_max == 0) ? 16 : add_max * 2;
1491 object_lst = XRESIZEVEC (char *, object_lst,
1492 object_nbr + add_max);
e4e4eb40 1493 object = CONST_CAST2 (const char **, char **,
1494 object_lst) + pos;
a5e27f17 1495 object_nbr += add_max;
1496 }
1497 *object++ = xstrdup (buf);
1498 add_nbr++;
1499 }
1500 fclose (stream);
1501 }
1502#endif
7bfefa9d 1503 break;
1504
b7c87ff2 1505 case 'l':
1506 if (first_file)
1507 {
1508 /* place o_file BEFORE this argument! */
1509 first_file = 0;
1510 ld2--;
1511 *ld2++ = o_file;
1512 *ld2++ = arg;
1513 }
d1058090 1514#ifdef COLLECT_EXPORT_LIST
1515 {
a0c938f0 1516 /* Resolving full library name. */
e504db4a 1517 const char *s = resolve_lib_name (arg+2);
d1058090 1518
d1058090 1519 /* Saving a full library name. */
1520 add_to_list (&libs, s);
1521 }
1522#endif
1523 break;
1524
1525#ifdef COLLECT_EXPORT_LIST
1526 /* Saving directories where to search for libraries. */
89a1f620 1527 case 'L':
d1058090 1528 add_prefix (&cmdline_lib_dirs, arg+2);
b7c87ff2 1529 break;
d1058090 1530#endif
b7c87ff2 1531
832f2315 1532 case 'o':
661ab6cf 1533 if (arg[2] == '\0')
1534 output_file = *ld1++ = *ld2++ = *++argv;
eb31cde6 1535 else
661ab6cf 1536 output_file = &arg[2];
832f2315 1537 break;
1538
1539 case 'r':
1540 if (arg[2] == '\0')
1541 rflag = 1;
1542 break;
1543
8989da5d 1544 case 's':
d2f0b724 1545 if (arg[2] == '\0' && do_collecting)
8989da5d 1546 {
1547 /* We must strip after the nm run, otherwise C++ linking
d1058090 1548 will not work. Thus we strip in the second ld run, or
8989da5d 1549 else with strip if there is no second ld run. */
1550 strip_flag = 1;
1551 ld1--;
1552 }
1553 break;
1554
832f2315 1555 case 'v':
1556 if (arg[2] == '\0')
2bd5037b 1557 vflag = true;
832f2315 1558 break;
5814fc8c 1559
1560 case '-':
1561 if (strcmp (arg, "--no-demangle") == 0)
1562 {
73caa9f3 1563#ifndef HAVE_LD_DEMANGLE
5814fc8c 1564 no_demangle = 1;
1565 ld1--;
1566 ld2--;
73caa9f3 1567#endif
5814fc8c 1568 }
1569 else if (strncmp (arg, "--demangle", 10) == 0)
1570 {
5814fc8c 1571#ifndef HAVE_LD_DEMANGLE
73caa9f3 1572 no_demangle = 0;
5814fc8c 1573 if (arg[10] == '=')
1574 {
1575 enum demangling_styles style
1576 = cplus_demangle_name_to_style (arg+11);
1577 if (style == unknown_demangling)
1578 error ("unknown demangling style '%s'", arg+11);
1579 else
1580 current_demangling_style = style;
1581 }
5814fc8c 1582 ld1--;
1583 ld2--;
73caa9f3 1584#endif
5814fc8c 1585 }
ef6fd54f 1586 else if (strncmp (arg, "--sysroot=", 10) == 0)
1587 target_system_root = arg + 10;
f0bf77c8 1588 else if (strcmp (arg, "--version") == 0)
2bd5037b 1589 vflag = true;
f0bf77c8 1590 else if (strcmp (arg, "--help") == 0)
2bd5037b 1591 helpflag = true;
5814fc8c 1592 break;
832f2315 1593 }
f314c55f 1594 }
78dbff7c 1595 else if ((p = strrchr (arg, '.')) != (char *) 0
d1058090 1596 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
c8b793cf 1597 || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1598 || strcmp (p, ".obj") == 0))
832f2315 1599 {
fc630b38 1600 if (first_file)
1601 {
1602 first_file = 0;
661ab6cf 1603 if (p[1] == 'o')
1604 *ld2++ = o_file;
1605 else
1606 {
1607 /* place o_file BEFORE this argument! */
1608 ld2--;
1609 *ld2++ = o_file;
1610 *ld2++ = arg;
1611 }
fc630b38 1612 }
0320a56b 1613 if (p[1] == 'o' || p[1] == 'l')
fc630b38 1614 *object++ = arg;
d1058090 1615#ifdef COLLECT_EXPORT_LIST
1616 /* libraries can be specified directly, i.e. without -l flag. */
89a1f620 1617 else
1618 {
d1058090 1619 /* Saving a full library name. */
a0c938f0 1620 add_to_list (&libs, arg);
1621 }
d1058090 1622#endif
832f2315 1623 }
1624 }
1625
d1058090 1626#ifdef COLLECT_EXPORT_LIST
1627 /* This is added only for debugging purposes. */
1628 if (debug)
7802b788 1629 {
d1058090 1630 fprintf (stderr, "List of libraries:\n");
1631 dump_list (stderr, "\t", libs.first);
7802b788 1632 }
22f0924c 1633
a9b00323 1634 /* The AIX linker will discard static constructors in object files if
912df756 1635 nothing else in the file is referenced, so look at them first. Unless
1636 we are building a shared object, ignore the eh frame tables, as we
1637 would otherwise reference them all, hence drag all the corresponding
1638 objects even if nothing else is referenced. */
d1058090 1639 {
48e1416a 1640 const char **export_object_lst
912df756 1641 = CONST_CAST2 (const char **, char **, object_lst);
48e1416a 1642
d1058090 1643 struct id *list = libs.first;
4e2fa0bf 1644
912df756 1645 /* Compute the filter to use from the current one, do scan, then adjust
1646 the "current" filter to remove what we just included here. This will
1647 control whether we need a first pass link later on or not, and what
1648 will remain to be scanned there. */
48e1416a 1649
1a9c54a3 1650 scanfilter this_filter = ld1_filter;
1651#if HAVE_AS_REF
1652 if (!shared_obj)
1653 this_filter &= ~SCAN_DWEH;
1654#endif
48e1416a 1655
912df756 1656 while (export_object_lst < object)
1657 scan_prog_file (*export_object_lst++, PASS_OBJ, this_filter);
48e1416a 1658
d1058090 1659 for (; list; list = list->next)
912df756 1660 scan_prog_file (list->name, PASS_FIRST, this_filter);
48e1416a 1661
912df756 1662 ld1_filter = ld1_filter & ~this_filter;
d1058090 1663 }
4e2fa0bf 1664
1665 if (exports.first)
1666 {
284a7b54 1667 char *buf = concat ("-bE:", export_file, NULL);
89a1f620 1668
4e2fa0bf 1669 *ld1++ = buf;
1670 *ld2++ = buf;
1671
1672 exportf = fopen (export_file, "w");
1673 if (exportf == (FILE *) 0)
11091b4d 1674 fatal_error ("fopen %s: %m", export_file);
4e2fa0bf 1675 write_aix_file (exportf, exports.first);
1676 if (fclose (exportf))
11091b4d 1677 fatal_error ("fclose %s: %m", export_file);
4e2fa0bf 1678 }
a9b00323 1679#endif
1680
832f2315 1681 *c_ptr++ = c_file;
e504db4a 1682 *c_ptr = *ld1 = *object = (char *) 0;
832f2315 1683
1684 if (vflag)
a19f368c 1685 notice ("collect2 version %s\n", version_string);
832f2315 1686
2bd5037b 1687 if (helpflag)
1688 {
ab723605 1689 printf ("Usage: collect2 [options]\n");
1690 printf (" Wrap linker and generate constructor code if needed.\n");
1691 printf (" Options:\n");
1692 printf (" -debug Enable debug output\n");
1693 printf (" --help Display this information\n");
1694 printf (" -v, --version Display this program's version number\n");
1695 printf ("\n");
1696 printf ("Overview: http://gcc.gnu.org/onlinedocs/gccint/Collect2.html\n");
1697 printf ("Report bugs: %s\n", bug_report_url);
1698 printf ("\n");
2bd5037b 1699 }
1700
832f2315 1701 if (debug)
1702 {
e504db4a 1703 const char *ptr;
2271b4f6 1704 fprintf (stderr, "ld_file_name = %s\n",
1705 (ld_file_name ? ld_file_name : "not found"));
1706 fprintf (stderr, "c_file_name = %s\n",
1707 (c_file_name ? c_file_name : "not found"));
1708 fprintf (stderr, "nm_file_name = %s\n",
1709 (nm_file_name ? nm_file_name : "not found"));
b7c87ff2 1710#ifdef LDD_SUFFIX
1711 fprintf (stderr, "ldd_file_name = %s\n",
1712 (ldd_file_name ? ldd_file_name : "not found"));
1713#endif
2271b4f6 1714 fprintf (stderr, "strip_file_name = %s\n",
1715 (strip_file_name ? strip_file_name : "not found"));
1716 fprintf (stderr, "c_file = %s\n",
1717 (c_file ? c_file : "not found"));
1718 fprintf (stderr, "o_file = %s\n",
1719 (o_file ? o_file : "not found"));
22f0924c 1720
1721 ptr = getenv ("COLLECT_GCC_OPTIONS");
1722 if (ptr)
1723 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1724
1725 ptr = getenv ("COLLECT_GCC");
1726 if (ptr)
1727 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1728
1729 ptr = getenv ("COMPILER_PATH");
1730 if (ptr)
1731 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1732
397f1574 1733 ptr = getenv (LIBRARY_PATH_ENV);
22f0924c 1734 if (ptr)
397f1574 1735 fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
22f0924c 1736
1737 fprintf (stderr, "\n");
832f2315 1738 }
1739
94ca3aab 1740 /* Load the program, searching all libraries and attempting to provide
912df756 1741 undefined symbols from repository information.
48e1416a 1742
912df756 1743 If -r or they will be run via some other method, do not build the
48e1416a 1744 constructor or destructor list, just return now. */
912df756 1745 {
1746 bool early_exit
1747 = rflag || (! DO_COLLECT_EXPORT_LIST && ! do_collecting);
1748
1749 /* Perform the first pass link now, if we're about to exit or if we need
1750 to scan for things we haven't collected yet before pursuing further.
1751
1752 On AIX, the latter typically includes nothing for shared objects or
1753 frame tables for an executable, out of what the required early scan on
1754 objects and libraries has performed above. In the !shared_obj case, we
1755 expect the relevant tables to be dragged together with their associated
1756 functions from precise cross reference insertions by the compiler. */
48e1416a 1757
912df756 1758 if (early_exit || ld1_filter != SCAN_NOTHING)
09d1782e 1759 do_tlink (ld1_argv, object_lst);
48e1416a 1760
912df756 1761 if (early_exit)
1762 {
1763#ifdef COLLECT_EXPORT_LIST
1764 /* Make sure we delete the export file we may have created. */
1765 if (export_file != 0 && export_file[0])
1766 maybe_unlink (export_file);
35363d84 1767#endif
23433d72 1768 if (lto_mode != LTO_MODE_NONE)
7bfefa9d 1769 maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
3f5e90a3 1770 else
1771 post_ld_pass (false);
7bfefa9d 1772
912df756 1773 maybe_unlink (c_file);
1774 maybe_unlink (o_file);
1775 return 0;
1776 }
1777 }
832f2315 1778
912df756 1779 /* Unless we have done it all already, examine the namelist and search for
1780 static constructors and destructors to call. Write the constructor and
1781 destructor tables to a .s file and reload. */
d2f0b724 1782
912df756 1783 if (ld1_filter != SCAN_NOTHING)
1784 scan_prog_file (output_file, PASS_FIRST, ld1_filter);
832f2315 1785
b7c87ff2 1786#ifdef SCAN_LIBRARIES
1787 scan_libraries (output_file);
1788#endif
1789
832f2315 1790 if (debug)
1791 {
70da6ffe 1792 notice_translated (ngettext ("%d constructor found\n",
1793 "%d constructors found\n",
1794 constructors.number),
1795 constructors.number);
1796 notice_translated (ngettext ("%d destructor found\n",
1797 "%d destructors found\n",
1798 destructors.number),
1799 destructors.number);
1800 notice_translated (ngettext("%d frame table found\n",
1801 "%d frame tables found\n",
1802 frame_tables.number),
1803 frame_tables.number);
832f2315 1804 }
1805
912df756 1806 /* If the scan exposed nothing of special interest, there's no need to
1807 generate the glue code and relink so return now. */
1808
b7c87ff2 1809 if (constructors.number == 0 && destructors.number == 0
d757b8c9 1810 && frame_tables.number == 0
d1058090 1811#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
b7c87ff2 1812 /* If we will be running these functions ourselves, we want to emit
d1058090 1813 stubs into the shared library so that we do not have to relink
b7c87ff2 1814 dependent programs when we add static objects. */
1815 && ! shared_obj
1816#endif
1817 )
8989da5d 1818 {
912df756 1819 /* Do tlink without additional code generation now if we didn't
1820 do it earlier for scanning purposes. */
1821 if (ld1_filter == SCAN_NOTHING)
1822 do_tlink (ld1_argv, object_lst);
1823
7bfefa9d 1824 if (lto_mode)
1825 maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
1826
8989da5d 1827 /* Strip now if it was requested on the command line. */
1828 if (strip_flag)
1829 {
4c36ffe6 1830 char **real_strip_argv = XCNEWVEC (char *, 3);
402ba866 1831 const char ** strip_argv = CONST_CAST2 (const char **, char **,
1832 real_strip_argv);
89a1f620 1833
f9a00e58 1834 strip_argv[0] = strip_file_name;
131353cd 1835 strip_argv[1] = output_file;
8989da5d 1836 strip_argv[2] = (char *) 0;
e504db4a 1837 fork_execute ("strip", real_strip_argv);
8989da5d 1838 }
46a1b049 1839
1840#ifdef COLLECT_EXPORT_LIST
1841 maybe_unlink (export_file);
1842#endif
3f5e90a3 1843 post_ld_pass (false);
1844
1526a87c 1845 maybe_unlink (c_file);
1846 maybe_unlink (o_file);
8989da5d 1847 return 0;
1848 }
832f2315 1849
2c0e001b 1850 /* Sort ctor and dtor lists by priority. */
9bc65db1 1851 sort_ids (&constructors);
1852 sort_ids (&destructors);
1853
1611b3e1 1854 maybe_unlink(output_file);
832f2315 1855 outf = fopen (c_file, "w");
a92771b8 1856 if (outf == (FILE *) 0)
11091b4d 1857 fatal_error ("fopen %s: %m", c_file);
832f2315 1858
1859 write_c_file (outf, c_file);
1860
1861 if (fclose (outf))
11091b4d 1862 fatal_error ("fclose %s: %m", c_file);
832f2315 1863
661ab6cf 1864 /* Tell the linker that we have initializer and finalizer functions. */
1865#ifdef LD_INIT_SWITCH
a737f54e 1866#ifdef COLLECT_EXPORT_LIST
284a7b54 1867 *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
a737f54e 1868#else
661ab6cf 1869 *ld2++ = LD_INIT_SWITCH;
1870 *ld2++ = initname;
1871 *ld2++ = LD_FINI_SWITCH;
1872 *ld2++ = fininame;
1873#endif
a737f54e 1874#endif
661ab6cf 1875
a9b00323 1876#ifdef COLLECT_EXPORT_LIST
1877 if (shared_obj)
1878 {
4e2fa0bf 1879 /* If we did not add export flag to link arguments before, add it to
1880 second link phase now. No new exports should have been added. */
1881 if (! exports.first)
284a7b54 1882 *ld2++ = concat ("-bE:", export_file, NULL);
4e2fa0bf 1883
d3cef9f8 1884#ifndef LD_INIT_SWITCH
a9b00323 1885 add_to_list (&exports, initname);
1886 add_to_list (&exports, fininame);
661ab6cf 1887 add_to_list (&exports, "_GLOBAL__DI");
1888 add_to_list (&exports, "_GLOBAL__DD");
d3cef9f8 1889#endif
a9b00323 1890 exportf = fopen (export_file, "w");
a92771b8 1891 if (exportf == (FILE *) 0)
11091b4d 1892 fatal_error ("fopen %s: %m", export_file);
4e2fa0bf 1893 write_aix_file (exportf, exports.first);
a9b00323 1894 if (fclose (exportf))
11091b4d 1895 fatal_error ("fclose %s: %m", export_file);
a9b00323 1896 }
1897#endif
1898
4e2fa0bf 1899 /* End of arguments to second link phase. */
1900 *ld2 = (char*) 0;
1901
832f2315 1902 if (debug)
1903 {
131353cd 1904 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1905 output_file, c_file);
832f2315 1906 write_c_file (stderr, "stderr");
1907 fprintf (stderr, "========== end of c_file\n\n");
a9b00323 1908#ifdef COLLECT_EXPORT_LIST
1909 fprintf (stderr, "\n========== export_file = %s\n", export_file);
4e2fa0bf 1910 write_aix_file (stderr, exports.first);
a9b00323 1911 fprintf (stderr, "========== end of export_file\n\n");
1912#endif
832f2315 1913 }
1914
1915 /* Assemble the constructor and destructor tables.
a92771b8 1916 Link the tables in with the rest of the program. */
832f2315 1917
f9a00e58 1918 fork_execute ("gcc", c_argv);
d1058090 1919#ifdef COLLECT_EXPORT_LIST
8b332087 1920 /* On AIX we must call tlink because of possible templates resolution. */
d1058090 1921 do_tlink (ld2_argv, object_lst);
7bfefa9d 1922
1923 if (lto_mode)
1924 maybe_run_lto_and_relink (ld2_argv, object_lst, object, false);
d1058090 1925#else
8b332087 1926 /* Otherwise, simply call ld because tlink is already done. */
7bfefa9d 1927 if (lto_mode)
1928 maybe_run_lto_and_relink (ld2_argv, object_lst, object, true);
1929 else
3f5e90a3 1930 {
1931 fork_execute ("ld", ld2_argv);
1932 post_ld_pass (false);
1933 }
832f2315 1934
1935 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1936 constructors/destructors in shared libraries. */
912df756 1937 scan_prog_file (output_file, PASS_SECOND, SCAN_ALL);
89a1f620 1938#endif
832f2315 1939
1940 maybe_unlink (c_file);
1941 maybe_unlink (o_file);
d1058090 1942
1943#ifdef COLLECT_EXPORT_LIST
a9b00323 1944 maybe_unlink (export_file);
d1058090 1945#endif
1946
832f2315 1947 return 0;
1948}
1949
1950\f
d10cfa8d 1951/* Wait for a process to finish, and exit if a nonzero status is found. */
832f2315 1952
d2f0b724 1953int
6e24b140 1954collect_wait (const char *prog, struct pex_obj *pex)
832f2315 1955{
1956 int status;
1957
6e24b140 1958 if (!pex_get_status (pex, 1, &status))
11091b4d 1959 fatal_error ("can't get program status: %m");
6e24b140 1960 pex_free (pex);
1961
832f2315 1962 if (status)
1963 {
b7826aae 1964 if (WIFSIGNALED (status))
832f2315 1965 {
b7826aae 1966 int sig = WTERMSIG (status);
e4ba8ded 1967 error ("%s terminated with signal %d [%s]%s",
1968 prog, sig, strsignal(sig),
5519412f 1969 WCOREDUMP(status) ? ", core dumped" : "");
5fcf1827 1970 collect_exit (FATAL_EXIT_CODE);
832f2315 1971 }
1972
b7826aae 1973 if (WIFEXITED (status))
d2f0b724 1974 return WEXITSTATUS (status);
1975 }
1976 return 0;
1977}
1978
1979static void
6e24b140 1980do_wait (const char *prog, struct pex_obj *pex)
d2f0b724 1981{
6e24b140 1982 int ret = collect_wait (prog, pex);
d2f0b724 1983 if (ret != 0)
1984 {
1985 error ("%s returned %d exit status", prog, ret);
1986 collect_exit (ret);
832f2315 1987 }
c159e0b7 1988
1989 if (response_file)
1990 {
1991 unlink (response_file);
1992 response_file = NULL;
1993 }
832f2315 1994}
1995
1996\f
3b774709 1997/* Execute a program, and wait for the reply. */
832f2315 1998
6e24b140 1999struct pex_obj *
d6b5203d 2000collect_execute (const char *prog, char **argv, const char *outname,
7bfefa9d 2001 const char *errname, int flags)
832f2315 2002{
6e24b140 2003 struct pex_obj *pex;
2004 const char *errmsg;
2005 int err;
c159e0b7 2006 char *response_arg = NULL;
2007 char *response_argv[3] ATTRIBUTE_UNUSED;
2008
2009 if (HAVE_GNU_LD && at_file_supplied && argv[0] != NULL)
2010 {
2011 /* If using @file arguments, create a temporary file and put the
2012 contents of argv into it. Then change argv to an array corresponding
2013 to a single argument @FILE, where FILE is the temporary filename. */
2014
2015 char **current_argv = argv + 1;
2016 char *argv0 = argv[0];
2017 int status;
2018 FILE *f;
2019
2020 /* Note: we assume argv contains at least one element; this is
2021 checked above. */
2022
2023 response_file = make_temp_file ("");
2024
2025 f = fopen (response_file, "w");
2026
2027 if (f == NULL)
11091b4d 2028 fatal_error ("could not open response file %s", response_file);
c159e0b7 2029
2030 status = writeargv (current_argv, f);
2031
2032 if (status)
11091b4d 2033 fatal_error ("could not write to response file %s", response_file);
c159e0b7 2034
2035 status = fclose (f);
2036
2037 if (EOF == status)
11091b4d 2038 fatal_error ("could not close response file %s", response_file);
c159e0b7 2039
2040 response_arg = concat ("@", response_file, NULL);
2041 response_argv[0] = argv0;
2042 response_argv[1] = response_arg;
2043 response_argv[2] = NULL;
2044
2045 argv = response_argv;
2046 }
832f2315 2047
2048 if (vflag || debug)
2049 {
2050 char **p_argv;
e504db4a 2051 const char *str;
832f2315 2052
f9a00e58 2053 if (argv[0])
2054 fprintf (stderr, "%s", argv[0]);
e533c428 2055 else
be2828ce 2056 notice ("[cannot find %s]", prog);
e533c428 2057
a92771b8 2058 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
832f2315 2059 fprintf (stderr, " %s", str);
2060
2061 fprintf (stderr, "\n");
2062 }
2063
2064 fflush (stdout);
2065 fflush (stderr);
2066
d1058090 2067 /* If we cannot find a program we need, complain error. Do this here
2068 since we might not end up needing something that we could not find. */
e533c428 2069
f9a00e58 2070 if (argv[0] == 0)
11091b4d 2071 fatal_error ("cannot find '%s'", prog);
e533c428 2072
6e24b140 2073 pex = pex_init (0, "collect2", NULL);
2074 if (pex == NULL)
11091b4d 2075 fatal_error ("pex_init failed: %m");
3b774709 2076
7bfefa9d 2077 errmsg = pex_run (pex, flags, argv[0], argv, outname,
d6b5203d 2078 errname, &err);
6e24b140 2079 if (errmsg != NULL)
832f2315 2080 {
6e24b140 2081 if (err != 0)
2082 {
2083 errno = err;
11091b4d 2084 fatal_error ("%s: %m", _(errmsg));
6e24b140 2085 }
2086 else
11091b4d 2087 fatal_error (errmsg);
832f2315 2088 }
3b774709 2089
dd045aee 2090 free (response_arg);
c159e0b7 2091
6e24b140 2092 return pex;
d2f0b724 2093}
832f2315 2094
d2f0b724 2095static void
89a1f620 2096fork_execute (const char *prog, char **argv)
d2f0b724 2097{
6e24b140 2098 struct pex_obj *pex;
2099
7bfefa9d 2100 pex = collect_execute (prog, argv, NULL, NULL, PEX_LAST | PEX_SEARCH);
6e24b140 2101 do_wait (prog, pex);
832f2315 2102}
832f2315 2103\f
2b98e22b 2104/* Unlink FILE unless we are debugging or this is the output_file
2105 and we may not unlink it. */
832f2315 2106
2107static void
89a1f620 2108maybe_unlink (const char *file)
832f2315 2109{
2b98e22b 2110 if (debug)
2111 {
2112 notice ("[Leaving %s]\n", file);
2113 return;
2114 }
2115
2116 if (file == output_file && !may_unlink_output_file)
2117 return;
2118
2119 unlink_if_ordinary (file);
832f2315 2120}
2121
7bfefa9d 2122/* Call maybe_unlink on the NULL-terminated list, FILE_LIST. */
2123
2124static void
2125maybe_unlink_list (char **file_list)
2126{
2127 char **tmp = file_list;
2128
2129 while (*tmp)
2130 maybe_unlink (*(tmp++));
2131}
2132
832f2315 2133\f
9bc65db1 2134static long sequence_number = 0;
2135
832f2315 2136/* Add a name to a linked list. */
2137
2138static void
89a1f620 2139add_to_list (struct head *head_ptr, const char *name)
832f2315 2140{
25a1c410 2141 struct id *newid
2142 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
b821b836 2143 struct id *p;
832f2315 2144 strcpy (newid->name, name);
2145
2146 if (head_ptr->first)
2147 head_ptr->last->next = newid;
2148 else
2149 head_ptr->first = newid;
2150
b821b836 2151 /* Check for duplicate symbols. */
2152 for (p = head_ptr->first;
2153 strcmp (name, p->name) != 0;
2154 p = p->next)
2155 ;
2156 if (p != newid)
2157 {
2158 head_ptr->last->next = 0;
2159 free (newid);
2160 return;
2161 }
2162
2163 newid->sequence = ++sequence_number;
832f2315 2164 head_ptr->last = newid;
2165 head_ptr->number++;
2166}
2167
9bc65db1 2168/* Grab the init priority number from an init function name that
2169 looks like "_GLOBAL_.I.12345.foo". */
2170
2171static int
89a1f620 2172extract_init_priority (const char *name)
9bc65db1 2173{
69988048 2174 int pos = 0, pri;
9bc65db1 2175
2176 while (name[pos] == '_')
2177 ++pos;
2178 pos += 10; /* strlen ("GLOBAL__X_") */
2179
2c0e001b 2180 /* Extract init_p number from ctor/dtor name. */
69988048 2181 pri = atoi (name + pos);
2182 return pri ? pri : DEFAULT_INIT_PRIORITY;
9bc65db1 2183}
2184
2185/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
2186 ctors will be run from right to left, dtors from left to right. */
2187
2188static void
89a1f620 2189sort_ids (struct head *head_ptr)
9bc65db1 2190{
2191 /* id holds the current element to insert. id_next holds the next
2192 element to insert. id_ptr iterates through the already sorted elements
2193 looking for the place to insert id. */
2194 struct id *id, *id_next, **id_ptr;
9bc65db1 2195
2196 id = head_ptr->first;
2197
2198 /* We don't have any sorted elements yet. */
2199 head_ptr->first = NULL;
2200
2201 for (; id; id = id_next)
2202 {
2203 id_next = id->next;
2204 id->sequence = extract_init_priority (id->name);
2205
2206 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
2207 if (*id_ptr == NULL
2208 /* If the sequence numbers are the same, we put the id from the
2209 file later on the command line later in the list. */
2210 || id->sequence > (*id_ptr)->sequence
2211 /* Hack: do lexical compare, too.
2212 || (id->sequence == (*id_ptr)->sequence
a0c938f0 2213 && strcmp (id->name, (*id_ptr)->name) > 0) */
9bc65db1 2214 )
2215 {
2216 id->next = *id_ptr;
2217 *id_ptr = id;
2218 break;
2219 }
2220 }
2221
2222 /* Now set the sequence numbers properly so write_c_file works. */
2223 for (id = head_ptr->first; id; id = id->next)
2224 id->sequence = ++sequence_number;
2225}
2226
832f2315 2227/* Write: `prefix', the names on list LIST, `suffix'. */
2228
2229static void
89a1f620 2230write_list (FILE *stream, const char *prefix, struct id *list)
832f2315 2231{
2232 while (list)
2233 {
2234 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
2235 list = list->next;
2236 }
2237}
2238
82dc74ff 2239#ifdef COLLECT_EXPORT_LIST
d1058090 2240/* This function is really used only on AIX, but may be useful. */
0c87a39e 2241#if 0
d1058090 2242static int
89a1f620 2243is_in_list (const char *prefix, struct id *list)
d1058090 2244{
2245 while (list)
2246 {
2247 if (!strcmp (prefix, list->name)) return 1;
2248 list = list->next;
2249 }
2250 return 0;
2251}
82dc74ff 2252#endif
0c87a39e 2253#endif /* COLLECT_EXPORT_LIST */
d1058090 2254
2255/* Added for debugging purpose. */
0e93a6ac 2256#ifdef COLLECT_EXPORT_LIST
d1058090 2257static void
89a1f620 2258dump_list (FILE *stream, const char *prefix, struct id *list)
d1058090 2259{
2260 while (list)
2261 {
2262 fprintf (stream, "%s%s,\n", prefix, list->name);
2263 list = list->next;
2264 }
2265}
0e93a6ac 2266#endif
d1058090 2267
0e93a6ac 2268#if 0
d1058090 2269static void
89a1f620 2270dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
d1058090 2271{
2272 while (list)
2273 {
2274 fprintf (stream, "%s%s,\n", prefix, list->prefix);
2275 list = list->next;
2276 }
2277}
0e93a6ac 2278#endif
d1058090 2279
832f2315 2280static void
89a1f620 2281write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
832f2315 2282{
2283 while (list)
2284 {
6dd50474 2285 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
832f2315 2286 prefix, list->sequence, list->name);
2287 list = list->next;
2288 }
2289}
2290
b7c87ff2 2291/* Write out the constructor and destructor tables statically (for a shared
2292 object), along with the functions to execute them. */
2293
2294static void
89a1f620 2295write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
b7c87ff2 2296{
e504db4a 2297 const char *p, *q;
2298 char *prefix, *r;
d757b8c9 2299 int frames = (frame_tables.number > 0);
b7c87ff2 2300
2301 /* Figure out name of output_file, stripping off .so version. */
82715bcd 2302 q = p = lbasename (output_file);
2303
b7c87ff2 2304 while (q)
2305 {
78dbff7c 2306 q = strchr (q,'.');
b7c87ff2 2307 if (q == 0)
2308 {
2309 q = p + strlen (p);
2310 break;
2311 }
2312 else
2313 {
82715bcd 2314 if (filename_ncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0)
b7c87ff2 2315 {
1ba3a590 2316 q += strlen (SHLIB_SUFFIX);
b7c87ff2 2317 break;
2318 }
2319 else
2320 q++;
2321 }
2322 }
2323 /* q points to null at end of the string (or . of the .so version) */
4c36ffe6 2324 prefix = XNEWVEC (char, q - p + 1);
b7c87ff2 2325 strncpy (prefix, p, q - p);
2326 prefix[q - p] = 0;
e504db4a 2327 for (r = prefix; *r; r++)
2328 if (!ISALNUM ((unsigned char)*r))
2329 *r = '_';
b7c87ff2 2330 if (debug)
be2828ce 2331 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
2332 output_file, prefix);
b7c87ff2 2333
284a7b54 2334 initname = concat ("_GLOBAL__FI_", prefix, NULL);
2335 fininame = concat ("_GLOBAL__FD_", prefix, NULL);
b7c87ff2 2336
2337 free (prefix);
2338
2358393e 2339 /* Write the tables as C code. */
b7c87ff2 2340
2341 fprintf (stream, "static int count;\n");
2342 fprintf (stream, "typedef void entry_pt();\n");
2343 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
d757b8c9 2344
2345 if (frames)
2346 {
2347 write_list_with_asm (stream, "extern void *", frame_tables.first);
2348
2349 fprintf (stream, "\tstatic void *frame_table[] = {\n");
2350 write_list (stream, "\t\t&", frame_tables.first);
2351 fprintf (stream, "\t0\n};\n");
2352
ad87de1e 2353 /* This must match what's in frame.h. */
2354 fprintf (stream, "struct object {\n");
2355 fprintf (stream, " void *pc_begin;\n");
2356 fprintf (stream, " void *pc_end;\n");
2357 fprintf (stream, " void *fde_begin;\n");
2358 fprintf (stream, " void *fde_array;\n");
68b88e86 2359 fprintf (stream, " __SIZE_TYPE__ count;\n");
ad87de1e 2360 fprintf (stream, " struct object *next;\n");
2361 fprintf (stream, "};\n");
2362
c4fa4c4d 2363 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
cd236c08 2364 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
d757b8c9 2365
2366 fprintf (stream, "static void reg_frame () {\n");
ad87de1e 2367 fprintf (stream, "\tstatic struct object ob;\n");
c4fa4c4d 2368 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
d757b8c9 2369 fprintf (stream, "\t}\n");
2370
2371 fprintf (stream, "static void dereg_frame () {\n");
c4fa4c4d 2372 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
d757b8c9 2373 fprintf (stream, "\t}\n");
2374 }
2375
b7c87ff2 2376 fprintf (stream, "void %s() {\n", initname);
d757b8c9 2377 if (constructors.number > 0 || frames)
b7c87ff2 2378 {
2379 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
2380 write_list (stream, "\t\t", constructors.first);
d757b8c9 2381 if (frames)
2382 fprintf (stream, "\treg_frame,\n");
b7c87ff2 2383 fprintf (stream, "\t};\n");
2384 fprintf (stream, "\tentry_pt **p;\n");
2385 fprintf (stream, "\tif (count++ != 0) return;\n");
d757b8c9 2386 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
b7c87ff2 2387 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
2388 }
661ab6cf 2389 else
2390 fprintf (stream, "\t++count;\n");
b7c87ff2 2391 fprintf (stream, "}\n");
2392 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2393 fprintf (stream, "void %s() {\n", fininame);
d757b8c9 2394 if (destructors.number > 0 || frames)
b7c87ff2 2395 {
2396 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
2397 write_list (stream, "\t\t", destructors.first);
d757b8c9 2398 if (frames)
2399 fprintf (stream, "\tdereg_frame,\n");
b7c87ff2 2400 fprintf (stream, "\t};\n");
2401 fprintf (stream, "\tentry_pt **p;\n");
2402 fprintf (stream, "\tif (--count != 0) return;\n");
2403 fprintf (stream, "\tp = dtors;\n");
2404 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
d757b8c9 2405 destructors.number + frames);
b7c87ff2 2406 }
2407 fprintf (stream, "}\n");
2408
661ab6cf 2409 if (shared_obj)
2410 {
2f9e77d1 2411 COLLECT_SHARED_INIT_FUNC(stream, initname);
2412 COLLECT_SHARED_FINI_FUNC(stream, fininame);
661ab6cf 2413 }
b7c87ff2 2414}
2415
a92771b8 2416/* Write the constructor/destructor tables. */
832f2315 2417
73439ee0 2418#ifndef LD_INIT_SWITCH
832f2315 2419static void
89a1f620 2420write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
832f2315 2421{
2358393e 2422 /* Write the tables as C code. */
832f2315 2423
d757b8c9 2424 int frames = (frame_tables.number > 0);
2425
832f2315 2426 fprintf (stream, "typedef void entry_pt();\n\n");
89a1f620 2427
77a5425a 2428 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
d757b8c9 2429
2430 if (frames)
2431 {
2432 write_list_with_asm (stream, "extern void *", frame_tables.first);
2433
2434 fprintf (stream, "\tstatic void *frame_table[] = {\n");
2435 write_list (stream, "\t\t&", frame_tables.first);
2436 fprintf (stream, "\t0\n};\n");
2437
285cf8b8 2438 /* This must match what's in frame.h. */
2439 fprintf (stream, "struct object {\n");
2440 fprintf (stream, " void *pc_begin;\n");
2441 fprintf (stream, " void *pc_end;\n");
2442 fprintf (stream, " void *fde_begin;\n");
2443 fprintf (stream, " void *fde_array;\n");
2444 fprintf (stream, " __SIZE_TYPE__ count;\n");
2445 fprintf (stream, " struct object *next;\n");
2446 fprintf (stream, "};\n");
2447
c4fa4c4d 2448 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
cd236c08 2449 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
d757b8c9 2450
2451 fprintf (stream, "static void reg_frame () {\n");
285cf8b8 2452 fprintf (stream, "\tstatic struct object ob;\n");
c4fa4c4d 2453 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
d757b8c9 2454 fprintf (stream, "\t}\n");
2455
2456 fprintf (stream, "static void dereg_frame () {\n");
c4fa4c4d 2457 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
d757b8c9 2458 fprintf (stream, "\t}\n");
2459 }
2460
832f2315 2461 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
d757b8c9 2462 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
22f0924c 2463 write_list (stream, "\t", constructors.first);
d757b8c9 2464 if (frames)
2465 fprintf (stream, "\treg_frame,\n");
832f2315 2466 fprintf (stream, "\t0\n};\n\n");
2467
77a5425a 2468 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
832f2315 2469
2470 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
d757b8c9 2471 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
22f0924c 2472 write_list (stream, "\t", destructors.first);
d757b8c9 2473 if (frames)
2474 fprintf (stream, "\tdereg_frame,\n");
832f2315 2475 fprintf (stream, "\t0\n};\n\n");
2476
b0b9762f 2477 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2478 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
832f2315 2479}
73439ee0 2480#endif /* ! LD_INIT_SWITCH */
832f2315 2481
b7c87ff2 2482static void
89a1f620 2483write_c_file (FILE *stream, const char *name)
b7c87ff2 2484{
661ab6cf 2485#ifndef LD_INIT_SWITCH
2486 if (! shared_obj)
b7c87ff2 2487 write_c_file_glob (stream, name);
661ab6cf 2488 else
2489#endif
2490 write_c_file_stat (stream, name);
b7c87ff2 2491}
a9b00323 2492
d1058090 2493#ifdef COLLECT_EXPORT_LIST
a9b00323 2494static void
89a1f620 2495write_aix_file (FILE *stream, struct id *list)
d1058090 2496{
d1058090 2497 for (; list; list = list->next)
4e2fa0bf 2498 {
2499 fputs (list->name, stream);
2500 putc ('\n', stream);
2501 }
d1058090 2502}
2503#endif
832f2315 2504\f
22f0924c 2505#ifdef OBJECT_FORMAT_NONE
832f2315 2506
23433d72 2507/* Check to make sure the file is an LTO object file. */
7bfefa9d 2508
2509static bool
23433d72 2510maybe_lto_object_file (const char *prog_name)
7bfefa9d 2511{
2512 FILE *f;
23433d72 2513 unsigned char buf[4];
2514 int i;
2515
2516 static unsigned char elfmagic[4] = { 0x7f, 'E', 'L', 'F' };
2517 static unsigned char coffmagic[2] = { 0x4c, 0x01 };
85880558 2518 static unsigned char coffmagic_x64[2] = { 0x64, 0x86 };
23433d72 2519 static unsigned char machomagic[4][4] = {
2520 { 0xcf, 0xfa, 0xed, 0xfe },
2521 { 0xce, 0xfa, 0xed, 0xfe },
2522 { 0xfe, 0xed, 0xfa, 0xcf },
2523 { 0xfe, 0xed, 0xfa, 0xce }
2524 };
7bfefa9d 2525
4d992eb6 2526 f = fopen (prog_name, "rb");
7bfefa9d 2527 if (f == NULL)
2528 return false;
2529 if (fread (buf, sizeof (buf), 1, f) != 1)
2530 buf[0] = 0;
2531 fclose (f);
23433d72 2532
2533 if (memcmp (buf, elfmagic, sizeof (elfmagic)) == 0
85880558 2534 || memcmp (buf, coffmagic, sizeof (coffmagic)) == 0
2535 || memcmp (buf, coffmagic_x64, sizeof (coffmagic_x64)) == 0)
23433d72 2536 return true;
2537 for (i = 0; i < 4; i++)
2538 if (memcmp (buf, machomagic[i], sizeof (machomagic[i])) == 0)
2539 return true;
2540
2541 return false;
7bfefa9d 2542}
2543
22f0924c 2544/* Generic version to scan the name list of the loaded program for
912df756 2545 the symbols g++ uses for static constructors and destructors. */
832f2315 2546
2547static void
912df756 2548scan_prog_file (const char *prog_name, scanpass which_pass,
2549 scanfilter filter)
832f2315 2550{
89a1f620 2551 void (*int_handler) (int);
6e24b140 2552#ifdef SIGQUIT
89a1f620 2553 void (*quit_handler) (int);
6e24b140 2554#endif
e504db4a 2555 char *real_nm_argv[4];
402ba866 2556 const char **nm_argv = CONST_CAST2 (const char **, char**, real_nm_argv);
832f2315 2557 int argc = 0;
6e24b140 2558 struct pex_obj *pex;
2559 const char *errmsg;
2560 int err;
832f2315 2561 char *p, buf[1024];
2562 FILE *inf;
7bfefa9d 2563 int found_lto = 0;
832f2315 2564
b7c87ff2 2565 if (which_pass == PASS_SECOND)
832f2315 2566 return;
2567
4d992eb6 2568 /* LTO objects must be in a known format. This check prevents
7bfefa9d 2569 us from accepting an archive containing LTO objects, which
9d75589a 2570 gcc cannot currently handle. */
23433d72 2571 if (which_pass == PASS_LTOINFO && !maybe_lto_object_file (prog_name))
7bfefa9d 2572 return;
2573
d1058090 2574 /* If we do not have an `nm', complain. */
e533c428 2575 if (nm_file_name == 0)
11091b4d 2576 fatal_error ("cannot find 'nm'");
e533c428 2577
b7c87ff2 2578 nm_argv[argc++] = nm_file_name;
832f2315 2579 if (NM_FLAGS[0] != '\0')
22f0924c 2580 nm_argv[argc++] = NM_FLAGS;
832f2315 2581
22f0924c 2582 nm_argv[argc++] = prog_name;
a92771b8 2583 nm_argv[argc++] = (char *) 0;
832f2315 2584
832f2315 2585 /* Trace if needed. */
2586 if (vflag)
2587 {
e504db4a 2588 const char **p_argv;
2589 const char *str;
832f2315 2590
a92771b8 2591 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
832f2315 2592 fprintf (stderr, " %s", str);
2593
2594 fprintf (stderr, "\n");
2595 }
2596
2597 fflush (stdout);
2598 fflush (stderr);
2599
6e24b140 2600 pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2601 if (pex == NULL)
11091b4d 2602 fatal_error ("pex_init failed: %m");
832f2315 2603
7bfefa9d 2604 errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, HOST_BIT_BUCKET,
2605 &err);
6e24b140 2606 if (errmsg != NULL)
832f2315 2607 {
6e24b140 2608 if (err != 0)
2609 {
2610 errno = err;
11091b4d 2611 fatal_error ("%s: %m", _(errmsg));
6e24b140 2612 }
2613 else
11091b4d 2614 fatal_error (errmsg);
832f2315 2615 }
2616
89a1f620 2617 int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
3a0eb8c2 2618#ifdef SIGQUIT
89a1f620 2619 quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
3a0eb8c2 2620#endif
832f2315 2621
6e24b140 2622 inf = pex_read_output (pex, 0);
2623 if (inf == NULL)
11091b4d 2624 fatal_error ("can't open nm output: %m");
832f2315 2625
2626 if (debug)
7bfefa9d 2627 {
2628 if (which_pass == PASS_LTOINFO)
2629 fprintf (stderr, "\nnm output with LTO info marker symbol.\n");
2630 else
2631 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2632 }
832f2315 2633
2634 /* Read each line of nm output. */
a92771b8 2635 while (fgets (buf, sizeof buf, inf) != (char *) 0)
832f2315 2636 {
2637 int ch, ch2;
22f0924c 2638 char *name, *end;
832f2315 2639
7bfefa9d 2640 if (debug)
2641 fprintf (stderr, "\t%s\n", buf);
2642
2643 if (which_pass == PASS_LTOINFO)
2644 {
2645 if (found_lto)
2646 continue;
2647
2648 /* Look for the LTO info marker symbol, and add filename to
2649 the LTO objects list if found. */
2650 for (p = buf; (ch = *p) != '\0' && ch != '\n'; p++)
4d992eb6 2651 if (ch == ' ' && p[1] == '_' && p[2] == '_'
2652 && (strncmp (p + (p[3] == '_' ? 2 : 1), "__gnu_lto_v1", 12) == 0)
2653 && ISSPACE (p[p[3] == '_' ? 14 : 13]))
7bfefa9d 2654 {
2655 add_lto_object (&lto_objects, prog_name);
2656
2657 /* We need to read all the input, so we can't just
2658 return here. But we can avoid useless work. */
2659 found_lto = 1;
2660
2661 break;
2662 }
2663
2664 continue;
2665 }
2666
832f2315 2667 /* If it contains a constructor or destructor name, add the name
912df756 2668 to the appropriate list unless this is a kind of symbol we're
2669 not supposed to even consider. */
832f2315 2670
2671 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
b7c87ff2 2672 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2673 break;
832f2315 2674
b7c87ff2 2675 if (ch != '_')
832f2315 2676 continue;
89a1f620 2677
22f0924c 2678 name = p;
2679 /* Find the end of the symbol name.
d1058090 2680 Do not include `|', because Encore nm can tack that on the end. */
cc404a47 2681 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
22f0924c 2682 end++)
2683 continue;
832f2315 2684
6f73c4a6 2685
832f2315 2686 *end = '\0';
22f0924c 2687 switch (is_ctor_dtor (name))
832f2315 2688 {
efc8f8d6 2689 case SYM_CTOR:
912df756 2690 if (! (filter & SCAN_CTOR))
2691 break;
b7c87ff2 2692 if (which_pass != PASS_LIB)
2693 add_to_list (&constructors, name);
22f0924c 2694 break;
832f2315 2695
efc8f8d6 2696 case SYM_DTOR:
912df756 2697 if (! (filter & SCAN_DTOR))
2698 break;
b7c87ff2 2699 if (which_pass != PASS_LIB)
2700 add_to_list (&destructors, name);
2701 break;
2702
efc8f8d6 2703 case SYM_INIT:
912df756 2704 if (! (filter & SCAN_INIT))
2705 break;
b7c87ff2 2706 if (which_pass != PASS_LIB)
11091b4d 2707 fatal_error ("init function found in object %s", prog_name);
c45f936d 2708#ifndef LD_INIT_SWITCH
b7c87ff2 2709 add_to_list (&constructors, name);
c45f936d 2710#endif
b7c87ff2 2711 break;
2712
efc8f8d6 2713 case SYM_FINI:
912df756 2714 if (! (filter & SCAN_FINI))
2715 break;
b7c87ff2 2716 if (which_pass != PASS_LIB)
11091b4d 2717 fatal_error ("fini function found in object %s", prog_name);
c45f936d 2718#ifndef LD_FINI_SWITCH
22f0924c 2719 add_to_list (&destructors, name);
c45f936d 2720#endif
22f0924c 2721 break;
832f2315 2722
efc8f8d6 2723 case SYM_DWEH:
912df756 2724 if (! (filter & SCAN_DWEH))
2725 break;
d757b8c9 2726 if (which_pass != PASS_LIB)
2727 add_to_list (&frame_tables, name);
c3393573 2728 break;
d757b8c9 2729
22f0924c 2730 default: /* not a constructor or destructor */
2731 continue;
832f2315 2732 }
832f2315 2733 }
2734
2735 if (debug)
2736 fprintf (stderr, "\n");
2737
6e24b140 2738 do_wait (nm_file_name, pex);
832f2315 2739
2740 signal (SIGINT, int_handler);
3a0eb8c2 2741#ifdef SIGQUIT
832f2315 2742 signal (SIGQUIT, quit_handler);
3a0eb8c2 2743#endif
832f2315 2744}
2745
b7c87ff2 2746#ifdef LDD_SUFFIX
2747
2748/* Use the List Dynamic Dependencies program to find shared libraries that
2749 the output file depends upon and their initialization/finalization
2750 routines, if any. */
2751
89a1f620 2752static void
2753scan_libraries (const char *prog_name)
b7c87ff2 2754{
2755 static struct head libraries; /* list of shared libraries found */
2756 struct id *list;
89a1f620 2757 void (*int_handler) (int);
6e24b140 2758#ifdef SIGQUIT
89a1f620 2759 void (*quit_handler) (int);
6e24b140 2760#endif
ba40f012 2761 char *real_ldd_argv[4];
ecf52e84 2762 const char **ldd_argv = CONST_CAST2 (const char **, char **, real_ldd_argv);
b7c87ff2 2763 int argc = 0;
6e24b140 2764 struct pex_obj *pex;
2765 const char *errmsg;
2766 int err;
b7c87ff2 2767 char buf[1024];
2768 FILE *inf;
2769
d1058090 2770 /* If we do not have an `ldd', complain. */
b7c87ff2 2771 if (ldd_file_name == 0)
2772 {
1e5fcbe2 2773 error ("cannot find 'ldd'");
b7c87ff2 2774 return;
2775 }
2776
2777 ldd_argv[argc++] = ldd_file_name;
2778 ldd_argv[argc++] = prog_name;
2779 ldd_argv[argc++] = (char *) 0;
2780
b7c87ff2 2781 /* Trace if needed. */
2782 if (vflag)
2783 {
e504db4a 2784 const char **p_argv;
2785 const char *str;
b7c87ff2 2786
2787 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2788 fprintf (stderr, " %s", str);
2789
2790 fprintf (stderr, "\n");
2791 }
2792
2793 fflush (stdout);
2794 fflush (stderr);
2795
6e24b140 2796 pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2797 if (pex == NULL)
11091b4d 2798 fatal_error ("pex_init failed: %m");
b7c87ff2 2799
6e24b140 2800 errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err);
2801 if (errmsg != NULL)
b7c87ff2 2802 {
6e24b140 2803 if (err != 0)
2804 {
2805 errno = err;
11091b4d 2806 fatal_error ("%s: %m", _(errmsg));
6e24b140 2807 }
2808 else
11091b4d 2809 fatal_error (errmsg);
b7c87ff2 2810 }
2811
5b6b3be8 2812 int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
b7c87ff2 2813#ifdef SIGQUIT
5b6b3be8 2814 quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
b7c87ff2 2815#endif
2816
6e24b140 2817 inf = pex_read_output (pex, 0);
2818 if (inf == NULL)
11091b4d 2819 fatal_error ("can't open ldd output: %m");
b7c87ff2 2820
2821 if (debug)
be2828ce 2822 notice ("\nldd output with constructors/destructors.\n");
b7c87ff2 2823
2824 /* Read each line of ldd output. */
2825 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2826 {
0f2b564d 2827 int ch2;
b7c87ff2 2828 char *name, *end, *p = buf;
2829
a92771b8 2830 /* Extract names of libraries and add to list. */
b7c87ff2 2831 PARSE_LDD_OUTPUT (p);
2832 if (p == 0)
2833 continue;
2834
2835 name = p;
2836 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
11091b4d 2837 fatal_error ("dynamic dependency %s not found", buf);
b7c87ff2 2838
a92771b8 2839 /* Find the end of the symbol name. */
89a1f620 2840 for (end = p;
cc404a47 2841 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
b7c87ff2 2842 end++)
2843 continue;
2844 *end = '\0';
2845
2846 if (access (name, R_OK) == 0)
a0c938f0 2847 add_to_list (&libraries, name);
b7c87ff2 2848 else
11091b4d 2849 fatal_error ("unable to open dynamic dependency '%s'", buf);
b7c87ff2 2850
2851 if (debug)
2852 fprintf (stderr, "\t%s\n", buf);
2853 }
2854 if (debug)
2855 fprintf (stderr, "\n");
2856
6e24b140 2857 do_wait (ldd_file_name, pex);
b7c87ff2 2858
2859 signal (SIGINT, int_handler);
2860#ifdef SIGQUIT
2861 signal (SIGQUIT, quit_handler);
2862#endif
2863
21dda4ee 2864 /* Now iterate through the library list adding their symbols to
b7c87ff2 2865 the list. */
2866 for (list = libraries.first; list; list = list->next)
18d8a00d 2867 scan_prog_file (list->name, PASS_LIB, SCAN_ALL);
b7c87ff2 2868}
2869
2870#endif /* LDD_SUFFIX */
b7c87ff2 2871
22f0924c 2872#endif /* OBJECT_FORMAT_NONE */
2873
2874\f
2875/*
2876 * COFF specific stuff.
2877 */
2878
2879#ifdef OBJECT_FORMAT_COFF
2880
8ddac116 2881#if defined (EXTENDED_COFF)
c8b793cf 2882
77a5425a 2883# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2884# define GCC_SYMENT SYMR
c3393573 2885# define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
77a5425a 2886# define GCC_SYMINC(X) (1)
2887# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2888# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
c8b793cf 2889
22f0924c 2890#else
c8b793cf 2891
77a5425a 2892# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2893# define GCC_SYMENT SYMENT
8ddac116 2894# if defined (C_WEAKEXT)
2895# define GCC_OK_SYMBOL(X) \
2896 (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
a0c938f0 2897 ((X).n_scnum > N_UNDEF) && \
2898 (aix64_flag \
2899 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2900 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
8ddac116 2901# define GCC_UNDEF_SYMBOL(X) \
2902 (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
a0c938f0 2903 ((X).n_scnum == N_UNDEF))
8ddac116 2904# else
2905# define GCC_OK_SYMBOL(X) \
2906 (((X).n_sclass == C_EXT) && \
a0c938f0 2907 ((X).n_scnum > N_UNDEF) && \
2908 (aix64_flag \
2909 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2910 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
8ddac116 2911# define GCC_UNDEF_SYMBOL(X) \
2912 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2913# endif
77a5425a 2914# define GCC_SYMINC(X) ((X).n_numaux+1)
2915# define GCC_SYMZERO(X) 0
c8b793cf 2916
2917/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
cabc7147 2918#if TARGET_AIX_VERSION >= 51
c8b793cf 2919# define GCC_CHECK_HDR(X) \
2920 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2921 || (HEADER (X).f_magic == 0767 && aix64_flag))
2922#else
9ae139a2 2923# define GCC_CHECK_HDR(X) \
2924 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2925 || (HEADER (X).f_magic == 0757 && aix64_flag))
22f0924c 2926#endif
2927
c8b793cf 2928#endif
2929
805e22b2 2930#ifdef COLLECT_EXPORT_LIST
2931/* Array of standard AIX libraries which should not
2932 be scanned for ctors/dtors. */
2933static const char *const aix_std_libs[] = {
2934 "/unix",
2935 "/lib/libc.a",
2936 "/lib/libm.a",
2937 "/lib/libc_r.a",
2938 "/lib/libm_r.a",
2939 "/usr/lib/libc.a",
2940 "/usr/lib/libm.a",
2941 "/usr/lib/libc_r.a",
2942 "/usr/lib/libm_r.a",
2943 "/usr/lib/threads/libc.a",
2944 "/usr/ccs/lib/libc.a",
2945 "/usr/ccs/lib/libm.a",
2946 "/usr/ccs/lib/libc_r.a",
2947 "/usr/ccs/lib/libm_r.a",
2948 NULL
2949};
2950
2951/* This function checks the filename and returns 1
2952 if this name matches the location of a standard AIX library. */
89a1f620 2953static int ignore_library (const char *);
805e22b2 2954static int
89a1f620 2955ignore_library (const char *name)
805e22b2 2956{
329cbab5 2957 const char *const *p;
ef6fd54f 2958 size_t length;
329cbab5 2959
ef6fd54f 2960 if (target_system_root[0] != '\0')
2961 {
2962 length = strlen (target_system_root);
2963 if (strncmp (name, target_system_root, length) != 0)
2964 return 0;
2965 name += length;
2966 }
329cbab5 2967 for (p = &aix_std_libs[0]; *p != NULL; ++p)
2968 if (strcmp (name, *p) == 0)
2969 return 1;
805e22b2 2970 return 0;
2971}
2972#endif /* COLLECT_EXPORT_LIST */
2973
31a83412 2974#if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
89a1f620 2975extern char *ldgetname (LDFILE *, GCC_SYMENT *);
31a83412 2976#endif
22f0924c 2977
2978/* COFF version to scan the name list of the loaded program for
912df756 2979 the symbols g++ uses for static constructors and destructors. */
22f0924c 2980
2981static void
912df756 2982scan_prog_file (const char *prog_name, scanpass which_pass,
2983 scanfilter filter)
22f0924c 2984{
f64f3678 2985 LDFILE *ldptr = NULL;
22f0924c 2986 int sym_index, sym_count;
d1058090 2987 int is_shared = 0;
22f0924c 2988
a9b00323 2989 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
22f0924c 2990 return;
2991
d1058090 2992#ifdef COLLECT_EXPORT_LIST
2993 /* We do not need scanning for some standard C libraries. */
2994 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2995 return;
22f0924c 2996
d1058090 2997 /* On AIX we have a loop, because there is not much difference
2998 between an object and an archive. This trick allows us to
2999 eliminate scan_libraries() function. */
3000 do
22f0924c 3001 {
d1058090 3002#endif
e504db4a 3003 /* Some platforms (e.g. OSF4) declare ldopen as taking a
a0c938f0 3004 non-const char * filename parameter, even though it will not
3005 modify that string. So we must cast away const-ness here,
888fe6b2 3006 using CONST_CAST to prevent complaints from -Wcast-qual. */
3007 if ((ldptr = ldopen (CONST_CAST (char *, prog_name), ldptr)) != NULL)
77a5425a 3008 {
9ae139a2 3009 if (! MY_ISCOFF (HEADER (ldptr).f_magic))
11091b4d 3010 fatal_error ("%s: not a COFF file", prog_name);
22f0924c 3011
d1058090 3012 if (GCC_CHECK_HDR (ldptr))
77a5425a 3013 {
d1058090 3014 sym_count = GCC_SYMBOLS (ldptr);
3015 sym_index = GCC_SYMZERO (ldptr);
9ae139a2 3016
3017#ifdef COLLECT_EXPORT_LIST
3018 /* Is current archive member a shared object? */
3019 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
3020#endif
3021
d1058090 3022 while (sym_index < sym_count)
3023 {
3024 GCC_SYMENT symbol;
3025
3026 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
3027 break;
3028 sym_index += GCC_SYMINC (symbol);
3029
3030 if (GCC_OK_SYMBOL (symbol))
3031 {
3032 char *name;
22f0924c 3033
d1058090 3034 if ((name = ldgetname (ldptr, &symbol)) == NULL)
21dda4ee 3035 continue; /* Should never happen. */
22f0924c 3036
a9b00323 3037#ifdef XCOFF_DEBUGGING_INFO
d1058090 3038 /* All AIX function names have a duplicate entry
3039 beginning with a dot. */
3040 if (*name == '.')
3041 ++name;
22f0924c 3042#endif
3043
d1058090 3044 switch (is_ctor_dtor (name))
3045 {
efc8f8d6 3046 case SYM_CTOR:
912df756 3047 if (! (filter & SCAN_CTOR))
3048 break;
a737f54e 3049 if (! is_shared)
3050 add_to_list (&constructors, name);
d3cef9f8 3051#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
d1058090 3052 if (which_pass == PASS_OBJ)
3053 add_to_list (&exports, name);
d1058090 3054#endif
3055 break;
3056
efc8f8d6 3057 case SYM_DTOR:
912df756 3058 if (! (filter & SCAN_DTOR))
3059 break;
a737f54e 3060 if (! is_shared)
3061 add_to_list (&destructors, name);
d3cef9f8 3062#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
d1058090 3063 if (which_pass == PASS_OBJ)
3064 add_to_list (&exports, name);
d1058090 3065#endif
3066 break;
3067
3068#ifdef COLLECT_EXPORT_LIST
efc8f8d6 3069 case SYM_INIT:
912df756 3070 if (! (filter & SCAN_INIT))
3071 break;
a737f54e 3072#ifndef LD_INIT_SWITCH
d1058090 3073 if (is_shared)
3074 add_to_list (&constructors, name);
a737f54e 3075#endif
d1058090 3076 break;
3077
efc8f8d6 3078 case SYM_FINI:
912df756 3079 if (! (filter & SCAN_FINI))
3080 break;
a737f54e 3081#ifndef LD_INIT_SWITCH
d1058090 3082 if (is_shared)
3083 add_to_list (&destructors, name);
a737f54e 3084#endif
d1058090 3085 break;
3086#endif
3087
efc8f8d6 3088 case SYM_DWEH:
912df756 3089 if (! (filter & SCAN_DWEH))
3090 break;
c3393573 3091 if (! is_shared)
3092 add_to_list (&frame_tables, name);
d3cef9f8 3093#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
d14933cf 3094 if (which_pass == PASS_OBJ)
3095 add_to_list (&exports, name);
d14933cf 3096#endif
c3393573 3097 break;
3098
d1058090 3099 default: /* not a constructor or destructor */
3100#ifdef COLLECT_EXPORT_LIST
d3cef9f8 3101 /* Explicitly export all global symbols when
3102 building a shared object on AIX, but do not
3103 re-export symbols from another shared object
3104 and do not export symbols if the user
3105 provides an explicit export list. */
3106 if (shared_obj && !is_shared
3107 && which_pass == PASS_OBJ && !export_flag)
3108 add_to_list (&exports, name);
d1058090 3109#endif
3110 continue;
3111 }
22f0924c 3112
d1058090 3113 if (debug)
a737f54e 3114#if !defined(EXTENDED_COFF)
d1058090 3115 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
3116 symbol.n_scnum, symbol.n_sclass,
3117 (symbol.n_type ? "0" : ""), symbol.n_type,
3118 name);
22f0924c 3119#else
d1058090 3120 fprintf (stderr,
ad6c9a58 3121 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
3122 symbol.iss, (long) symbol.value, symbol.index, name);
d1058090 3123#endif
3124 }
d1058090 3125 }
77a5425a 3126 }
9ae139a2 3127#ifdef COLLECT_EXPORT_LIST
3128 else
3129 {
3130 /* If archive contains both 32-bit and 64-bit objects,
3131 we want to skip objects in other mode so mismatch normal. */
3132 if (debug)
3133 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
3134 prog_name, HEADER (ldptr).f_magic, aix64_flag);
3135 }
3136#endif
22f0924c 3137 }
d1058090 3138 else
3139 {
11091b4d 3140 fatal_error ("%s: cannot open as COFF file", prog_name);
d1058090 3141 }
3142#ifdef COLLECT_EXPORT_LIST
3143 /* On AIX loop continues while there are more members in archive. */
22f0924c 3144 }
d1058090 3145 while (ldclose (ldptr) == FAILURE);
3146#else
3147 /* Otherwise we simply close ldptr. */
22f0924c 3148 (void) ldclose(ldptr);
d1058090 3149#endif
22f0924c 3150}
02159c3f 3151#endif /* OBJECT_FORMAT_COFF */
97d49287 3152
d1058090 3153#ifdef COLLECT_EXPORT_LIST
d1058090 3154/* Given a library name without "lib" prefix, this function
3155 returns a full library name including a path. */
3156static char *
89a1f620 3157resolve_lib_name (const char *name)
d1058090 3158{
3159 char *lib_buf;
3160 int i, j, l = 0;
07090bac 3161 /* Library extensions for AIX dynamic linking. */
3162 const char * const libexts[2] = {"a", "so"};
f2156a9c 3163
d1058090 3164 for (i = 0; libpaths[i]; i++)
3165 if (libpaths[i]->max_len > l)
3166 l = libpaths[i]->max_len;
3167
225ab426 3168 lib_buf = XNEWVEC (char, l + strlen(name) + 10);
d1058090 3169
3170 for (i = 0; libpaths[i]; i++)
3171 {
3172 struct prefix_list *list = libpaths[i]->plist;
3173 for (; list; list = list->next)
3174 {
ba21f363 3175 /* The following lines are needed because path_prefix list
82715bcd 3176 may contain directories both with trailing DIR_SEPARATOR and
ba21f363 3177 without it. */
3178 const char *p = "";
82715bcd 3179 if (!IS_DIR_SEPARATOR (list->prefix[strlen(list->prefix)-1]))
ba21f363 3180 p = "/";
07090bac 3181 for (j = 0; j < 2; j++)
97d49287 3182 {
89a1f620 3183 sprintf (lib_buf, "%s%slib%s.%s",
07090bac 3184 list->prefix, p, name,
3185 libexts[(j + aixrtl_flag) % 2]);
3186 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
d1058090 3187 if (file_exists (lib_buf))
97d49287 3188 {
07090bac 3189 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
d1058090 3190 return (lib_buf);
97d49287 3191 }
97d49287 3192 }
97d49287 3193 }
3194 }
d1058090 3195 if (debug)
3196 fprintf (stderr, "not found\n");
3197 else
11091b4d 3198 fatal_error ("library lib%s not found", name);
d1058090 3199 return (NULL);
3200}
02159c3f 3201#endif /* COLLECT_EXPORT_LIST */
3f5e90a3 3202
3203#ifdef COLLECT_RUN_DSYMUTIL
3204static int flag_dsym = false;
3205static int flag_idsym = false;
3206
3207static void
3208process_args (int *argcp, char **argv) {
3209 int i, j;
3210 int argc = *argcp;
3211 for (i=0; i<argc; ++i)
3212 {
3213 if (strcmp (argv[i], "-dsym") == 0)
3214 {
3215 flag_dsym = true;
3216 /* Remove the flag, as we handle all processing for it. */
3217 j = i;
3218 do
3219 argv[j] = argv[j+1];
3220 while (++j < argc);
3221 --i;
3222 argc = --(*argcp);
3223 }
3224 else if (strcmp (argv[i], "-idsym") == 0)
3225 {
3226 flag_idsym = true;
3227 /* Remove the flag, as we handle all processing for it. */
3228 j = i;
3229 do
3230 argv[j] = argv[j+1];
3231 while (++j < argc);
3232 --i;
3233 argc = --(*argcp);
3234 }
3235 }
3236}
3237
3238static void
3239do_dsymutil (const char *output_file) {
3240 const char *dsymutil = DSYMUTIL + 1;
3241 struct pex_obj *pex;
3242 char **real_argv = XCNEWVEC (char *, 3);
3243 const char ** argv = CONST_CAST2 (const char **, char **,
3244 real_argv);
3245
3246 argv[0] = dsymutil;
3247 argv[1] = output_file;
3248 argv[2] = (char *) 0;
3249
3250 pex = collect_execute (dsymutil, real_argv, NULL, NULL, PEX_LAST | PEX_SEARCH);
3251 do_wait (dsymutil, pex);
3252}
3253
3254static void
3255post_ld_pass (bool temp_file) {
3256 if (!(temp_file && flag_idsym) && !flag_dsym)
3257 return;
3258
3259 do_dsymutil (output_file);
3260}
3261#else
3262static void
3263process_args (int *argcp ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { }
3264static void post_ld_pass (bool temp_file ATTRIBUTE_UNUSED) { }
3265#endif