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 93805 : tool_cleanup (bool from_signal)
384 : {
385 : /* maybe_unlink may call notice, which is not signal safe. */
386 93805 : if (from_signal)
387 0 : verbose = false;
388 :
389 93805 : if (c_file != 0 && c_file[0])
390 93805 : maybe_unlink (c_file);
391 :
392 93805 : if (o_file != 0 && o_file[0])
393 93805 : 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 93805 : if (lto_o_files)
401 4356 : maybe_unlink_list (lto_o_files);
402 93805 : }
403 :
404 : static void
405 93805 : collect_atexit (void)
406 : {
407 93805 : tool_cleanup (false);
408 93805 : }
409 :
410 : /* Notify user of a non-error, without translating the format string. */
411 : void
412 0 : notice_translated (const char *cmsgid, ...)
413 : {
414 0 : va_list ap;
415 :
416 0 : va_start (ap, cmsgid);
417 0 : vfprintf (stderr, cmsgid, ap);
418 0 : va_end (ap);
419 0 : }
420 :
421 : int
422 508 : file_exists (const char *name)
423 : {
424 508 : return access (name, R_OK) == 0;
425 : }
426 :
427 : /* Parse a reasonable subset of shell quoting syntax. */
428 :
429 : static char *
430 5564908 : extract_string (const char **pp)
431 : {
432 5564908 : const char *p = *pp;
433 5564908 : int backquote = 0;
434 5564908 : int inside = 0;
435 :
436 170360604 : for (;;)
437 : {
438 170360604 : char c = *p;
439 170360604 : if (c == '\0')
440 : break;
441 170172994 : ++p;
442 170172994 : if (backquote)
443 0 : obstack_1grow (&temporary_obstack, c);
444 170172994 : else if (! inside && c == ' ')
445 : break;
446 164795696 : else if (! inside && c == '\\')
447 : backquote = 1;
448 164795696 : else if (c == '\'')
449 11122484 : inside = !inside;
450 : else
451 153673212 : obstack_1grow (&temporary_obstack, c);
452 : }
453 :
454 5564908 : obstack_1grow (&temporary_obstack, '\0');
455 5564908 : *pp = p;
456 5564908 : 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 4673 : add_lto_object (struct lto_object_list *list, const char *name)
536 : {
537 4673 : struct lto_object *n = XNEW (struct lto_object);
538 4673 : n->name = name;
539 4673 : n->next = NULL;
540 :
541 4673 : if (list->last)
542 317 : list->last->next = n;
543 : else
544 4356 : list->first = n;
545 :
546 4673 : list->last = n;
547 4673 : }
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 4356 : maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
580 : const char **object, bool force)
581 : {
582 4356 : const char **object_file = const_cast<const char **> (object_lst);
583 :
584 4356 : int num_lto_c_args = 1; /* Allow space for the terminating NULL. */
585 :
586 30866 : while (object_file < object)
587 : {
588 : /* If file contains LTO info, add it to the list of LTO objects. */
589 26510 : 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 26510 : num_lto_c_args++;
595 : }
596 :
597 4356 : if (lto_objects.first)
598 : {
599 4356 : char **lto_c_argv;
600 4356 : const char **lto_c_ptr;
601 4356 : char **p;
602 4356 : char **lto_o_ptr;
603 4356 : struct lto_object *list;
604 4356 : char *lto_wrapper = getenv ("COLLECT_LTO_WRAPPER");
605 4356 : struct pex_obj *pex;
606 4356 : const char *prog = "lto-wrapper";
607 4356 : int lto_ld_argv_size = 0;
608 4356 : char **out_lto_ld_argv;
609 4356 : int out_lto_ld_argv_size;
610 4356 : size_t num_files;
611 :
612 4356 : if (!lto_wrapper)
613 0 : fatal_error (input_location, "environment variable "
614 : "%<COLLECT_LTO_WRAPPER%> must be set");
615 :
616 4356 : 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 4356 : lto_c_argv = (char **) xcalloc (num_lto_c_args, sizeof (char *));
626 4356 : lto_c_ptr = const_cast<const char **> (lto_c_argv);
627 :
628 4356 : *lto_c_ptr++ = lto_wrapper;
629 :
630 : /* Add LTO objects to the wrapper command line. */
631 9029 : for (list = lto_objects.first; list; list = list->next)
632 4673 : *lto_c_ptr++ = list->name;
633 :
634 4356 : *lto_c_ptr = NULL;
635 :
636 : /* Run the LTO back end. */
637 4356 : pex = collect_execute (prog, lto_c_argv, NULL, NULL, PEX_SEARCH,
638 : at_file_supplied, "lto_args");
639 4356 : {
640 4356 : int c;
641 4356 : FILE *stream;
642 4356 : size_t i;
643 4356 : char *start, *end;
644 :
645 4356 : stream = pex_read_output (pex, 0);
646 4356 : gcc_assert (stream);
647 :
648 : num_files = 0;
649 106350 : while ((c = getc (stream)) != EOF)
650 : {
651 101994 : obstack_1grow (&temporary_obstack, c);
652 101994 : if (c == '\n')
653 4778 : ++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 4356 : lto_o_files = XCNEWVEC (char *, num_files + 1);
660 4356 : lto_o_files[num_files] = NULL;
661 4356 : start = XOBFINISH (&temporary_obstack, char *);
662 9134 : for (i = 0; i < num_files; ++i)
663 : {
664 : end = start;
665 101994 : while (*end != '\n')
666 97216 : ++end;
667 4778 : *end = '\0';
668 :
669 4778 : lto_o_files[i] = xstrdup (start);
670 :
671 4778 : start = end + 1;
672 : }
673 :
674 4356 : obstack_free (&temporary_obstack, temporary_firstobj);
675 : }
676 4356 : do_wait (prog, pex);
677 4356 : pex = NULL;
678 :
679 : /* Compute memory needed for new LD arguments. At most number of original arguments
680 : plus number of partitions. */
681 137074 : for (lto_ld_argv_size = 0; lto_ld_argv[lto_ld_argv_size]; lto_ld_argv_size++)
682 : ;
683 4356 : out_lto_ld_argv = XCNEWVEC (char *, num_files + lto_ld_argv_size + 1);
684 4356 : 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 4356 : p = lto_ld_argv;
692 92554 : while (*p != NULL)
693 : {
694 178190 : for (list = lto_objects.first; list; list = list->next)
695 94348 : if (*p == list->name) /* Note test for pointer equality! */
696 : break;
697 83842 : if (list)
698 : break;
699 83842 : out_lto_ld_argv[out_lto_ld_argv_size++] = *p++;
700 : }
701 :
702 : /* Now insert all LTO partitions. */
703 4356 : lto_o_ptr = lto_o_files;
704 9134 : while (*lto_o_ptr)
705 4778 : out_lto_ld_argv[out_lto_ld_argv_size++] = *lto_o_ptr++;
706 :
707 : /* ... and copy the rest. */
708 48876 : while (*p != NULL)
709 : {
710 87571 : for (list = lto_objects.first; list; list = list->next)
711 47724 : if (*p == list->name) /* Note test for pointer equality! */
712 : break;
713 44520 : if (!list)
714 39847 : out_lto_ld_argv[out_lto_ld_argv_size++] = *p;
715 44520 : p++;
716 : }
717 4356 : 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 4356 : fork_execute ("ld", out_lto_ld_argv, HAVE_GNU_LD && at_file_supplied,
722 : "ld_args");
723 : /* We assume that temp files were created, and therefore we need to take
724 : that into account (maybe run dsymutil). */
725 4356 : post_ld_pass (/*temp_file*/true);
726 4356 : free (lto_ld_argv);
727 :
728 4356 : maybe_unlink_list (lto_o_files);
729 : }
730 0 : else if (force)
731 : {
732 : /* Our caller is relying on us to do the link
733 : even though there is no LTO back end work to be done. */
734 0 : fork_execute ("ld", lto_ld_argv, HAVE_GNU_LD && at_file_supplied,
735 : "ld_args");
736 : /* No LTO objects were found, so no new temp file. */
737 0 : post_ld_pass (/*temp_file*/false);
738 : }
739 : else
740 : post_ld_pass (false); /* No LTO objects were found, no temp file. */
741 4356 : }
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 93805 : do_link (char **ld_argv, const char *atsuffix)
747 : {
748 93805 : struct pex_obj *pex;
749 93805 : const char *prog = "ld";
750 93805 : pex = collect_execute (prog, ld_argv, NULL, NULL,
751 : PEX_LAST | PEX_SEARCH,
752 : HAVE_GNU_LD && at_file_supplied, atsuffix);
753 93805 : int ret = collect_wait (prog, pex);
754 93805 : 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 93674 : may_unlink_output_file = true;
764 : }
765 93674 : }
766 :
767 : /* Main program. */
768 :
769 : int
770 93805 : main (int argc, char **argv)
771 : {
772 93805 : 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 93805 : } selected_linker = USE_DEFAULT_LD;
783 93805 : 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 93805 : static const char *const real_ld_suffix = "real-ld";
794 93805 : static const char *const collect_ld_suffix = "collect-ld";
795 93805 : static const char *const nm_suffix = "nm";
796 93805 : static const char *const gnm_suffix = "gnm";
797 : #ifdef LDD_SUFFIX
798 : static const char *const ldd_suffix = LDD_SUFFIX;
799 : #endif
800 93805 : static const char *const strip_suffix = "strip";
801 93805 : static const char *const gstrip_suffix = "gstrip";
802 :
803 93805 : 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 93805 : const char *const full_nm_suffix = nm_suffix;
827 93805 : const char *const full_gnm_suffix = gnm_suffix;
828 93805 : const char *const full_strip_suffix = strip_suffix;
829 93805 : const char *const full_gstrip_suffix = gstrip_suffix;
830 : #endif /* CROSS_DIRECTORY_STRUCTURE */
831 :
832 93805 : const char *arg;
833 93805 : FILE *outf;
834 : #ifdef COLLECT_EXPORT_LIST
835 : FILE *exportf;
836 : #endif
837 93805 : const char *ld_file_name;
838 93805 : const char *p;
839 93805 : char **c_argv;
840 93805 : const char **c_ptr;
841 93805 : char **ld1_argv;
842 93805 : const char **ld1;
843 93805 : bool use_plugin = false;
844 93805 : 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 93805 : scanfilter ld1_filter = SCAN_ALL;
853 :
854 93805 : char **ld2_argv;
855 93805 : const char **ld2;
856 93805 : char **object_lst;
857 93805 : const char **object;
858 : #ifdef TARGET_AIX_VERSION
859 : int object_nbr = argc;
860 : #endif
861 93805 : int first_file;
862 93805 : int num_c_args;
863 93805 : char **old_argv;
864 : #ifdef COLLECT_EXPORT_LIST
865 : bool is_static = false;
866 : #endif
867 93805 : int i;
868 :
869 750440 : 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 656635 : full_ld_suffixes[i] = ld_suffixes[i];
879 :
880 93805 : p = argv[0] + strlen (argv[0]);
881 844245 : while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
882 750440 : --p;
883 93805 : progname = p;
884 :
885 93805 : xmalloc_set_program_name (progname);
886 :
887 93805 : old_argv = argv;
888 93805 : expandargv (&argc, &argv);
889 93805 : if (argv != old_argv)
890 6 : at_file_supplied = 1;
891 :
892 93805 : process_args (&argc, argv);
893 :
894 93805 : 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 93805 : setup_signals ();
909 :
910 : /* Unlock the stdio streams. */
911 93805 : unlock_std_streams ();
912 :
913 93805 : gcc_init_libintl ();
914 :
915 93805 : diagnostic_initialize (global_dc, 0);
916 :
917 93805 : 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 93805 : ld1_argv = XCNEWVEC (char *, argc + 4);
924 93805 : ld1 = const_cast<const char **> (ld1_argv);
925 93805 : ld2_argv = XCNEWVEC (char *, argc + 11);
926 93805 : ld2 = const_cast<const char **> (ld2_argv);
927 93805 : object_lst = XCNEWVEC (char *, argc);
928 93805 : object = const_cast<const char **> (object_lst);
929 :
930 : #ifdef DEBUG
931 : debug = true;
932 : #endif
933 :
934 93805 : save_temps = false;
935 93805 : verbose = false;
936 :
937 : #ifndef DEFAULT_A_OUT_NAME
938 93805 : 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 93805 : {
947 93805 : bool no_partition = false;
948 :
949 3979118 : for (i = 1; argv[i] != NULL; i ++)
950 : {
951 3885313 : if (! strcmp (argv[i], "-debug"))
952 0 : debug = true;
953 3885313 : else if (startswith (argv[i], "-fno-lto"))
954 35 : lto_mode = LTO_MODE_NONE;
955 3885278 : else if (! strcmp (argv[i], "-plugin"))
956 : {
957 89414 : use_plugin = true;
958 89414 : if (selected_linker == USE_DEFAULT_LD)
959 : selected_linker = USE_PLUGIN_LD;
960 : }
961 3795864 : else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
962 : selected_linker = USE_BFD_LD;
963 3795864 : else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
964 : selected_linker = USE_GOLD_LD;
965 3795864 : else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
966 : selected_linker = USE_LLD_LD;
967 3795864 : else if (strcmp (argv[i], "-fuse-ld=mold") == 0)
968 : selected_linker = USE_MOLD_LD;
969 3795864 : else if (strcmp (argv[i], "-fuse-ld=wild") == 0)
970 : selected_linker = USE_WILD_LD;
971 3795864 : 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 93322 : if (argv[i][2] != '\0')
976 0 : output_file = &argv[i][2];
977 93322 : else if (argv[i+1] != NULL)
978 93322 : 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 93805 : obstack_begin (&temporary_obstack, 0);
1002 93805 : 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 93805 : p = getenv ("COLLECT_GCC_OPTIONS");
1012 2469093 : while (p && *p)
1013 : {
1014 2375288 : const char *q = extract_string (&p);
1015 2375288 : if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1016 1186993 : num_c_args++;
1017 2375288 : if (startswith (q, "-flto-partition=none"))
1018 : no_partition = true;
1019 2370926 : else if (startswith (q, "-fno-lto"))
1020 35 : lto_mode = LTO_MODE_NONE;
1021 2370891 : else if (startswith (q, "-save-temps"))
1022 : /* FIXME: Honour =obj. */
1023 259 : save_temps = true;
1024 2370632 : else if (strcmp (q, "-dumpdir") == 0)
1025 93802 : dumppfx = xstrdup (extract_string (&p));
1026 2276830 : else if (strcmp (q, "-o") == 0
1027 2183508 : || strcmp (q, "-B") == 0
1028 1981266 : || strcmp (q, "-isystem") == 0)
1029 313364 : (void) extract_string (&p);
1030 : }
1031 93805 : obstack_free (&temporary_obstack, temporary_firstobj);
1032 :
1033 93805 : verbose = verbose || debug;
1034 93805 : save_temps = save_temps || debug;
1035 93805 : find_file_set_debug (debug);
1036 93805 : if (use_plugin)
1037 89414 : lto_mode = LTO_MODE_NONE;
1038 93805 : if (no_partition && lto_mode == LTO_MODE_WHOPR)
1039 4098 : 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 93805 : num_c_args += 8;
1046 :
1047 93805 : c_argv = XCNEWVEC (char *, num_c_args);
1048 93805 : c_ptr = const_cast<const char **> (c_argv);
1049 :
1050 93805 : if (argc < 2)
1051 0 : fatal_error (input_location, "no arguments");
1052 :
1053 : /* Extract COMPILER_PATH and PATH into our prefix list. */
1054 93805 : prefix_from_env ("COMPILER_PATH", &cpath);
1055 93805 : 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 93805 : 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 93805 : ld_file_name = find_a_file (&cpath, real_ld_suffix, X_OK);
1102 : /* Likewise for `collect-ld'. */
1103 93805 : if (ld_file_name == 0)
1104 : {
1105 93805 : ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK);
1106 93805 : 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 93805 : 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 93805 : nm_file_name = find_a_file (&cpath, gnm_suffix, X_OK);
1122 93805 : if (nm_file_name == 0)
1123 93805 : nm_file_name = find_a_file (&path, full_gnm_suffix, X_OK);
1124 93805 : if (nm_file_name == 0)
1125 93805 : nm_file_name = find_a_file (&cpath, nm_suffix, X_OK);
1126 93805 : 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 93805 : strip_file_name = find_a_file (&cpath, gstrip_suffix, X_OK);
1140 93805 : if (strip_file_name == 0)
1141 93805 : strip_file_name = find_a_file (&path, full_gstrip_suffix, X_OK);
1142 93805 : if (strip_file_name == 0)
1143 93805 : strip_file_name = find_a_file (&cpath, strip_suffix, X_OK);
1144 93805 : if (strip_file_name == 0)
1145 93805 : 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 93805 : c_file_name = getenv ("COLLECT_GCC");
1149 93805 : 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 93805 : 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 93805 : if (p == 0)
1163 0 : p = find_a_file (&path, c_file_name, X_OK);
1164 :
1165 93805 : if (p)
1166 93805 : c_file_name = p;
1167 :
1168 93805 : *ld1++ = *ld2++ = ld_file_name;
1169 :
1170 : /* Make temp file names. */
1171 93805 : if (save_temps)
1172 : {
1173 253 : c_file = concat (output_file, ".cdtor.c", NULL);
1174 253 : o_file = concat (output_file, ".cdtor.o", NULL);
1175 : #ifdef COLLECT_EXPORT_LIST
1176 : export_file = concat (output_file, ".x", NULL);
1177 : #endif
1178 : }
1179 : else
1180 : {
1181 93552 : c_file = make_temp_file (".cdtor.c");
1182 93552 : 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 93805 : *c_ptr++ = c_file_name;
1189 93805 : *c_ptr++ = "-x";
1190 93805 : *c_ptr++ = "c";
1191 93805 : *c_ptr++ = "-c";
1192 93805 : *c_ptr++ = "-o";
1193 93805 : *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 93805 : p = getenv ("COLLECT_GCC_OPTIONS");
1210 2469093 : while (p && *p)
1211 : {
1212 2375288 : const char *q = extract_string (&p);
1213 2375288 : if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1214 1186993 : *c_ptr++ = xstrdup (q);
1215 2375288 : if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1216 0 : *c_ptr++ = xstrdup (q);
1217 2375288 : if (strcmp (q, "-shared") == 0)
1218 248 : shared_obj = 1;
1219 2375288 : if (strcmp (q, "-static") == 0)
1220 95 : static_obj = 1;
1221 2375288 : if (*q == '-' && q[1] == 'B')
1222 : {
1223 202242 : *c_ptr++ = xstrdup (q);
1224 202242 : if (q[2] == 0)
1225 : {
1226 202242 : q = extract_string (&p);
1227 202242 : *c_ptr++ = xstrdup (q);
1228 : }
1229 : }
1230 2173046 : else if (strcmp (q, "-o") == 0
1231 2079724 : || strcmp (q, "-dumpdir") == 0
1232 1985922 : || strcmp (q, "-isystem") == 0)
1233 204924 : (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 93805 : obstack_free (&temporary_obstack, temporary_firstobj);
1241 93805 : *c_ptr++ = "-fno-profile-arcs";
1242 93805 : *c_ptr++ = "-fno-condition-coverage";
1243 93805 : *c_ptr++ = "-fno-path-coverage";
1244 93805 : *c_ptr++ = "-fno-test-coverage";
1245 93805 : *c_ptr++ = "-fno-branch-probabilities";
1246 93805 : *c_ptr++ = "-fno-exceptions";
1247 93805 : *c_ptr++ = "-w";
1248 93805 : *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 93805 : first_file = 1;
1264 3885656 : while ((arg = *++argv) != (char *) 0)
1265 : {
1266 3791851 : *ld1++ = *ld2++ = arg;
1267 :
1268 3791851 : if (arg[0] == '-')
1269 : {
1270 3019396 : switch (arg[1])
1271 : {
1272 93462 : case 'd':
1273 93462 : if (!strcmp (arg, "-debug"))
1274 : {
1275 : /* Already parsed. */
1276 0 : ld1--;
1277 0 : ld2--;
1278 : }
1279 93462 : if (!strcmp (arg, "-dynamic-linker") && argv[1])
1280 : {
1281 93462 : ++argv;
1282 93462 : *ld1++ = *ld2++ = *argv;
1283 : }
1284 : break;
1285 :
1286 12230 : case 'f':
1287 12230 : 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 3791851 : ld1--;
1309 3791851 : ld2--;
1310 : }
1311 : #ifdef TARGET_AIX_VERSION
1312 : else
1313 : {
1314 : /* File containing a list of input files to process. */
1315 :
1316 : FILE *stream;
1317 : char buf[MAXPATHLEN + 2];
1318 : /* Number of additionnal object files. */
1319 : int add_nbr = 0;
1320 : /* Maximum of additionnal object files before vector
1321 : expansion. */
1322 : int add_max = 0;
1323 : const char *list_filename = arg + 2;
1324 :
1325 : /* Accept -fFILENAME and -f FILENAME. */
1326 : if (*list_filename == '\0' && argv[1])
1327 : {
1328 : ++argv;
1329 : list_filename = *argv;
1330 : *ld1++ = *ld2++ = *argv;
1331 : }
1332 :
1333 : stream = fopen (list_filename, "r");
1334 : if (stream == NULL)
1335 : fatal_error (input_location, "cannot open %s: %m",
1336 : list_filename);
1337 :
1338 : while (fgets (buf, sizeof buf, stream) != NULL)
1339 : {
1340 : /* Remove end of line. */
1341 : int len = strlen (buf);
1342 : if (len >= 1 && buf[len - 1] =='\n')
1343 : buf[len - 1] = '\0';
1344 :
1345 : /* Put on object vector.
1346 : Note: we only expanse vector here, so we must keep
1347 : extra space for remaining arguments. */
1348 : if (add_nbr >= add_max)
1349 : {
1350 : int pos =
1351 : object - const_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 819536 : case 'l':
1380 819536 : 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 93322 : case 'o':
1409 93322 : if (arg[2] != '\0')
1410 0 : output_file = &arg[2];
1411 93322 : else if (argv[1])
1412 93322 : output_file = *ld1++ = *ld2++ = *++argv;
1413 : break;
1414 :
1415 232 : case 'r':
1416 232 : if (arg[2] == '\0')
1417 190 : rflag = 1;
1418 : break;
1419 :
1420 402 : case 's':
1421 402 : 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 144920 : case '-':
1437 144920 : if (strcmp (arg, "--no-demangle") == 0)
1438 : {
1439 : #ifndef HAVE_LD_DEMANGLE
1440 : no_demangle = 1;
1441 : ld1--;
1442 : ld2--;
1443 : #endif
1444 : }
1445 144920 : 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 144920 : else if (startswith (arg, "--sysroot="))
1463 0 : target_system_root = arg + 10;
1464 144920 : else if (strcmp (arg, "--version") == 0)
1465 0 : verbose = true;
1466 144920 : else if (strcmp (arg, "--help") == 0)
1467 5 : helpflag = true;
1468 : break;
1469 : }
1470 : }
1471 772455 : else if ((p = strrchr (arg, '.')) != (char *) 0
1472 772455 : && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1473 89481 : || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1474 59 : || strcmp (p, ".obj") == 0))
1475 : {
1476 678351 : if (first_file)
1477 : {
1478 93805 : first_file = 0;
1479 93805 : if (p[1] == 'o')
1480 4391 : *ld2++ = o_file;
1481 : else
1482 : {
1483 : /* place o_file BEFORE this argument! */
1484 89414 : ld2--;
1485 89414 : *ld2++ = o_file;
1486 89414 : *ld2++ = arg;
1487 : }
1488 : }
1489 678351 : if (p[1] == 'o' || p[1] == 'l')
1490 575386 : *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 93805 : *c_ptr++ = c_file;
1563 93805 : *c_ptr = *ld1 = *object = (char *) 0;
1564 :
1565 93805 : if (verbose)
1566 0 : notice ("collect2 version %s\n", version_string);
1567 :
1568 93805 : 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 93805 : 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 = getenv ("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 93805 : {
1627 187610 : bool early_exit
1628 93805 : = 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 93805 : if (early_exit || ld1_filter != SCAN_NOTHING)
1640 93805 : do_link (ld1_argv, "ld1_args");
1641 :
1642 93674 : 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 93674 : if (lto_mode != LTO_MODE_NONE)
1650 4356 : maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
1651 : else
1652 : post_ld_pass (/*temp_file*/false);
1653 :
1654 93674 : 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_GNU_LD && at_file_supplied, "ld_args");
1813 0 : post_ld_pass (/*temp_file*/false);
1814 : }
1815 :
1816 : /* Let scan_prog_file do any final mods (OSF/rose needs this for
1817 : constructors/destructors in shared libraries. */
1818 0 : scan_prog_file (output_file, PASS_SECOND, SCAN_ALL);
1819 : #endif
1820 :
1821 0 : return 0;
1822 : }
1823 :
1824 :
1825 : /* Unlink FILE unless we are debugging or this is the output_file
1826 : and we may not unlink it. */
1827 :
1828 : void
1829 197166 : maybe_unlink (const char *file)
1830 : {
1831 197166 : if (save_temps && file_exists (file))
1832 : {
1833 2 : if (verbose)
1834 0 : notice ("[Leaving %s]\n", file);
1835 2 : return;
1836 : }
1837 :
1838 197164 : if (file == output_file && !may_unlink_output_file)
1839 : return;
1840 :
1841 197164 : unlink_if_ordinary (file);
1842 : }
1843 :
1844 : /* Call maybe_unlink on the NULL-terminated list, FILE_LIST. */
1845 :
1846 : static void
1847 8712 : maybe_unlink_list (char **file_list)
1848 : {
1849 8712 : char **tmp = file_list;
1850 :
1851 18268 : while (*tmp)
1852 9556 : maybe_unlink (*(tmp++));
1853 8712 : }
1854 :
1855 :
1856 : static long sequence_number = 0;
1857 :
1858 : /* Add a name to a linked list. */
1859 :
1860 : static void
1861 0 : add_to_list (struct head *head_ptr, const char *name)
1862 : {
1863 0 : struct id *newid
1864 0 : = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1865 0 : struct id *p;
1866 0 : strcpy (newid->name, name);
1867 :
1868 0 : if (head_ptr->first)
1869 0 : head_ptr->last->next = newid;
1870 : else
1871 0 : head_ptr->first = newid;
1872 :
1873 : /* Check for duplicate symbols. */
1874 0 : for (p = head_ptr->first;
1875 0 : strcmp (name, p->name) != 0;
1876 0 : p = p->next)
1877 : ;
1878 0 : if (p != newid)
1879 : {
1880 0 : head_ptr->last->next = 0;
1881 0 : free (newid);
1882 0 : return;
1883 : }
1884 :
1885 0 : newid->sequence = ++sequence_number;
1886 0 : head_ptr->last = newid;
1887 0 : head_ptr->number++;
1888 : }
1889 :
1890 : /* Grab the init priority number from an init function name that
1891 : looks like "_GLOBAL_.I.12345.foo". */
1892 :
1893 : static int
1894 0 : extract_init_priority (const char *name)
1895 : {
1896 0 : int pos = 0, pri;
1897 :
1898 : #ifdef TARGET_AIX_VERSION
1899 : /* Run dependent module initializers before any constructors in this
1900 : module. */
1901 : switch (is_ctor_dtor (name))
1902 : {
1903 : case SYM_AIXI:
1904 : case SYM_AIXD:
1905 : return INT_MIN;
1906 : default:
1907 : break;
1908 : }
1909 : #endif
1910 :
1911 0 : while (name[pos] == '_')
1912 0 : ++pos;
1913 0 : pos += 10; /* strlen ("GLOBAL__X_") */
1914 :
1915 : /* Extract init_p number from ctor/dtor name. */
1916 0 : pri = atoi (name + pos);
1917 0 : return pri ? pri : DEFAULT_INIT_PRIORITY;
1918 : }
1919 :
1920 : /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1921 : ctors will be run from right to left, dtors from left to right. */
1922 :
1923 : static void
1924 0 : sort_ids (struct head *head_ptr)
1925 : {
1926 : /* id holds the current element to insert. id_next holds the next
1927 : element to insert. id_ptr iterates through the already sorted elements
1928 : looking for the place to insert id. */
1929 0 : struct id *id, *id_next, **id_ptr;
1930 :
1931 0 : id = head_ptr->first;
1932 :
1933 : /* We don't have any sorted elements yet. */
1934 0 : head_ptr->first = NULL;
1935 :
1936 0 : for (; id; id = id_next)
1937 : {
1938 0 : id_next = id->next;
1939 0 : id->sequence = extract_init_priority (id->name);
1940 :
1941 0 : for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1942 0 : if (*id_ptr == NULL
1943 : /* If the sequence numbers are the same, we put the id from the
1944 : file later on the command line later in the list. */
1945 0 : || id->sequence > (*id_ptr)->sequence
1946 : /* Hack: do lexical compare, too.
1947 : || (id->sequence == (*id_ptr)->sequence
1948 : && strcmp (id->name, (*id_ptr)->name) > 0) */
1949 : )
1950 : {
1951 0 : id->next = *id_ptr;
1952 0 : *id_ptr = id;
1953 0 : break;
1954 : }
1955 : }
1956 :
1957 : /* Now set the sequence numbers properly so write_c_file works. */
1958 0 : for (id = head_ptr->first; id; id = id->next)
1959 0 : id->sequence = ++sequence_number;
1960 0 : }
1961 :
1962 : /* Write: `prefix', the names on list LIST, `suffix'. */
1963 :
1964 : static void
1965 0 : write_list (FILE *stream, const char *prefix, struct id *list)
1966 : {
1967 0 : while (list)
1968 : {
1969 0 : fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1970 0 : list = list->next;
1971 : }
1972 0 : }
1973 :
1974 : #ifdef COLLECT_EXPORT_LIST
1975 : /* This function is really used only on AIX, but may be useful. */
1976 : static int
1977 : is_in_list (const char *prefix, struct id *list)
1978 : {
1979 : while (list)
1980 : {
1981 : if (!strcmp (prefix, list->name)) return 1;
1982 : list = list->next;
1983 : }
1984 : return 0;
1985 : }
1986 : #endif /* COLLECT_EXPORT_LIST */
1987 :
1988 : /* Added for debugging purpose. */
1989 : #ifdef COLLECT_EXPORT_LIST
1990 : static void
1991 : dump_list (FILE *stream, const char *prefix, struct id *list)
1992 : {
1993 : while (list)
1994 : {
1995 : fprintf (stream, "%s%s,\n", prefix, list->name);
1996 : list = list->next;
1997 : }
1998 : }
1999 : #endif
2000 :
2001 : #if 0
2002 : static void
2003 : dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
2004 : {
2005 : while (list)
2006 : {
2007 : fprintf (stream, "%s%s,\n", prefix, list->prefix);
2008 : list = list->next;
2009 : }
2010 : }
2011 : #endif
2012 :
2013 : static void
2014 0 : write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
2015 : {
2016 0 : while (list)
2017 : {
2018 0 : fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
2019 0 : prefix, list->sequence, list->name);
2020 0 : list = list->next;
2021 : }
2022 0 : }
2023 :
2024 : /* Write out the constructor and destructor tables statically (for a shared
2025 : object), along with the functions to execute them. */
2026 :
2027 : static void
2028 0 : write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
2029 : {
2030 0 : const char *p, *q;
2031 0 : char *prefix, *r;
2032 0 : int frames = (frame_tables.number > 0);
2033 :
2034 : /* Figure out name of output_file, stripping off .so version. */
2035 0 : q = p = lbasename (output_file);
2036 :
2037 0 : while (q)
2038 : {
2039 0 : q = strchr (q,'.');
2040 0 : if (q == 0)
2041 : {
2042 0 : q = p + strlen (p);
2043 0 : break;
2044 : }
2045 : else
2046 : {
2047 0 : if (filename_ncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0)
2048 : {
2049 0 : q += strlen (SHLIB_SUFFIX);
2050 0 : break;
2051 : }
2052 : else
2053 0 : q++;
2054 : }
2055 : }
2056 : /* q points to null at end of the string (or . of the .so version) */
2057 0 : prefix = XNEWVEC (char, q - p + 1);
2058 0 : strncpy (prefix, p, q - p);
2059 0 : prefix[q - p] = 0;
2060 0 : for (r = prefix; *r; r++)
2061 0 : if (!ISALNUM ((unsigned char)*r))
2062 0 : *r = '_';
2063 0 : if (debug)
2064 0 : notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
2065 : output_file, prefix);
2066 :
2067 0 : initname = concat ("_GLOBAL__FI_", prefix, NULL);
2068 0 : fininame = concat ("_GLOBAL__FD_", prefix, NULL);
2069 : #ifdef TARGET_AIX_VERSION
2070 : aix_shared_initname = concat ("_GLOBAL__AIXI_", prefix, NULL);
2071 : aix_shared_fininame = concat ("_GLOBAL__AIXD_", prefix, NULL);
2072 : #endif
2073 :
2074 0 : free (prefix);
2075 :
2076 : /* Write the tables as C code. */
2077 :
2078 : /* This count variable is used to prevent multiple calls to the
2079 : constructors/destructors.
2080 : This guard against multiple calls is important on AIX as the initfini
2081 : functions are deliberately invoked multiple times as part of the
2082 : mechanisms GCC uses to order constructors across different dependent
2083 : shared libraries (see config/rs6000/aix.h).
2084 : */
2085 0 : fprintf (stream, "static int count;\n");
2086 0 : fprintf (stream, "typedef void entry_pt();\n");
2087 0 : write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2088 :
2089 0 : if (frames)
2090 : {
2091 0 : write_list_with_asm (stream, "extern void *", frame_tables.first);
2092 :
2093 0 : fprintf (stream, "\tstatic void *frame_table[] = {\n");
2094 0 : write_list (stream, "\t\t&", frame_tables.first);
2095 0 : fprintf (stream, "\t0\n};\n");
2096 :
2097 : /* This must match what's in frame.h. */
2098 0 : fprintf (stream, "struct object {\n");
2099 0 : fprintf (stream, " void *pc_begin;\n");
2100 0 : fprintf (stream, " void *pc_end;\n");
2101 0 : fprintf (stream, " void *fde_begin;\n");
2102 0 : fprintf (stream, " void *fde_array;\n");
2103 0 : fprintf (stream, " __SIZE_TYPE__ count;\n");
2104 0 : fprintf (stream, " struct object *next;\n");
2105 0 : fprintf (stream, "};\n");
2106 :
2107 0 : fprintf (stream, "extern void __register_frame_info_table_bases (void *, struct object *, void *tbase, void *dbase);\n");
2108 0 : fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2109 0 : fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2110 : #ifdef TARGET_AIX_VERSION
2111 : fprintf (stream, "extern void *__gcc_unwind_dbase;\n");
2112 : #endif
2113 :
2114 0 : fprintf (stream, "static void reg_frame () {\n");
2115 0 : fprintf (stream, "\tstatic struct object ob;\n");
2116 : #ifdef TARGET_AIX_VERSION
2117 : /* Use __gcc_unwind_dbase as the base address for data on AIX.
2118 : This might not be the start of the segment, signed offsets assumed.
2119 : */
2120 : fprintf (stream, "\t__register_frame_info_table_bases (frame_table, &ob, (void *)0, &__gcc_unwind_dbase);\n");
2121 : #else
2122 0 : fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2123 : #endif
2124 0 : fprintf (stream, "\t}\n");
2125 :
2126 0 : fprintf (stream, "static void dereg_frame () {\n");
2127 0 : fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2128 0 : fprintf (stream, "\t}\n");
2129 : }
2130 :
2131 : #ifdef COLLECT_EXPORT_LIST
2132 : /* Set visibility of initializers to default. */
2133 : if (visibility_flag)
2134 : fprintf (stream, "#pragma GCC visibility push(default)\n");
2135 : #endif
2136 0 : fprintf (stream, "void %s() {\n", initname);
2137 0 : if (constructors.number > 0 || frames)
2138 : {
2139 0 : fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
2140 0 : write_list (stream, "\t\t", constructors.first);
2141 0 : if (frames)
2142 0 : fprintf (stream, "\treg_frame,\n");
2143 0 : fprintf (stream, "\t};\n");
2144 0 : fprintf (stream, "\tentry_pt **p;\n");
2145 0 : fprintf (stream, "\tif (count++ != 0) return;\n");
2146 0 : fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
2147 0 : fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
2148 : }
2149 : else
2150 0 : fprintf (stream, "\t++count;\n");
2151 0 : fprintf (stream, "}\n");
2152 0 : write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2153 0 : fprintf (stream, "void %s() {\n", fininame);
2154 0 : if (destructors.number > 0 || frames)
2155 : {
2156 0 : fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
2157 0 : write_list (stream, "\t\t", destructors.first);
2158 0 : if (frames)
2159 0 : fprintf (stream, "\tdereg_frame,\n");
2160 0 : fprintf (stream, "\t};\n");
2161 0 : fprintf (stream, "\tentry_pt **p;\n");
2162 0 : fprintf (stream, "\tif (--count != 0) return;\n");
2163 0 : fprintf (stream, "\tp = dtors;\n");
2164 0 : fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
2165 0 : destructors.number + frames);
2166 : }
2167 0 : fprintf (stream, "}\n");
2168 : #ifdef COLLECT_EXPORT_LIST
2169 : if (visibility_flag)
2170 : fprintf (stream, "#pragma GCC visibility pop\n");
2171 : #endif
2172 :
2173 0 : if (shared_obj)
2174 : {
2175 : #ifdef COLLECT_EXPORT_LIST
2176 : /* Set visibility of initializers to default. */
2177 : if (visibility_flag)
2178 : fprintf (stream, "#pragma GCC visibility push(default)\n");
2179 : #endif
2180 0 : COLLECT_SHARED_INIT_FUNC (stream, initname);
2181 0 : COLLECT_SHARED_FINI_FUNC (stream, fininame);
2182 : #ifdef COLLECT_EXPORT_LIST
2183 : if (visibility_flag)
2184 : fprintf (stream, "#pragma GCC visibility pop\n");
2185 : #endif
2186 : }
2187 0 : }
2188 :
2189 : /* Write the constructor/destructor tables. */
2190 :
2191 : #ifndef LD_INIT_SWITCH
2192 : static void
2193 0 : write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
2194 : {
2195 : /* Write the tables as C code. */
2196 :
2197 0 : int frames = (frame_tables.number > 0);
2198 :
2199 0 : fprintf (stream, "typedef void entry_pt();\n\n");
2200 :
2201 0 : write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2202 :
2203 0 : if (frames)
2204 : {
2205 0 : write_list_with_asm (stream, "extern void *", frame_tables.first);
2206 :
2207 0 : fprintf (stream, "\tstatic void *frame_table[] = {\n");
2208 0 : write_list (stream, "\t\t&", frame_tables.first);
2209 0 : fprintf (stream, "\t0\n};\n");
2210 :
2211 : /* This must match what's in frame.h. */
2212 0 : fprintf (stream, "struct object {\n");
2213 0 : fprintf (stream, " void *pc_begin;\n");
2214 0 : fprintf (stream, " void *pc_end;\n");
2215 0 : fprintf (stream, " void *fde_begin;\n");
2216 0 : fprintf (stream, " void *fde_array;\n");
2217 0 : fprintf (stream, " __SIZE_TYPE__ count;\n");
2218 0 : fprintf (stream, " struct object *next;\n");
2219 0 : fprintf (stream, "};\n");
2220 :
2221 0 : fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2222 0 : fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2223 :
2224 0 : fprintf (stream, "static void reg_frame () {\n");
2225 0 : fprintf (stream, "\tstatic struct object ob;\n");
2226 0 : fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2227 0 : fprintf (stream, "\t}\n");
2228 :
2229 0 : fprintf (stream, "static void dereg_frame () {\n");
2230 0 : fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2231 0 : fprintf (stream, "\t}\n");
2232 : }
2233 :
2234 0 : fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2235 0 : fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2236 0 : write_list (stream, "\t", constructors.first);
2237 0 : if (frames)
2238 0 : fprintf (stream, "\treg_frame,\n");
2239 0 : fprintf (stream, "\t0\n};\n\n");
2240 :
2241 0 : write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2242 :
2243 0 : fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2244 0 : fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2245 0 : write_list (stream, "\t", destructors.first);
2246 0 : if (frames)
2247 0 : fprintf (stream, "\tdereg_frame,\n");
2248 0 : fprintf (stream, "\t0\n};\n\n");
2249 :
2250 0 : fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2251 0 : fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2252 0 : }
2253 : #endif /* ! LD_INIT_SWITCH */
2254 :
2255 : static void
2256 0 : write_c_file (FILE *stream, const char *name)
2257 : {
2258 : #ifndef LD_INIT_SWITCH
2259 0 : if (! shared_obj)
2260 0 : write_c_file_glob (stream, name);
2261 : else
2262 : #endif
2263 0 : write_c_file_stat (stream, name);
2264 0 : }
2265 :
2266 : #ifdef COLLECT_EXPORT_LIST
2267 : static void
2268 : write_aix_file (FILE *stream, struct id *list)
2269 : {
2270 : for (; list; list = list->next)
2271 : {
2272 : fputs (list->name, stream);
2273 : putc ('\n', stream);
2274 : }
2275 : }
2276 : #endif
2277 :
2278 : #ifdef OBJECT_FORMAT_NONE
2279 :
2280 : /* Check to make sure the file is an LTO object file. */
2281 :
2282 : static int
2283 421800 : has_lto_section (void *data, const char *name ATTRIBUTE_UNUSED,
2284 : off_t offset ATTRIBUTE_UNUSED,
2285 : off_t length ATTRIBUTE_UNUSED)
2286 : {
2287 421800 : int *found = (int *) data;
2288 :
2289 421800 : if (!startswith (name, LTO_SECTION_NAME_PREFIX)
2290 421800 : && !startswith (name, OFFLOAD_SECTION_NAME_PREFIX))
2291 : return 1;
2292 :
2293 4673 : *found = 1;
2294 :
2295 : /* Stop iteration. */
2296 4673 : return 0;
2297 : }
2298 :
2299 : static bool
2300 26510 : is_lto_object_file (const char *prog_name)
2301 : {
2302 26510 : const char *errmsg;
2303 26510 : int err;
2304 26510 : int found = 0;
2305 26510 : off_t inoff = 0;
2306 26510 : int infd = open (prog_name, O_RDONLY | O_BINARY);
2307 :
2308 26510 : if (infd == -1)
2309 : return false;
2310 :
2311 26510 : simple_object_read *inobj = simple_object_start_read (infd, inoff,
2312 : LTO_SEGMENT_NAME,
2313 : &errmsg, &err);
2314 26510 : if (!inobj)
2315 : {
2316 0 : close (infd);
2317 0 : return false;
2318 : }
2319 :
2320 26510 : errmsg = simple_object_find_sections (inobj, has_lto_section,
2321 : (void *) &found, &err);
2322 26510 : simple_object_release_read (inobj);
2323 26510 : close (infd);
2324 26510 : if (! errmsg && found)
2325 : return true;
2326 :
2327 21837 : if (errmsg)
2328 0 : fatal_error (0, "%s: %s", errmsg, xstrerror (err));
2329 : return false;
2330 : }
2331 :
2332 : /* Generic version to scan the name list of the loaded program for
2333 : the symbols g++ uses for static constructors and destructors. */
2334 :
2335 : static void
2336 26510 : scan_prog_file (const char *prog_name, scanpass which_pass,
2337 : scanfilter filter)
2338 : {
2339 26510 : void (*int_handler) (int);
2340 : #ifdef SIGQUIT
2341 26510 : void (*quit_handler) (int);
2342 : #endif
2343 26510 : char *real_nm_argv[4];
2344 26510 : const char **nm_argv = const_cast<const char **> (real_nm_argv);
2345 26510 : int argc = 0;
2346 26510 : struct pex_obj *pex;
2347 26510 : const char *errmsg;
2348 26510 : int err;
2349 26510 : char *p, buf[1024];
2350 26510 : FILE *inf;
2351 :
2352 26510 : if (which_pass == PASS_SECOND)
2353 26510 : return;
2354 :
2355 : /* LTO objects must be in a known format. This check prevents
2356 : us from accepting an archive containing LTO objects, which
2357 : gcc cannot currently handle. */
2358 26510 : if (which_pass == PASS_LTOINFO)
2359 : {
2360 26510 : if(is_lto_object_file (prog_name)) {
2361 4673 : add_lto_object (<o_objects, prog_name);
2362 : }
2363 26510 : return;
2364 : }
2365 :
2366 : /* If we do not have an `nm', complain. */
2367 0 : if (nm_file_name == 0)
2368 0 : fatal_error (input_location, "cannot find %<nm%>");
2369 :
2370 0 : nm_argv[argc++] = nm_file_name;
2371 0 : if (NM_FLAGS[0] != '\0')
2372 0 : nm_argv[argc++] = NM_FLAGS;
2373 :
2374 0 : nm_argv[argc++] = prog_name;
2375 0 : nm_argv[argc++] = (char *) 0;
2376 :
2377 : /* Trace if needed. */
2378 0 : if (verbose)
2379 : {
2380 : const char **p_argv;
2381 : const char *str;
2382 :
2383 0 : for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2384 0 : fprintf (stderr, " %s", str);
2385 :
2386 0 : fprintf (stderr, "\n");
2387 : }
2388 :
2389 0 : fflush (stdout);
2390 0 : fflush (stderr);
2391 :
2392 0 : pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2393 0 : if (pex == NULL)
2394 : fatal_error (input_location, "%<pex_init%> failed: %m");
2395 :
2396 0 : errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, HOST_BIT_BUCKET,
2397 : &err);
2398 0 : if (errmsg != NULL)
2399 : {
2400 0 : if (err != 0)
2401 : {
2402 0 : errno = err;
2403 0 : fatal_error (input_location, "%s: %m", _(errmsg));
2404 : }
2405 : else
2406 0 : fatal_error (input_location, errmsg);
2407 : }
2408 :
2409 0 : int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
2410 : #ifdef SIGQUIT
2411 0 : quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2412 : #endif
2413 :
2414 0 : inf = pex_read_output (pex, 0);
2415 0 : if (inf == NULL)
2416 0 : fatal_error (input_location, "cannot open nm output: %m");
2417 :
2418 0 : if (debug)
2419 0 : fprintf (stderr, "\nnm output with constructors/destructors.\n");
2420 :
2421 : /* Read each line of nm output. */
2422 0 : while (fgets (buf, sizeof buf, inf) != (char *) 0)
2423 : {
2424 0 : int ch, ch2;
2425 0 : char *name, *end;
2426 :
2427 0 : if (debug)
2428 0 : fprintf (stderr, "\t%s\n", buf);
2429 :
2430 : /* If it contains a constructor or destructor name, add the name
2431 : to the appropriate list unless this is a kind of symbol we're
2432 : not supposed to even consider. */
2433 :
2434 0 : for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2435 0 : if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2436 : break;
2437 :
2438 0 : if (ch != '_')
2439 0 : continue;
2440 :
2441 : name = p;
2442 : /* Find the end of the symbol name.
2443 : Do not include `|', because Encore nm can tack that on the end. */
2444 0 : for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2445 : end++)
2446 0 : continue;
2447 :
2448 :
2449 0 : *end = '\0';
2450 :
2451 0 : switch (is_ctor_dtor (name))
2452 : {
2453 0 : case SYM_CTOR:
2454 0 : if (! (filter & SCAN_CTOR))
2455 : break;
2456 0 : if (which_pass != PASS_LIB)
2457 0 : add_to_list (&constructors, name);
2458 : break;
2459 :
2460 0 : case SYM_DTOR:
2461 0 : if (! (filter & SCAN_DTOR))
2462 : break;
2463 0 : if (which_pass != PASS_LIB)
2464 0 : add_to_list (&destructors, name);
2465 : break;
2466 :
2467 0 : case SYM_INIT:
2468 0 : if (! (filter & SCAN_INIT))
2469 : break;
2470 0 : if (which_pass != PASS_LIB)
2471 0 : fatal_error (input_location, "init function found in object %s",
2472 : prog_name);
2473 : #ifndef LD_INIT_SWITCH
2474 0 : add_to_list (&constructors, name);
2475 : #endif
2476 0 : break;
2477 :
2478 0 : case SYM_FINI:
2479 0 : if (! (filter & SCAN_FINI))
2480 : break;
2481 0 : if (which_pass != PASS_LIB)
2482 0 : fatal_error (input_location, "fini function found in object %s",
2483 : prog_name);
2484 : #ifndef LD_FINI_SWITCH
2485 0 : add_to_list (&destructors, name);
2486 : #endif
2487 0 : break;
2488 :
2489 0 : case SYM_DWEH:
2490 0 : if (! (filter & SCAN_DWEH))
2491 : break;
2492 0 : if (which_pass != PASS_LIB)
2493 0 : add_to_list (&frame_tables, name);
2494 : break;
2495 :
2496 0 : default: /* not a constructor or destructor */
2497 0 : continue;
2498 : }
2499 0 : }
2500 :
2501 0 : if (debug)
2502 0 : fprintf (stderr, "\n");
2503 :
2504 0 : do_wait (nm_file_name, pex);
2505 :
2506 0 : signal (SIGINT, int_handler);
2507 : #ifdef SIGQUIT
2508 0 : signal (SIGQUIT, quit_handler);
2509 : #endif
2510 : }
2511 :
2512 : #ifdef LDD_SUFFIX
2513 :
2514 : /* Use the List Dynamic Dependencies program to find shared libraries that
2515 : the output file depends upon and their initialization/finalization
2516 : routines, if any. */
2517 :
2518 : static void
2519 : scan_libraries (const char *prog_name)
2520 : {
2521 : static struct head libraries; /* list of shared libraries found */
2522 : struct id *list;
2523 : void (*int_handler) (int);
2524 : #ifdef SIGQUIT
2525 : void (*quit_handler) (int);
2526 : #endif
2527 : char *real_ldd_argv[4];
2528 : const char **ldd_argv = const_cast<const char **> (real_ldd_argv);
2529 : int argc = 0;
2530 : struct pex_obj *pex;
2531 : const char *errmsg;
2532 : int err;
2533 : char buf[1024];
2534 : FILE *inf;
2535 :
2536 : /* If we do not have an `ldd', complain. */
2537 : if (ldd_file_name == 0)
2538 : {
2539 : error ("cannot find %<ldd%>");
2540 : return;
2541 : }
2542 :
2543 : ldd_argv[argc++] = ldd_file_name;
2544 : ldd_argv[argc++] = prog_name;
2545 : ldd_argv[argc++] = (char *) 0;
2546 :
2547 : /* Trace if needed. */
2548 : if (verbose)
2549 : {
2550 : const char **p_argv;
2551 : const char *str;
2552 :
2553 : for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2554 : fprintf (stderr, " %s", str);
2555 :
2556 : fprintf (stderr, "\n");
2557 : }
2558 :
2559 : fflush (stdout);
2560 : fflush (stderr);
2561 :
2562 : pex = pex_init (PEX_USE_PIPES, "collect2", NULL);
2563 : if (pex == NULL)
2564 : fatal_error (input_location, "%<pex_init%> failed: %m");
2565 :
2566 : errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err);
2567 : if (errmsg != NULL)
2568 : {
2569 : if (err != 0)
2570 : {
2571 : errno = err;
2572 : fatal_error (input_location, "%s: %m", _(errmsg));
2573 : }
2574 : else
2575 : fatal_error (input_location, errmsg);
2576 : }
2577 :
2578 : int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
2579 : #ifdef SIGQUIT
2580 : quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2581 : #endif
2582 :
2583 : inf = pex_read_output (pex, 0);
2584 : if (inf == NULL)
2585 : fatal_error (input_location, "cannot open ldd output: %m");
2586 :
2587 : if (debug)
2588 : notice ("\nldd output with constructors/destructors.\n");
2589 :
2590 : /* Read each line of ldd output. */
2591 : while (fgets (buf, sizeof buf, inf) != (char *) 0)
2592 : {
2593 : int ch2;
2594 : char *name, *end, *p = buf;
2595 :
2596 : /* Extract names of libraries and add to list. */
2597 : PARSE_LDD_OUTPUT (p);
2598 : if (p == 0)
2599 : continue;
2600 :
2601 : name = p;
2602 : if (startswith (name, "not found"))
2603 : fatal_error (input_location, "dynamic dependency %s not found", buf);
2604 :
2605 : /* Find the end of the symbol name. */
2606 : for (end = p;
2607 : (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2608 : end++)
2609 : continue;
2610 : *end = '\0';
2611 :
2612 : if (access (name, R_OK) == 0)
2613 : add_to_list (&libraries, name);
2614 : else
2615 : fatal_error (input_location, "unable to open dynamic dependency "
2616 : "%qs", buf);
2617 :
2618 : if (debug)
2619 : fprintf (stderr, "\t%s\n", buf);
2620 : }
2621 : if (debug)
2622 : fprintf (stderr, "\n");
2623 :
2624 : do_wait (ldd_file_name, pex);
2625 :
2626 : signal (SIGINT, int_handler);
2627 : #ifdef SIGQUIT
2628 : signal (SIGQUIT, quit_handler);
2629 : #endif
2630 :
2631 : /* Now iterate through the library list adding their symbols to
2632 : the list. */
2633 : for (list = libraries.first; list; list = list->next)
2634 : scan_prog_file (list->name, PASS_LIB, SCAN_ALL);
2635 : }
2636 :
2637 : #endif /* LDD_SUFFIX */
2638 :
2639 : #endif /* OBJECT_FORMAT_NONE */
2640 :
2641 :
2642 : /*
2643 : * COFF specific stuff.
2644 : */
2645 :
2646 : #ifdef OBJECT_FORMAT_COFF
2647 :
2648 : # define GCC_SYMBOLS(X) (HEADER (ldptr).f_nsyms)
2649 : # define GCC_SYMENT SYMENT
2650 : # if defined (C_WEAKEXT)
2651 : # define GCC_OK_SYMBOL(X) \
2652 : (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2653 : ((X).n_scnum > N_UNDEF) && \
2654 : (aix64_flag \
2655 : || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2656 : || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2657 : # define GCC_UNDEF_SYMBOL(X) \
2658 : (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2659 : ((X).n_scnum == N_UNDEF))
2660 : # else
2661 : # define GCC_OK_SYMBOL(X) \
2662 : (((X).n_sclass == C_EXT) && \
2663 : ((X).n_scnum > N_UNDEF) && \
2664 : (aix64_flag \
2665 : || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2666 : || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2667 : # define GCC_UNDEF_SYMBOL(X) \
2668 : (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2669 : # endif
2670 : # define GCC_SYMINC(X) ((X).n_numaux+1)
2671 : # define GCC_SYMZERO(X) 0
2672 :
2673 : /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2674 : #if TARGET_AIX_VERSION >= 51
2675 : # define GCC_CHECK_HDR(X) \
2676 : (((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2677 : || (HEADER (X).f_magic == 0767 && aix64_flag)) \
2678 : && !(HEADER (X).f_flags & F_LOADONLY))
2679 : #else
2680 : # define GCC_CHECK_HDR(X) \
2681 : (((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2682 : || (HEADER (X).f_magic == 0757 && aix64_flag)) \
2683 : && !(HEADER (X).f_flags & F_LOADONLY))
2684 : #endif
2685 :
2686 : #ifdef COLLECT_EXPORT_LIST
2687 : /* Array of standard AIX libraries which should not
2688 : be scanned for ctors/dtors. */
2689 : static const char *const aix_std_libs[] = {
2690 : "/unix",
2691 : "/lib/libc.a",
2692 : "/lib/libm.a",
2693 : "/lib/libc_r.a",
2694 : "/lib/libm_r.a",
2695 : "/usr/lib/libc.a",
2696 : "/usr/lib/libm.a",
2697 : "/usr/lib/libc_r.a",
2698 : "/usr/lib/libm_r.a",
2699 : "/usr/lib/threads/libc.a",
2700 : "/usr/ccs/lib/libc.a",
2701 : "/usr/ccs/lib/libm.a",
2702 : "/usr/ccs/lib/libc_r.a",
2703 : "/usr/ccs/lib/libm_r.a",
2704 : NULL
2705 : };
2706 :
2707 : /* This function checks the filename and returns 1
2708 : if this name matches the location of a standard AIX library. */
2709 : static int ignore_library (const char *);
2710 : static int
2711 : ignore_library (const char *name)
2712 : {
2713 : const char *const *p;
2714 : size_t length;
2715 :
2716 : if (target_system_root[0] != '\0')
2717 : {
2718 : length = strlen (target_system_root);
2719 : if (strncmp (name, target_system_root, length) != 0)
2720 : return 0;
2721 : name += length;
2722 : }
2723 : for (p = &aix_std_libs[0]; *p != NULL; ++p)
2724 : if (strcmp (name, *p) == 0)
2725 : return 1;
2726 : return 0;
2727 : }
2728 : #endif /* COLLECT_EXPORT_LIST */
2729 :
2730 : #if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2731 : extern char *ldgetname (LDFILE *, GCC_SYMENT *);
2732 : #endif
2733 :
2734 : /* COFF version to scan the name list of the loaded program for
2735 : the symbols g++ uses for static constructors and destructors. */
2736 :
2737 : static void
2738 : scan_prog_file (const char *prog_name, scanpass which_pass,
2739 : scanfilter filter)
2740 : {
2741 : LDFILE *ldptr = NULL;
2742 : int sym_index, sym_count;
2743 : int is_shared = 0;
2744 :
2745 : if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2746 : return;
2747 :
2748 : #ifdef COLLECT_EXPORT_LIST
2749 : /* We do not need scanning for some standard C libraries. */
2750 : if (which_pass == PASS_FIRST && ignore_library (prog_name))
2751 : return;
2752 :
2753 : /* On AIX we have a loop, because there is not much difference
2754 : between an object and an archive. This trick allows us to
2755 : eliminate scan_libraries() function. */
2756 : do
2757 : {
2758 : #endif
2759 : /* Some platforms (e.g. OSF4) declare ldopen as taking a
2760 : non-const char * filename parameter, even though it will not
2761 : modify that string. So we must cast away const-ness here,
2762 : using CONST_CAST to prevent complaints from -Wcast-qual. */
2763 : if ((ldptr = ldopen (const_cast<char *> (prog_name), ldptr)) != NULL)
2764 : {
2765 : if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2766 : {
2767 : warning (0, "%s: not a COFF file", prog_name);
2768 : continue;
2769 : }
2770 :
2771 : if (GCC_CHECK_HDR (ldptr))
2772 : {
2773 : sym_count = GCC_SYMBOLS (ldptr);
2774 : sym_index = GCC_SYMZERO (ldptr);
2775 :
2776 : #ifdef COLLECT_EXPORT_LIST
2777 : /* Is current archive member a shared object? */
2778 : is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2779 : #endif
2780 :
2781 : while (sym_index < sym_count)
2782 : {
2783 : GCC_SYMENT symbol;
2784 :
2785 : if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2786 : break;
2787 : sym_index += GCC_SYMINC (symbol);
2788 :
2789 : if (GCC_OK_SYMBOL (symbol))
2790 : {
2791 : char *name;
2792 :
2793 : if ((name = ldgetname (ldptr, &symbol)) == NULL)
2794 : continue; /* Should never happen. */
2795 :
2796 : #ifdef XCOFF_DEBUGGING_INFO
2797 : /* All AIX function names have a duplicate entry
2798 : beginning with a dot. */
2799 : if (*name == '.')
2800 : ++name;
2801 : #endif
2802 :
2803 : switch (is_ctor_dtor (name))
2804 : {
2805 : #if TARGET_AIX_VERSION
2806 : /* Add AIX shared library initalisers/finalisers
2807 : to the constructors/destructors list of the
2808 : current module. */
2809 : case SYM_AIXI:
2810 : if (! (filter & SCAN_CTOR))
2811 : break;
2812 : if (is_shared && !aixlazy_flag
2813 : #ifdef COLLECT_EXPORT_LIST
2814 : && ! static_obj
2815 : && ! is_in_list (prog_name, static_libs.first)
2816 : #endif
2817 : )
2818 : add_to_list (&constructors, name);
2819 : break;
2820 :
2821 : case SYM_AIXD:
2822 : if (! (filter & SCAN_DTOR))
2823 : break;
2824 : if (is_shared && !aixlazy_flag)
2825 : add_to_list (&destructors, name);
2826 : break;
2827 : #endif
2828 :
2829 : case SYM_CTOR:
2830 : if (! (filter & SCAN_CTOR))
2831 : break;
2832 : if (! is_shared)
2833 : add_to_list (&constructors, name);
2834 : #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2835 : if (which_pass == PASS_OBJ)
2836 : add_to_list (&exports, name);
2837 : #endif
2838 : break;
2839 :
2840 : case SYM_DTOR:
2841 : if (! (filter & SCAN_DTOR))
2842 : break;
2843 : if (! is_shared)
2844 : add_to_list (&destructors, name);
2845 : #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2846 : if (which_pass == PASS_OBJ)
2847 : add_to_list (&exports, name);
2848 : #endif
2849 : break;
2850 :
2851 : #ifdef COLLECT_EXPORT_LIST
2852 : case SYM_INIT:
2853 : if (! (filter & SCAN_INIT))
2854 : break;
2855 : #ifndef LD_INIT_SWITCH
2856 : if (is_shared)
2857 : add_to_list (&constructors, name);
2858 : #endif
2859 : break;
2860 :
2861 : case SYM_FINI:
2862 : if (! (filter & SCAN_FINI))
2863 : break;
2864 : #ifndef LD_INIT_SWITCH
2865 : if (is_shared)
2866 : add_to_list (&destructors, name);
2867 : #endif
2868 : break;
2869 : #endif
2870 :
2871 : case SYM_DWEH:
2872 : if (! (filter & SCAN_DWEH))
2873 : break;
2874 : if (! is_shared)
2875 : add_to_list (&frame_tables, name);
2876 : #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2877 : if (which_pass == PASS_OBJ)
2878 : add_to_list (&exports, name);
2879 : #endif
2880 : break;
2881 :
2882 : default: /* not a constructor or destructor */
2883 : #ifdef COLLECT_EXPORT_LIST
2884 : /* Explicitly export all global symbols when
2885 : building a shared object on AIX, but do not
2886 : re-export symbols from another shared object
2887 : and do not export symbols if the user
2888 : provides an explicit export list. */
2889 : if (shared_obj && !is_shared
2890 : && which_pass == PASS_OBJ && !export_flag)
2891 : {
2892 : /* Do not auto-export __dso_handle or
2893 : __gcc_unwind_dbase. They are required
2894 : to be local to each module. */
2895 : if (strcmp(name, "__dso_handle") != 0
2896 : && strcmp(name, "__gcc_unwind_dbase") != 0)
2897 : {
2898 : add_to_list (&exports, name);
2899 : }
2900 : }
2901 : #endif
2902 : continue;
2903 : }
2904 :
2905 : if (debug)
2906 : fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2907 : symbol.n_scnum, symbol.n_sclass,
2908 : (symbol.n_type ? "0" : ""), symbol.n_type,
2909 : name);
2910 : }
2911 : }
2912 : }
2913 : #ifdef COLLECT_EXPORT_LIST
2914 : else
2915 : {
2916 : /* If archive contains both 32-bit and 64-bit objects,
2917 : we want to skip objects in other mode so mismatch normal. */
2918 : if (debug)
2919 : fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2920 : prog_name, HEADER (ldptr).f_magic, aix64_flag);
2921 : }
2922 : #endif
2923 : }
2924 : else
2925 : {
2926 : fatal_error (input_location, "%s: cannot open as COFF file",
2927 : prog_name);
2928 : }
2929 : #ifdef COLLECT_EXPORT_LIST
2930 : /* On AIX loop continues while there are more members in archive. */
2931 : }
2932 : while (ldclose (ldptr) == FAILURE);
2933 : #else
2934 : /* Otherwise we simply close ldptr. */
2935 : (void) ldclose (ldptr);
2936 : #endif
2937 : }
2938 : #endif /* OBJECT_FORMAT_COFF */
2939 :
2940 : #ifdef COLLECT_EXPORT_LIST
2941 : /* Given a library name without "lib" prefix, this function
2942 : returns a full library name including a path. */
2943 : static char *
2944 : resolve_lib_name (const char *name)
2945 : {
2946 : char *lib_buf;
2947 : int i, j, l = 0;
2948 : /* Library extensions for AIX dynamic linking. */
2949 : const char * const libexts[2] = {"a", "so"};
2950 :
2951 : for (i = 0; libpaths[i]; i++)
2952 : if (libpaths[i]->max_len > l)
2953 : l = libpaths[i]->max_len;
2954 :
2955 : lib_buf = XNEWVEC (char, l + strlen (name) + 10);
2956 :
2957 : for (i = 0; libpaths[i]; i++)
2958 : {
2959 : struct prefix_list *list = libpaths[i]->plist;
2960 : for (; list; list = list->next)
2961 : {
2962 : /* The following lines are needed because path_prefix list
2963 : may contain directories both with trailing DIR_SEPARATOR and
2964 : without it. */
2965 : const char *p = "";
2966 : if (!IS_DIR_SEPARATOR (list->prefix[strlen (list->prefix)-1]))
2967 : p = "/";
2968 : for (j = 0; j < 2; j++)
2969 : {
2970 : sprintf (lib_buf, "%s%slib%s.%s",
2971 : list->prefix, p, name,
2972 : libexts[(j + aixrtl_flag) % 2]);
2973 : if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2974 : if (file_exists (lib_buf))
2975 : {
2976 : if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2977 : return (lib_buf);
2978 : }
2979 : }
2980 : }
2981 : }
2982 : if (debug)
2983 : fprintf (stderr, "not found\n");
2984 : else
2985 : fatal_error (input_location, "library lib%s not found", name);
2986 : return (NULL);
2987 : }
2988 : #endif /* COLLECT_EXPORT_LIST */
2989 :
2990 : #ifdef COLLECT_RUN_DSYMUTIL
2991 : static int flag_dsym = false;
2992 : static int flag_idsym = false;
2993 :
2994 : static void
2995 : process_args (int *argcp, char **argv) {
2996 : int i, j;
2997 : int argc = *argcp;
2998 : for (i=0; i<argc; ++i)
2999 : {
3000 : if (strcmp (argv[i], "-dsym") == 0)
3001 : {
3002 : flag_dsym = true;
3003 : /* Remove the flag, as we handle all processing for it. */
3004 : j = i;
3005 : do
3006 : argv[j] = argv[j+1];
3007 : while (++j < argc);
3008 : --i;
3009 : argc = --(*argcp);
3010 : }
3011 : else if (strcmp (argv[i], "-idsym") == 0)
3012 : {
3013 : flag_idsym = true;
3014 : /* Remove the flag, as we handle all processing for it. */
3015 : j = i;
3016 : do
3017 : argv[j] = argv[j+1];
3018 : while (++j < argc);
3019 : --i;
3020 : argc = --(*argcp);
3021 : }
3022 : }
3023 : }
3024 :
3025 : static void
3026 : do_dsymutil (const char *output_file) {
3027 : const char *dsymutil = 0;
3028 : struct pex_obj *pex;
3029 : char **real_argv = XCNEWVEC (char *, verbose ? 4 : 3);
3030 : const char ** argv = const_cast<const char **> (real_argv);
3031 : /* For cross-builds search the PATH using target-qualified name if we
3032 : have not already found a suitable dsymutil. In practice, all modern
3033 : versions of dsymutil handle all supported archs, however the approach
3034 : here is consistent with the way other installations work (and one can
3035 : always symlink a multitarget dsymutil with a target-specific name). */
3036 : const char *dsname = "dsymutil";
3037 : #ifdef CROSS_DIRECTORY_STRUCTURE
3038 : const char *qname = concat (target_machine, "-", dsname, NULL);
3039 : #else
3040 : const char *qname = dsname;
3041 : #endif
3042 : #ifdef DEFAULT_DSYMUTIL
3043 : /* Configured default takes priority. */
3044 : if (dsymutil == 0 && access (DEFAULT_DSYMUTIL, X_OK) == 0)
3045 : dsymutil = DEFAULT_DSYMUTIL;
3046 : if (dsymutil == 0)
3047 : #endif
3048 : #ifdef DSYMUTIL
3049 : /* Followed by one supplied in the target header, somewhat like the
3050 : REAL_XX_NAME used elsewhere. */
3051 : dsymutil = find_a_file (&cpath, DSYMUTIL, X_OK);
3052 : if (dsymutil == 0)
3053 : dsymutil = find_a_file (&path, DSYMUTIL, X_OK);
3054 : if (dsymutil == 0)
3055 : #endif
3056 : dsymutil = find_a_file (&cpath, dsname, X_OK);
3057 : if (dsymutil == 0)
3058 : dsymutil = find_a_file (&path, qname, X_OK);
3059 :
3060 : argv[0] = dsymutil;
3061 : argv[1] = output_file;
3062 : if (verbose)
3063 : {
3064 : argv[2] = "-v";
3065 : argv[3] = (char *) 0;
3066 : }
3067 : else
3068 : argv[2] = (char *) 0;
3069 :
3070 : pex = collect_execute (dsymutil, real_argv, NULL, NULL,
3071 : PEX_LAST | PEX_SEARCH, false, NULL);
3072 : do_wait (dsymutil, pex);
3073 : }
3074 :
3075 : static void
3076 : post_ld_pass (bool temp_file) {
3077 : if (!(temp_file && flag_idsym) && !flag_dsym)
3078 : return;
3079 :
3080 : do_dsymutil (output_file);
3081 : }
3082 : #else
3083 : static void
3084 0 : process_args (int *argcp ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { }
3085 0 : static void post_ld_pass (bool temp_file ATTRIBUTE_UNUSED) { }
3086 : #endif
|