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