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