1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
5 Free Software Foundation, Inc.
6 Contributed by Chris Smith (csmith@convex.com).
7 Heavily modified by Michael Meissner (meissner@cygnus.com),
8 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
10 This file is part of GCC.
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3. If not see
24 <http://www.gnu.org/licenses/>. */
27 /* Build tables of static constructors and destructors and run ld. */
31 #include "coretypes.h"
34 #if ! defined( SIGCHLD ) && defined( SIGCLD )
35 # define SIGCHLD SIGCLD
38 #ifndef LIBRARY_PATH_ENV
39 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
45 #include "collect2-aix.h"
51 /* On certain systems, we have code that works by scanning the object file
52 directly. But this code uses system-specific header files and library
53 functions, so turn it off in a cross-compiler. Likewise, the names of
54 the utilities are not correct for a cross-compiler; we have to hope that
55 cross-versions are in the proper directories. */
57 #ifdef CROSS_DIRECTORY_STRUCTURE
58 #ifndef CROSS_AIX_SUPPORT
59 #undef OBJECT_FORMAT_COFF
62 #undef REAL_LD_FILE_NAME
63 #undef REAL_NM_FILE_NAME
64 #undef REAL_STRIP_FILE_NAME
67 /* If we cannot use a special method, use the ordinary one:
68 run nm to find what symbols are present.
69 In a cross-compiler, this means you need a cross nm,
70 but that is not quite as unpleasant as special headers. */
72 #if !defined (OBJECT_FORMAT_COFF)
73 #define OBJECT_FORMAT_NONE
76 #ifdef OBJECT_FORMAT_COFF
78 #ifndef CROSS_DIRECTORY_STRUCTURE
86 /* Many versions of ldfcn.h define these. */
95 /* Some systems have an ISCOFF macro, but others do not. In some cases
96 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
97 that either do not have an ISCOFF macro in /usr/include or for those
101 #define MY_ISCOFF(X) ISCOFF (X)
104 #endif /* OBJECT_FORMAT_COFF */
106 #ifdef OBJECT_FORMAT_NONE
108 /* Default flags to pass to nm. */
110 #define NM_FLAGS "-n"
113 #endif /* OBJECT_FORMAT_NONE */
115 /* Some systems use __main in a way incompatible with its use in gcc, in these
116 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
117 give the same symbol without quotes for an alternative entry point. */
119 #define NAME__MAIN "__main"
122 /* This must match tree.h. */
123 #define DEFAULT_INIT_PRIORITY 65535
125 #ifndef COLLECT_SHARED_INIT_FUNC
126 #define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
127 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
129 #ifndef COLLECT_SHARED_FINI_FUNC
130 #define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
131 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
135 #define SCAN_LIBRARIES
139 #define SHLIB_SUFFIX ".so"
143 int do_collecting
= 1;
145 int do_collecting
= 0;
148 /* Nonzero if we should suppress the automatic demangling of identifiers
149 in linker error messages. Set from COLLECT_NO_DEMANGLE. */
152 /* Linked lists of constructor and destructor names. */
168 /* Enumeration giving which pass this is for scanning the program file. */
171 PASS_FIRST
, /* without constructors */
172 PASS_OBJ
, /* individual objects */
173 PASS_LIB
, /* looking for shared libraries */
174 PASS_SECOND
/* with constructors linked in */
177 int vflag
; /* true if -v */
178 static int rflag
; /* true if -r */
179 static int strip_flag
; /* true if -s */
180 static const char *demangle_flag
;
181 #ifdef COLLECT_EXPORT_LIST
182 static int export_flag
; /* true if -bE */
183 static int aix64_flag
; /* true if -b64 */
184 static int aixrtl_flag
; /* true if -brtl */
187 int debug
; /* true if -debug */
189 static int shared_obj
; /* true if -shared */
191 static const char *c_file
; /* <xxx>.c for constructor/destructor list. */
192 static const char *o_file
; /* <xxx>.o for constructor/destructor list. */
193 #ifdef COLLECT_EXPORT_LIST
194 static const char *export_file
; /* <xxx>.x for AIX export list. */
196 const char *ldout
; /* File for ld stdout. */
197 const char *lderrout
; /* File for ld stderr. */
198 static const char *output_file
; /* Output file for ld. */
199 static const char *nm_file_name
; /* pathname of nm */
201 static const char *ldd_file_name
; /* pathname of ldd (or equivalent) */
203 static const char *strip_file_name
; /* pathname of strip */
204 const char *c_file_name
; /* pathname of gcc */
205 static char *initname
, *fininame
; /* names of init and fini funcs */
207 static struct head constructors
; /* list of constructors found */
208 static struct head destructors
; /* list of destructors found */
209 #ifdef COLLECT_EXPORT_LIST
210 static struct head exports
; /* list of exported symbols */
212 static struct head frame_tables
; /* list of frame unwind info tables */
214 static bool at_file_supplied
; /* Whether to use @file arguments */
215 static char *response_file
; /* Name of any current response file */
217 struct obstack temporary_obstack
;
218 char * temporary_firstobj
;
220 /* Structure to hold all the directories in which to search for files to
225 const char *prefix
; /* String to prepend to the path. */
226 struct prefix_list
*next
; /* Next in linked list. */
231 struct prefix_list
*plist
; /* List of prefixes to try */
232 int max_len
; /* Max length of a prefix in PLIST */
233 const char *name
; /* Name of this list (used in config stuff) */
236 #ifdef COLLECT_EXPORT_LIST
237 /* Lists to keep libraries to be scanned for global constructors/destructors. */
238 static struct head libs
; /* list of libraries */
239 static struct path_prefix cmdline_lib_dirs
; /* directories specified with -L */
240 static struct path_prefix libpath_lib_dirs
; /* directories in LIBPATH */
241 static struct path_prefix
*libpaths
[3] = {&cmdline_lib_dirs
,
242 &libpath_lib_dirs
, NULL
};
245 /* Special kinds of symbols that a name may denote. */
248 SYM_REGULAR
= 0, /* nothing special */
250 SYM_CTOR
= 1, /* constructor */
251 SYM_DTOR
= 2, /* destructor */
252 SYM_INIT
= 3, /* shared object routine that calls all the ctors */
253 SYM_FINI
= 4, /* shared object routine that calls all the dtors */
254 SYM_DWEH
= 5 /* DWARF exception handling table */
257 static symkind
is_ctor_dtor (const char *);
259 static void handler (int);
260 static char *find_a_file (struct path_prefix
*, const char *);
261 static void add_prefix (struct path_prefix
*, const char *);
262 static void prefix_from_env (const char *, struct path_prefix
*);
263 static void prefix_from_string (const char *, struct path_prefix
*);
264 static void do_wait (const char *, struct pex_obj
*);
265 static void fork_execute (const char *, char **);
266 static void maybe_unlink (const char *);
267 static void add_to_list (struct head
*, const char *);
268 static int extract_init_priority (const char *);
269 static void sort_ids (struct head
*);
270 static void write_list (FILE *, const char *, struct id
*);
271 #ifdef COLLECT_EXPORT_LIST
272 static void dump_list (FILE *, const char *, struct id
*);
275 static void dump_prefix_list (FILE *, const char *, struct prefix_list
*);
277 static void write_list_with_asm (FILE *, const char *, struct id
*);
278 static void write_c_file (FILE *, const char *);
279 static void write_c_file_stat (FILE *, const char *);
280 #ifndef LD_INIT_SWITCH
281 static void write_c_file_glob (FILE *, const char *);
283 static void scan_prog_file (const char *, enum pass
);
284 #ifdef SCAN_LIBRARIES
285 static void scan_libraries (const char *);
287 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
288 static int is_in_args (const char *, const char **, const char **);
290 #ifdef COLLECT_EXPORT_LIST
292 static int is_in_list (const char *, struct id
*);
294 static void write_aix_file (FILE *, struct id
*);
295 static char *resolve_lib_name (const char *);
297 static char *extract_string (const char **);
299 /* Delete tempfiles and exit function. */
302 collect_exit (int status
)
304 if (c_file
!= 0 && c_file
[0])
305 maybe_unlink (c_file
);
307 if (o_file
!= 0 && o_file
[0])
308 maybe_unlink (o_file
);
310 #ifdef COLLECT_EXPORT_LIST
311 if (export_file
!= 0 && export_file
[0])
312 maybe_unlink (export_file
);
315 if (ldout
!= 0 && ldout
[0])
317 dump_file (ldout
, stdout
);
318 maybe_unlink (ldout
);
321 if (lderrout
!= 0 && lderrout
[0])
323 dump_file (lderrout
, stderr
);
324 maybe_unlink (lderrout
);
327 if (status
!= 0 && output_file
!= 0 && output_file
[0])
328 maybe_unlink (output_file
);
331 maybe_unlink (response_file
);
337 /* Notify user of a non-error. */
339 notice (const char *cmsgid
, ...)
343 va_start (ap
, cmsgid
);
344 vfprintf (stderr
, _(cmsgid
), ap
);
348 /* Die when sys call fails. */
351 fatal_perror (const char * cmsgid
, ...)
356 va_start (ap
, cmsgid
);
357 fprintf (stderr
, "collect2: ");
358 vfprintf (stderr
, _(cmsgid
), ap
);
359 fprintf (stderr
, ": %s\n", xstrerror (e
));
362 collect_exit (FATAL_EXIT_CODE
);
368 fatal (const char * cmsgid
, ...)
372 va_start (ap
, cmsgid
);
373 fprintf (stderr
, "collect2: ");
374 vfprintf (stderr
, _(cmsgid
), ap
);
375 fprintf (stderr
, "\n");
378 collect_exit (FATAL_EXIT_CODE
);
381 /* Write error message. */
384 error (const char * gmsgid
, ...)
388 va_start (ap
, gmsgid
);
389 fprintf (stderr
, "collect2: ");
390 vfprintf (stderr
, _(gmsgid
), ap
);
391 fprintf (stderr
, "\n");
395 /* In case obstack is linked in, and abort is defined to fancy_abort,
396 provide a default entry. */
399 fancy_abort (const char *file
, int line
, const char *func
)
401 fatal ("internal gcc abort in %s, at %s:%d", func
, file
, line
);
407 if (c_file
!= 0 && c_file
[0])
408 maybe_unlink (c_file
);
410 if (o_file
!= 0 && o_file
[0])
411 maybe_unlink (o_file
);
413 if (ldout
!= 0 && ldout
[0])
414 maybe_unlink (ldout
);
416 if (lderrout
!= 0 && lderrout
[0])
417 maybe_unlink (lderrout
);
419 #ifdef COLLECT_EXPORT_LIST
420 if (export_file
!= 0 && export_file
[0])
421 maybe_unlink (export_file
);
425 maybe_unlink (response_file
);
427 signal (signo
, SIG_DFL
);
433 file_exists (const char *name
)
435 return access (name
, R_OK
) == 0;
438 /* Parse a reasonable subset of shell quoting syntax. */
441 extract_string (const char **pp
)
454 obstack_1grow (&temporary_obstack
, c
);
455 else if (! inside
&& c
== ' ')
457 else if (! inside
&& c
== '\\')
462 obstack_1grow (&temporary_obstack
, c
);
465 obstack_1grow (&temporary_obstack
, '\0');
467 return XOBFINISH (&temporary_obstack
, char *);
471 dump_file (const char *name
, FILE *to
)
473 FILE *stream
= fopen (name
, "r");
480 while (c
= getc (stream
),
481 c
!= EOF
&& (ISIDNUM (c
) || c
== '$' || c
== '.'))
482 obstack_1grow (&temporary_obstack
, c
);
483 if (obstack_object_size (&temporary_obstack
) > 0)
485 const char *word
, *p
;
487 obstack_1grow (&temporary_obstack
, '\0');
488 word
= XOBFINISH (&temporary_obstack
, const char *);
491 ++word
, putc ('.', to
);
493 if (!strncmp (p
, USER_LABEL_PREFIX
, strlen (USER_LABEL_PREFIX
)))
494 p
+= strlen (USER_LABEL_PREFIX
);
496 #ifdef HAVE_LD_DEMANGLE
502 result
= cplus_demangle (p
, DMGL_PARAMS
| DMGL_ANSI
| DMGL_VERBOSE
);
510 diff
= strlen (word
) - strlen (result
);
511 while (diff
> 0 && c
== ' ')
512 --diff
, putc (' ', to
);
513 if (diff
< 0 && c
== ' ')
515 while (diff
< 0 && c
== ' ')
516 ++diff
, c
= getc (stream
);
519 /* Make sure we output at least one space, or
520 the demangled symbol name will run into
521 whatever text follows. */
532 obstack_free (&temporary_obstack
, temporary_firstobj
);
541 /* Return the kind of symbol denoted by name S. */
544 is_ctor_dtor (const char *s
)
546 struct names
{ const char *const name
; const int len
; symkind ret
;
547 const int two_underscores
; };
549 const struct names
*p
;
551 const char *orig_s
= s
;
553 static const struct names special
[] = {
554 #ifndef NO_DOLLAR_IN_LABEL
555 { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, SYM_CTOR
, 0 },
556 { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, SYM_DTOR
, 0 },
558 #ifndef NO_DOT_IN_LABEL
559 { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, SYM_CTOR
, 0 },
560 { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, SYM_DTOR
, 0 },
561 #endif /* NO_DOT_IN_LABEL */
562 #endif /* NO_DOLLAR_IN_LABEL */
563 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, SYM_CTOR
, 0 },
564 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, SYM_DTOR
, 0 },
565 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, SYM_DWEH
, 0 },
566 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, SYM_INIT
, 0 },
567 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, SYM_FINI
, 0 },
568 { NULL
, 0, SYM_REGULAR
, 0 }
571 while ((ch
= *s
) == '_')
577 for (p
= &special
[0]; p
->len
> 0; p
++)
580 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
581 && strncmp(s
, p
->name
, p
->len
) == 0)
589 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
590 and one from the PATH variable. */
592 static struct path_prefix cpath
, path
;
594 #ifdef CROSS_DIRECTORY_STRUCTURE
595 /* This is the name of the target machine. We use it to form the name
596 of the files to execute. */
598 static const char *const target_machine
= TARGET_MACHINE
;
601 /* Search for NAME using prefix list PPREFIX. We only look for executable
604 Return 0 if not found, otherwise return its name, allocated with malloc. */
607 find_a_file (struct path_prefix
*pprefix
, const char *name
)
610 struct prefix_list
*pl
;
611 int len
= pprefix
->max_len
+ strlen (name
) + 1;
614 fprintf (stderr
, "Looking for '%s'\n", name
);
616 #ifdef HOST_EXECUTABLE_SUFFIX
617 len
+= strlen (HOST_EXECUTABLE_SUFFIX
);
620 temp
= XNEWVEC (char, len
);
622 /* Determine the filename to execute (special case for absolute paths). */
624 if (IS_ABSOLUTE_PATH (name
))
626 if (access (name
, X_OK
) == 0)
631 fprintf (stderr
, " - found: absolute path\n");
636 #ifdef HOST_EXECUTABLE_SUFFIX
637 /* Some systems have a suffix for executable files.
638 So try appending that. */
640 strcat (temp
, HOST_EXECUTABLE_SUFFIX
);
642 if (access (temp
, X_OK
) == 0)
647 fprintf (stderr
, " - failed to locate using absolute path\n");
650 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
654 strcpy (temp
, pl
->prefix
);
657 if (stat (temp
, &st
) >= 0
658 && ! S_ISDIR (st
.st_mode
)
659 && access (temp
, X_OK
) == 0)
662 #ifdef HOST_EXECUTABLE_SUFFIX
663 /* Some systems have a suffix for executable files.
664 So try appending that. */
665 strcat (temp
, HOST_EXECUTABLE_SUFFIX
);
667 if (stat (temp
, &st
) >= 0
668 && ! S_ISDIR (st
.st_mode
)
669 && access (temp
, X_OK
) == 0)
674 if (debug
&& pprefix
->plist
== NULL
)
675 fprintf (stderr
, " - failed: no entries in prefix list\n");
681 /* Add an entry for PREFIX to prefix list PPREFIX. */
684 add_prefix (struct path_prefix
*pprefix
, const char *prefix
)
686 struct prefix_list
*pl
, **prev
;
691 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
696 prev
= &pprefix
->plist
;
698 /* Keep track of the longest prefix. */
700 len
= strlen (prefix
);
701 if (len
> pprefix
->max_len
)
702 pprefix
->max_len
= len
;
704 pl
= XNEW (struct prefix_list
);
705 pl
->prefix
= xstrdup (prefix
);
710 pl
->next
= (struct prefix_list
*) 0;
714 /* Take the value of the environment variable ENV, break it into a path, and
715 add of the entries to PPREFIX. */
718 prefix_from_env (const char *env
, struct path_prefix
*pprefix
)
721 GET_ENVIRONMENT (p
, env
);
724 prefix_from_string (p
, pprefix
);
728 prefix_from_string (const char *p
, struct path_prefix
*pprefix
)
730 const char *startp
, *endp
;
731 char *nstore
= XNEWVEC (char, strlen (p
) + 3);
734 fprintf (stderr
, "Convert string '%s' into prefixes, separator = '%c'\n", p
, PATH_SEPARATOR
);
739 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
741 strncpy (nstore
, startp
, endp
-startp
);
744 strcpy (nstore
, "./");
746 else if (! IS_DIR_SEPARATOR (endp
[-1]))
748 nstore
[endp
-startp
] = DIR_SEPARATOR
;
749 nstore
[endp
-startp
+1] = 0;
752 nstore
[endp
-startp
] = 0;
755 fprintf (stderr
, " - add prefix: %s\n", nstore
);
757 add_prefix (pprefix
, nstore
);
760 endp
= startp
= endp
+ 1;
771 main (int argc
, char **argv
)
773 static const char *const ld_suffix
= "ld";
774 static const char *const real_ld_suffix
= "real-ld";
775 static const char *const collect_ld_suffix
= "collect-ld";
776 static const char *const nm_suffix
= "nm";
777 static const char *const gnm_suffix
= "gnm";
779 static const char *const ldd_suffix
= LDD_SUFFIX
;
781 static const char *const strip_suffix
= "strip";
782 static const char *const gstrip_suffix
= "gstrip";
784 #ifdef CROSS_DIRECTORY_STRUCTURE
785 /* If we look for a program in the compiler directories, we just use
786 the short name, since these directories are already system-specific.
787 But it we look for a program in the system directories, we need to
788 qualify the program name with the target machine. */
790 const char *const full_ld_suffix
=
791 concat(target_machine
, "-", ld_suffix
, NULL
);
792 const char *const full_nm_suffix
=
793 concat (target_machine
, "-", nm_suffix
, NULL
);
794 const char *const full_gnm_suffix
=
795 concat (target_machine
, "-", gnm_suffix
, NULL
);
797 const char *const full_ldd_suffix
=
798 concat (target_machine
, "-", ldd_suffix
, NULL
);
800 const char *const full_strip_suffix
=
801 concat (target_machine
, "-", strip_suffix
, NULL
);
802 const char *const full_gstrip_suffix
=
803 concat (target_machine
, "-", gstrip_suffix
, NULL
);
805 const char *const full_ld_suffix
= ld_suffix
;
806 const char *const full_nm_suffix
= nm_suffix
;
807 const char *const full_gnm_suffix
= gnm_suffix
;
809 const char *const full_ldd_suffix
= ldd_suffix
;
811 const char *const full_strip_suffix
= strip_suffix
;
812 const char *const full_gstrip_suffix
= gstrip_suffix
;
813 #endif /* CROSS_DIRECTORY_STRUCTURE */
817 #ifdef COLLECT_EXPORT_LIST
820 const char *ld_file_name
;
835 expandargv (&argc
, &argv
);
836 if (argv
!= old_argv
)
837 at_file_supplied
= 1;
839 num_c_args
= argc
+ 9;
841 no_demangle
= !! getenv ("COLLECT_NO_DEMANGLE");
843 /* Suppress demangling by the real linker, which may be broken. */
844 putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
846 #if defined (COLLECT2_HOST_INITIALIZATION)
847 /* Perform system dependent initialization, if necessary. */
848 COLLECT2_HOST_INITIALIZATION
;
852 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
853 receive the signal. A different setting is inheritable */
854 signal (SIGCHLD
, SIG_DFL
);
857 /* Unlock the stdio streams. */
858 unlock_std_streams ();
862 /* Do not invoke xcalloc before this point, since locale needs to be
863 set first, in case a diagnostic is issued. */
865 ld1_argv
= XCNEWVEC (char *, argc
+ 4);
866 ld1
= CONST_CAST2 (const char **, char **, ld1_argv
);
867 ld2_argv
= XCNEWVEC (char *, argc
+ 11);
868 ld2
= CONST_CAST2 (const char **, char **, ld2_argv
);
869 object_lst
= XCNEWVEC (char *, argc
);
870 object
= CONST_CAST2 (const char **, char **, object_lst
);
876 /* Parse command line early for instances of -debug. This allows
877 the debug flag to be set before functions like find_a_file()
882 for (i
= 1; argv
[i
] != NULL
; i
++)
884 if (! strcmp (argv
[i
], "-debug"))
890 #ifndef DEFAULT_A_OUT_NAME
891 output_file
= "a.out";
893 output_file
= DEFAULT_A_OUT_NAME
;
896 obstack_begin (&temporary_obstack
, 0);
897 temporary_firstobj
= (char *) obstack_alloc (&temporary_obstack
, 0);
899 #ifndef HAVE_LD_DEMANGLE
900 current_demangling_style
= auto_demangling
;
902 p
= getenv ("COLLECT_GCC_OPTIONS");
905 const char *q
= extract_string (&p
);
906 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
909 obstack_free (&temporary_obstack
, temporary_firstobj
);
911 /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
912 -fno-exceptions -w */
915 c_argv
= XCNEWVEC (char *, num_c_args
);
916 c_ptr
= CONST_CAST2 (const char **, char **, c_argv
);
919 fatal ("no arguments");
922 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
923 signal (SIGQUIT
, handler
);
925 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
926 signal (SIGINT
, handler
);
928 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
929 signal (SIGALRM
, handler
);
932 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
933 signal (SIGHUP
, handler
);
935 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
936 signal (SIGSEGV
, handler
);
938 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
939 signal (SIGBUS
, handler
);
942 /* Extract COMPILER_PATH and PATH into our prefix list. */
943 prefix_from_env ("COMPILER_PATH", &cpath
);
944 prefix_from_env ("PATH", &path
);
946 /* Try to discover a valid linker/nm/strip to use. */
948 /* Maybe we know the right file to use (if not cross). */
950 #ifdef DEFAULT_LINKER
951 if (access (DEFAULT_LINKER
, X_OK
) == 0)
952 ld_file_name
= DEFAULT_LINKER
;
953 if (ld_file_name
== 0)
955 #ifdef REAL_LD_FILE_NAME
956 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
957 if (ld_file_name
== 0)
959 /* Search the (target-specific) compiler dirs for ld'. */
960 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
961 /* Likewise for `collect-ld'. */
962 if (ld_file_name
== 0)
963 ld_file_name
= find_a_file (&cpath
, collect_ld_suffix
);
964 /* Search the compiler directories for `ld'. We have protection against
965 recursive calls in find_a_file. */
966 if (ld_file_name
== 0)
967 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
968 /* Search the ordinary system bin directories
969 for `ld' (if native linking) or `TARGET-ld' (if cross). */
970 if (ld_file_name
== 0)
971 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
973 #ifdef REAL_NM_FILE_NAME
974 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
975 if (nm_file_name
== 0)
977 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
978 if (nm_file_name
== 0)
979 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
980 if (nm_file_name
== 0)
981 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
982 if (nm_file_name
== 0)
983 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
986 ldd_file_name
= find_a_file (&cpath
, ldd_suffix
);
987 if (ldd_file_name
== 0)
988 ldd_file_name
= find_a_file (&path
, full_ldd_suffix
);
991 #ifdef REAL_STRIP_FILE_NAME
992 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
993 if (strip_file_name
== 0)
995 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
996 if (strip_file_name
== 0)
997 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
998 if (strip_file_name
== 0)
999 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
1000 if (strip_file_name
== 0)
1001 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
1003 /* Determine the full path name of the C compiler to use. */
1004 c_file_name
= getenv ("COLLECT_GCC");
1005 if (c_file_name
== 0)
1007 #ifdef CROSS_DIRECTORY_STRUCTURE
1008 c_file_name
= concat (target_machine
, "-gcc", NULL
);
1010 c_file_name
= "gcc";
1014 p
= find_a_file (&cpath
, c_file_name
);
1016 /* Here it should be safe to use the system search path since we should have
1017 already qualified the name of the compiler when it is needed. */
1019 p
= find_a_file (&path
, c_file_name
);
1024 *ld1
++ = *ld2
++ = ld_file_name
;
1026 /* Make temp file names. */
1027 c_file
= make_temp_file (".c");
1028 o_file
= make_temp_file (".o");
1029 #ifdef COLLECT_EXPORT_LIST
1030 export_file
= make_temp_file (".x");
1032 ldout
= make_temp_file (".ld");
1033 lderrout
= make_temp_file (".le");
1034 *c_ptr
++ = c_file_name
;
1041 #ifdef COLLECT_EXPORT_LIST
1042 /* Generate a list of directories from LIBPATH. */
1043 prefix_from_env ("LIBPATH", &libpath_lib_dirs
);
1044 /* Add to this list also two standard directories where
1045 AIX loader always searches for libraries. */
1046 add_prefix (&libpath_lib_dirs
, "/lib");
1047 add_prefix (&libpath_lib_dirs
, "/usr/lib");
1050 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1052 AIX support needs to know if -shared has been specified before
1053 parsing commandline arguments. */
1055 p
= getenv ("COLLECT_GCC_OPTIONS");
1058 const char *q
= extract_string (&p
);
1059 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1060 *c_ptr
++ = xstrdup (q
);
1061 if (strcmp (q
, "-EL") == 0 || strcmp (q
, "-EB") == 0)
1062 *c_ptr
++ = xstrdup (q
);
1063 if (strcmp (q
, "-shared") == 0)
1065 if (*q
== '-' && q
[1] == 'B')
1067 *c_ptr
++ = xstrdup (q
);
1070 q
= extract_string (&p
);
1071 *c_ptr
++ = xstrdup (q
);
1075 obstack_free (&temporary_obstack
, temporary_firstobj
);
1076 *c_ptr
++ = "-fno-profile-arcs";
1077 *c_ptr
++ = "-fno-test-coverage";
1078 *c_ptr
++ = "-fno-branch-probabilities";
1079 *c_ptr
++ = "-fno-exceptions";
1082 /* !!! When GCC calls collect2,
1083 it does not know whether it is calling collect2 or ld.
1084 So collect2 cannot meaningfully understand any options
1085 except those ld understands.
1086 If you propose to make GCC pass some other option,
1087 just imagine what will happen if ld is really ld!!! */
1089 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1090 /* After the first file, put in the c++ rt0. */
1093 #ifdef HAVE_LD_DEMANGLE
1094 if (!demangle_flag
&& !no_demangle
)
1095 demangle_flag
= "--demangle";
1097 *ld1
++ = *ld2
++ = demangle_flag
;
1099 while ((arg
= *++argv
) != (char *) 0)
1101 *ld1
++ = *ld2
++ = arg
;
1107 #ifdef COLLECT_EXPORT_LIST
1108 /* We want to disable automatic exports on AIX when user
1109 explicitly puts an export list in command line */
1111 if (arg
[2] == 'E' || strncmp (&arg
[2], "export", 6) == 0)
1113 else if (arg
[2] == '6' && arg
[3] == '4')
1115 else if (arg
[2] == 'r' && arg
[3] == 't' && arg
[4] == 'l')
1121 if (!strcmp (arg
, "-debug"))
1123 /* Already parsed. */
1127 if (!strcmp (arg
, "-dynamic-linker") && argv
[1])
1130 *ld1
++ = *ld2
++ = *argv
;
1137 /* place o_file BEFORE this argument! */
1143 #ifdef COLLECT_EXPORT_LIST
1145 /* Resolving full library name. */
1146 const char *s
= resolve_lib_name (arg
+2);
1148 /* Saving a full library name. */
1149 add_to_list (&libs
, s
);
1154 #ifdef COLLECT_EXPORT_LIST
1155 /* Saving directories where to search for libraries. */
1157 add_prefix (&cmdline_lib_dirs
, arg
+2);
1160 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1162 if (is_in_args (arg
, (const char **) ld1_argv
, ld1
-1))
1165 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1170 output_file
= *ld1
++ = *ld2
++ = *++argv
;
1172 #ifdef SWITCHES_NEED_SPACES
1173 && ! strchr (SWITCHES_NEED_SPACES
, arg
[1])
1177 output_file
= &arg
[2];
1186 if (arg
[2] == '\0' && do_collecting
)
1188 /* We must strip after the nm run, otherwise C++ linking
1189 will not work. Thus we strip in the second ld run, or
1190 else with strip if there is no second ld run. */
1202 if (strcmp (arg
, "--no-demangle") == 0)
1204 demangle_flag
= arg
;
1209 else if (strncmp (arg
, "--demangle", 10) == 0)
1211 demangle_flag
= arg
;
1213 #ifndef HAVE_LD_DEMANGLE
1216 enum demangling_styles style
1217 = cplus_demangle_name_to_style (arg
+11);
1218 if (style
== unknown_demangling
)
1219 error ("unknown demangling style '%s'", arg
+11);
1221 current_demangling_style
= style
;
1230 else if ((p
= strrchr (arg
, '.')) != (char *) 0
1231 && (strcmp (p
, ".o") == 0 || strcmp (p
, ".a") == 0
1232 || strcmp (p
, ".so") == 0 || strcmp (p
, ".lo") == 0
1233 || strcmp (p
, ".obj") == 0))
1242 /* place o_file BEFORE this argument! */
1248 if (p
[1] == 'o' || p
[1] == 'l')
1250 #ifdef COLLECT_EXPORT_LIST
1251 /* libraries can be specified directly, i.e. without -l flag. */
1254 /* Saving a full library name. */
1255 add_to_list (&libs
, arg
);
1261 #ifdef COLLECT_EXPORT_LIST
1262 /* This is added only for debugging purposes. */
1265 fprintf (stderr
, "List of libraries:\n");
1266 dump_list (stderr
, "\t", libs
.first
);
1269 /* The AIX linker will discard static constructors in object files if
1270 nothing else in the file is referenced, so look at them first. */
1272 const char **export_object_lst
= (const char **)object_lst
;
1274 while (export_object_lst
< object
)
1275 scan_prog_file (*export_object_lst
++, PASS_OBJ
);
1278 struct id
*list
= libs
.first
;
1280 for (; list
; list
= list
->next
)
1281 scan_prog_file (list
->name
, PASS_FIRST
);
1286 char *buf
= concat ("-bE:", export_file
, NULL
);
1291 exportf
= fopen (export_file
, "w");
1292 if (exportf
== (FILE *) 0)
1293 fatal_perror ("fopen %s", export_file
);
1294 write_aix_file (exportf
, exports
.first
);
1295 if (fclose (exportf
))
1296 fatal_perror ("fclose %s", export_file
);
1301 *c_ptr
= *ld1
= *object
= (char *) 0;
1305 notice ("collect2 version %s", version_string
);
1306 #ifdef TARGET_VERSION
1309 fprintf (stderr
, "\n");
1315 fprintf (stderr
, "ld_file_name = %s\n",
1316 (ld_file_name
? ld_file_name
: "not found"));
1317 fprintf (stderr
, "c_file_name = %s\n",
1318 (c_file_name
? c_file_name
: "not found"));
1319 fprintf (stderr
, "nm_file_name = %s\n",
1320 (nm_file_name
? nm_file_name
: "not found"));
1322 fprintf (stderr
, "ldd_file_name = %s\n",
1323 (ldd_file_name
? ldd_file_name
: "not found"));
1325 fprintf (stderr
, "strip_file_name = %s\n",
1326 (strip_file_name
? strip_file_name
: "not found"));
1327 fprintf (stderr
, "c_file = %s\n",
1328 (c_file
? c_file
: "not found"));
1329 fprintf (stderr
, "o_file = %s\n",
1330 (o_file
? o_file
: "not found"));
1332 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1334 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1336 ptr
= getenv ("COLLECT_GCC");
1338 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1340 ptr
= getenv ("COMPILER_PATH");
1342 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1344 ptr
= getenv (LIBRARY_PATH_ENV
);
1346 fprintf (stderr
, "%-20s= %s\n", LIBRARY_PATH_ENV
, ptr
);
1348 fprintf (stderr
, "\n");
1351 /* Load the program, searching all libraries and attempting to provide
1352 undefined symbols from repository information. */
1354 /* On AIX we do this later. */
1355 #ifndef COLLECT_EXPORT_LIST
1356 do_tlink (ld1_argv
, object_lst
);
1359 /* If -r or they will be run via some other method, do not build the
1360 constructor or destructor list, just return now. */
1362 #ifndef COLLECT_EXPORT_LIST
1367 #ifdef COLLECT_EXPORT_LIST
1368 /* Do the link we avoided above if we are exiting. */
1369 do_tlink (ld1_argv
, object_lst
);
1371 /* But make sure we delete the export file we may have created. */
1372 if (export_file
!= 0 && export_file
[0])
1373 maybe_unlink (export_file
);
1375 maybe_unlink (c_file
);
1376 maybe_unlink (o_file
);
1380 /* Examine the namelist with nm and search it for static constructors
1381 and destructors to call.
1382 Write the constructor and destructor tables to a .s file and reload. */
1384 /* On AIX we already scanned for global constructors/destructors. */
1385 #ifndef COLLECT_EXPORT_LIST
1386 scan_prog_file (output_file
, PASS_FIRST
);
1389 #ifdef SCAN_LIBRARIES
1390 scan_libraries (output_file
);
1395 notice ("%d constructor(s) found\n", constructors
.number
);
1396 notice ("%d destructor(s) found\n", destructors
.number
);
1397 notice ("%d frame table(s) found\n", frame_tables
.number
);
1400 if (constructors
.number
== 0 && destructors
.number
== 0
1401 && frame_tables
.number
== 0
1402 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1403 /* If we will be running these functions ourselves, we want to emit
1404 stubs into the shared library so that we do not have to relink
1405 dependent programs when we add static objects. */
1410 #ifdef COLLECT_EXPORT_LIST
1411 /* Do tlink without additional code generation. */
1412 do_tlink (ld1_argv
, object_lst
);
1414 /* Strip now if it was requested on the command line. */
1417 char **real_strip_argv
= XCNEWVEC (char *, 3);
1418 const char ** strip_argv
= CONST_CAST2 (const char **, char **,
1421 strip_argv
[0] = strip_file_name
;
1422 strip_argv
[1] = output_file
;
1423 strip_argv
[2] = (char *) 0;
1424 fork_execute ("strip", real_strip_argv
);
1427 #ifdef COLLECT_EXPORT_LIST
1428 maybe_unlink (export_file
);
1430 maybe_unlink (c_file
);
1431 maybe_unlink (o_file
);
1435 /* Sort ctor and dtor lists by priority. */
1436 sort_ids (&constructors
);
1437 sort_ids (&destructors
);
1439 maybe_unlink(output_file
);
1440 outf
= fopen (c_file
, "w");
1441 if (outf
== (FILE *) 0)
1442 fatal_perror ("fopen %s", c_file
);
1444 write_c_file (outf
, c_file
);
1447 fatal_perror ("fclose %s", c_file
);
1449 /* Tell the linker that we have initializer and finalizer functions. */
1450 #ifdef LD_INIT_SWITCH
1451 #ifdef COLLECT_EXPORT_LIST
1452 *ld2
++ = concat (LD_INIT_SWITCH
, ":", initname
, ":", fininame
, NULL
);
1454 *ld2
++ = LD_INIT_SWITCH
;
1456 *ld2
++ = LD_FINI_SWITCH
;
1461 #ifdef COLLECT_EXPORT_LIST
1464 /* If we did not add export flag to link arguments before, add it to
1465 second link phase now. No new exports should have been added. */
1466 if (! exports
.first
)
1467 *ld2
++ = concat ("-bE:", export_file
, NULL
);
1469 #ifndef LD_INIT_SWITCH
1470 add_to_list (&exports
, initname
);
1471 add_to_list (&exports
, fininame
);
1472 add_to_list (&exports
, "_GLOBAL__DI");
1473 add_to_list (&exports
, "_GLOBAL__DD");
1475 exportf
= fopen (export_file
, "w");
1476 if (exportf
== (FILE *) 0)
1477 fatal_perror ("fopen %s", export_file
);
1478 write_aix_file (exportf
, exports
.first
);
1479 if (fclose (exportf
))
1480 fatal_perror ("fclose %s", export_file
);
1484 /* End of arguments to second link phase. */
1489 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1490 output_file
, c_file
);
1491 write_c_file (stderr
, "stderr");
1492 fprintf (stderr
, "========== end of c_file\n\n");
1493 #ifdef COLLECT_EXPORT_LIST
1494 fprintf (stderr
, "\n========== export_file = %s\n", export_file
);
1495 write_aix_file (stderr
, exports
.first
);
1496 fprintf (stderr
, "========== end of export_file\n\n");
1500 /* Assemble the constructor and destructor tables.
1501 Link the tables in with the rest of the program. */
1503 fork_execute ("gcc", c_argv
);
1504 #ifdef COLLECT_EXPORT_LIST
1505 /* On AIX we must call tlink because of possible templates resolution. */
1506 do_tlink (ld2_argv
, object_lst
);
1508 /* Otherwise, simply call ld because tlink is already done. */
1509 fork_execute ("ld", ld2_argv
);
1511 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1512 constructors/destructors in shared libraries. */
1513 scan_prog_file (output_file
, PASS_SECOND
);
1516 maybe_unlink (c_file
);
1517 maybe_unlink (o_file
);
1519 #ifdef COLLECT_EXPORT_LIST
1520 maybe_unlink (export_file
);
1527 /* Wait for a process to finish, and exit if a nonzero status is found. */
1530 collect_wait (const char *prog
, struct pex_obj
*pex
)
1534 if (!pex_get_status (pex
, 1, &status
))
1535 fatal_perror ("can't get program status");
1540 if (WIFSIGNALED (status
))
1542 int sig
= WTERMSIG (status
);
1543 error ("%s terminated with signal %d [%s]%s",
1544 prog
, sig
, strsignal(sig
),
1545 WCOREDUMP(status
) ? ", core dumped" : "");
1546 collect_exit (FATAL_EXIT_CODE
);
1549 if (WIFEXITED (status
))
1550 return WEXITSTATUS (status
);
1556 do_wait (const char *prog
, struct pex_obj
*pex
)
1558 int ret
= collect_wait (prog
, pex
);
1561 error ("%s returned %d exit status", prog
, ret
);
1567 unlink (response_file
);
1568 response_file
= NULL
;
1573 /* Execute a program, and wait for the reply. */
1576 collect_execute (const char *prog
, char **argv
, const char *outname
,
1577 const char *errname
)
1579 struct pex_obj
*pex
;
1582 char *response_arg
= NULL
;
1583 char *response_argv
[3] ATTRIBUTE_UNUSED
;
1585 if (HAVE_GNU_LD
&& at_file_supplied
&& argv
[0] != NULL
)
1587 /* If using @file arguments, create a temporary file and put the
1588 contents of argv into it. Then change argv to an array corresponding
1589 to a single argument @FILE, where FILE is the temporary filename. */
1591 char **current_argv
= argv
+ 1;
1592 char *argv0
= argv
[0];
1596 /* Note: we assume argv contains at least one element; this is
1599 response_file
= make_temp_file ("");
1601 f
= fopen (response_file
, "w");
1604 fatal ("could not open response file %s", response_file
);
1606 status
= writeargv (current_argv
, f
);
1609 fatal ("could not write to response file %s", response_file
);
1611 status
= fclose (f
);
1614 fatal ("could not close response file %s", response_file
);
1616 response_arg
= concat ("@", response_file
, NULL
);
1617 response_argv
[0] = argv0
;
1618 response_argv
[1] = response_arg
;
1619 response_argv
[2] = NULL
;
1621 argv
= response_argv
;
1630 fprintf (stderr
, "%s", argv
[0]);
1632 notice ("[cannot find %s]", prog
);
1634 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *) 0; p_argv
++)
1635 fprintf (stderr
, " %s", str
);
1637 fprintf (stderr
, "\n");
1643 /* If we cannot find a program we need, complain error. Do this here
1644 since we might not end up needing something that we could not find. */
1647 fatal ("cannot find '%s'", prog
);
1649 pex
= pex_init (0, "collect2", NULL
);
1651 fatal_perror ("pex_init failed");
1653 errmsg
= pex_run (pex
, PEX_LAST
| PEX_SEARCH
, argv
[0], argv
, outname
,
1660 fatal_perror (errmsg
);
1667 free (response_arg
);
1673 fork_execute (const char *prog
, char **argv
)
1675 struct pex_obj
*pex
;
1677 pex
= collect_execute (prog
, argv
, NULL
, NULL
);
1678 do_wait (prog
, pex
);
1681 /* Unlink a file unless we are debugging. */
1684 maybe_unlink (const char *file
)
1687 unlink_if_ordinary (file
);
1689 notice ("[Leaving %s]\n", file
);
1693 static long sequence_number
= 0;
1695 /* Add a name to a linked list. */
1698 add_to_list (struct head
*head_ptr
, const char *name
)
1701 = (struct id
*) xcalloc (sizeof (struct id
) + strlen (name
), 1);
1703 strcpy (newid
->name
, name
);
1705 if (head_ptr
->first
)
1706 head_ptr
->last
->next
= newid
;
1708 head_ptr
->first
= newid
;
1710 /* Check for duplicate symbols. */
1711 for (p
= head_ptr
->first
;
1712 strcmp (name
, p
->name
) != 0;
1717 head_ptr
->last
->next
= 0;
1722 newid
->sequence
= ++sequence_number
;
1723 head_ptr
->last
= newid
;
1727 /* Grab the init priority number from an init function name that
1728 looks like "_GLOBAL_.I.12345.foo". */
1731 extract_init_priority (const char *name
)
1735 while (name
[pos
] == '_')
1737 pos
+= 10; /* strlen ("GLOBAL__X_") */
1739 /* Extract init_p number from ctor/dtor name. */
1740 pri
= atoi (name
+ pos
);
1741 return pri
? pri
: DEFAULT_INIT_PRIORITY
;
1744 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1745 ctors will be run from right to left, dtors from left to right. */
1748 sort_ids (struct head
*head_ptr
)
1750 /* id holds the current element to insert. id_next holds the next
1751 element to insert. id_ptr iterates through the already sorted elements
1752 looking for the place to insert id. */
1753 struct id
*id
, *id_next
, **id_ptr
;
1755 id
= head_ptr
->first
;
1757 /* We don't have any sorted elements yet. */
1758 head_ptr
->first
= NULL
;
1760 for (; id
; id
= id_next
)
1763 id
->sequence
= extract_init_priority (id
->name
);
1765 for (id_ptr
= &(head_ptr
->first
); ; id_ptr
= &((*id_ptr
)->next
))
1767 /* If the sequence numbers are the same, we put the id from the
1768 file later on the command line later in the list. */
1769 || id
->sequence
> (*id_ptr
)->sequence
1770 /* Hack: do lexical compare, too.
1771 || (id->sequence == (*id_ptr)->sequence
1772 && strcmp (id->name, (*id_ptr)->name) > 0) */
1781 /* Now set the sequence numbers properly so write_c_file works. */
1782 for (id
= head_ptr
->first
; id
; id
= id
->next
)
1783 id
->sequence
= ++sequence_number
;
1786 /* Write: `prefix', the names on list LIST, `suffix'. */
1789 write_list (FILE *stream
, const char *prefix
, struct id
*list
)
1793 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1798 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1799 /* Given a STRING, return nonzero if it occurs in the list in range
1800 [ARGS_BEGIN,ARGS_END). */
1803 is_in_args (const char *string
, const char **args_begin
,
1804 const char **args_end
)
1806 const char **args_pointer
;
1807 for (args_pointer
= args_begin
; args_pointer
!= args_end
; ++args_pointer
)
1808 if (strcmp (string
, *args_pointer
) == 0)
1812 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1814 #ifdef COLLECT_EXPORT_LIST
1815 /* This function is really used only on AIX, but may be useful. */
1818 is_in_list (const char *prefix
, struct id
*list
)
1822 if (!strcmp (prefix
, list
->name
)) return 1;
1828 #endif /* COLLECT_EXPORT_LIST */
1830 /* Added for debugging purpose. */
1831 #ifdef COLLECT_EXPORT_LIST
1833 dump_list (FILE *stream
, const char *prefix
, struct id
*list
)
1837 fprintf (stream
, "%s%s,\n", prefix
, list
->name
);
1845 dump_prefix_list (FILE *stream
, const char *prefix
, struct prefix_list
*list
)
1849 fprintf (stream
, "%s%s,\n", prefix
, list
->prefix
);
1856 write_list_with_asm (FILE *stream
, const char *prefix
, struct id
*list
)
1860 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1861 prefix
, list
->sequence
, list
->name
);
1866 /* Write out the constructor and destructor tables statically (for a shared
1867 object), along with the functions to execute them. */
1870 write_c_file_stat (FILE *stream
, const char *name ATTRIBUTE_UNUSED
)
1874 int frames
= (frame_tables
.number
> 0);
1876 /* Figure out name of output_file, stripping off .so version. */
1877 p
= strrchr (output_file
, '/');
1893 if (strncmp (q
, SHLIB_SUFFIX
, strlen (SHLIB_SUFFIX
)) == 0)
1895 q
+= strlen (SHLIB_SUFFIX
);
1902 /* q points to null at end of the string (or . of the .so version) */
1903 prefix
= XNEWVEC (char, q
- p
+ 1);
1904 strncpy (prefix
, p
, q
- p
);
1906 for (r
= prefix
; *r
; r
++)
1907 if (!ISALNUM ((unsigned char)*r
))
1910 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1911 output_file
, prefix
);
1913 initname
= concat ("_GLOBAL__FI_", prefix
, NULL
);
1914 fininame
= concat ("_GLOBAL__FD_", prefix
, NULL
);
1918 /* Write the tables as C code. */
1920 fprintf (stream
, "static int count;\n");
1921 fprintf (stream
, "typedef void entry_pt();\n");
1922 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1926 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1928 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1929 write_list (stream
, "\t\t&", frame_tables
.first
);
1930 fprintf (stream
, "\t0\n};\n");
1932 /* This must match what's in frame.h. */
1933 fprintf (stream
, "struct object {\n");
1934 fprintf (stream
, " void *pc_begin;\n");
1935 fprintf (stream
, " void *pc_end;\n");
1936 fprintf (stream
, " void *fde_begin;\n");
1937 fprintf (stream
, " void *fde_array;\n");
1938 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1939 fprintf (stream
, " struct object *next;\n");
1940 fprintf (stream
, "};\n");
1942 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1943 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1945 fprintf (stream
, "static void reg_frame () {\n");
1946 fprintf (stream
, "\tstatic struct object ob;\n");
1947 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
1948 fprintf (stream
, "\t}\n");
1950 fprintf (stream
, "static void dereg_frame () {\n");
1951 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
1952 fprintf (stream
, "\t}\n");
1955 fprintf (stream
, "void %s() {\n", initname
);
1956 if (constructors
.number
> 0 || frames
)
1958 fprintf (stream
, "\tstatic entry_pt *ctors[] = {\n");
1959 write_list (stream
, "\t\t", constructors
.first
);
1961 fprintf (stream
, "\treg_frame,\n");
1962 fprintf (stream
, "\t};\n");
1963 fprintf (stream
, "\tentry_pt **p;\n");
1964 fprintf (stream
, "\tif (count++ != 0) return;\n");
1965 fprintf (stream
, "\tp = ctors + %d;\n", constructors
.number
+ frames
);
1966 fprintf (stream
, "\twhile (p > ctors) (*--p)();\n");
1969 fprintf (stream
, "\t++count;\n");
1970 fprintf (stream
, "}\n");
1971 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1972 fprintf (stream
, "void %s() {\n", fininame
);
1973 if (destructors
.number
> 0 || frames
)
1975 fprintf (stream
, "\tstatic entry_pt *dtors[] = {\n");
1976 write_list (stream
, "\t\t", destructors
.first
);
1978 fprintf (stream
, "\tdereg_frame,\n");
1979 fprintf (stream
, "\t};\n");
1980 fprintf (stream
, "\tentry_pt **p;\n");
1981 fprintf (stream
, "\tif (--count != 0) return;\n");
1982 fprintf (stream
, "\tp = dtors;\n");
1983 fprintf (stream
, "\twhile (p < dtors + %d) (*p++)();\n",
1984 destructors
.number
+ frames
);
1986 fprintf (stream
, "}\n");
1990 COLLECT_SHARED_INIT_FUNC(stream
, initname
);
1991 COLLECT_SHARED_FINI_FUNC(stream
, fininame
);
1995 /* Write the constructor/destructor tables. */
1997 #ifndef LD_INIT_SWITCH
1999 write_c_file_glob (FILE *stream
, const char *name ATTRIBUTE_UNUSED
)
2001 /* Write the tables as C code. */
2003 int frames
= (frame_tables
.number
> 0);
2005 fprintf (stream
, "typedef void entry_pt();\n\n");
2007 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
2011 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
2013 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
2014 write_list (stream
, "\t\t&", frame_tables
.first
);
2015 fprintf (stream
, "\t0\n};\n");
2017 /* This must match what's in frame.h. */
2018 fprintf (stream
, "struct object {\n");
2019 fprintf (stream
, " void *pc_begin;\n");
2020 fprintf (stream
, " void *pc_end;\n");
2021 fprintf (stream
, " void *fde_begin;\n");
2022 fprintf (stream
, " void *fde_array;\n");
2023 fprintf (stream
, " __SIZE_TYPE__ count;\n");
2024 fprintf (stream
, " struct object *next;\n");
2025 fprintf (stream
, "};\n");
2027 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
2028 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
2030 fprintf (stream
, "static void reg_frame () {\n");
2031 fprintf (stream
, "\tstatic struct object ob;\n");
2032 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
2033 fprintf (stream
, "\t}\n");
2035 fprintf (stream
, "static void dereg_frame () {\n");
2036 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
2037 fprintf (stream
, "\t}\n");
2040 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
2041 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
+ frames
);
2042 write_list (stream
, "\t", constructors
.first
);
2044 fprintf (stream
, "\treg_frame,\n");
2045 fprintf (stream
, "\t0\n};\n\n");
2047 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
2049 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
2050 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
+ frames
);
2051 write_list (stream
, "\t", destructors
.first
);
2053 fprintf (stream
, "\tdereg_frame,\n");
2054 fprintf (stream
, "\t0\n};\n\n");
2056 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
2057 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
2059 #endif /* ! LD_INIT_SWITCH */
2062 write_c_file (FILE *stream
, const char *name
)
2064 #ifndef LD_INIT_SWITCH
2066 write_c_file_glob (stream
, name
);
2069 write_c_file_stat (stream
, name
);
2072 #ifdef COLLECT_EXPORT_LIST
2074 write_aix_file (FILE *stream
, struct id
*list
)
2076 for (; list
; list
= list
->next
)
2078 fputs (list
->name
, stream
);
2079 putc ('\n', stream
);
2084 #ifdef OBJECT_FORMAT_NONE
2086 /* Generic version to scan the name list of the loaded program for
2087 the symbols g++ uses for static constructors and destructors.
2089 The constructor table begins at __CTOR_LIST__ and contains a count
2090 of the number of pointers (or -1 if the constructors are built in a
2091 separate section by the linker), followed by the pointers to the
2092 constructor functions, terminated with a null pointer. The
2093 destructor table has the same format, and begins at __DTOR_LIST__. */
2096 scan_prog_file (const char *prog_name
, enum pass which_pass
)
2098 void (*int_handler
) (int);
2100 void (*quit_handler
) (int);
2102 char *real_nm_argv
[4];
2103 const char **nm_argv
= CONST_CAST2 (const char **, char**, real_nm_argv
);
2105 struct pex_obj
*pex
;
2111 if (which_pass
== PASS_SECOND
)
2114 /* If we do not have an `nm', complain. */
2115 if (nm_file_name
== 0)
2116 fatal ("cannot find 'nm'");
2118 nm_argv
[argc
++] = nm_file_name
;
2119 if (NM_FLAGS
[0] != '\0')
2120 nm_argv
[argc
++] = NM_FLAGS
;
2122 nm_argv
[argc
++] = prog_name
;
2123 nm_argv
[argc
++] = (char *) 0;
2125 /* Trace if needed. */
2128 const char **p_argv
;
2131 for (p_argv
= &nm_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2132 fprintf (stderr
, " %s", str
);
2134 fprintf (stderr
, "\n");
2140 pex
= pex_init (PEX_USE_PIPES
, "collect2", NULL
);
2142 fatal_perror ("pex_init failed");
2144 errmsg
= pex_run (pex
, 0, nm_file_name
, real_nm_argv
, NULL
, NULL
, &err
);
2150 fatal_perror (errmsg
);
2156 int_handler
= (void (*) (int)) signal (SIGINT
, SIG_IGN
);
2158 quit_handler
= (void (*) (int)) signal (SIGQUIT
, SIG_IGN
);
2161 inf
= pex_read_output (pex
, 0);
2163 fatal_perror ("can't open nm output");
2166 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
2168 /* Read each line of nm output. */
2169 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2174 /* If it contains a constructor or destructor name, add the name
2175 to the appropriate list. */
2177 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
2178 if (ch
== ' ' && p
[1] == 'U' && p
[2] == ' ')
2185 /* Find the end of the symbol name.
2186 Do not include `|', because Encore nm can tack that on the end. */
2187 for (end
= p
; (ch2
= *end
) != '\0' && !ISSPACE (ch2
) && ch2
!= '|';
2193 switch (is_ctor_dtor (name
))
2196 if (which_pass
!= PASS_LIB
)
2197 add_to_list (&constructors
, name
);
2201 if (which_pass
!= PASS_LIB
)
2202 add_to_list (&destructors
, name
);
2206 if (which_pass
!= PASS_LIB
)
2207 fatal ("init function found in object %s", prog_name
);
2208 #ifndef LD_INIT_SWITCH
2209 add_to_list (&constructors
, name
);
2214 if (which_pass
!= PASS_LIB
)
2215 fatal ("fini function found in object %s", prog_name
);
2216 #ifndef LD_FINI_SWITCH
2217 add_to_list (&destructors
, name
);
2222 if (which_pass
!= PASS_LIB
)
2223 add_to_list (&frame_tables
, name
);
2226 default: /* not a constructor or destructor */
2231 fprintf (stderr
, "\t%s\n", buf
);
2235 fprintf (stderr
, "\n");
2237 do_wait (nm_file_name
, pex
);
2239 signal (SIGINT
, int_handler
);
2241 signal (SIGQUIT
, quit_handler
);
2247 /* Use the List Dynamic Dependencies program to find shared libraries that
2248 the output file depends upon and their initialization/finalization
2249 routines, if any. */
2252 scan_libraries (const char *prog_name
)
2254 static struct head libraries
; /* list of shared libraries found */
2256 void (*int_handler
) (int);
2258 void (*quit_handler
) (int);
2260 char *real_ldd_argv
[4];
2261 const char **ldd_argv
= (const char **) real_ldd_argv
;
2263 struct pex_obj
*pex
;
2269 /* If we do not have an `ldd', complain. */
2270 if (ldd_file_name
== 0)
2272 error ("cannot find 'ldd'");
2276 ldd_argv
[argc
++] = ldd_file_name
;
2277 ldd_argv
[argc
++] = prog_name
;
2278 ldd_argv
[argc
++] = (char *) 0;
2280 /* Trace if needed. */
2283 const char **p_argv
;
2286 for (p_argv
= &ldd_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2287 fprintf (stderr
, " %s", str
);
2289 fprintf (stderr
, "\n");
2295 pex
= pex_init (PEX_USE_PIPES
, "collect2", NULL
);
2297 fatal_perror ("pex_init failed");
2299 errmsg
= pex_run (pex
, 0, ldd_file_name
, real_ldd_argv
, NULL
, NULL
, &err
);
2305 fatal_perror (errmsg
);
2311 int_handler
= (void (*) (int)) signal (SIGINT
, SIG_IGN
);
2313 quit_handler
= (void (*) (int)) signal (SIGQUIT
, SIG_IGN
);
2316 inf
= pex_read_output (pex
, 0);
2318 fatal_perror ("can't open ldd output");
2321 notice ("\nldd output with constructors/destructors.\n");
2323 /* Read each line of ldd output. */
2324 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2327 char *name
, *end
, *p
= buf
;
2329 /* Extract names of libraries and add to list. */
2330 PARSE_LDD_OUTPUT (p
);
2335 if (strncmp (name
, "not found", sizeof ("not found") - 1) == 0)
2336 fatal ("dynamic dependency %s not found", buf
);
2338 /* Find the end of the symbol name. */
2340 (ch2
= *end
) != '\0' && ch2
!= '\n' && !ISSPACE (ch2
) && ch2
!= '|';
2345 if (access (name
, R_OK
) == 0)
2346 add_to_list (&libraries
, name
);
2348 fatal ("unable to open dynamic dependency '%s'", buf
);
2351 fprintf (stderr
, "\t%s\n", buf
);
2354 fprintf (stderr
, "\n");
2356 do_wait (ldd_file_name
, pex
);
2358 signal (SIGINT
, int_handler
);
2360 signal (SIGQUIT
, quit_handler
);
2363 /* Now iterate through the library list adding their symbols to
2365 for (list
= libraries
.first
; list
; list
= list
->next
)
2366 scan_prog_file (list
->name
, PASS_LIB
);
2369 #endif /* LDD_SUFFIX */
2371 #endif /* OBJECT_FORMAT_NONE */
2375 * COFF specific stuff.
2378 #ifdef OBJECT_FORMAT_COFF
2380 #if defined (EXTENDED_COFF)
2382 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2383 # define GCC_SYMENT SYMR
2384 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2385 # define GCC_SYMINC(X) (1)
2386 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2387 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2391 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2392 # define GCC_SYMENT SYMENT
2393 # if defined (C_WEAKEXT)
2394 # define GCC_OK_SYMBOL(X) \
2395 (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2396 ((X).n_scnum > N_UNDEF) && \
2398 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2399 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2400 # define GCC_UNDEF_SYMBOL(X) \
2401 (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2402 ((X).n_scnum == N_UNDEF))
2404 # define GCC_OK_SYMBOL(X) \
2405 (((X).n_sclass == C_EXT) && \
2406 ((X).n_scnum > N_UNDEF) && \
2408 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2409 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2410 # define GCC_UNDEF_SYMBOL(X) \
2411 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2413 # define GCC_SYMINC(X) ((X).n_numaux+1)
2414 # define GCC_SYMZERO(X) 0
2416 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2417 #if TARGET_AIX_VERSION >= 51
2418 # define GCC_CHECK_HDR(X) \
2419 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2420 || (HEADER (X).f_magic == 0767 && aix64_flag))
2422 # define GCC_CHECK_HDR(X) \
2423 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2424 || (HEADER (X).f_magic == 0757 && aix64_flag))
2429 #ifdef COLLECT_EXPORT_LIST
2430 /* Array of standard AIX libraries which should not
2431 be scanned for ctors/dtors. */
2432 static const char *const aix_std_libs
[] = {
2440 "/usr/lib/libc_r.a",
2441 "/usr/lib/libm_r.a",
2442 "/usr/lib/threads/libc.a",
2443 "/usr/ccs/lib/libc.a",
2444 "/usr/ccs/lib/libm.a",
2445 "/usr/ccs/lib/libc_r.a",
2446 "/usr/ccs/lib/libm_r.a",
2450 /* This function checks the filename and returns 1
2451 if this name matches the location of a standard AIX library. */
2452 static int ignore_library (const char *);
2454 ignore_library (const char *name
)
2456 const char *const *p
;
2458 for (p
= &aix_std_libs
[0]; *p
!= NULL
; ++p
)
2459 if (strcmp (name
, *p
) == 0)
2463 #endif /* COLLECT_EXPORT_LIST */
2465 #if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2466 extern char *ldgetname (LDFILE
*, GCC_SYMENT
*);
2469 /* COFF version to scan the name list of the loaded program for
2470 the symbols g++ uses for static constructors and destructors.
2472 The constructor table begins at __CTOR_LIST__ and contains a count
2473 of the number of pointers (or -1 if the constructors are built in a
2474 separate section by the linker), followed by the pointers to the
2475 constructor functions, terminated with a null pointer. The
2476 destructor table has the same format, and begins at __DTOR_LIST__. */
2479 scan_prog_file (const char *prog_name
, enum pass which_pass
)
2481 LDFILE
*ldptr
= NULL
;
2482 int sym_index
, sym_count
;
2485 if (which_pass
!= PASS_FIRST
&& which_pass
!= PASS_OBJ
)
2488 #ifdef COLLECT_EXPORT_LIST
2489 /* We do not need scanning for some standard C libraries. */
2490 if (which_pass
== PASS_FIRST
&& ignore_library (prog_name
))
2493 /* On AIX we have a loop, because there is not much difference
2494 between an object and an archive. This trick allows us to
2495 eliminate scan_libraries() function. */
2499 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2500 non-const char * filename parameter, even though it will not
2501 modify that string. So we must cast away const-ness here,
2502 using CONST_CAST to prevent complaints from -Wcast-qual. */
2503 if ((ldptr
= ldopen (CONST_CAST (char *, prog_name
), ldptr
)) != NULL
)
2505 if (! MY_ISCOFF (HEADER (ldptr
).f_magic
))
2506 fatal ("%s: not a COFF file", prog_name
);
2508 if (GCC_CHECK_HDR (ldptr
))
2510 sym_count
= GCC_SYMBOLS (ldptr
);
2511 sym_index
= GCC_SYMZERO (ldptr
);
2513 #ifdef COLLECT_EXPORT_LIST
2514 /* Is current archive member a shared object? */
2515 is_shared
= HEADER (ldptr
).f_flags
& F_SHROBJ
;
2518 while (sym_index
< sym_count
)
2522 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
2524 sym_index
+= GCC_SYMINC (symbol
);
2526 if (GCC_OK_SYMBOL (symbol
))
2530 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2531 continue; /* Should never happen. */
2533 #ifdef XCOFF_DEBUGGING_INFO
2534 /* All AIX function names have a duplicate entry
2535 beginning with a dot. */
2540 switch (is_ctor_dtor (name
))
2544 add_to_list (&constructors
, name
);
2545 #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2546 if (which_pass
== PASS_OBJ
)
2547 add_to_list (&exports
, name
);
2553 add_to_list (&destructors
, name
);
2554 #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2555 if (which_pass
== PASS_OBJ
)
2556 add_to_list (&exports
, name
);
2560 #ifdef COLLECT_EXPORT_LIST
2562 #ifndef LD_INIT_SWITCH
2564 add_to_list (&constructors
, name
);
2569 #ifndef LD_INIT_SWITCH
2571 add_to_list (&destructors
, name
);
2578 add_to_list (&frame_tables
, name
);
2579 #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2580 if (which_pass
== PASS_OBJ
)
2581 add_to_list (&exports
, name
);
2585 default: /* not a constructor or destructor */
2586 #ifdef COLLECT_EXPORT_LIST
2587 /* Explicitly export all global symbols when
2588 building a shared object on AIX, but do not
2589 re-export symbols from another shared object
2590 and do not export symbols if the user
2591 provides an explicit export list. */
2592 if (shared_obj
&& !is_shared
2593 && which_pass
== PASS_OBJ
&& !export_flag
)
2594 add_to_list (&exports
, name
);
2600 #if !defined(EXTENDED_COFF)
2601 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
2602 symbol
.n_scnum
, symbol
.n_sclass
,
2603 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
2607 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2608 symbol
.iss
, (long) symbol
.value
, symbol
.index
, name
);
2613 #ifdef COLLECT_EXPORT_LIST
2616 /* If archive contains both 32-bit and 64-bit objects,
2617 we want to skip objects in other mode so mismatch normal. */
2619 fprintf (stderr
, "%s : magic=%o aix64=%d mismatch\n",
2620 prog_name
, HEADER (ldptr
).f_magic
, aix64_flag
);
2626 fatal ("%s: cannot open as COFF file", prog_name
);
2628 #ifdef COLLECT_EXPORT_LIST
2629 /* On AIX loop continues while there are more members in archive. */
2631 while (ldclose (ldptr
) == FAILURE
);
2633 /* Otherwise we simply close ldptr. */
2634 (void) ldclose(ldptr
);
2637 #endif /* OBJECT_FORMAT_COFF */
2639 #ifdef COLLECT_EXPORT_LIST
2640 /* Given a library name without "lib" prefix, this function
2641 returns a full library name including a path. */
2643 resolve_lib_name (const char *name
)
2647 /* Library extensions for AIX dynamic linking. */
2648 const char * const libexts
[2] = {"a", "so"};
2650 for (i
= 0; libpaths
[i
]; i
++)
2651 if (libpaths
[i
]->max_len
> l
)
2652 l
= libpaths
[i
]->max_len
;
2654 lib_buf
= XNEWVEC (char, l
+ strlen(name
) + 10);
2656 for (i
= 0; libpaths
[i
]; i
++)
2658 struct prefix_list
*list
= libpaths
[i
]->plist
;
2659 for (; list
; list
= list
->next
)
2661 /* The following lines are needed because path_prefix list
2662 may contain directories both with trailing '/' and
2665 if (list
->prefix
[strlen(list
->prefix
)-1] != '/')
2667 for (j
= 0; j
< 2; j
++)
2669 sprintf (lib_buf
, "%s%slib%s.%s",
2670 list
->prefix
, p
, name
,
2671 libexts
[(j
+ aixrtl_flag
) % 2]);
2672 if (debug
) fprintf (stderr
, "searching for: %s\n", lib_buf
);
2673 if (file_exists (lib_buf
))
2675 if (debug
) fprintf (stderr
, "found: %s\n", lib_buf
);
2682 fprintf (stderr
, "not found\n");
2684 fatal ("library lib%s not found", name
);
2687 #endif /* COLLECT_EXPORT_LIST */