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