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 : 92966 : tool_cleanup (bool from_signal)
384 : : {
385 : : /* maybe_unlink may call notice, which is not signal safe. */
386 : 92966 : if (from_signal)
387 : 0 : verbose = false;
388 : :
389 : 92966 : if (c_file != 0 && c_file[0])
390 : 92966 : maybe_unlink (c_file);
391 : :
392 : 92966 : if (o_file != 0 && o_file[0])
393 : 92966 : 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 : 92966 : if (lto_o_files)
401 : 4200 : maybe_unlink_list (lto_o_files);
402 : 92966 : }
403 : :
404 : : static void
405 : 92966 : collect_atexit (void)
406 : : {
407 : 92966 : tool_cleanup (false);
408 : 92966 : }
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 : 5308306 : extract_string (const char **pp)
431 : : {
432 : 5308306 : const char *p = *pp;
433 : 5308306 : int backquote = 0;
434 : 5308306 : int inside = 0;
435 : :
436 : 162156272 : for (;;)
437 : : {
438 : 162156272 : char c = *p;
439 : 162156272 : if (c == '\0')
440 : : break;
441 : 161970340 : ++p;
442 : 161970340 : if (backquote)
443 : 0 : obstack_1grow (&temporary_obstack, c);
444 : 161970340 : else if (! inside && c == ' ')
445 : : break;
446 : 156847966 : else if (! inside && c == '\\')
447 : : backquote = 1;
448 : 156847966 : else if (c == '\'')
449 : 10609272 : inside = !inside;
450 : : else
451 : 146238694 : obstack_1grow (&temporary_obstack, c);
452 : : }
453 : :
454 : 5308306 : obstack_1grow (&temporary_obstack, '\0');
455 : 5308306 : *pp = p;
456 : 5308306 : 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 : 4515 : add_lto_object (struct lto_object_list *list, const char *name)
536 : : {
537 : 4515 : struct lto_object *n = XNEW (struct lto_object);
538 : 4515 : n->name = name;
539 : 4515 : n->next = NULL;
540 : :
541 : 4515 : if (list->last)
542 : 315 : list->last->next = n;
543 : : else
544 : 4200 : list->first = n;
545 : :
546 : 4515 : list->last = n;
547 : 4515 : }
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 : 4200 : maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
580 : : const char **object, bool force)
581 : : {
582 : 4200 : const char **object_file = CONST_CAST2 (const char **, char **, object_lst);
583 : :
584 : 4200 : int num_lto_c_args = 1; /* Allow space for the terminating NULL. */
585 : :
586 : 29768 : while (object_file < object)
587 : : {
588 : : /* If file contains LTO info, add it to the list of LTO objects. */
589 : 25568 : 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 : 25568 : num_lto_c_args++;
595 : : }
596 : :
597 : 4200 : if (lto_objects.first)
598 : : {
599 : 4200 : char **lto_c_argv;
600 : 4200 : const char **lto_c_ptr;
601 : 4200 : char **p;
602 : 4200 : char **lto_o_ptr;
603 : 4200 : struct lto_object *list;
604 : 4200 : char *lto_wrapper = getenv ("COLLECT_LTO_WRAPPER");
605 : 4200 : struct pex_obj *pex;
606 : 4200 : const char *prog = "lto-wrapper";
607 : 4200 : int lto_ld_argv_size = 0;
608 : 4200 : char **out_lto_ld_argv;
609 : 4200 : int out_lto_ld_argv_size;
610 : 4200 : size_t num_files;
611 : :
612 : 4200 : if (!lto_wrapper)
613 : 0 : fatal_error (input_location, "environment variable "
614 : : "%<COLLECT_LTO_WRAPPER%> must be set");
615 : :
616 : 4200 : 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 : 4200 : lto_c_argv = (char **) xcalloc (num_lto_c_args, sizeof (char *));
626 : 4200 : lto_c_ptr = CONST_CAST2 (const char **, char **, lto_c_argv);
627 : :
628 : 4200 : *lto_c_ptr++ = lto_wrapper;
629 : :
630 : : /* Add LTO objects to the wrapper command line. */
631 : 8715 : for (list = lto_objects.first; list; list = list->next)
632 : 4515 : *lto_c_ptr++ = list->name;
633 : :
634 : 4200 : *lto_c_ptr = NULL;
635 : :
636 : : /* Run the LTO back end. */
637 : 4200 : pex = collect_execute (prog, lto_c_argv, NULL, NULL, PEX_SEARCH,
638 : : at_file_supplied, "lto_args");
639 : 4200 : {
640 : 4200 : int c;
641 : 4200 : FILE *stream;
642 : 4200 : size_t i;
643 : 4200 : char *start, *end;
644 : :
645 : 4200 : stream = pex_read_output (pex, 0);
646 : 4200 : gcc_assert (stream);
647 : :
648 : : num_files = 0;
649 : 102886 : while ((c = getc (stream)) != EOF)
650 : : {
651 : 98686 : obstack_1grow (&temporary_obstack, c);
652 : 98686 : if (c == '\n')
653 : 4616 : ++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 : 4200 : lto_o_files = XCNEWVEC (char *, num_files + 1);
660 : 4200 : lto_o_files[num_files] = NULL;
661 : 4200 : start = XOBFINISH (&temporary_obstack, char *);
662 : 8816 : for (i = 0; i < num_files; ++i)
663 : : {
664 : : end = start;
665 : 98686 : while (*end != '\n')
666 : 94070 : ++end;
667 : 4616 : *end = '\0';
668 : :
669 : 4616 : lto_o_files[i] = xstrdup (start);
670 : :
671 : 4616 : start = end + 1;
672 : : }
673 : :
674 : 4200 : obstack_free (&temporary_obstack, temporary_firstobj);
675 : : }
676 : 4200 : do_wait (prog, pex);
677 : 4200 : pex = NULL;
678 : :
679 : : /* Compute memory needed for new LD arguments. At most number of original arguments
680 : : plus number of partitions. */
681 : 148510 : for (lto_ld_argv_size = 0; lto_ld_argv[lto_ld_argv_size]; lto_ld_argv_size++)
682 : : ;
683 : 4200 : out_lto_ld_argv = XCNEWVEC (char *, num_files + lto_ld_argv_size + 1);
684 : 4200 : 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 : 4200 : p = lto_ld_argv;
692 : 89260 : while (*p != NULL)
693 : : {
694 : 172034 : for (list = lto_objects.first; list; list = list->next)
695 : 91174 : if (*p == list->name) /* Note test for pointer equality! */
696 : : break;
697 : 80860 : if (list)
698 : : break;
699 : 80860 : out_lto_ld_argv[out_lto_ld_argv_size++] = *p++;
700 : : }
701 : :
702 : : /* Now insert all LTO partitions. */
703 : 4200 : lto_o_ptr = lto_o_files;
704 : 8816 : while (*lto_o_ptr)
705 : 4616 : out_lto_ld_argv[out_lto_ld_argv_size++] = *lto_o_ptr++;
706 : :
707 : : /* ... and copy the rest. */
708 : 63450 : while (*p != NULL)
709 : : {
710 : 118227 : for (list = lto_objects.first; list; list = list->next)
711 : 63492 : if (*p == list->name) /* Note test for pointer equality! */
712 : : break;
713 : 59250 : if (!list)
714 : 54735 : out_lto_ld_argv[out_lto_ld_argv_size++] = *p;
715 : 59250 : p++;
716 : : }
717 : 4200 : 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 : 4200 : 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 : 4200 : post_ld_pass (/*temp_file*/true);
726 : 4200 : free (lto_ld_argv);
727 : :
728 : 4200 : 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 : 4200 : }
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 : 92966 : do_link (char **ld_argv, const char *atsuffix)
747 : : {
748 : 92966 : struct pex_obj *pex;
749 : 92966 : const char *prog = "ld";
750 : 92966 : pex = collect_execute (prog, ld_argv, NULL, NULL,
751 : : PEX_LAST | PEX_SEARCH,
752 : : HAVE_GNU_LD && at_file_supplied, atsuffix);
753 : 92966 : int ret = collect_wait (prog, pex);
754 : 92966 : if (ret)
755 : : {
756 : 125 : error ("ld returned %d exit status", ret);
757 : 125 : 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 : 92841 : may_unlink_output_file = true;
764 : : }
765 : 92841 : }
766 : :
767 : : /* Main program. */
768 : :
769 : : int
770 : 92966 : main (int argc, char **argv)
771 : : {
772 : 92966 : 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 : 92966 : } selected_linker = USE_DEFAULT_LD;
782 : 92966 : 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 : 92966 : static const char *const real_ld_suffix = "real-ld";
792 : 92966 : static const char *const collect_ld_suffix = "collect-ld";
793 : 92966 : static const char *const nm_suffix = "nm";
794 : 92966 : static const char *const gnm_suffix = "gnm";
795 : : #ifdef LDD_SUFFIX
796 : : static const char *const ldd_suffix = LDD_SUFFIX;
797 : : #endif
798 : 92966 : static const char *const strip_suffix = "strip";
799 : 92966 : static const char *const gstrip_suffix = "gstrip";
800 : :
801 : 92966 : 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 : 92966 : const char *const full_nm_suffix = nm_suffix;
825 : 92966 : const char *const full_gnm_suffix = gnm_suffix;
826 : 92966 : const char *const full_strip_suffix = strip_suffix;
827 : 92966 : const char *const full_gstrip_suffix = gstrip_suffix;
828 : : #endif /* CROSS_DIRECTORY_STRUCTURE */
829 : :
830 : 92966 : const char *arg;
831 : 92966 : FILE *outf;
832 : : #ifdef COLLECT_EXPORT_LIST
833 : : FILE *exportf;
834 : : #endif
835 : 92966 : const char *ld_file_name;
836 : 92966 : const char *p;
837 : 92966 : char **c_argv;
838 : 92966 : const char **c_ptr;
839 : 92966 : char **ld1_argv;
840 : 92966 : const char **ld1;
841 : 92966 : bool use_plugin = false;
842 : 92966 : 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 : 92966 : scanfilter ld1_filter = SCAN_ALL;
851 : :
852 : 92966 : char **ld2_argv;
853 : 92966 : const char **ld2;
854 : 92966 : char **object_lst;
855 : 92966 : const char **object;
856 : : #ifdef TARGET_AIX_VERSION
857 : : int object_nbr = argc;
858 : : #endif
859 : 92966 : int first_file;
860 : 92966 : int num_c_args;
861 : 92966 : char **old_argv;
862 : : #ifdef COLLECT_EXPORT_LIST
863 : : bool is_static = false;
864 : : #endif
865 : 92966 : int i;
866 : :
867 : 650762 : 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 : 557796 : full_ld_suffixes[i] = ld_suffixes[i];
877 : :
878 : 92966 : p = argv[0] + strlen (argv[0]);
879 : 836694 : while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
880 : 743728 : --p;
881 : 92966 : progname = p;
882 : :
883 : 92966 : xmalloc_set_program_name (progname);
884 : :
885 : 92966 : old_argv = argv;
886 : 92966 : expandargv (&argc, &argv);
887 : 92966 : if (argv != old_argv)
888 : 6 : at_file_supplied = 1;
889 : :
890 : 92966 : process_args (&argc, argv);
891 : :
892 : 92966 : 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 : 92966 : setup_signals ();
907 : :
908 : : /* Unlock the stdio streams. */
909 : 92966 : unlock_std_streams ();
910 : :
911 : 92966 : gcc_init_libintl ();
912 : :
913 : 92966 : diagnostic_initialize (global_dc, 0);
914 : :
915 : 92966 : 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 : 92966 : ld1_argv = XCNEWVEC (char *, argc + 4);
922 : 92966 : ld1 = CONST_CAST2 (const char **, char **, ld1_argv);
923 : 92966 : ld2_argv = XCNEWVEC (char *, argc + 11);
924 : 92966 : ld2 = CONST_CAST2 (const char **, char **, ld2_argv);
925 : 92966 : object_lst = XCNEWVEC (char *, argc);
926 : 92966 : object = CONST_CAST2 (const char **, char **, object_lst);
927 : :
928 : : #ifdef DEBUG
929 : : debug = true;
930 : : #endif
931 : :
932 : 92966 : save_temps = false;
933 : 92966 : verbose = false;
934 : :
935 : : #ifndef DEFAULT_A_OUT_NAME
936 : 92966 : 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 : 92966 : {
945 : 92966 : bool no_partition = false;
946 : :
947 : 4012249 : for (i = 1; argv[i] != NULL; i ++)
948 : : {
949 : 3919283 : if (! strcmp (argv[i], "-debug"))
950 : 0 : debug = true;
951 : 3919283 : else if (startswith (argv[i], "-fno-lto"))
952 : 35 : lto_mode = LTO_MODE_NONE;
953 : 3919248 : else if (! strcmp (argv[i], "-plugin"))
954 : : {
955 : 88731 : use_plugin = true;
956 : 88731 : if (selected_linker == USE_DEFAULT_LD)
957 : : selected_linker = USE_PLUGIN_LD;
958 : : }
959 : 3830517 : else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
960 : : selected_linker = USE_BFD_LD;
961 : 3830517 : else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
962 : : selected_linker = USE_GOLD_LD;
963 : 3830517 : else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
964 : : selected_linker = USE_LLD_LD;
965 : 3830517 : else if (strcmp (argv[i], "-fuse-ld=mold") == 0)
966 : : selected_linker = USE_MOLD_LD;
967 : 3830517 : 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 : 92483 : if (argv[i][2] != '\0')
972 : 0 : output_file = &argv[i][2];
973 : 92483 : else if (argv[i+1] != NULL)
974 : 92483 : 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 : 92966 : obstack_begin (&temporary_obstack, 0);
998 : 92966 : 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 : 92966 : p = getenv ("COLLECT_GCC_OPTIONS");
1008 : 2343710 : while (p && *p)
1009 : : {
1010 : 2250744 : const char *q = extract_string (&p);
1011 : 2250744 : if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1012 : 1084125 : num_c_args++;
1013 : 2250744 : if (startswith (q, "-flto-partition=none"))
1014 : : no_partition = true;
1015 : 2246538 : else if (startswith (q, "-fno-lto"))
1016 : 35 : lto_mode = LTO_MODE_NONE;
1017 : 2246503 : else if (startswith (q, "-save-temps"))
1018 : : /* FIXME: Honour =obj. */
1019 : 255 : save_temps = true;
1020 : 2246248 : else if (strcmp (q, "-dumpdir") == 0)
1021 : 92963 : dumppfx = xstrdup (extract_string (&p));
1022 : 2153285 : else if (strcmp (q, "-o") == 0
1023 : 2060802 : || strcmp (q, "-B") == 0
1024 : 1860847 : || strcmp (q, "-isystem") == 0)
1025 : 310446 : (void) extract_string (&p);
1026 : : }
1027 : 92966 : obstack_free (&temporary_obstack, temporary_firstobj);
1028 : :
1029 : 92966 : verbose = verbose || debug;
1030 : 92966 : save_temps = save_temps || debug;
1031 : 92966 : find_file_set_debug (debug);
1032 : 92966 : if (use_plugin)
1033 : 88731 : lto_mode = LTO_MODE_NONE;
1034 : 92966 : if (no_partition && lto_mode == LTO_MODE_WHOPR)
1035 : 3944 : lto_mode = LTO_MODE_LTO;
1036 : : }
1037 : :
1038 : : /* -fno-profile-arcs -fno-condition-coverage -fno-test-coverage
1039 : : -fno-branch-probabilities -fno-exceptions -w -fno-whole-program */
1040 : 92966 : num_c_args += 7;
1041 : :
1042 : 92966 : c_argv = XCNEWVEC (char *, num_c_args);
1043 : 92966 : c_ptr = CONST_CAST2 (const char **, char **, c_argv);
1044 : :
1045 : 92966 : if (argc < 2)
1046 : 0 : fatal_error (input_location, "no arguments");
1047 : :
1048 : : /* Extract COMPILER_PATH and PATH into our prefix list. */
1049 : 92966 : prefix_from_env ("COMPILER_PATH", &cpath);
1050 : 92966 : prefix_from_env ("PATH", &path);
1051 : :
1052 : : /* Try to discover a valid linker/nm/strip to use. */
1053 : :
1054 : : /* Maybe we know the right file to use (if not cross). */
1055 : 92966 : ld_file_name = 0;
1056 : : #ifdef DEFAULT_LINKER
1057 : : if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
1058 : : selected_linker == USE_LLD_LD || selected_linker == USE_MOLD_LD)
1059 : : {
1060 : : char *linker_name;
1061 : : # ifdef HOST_EXECUTABLE_SUFFIX
1062 : : int len = (sizeof (DEFAULT_LINKER)
1063 : : - sizeof (HOST_EXECUTABLE_SUFFIX));
1064 : : linker_name = NULL;
1065 : : if (len > 0)
1066 : : {
1067 : : char *default_linker = xstrdup (DEFAULT_LINKER);
1068 : : /* Strip HOST_EXECUTABLE_SUFFIX if DEFAULT_LINKER contains
1069 : : HOST_EXECUTABLE_SUFFIX. */
1070 : : if (! strcmp (&default_linker[len], HOST_EXECUTABLE_SUFFIX))
1071 : : {
1072 : : default_linker[len] = '\0';
1073 : : linker_name = concat (default_linker,
1074 : : &ld_suffixes[selected_linker][2],
1075 : : HOST_EXECUTABLE_SUFFIX, NULL);
1076 : : }
1077 : : }
1078 : : if (linker_name == NULL)
1079 : : # endif
1080 : : linker_name = concat (DEFAULT_LINKER,
1081 : : &ld_suffixes[selected_linker][2],
1082 : : NULL);
1083 : : if (access (linker_name, X_OK) == 0)
1084 : : ld_file_name = linker_name;
1085 : : }
1086 : : if (ld_file_name == 0 && access (DEFAULT_LINKER, X_OK) == 0)
1087 : : ld_file_name = DEFAULT_LINKER;
1088 : : if (ld_file_name == 0)
1089 : : #endif
1090 : : #ifdef REAL_LD_FILE_NAME
1091 : : ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME, X_OK);
1092 : : if (ld_file_name == 0)
1093 : : #endif
1094 : : /* Search the (target-specific) compiler dirs for ld'. */
1095 : 92966 : ld_file_name = find_a_file (&cpath, real_ld_suffix, X_OK);
1096 : : /* Likewise for `collect-ld'. */
1097 : 92966 : if (ld_file_name == 0)
1098 : : {
1099 : 92966 : ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
1100 : 92966 : use_collect_ld = ld_file_name != 0;
1101 : : }
1102 : : /* Search the compiler directories for `ld'. We have protection against
1103 : : recursive calls in find_a_file. */
1104 : 92966 : if (ld_file_name == 0)
1105 : 0 : ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK);
1106 : : /* Search the ordinary system bin directories
1107 : : for `ld' (if native linking) or `TARGET-ld' (if cross). */
1108 : 0 : if (ld_file_name == 0)
1109 : 0 : ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK);
1110 : :
1111 : : #ifdef REAL_NM_FILE_NAME
1112 : : nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK);
1113 : : if (nm_file_name == 0)
1114 : : #endif
1115 : 92966 : nm_file_name = find_a_file (&cpath, gnm_suffix, X_OK);
1116 : 92966 : if (nm_file_name == 0)
1117 : 92966 : nm_file_name = find_a_file (&path, full_gnm_suffix, X_OK);
1118 : 92966 : if (nm_file_name == 0)
1119 : 92966 : nm_file_name = find_a_file (&cpath, nm_suffix, X_OK);
1120 : 92966 : if (nm_file_name == 0)
1121 : 0 : nm_file_name = find_a_file (&path, full_nm_suffix, X_OK);
1122 : :
1123 : : #ifdef LDD_SUFFIX
1124 : : ldd_file_name = find_a_file (&cpath, ldd_suffix, X_OK);
1125 : : if (ldd_file_name == 0)
1126 : : ldd_file_name = find_a_file (&path, full_ldd_suffix, X_OK);
1127 : : #endif
1128 : :
1129 : : #ifdef REAL_STRIP_FILE_NAME
1130 : : strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME, X_OK);
1131 : : if (strip_file_name == 0)
1132 : : #endif
1133 : 92966 : strip_file_name = find_a_file (&cpath, gstrip_suffix, X_OK);
1134 : 92966 : if (strip_file_name == 0)
1135 : 92966 : strip_file_name = find_a_file (&path, full_gstrip_suffix, X_OK);
1136 : 92966 : if (strip_file_name == 0)
1137 : 92966 : strip_file_name = find_a_file (&cpath, strip_suffix, X_OK);
1138 : 92966 : if (strip_file_name == 0)
1139 : 92966 : strip_file_name = find_a_file (&path, full_strip_suffix, X_OK);
1140 : :
1141 : : /* Determine the full path name of the C compiler to use. */
1142 : 92966 : c_file_name = getenv ("COLLECT_GCC");
1143 : 92966 : if (c_file_name == 0)
1144 : : {
1145 : : #ifdef CROSS_DIRECTORY_STRUCTURE
1146 : : c_file_name = concat (target_machine, "-gcc", NULL);
1147 : : #else
1148 : 0 : c_file_name = "gcc";
1149 : : #endif
1150 : : }
1151 : :
1152 : 92966 : p = find_a_file (&cpath, c_file_name, X_OK);
1153 : :
1154 : : /* Here it should be safe to use the system search path since we should have
1155 : : already qualified the name of the compiler when it is needed. */
1156 : 92966 : if (p == 0)
1157 : 0 : p = find_a_file (&path, c_file_name, X_OK);
1158 : :
1159 : 92966 : if (p)
1160 : 92966 : c_file_name = p;
1161 : :
1162 : 92966 : *ld1++ = *ld2++ = ld_file_name;
1163 : :
1164 : : /* Make temp file names. */
1165 : 92966 : if (save_temps)
1166 : : {
1167 : 249 : c_file = concat (output_file, ".cdtor.c", NULL);
1168 : 249 : o_file = concat (output_file, ".cdtor.o", NULL);
1169 : : #ifdef COLLECT_EXPORT_LIST
1170 : : export_file = concat (output_file, ".x", NULL);
1171 : : #endif
1172 : : }
1173 : : else
1174 : : {
1175 : 92717 : c_file = make_temp_file (".cdtor.c");
1176 : 92717 : o_file = make_temp_file (".cdtor.o");
1177 : : #ifdef COLLECT_EXPORT_LIST
1178 : : export_file = make_temp_file (".x");
1179 : : #endif
1180 : : }
1181 : : /* Build the command line to compile the ctor/dtor list. */
1182 : 92966 : *c_ptr++ = c_file_name;
1183 : 92966 : *c_ptr++ = "-x";
1184 : 92966 : *c_ptr++ = "c";
1185 : 92966 : *c_ptr++ = "-c";
1186 : 92966 : *c_ptr++ = "-o";
1187 : 92966 : *c_ptr++ = o_file;
1188 : :
1189 : : #ifdef COLLECT_EXPORT_LIST
1190 : : /* Generate a list of directories from LIBPATH. */
1191 : : prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1192 : : /* Add to this list also two standard directories where
1193 : : AIX loader always searches for libraries. */
1194 : : add_prefix (&libpath_lib_dirs, "/lib");
1195 : : add_prefix (&libpath_lib_dirs, "/usr/lib");
1196 : : #endif
1197 : :
1198 : : /* Get any options that the upper GCC wants to pass to the sub-GCC.
1199 : :
1200 : : AIX support needs to know if -shared has been specified before
1201 : : parsing commandline arguments. */
1202 : :
1203 : 92966 : p = getenv ("COLLECT_GCC_OPTIONS");
1204 : 2343710 : while (p && *p)
1205 : : {
1206 : 2250744 : const char *q = extract_string (&p);
1207 : 2250744 : if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1208 : 1084125 : *c_ptr++ = xstrdup (q);
1209 : 2250744 : if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1210 : 0 : *c_ptr++ = xstrdup (q);
1211 : 2250744 : if (strcmp (q, "-shared") == 0)
1212 : 209 : shared_obj = 1;
1213 : 2250744 : if (strcmp (q, "-static") == 0)
1214 : 98 : static_obj = 1;
1215 : 2250744 : if (*q == '-' && q[1] == 'B')
1216 : : {
1217 : 199955 : *c_ptr++ = xstrdup (q);
1218 : 199955 : if (q[2] == 0)
1219 : : {
1220 : 199955 : q = extract_string (&p);
1221 : 199955 : *c_ptr++ = xstrdup (q);
1222 : : }
1223 : : }
1224 : 2050789 : else if (strcmp (q, "-o") == 0
1225 : 1958306 : || strcmp (q, "-dumpdir") == 0
1226 : 1865343 : || strcmp (q, "-isystem") == 0)
1227 : 203454 : (void) extract_string (&p);
1228 : : #ifdef COLLECT_EXPORT_LIST
1229 : : /* Detect any invocation with -fvisibility. */
1230 : : if (startswith (q, "-fvisibility"))
1231 : : visibility_flag = 1;
1232 : : #endif
1233 : : }
1234 : 92966 : obstack_free (&temporary_obstack, temporary_firstobj);
1235 : 92966 : *c_ptr++ = "-fno-profile-arcs";
1236 : 92966 : *c_ptr++ = "-fno-condition-coverage";
1237 : 92966 : *c_ptr++ = "-fno-test-coverage";
1238 : 92966 : *c_ptr++ = "-fno-branch-probabilities";
1239 : 92966 : *c_ptr++ = "-fno-exceptions";
1240 : 92966 : *c_ptr++ = "-w";
1241 : 92966 : *c_ptr++ = "-fno-whole-program";
1242 : :
1243 : : /* !!! When GCC calls collect2,
1244 : : it does not know whether it is calling collect2 or ld.
1245 : : So collect2 cannot meaningfully understand any options
1246 : : except those ld understands.
1247 : : If you propose to make GCC pass some other option,
1248 : : just imagine what will happen if ld is really ld!!! */
1249 : :
1250 : : /* Parse arguments. Remember output file spec, pass the rest to ld. */
1251 : : /* After the first file, put in the c++ rt0. */
1252 : :
1253 : : #ifdef COLLECT_EXPORT_LIST
1254 : : is_static = static_obj;
1255 : : #endif
1256 : 92966 : first_file = 1;
1257 : 3919590 : while ((arg = *++argv) != (char *) 0)
1258 : : {
1259 : 3826624 : *ld1++ = *ld2++ = arg;
1260 : :
1261 : 3826624 : if (arg[0] == '-')
1262 : : {
1263 : 3060850 : switch (arg[1])
1264 : : {
1265 : 92659 : case 'd':
1266 : 92659 : if (!strcmp (arg, "-debug"))
1267 : : {
1268 : : /* Already parsed. */
1269 : 0 : ld1--;
1270 : 0 : ld2--;
1271 : : }
1272 : 92659 : if (!strcmp (arg, "-dynamic-linker") && argv[1])
1273 : : {
1274 : 92659 : ++argv;
1275 : 92659 : *ld1++ = *ld2++ = *argv;
1276 : : }
1277 : : break;
1278 : :
1279 : 12850 : case 'f':
1280 : 12850 : if (startswith (arg, "-flto"))
1281 : : {
1282 : : #ifdef ENABLE_LTO
1283 : : /* Do not pass LTO flag to the linker. */
1284 : : ld1--;
1285 : : ld2--;
1286 : : #else
1287 : : error ("LTO support has not been enabled in this "
1288 : : "configuration");
1289 : : #endif
1290 : : }
1291 : 35 : else if (!use_collect_ld
1292 : 35 : && startswith (arg, "-fuse-ld="))
1293 : : {
1294 : : /* Do not pass -fuse-ld={bfd|gold|lld|mold} to the linker. */
1295 : : ld1--;
1296 : : ld2--;
1297 : : }
1298 : 35 : else if (startswith (arg, "-fno-lto"))
1299 : : {
1300 : : /* Do not pass -fno-lto to the linker. */
1301 : 3826624 : ld1--;
1302 : 3826624 : ld2--;
1303 : : }
1304 : : #ifdef TARGET_AIX_VERSION
1305 : : else
1306 : : {
1307 : : /* File containing a list of input files to process. */
1308 : :
1309 : : FILE *stream;
1310 : : char buf[MAXPATHLEN + 2];
1311 : : /* Number of additionnal object files. */
1312 : : int add_nbr = 0;
1313 : : /* Maximum of additionnal object files before vector
1314 : : expansion. */
1315 : : int add_max = 0;
1316 : : const char *list_filename = arg + 2;
1317 : :
1318 : : /* Accept -fFILENAME and -f FILENAME. */
1319 : : if (*list_filename == '\0' && argv[1])
1320 : : {
1321 : : ++argv;
1322 : : list_filename = *argv;
1323 : : *ld1++ = *ld2++ = *argv;
1324 : : }
1325 : :
1326 : : stream = fopen (list_filename, "r");
1327 : : if (stream == NULL)
1328 : : fatal_error (input_location, "cannot open %s: %m",
1329 : : list_filename);
1330 : :
1331 : : while (fgets (buf, sizeof buf, stream) != NULL)
1332 : : {
1333 : : /* Remove end of line. */
1334 : : int len = strlen (buf);
1335 : : if (len >= 1 && buf[len - 1] =='\n')
1336 : : buf[len - 1] = '\0';
1337 : :
1338 : : /* Put on object vector.
1339 : : Note: we only expanse vector here, so we must keep
1340 : : extra space for remaining arguments. */
1341 : : if (add_nbr >= add_max)
1342 : : {
1343 : : int pos =
1344 : : object - CONST_CAST2 (const char **, char **,
1345 : : object_lst);
1346 : : add_max = (add_max == 0) ? 16 : add_max * 2;
1347 : : object_lst = XRESIZEVEC (char *, object_lst,
1348 : : object_nbr + add_max);
1349 : : object = CONST_CAST2 (const char **, char **,
1350 : : object_lst) + pos;
1351 : : object_nbr += add_max;
1352 : : }
1353 : : *object++ = xstrdup (buf);
1354 : : add_nbr++;
1355 : : }
1356 : : fclose (stream);
1357 : : }
1358 : : #endif
1359 : : break;
1360 : :
1361 : : #ifdef COLLECT_EXPORT_LIST
1362 : : case 'b':
1363 : : if (!strcmp (arg, "-bstatic"))
1364 : : {
1365 : : is_static = true;
1366 : : }
1367 : : else if (!strcmp (arg, "-bdynamic") || !strcmp (arg, "-bshared"))
1368 : : {
1369 : : is_static = false;
1370 : : }
1371 : : break;
1372 : : #endif
1373 : 717674 : case 'l':
1374 : 717674 : if (first_file)
1375 : : {
1376 : : /* place o_file BEFORE this argument! */
1377 : 0 : first_file = 0;
1378 : 0 : ld2--;
1379 : 0 : *ld2++ = o_file;
1380 : 0 : *ld2++ = arg;
1381 : : }
1382 : : #ifdef COLLECT_EXPORT_LIST
1383 : : {
1384 : : /* Resolving full library name. */
1385 : : const char *s = resolve_lib_name (arg+2);
1386 : :
1387 : : /* Saving a full library name. */
1388 : : add_to_list (&libs, s);
1389 : : if (is_static)
1390 : : add_to_list (&static_libs, s);
1391 : : }
1392 : : #endif
1393 : : break;
1394 : :
1395 : : #ifdef COLLECT_EXPORT_LIST
1396 : : /* Saving directories where to search for libraries. */
1397 : : case 'L':
1398 : : add_prefix (&cmdline_lib_dirs, arg+2);
1399 : : break;
1400 : : #endif
1401 : :
1402 : 92483 : case 'o':
1403 : 92483 : if (arg[2] != '\0')
1404 : 0 : output_file = &arg[2];
1405 : 92483 : else if (argv[1])
1406 : 92483 : output_file = *ld1++ = *ld2++ = *++argv;
1407 : : break;
1408 : :
1409 : 230 : case 'r':
1410 : 230 : if (arg[2] == '\0')
1411 : 188 : rflag = 1;
1412 : : break;
1413 : :
1414 : 366 : case 's':
1415 : 366 : if (arg[2] == '\0' && do_collecting)
1416 : : {
1417 : : /* We must strip after the nm run, otherwise C++ linking
1418 : : will not work. Thus we strip in the second ld run, or
1419 : : else with strip if there is no second ld run. */
1420 : 0 : strip_flag = 1;
1421 : 0 : ld1--;
1422 : : }
1423 : : break;
1424 : :
1425 : 0 : case 'v':
1426 : 0 : if (arg[2] == '\0')
1427 : 0 : verbose = true;
1428 : : break;
1429 : :
1430 : 394811 : case '-':
1431 : 394811 : if (strcmp (arg, "--no-demangle") == 0)
1432 : : {
1433 : : #ifndef HAVE_LD_DEMANGLE
1434 : : no_demangle = 1;
1435 : : ld1--;
1436 : : ld2--;
1437 : : #endif
1438 : : }
1439 : 394811 : else if (startswith (arg, "--demangle"))
1440 : : {
1441 : : #ifndef HAVE_LD_DEMANGLE
1442 : : no_demangle = 0;
1443 : : if (arg[10] == '=')
1444 : : {
1445 : : enum demangling_styles style
1446 : : = cplus_demangle_name_to_style (arg+11);
1447 : : if (style == unknown_demangling)
1448 : : error ("unknown demangling style %qs", arg+11);
1449 : : else
1450 : : current_demangling_style = style;
1451 : : }
1452 : : ld1--;
1453 : : ld2--;
1454 : : #endif
1455 : : }
1456 : 394811 : else if (startswith (arg, "--sysroot="))
1457 : 0 : target_system_root = arg + 10;
1458 : 394811 : else if (strcmp (arg, "--version") == 0)
1459 : 0 : verbose = true;
1460 : 394811 : else if (strcmp (arg, "--help") == 0)
1461 : 5 : helpflag = true;
1462 : : break;
1463 : : }
1464 : : }
1465 : 765774 : else if ((p = strrchr (arg, '.')) != (char *) 0
1466 : 765774 : && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1467 : 88798 : || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1468 : 59 : || strcmp (p, ".obj") == 0))
1469 : : {
1470 : 672520 : if (first_file)
1471 : : {
1472 : 92966 : first_file = 0;
1473 : 92966 : if (p[1] == 'o')
1474 : 4235 : *ld2++ = o_file;
1475 : : else
1476 : : {
1477 : : /* place o_file BEFORE this argument! */
1478 : 88731 : ld2--;
1479 : 88731 : *ld2++ = o_file;
1480 : 88731 : *ld2++ = arg;
1481 : : }
1482 : : }
1483 : 672520 : if (p[1] == 'o' || p[1] == 'l')
1484 : 570454 : *object++ = arg;
1485 : : #ifdef COLLECT_EXPORT_LIST
1486 : : /* libraries can be specified directly, i.e. without -l flag. */
1487 : : else
1488 : : {
1489 : : /* Saving a full library name. */
1490 : : add_to_list (&libs, arg);
1491 : : if (is_static)
1492 : : add_to_list (&static_libs, arg);
1493 : : }
1494 : : #endif
1495 : : }
1496 : : }
1497 : :
1498 : : #ifdef COLLECT_EXPORT_LIST
1499 : : /* This is added only for debugging purposes. */
1500 : : if (debug)
1501 : : {
1502 : : fprintf (stderr, "List of libraries:\n");
1503 : : dump_list (stderr, "\t", libs.first);
1504 : : fprintf (stderr, "List of statically linked libraries:\n");
1505 : : dump_list (stderr, "\t", static_libs.first);
1506 : : }
1507 : :
1508 : : /* The AIX linker will discard static constructors in object files if
1509 : : nothing else in the file is referenced, so look at them first. Unless
1510 : : we are building a shared object, ignore the eh frame tables, as we
1511 : : would otherwise reference them all, hence drag all the corresponding
1512 : : objects even if nothing else is referenced. */
1513 : : {
1514 : : const char **export_object_lst
1515 : : = CONST_CAST2 (const char **, char **, object_lst);
1516 : :
1517 : : struct id *list = libs.first;
1518 : :
1519 : : /* Compute the filter to use from the current one, do scan, then adjust
1520 : : the "current" filter to remove what we just included here. This will
1521 : : control whether we need a first pass link later on or not, and what
1522 : : will remain to be scanned there. */
1523 : :
1524 : : scanfilter this_filter = ld1_filter;
1525 : : #if HAVE_AS_REF
1526 : : if (!shared_obj)
1527 : : this_filter &= ~SCAN_DWEH;
1528 : : #endif
1529 : :
1530 : : /* Scan object files. */
1531 : : while (export_object_lst < object)
1532 : : scan_prog_file (*export_object_lst++, PASS_OBJ, this_filter);
1533 : :
1534 : : /* Scan libraries. */
1535 : : for (; list; list = list->next)
1536 : : scan_prog_file (list->name, PASS_FIRST, this_filter);
1537 : :
1538 : : ld1_filter = ld1_filter & ~this_filter;
1539 : : }
1540 : :
1541 : : if (exports.first)
1542 : : {
1543 : : char *buf = concat ("-bE:", export_file, NULL);
1544 : :
1545 : : *ld1++ = buf;
1546 : : *ld2++ = buf;
1547 : :
1548 : : exportf = fopen (export_file, "w");
1549 : : if (exportf == (FILE *) 0)
1550 : : fatal_error (input_location, "fopen %s: %m", export_file);
1551 : : write_aix_file (exportf, exports.first);
1552 : : if (fclose (exportf))
1553 : : fatal_error (input_location, "fclose %s: %m", export_file);
1554 : : }
1555 : : #endif
1556 : :
1557 : 92966 : *c_ptr++ = c_file;
1558 : 92966 : *c_ptr = *ld1 = *object = (char *) 0;
1559 : :
1560 : 92966 : if (verbose)
1561 : 0 : notice ("collect2 version %s\n", version_string);
1562 : :
1563 : 92966 : if (helpflag)
1564 : : {
1565 : 5 : printf ("Usage: collect2 [options]\n");
1566 : 5 : printf (" Wrap linker and generate constructor code if needed.\n");
1567 : 5 : printf (" Options:\n");
1568 : 5 : printf (" -debug Enable debug output\n");
1569 : 5 : printf (" --help Display this information\n");
1570 : 5 : printf (" -v, --version Display this program's version number\n");
1571 : 5 : printf ("\n");
1572 : 5 : printf ("Overview: https://gcc.gnu.org/onlinedocs/gccint/Collect2.html\n");
1573 : 5 : printf ("Report bugs: %s\n", bug_report_url);
1574 : 5 : printf ("\n");
1575 : : }
1576 : :
1577 : 92966 : if (debug)
1578 : : {
1579 : 0 : const char *ptr;
1580 : 0 : fprintf (stderr, "ld_file_name = %s\n",
1581 : : (ld_file_name ? ld_file_name : "not found"));
1582 : 0 : fprintf (stderr, "c_file_name = %s\n",
1583 : 0 : (c_file_name ? c_file_name : "not found"));
1584 : 0 : fprintf (stderr, "nm_file_name = %s\n",
1585 : 0 : (nm_file_name ? nm_file_name : "not found"));
1586 : : #ifdef LDD_SUFFIX
1587 : : fprintf (stderr, "ldd_file_name = %s\n",
1588 : : (ldd_file_name ? ldd_file_name : "not found"));
1589 : : #endif
1590 : 0 : fprintf (stderr, "strip_file_name = %s\n",
1591 : 0 : (strip_file_name ? strip_file_name : "not found"));
1592 : 0 : fprintf (stderr, "c_file = %s\n",
1593 : 0 : (c_file ? c_file : "not found"));
1594 : 0 : fprintf (stderr, "o_file = %s\n",
1595 : 0 : (o_file ? o_file : "not found"));
1596 : :
1597 : 0 : ptr = getenv ("COLLECT_GCC_OPTIONS");
1598 : 0 : if (ptr)
1599 : 0 : fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1600 : :
1601 : 0 : ptr = getenv ("COLLECT_GCC");
1602 : 0 : if (ptr)
1603 : 0 : fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1604 : :
1605 : 0 : ptr = getenv ("COMPILER_PATH");
1606 : 0 : if (ptr)
1607 : 0 : fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1608 : :
1609 : 0 : ptr = getenv (LIBRARY_PATH_ENV);
1610 : 0 : if (ptr)
1611 : 0 : fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1612 : :
1613 : 0 : fprintf (stderr, "\n");
1614 : : }
1615 : :
1616 : : /* Load the program, searching all libraries and attempting to provide
1617 : : undefined symbols from repository information.
1618 : :
1619 : : If -r or they will be run via some other method, do not build the
1620 : : constructor or destructor list, just return now. */
1621 : 92966 : {
1622 : 185932 : bool early_exit
1623 : 92966 : = rflag || (! DO_COLLECT_EXPORT_LIST && ! do_collecting);
1624 : :
1625 : : /* Perform the first pass link now, if we're about to exit or if we need
1626 : : to scan for things we haven't collected yet before pursuing further.
1627 : :
1628 : : On AIX, the latter typically includes nothing for shared objects or
1629 : : frame tables for an executable, out of what the required early scan on
1630 : : objects and libraries has performed above. In the !shared_obj case, we
1631 : : expect the relevant tables to be dragged together with their associated
1632 : : functions from precise cross reference insertions by the compiler. */
1633 : :
1634 : 92966 : if (early_exit || ld1_filter != SCAN_NOTHING)
1635 : 92966 : do_link (ld1_argv, "ld1_args");
1636 : :
1637 : 92841 : if (early_exit)
1638 : : {
1639 : : #ifdef COLLECT_EXPORT_LIST
1640 : : /* Make sure we delete the export file we may have created. */
1641 : : if (export_file != 0 && export_file[0])
1642 : : maybe_unlink (export_file);
1643 : : #endif
1644 : 92841 : if (lto_mode != LTO_MODE_NONE)
1645 : 4200 : maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
1646 : : else
1647 : : post_ld_pass (/*temp_file*/false);
1648 : :
1649 : 92841 : return 0;
1650 : : }
1651 : : }
1652 : :
1653 : : /* Unless we have done it all already, examine the namelist and search for
1654 : : static constructors and destructors to call. Write the constructor and
1655 : : destructor tables to a .s file and reload. */
1656 : :
1657 : 0 : if (ld1_filter != SCAN_NOTHING)
1658 : 0 : scan_prog_file (output_file, PASS_FIRST, ld1_filter);
1659 : :
1660 : : #ifdef SCAN_LIBRARIES
1661 : : scan_libraries (output_file);
1662 : : #endif
1663 : :
1664 : 0 : if (debug)
1665 : : {
1666 : 0 : notice_translated (ngettext ("%d constructor found\n",
1667 : : "%d constructors found\n",
1668 : : constructors.number),
1669 : : constructors.number);
1670 : 0 : notice_translated (ngettext ("%d destructor found\n",
1671 : : "%d destructors found\n",
1672 : : destructors.number),
1673 : : destructors.number);
1674 : 0 : notice_translated (ngettext ("%d frame table found\n",
1675 : : "%d frame tables found\n",
1676 : : frame_tables.number),
1677 : : frame_tables.number);
1678 : : }
1679 : :
1680 : : /* If the scan exposed nothing of special interest, there's no need to
1681 : : generate the glue code and relink so return now. */
1682 : :
1683 : 0 : if (constructors.number == 0 && destructors.number == 0
1684 : 0 : && frame_tables.number == 0
1685 : : #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1686 : : /* If we will be running these functions ourselves, we want to emit
1687 : : stubs into the shared library so that we do not have to relink
1688 : : dependent programs when we add static objects. */
1689 : : && ! shared_obj
1690 : : #endif
1691 : : )
1692 : : {
1693 : : /* Do link without additional code generation now if we didn't
1694 : : do it earlier for scanning purposes. */
1695 : 0 : if (ld1_filter == SCAN_NOTHING)
1696 : : do_link (ld1_argv, "ld1_args");
1697 : :
1698 : 0 : if (lto_mode)
1699 : 0 : maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
1700 : :
1701 : : /* Strip now if it was requested on the command line. */
1702 : 0 : if (strip_flag)
1703 : : {
1704 : 0 : char **real_strip_argv = XCNEWVEC (char *, 3);
1705 : 0 : const char ** strip_argv = CONST_CAST2 (const char **, char **,
1706 : : real_strip_argv);
1707 : :
1708 : 0 : strip_argv[0] = strip_file_name;
1709 : 0 : strip_argv[1] = output_file;
1710 : 0 : strip_argv[2] = (char *) 0;
1711 : 0 : fork_execute ("strip", real_strip_argv, false, NULL);
1712 : : }
1713 : :
1714 : : #ifdef COLLECT_EXPORT_LIST
1715 : : maybe_unlink (export_file);
1716 : : #endif
1717 : 0 : post_ld_pass (/*temp_file*/false);
1718 : 0 : return 0;
1719 : : }
1720 : :
1721 : : /* Sort ctor and dtor lists by priority. */
1722 : 0 : sort_ids (&constructors);
1723 : 0 : sort_ids (&destructors);
1724 : :
1725 : 0 : maybe_unlink (output_file);
1726 : 0 : outf = fopen (c_file, "w");
1727 : 0 : if (outf == (FILE *) 0)
1728 : 0 : fatal_error (input_location, "fopen %s: %m", c_file);
1729 : :
1730 : 0 : write_c_file (outf, c_file);
1731 : :
1732 : 0 : if (fclose (outf))
1733 : 0 : fatal_error (input_location, "fclose %s: %m", c_file);
1734 : :
1735 : : /* Tell the linker that we have initializer and finalizer functions. */
1736 : : #ifdef LD_INIT_SWITCH
1737 : : #ifdef COLLECT_EXPORT_LIST
1738 : : *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
1739 : : #else
1740 : : *ld2++ = LD_INIT_SWITCH;
1741 : : *ld2++ = initname;
1742 : : *ld2++ = LD_FINI_SWITCH;
1743 : : *ld2++ = fininame;
1744 : : #endif
1745 : : #endif
1746 : :
1747 : : #ifdef COLLECT_EXPORT_LIST
1748 : : if (shared_obj)
1749 : : {
1750 : : /* If we did not add export flag to link arguments before, add it to
1751 : : second link phase now. No new exports should have been added. */
1752 : : if (! exports.first)
1753 : : *ld2++ = concat ("-bE:", export_file, NULL);
1754 : :
1755 : : #ifdef TARGET_AIX_VERSION
1756 : : add_to_list (&exports, aix_shared_initname);
1757 : : add_to_list (&exports, aix_shared_fininame);
1758 : : #endif
1759 : :
1760 : : #ifndef LD_INIT_SWITCH
1761 : : add_to_list (&exports, initname);
1762 : : add_to_list (&exports, fininame);
1763 : : add_to_list (&exports, "_GLOBAL__DI");
1764 : : add_to_list (&exports, "_GLOBAL__DD");
1765 : : #endif
1766 : : exportf = fopen (export_file, "w");
1767 : : if (exportf == (FILE *) 0)
1768 : : fatal_error (input_location, "fopen %s: %m", export_file);
1769 : : write_aix_file (exportf, exports.first);
1770 : : if (fclose (exportf))
1771 : : fatal_error (input_location, "fclose %s: %m", export_file);
1772 : : }
1773 : : #endif
1774 : :
1775 : : /* End of arguments to second link phase. */
1776 : 0 : *ld2 = (char*) 0;
1777 : :
1778 : 0 : if (debug)
1779 : : {
1780 : 0 : fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1781 : : output_file, c_file);
1782 : 0 : write_c_file (stderr, "stderr");
1783 : 0 : fprintf (stderr, "========== end of c_file\n\n");
1784 : : #ifdef COLLECT_EXPORT_LIST
1785 : : fprintf (stderr, "\n========== export_file = %s\n", export_file);
1786 : : write_aix_file (stderr, exports.first);
1787 : : fprintf (stderr, "========== end of export_file\n\n");
1788 : : #endif
1789 : : }
1790 : :
1791 : : /* Assemble the constructor and destructor tables.
1792 : : Link the tables in with the rest of the program. */
1793 : :
1794 : 0 : fork_execute ("gcc", c_argv, at_file_supplied, "gcc_args");
1795 : : #ifdef COLLECT_EXPORT_LIST
1796 : : /* On AIX we must call link because of possible templates resolution. */
1797 : : do_link (ld2_argv, "ld2_args");
1798 : :
1799 : : if (lto_mode)
1800 : : maybe_run_lto_and_relink (ld2_argv, object_lst, object, false);
1801 : : #else
1802 : : /* Otherwise, simply call ld because link is already done. */
1803 : 0 : if (lto_mode)
1804 : 0 : maybe_run_lto_and_relink (ld2_argv, object_lst, object, true);
1805 : : else
1806 : : {
1807 : 0 : fork_execute ("ld", ld2_argv, HAVE_GNU_LD && at_file_supplied, "ld_args");
1808 : 0 : post_ld_pass (/*temp_file*/false);
1809 : : }
1810 : :
1811 : : /* Let scan_prog_file do any final mods (OSF/rose needs this for
1812 : : constructors/destructors in shared libraries. */
1813 : 0 : scan_prog_file (output_file, PASS_SECOND, SCAN_ALL);
1814 : : #endif
1815 : :
1816 : 0 : return 0;
1817 : : }
1818 : :
1819 : :
1820 : : /* Unlink FILE unless we are debugging or this is the output_file
1821 : : and we may not unlink it. */
1822 : :
1823 : : void
1824 : 195164 : maybe_unlink (const char *file)
1825 : : {
1826 : 195164 : if (save_temps && file_exists (file))
1827 : : {
1828 : 2 : if (verbose)
1829 : 0 : notice ("[Leaving %s]\n", file);
1830 : 2 : return;
1831 : : }
1832 : :
1833 : 195162 : if (file == output_file && !may_unlink_output_file)
1834 : : return;
1835 : :
1836 : 195162 : unlink_if_ordinary (file);
1837 : : }
1838 : :
1839 : : /* Call maybe_unlink on the NULL-terminated list, FILE_LIST. */
1840 : :
1841 : : static void
1842 : 8400 : maybe_unlink_list (char **file_list)
1843 : : {
1844 : 8400 : char **tmp = file_list;
1845 : :
1846 : 17632 : while (*tmp)
1847 : 9232 : maybe_unlink (*(tmp++));
1848 : 8400 : }
1849 : :
1850 : :
1851 : : static long sequence_number = 0;
1852 : :
1853 : : /* Add a name to a linked list. */
1854 : :
1855 : : static void
1856 : 0 : add_to_list (struct head *head_ptr, const char *name)
1857 : : {
1858 : 0 : struct id *newid
1859 : 0 : = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1860 : 0 : struct id *p;
1861 : 0 : strcpy (newid->name, name);
1862 : :
1863 : 0 : if (head_ptr->first)
1864 : 0 : head_ptr->last->next = newid;
1865 : : else
1866 : 0 : head_ptr->first = newid;
1867 : :
1868 : : /* Check for duplicate symbols. */
1869 : 0 : for (p = head_ptr->first;
1870 : 0 : strcmp (name, p->name) != 0;
1871 : 0 : p = p->next)
1872 : : ;
1873 : 0 : if (p != newid)
1874 : : {
1875 : 0 : head_ptr->last->next = 0;
1876 : 0 : free (newid);
1877 : 0 : return;
1878 : : }
1879 : :
1880 : 0 : newid->sequence = ++sequence_number;
1881 : 0 : head_ptr->last = newid;
1882 : 0 : head_ptr->number++;
1883 : : }
1884 : :
1885 : : /* Grab the init priority number from an init function name that
1886 : : looks like "_GLOBAL_.I.12345.foo". */
1887 : :
1888 : : static int
1889 : 0 : extract_init_priority (const char *name)
1890 : : {
1891 : 0 : int pos = 0, pri;
1892 : :
1893 : : #ifdef TARGET_AIX_VERSION
1894 : : /* Run dependent module initializers before any constructors in this
1895 : : module. */
1896 : : switch (is_ctor_dtor (name))
1897 : : {
1898 : : case SYM_AIXI:
1899 : : case SYM_AIXD:
1900 : : return INT_MIN;
1901 : : default:
1902 : : break;
1903 : : }
1904 : : #endif
1905 : :
1906 : 0 : while (name[pos] == '_')
1907 : 0 : ++pos;
1908 : 0 : pos += 10; /* strlen ("GLOBAL__X_") */
1909 : :
1910 : : /* Extract init_p number from ctor/dtor name. */
1911 : 0 : pri = atoi (name + pos);
1912 : 0 : return pri ? pri : DEFAULT_INIT_PRIORITY;
1913 : : }
1914 : :
1915 : : /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1916 : : ctors will be run from right to left, dtors from left to right. */
1917 : :
1918 : : static void
1919 : 0 : sort_ids (struct head *head_ptr)
1920 : : {
1921 : : /* id holds the current element to insert. id_next holds the next
1922 : : element to insert. id_ptr iterates through the already sorted elements
1923 : : looking for the place to insert id. */
1924 : 0 : struct id *id, *id_next, **id_ptr;
1925 : :
1926 : 0 : id = head_ptr->first;
1927 : :
1928 : : /* We don't have any sorted elements yet. */
1929 : 0 : head_ptr->first = NULL;
1930 : :
1931 : 0 : for (; id; id = id_next)
1932 : : {
1933 : 0 : id_next = id->next;
1934 : 0 : id->sequence = extract_init_priority (id->name);
1935 : :
1936 : 0 : for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1937 : 0 : if (*id_ptr == NULL
1938 : : /* If the sequence numbers are the same, we put the id from the
1939 : : file later on the command line later in the list. */
1940 : 0 : || id->sequence > (*id_ptr)->sequence
1941 : : /* Hack: do lexical compare, too.
1942 : : || (id->sequence == (*id_ptr)->sequence
1943 : : && strcmp (id->name, (*id_ptr)->name) > 0) */
1944 : : )
1945 : : {
1946 : 0 : id->next = *id_ptr;
1947 : 0 : *id_ptr = id;
1948 : 0 : break;
1949 : : }
1950 : : }
1951 : :
1952 : : /* Now set the sequence numbers properly so write_c_file works. */
1953 : 0 : for (id = head_ptr->first; id; id = id->next)
1954 : 0 : id->sequence = ++sequence_number;
1955 : 0 : }
1956 : :
1957 : : /* Write: `prefix', the names on list LIST, `suffix'. */
1958 : :
1959 : : static void
1960 : 0 : write_list (FILE *stream, const char *prefix, struct id *list)
1961 : : {
1962 : 0 : while (list)
1963 : : {
1964 : 0 : fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1965 : 0 : list = list->next;
1966 : : }
1967 : 0 : }
1968 : :
1969 : : #ifdef COLLECT_EXPORT_LIST
1970 : : /* This function is really used only on AIX, but may be useful. */
1971 : : static int
1972 : : is_in_list (const char *prefix, struct id *list)
1973 : : {
1974 : : while (list)
1975 : : {
1976 : : if (!strcmp (prefix, list->name)) return 1;
1977 : : list = list->next;
1978 : : }
1979 : : return 0;
1980 : : }
1981 : : #endif /* COLLECT_EXPORT_LIST */
1982 : :
1983 : : /* Added for debugging purpose. */
1984 : : #ifdef COLLECT_EXPORT_LIST
1985 : : static void
1986 : : dump_list (FILE *stream, const char *prefix, struct id *list)
1987 : : {
1988 : : while (list)
1989 : : {
1990 : : fprintf (stream, "%s%s,\n", prefix, list->name);
1991 : : list = list->next;
1992 : : }
1993 : : }
1994 : : #endif
1995 : :
1996 : : #if 0
1997 : : static void
1998 : : dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
1999 : : {
2000 : : while (list)
2001 : : {
2002 : : fprintf (stream, "%s%s,\n", prefix, list->prefix);
2003 : : list = list->next;
2004 : : }
2005 : : }
2006 : : #endif
2007 : :
2008 : : static void
2009 : 0 : write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
2010 : : {
2011 : 0 : while (list)
2012 : : {
2013 : 0 : fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
2014 : 0 : prefix, list->sequence, list->name);
2015 : 0 : list = list->next;
2016 : : }
2017 : 0 : }
2018 : :
2019 : : /* Write out the constructor and destructor tables statically (for a shared
2020 : : object), along with the functions to execute them. */
2021 : :
2022 : : static void
2023 : 0 : write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
2024 : : {
2025 : 0 : const char *p, *q;
2026 : 0 : char *prefix, *r;
2027 : 0 : int frames = (frame_tables.number > 0);
2028 : :
2029 : : /* Figure out name of output_file, stripping off .so version. */
2030 : 0 : q = p = lbasename (output_file);
2031 : :
2032 : 0 : while (q)
2033 : : {
2034 : 0 : q = strchr (q,'.');
2035 : 0 : if (q == 0)
2036 : : {
2037 : 0 : q = p + strlen (p);
2038 : 0 : break;
2039 : : }
2040 : : else
2041 : : {
2042 : 0 : if (filename_ncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0)
2043 : : {
2044 : 0 : q += strlen (SHLIB_SUFFIX);
2045 : 0 : break;
2046 : : }
2047 : : else
2048 : 0 : q++;
2049 : : }
2050 : : }
2051 : : /* q points to null at end of the string (or . of the .so version) */
2052 : 0 : prefix = XNEWVEC (char, q - p + 1);
2053 : 0 : strncpy (prefix, p, q - p);
2054 : 0 : prefix[q - p] = 0;
2055 : 0 : for (r = prefix; *r; r++)
2056 : 0 : if (!ISALNUM ((unsigned char)*r))
2057 : 0 : *r = '_';
2058 : 0 : if (debug)
2059 : 0 : notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
2060 : : output_file, prefix);
2061 : :
2062 : 0 : initname = concat ("_GLOBAL__FI_", prefix, NULL);
2063 : 0 : fininame = concat ("_GLOBAL__FD_", prefix, NULL);
2064 : : #ifdef TARGET_AIX_VERSION
2065 : : aix_shared_initname = concat ("_GLOBAL__AIXI_", prefix, NULL);
2066 : : aix_shared_fininame = concat ("_GLOBAL__AIXD_", prefix, NULL);
2067 : : #endif
2068 : :
2069 : 0 : free (prefix);
2070 : :
2071 : : /* Write the tables as C code. */
2072 : :
2073 : : /* This count variable is used to prevent multiple calls to the
2074 : : constructors/destructors.
2075 : : This guard against multiple calls is important on AIX as the initfini
2076 : : functions are deliberately invoked multiple times as part of the
2077 : : mechanisms GCC uses to order constructors across different dependent
2078 : : shared libraries (see config/rs6000/aix.h).
2079 : : */
2080 : 0 : fprintf (stream, "static int count;\n");
2081 : 0 : fprintf (stream, "typedef void entry_pt();\n");
2082 : 0 : write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2083 : :
2084 : 0 : if (frames)
2085 : : {
2086 : 0 : write_list_with_asm (stream, "extern void *", frame_tables.first);
2087 : :
2088 : 0 : fprintf (stream, "\tstatic void *frame_table[] = {\n");
2089 : 0 : write_list (stream, "\t\t&", frame_tables.first);
2090 : 0 : fprintf (stream, "\t0\n};\n");
2091 : :
2092 : : /* This must match what's in frame.h. */
2093 : 0 : fprintf (stream, "struct object {\n");
2094 : 0 : fprintf (stream, " void *pc_begin;\n");
2095 : 0 : fprintf (stream, " void *pc_end;\n");
2096 : 0 : fprintf (stream, " void *fde_begin;\n");
2097 : 0 : fprintf (stream, " void *fde_array;\n");
2098 : 0 : fprintf (stream, " __SIZE_TYPE__ count;\n");
2099 : 0 : fprintf (stream, " struct object *next;\n");
2100 : 0 : fprintf (stream, "};\n");
2101 : :
2102 : 0 : fprintf (stream, "extern void __register_frame_info_table_bases (void *, struct object *, void *tbase, void *dbase);\n");
2103 : 0 : fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2104 : 0 : fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2105 : : #ifdef TARGET_AIX_VERSION
2106 : : fprintf (stream, "extern void *__gcc_unwind_dbase;\n");
2107 : : #endif
2108 : :
2109 : 0 : fprintf (stream, "static void reg_frame () {\n");
2110 : 0 : fprintf (stream, "\tstatic struct object ob;\n");
2111 : : #ifdef TARGET_AIX_VERSION
2112 : : /* Use __gcc_unwind_dbase as the base address for data on AIX.
2113 : : This might not be the start of the segment, signed offsets assumed.
2114 : : */
2115 : : fprintf (stream, "\t__register_frame_info_table_bases (frame_table, &ob, (void *)0, &__gcc_unwind_dbase);\n");
2116 : : #else
2117 : 0 : fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2118 : : #endif
2119 : 0 : fprintf (stream, "\t}\n");
2120 : :
2121 : 0 : fprintf (stream, "static void dereg_frame () {\n");
2122 : 0 : fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2123 : 0 : fprintf (stream, "\t}\n");
2124 : : }
2125 : :
2126 : : #ifdef COLLECT_EXPORT_LIST
2127 : : /* Set visibility of initializers to default. */
2128 : : if (visibility_flag)
2129 : : fprintf (stream, "#pragma GCC visibility push(default)\n");
2130 : : #endif
2131 : 0 : fprintf (stream, "void %s() {\n", initname);
2132 : 0 : if (constructors.number > 0 || frames)
2133 : : {
2134 : 0 : fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
2135 : 0 : write_list (stream, "\t\t", constructors.first);
2136 : 0 : if (frames)
2137 : 0 : fprintf (stream, "\treg_frame,\n");
2138 : 0 : fprintf (stream, "\t};\n");
2139 : 0 : fprintf (stream, "\tentry_pt **p;\n");
2140 : 0 : fprintf (stream, "\tif (count++ != 0) return;\n");
2141 : 0 : fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
2142 : 0 : fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
2143 : : }
2144 : : else
2145 : 0 : fprintf (stream, "\t++count;\n");
2146 : 0 : fprintf (stream, "}\n");
2147 : 0 : write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2148 : 0 : fprintf (stream, "void %s() {\n", fininame);
2149 : 0 : if (destructors.number > 0 || frames)
2150 : : {
2151 : 0 : fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
2152 : 0 : write_list (stream, "\t\t", destructors.first);
2153 : 0 : if (frames)
2154 : 0 : fprintf (stream, "\tdereg_frame,\n");
2155 : 0 : fprintf (stream, "\t};\n");
2156 : 0 : fprintf (stream, "\tentry_pt **p;\n");
2157 : 0 : fprintf (stream, "\tif (--count != 0) return;\n");
2158 : 0 : fprintf (stream, "\tp = dtors;\n");
2159 : 0 : fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
2160 : 0 : destructors.number + frames);
2161 : : }
2162 : 0 : fprintf (stream, "}\n");
2163 : : #ifdef COLLECT_EXPORT_LIST
2164 : : if (visibility_flag)
2165 : : fprintf (stream, "#pragma GCC visibility pop\n");
2166 : : #endif
2167 : :
2168 : 0 : if (shared_obj)
2169 : : {
2170 : : #ifdef COLLECT_EXPORT_LIST
2171 : : /* Set visibility of initializers to default. */
2172 : : if (visibility_flag)
2173 : : fprintf (stream, "#pragma GCC visibility push(default)\n");
2174 : : #endif
2175 : 0 : COLLECT_SHARED_INIT_FUNC (stream, initname);
2176 : 0 : COLLECT_SHARED_FINI_FUNC (stream, fininame);
2177 : : #ifdef COLLECT_EXPORT_LIST
2178 : : if (visibility_flag)
2179 : : fprintf (stream, "#pragma GCC visibility pop\n");
2180 : : #endif
2181 : : }
2182 : 0 : }
2183 : :
2184 : : /* Write the constructor/destructor tables. */
2185 : :
2186 : : #ifndef LD_INIT_SWITCH
2187 : : static void
2188 : 0 : write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
2189 : : {
2190 : : /* Write the tables as C code. */
2191 : :
2192 : 0 : int frames = (frame_tables.number > 0);
2193 : :
2194 : 0 : fprintf (stream, "typedef void entry_pt();\n\n");
2195 : :
2196 : 0 : write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2197 : :
2198 : 0 : if (frames)
2199 : : {
2200 : 0 : write_list_with_asm (stream, "extern void *", frame_tables.first);
2201 : :
2202 : 0 : fprintf (stream, "\tstatic void *frame_table[] = {\n");
2203 : 0 : write_list (stream, "\t\t&", frame_tables.first);
2204 : 0 : fprintf (stream, "\t0\n};\n");
2205 : :
2206 : : /* This must match what's in frame.h. */
2207 : 0 : fprintf (stream, "struct object {\n");
2208 : 0 : fprintf (stream, " void *pc_begin;\n");
2209 : 0 : fprintf (stream, " void *pc_end;\n");
2210 : 0 : fprintf (stream, " void *fde_begin;\n");
2211 : 0 : fprintf (stream, " void *fde_array;\n");
2212 : 0 : fprintf (stream, " __SIZE_TYPE__ count;\n");
2213 : 0 : fprintf (stream, " struct object *next;\n");
2214 : 0 : fprintf (stream, "};\n");
2215 : :
2216 : 0 : fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2217 : 0 : fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2218 : :
2219 : 0 : fprintf (stream, "static void reg_frame () {\n");
2220 : 0 : fprintf (stream, "\tstatic struct object ob;\n");
2221 : 0 : fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2222 : 0 : fprintf (stream, "\t}\n");
2223 : :
2224 : 0 : fprintf (stream, "static void dereg_frame () {\n");
2225 : 0 : fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2226 : 0 : fprintf (stream, "\t}\n");
2227 : : }
2228 : :
2229 : 0 : fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2230 : 0 : fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2231 : 0 : write_list (stream, "\t", constructors.first);
2232 : 0 : if (frames)
2233 : 0 : fprintf (stream, "\treg_frame,\n");
2234 : 0 : fprintf (stream, "\t0\n};\n\n");
2235 : :
2236 : 0 : write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2237 : :
2238 : 0 : fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2239 : 0 : fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2240 : 0 : write_list (stream, "\t", destructors.first);
2241 : 0 : if (frames)
2242 : 0 : fprintf (stream, "\tdereg_frame,\n");
2243 : 0 : fprintf (stream, "\t0\n};\n\n");
2244 : :
2245 : 0 : fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2246 : 0 : fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2247 : 0 : }
2248 : : #endif /* ! LD_INIT_SWITCH */
2249 : :
2250 : : static void
2251 : 0 : write_c_file (FILE *stream, const char *name)
2252 : : {
2253 : : #ifndef LD_INIT_SWITCH
2254 : 0 : if (! shared_obj)
2255 : 0 : write_c_file_glob (stream, name);
2256 : : else
2257 : : #endif
2258 : 0 : write_c_file_stat (stream, name);
2259 : 0 : }
2260 : :
2261 : : #ifdef COLLECT_EXPORT_LIST
2262 : : static void
2263 : : write_aix_file (FILE *stream, struct id *list)
2264 : : {
2265 : : for (; list; list = list->next)
2266 : : {
2267 : : fputs (list->name, stream);
2268 : : putc ('\n', stream);
2269 : : }
2270 : : }
2271 : : #endif
2272 : :
2273 : : #ifdef OBJECT_FORMAT_NONE
2274 : :
2275 : : /* Check to make sure the file is an LTO object file. */
2276 : :
2277 : : static int
2278 : 406740 : has_lto_section (void *data, const char *name ATTRIBUTE_UNUSED,
2279 : : off_t offset ATTRIBUTE_UNUSED,
2280 : : off_t length ATTRIBUTE_UNUSED)
2281 : : {
2282 : 406740 : int *found = (int *) data;
2283 : :
2284 : 406740 : if (!startswith (name, LTO_SECTION_NAME_PREFIX)
2285 : 406740 : && !startswith (name, OFFLOAD_SECTION_NAME_PREFIX))
2286 : : return 1;
2287 : :
2288 : 4515 : *found = 1;
2289 : :
2290 : : /* Stop iteration. */
2291 : 4515 : return 0;
2292 : : }
2293 : :
2294 : : static bool
2295 : 25568 : is_lto_object_file (const char *prog_name)
2296 : : {
2297 : 25568 : const char *errmsg;
2298 : 25568 : int err;
2299 : 25568 : int found = 0;
2300 : 25568 : off_t inoff = 0;
2301 : 25568 : int infd = open (prog_name, O_RDONLY | O_BINARY);
2302 : :
2303 : 25568 : if (infd == -1)
2304 : : return false;
2305 : :
2306 : 25568 : simple_object_read *inobj = simple_object_start_read (infd, inoff,
2307 : : LTO_SEGMENT_NAME,
2308 : : &errmsg, &err);
2309 : 25568 : if (!inobj)
2310 : : {
2311 : 0 : close (infd);
2312 : 0 : return false;
2313 : : }
2314 : :
2315 : 25568 : errmsg = simple_object_find_sections (inobj, has_lto_section,
2316 : : (void *) &found, &err);
2317 : 25568 : simple_object_release_read (inobj);
2318 : 25568 : close (infd);
2319 : 25568 : if (! errmsg && found)
2320 : : return true;
2321 : :
2322 : 21053 : if (errmsg)
2323 : 0 : fatal_error (0, "%s: %s", errmsg, xstrerror (err));
2324 : : return false;
2325 : : }
2326 : :
2327 : : /* Generic version to scan the name list of the loaded program for
2328 : : the symbols g++ uses for static constructors and destructors. */
2329 : :
2330 : : static void
2331 : 25568 : scan_prog_file (const char *prog_name, scanpass which_pass,
2332 : : scanfilter filter)
2333 : : {
2334 : 25568 : void (*int_handler) (int);
2335 : : #ifdef SIGQUIT
2336 : 25568 : void (*quit_handler) (int);
2337 : : #endif
2338 : 25568 : char *real_nm_argv[4];
2339 : 25568 : const char **nm_argv = CONST_CAST2 (const char **, char**, real_nm_argv);
2340 : 25568 : int argc = 0;
2341 : 25568 : struct pex_obj *pex;
2342 : 25568 : const char *errmsg;
2343 : 25568 : int err;
2344 : 25568 : char *p, buf[1024];
2345 : 25568 : FILE *inf;
2346 : :
2347 : 25568 : if (which_pass == PASS_SECOND)
2348 : 25568 : return;
2349 : :
2350 : : /* LTO objects must be in a known format. This check prevents
2351 : : us from accepting an archive containing LTO objects, which
2352 : : gcc cannot currently handle. */
2353 : 25568 : if (which_pass == PASS_LTOINFO)
2354 : : {
2355 : 25568 : if(is_lto_object_file (prog_name)) {
2356 : 4515 : add_lto_object (<o_objects, prog_name);
2357 : : }
2358 : 25568 : return;
2359 : : }
2360 : :
2361 : : /* If we do not have an `nm', complain. */
2362 : 0 : if (nm_file_name == 0)
2363 : 0 : fatal_error (input_location, "cannot find %<nm%>");
2364 : :
2365 : 0 : nm_argv[argc++] = nm_file_name;
2366 : 0 : if (NM_FLAGS[0] != '\0')
2367 : 0 : nm_argv[argc++] = NM_FLAGS;
2368 : :
2369 : 0 : nm_argv[argc++] = prog_name;
2370 : 0 : nm_argv[argc++] = (char *) 0;
2371 : :
2372 : : /* Trace if needed. */
2373 : 0 : if (verbose)
2374 : : {
2375 : : const char **p_argv;
2376 : : const char *str;
2377 : :
2378 : 0 : for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2379 : 0 : fprintf (stderr, " %s", str);
2380 : :
2381 : 0 : fprintf (stderr, "\n");
2382 : : }
2383 : :
2384 : 0 : fflush (stdout);
2385 : 0 : fflush (stderr);
2386 : :
2387 : 0 : pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2388 : 0 : if (pex == NULL)
2389 : : fatal_error (input_location, "%<pex_init%> failed: %m");
2390 : :
2391 : 0 : errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, HOST_BIT_BUCKET,
2392 : : &err);
2393 : 0 : if (errmsg != NULL)
2394 : : {
2395 : 0 : if (err != 0)
2396 : : {
2397 : 0 : errno = err;
2398 : 0 : fatal_error (input_location, "%s: %m", _(errmsg));
2399 : : }
2400 : : else
2401 : 0 : fatal_error (input_location, errmsg);
2402 : : }
2403 : :
2404 : 0 : int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
2405 : : #ifdef SIGQUIT
2406 : 0 : quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2407 : : #endif
2408 : :
2409 : 0 : inf = pex_read_output (pex, 0);
2410 : 0 : if (inf == NULL)
2411 : 0 : fatal_error (input_location, "cannot open nm output: %m");
2412 : :
2413 : 0 : if (debug)
2414 : 0 : fprintf (stderr, "\nnm output with constructors/destructors.\n");
2415 : :
2416 : : /* Read each line of nm output. */
2417 : 0 : while (fgets (buf, sizeof buf, inf) != (char *) 0)
2418 : : {
2419 : 0 : int ch, ch2;
2420 : 0 : char *name, *end;
2421 : :
2422 : 0 : if (debug)
2423 : 0 : fprintf (stderr, "\t%s\n", buf);
2424 : :
2425 : : /* If it contains a constructor or destructor name, add the name
2426 : : to the appropriate list unless this is a kind of symbol we're
2427 : : not supposed to even consider. */
2428 : :
2429 : 0 : for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2430 : 0 : if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2431 : : break;
2432 : :
2433 : 0 : if (ch != '_')
2434 : 0 : continue;
2435 : :
2436 : : name = p;
2437 : : /* Find the end of the symbol name.
2438 : : Do not include `|', because Encore nm can tack that on the end. */
2439 : 0 : for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2440 : : end++)
2441 : 0 : continue;
2442 : :
2443 : :
2444 : 0 : *end = '\0';
2445 : :
2446 : 0 : switch (is_ctor_dtor (name))
2447 : : {
2448 : 0 : case SYM_CTOR:
2449 : 0 : if (! (filter & SCAN_CTOR))
2450 : : break;
2451 : 0 : if (which_pass != PASS_LIB)
2452 : 0 : add_to_list (&constructors, name);
2453 : : break;
2454 : :
2455 : 0 : case SYM_DTOR:
2456 : 0 : if (! (filter & SCAN_DTOR))
2457 : : break;
2458 : 0 : if (which_pass != PASS_LIB)
2459 : 0 : add_to_list (&destructors, name);
2460 : : break;
2461 : :
2462 : 0 : case SYM_INIT:
2463 : 0 : if (! (filter & SCAN_INIT))
2464 : : break;
2465 : 0 : if (which_pass != PASS_LIB)
2466 : 0 : fatal_error (input_location, "init function found in object %s",
2467 : : prog_name);
2468 : : #ifndef LD_INIT_SWITCH
2469 : 0 : add_to_list (&constructors, name);
2470 : : #endif
2471 : 0 : break;
2472 : :
2473 : 0 : case SYM_FINI:
2474 : 0 : if (! (filter & SCAN_FINI))
2475 : : break;
2476 : 0 : if (which_pass != PASS_LIB)
2477 : 0 : fatal_error (input_location, "fini function found in object %s",
2478 : : prog_name);
2479 : : #ifndef LD_FINI_SWITCH
2480 : 0 : add_to_list (&destructors, name);
2481 : : #endif
2482 : 0 : break;
2483 : :
2484 : 0 : case SYM_DWEH:
2485 : 0 : if (! (filter & SCAN_DWEH))
2486 : : break;
2487 : 0 : if (which_pass != PASS_LIB)
2488 : 0 : add_to_list (&frame_tables, name);
2489 : : break;
2490 : :
2491 : 0 : default: /* not a constructor or destructor */
2492 : 0 : continue;
2493 : : }
2494 : 0 : }
2495 : :
2496 : 0 : if (debug)
2497 : 0 : fprintf (stderr, "\n");
2498 : :
2499 : 0 : do_wait (nm_file_name, pex);
2500 : :
2501 : 0 : signal (SIGINT, int_handler);
2502 : : #ifdef SIGQUIT
2503 : 0 : signal (SIGQUIT, quit_handler);
2504 : : #endif
2505 : : }
2506 : :
2507 : : #ifdef LDD_SUFFIX
2508 : :
2509 : : /* Use the List Dynamic Dependencies program to find shared libraries that
2510 : : the output file depends upon and their initialization/finalization
2511 : : routines, if any. */
2512 : :
2513 : : static void
2514 : : scan_libraries (const char *prog_name)
2515 : : {
2516 : : static struct head libraries; /* list of shared libraries found */
2517 : : struct id *list;
2518 : : void (*int_handler) (int);
2519 : : #ifdef SIGQUIT
2520 : : void (*quit_handler) (int);
2521 : : #endif
2522 : : char *real_ldd_argv[4];
2523 : : const char **ldd_argv = CONST_CAST2 (const char **, char **, real_ldd_argv);
2524 : : int argc = 0;
2525 : : struct pex_obj *pex;
2526 : : const char *errmsg;
2527 : : int err;
2528 : : char buf[1024];
2529 : : FILE *inf;
2530 : :
2531 : : /* If we do not have an `ldd', complain. */
2532 : : if (ldd_file_name == 0)
2533 : : {
2534 : : error ("cannot find %<ldd%>");
2535 : : return;
2536 : : }
2537 : :
2538 : : ldd_argv[argc++] = ldd_file_name;
2539 : : ldd_argv[argc++] = prog_name;
2540 : : ldd_argv[argc++] = (char *) 0;
2541 : :
2542 : : /* Trace if needed. */
2543 : : if (verbose)
2544 : : {
2545 : : const char **p_argv;
2546 : : const char *str;
2547 : :
2548 : : for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2549 : : fprintf (stderr, " %s", str);
2550 : :
2551 : : fprintf (stderr, "\n");
2552 : : }
2553 : :
2554 : : fflush (stdout);
2555 : : fflush (stderr);
2556 : :
2557 : : pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2558 : : if (pex == NULL)
2559 : : fatal_error (input_location, "%<pex_init%> failed: %m");
2560 : :
2561 : : errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err);
2562 : : if (errmsg != NULL)
2563 : : {
2564 : : if (err != 0)
2565 : : {
2566 : : errno = err;
2567 : : fatal_error (input_location, "%s: %m", _(errmsg));
2568 : : }
2569 : : else
2570 : : fatal_error (input_location, errmsg);
2571 : : }
2572 : :
2573 : : int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
2574 : : #ifdef SIGQUIT
2575 : : quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2576 : : #endif
2577 : :
2578 : : inf = pex_read_output (pex, 0);
2579 : : if (inf == NULL)
2580 : : fatal_error (input_location, "cannot open ldd output: %m");
2581 : :
2582 : : if (debug)
2583 : : notice ("\nldd output with constructors/destructors.\n");
2584 : :
2585 : : /* Read each line of ldd output. */
2586 : : while (fgets (buf, sizeof buf, inf) != (char *) 0)
2587 : : {
2588 : : int ch2;
2589 : : char *name, *end, *p = buf;
2590 : :
2591 : : /* Extract names of libraries and add to list. */
2592 : : PARSE_LDD_OUTPUT (p);
2593 : : if (p == 0)
2594 : : continue;
2595 : :
2596 : : name = p;
2597 : : if (startswith (name, "not found"))
2598 : : fatal_error (input_location, "dynamic dependency %s not found", buf);
2599 : :
2600 : : /* Find the end of the symbol name. */
2601 : : for (end = p;
2602 : : (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2603 : : end++)
2604 : : continue;
2605 : : *end = '\0';
2606 : :
2607 : : if (access (name, R_OK) == 0)
2608 : : add_to_list (&libraries, name);
2609 : : else
2610 : : fatal_error (input_location, "unable to open dynamic dependency "
2611 : : "%qs", buf);
2612 : :
2613 : : if (debug)
2614 : : fprintf (stderr, "\t%s\n", buf);
2615 : : }
2616 : : if (debug)
2617 : : fprintf (stderr, "\n");
2618 : :
2619 : : do_wait (ldd_file_name, pex);
2620 : :
2621 : : signal (SIGINT, int_handler);
2622 : : #ifdef SIGQUIT
2623 : : signal (SIGQUIT, quit_handler);
2624 : : #endif
2625 : :
2626 : : /* Now iterate through the library list adding their symbols to
2627 : : the list. */
2628 : : for (list = libraries.first; list; list = list->next)
2629 : : scan_prog_file (list->name, PASS_LIB, SCAN_ALL);
2630 : : }
2631 : :
2632 : : #endif /* LDD_SUFFIX */
2633 : :
2634 : : #endif /* OBJECT_FORMAT_NONE */
2635 : :
2636 : :
2637 : : /*
2638 : : * COFF specific stuff.
2639 : : */
2640 : :
2641 : : #ifdef OBJECT_FORMAT_COFF
2642 : :
2643 : : # define GCC_SYMBOLS(X) (HEADER (ldptr).f_nsyms)
2644 : : # define GCC_SYMENT SYMENT
2645 : : # if defined (C_WEAKEXT)
2646 : : # define GCC_OK_SYMBOL(X) \
2647 : : (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2648 : : ((X).n_scnum > N_UNDEF) && \
2649 : : (aix64_flag \
2650 : : || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2651 : : || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2652 : : # define GCC_UNDEF_SYMBOL(X) \
2653 : : (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2654 : : ((X).n_scnum == N_UNDEF))
2655 : : # else
2656 : : # define GCC_OK_SYMBOL(X) \
2657 : : (((X).n_sclass == C_EXT) && \
2658 : : ((X).n_scnum > N_UNDEF) && \
2659 : : (aix64_flag \
2660 : : || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2661 : : || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2662 : : # define GCC_UNDEF_SYMBOL(X) \
2663 : : (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2664 : : # endif
2665 : : # define GCC_SYMINC(X) ((X).n_numaux+1)
2666 : : # define GCC_SYMZERO(X) 0
2667 : :
2668 : : /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2669 : : #if TARGET_AIX_VERSION >= 51
2670 : : # define GCC_CHECK_HDR(X) \
2671 : : (((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2672 : : || (HEADER (X).f_magic == 0767 && aix64_flag)) \
2673 : : && !(HEADER (X).f_flags & F_LOADONLY))
2674 : : #else
2675 : : # define GCC_CHECK_HDR(X) \
2676 : : (((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2677 : : || (HEADER (X).f_magic == 0757 && aix64_flag)) \
2678 : : && !(HEADER (X).f_flags & F_LOADONLY))
2679 : : #endif
2680 : :
2681 : : #ifdef COLLECT_EXPORT_LIST
2682 : : /* Array of standard AIX libraries which should not
2683 : : be scanned for ctors/dtors. */
2684 : : static const char *const aix_std_libs[] = {
2685 : : "/unix",
2686 : : "/lib/libc.a",
2687 : : "/lib/libm.a",
2688 : : "/lib/libc_r.a",
2689 : : "/lib/libm_r.a",
2690 : : "/usr/lib/libc.a",
2691 : : "/usr/lib/libm.a",
2692 : : "/usr/lib/libc_r.a",
2693 : : "/usr/lib/libm_r.a",
2694 : : "/usr/lib/threads/libc.a",
2695 : : "/usr/ccs/lib/libc.a",
2696 : : "/usr/ccs/lib/libm.a",
2697 : : "/usr/ccs/lib/libc_r.a",
2698 : : "/usr/ccs/lib/libm_r.a",
2699 : : NULL
2700 : : };
2701 : :
2702 : : /* This function checks the filename and returns 1
2703 : : if this name matches the location of a standard AIX library. */
2704 : : static int ignore_library (const char *);
2705 : : static int
2706 : : ignore_library (const char *name)
2707 : : {
2708 : : const char *const *p;
2709 : : size_t length;
2710 : :
2711 : : if (target_system_root[0] != '\0')
2712 : : {
2713 : : length = strlen (target_system_root);
2714 : : if (strncmp (name, target_system_root, length) != 0)
2715 : : return 0;
2716 : : name += length;
2717 : : }
2718 : : for (p = &aix_std_libs[0]; *p != NULL; ++p)
2719 : : if (strcmp (name, *p) == 0)
2720 : : return 1;
2721 : : return 0;
2722 : : }
2723 : : #endif /* COLLECT_EXPORT_LIST */
2724 : :
2725 : : #if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2726 : : extern char *ldgetname (LDFILE *, GCC_SYMENT *);
2727 : : #endif
2728 : :
2729 : : /* COFF version to scan the name list of the loaded program for
2730 : : the symbols g++ uses for static constructors and destructors. */
2731 : :
2732 : : static void
2733 : : scan_prog_file (const char *prog_name, scanpass which_pass,
2734 : : scanfilter filter)
2735 : : {
2736 : : LDFILE *ldptr = NULL;
2737 : : int sym_index, sym_count;
2738 : : int is_shared = 0;
2739 : :
2740 : : if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2741 : : return;
2742 : :
2743 : : #ifdef COLLECT_EXPORT_LIST
2744 : : /* We do not need scanning for some standard C libraries. */
2745 : : if (which_pass == PASS_FIRST && ignore_library (prog_name))
2746 : : return;
2747 : :
2748 : : /* On AIX we have a loop, because there is not much difference
2749 : : between an object and an archive. This trick allows us to
2750 : : eliminate scan_libraries() function. */
2751 : : do
2752 : : {
2753 : : #endif
2754 : : /* Some platforms (e.g. OSF4) declare ldopen as taking a
2755 : : non-const char * filename parameter, even though it will not
2756 : : modify that string. So we must cast away const-ness here,
2757 : : using CONST_CAST to prevent complaints from -Wcast-qual. */
2758 : : if ((ldptr = ldopen (CONST_CAST (char *, prog_name), ldptr)) != NULL)
2759 : : {
2760 : : if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2761 : : {
2762 : : warning (0, "%s: not a COFF file", prog_name);
2763 : : continue;
2764 : : }
2765 : :
2766 : : if (GCC_CHECK_HDR (ldptr))
2767 : : {
2768 : : sym_count = GCC_SYMBOLS (ldptr);
2769 : : sym_index = GCC_SYMZERO (ldptr);
2770 : :
2771 : : #ifdef COLLECT_EXPORT_LIST
2772 : : /* Is current archive member a shared object? */
2773 : : is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2774 : : #endif
2775 : :
2776 : : while (sym_index < sym_count)
2777 : : {
2778 : : GCC_SYMENT symbol;
2779 : :
2780 : : if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2781 : : break;
2782 : : sym_index += GCC_SYMINC (symbol);
2783 : :
2784 : : if (GCC_OK_SYMBOL (symbol))
2785 : : {
2786 : : char *name;
2787 : :
2788 : : if ((name = ldgetname (ldptr, &symbol)) == NULL)
2789 : : continue; /* Should never happen. */
2790 : :
2791 : : #ifdef XCOFF_DEBUGGING_INFO
2792 : : /* All AIX function names have a duplicate entry
2793 : : beginning with a dot. */
2794 : : if (*name == '.')
2795 : : ++name;
2796 : : #endif
2797 : :
2798 : : switch (is_ctor_dtor (name))
2799 : : {
2800 : : #if TARGET_AIX_VERSION
2801 : : /* Add AIX shared library initalisers/finalisers
2802 : : to the constructors/destructors list of the
2803 : : current module. */
2804 : : case SYM_AIXI:
2805 : : if (! (filter & SCAN_CTOR))
2806 : : break;
2807 : : if (is_shared && !aixlazy_flag
2808 : : #ifdef COLLECT_EXPORT_LIST
2809 : : && ! static_obj
2810 : : && ! is_in_list (prog_name, static_libs.first)
2811 : : #endif
2812 : : )
2813 : : add_to_list (&constructors, name);
2814 : : break;
2815 : :
2816 : : case SYM_AIXD:
2817 : : if (! (filter & SCAN_DTOR))
2818 : : break;
2819 : : if (is_shared && !aixlazy_flag)
2820 : : add_to_list (&destructors, name);
2821 : : break;
2822 : : #endif
2823 : :
2824 : : case SYM_CTOR:
2825 : : if (! (filter & SCAN_CTOR))
2826 : : break;
2827 : : if (! is_shared)
2828 : : add_to_list (&constructors, name);
2829 : : #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2830 : : if (which_pass == PASS_OBJ)
2831 : : add_to_list (&exports, name);
2832 : : #endif
2833 : : break;
2834 : :
2835 : : case SYM_DTOR:
2836 : : if (! (filter & SCAN_DTOR))
2837 : : break;
2838 : : if (! is_shared)
2839 : : add_to_list (&destructors, name);
2840 : : #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2841 : : if (which_pass == PASS_OBJ)
2842 : : add_to_list (&exports, name);
2843 : : #endif
2844 : : break;
2845 : :
2846 : : #ifdef COLLECT_EXPORT_LIST
2847 : : case SYM_INIT:
2848 : : if (! (filter & SCAN_INIT))
2849 : : break;
2850 : : #ifndef LD_INIT_SWITCH
2851 : : if (is_shared)
2852 : : add_to_list (&constructors, name);
2853 : : #endif
2854 : : break;
2855 : :
2856 : : case SYM_FINI:
2857 : : if (! (filter & SCAN_FINI))
2858 : : break;
2859 : : #ifndef LD_INIT_SWITCH
2860 : : if (is_shared)
2861 : : add_to_list (&destructors, name);
2862 : : #endif
2863 : : break;
2864 : : #endif
2865 : :
2866 : : case SYM_DWEH:
2867 : : if (! (filter & SCAN_DWEH))
2868 : : break;
2869 : : if (! is_shared)
2870 : : add_to_list (&frame_tables, name);
2871 : : #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2872 : : if (which_pass == PASS_OBJ)
2873 : : add_to_list (&exports, name);
2874 : : #endif
2875 : : break;
2876 : :
2877 : : default: /* not a constructor or destructor */
2878 : : #ifdef COLLECT_EXPORT_LIST
2879 : : /* Explicitly export all global symbols when
2880 : : building a shared object on AIX, but do not
2881 : : re-export symbols from another shared object
2882 : : and do not export symbols if the user
2883 : : provides an explicit export list. */
2884 : : if (shared_obj && !is_shared
2885 : : && which_pass == PASS_OBJ && !export_flag)
2886 : : {
2887 : : /* Do not auto-export __dso_handle or
2888 : : __gcc_unwind_dbase. They are required
2889 : : to be local to each module. */
2890 : : if (strcmp(name, "__dso_handle") != 0
2891 : : && strcmp(name, "__gcc_unwind_dbase") != 0)
2892 : : {
2893 : : add_to_list (&exports, name);
2894 : : }
2895 : : }
2896 : : #endif
2897 : : continue;
2898 : : }
2899 : :
2900 : : if (debug)
2901 : : fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2902 : : symbol.n_scnum, symbol.n_sclass,
2903 : : (symbol.n_type ? "0" : ""), symbol.n_type,
2904 : : name);
2905 : : }
2906 : : }
2907 : : }
2908 : : #ifdef COLLECT_EXPORT_LIST
2909 : : else
2910 : : {
2911 : : /* If archive contains both 32-bit and 64-bit objects,
2912 : : we want to skip objects in other mode so mismatch normal. */
2913 : : if (debug)
2914 : : fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2915 : : prog_name, HEADER (ldptr).f_magic, aix64_flag);
2916 : : }
2917 : : #endif
2918 : : }
2919 : : else
2920 : : {
2921 : : fatal_error (input_location, "%s: cannot open as COFF file",
2922 : : prog_name);
2923 : : }
2924 : : #ifdef COLLECT_EXPORT_LIST
2925 : : /* On AIX loop continues while there are more members in archive. */
2926 : : }
2927 : : while (ldclose (ldptr) == FAILURE);
2928 : : #else
2929 : : /* Otherwise we simply close ldptr. */
2930 : : (void) ldclose (ldptr);
2931 : : #endif
2932 : : }
2933 : : #endif /* OBJECT_FORMAT_COFF */
2934 : :
2935 : : #ifdef COLLECT_EXPORT_LIST
2936 : : /* Given a library name without "lib" prefix, this function
2937 : : returns a full library name including a path. */
2938 : : static char *
2939 : : resolve_lib_name (const char *name)
2940 : : {
2941 : : char *lib_buf;
2942 : : int i, j, l = 0;
2943 : : /* Library extensions for AIX dynamic linking. */
2944 : : const char * const libexts[2] = {"a", "so"};
2945 : :
2946 : : for (i = 0; libpaths[i]; i++)
2947 : : if (libpaths[i]->max_len > l)
2948 : : l = libpaths[i]->max_len;
2949 : :
2950 : : lib_buf = XNEWVEC (char, l + strlen (name) + 10);
2951 : :
2952 : : for (i = 0; libpaths[i]; i++)
2953 : : {
2954 : : struct prefix_list *list = libpaths[i]->plist;
2955 : : for (; list; list = list->next)
2956 : : {
2957 : : /* The following lines are needed because path_prefix list
2958 : : may contain directories both with trailing DIR_SEPARATOR and
2959 : : without it. */
2960 : : const char *p = "";
2961 : : if (!IS_DIR_SEPARATOR (list->prefix[strlen (list->prefix)-1]))
2962 : : p = "/";
2963 : : for (j = 0; j < 2; j++)
2964 : : {
2965 : : sprintf (lib_buf, "%s%slib%s.%s",
2966 : : list->prefix, p, name,
2967 : : libexts[(j + aixrtl_flag) % 2]);
2968 : : if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2969 : : if (file_exists (lib_buf))
2970 : : {
2971 : : if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2972 : : return (lib_buf);
2973 : : }
2974 : : }
2975 : : }
2976 : : }
2977 : : if (debug)
2978 : : fprintf (stderr, "not found\n");
2979 : : else
2980 : : fatal_error (input_location, "library lib%s not found", name);
2981 : : return (NULL);
2982 : : }
2983 : : #endif /* COLLECT_EXPORT_LIST */
2984 : :
2985 : : #ifdef COLLECT_RUN_DSYMUTIL
2986 : : static int flag_dsym = false;
2987 : : static int flag_idsym = false;
2988 : :
2989 : : static void
2990 : : process_args (int *argcp, char **argv) {
2991 : : int i, j;
2992 : : int argc = *argcp;
2993 : : for (i=0; i<argc; ++i)
2994 : : {
2995 : : if (strcmp (argv[i], "-dsym") == 0)
2996 : : {
2997 : : flag_dsym = true;
2998 : : /* Remove the flag, as we handle all processing for it. */
2999 : : j = i;
3000 : : do
3001 : : argv[j] = argv[j+1];
3002 : : while (++j < argc);
3003 : : --i;
3004 : : argc = --(*argcp);
3005 : : }
3006 : : else if (strcmp (argv[i], "-idsym") == 0)
3007 : : {
3008 : : flag_idsym = true;
3009 : : /* Remove the flag, as we handle all processing for it. */
3010 : : j = i;
3011 : : do
3012 : : argv[j] = argv[j+1];
3013 : : while (++j < argc);
3014 : : --i;
3015 : : argc = --(*argcp);
3016 : : }
3017 : : }
3018 : : }
3019 : :
3020 : : static void
3021 : : do_dsymutil (const char *output_file) {
3022 : : const char *dsymutil = 0;
3023 : : struct pex_obj *pex;
3024 : : char **real_argv = XCNEWVEC (char *, verbose ? 4 : 3);
3025 : : const char ** argv = CONST_CAST2 (const char **, char **,
3026 : : real_argv);
3027 : : /* For cross-builds search the PATH using target-qualified name if we
3028 : : have not already found a suitable dsymutil. In practice, all modern
3029 : : versions of dsymutil handle all supported archs, however the approach
3030 : : here is consistent with the way other installations work (and one can
3031 : : always symlink a multitarget dsymutil with a target-specific name). */
3032 : : const char *dsname = "dsymutil";
3033 : : #ifdef CROSS_DIRECTORY_STRUCTURE
3034 : : const char *qname = concat (target_machine, "-", dsname, NULL);
3035 : : #else
3036 : : const char *qname = dsname;
3037 : : #endif
3038 : : #ifdef DEFAULT_DSYMUTIL
3039 : : /* Configured default takes priority. */
3040 : : if (dsymutil == 0 && access (DEFAULT_DSYMUTIL, X_OK) == 0)
3041 : : dsymutil = DEFAULT_DSYMUTIL;
3042 : : if (dsymutil == 0)
3043 : : #endif
3044 : : #ifdef DSYMUTIL
3045 : : /* Followed by one supplied in the target header, somewhat like the
3046 : : REAL_XX_NAME used elsewhere. */
3047 : : dsymutil = find_a_file (&cpath, DSYMUTIL, X_OK);
3048 : : if (dsymutil == 0)
3049 : : dsymutil = find_a_file (&path, DSYMUTIL, X_OK);
3050 : : if (dsymutil == 0)
3051 : : #endif
3052 : : dsymutil = find_a_file (&cpath, dsname, X_OK);
3053 : : if (dsymutil == 0)
3054 : : dsymutil = find_a_file (&path, qname, X_OK);
3055 : :
3056 : : argv[0] = dsymutil;
3057 : : argv[1] = output_file;
3058 : : if (verbose)
3059 : : {
3060 : : argv[2] = "-v";
3061 : : argv[3] = (char *) 0;
3062 : : }
3063 : : else
3064 : : argv[2] = (char *) 0;
3065 : :
3066 : : pex = collect_execute (dsymutil, real_argv, NULL, NULL,
3067 : : PEX_LAST | PEX_SEARCH, false, NULL);
3068 : : do_wait (dsymutil, pex);
3069 : : }
3070 : :
3071 : : static void
3072 : : post_ld_pass (bool temp_file) {
3073 : : if (!(temp_file && flag_idsym) && !flag_dsym)
3074 : : return;
3075 : :
3076 : : do_dsymutil (output_file);
3077 : : }
3078 : : #else
3079 : : static void
3080 : 0 : process_args (int *argcp ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { }
3081 : 0 : static void post_ld_pass (bool temp_file ATTRIBUTE_UNUSED) { }
3082 : : #endif
|