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