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 Free Software Foundation, Inc.
5 Contributed by Chris Smith (csmith@convex.com).
6 Heavily modified by Michael Meissner (meissner@cygnus.com),
7 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
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 #ifdef vfork /* Autoconf may define this to fork for us. */
39 # define VFORK_STRING "fork"
41 # define VFORK_STRING "vfork"
47 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
48 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
51 #ifndef LIBRARY_PATH_ENV
52 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
63 /* On certain systems, we have code that works by scanning the object file
64 directly. But this code uses system-specific header files and library
65 functions, so turn it off in a cross-compiler. Likewise, the names of
66 the utilities are not correct for a cross-compiler; we have to hope that
67 cross-versions are in the proper directories. */
70 #undef SUNOS4_SHARED_LIBRARIES
71 #undef OBJECT_FORMAT_COFF
73 #undef REAL_LD_FILE_NAME
74 #undef REAL_NM_FILE_NAME
75 #undef REAL_STRIP_FILE_NAME
78 /* If we cannot use a special method, use the ordinary one:
79 run nm to find what symbols are present.
80 In a cross-compiler, this means you need a cross nm,
81 but that is not quite as unpleasant as special headers. */
83 #if !defined (OBJECT_FORMAT_COFF)
84 #define OBJECT_FORMAT_NONE
87 #ifdef OBJECT_FORMAT_COFF
96 /* Many versions of ldfcn.h define these. */
104 /* Some systems have an ISCOFF macro, but others do not. In some cases
105 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
106 that either do not have an ISCOFF macro in /usr/include or for those
107 where it is wrong. */
110 #define MY_ISCOFF(X) ISCOFF (X)
113 #endif /* OBJECT_FORMAT_COFF */
115 #ifdef OBJECT_FORMAT_NONE
117 /* Default flags to pass to nm. */
119 #define NM_FLAGS "-n"
122 #endif /* OBJECT_FORMAT_NONE */
124 /* Some systems use __main in a way incompatible with its use in gcc, in these
125 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
126 give the same symbol without quotes for an alternative entry point. */
128 #define NAME__MAIN "__main"
131 /* This must match tree.h. */
132 #define DEFAULT_INIT_PRIORITY 65535
134 #ifndef COLLECT_SHARED_INIT_FUNC
135 #define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
136 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
138 #ifndef COLLECT_SHARED_FINI_FUNC
139 #define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
140 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
143 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
144 #define SCAN_LIBRARIES
148 int do_collecting
= 1;
150 int do_collecting
= 0;
153 /* Nonzero if we should suppress the automatic demangling of identifiers
154 in linker error messages. Set from COLLECT_NO_DEMANGLE. */
157 /* Linked lists of constructor and destructor names. */
173 /* Enumeration giving which pass this is for scanning the program file. */
176 PASS_FIRST
, /* without constructors */
177 PASS_OBJ
, /* individual objects */
178 PASS_LIB
, /* looking for shared libraries */
179 PASS_SECOND
/* with constructors linked in */
182 int vflag
; /* true if -v */
183 static int rflag
; /* true if -r */
184 static int strip_flag
; /* true if -s */
185 #ifdef COLLECT_EXPORT_LIST
186 static int export_flag
; /* true if -bE */
187 static int aix64_flag
; /* true if -b64 */
190 int debug
; /* true if -debug */
192 static int shared_obj
; /* true if -shared */
194 static const char *c_file
; /* <xxx>.c for constructor/destructor list. */
195 static const char *o_file
; /* <xxx>.o for constructor/destructor list. */
196 #ifdef COLLECT_EXPORT_LIST
197 static const char *export_file
; /* <xxx>.x for AIX export list. */
199 const char *ldout
; /* File for ld errors. */
200 static const char *output_file
; /* Output file for ld. */
201 static const char *nm_file_name
; /* pathname of nm */
203 static const char *ldd_file_name
; /* pathname of ldd (or equivalent) */
205 static const char *strip_file_name
; /* pathname of strip */
206 const char *c_file_name
; /* pathname of gcc */
207 static char *initname
, *fininame
; /* names of init and fini funcs */
209 static struct head constructors
; /* list of constructors found */
210 static struct head destructors
; /* list of destructors found */
211 #ifdef COLLECT_EXPORT_LIST
212 static struct head exports
; /* list of exported symbols */
214 static struct head frame_tables
; /* list of frame unwind info tables */
216 struct obstack temporary_obstack
;
217 char * temporary_firstobj
;
219 /* Holds the return value of pexecute and fork. */
222 /* Structure to hold all the directories in which to search for files to
227 const char *prefix
; /* String to prepend to the path. */
228 struct prefix_list
*next
; /* Next in linked list. */
233 struct prefix_list
*plist
; /* List of prefixes to try */
234 int max_len
; /* Max length of a prefix in PLIST */
235 const char *name
; /* Name of this list (used in config stuff) */
238 #ifdef COLLECT_EXPORT_LIST
239 /* Lists to keep libraries to be scanned for global constructors/destructors. */
240 static struct head libs
; /* list of libraries */
241 static struct path_prefix cmdline_lib_dirs
; /* directories specified with -L */
242 static struct path_prefix libpath_lib_dirs
; /* directories in LIBPATH */
243 static struct path_prefix
*libpaths
[3] = {&cmdline_lib_dirs
,
244 &libpath_lib_dirs
, NULL
};
245 static const char *const libexts
[3] = {"a", "so", NULL
}; /* possible library extensions */
248 static void handler (int);
249 static int is_ctor_dtor (const char *);
250 static char *find_a_file (struct path_prefix
*, const char *);
251 static void add_prefix (struct path_prefix
*, const char *);
252 static void prefix_from_env (const char *, struct path_prefix
*);
253 static void prefix_from_string (const char *, struct path_prefix
*);
254 static void do_wait (const char *);
255 static void fork_execute (const char *, char **);
256 static void maybe_unlink (const char *);
257 static void add_to_list (struct head
*, const char *);
258 static int extract_init_priority (const char *);
259 static void sort_ids (struct head
*);
260 static void write_list (FILE *, const char *, struct id
*);
261 #ifdef COLLECT_EXPORT_LIST
262 static void dump_list (FILE *, const char *, struct id
*);
265 static void dump_prefix_list (FILE *, const char *, struct prefix_list
*);
267 static void write_list_with_asm (FILE *, const char *, struct id
*);
268 static void write_c_file (FILE *, const char *);
269 static void write_c_file_stat (FILE *, const char *);
270 #ifndef LD_INIT_SWITCH
271 static void write_c_file_glob (FILE *, const char *);
273 static void scan_prog_file (const char *, enum pass
);
274 #ifdef SCAN_LIBRARIES
275 static void scan_libraries (const char *);
277 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
278 static int is_in_args (const char *, const char **, const char **);
280 #ifdef COLLECT_EXPORT_LIST
282 static int is_in_list (const char *, struct id
*);
284 static void write_aix_file (FILE *, struct id
*);
285 static char *resolve_lib_name (const char *);
287 static char *extract_string (const char **);
291 dup2 (int oldfd
, int newfd
)
300 while ((fd
= dup (oldfd
)) != newfd
&& fd
>= 0) /* good enough for low fd's */
303 close (fdtmp
[--fdx
]);
307 #endif /* ! HAVE_DUP2 */
309 /* Delete tempfiles and exit function. */
312 collect_exit (int status
)
314 if (c_file
!= 0 && c_file
[0])
315 maybe_unlink (c_file
);
317 if (o_file
!= 0 && o_file
[0])
318 maybe_unlink (o_file
);
320 #ifdef COLLECT_EXPORT_LIST
321 if (export_file
!= 0 && export_file
[0])
322 maybe_unlink (export_file
);
325 if (ldout
!= 0 && ldout
[0])
328 maybe_unlink (ldout
);
331 if (status
!= 0 && output_file
!= 0 && output_file
[0])
332 maybe_unlink (output_file
);
338 /* Notify user of a non-error. */
340 notice (const char *msgid
, ...)
344 va_start (ap
, msgid
);
345 vfprintf (stderr
, _(msgid
), ap
);
349 /* Die when sys call fails. */
352 fatal_perror (const char * msgid
, ...)
357 va_start (ap
, msgid
);
358 fprintf (stderr
, "collect2: ");
359 vfprintf (stderr
, _(msgid
), ap
);
360 fprintf (stderr
, ": %s\n", xstrerror (e
));
363 collect_exit (FATAL_EXIT_CODE
);
369 fatal (const char * msgid
, ...)
373 va_start (ap
, msgid
);
374 fprintf (stderr
, "collect2: ");
375 vfprintf (stderr
, _(msgid
), ap
);
376 fprintf (stderr
, "\n");
379 collect_exit (FATAL_EXIT_CODE
);
382 /* Write error message. */
385 error (const char * msgid
, ...)
389 va_start (ap
, msgid
);
390 fprintf (stderr
, "collect2: ");
391 vfprintf (stderr
, _(msgid
), ap
);
392 fprintf (stderr
, "\n");
396 /* In case obstack is linked in, and abort is defined to fancy_abort,
397 provide a default entry. */
402 fatal ("internal error");
408 if (c_file
!= 0 && c_file
[0])
409 maybe_unlink (c_file
);
411 if (o_file
!= 0 && o_file
[0])
412 maybe_unlink (o_file
);
414 if (ldout
!= 0 && ldout
[0])
415 maybe_unlink (ldout
);
417 #ifdef COLLECT_EXPORT_LIST
418 if (export_file
!= 0 && export_file
[0])
419 maybe_unlink (export_file
);
422 signal (signo
, SIG_DFL
);
423 kill (getpid (), signo
);
428 file_exists (const char *name
)
430 return access (name
, R_OK
) == 0;
433 /* Parse a reasonable subset of shell quoting syntax. */
436 extract_string (const char **pp
)
449 obstack_1grow (&temporary_obstack
, c
);
450 else if (! inside
&& c
== ' ')
452 else if (! inside
&& c
== '\\')
457 obstack_1grow (&temporary_obstack
, c
);
460 obstack_1grow (&temporary_obstack
, '\0');
462 return obstack_finish (&temporary_obstack
);
466 dump_file (const char *name
)
468 FILE *stream
= fopen (name
, "r");
475 while (c
= getc (stream
),
476 c
!= EOF
&& (ISIDNUM (c
) || c
== '$' || c
== '.'))
477 obstack_1grow (&temporary_obstack
, c
);
478 if (obstack_object_size (&temporary_obstack
) > 0)
480 const char *word
, *p
;
482 obstack_1grow (&temporary_obstack
, '\0');
483 word
= obstack_finish (&temporary_obstack
);
486 ++word
, putc ('.', stderr
);
488 if (!strncmp (p
, USER_LABEL_PREFIX
, strlen (USER_LABEL_PREFIX
)))
489 p
+= strlen (USER_LABEL_PREFIX
);
494 result
= cplus_demangle (p
, DMGL_PARAMS
| DMGL_ANSI
| DMGL_VERBOSE
);
499 fputs (result
, stderr
);
501 diff
= strlen (word
) - strlen (result
);
502 while (diff
> 0 && c
== ' ')
503 --diff
, putc (' ', stderr
);
504 while (diff
< 0 && c
== ' ')
505 ++diff
, c
= getc (stream
);
510 fputs (word
, stderr
);
513 obstack_free (&temporary_obstack
, temporary_firstobj
);
522 /* Decide whether the given symbol is: a constructor (1), a destructor
523 (2), a routine in a shared object that calls all the constructors
524 (3) or destructors (4), a DWARF exception-handling table (5), or
525 nothing special (0). */
528 is_ctor_dtor (const char *s
)
530 struct names
{ const char *const name
; const int len
; const int ret
;
531 const int two_underscores
; };
533 const struct names
*p
;
535 const char *orig_s
= s
;
537 static const struct names special
[] = {
538 #ifndef NO_DOLLAR_IN_LABEL
539 { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
540 { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
542 #ifndef NO_DOT_IN_LABEL
543 { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
544 { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
545 #endif /* NO_DOT_IN_LABEL */
546 #endif /* NO_DOLLAR_IN_LABEL */
547 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
548 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
549 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
550 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
551 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
555 while ((ch
= *s
) == '_')
561 for (p
= &special
[0]; p
->len
> 0; p
++)
564 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
565 && strncmp(s
, p
->name
, p
->len
) == 0)
573 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
574 and one from the PATH variable. */
576 static struct path_prefix cpath
, path
;
579 /* This is the name of the target machine. We use it to form the name
580 of the files to execute. */
582 static const char *const target_machine
= TARGET_MACHINE
;
585 /* Search for NAME using prefix list PPREFIX. We only look for executable
588 Return 0 if not found, otherwise return its name, allocated with malloc. */
591 find_a_file (struct path_prefix
*pprefix
, const char *name
)
594 struct prefix_list
*pl
;
595 int len
= pprefix
->max_len
+ strlen (name
) + 1;
598 fprintf (stderr
, "Looking for '%s'\n", name
);
600 #ifdef HOST_EXECUTABLE_SUFFIX
601 len
+= strlen (HOST_EXECUTABLE_SUFFIX
);
604 temp
= xmalloc (len
);
606 /* Determine the filename to execute (special case for absolute paths). */
609 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
610 || (*name
&& name
[1] == ':')
614 if (access (name
, X_OK
) == 0)
619 fprintf (stderr
, " - found: absolute path\n");
624 #ifdef HOST_EXECUTABLE_SUFFIX
625 /* Some systems have a suffix for executable files.
626 So try appending that. */
628 strcat (temp
, HOST_EXECUTABLE_SUFFIX
);
630 if (access (temp
, X_OK
) == 0)
635 fprintf (stderr
, " - failed to locate using absolute path\n");
638 for (pl
= pprefix
->plist
; pl
; pl
= pl
->next
)
642 strcpy (temp
, pl
->prefix
);
645 if (stat (temp
, &st
) >= 0
646 && ! S_ISDIR (st
.st_mode
)
647 && access (temp
, X_OK
) == 0)
650 #ifdef HOST_EXECUTABLE_SUFFIX
651 /* Some systems have a suffix for executable files.
652 So try appending that. */
653 strcat (temp
, HOST_EXECUTABLE_SUFFIX
);
655 if (stat (temp
, &st
) >= 0
656 && ! S_ISDIR (st
.st_mode
)
657 && access (temp
, X_OK
) == 0)
662 if (debug
&& pprefix
->plist
== NULL
)
663 fprintf (stderr
, " - failed: no entries in prefix list\n");
669 /* Add an entry for PREFIX to prefix list PPREFIX. */
672 add_prefix (struct path_prefix
*pprefix
, const char *prefix
)
674 struct prefix_list
*pl
, **prev
;
679 for (pl
= pprefix
->plist
; pl
->next
; pl
= pl
->next
)
684 prev
= &pprefix
->plist
;
686 /* Keep track of the longest prefix. */
688 len
= strlen (prefix
);
689 if (len
> pprefix
->max_len
)
690 pprefix
->max_len
= len
;
692 pl
= xmalloc (sizeof (struct prefix_list
));
693 pl
->prefix
= xstrdup (prefix
);
698 pl
->next
= (struct prefix_list
*) 0;
702 /* Take the value of the environment variable ENV, break it into a path, and
703 add of the entries to PPREFIX. */
706 prefix_from_env (const char *env
, struct path_prefix
*pprefix
)
709 GET_ENVIRONMENT (p
, env
);
712 prefix_from_string (p
, pprefix
);
716 prefix_from_string (const char *p
, struct path_prefix
*pprefix
)
718 const char *startp
, *endp
;
719 char *nstore
= xmalloc (strlen (p
) + 3);
722 fprintf (stderr
, "Convert string '%s' into prefixes, separator = '%c'\n", p
, PATH_SEPARATOR
);
727 if (*endp
== PATH_SEPARATOR
|| *endp
== 0)
729 strncpy (nstore
, startp
, endp
-startp
);
732 strcpy (nstore
, "./");
734 else if (! IS_DIR_SEPARATOR (endp
[-1]))
736 nstore
[endp
-startp
] = DIR_SEPARATOR
;
737 nstore
[endp
-startp
+1] = 0;
740 nstore
[endp
-startp
] = 0;
743 fprintf (stderr
, " - add prefix: %s\n", nstore
);
745 add_prefix (pprefix
, nstore
);
748 endp
= startp
= endp
+ 1;
758 main (int argc
, char **argv
)
760 static const char *const ld_suffix
= "ld";
761 static const char *const real_ld_suffix
= "real-ld";
762 static const char *const collect_ld_suffix
= "collect-ld";
763 static const char *const nm_suffix
= "nm";
764 static const char *const gnm_suffix
= "gnm";
766 static const char *const ldd_suffix
= LDD_SUFFIX
;
768 static const char *const strip_suffix
= "strip";
769 static const char *const gstrip_suffix
= "gstrip";
772 /* If we look for a program in the compiler directories, we just use
773 the short name, since these directories are already system-specific.
774 But it we look for a program in the system directories, we need to
775 qualify the program name with the target machine. */
777 const char *const full_ld_suffix
=
778 concat(target_machine
, "-", ld_suffix
, NULL
);
779 const char *const full_nm_suffix
=
780 concat (target_machine
, "-", nm_suffix
, NULL
);
781 const char *const full_gnm_suffix
=
782 concat (target_machine
, "-", gnm_suffix
, NULL
);
784 const char *const full_ldd_suffix
=
785 concat (target_machine
, "-", ldd_suffix
, NULL
);
787 const char *const full_strip_suffix
=
788 concat (target_machine
, "-", strip_suffix
, NULL
);
789 const char *const full_gstrip_suffix
=
790 concat (target_machine
, "-", gstrip_suffix
, NULL
);
792 const char *const full_ld_suffix
= ld_suffix
;
793 const char *const full_nm_suffix
= nm_suffix
;
794 const char *const full_gnm_suffix
= gnm_suffix
;
796 const char *const full_ldd_suffix
= ldd_suffix
;
798 const char *const full_strip_suffix
= strip_suffix
;
799 const char *const full_gstrip_suffix
= gstrip_suffix
;
800 #endif /* CROSS_COMPILE */
804 #ifdef COLLECT_EXPORT_LIST
807 const char *ld_file_name
;
818 int num_c_args
= argc
+9;
820 no_demangle
= !! getenv ("COLLECT_NO_DEMANGLE");
822 /* Suppress demangling by the real linker, which may be broken. */
823 putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
825 #if defined (COLLECT2_HOST_INITIALIZATION)
826 /* Perform system dependent initialization, if necessary. */
827 COLLECT2_HOST_INITIALIZATION
;
831 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
832 receive the signal. A different setting is inheritable */
833 signal (SIGCHLD
, SIG_DFL
);
838 /* Do not invoke xcalloc before this point, since locale needs to be
839 set first, in case a diagnostic is issued. */
841 ld1
= (const char **)(ld1_argv
= xcalloc(sizeof (char *), argc
+3));
842 ld2
= (const char **)(ld2_argv
= xcalloc(sizeof (char *), argc
+10));
843 object
= (const char **)(object_lst
= xcalloc(sizeof (char *), argc
));
849 /* Parse command line early for instances of -debug. This allows
850 the debug flag to be set before functions like find_a_file()
855 for (i
= 1; argv
[i
] != NULL
; i
++)
856 if (! strcmp (argv
[i
], "-debug"))
861 #ifndef DEFAULT_A_OUT_NAME
862 output_file
= "a.out";
864 output_file
= DEFAULT_A_OUT_NAME
;
867 obstack_begin (&temporary_obstack
, 0);
868 temporary_firstobj
= obstack_alloc (&temporary_obstack
, 0);
870 current_demangling_style
= auto_demangling
;
871 p
= getenv ("COLLECT_GCC_OPTIONS");
874 const char *q
= extract_string (&p
);
875 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
878 obstack_free (&temporary_obstack
, temporary_firstobj
);
880 /* -fno-exceptions -w */
883 c_ptr
= (const char **) (c_argv
= xcalloc (sizeof (char *), num_c_args
));
886 fatal ("no arguments");
889 if (signal (SIGQUIT
, SIG_IGN
) != SIG_IGN
)
890 signal (SIGQUIT
, handler
);
892 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
893 signal (SIGINT
, handler
);
895 if (signal (SIGALRM
, SIG_IGN
) != SIG_IGN
)
896 signal (SIGALRM
, handler
);
899 if (signal (SIGHUP
, SIG_IGN
) != SIG_IGN
)
900 signal (SIGHUP
, handler
);
902 if (signal (SIGSEGV
, SIG_IGN
) != SIG_IGN
)
903 signal (SIGSEGV
, handler
);
905 if (signal (SIGBUS
, SIG_IGN
) != SIG_IGN
)
906 signal (SIGBUS
, handler
);
909 /* Extract COMPILER_PATH and PATH into our prefix list. */
910 prefix_from_env ("COMPILER_PATH", &cpath
);
911 prefix_from_env ("PATH", &path
);
913 /* Try to discover a valid linker/nm/strip to use. */
915 /* Maybe we know the right file to use (if not cross). */
917 #ifdef DEFAULT_LINKER
918 if (access (DEFAULT_LINKER
, X_OK
) == 0)
919 ld_file_name
= DEFAULT_LINKER
;
920 if (ld_file_name
== 0)
922 #ifdef REAL_LD_FILE_NAME
923 ld_file_name
= find_a_file (&path
, REAL_LD_FILE_NAME
);
924 if (ld_file_name
== 0)
926 /* Search the (target-specific) compiler dirs for ld'. */
927 ld_file_name
= find_a_file (&cpath
, real_ld_suffix
);
928 /* Likewise for `collect-ld'. */
929 if (ld_file_name
== 0)
930 ld_file_name
= find_a_file (&cpath
, collect_ld_suffix
);
931 /* Search the compiler directories for `ld'. We have protection against
932 recursive calls in find_a_file. */
933 if (ld_file_name
== 0)
934 ld_file_name
= find_a_file (&cpath
, ld_suffix
);
935 /* Search the ordinary system bin directories
936 for `ld' (if native linking) or `TARGET-ld' (if cross). */
937 if (ld_file_name
== 0)
938 ld_file_name
= find_a_file (&path
, full_ld_suffix
);
940 #ifdef REAL_NM_FILE_NAME
941 nm_file_name
= find_a_file (&path
, REAL_NM_FILE_NAME
);
942 if (nm_file_name
== 0)
944 nm_file_name
= find_a_file (&cpath
, gnm_suffix
);
945 if (nm_file_name
== 0)
946 nm_file_name
= find_a_file (&path
, full_gnm_suffix
);
947 if (nm_file_name
== 0)
948 nm_file_name
= find_a_file (&cpath
, nm_suffix
);
949 if (nm_file_name
== 0)
950 nm_file_name
= find_a_file (&path
, full_nm_suffix
);
953 ldd_file_name
= find_a_file (&cpath
, ldd_suffix
);
954 if (ldd_file_name
== 0)
955 ldd_file_name
= find_a_file (&path
, full_ldd_suffix
);
958 #ifdef REAL_STRIP_FILE_NAME
959 strip_file_name
= find_a_file (&path
, REAL_STRIP_FILE_NAME
);
960 if (strip_file_name
== 0)
962 strip_file_name
= find_a_file (&cpath
, gstrip_suffix
);
963 if (strip_file_name
== 0)
964 strip_file_name
= find_a_file (&path
, full_gstrip_suffix
);
965 if (strip_file_name
== 0)
966 strip_file_name
= find_a_file (&cpath
, strip_suffix
);
967 if (strip_file_name
== 0)
968 strip_file_name
= find_a_file (&path
, full_strip_suffix
);
970 /* Determine the full path name of the C compiler to use. */
971 c_file_name
= getenv ("COLLECT_GCC");
972 if (c_file_name
== 0)
975 c_file_name
= concat (target_machine
, "-gcc", NULL
);
981 p
= find_a_file (&cpath
, c_file_name
);
983 /* Here it should be safe to use the system search path since we should have
984 already qualified the name of the compiler when it is needed. */
986 p
= find_a_file (&path
, c_file_name
);
991 *ld1
++ = *ld2
++ = ld_file_name
;
993 /* Make temp file names. */
994 c_file
= make_temp_file (".c");
995 o_file
= make_temp_file (".o");
996 #ifdef COLLECT_EXPORT_LIST
997 export_file
= make_temp_file (".x");
999 ldout
= make_temp_file (".ld");
1000 *c_ptr
++ = c_file_name
;
1007 #ifdef COLLECT_EXPORT_LIST
1008 /* Generate a list of directories from LIBPATH. */
1009 prefix_from_env ("LIBPATH", &libpath_lib_dirs
);
1010 /* Add to this list also two standard directories where
1011 AIX loader always searches for libraries. */
1012 add_prefix (&libpath_lib_dirs
, "/lib");
1013 add_prefix (&libpath_lib_dirs
, "/usr/lib");
1016 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1018 AIX support needs to know if -shared has been specified before
1019 parsing commandline arguments. */
1021 p
= getenv ("COLLECT_GCC_OPTIONS");
1024 const char *q
= extract_string (&p
);
1025 if (*q
== '-' && (q
[1] == 'm' || q
[1] == 'f'))
1026 *c_ptr
++ = xstrdup (q
);
1027 if (strcmp (q
, "-EL") == 0 || strcmp (q
, "-EB") == 0)
1028 *c_ptr
++ = xstrdup (q
);
1029 if (strcmp (q
, "-shared") == 0)
1031 if (*q
== '-' && q
[1] == 'B')
1033 *c_ptr
++ = xstrdup (q
);
1036 q
= extract_string (&p
);
1037 *c_ptr
++ = xstrdup (q
);
1041 obstack_free (&temporary_obstack
, temporary_firstobj
);
1042 *c_ptr
++ = "-fno-exceptions";
1045 /* !!! When GCC calls collect2,
1046 it does not know whether it is calling collect2 or ld.
1047 So collect2 cannot meaningfully understand any options
1048 except those ld understands.
1049 If you propose to make GCC pass some other option,
1050 just imagine what will happen if ld is really ld!!! */
1052 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1053 /* After the first file, put in the c++ rt0. */
1056 while ((arg
= *++argv
) != (char *) 0)
1058 *ld1
++ = *ld2
++ = arg
;
1064 #ifdef COLLECT_EXPORT_LIST
1065 /* We want to disable automatic exports on AIX when user
1066 explicitly puts an export list in command line */
1068 if (arg
[2] == 'E' || strncmp (&arg
[2], "export", 6) == 0)
1070 else if (arg
[2] == '6' && arg
[3] == '4')
1076 if (!strcmp (arg
, "-debug"))
1078 /* Already parsed. */
1087 /* place o_file BEFORE this argument! */
1093 #ifdef COLLECT_EXPORT_LIST
1095 /* Resolving full library name. */
1096 const char *s
= resolve_lib_name (arg
+2);
1098 /* Saving a full library name. */
1099 add_to_list (&libs
, s
);
1104 #ifdef COLLECT_EXPORT_LIST
1105 /* Saving directories where to search for libraries. */
1107 add_prefix (&cmdline_lib_dirs
, arg
+2);
1110 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1112 if (is_in_args (arg
, (const char **) ld1_argv
, ld1
-1))
1115 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1120 output_file
= *ld1
++ = *ld2
++ = *++argv
;
1122 #ifdef SWITCHES_NEED_SPACES
1123 && ! strchr (SWITCHES_NEED_SPACES
, arg
[1])
1127 output_file
= &arg
[2];
1136 if (arg
[2] == '\0' && do_collecting
)
1138 /* We must strip after the nm run, otherwise C++ linking
1139 will not work. Thus we strip in the second ld run, or
1140 else with strip if there is no second ld run. */
1152 else if ((p
= strrchr (arg
, '.')) != (char *) 0
1153 && (strcmp (p
, ".o") == 0 || strcmp (p
, ".a") == 0
1154 || strcmp (p
, ".so") == 0 || strcmp (p
, ".lo") == 0
1155 || strcmp (p
, ".obj") == 0))
1164 /* place o_file BEFORE this argument! */
1170 if (p
[1] == 'o' || p
[1] == 'l')
1172 #ifdef COLLECT_EXPORT_LIST
1173 /* libraries can be specified directly, i.e. without -l flag. */
1176 /* Saving a full library name. */
1177 add_to_list (&libs
, arg
);
1183 #ifdef COLLECT_EXPORT_LIST
1184 /* This is added only for debugging purposes. */
1187 fprintf (stderr
, "List of libraries:\n");
1188 dump_list (stderr
, "\t", libs
.first
);
1191 /* The AIX linker will discard static constructors in object files if
1192 nothing else in the file is referenced, so look at them first. */
1194 const char **export_object_lst
= (const char **)object_lst
;
1196 while (export_object_lst
< object
)
1197 scan_prog_file (*export_object_lst
++, PASS_OBJ
);
1200 struct id
*list
= libs
.first
;
1202 for (; list
; list
= list
->next
)
1203 scan_prog_file (list
->name
, PASS_FIRST
);
1208 char *buf
= concat ("-bE:", export_file
, NULL
);
1213 exportf
= fopen (export_file
, "w");
1214 if (exportf
== (FILE *) 0)
1215 fatal_perror ("fopen %s", export_file
);
1216 write_aix_file (exportf
, exports
.first
);
1217 if (fclose (exportf
))
1218 fatal_perror ("fclose %s", export_file
);
1223 *c_ptr
= *ld1
= *object
= (char *) 0;
1227 notice ("collect2 version %s", version_string
);
1228 #ifdef TARGET_VERSION
1231 fprintf (stderr
, "\n");
1237 fprintf (stderr
, "ld_file_name = %s\n",
1238 (ld_file_name
? ld_file_name
: "not found"));
1239 fprintf (stderr
, "c_file_name = %s\n",
1240 (c_file_name
? c_file_name
: "not found"));
1241 fprintf (stderr
, "nm_file_name = %s\n",
1242 (nm_file_name
? nm_file_name
: "not found"));
1244 fprintf (stderr
, "ldd_file_name = %s\n",
1245 (ldd_file_name
? ldd_file_name
: "not found"));
1247 fprintf (stderr
, "strip_file_name = %s\n",
1248 (strip_file_name
? strip_file_name
: "not found"));
1249 fprintf (stderr
, "c_file = %s\n",
1250 (c_file
? c_file
: "not found"));
1251 fprintf (stderr
, "o_file = %s\n",
1252 (o_file
? o_file
: "not found"));
1254 ptr
= getenv ("COLLECT_GCC_OPTIONS");
1256 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
1258 ptr
= getenv ("COLLECT_GCC");
1260 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
1262 ptr
= getenv ("COMPILER_PATH");
1264 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
1266 ptr
= getenv (LIBRARY_PATH_ENV
);
1268 fprintf (stderr
, "%-20s= %s\n", LIBRARY_PATH_ENV
, ptr
);
1270 fprintf (stderr
, "\n");
1273 /* Load the program, searching all libraries and attempting to provide
1274 undefined symbols from repository information. */
1276 /* On AIX we do this later. */
1277 #ifndef COLLECT_EXPORT_LIST
1278 do_tlink (ld1_argv
, object_lst
);
1281 /* If -r or they will be run via some other method, do not build the
1282 constructor or destructor list, just return now. */
1284 #ifndef COLLECT_EXPORT_LIST
1289 #ifdef COLLECT_EXPORT_LIST
1290 /* Do the link we avoided above if we are exiting. */
1291 do_tlink (ld1_argv
, object_lst
);
1293 /* But make sure we delete the export file we may have created. */
1294 if (export_file
!= 0 && export_file
[0])
1295 maybe_unlink (export_file
);
1297 maybe_unlink (c_file
);
1298 maybe_unlink (o_file
);
1302 /* Examine the namelist with nm and search it for static constructors
1303 and destructors to call.
1304 Write the constructor and destructor tables to a .s file and reload. */
1306 /* On AIX we already scanned for global constructors/destructors. */
1307 #ifndef COLLECT_EXPORT_LIST
1308 scan_prog_file (output_file
, PASS_FIRST
);
1311 #ifdef SCAN_LIBRARIES
1312 scan_libraries (output_file
);
1317 notice ("%d constructor(s) found\n", constructors
.number
);
1318 notice ("%d destructor(s) found\n", destructors
.number
);
1319 notice ("%d frame table(s) found\n", frame_tables
.number
);
1322 if (constructors
.number
== 0 && destructors
.number
== 0
1323 && frame_tables
.number
== 0
1324 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1325 /* If we will be running these functions ourselves, we want to emit
1326 stubs into the shared library so that we do not have to relink
1327 dependent programs when we add static objects. */
1332 #ifdef COLLECT_EXPORT_LIST
1333 /* Do tlink without additional code generation. */
1334 do_tlink (ld1_argv
, object_lst
);
1336 /* Strip now if it was requested on the command line. */
1339 char **real_strip_argv
= xcalloc (sizeof (char *), 3);
1340 const char ** strip_argv
= (const char **) real_strip_argv
;
1342 strip_argv
[0] = strip_file_name
;
1343 strip_argv
[1] = output_file
;
1344 strip_argv
[2] = (char *) 0;
1345 fork_execute ("strip", real_strip_argv
);
1348 #ifdef COLLECT_EXPORT_LIST
1349 maybe_unlink (export_file
);
1351 maybe_unlink (c_file
);
1352 maybe_unlink (o_file
);
1356 /* Sort ctor and dtor lists by priority. */
1357 sort_ids (&constructors
);
1358 sort_ids (&destructors
);
1360 maybe_unlink(output_file
);
1361 outf
= fopen (c_file
, "w");
1362 if (outf
== (FILE *) 0)
1363 fatal_perror ("fopen %s", c_file
);
1365 write_c_file (outf
, c_file
);
1368 fatal_perror ("fclose %s", c_file
);
1370 /* Tell the linker that we have initializer and finalizer functions. */
1371 #ifdef LD_INIT_SWITCH
1372 #ifdef COLLECT_EXPORT_LIST
1373 *ld2
++ = concat (LD_INIT_SWITCH
, ":", initname
, ":", fininame
, NULL
);
1375 *ld2
++ = LD_INIT_SWITCH
;
1377 *ld2
++ = LD_FINI_SWITCH
;
1382 #ifdef COLLECT_EXPORT_LIST
1385 /* If we did not add export flag to link arguments before, add it to
1386 second link phase now. No new exports should have been added. */
1387 if (! exports
.first
)
1388 *ld2
++ = concat ("-bE:", export_file
, NULL
);
1390 add_to_list (&exports
, initname
);
1391 add_to_list (&exports
, fininame
);
1392 add_to_list (&exports
, "_GLOBAL__DI");
1393 add_to_list (&exports
, "_GLOBAL__DD");
1394 exportf
= fopen (export_file
, "w");
1395 if (exportf
== (FILE *) 0)
1396 fatal_perror ("fopen %s", export_file
);
1397 write_aix_file (exportf
, exports
.first
);
1398 if (fclose (exportf
))
1399 fatal_perror ("fclose %s", export_file
);
1403 /* End of arguments to second link phase. */
1408 fprintf (stderr
, "\n========== output_file = %s, c_file = %s\n",
1409 output_file
, c_file
);
1410 write_c_file (stderr
, "stderr");
1411 fprintf (stderr
, "========== end of c_file\n\n");
1412 #ifdef COLLECT_EXPORT_LIST
1413 fprintf (stderr
, "\n========== export_file = %s\n", export_file
);
1414 write_aix_file (stderr
, exports
.first
);
1415 fprintf (stderr
, "========== end of export_file\n\n");
1419 /* Assemble the constructor and destructor tables.
1420 Link the tables in with the rest of the program. */
1422 fork_execute ("gcc", c_argv
);
1423 #ifdef COLLECT_EXPORT_LIST
1424 /* On AIX we must call tlink because of possible templates resolution */
1425 do_tlink (ld2_argv
, object_lst
);
1427 /* Otherwise, simply call ld because tlink is already done */
1428 fork_execute ("ld", ld2_argv
);
1430 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1431 constructors/destructors in shared libraries. */
1432 scan_prog_file (output_file
, PASS_SECOND
);
1435 maybe_unlink (c_file
);
1436 maybe_unlink (o_file
);
1438 #ifdef COLLECT_EXPORT_LIST
1439 maybe_unlink (export_file
);
1446 /* Wait for a process to finish, and exit if a nonzero status is found. */
1449 collect_wait (const char *prog
)
1453 pwait (pid
, &status
, 0);
1456 if (WIFSIGNALED (status
))
1458 int sig
= WTERMSIG (status
);
1459 error ("%s terminated with signal %d [%s]%s",
1460 prog
, sig
, strsignal(sig
),
1461 WCOREDUMP(status
) ? ", core dumped" : "");
1462 collect_exit (FATAL_EXIT_CODE
);
1465 if (WIFEXITED (status
))
1466 return WEXITSTATUS (status
);
1472 do_wait (const char *prog
)
1474 int ret
= collect_wait (prog
);
1477 error ("%s returned %d exit status", prog
, ret
);
1483 /* Execute a program, and wait for the reply. */
1486 collect_execute (const char *prog
, char **argv
, const char *redir
)
1490 int redir_handle
= -1;
1491 int stdout_save
= -1;
1492 int stderr_save
= -1;
1500 fprintf (stderr
, "%s", argv
[0]);
1502 notice ("[cannot find %s]", prog
);
1504 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *) 0; p_argv
++)
1505 fprintf (stderr
, " %s", str
);
1507 fprintf (stderr
, "\n");
1513 /* If we cannot find a program we need, complain error. Do this here
1514 since we might not end up needing something that we could not find. */
1517 fatal ("cannot find `%s'", prog
);
1521 /* Open response file. */
1522 redir_handle
= open (redir
, O_WRONLY
| O_TRUNC
| O_CREAT
);
1524 /* Duplicate the stdout and stderr file handles
1525 so they can be restored later. */
1526 stdout_save
= dup (STDOUT_FILENO
);
1527 if (stdout_save
== -1)
1528 fatal_perror ("redirecting stdout: %s", redir
);
1529 stderr_save
= dup (STDERR_FILENO
);
1530 if (stderr_save
== -1)
1531 fatal_perror ("redirecting stdout: %s", redir
);
1533 /* Redirect stdout & stderr to our response file. */
1534 dup2 (redir_handle
, STDOUT_FILENO
);
1535 dup2 (redir_handle
, STDERR_FILENO
);
1538 pid
= pexecute (argv
[0], argv
, argv
[0], NULL
, &errmsg_fmt
, &errmsg_arg
,
1539 (PEXECUTE_FIRST
| PEXECUTE_LAST
| PEXECUTE_SEARCH
));
1543 /* Restore stdout and stderr to their previous settings. */
1544 dup2 (stdout_save
, STDOUT_FILENO
);
1545 dup2 (stderr_save
, STDERR_FILENO
);
1547 /* Close response file. */
1548 close (redir_handle
);
1552 fatal_perror (errmsg_fmt
, errmsg_arg
);
1556 fork_execute (const char *prog
, char **argv
)
1558 collect_execute (prog
, argv
, NULL
);
1562 /* Unlink a file unless we are debugging. */
1565 maybe_unlink (const char *file
)
1570 notice ("[Leaving %s]\n", file
);
1574 static long sequence_number
= 0;
1576 /* Add a name to a linked list. */
1579 add_to_list (struct head
*head_ptr
, const char *name
)
1581 struct id
*newid
= xcalloc (sizeof (struct id
) + strlen (name
), 1);
1583 strcpy (newid
->name
, name
);
1585 if (head_ptr
->first
)
1586 head_ptr
->last
->next
= newid
;
1588 head_ptr
->first
= newid
;
1590 /* Check for duplicate symbols. */
1591 for (p
= head_ptr
->first
;
1592 strcmp (name
, p
->name
) != 0;
1597 head_ptr
->last
->next
= 0;
1602 newid
->sequence
= ++sequence_number
;
1603 head_ptr
->last
= newid
;
1607 /* Grab the init priority number from an init function name that
1608 looks like "_GLOBAL_.I.12345.foo". */
1611 extract_init_priority (const char *name
)
1615 while (name
[pos
] == '_')
1617 pos
+= 10; /* strlen ("GLOBAL__X_") */
1619 /* Extract init_p number from ctor/dtor name. */
1620 pri
= atoi (name
+ pos
);
1621 return pri
? pri
: DEFAULT_INIT_PRIORITY
;
1624 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1625 ctors will be run from right to left, dtors from left to right. */
1628 sort_ids (struct head
*head_ptr
)
1630 /* id holds the current element to insert. id_next holds the next
1631 element to insert. id_ptr iterates through the already sorted elements
1632 looking for the place to insert id. */
1633 struct id
*id
, *id_next
, **id_ptr
;
1635 id
= head_ptr
->first
;
1637 /* We don't have any sorted elements yet. */
1638 head_ptr
->first
= NULL
;
1640 for (; id
; id
= id_next
)
1643 id
->sequence
= extract_init_priority (id
->name
);
1645 for (id_ptr
= &(head_ptr
->first
); ; id_ptr
= &((*id_ptr
)->next
))
1647 /* If the sequence numbers are the same, we put the id from the
1648 file later on the command line later in the list. */
1649 || id
->sequence
> (*id_ptr
)->sequence
1650 /* Hack: do lexical compare, too.
1651 || (id->sequence == (*id_ptr)->sequence
1652 && strcmp (id->name, (*id_ptr)->name) > 0) */
1661 /* Now set the sequence numbers properly so write_c_file works. */
1662 for (id
= head_ptr
->first
; id
; id
= id
->next
)
1663 id
->sequence
= ++sequence_number
;
1666 /* Write: `prefix', the names on list LIST, `suffix'. */
1669 write_list (FILE *stream
, const char *prefix
, struct id
*list
)
1673 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
1678 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1679 /* Given a STRING, return nonzero if it occurs in the list in range
1680 [ARGS_BEGIN,ARGS_END). */
1683 is_in_args (const char *string
, const char **args_begin
,
1684 const char **args_end
)
1686 const char **args_pointer
;
1687 for (args_pointer
= args_begin
; args_pointer
!= args_end
; ++args_pointer
)
1688 if (strcmp (string
, *args_pointer
) == 0)
1692 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1694 #ifdef COLLECT_EXPORT_LIST
1695 /* This function is really used only on AIX, but may be useful. */
1698 is_in_list (const char *prefix
, struct id
*list
)
1702 if (!strcmp (prefix
, list
->name
)) return 1;
1708 #endif /* COLLECT_EXPORT_LIST */
1710 /* Added for debugging purpose. */
1711 #ifdef COLLECT_EXPORT_LIST
1713 dump_list (FILE *stream
, const char *prefix
, struct id
*list
)
1717 fprintf (stream
, "%s%s,\n", prefix
, list
->name
);
1725 dump_prefix_list (FILE *stream
, const char *prefix
, struct prefix_list
*list
)
1729 fprintf (stream
, "%s%s,\n", prefix
, list
->prefix
);
1736 write_list_with_asm (FILE *stream
, const char *prefix
, struct id
*list
)
1740 fprintf (stream
, "%sx%d __asm__ (\"%s\");\n",
1741 prefix
, list
->sequence
, list
->name
);
1746 /* Write out the constructor and destructor tables statically (for a shared
1747 object), along with the functions to execute them. */
1750 write_c_file_stat (FILE *stream
, const char *name ATTRIBUTE_UNUSED
)
1754 int frames
= (frame_tables
.number
> 0);
1756 /* Figure out name of output_file, stripping off .so version. */
1757 p
= strrchr (output_file
, '/');
1773 if (strncmp (q
, ".so", 3) == 0)
1782 /* q points to null at end of the string (or . of the .so version) */
1783 prefix
= xmalloc (q
- p
+ 1);
1784 strncpy (prefix
, p
, q
- p
);
1786 for (r
= prefix
; *r
; r
++)
1787 if (!ISALNUM ((unsigned char)*r
))
1790 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1791 output_file
, prefix
);
1793 initname
= concat ("_GLOBAL__FI_", prefix
, NULL
);
1794 fininame
= concat ("_GLOBAL__FD_", prefix
, NULL
);
1798 /* Write the tables as C code. */
1800 fprintf (stream
, "static int count;\n");
1801 fprintf (stream
, "typedef void entry_pt();\n");
1802 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1806 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1808 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1809 write_list (stream
, "\t\t&", frame_tables
.first
);
1810 fprintf (stream
, "\t0\n};\n");
1812 /* This must match what's in frame.h. */
1813 fprintf (stream
, "struct object {\n");
1814 fprintf (stream
, " void *pc_begin;\n");
1815 fprintf (stream
, " void *pc_end;\n");
1816 fprintf (stream
, " void *fde_begin;\n");
1817 fprintf (stream
, " void *fde_array;\n");
1818 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1819 fprintf (stream
, " struct object *next;\n");
1820 fprintf (stream
, "};\n");
1822 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1823 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1825 fprintf (stream
, "static void reg_frame () {\n");
1826 fprintf (stream
, "\tstatic struct object ob;\n");
1827 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
1828 fprintf (stream
, "\t}\n");
1830 fprintf (stream
, "static void dereg_frame () {\n");
1831 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
1832 fprintf (stream
, "\t}\n");
1835 fprintf (stream
, "void %s() {\n", initname
);
1836 if (constructors
.number
> 0 || frames
)
1838 fprintf (stream
, "\tstatic entry_pt *ctors[] = {\n");
1839 write_list (stream
, "\t\t", constructors
.first
);
1841 fprintf (stream
, "\treg_frame,\n");
1842 fprintf (stream
, "\t};\n");
1843 fprintf (stream
, "\tentry_pt **p;\n");
1844 fprintf (stream
, "\tif (count++ != 0) return;\n");
1845 fprintf (stream
, "\tp = ctors + %d;\n", constructors
.number
+ frames
);
1846 fprintf (stream
, "\twhile (p > ctors) (*--p)();\n");
1849 fprintf (stream
, "\t++count;\n");
1850 fprintf (stream
, "}\n");
1851 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1852 fprintf (stream
, "void %s() {\n", fininame
);
1853 if (destructors
.number
> 0 || frames
)
1855 fprintf (stream
, "\tstatic entry_pt *dtors[] = {\n");
1856 write_list (stream
, "\t\t", destructors
.first
);
1858 fprintf (stream
, "\tdereg_frame,\n");
1859 fprintf (stream
, "\t};\n");
1860 fprintf (stream
, "\tentry_pt **p;\n");
1861 fprintf (stream
, "\tif (--count != 0) return;\n");
1862 fprintf (stream
, "\tp = dtors;\n");
1863 fprintf (stream
, "\twhile (p < dtors + %d) (*p++)();\n",
1864 destructors
.number
+ frames
);
1866 fprintf (stream
, "}\n");
1870 COLLECT_SHARED_INIT_FUNC(stream
, initname
);
1871 COLLECT_SHARED_FINI_FUNC(stream
, fininame
);
1875 /* Write the constructor/destructor tables. */
1877 #ifndef LD_INIT_SWITCH
1879 write_c_file_glob (FILE *stream
, const char *name ATTRIBUTE_UNUSED
)
1881 /* Write the tables as C code. */
1883 int frames
= (frame_tables
.number
> 0);
1885 fprintf (stream
, "typedef void entry_pt();\n\n");
1887 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
1891 write_list_with_asm (stream
, "extern void *", frame_tables
.first
);
1893 fprintf (stream
, "\tstatic void *frame_table[] = {\n");
1894 write_list (stream
, "\t\t&", frame_tables
.first
);
1895 fprintf (stream
, "\t0\n};\n");
1897 /* This must match what's in frame.h. */
1898 fprintf (stream
, "struct object {\n");
1899 fprintf (stream
, " void *pc_begin;\n");
1900 fprintf (stream
, " void *pc_end;\n");
1901 fprintf (stream
, " void *fde_begin;\n");
1902 fprintf (stream
, " void *fde_array;\n");
1903 fprintf (stream
, " __SIZE_TYPE__ count;\n");
1904 fprintf (stream
, " struct object *next;\n");
1905 fprintf (stream
, "};\n");
1907 fprintf (stream
, "extern void __register_frame_info_table (void *, struct object *);\n");
1908 fprintf (stream
, "extern void *__deregister_frame_info (void *);\n");
1910 fprintf (stream
, "static void reg_frame () {\n");
1911 fprintf (stream
, "\tstatic struct object ob;\n");
1912 fprintf (stream
, "\t__register_frame_info_table (frame_table, &ob);\n");
1913 fprintf (stream
, "\t}\n");
1915 fprintf (stream
, "static void dereg_frame () {\n");
1916 fprintf (stream
, "\t__deregister_frame_info (frame_table);\n");
1917 fprintf (stream
, "\t}\n");
1920 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
1921 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
+ frames
);
1922 write_list (stream
, "\t", constructors
.first
);
1924 fprintf (stream
, "\treg_frame,\n");
1925 fprintf (stream
, "\t0\n};\n\n");
1927 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1929 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
1930 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
+ frames
);
1931 write_list (stream
, "\t", destructors
.first
);
1933 fprintf (stream
, "\tdereg_frame,\n");
1934 fprintf (stream
, "\t0\n};\n\n");
1936 fprintf (stream
, "extern entry_pt %s;\n", NAME__MAIN
);
1937 fprintf (stream
, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN
);
1939 #endif /* ! LD_INIT_SWITCH */
1942 write_c_file (FILE *stream
, const char *name
)
1944 fprintf (stream
, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
1945 #ifndef LD_INIT_SWITCH
1947 write_c_file_glob (stream
, name
);
1950 write_c_file_stat (stream
, name
);
1951 fprintf (stream
, "#ifdef __cplusplus\n}\n#endif\n");
1954 #ifdef COLLECT_EXPORT_LIST
1956 write_aix_file (FILE *stream
, struct id
*list
)
1958 for (; list
; list
= list
->next
)
1960 fputs (list
->name
, stream
);
1961 putc ('\n', stream
);
1966 #ifdef OBJECT_FORMAT_NONE
1968 /* Generic version to scan the name list of the loaded program for
1969 the symbols g++ uses for static constructors and destructors.
1971 The constructor table begins at __CTOR_LIST__ and contains a count
1972 of the number of pointers (or -1 if the constructors are built in a
1973 separate section by the linker), followed by the pointers to the
1974 constructor functions, terminated with a null pointer. The
1975 destructor table has the same format, and begins at __DTOR_LIST__. */
1978 scan_prog_file (const char *prog_name
, enum pass which_pass
)
1980 void (*int_handler
) (int);
1981 void (*quit_handler
) (int);
1982 char *real_nm_argv
[4];
1983 const char **nm_argv
= (const char **) real_nm_argv
;
1989 if (which_pass
== PASS_SECOND
)
1992 /* If we do not have an `nm', complain. */
1993 if (nm_file_name
== 0)
1994 fatal ("cannot find `nm'");
1996 nm_argv
[argc
++] = nm_file_name
;
1997 if (NM_FLAGS
[0] != '\0')
1998 nm_argv
[argc
++] = NM_FLAGS
;
2000 nm_argv
[argc
++] = prog_name
;
2001 nm_argv
[argc
++] = (char *) 0;
2003 if (pipe (pipe_fd
) < 0)
2004 fatal_perror ("pipe");
2006 inf
= fdopen (pipe_fd
[0], "r");
2007 if (inf
== (FILE *) 0)
2008 fatal_perror ("fdopen");
2010 /* Trace if needed. */
2013 const char **p_argv
;
2016 for (p_argv
= &nm_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2017 fprintf (stderr
, " %s", str
);
2019 fprintf (stderr
, "\n");
2025 /* Spawn child nm on pipe. */
2028 fatal_perror (VFORK_STRING
);
2030 if (pid
== 0) /* child context */
2033 if (dup2 (pipe_fd
[1], 1) < 0)
2034 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2036 if (close (pipe_fd
[0]) < 0)
2037 fatal_perror ("close %d", pipe_fd
[0]);
2039 if (close (pipe_fd
[1]) < 0)
2040 fatal_perror ("close %d", pipe_fd
[1]);
2042 execv (nm_file_name
, real_nm_argv
);
2043 fatal_perror ("execv %s", nm_file_name
);
2046 /* Parent context from here on. */
2047 int_handler
= (void (*) (int)) signal (SIGINT
, SIG_IGN
);
2049 quit_handler
= (void (*) (int)) signal (SIGQUIT
, SIG_IGN
);
2052 if (close (pipe_fd
[1]) < 0)
2053 fatal_perror ("close %d", pipe_fd
[1]);
2056 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
2058 /* Read each line of nm output. */
2059 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2064 /* If it contains a constructor or destructor name, add the name
2065 to the appropriate list. */
2067 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
2068 if (ch
== ' ' && p
[1] == 'U' && p
[2] == ' ')
2075 /* Find the end of the symbol name.
2076 Do not include `|', because Encore nm can tack that on the end. */
2077 for (end
= p
; (ch2
= *end
) != '\0' && !ISSPACE (ch2
) && ch2
!= '|';
2083 switch (is_ctor_dtor (name
))
2086 if (which_pass
!= PASS_LIB
)
2087 add_to_list (&constructors
, name
);
2091 if (which_pass
!= PASS_LIB
)
2092 add_to_list (&destructors
, name
);
2096 if (which_pass
!= PASS_LIB
)
2097 fatal ("init function found in object %s", prog_name
);
2098 #ifndef LD_INIT_SWITCH
2099 add_to_list (&constructors
, name
);
2104 if (which_pass
!= PASS_LIB
)
2105 fatal ("fini function found in object %s", prog_name
);
2106 #ifndef LD_FINI_SWITCH
2107 add_to_list (&destructors
, name
);
2112 if (which_pass
!= PASS_LIB
)
2113 add_to_list (&frame_tables
, name
);
2116 default: /* not a constructor or destructor */
2121 fprintf (stderr
, "\t%s\n", buf
);
2125 fprintf (stderr
, "\n");
2127 if (fclose (inf
) != 0)
2128 fatal_perror ("fclose");
2130 do_wait (nm_file_name
);
2132 signal (SIGINT
, int_handler
);
2134 signal (SIGQUIT
, quit_handler
);
2138 #if SUNOS4_SHARED_LIBRARIES
2140 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2141 that the output file depends upon and their initialization/finalization
2142 routines, if any. */
2147 #include <sys/mman.h>
2148 #include <sys/param.h>
2150 #include <sys/dir.h>
2152 /* pointers to the object file */
2153 unsigned object
; /* address of memory mapped file */
2154 unsigned objsize
; /* size of memory mapped to file */
2155 char * code
; /* pointer to code segment */
2156 char * data
; /* pointer to data segment */
2157 struct nlist
*symtab
; /* pointer to symbol table */
2158 struct link_dynamic
*ld
;
2159 struct link_dynamic_2
*ld_2
;
2160 struct head libraries
;
2162 /* Map the file indicated by NAME into memory and store its address. */
2165 mapfile (const char *name
)
2169 if ((fp
= open (name
, O_RDONLY
)) == -1)
2170 fatal ("unable to open file '%s'", name
);
2171 if (fstat (fp
, &s
) == -1)
2172 fatal ("unable to stat file '%s'", name
);
2174 objsize
= s
.st_size
;
2175 object
= (unsigned) mmap (0, objsize
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
,
2177 if (object
== (unsigned)-1)
2178 fatal ("unable to mmap file '%s'", name
);
2183 /* Helpers for locatelib. */
2185 static const char *libname
;
2188 libselect (struct direct
*d
)
2190 return (strncmp (libname
, d
->d_name
, strlen (libname
)) == 0);
2193 /* If one file has an additional numeric extension past LIBNAME, then put
2194 that one first in the sort. If both files have additional numeric
2195 extensions, then put the one with the higher number first in the sort.
2197 We must verify that the extension is numeric, because Sun saves the
2198 original versions of patched libraries with a .FCS extension. Files with
2199 invalid extensions must go last in the sort, so that they will not be used. */
2202 libcompare (struct direct
**d1
, struct direct
**d2
)
2204 int i1
, i2
= strlen (libname
);
2205 char *e1
= (*d1
)->d_name
+ i2
;
2206 char *e2
= (*d2
)->d_name
+ i2
;
2208 while (*e1
&& *e2
&& *e1
== '.' && *e2
== '.'
2209 && e1
[1] && ISDIGIT (e1
[1]) && e2
[1] && ISDIGIT (e2
[1]))
2213 i1
= strtol (e1
, &e1
, 10);
2214 i2
= strtol (e2
, &e2
, 10);
2221 /* It has a valid numeric extension, prefer this one. */
2222 if (*e1
== '.' && e1
[1] && ISDIGIT (e1
[1]))
2224 /* It has an invalid numeric extension, must prefer the other one. */
2230 /* It has a valid numeric extension, prefer this one. */
2231 if (*e2
== '.' && e2
[1] && ISDIGIT (e2
[1]))
2233 /* It has an invalid numeric extension, must prefer the other one. */
2241 /* Given the name NAME of a dynamic dependency, find its pathname and add
2242 it to the list of libraries. */
2245 locatelib (const char *name
)
2247 static const char **l
;
2249 char buf
[MAXPATHLEN
];
2257 /* counting elements in array, need 1 extra for null */
2259 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2263 for (; *ld_rules
!= 0; ld_rules
++)
2264 if (*ld_rules
== ':')
2266 ld_rules
= (char *) (ld_2
->ld_rules
+ code
);
2267 ldr
= xstrdup (ld_rules
);
2269 p
= getenv ("LD_LIBRARY_PATH");
2274 for (q
= p
; *q
!= 0; q
++)
2279 l
= xmalloc ((cnt
+ 3) * sizeof (char *));
2284 for (; *ldr
!= 0; ldr
++)
2294 for (; *q
!= 0; q
++)
2301 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2304 *pp
++ = "/usr/local/lib";
2308 for (pp
= l
; *pp
!= 0 ; pp
++)
2310 struct direct
**namelist
;
2312 if ((entries
= scandir (*pp
, &namelist
, libselect
, libcompare
)) > 0)
2314 sprintf (buf
, "%s/%s", *pp
, namelist
[entries
- 1]->d_name
);
2315 add_to_list (&libraries
, buf
);
2317 fprintf (stderr
, "%s\n", buf
);
2324 notice ("not found\n");
2326 fatal ("dynamic dependency %s not found", name
);
2330 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2331 that it depends upon and any constructors or destructors they contain. */
2334 scan_libraries (const char *prog_name
)
2336 struct exec
*header
;
2338 struct link_object
*lo
;
2339 char buff
[MAXPATHLEN
];
2342 mapfile (prog_name
);
2343 header
= (struct exec
*)object
;
2344 if (N_BADMAG (*header
))
2345 fatal ("bad magic number in file '%s'", prog_name
);
2346 if (header
->a_dynamic
== 0)
2349 code
= (char *) (N_TXTOFF (*header
) + (long) header
);
2350 data
= (char *) (N_DATOFF (*header
) + (long) header
);
2351 symtab
= (struct nlist
*) (N_SYMOFF (*header
) + (long) header
);
2353 if (header
->a_magic
== ZMAGIC
&& header
->a_entry
== 0x20)
2356 ld
= (struct link_dynamic
*) (symtab
->n_value
+ code
);
2362 ld
= (struct link_dynamic
*) data
;
2367 notice ("dynamic dependencies.\n");
2369 ld_2
= (struct link_dynamic_2
*) ((long) ld
->ld_un
.ld_2
+ (long)base
);
2370 for (lo
= (struct link_object
*) ld_2
->ld_need
; lo
;
2371 lo
= (struct link_object
*) lo
->lo_next
)
2374 lo
= (struct link_object
*) ((long) lo
+ code
);
2375 name
= (char *) (code
+ lo
->lo_name
);
2379 fprintf (stderr
, "\t-l%s.%d => ", name
, lo
->lo_major
);
2380 sprintf (buff
, "lib%s.so.%d.%d", name
, lo
->lo_major
, lo
->lo_minor
);
2386 fprintf (stderr
, "\t%s\n", name
);
2387 add_to_list (&libraries
, name
);
2392 fprintf (stderr
, "\n");
2394 /* now iterate through the library list adding their symbols to
2396 for (list
= libraries
.first
; list
; list
= list
->next
)
2397 scan_prog_file (list
->name
, PASS_LIB
);
2400 #else /* SUNOS4_SHARED_LIBRARIES */
2403 /* Use the List Dynamic Dependencies program to find shared libraries that
2404 the output file depends upon and their initialization/finalization
2405 routines, if any. */
2408 scan_libraries (const char *prog_name
)
2410 static struct head libraries
; /* list of shared libraries found */
2412 void (*int_handler
) (int);
2413 void (*quit_handler
) (int);
2414 char *real_ldd_argv
[4];
2415 const char **ldd_argv
= (const char **) real_ldd_argv
;
2421 /* If we do not have an `ldd', complain. */
2422 if (ldd_file_name
== 0)
2424 error ("cannot find `ldd'");
2428 ldd_argv
[argc
++] = ldd_file_name
;
2429 ldd_argv
[argc
++] = prog_name
;
2430 ldd_argv
[argc
++] = (char *) 0;
2432 if (pipe (pipe_fd
) < 0)
2433 fatal_perror ("pipe");
2435 inf
= fdopen (pipe_fd
[0], "r");
2436 if (inf
== (FILE *) 0)
2437 fatal_perror ("fdopen");
2439 /* Trace if needed. */
2442 const char **p_argv
;
2445 for (p_argv
= &ldd_argv
[0]; (str
= *p_argv
) != (char *) 0; p_argv
++)
2446 fprintf (stderr
, " %s", str
);
2448 fprintf (stderr
, "\n");
2454 /* Spawn child ldd on pipe. */
2457 fatal_perror (VFORK_STRING
);
2459 if (pid
== 0) /* child context */
2462 if (dup2 (pipe_fd
[1], 1) < 0)
2463 fatal_perror ("dup2 %d 1", pipe_fd
[1]);
2465 if (close (pipe_fd
[0]) < 0)
2466 fatal_perror ("close %d", pipe_fd
[0]);
2468 if (close (pipe_fd
[1]) < 0)
2469 fatal_perror ("close %d", pipe_fd
[1]);
2471 execv (ldd_file_name
, real_ldd_argv
);
2472 fatal_perror ("execv %s", ldd_file_name
);
2475 /* Parent context from here on. */
2476 int_handler
= (void (*) (int))) signal (SIGINT
, SIG_IGN
;
2478 quit_handler
= (void (*) (int))) signal (SIGQUIT
, SIG_IGN
;
2481 if (close (pipe_fd
[1]) < 0)
2482 fatal_perror ("close %d", pipe_fd
[1]);
2485 notice ("\nldd output with constructors/destructors.\n");
2487 /* Read each line of ldd output. */
2488 while (fgets (buf
, sizeof buf
, inf
) != (char *) 0)
2491 char *name
, *end
, *p
= buf
;
2493 /* Extract names of libraries and add to list. */
2494 PARSE_LDD_OUTPUT (p
);
2499 if (strncmp (name
, "not found", sizeof ("not found") - 1) == 0)
2500 fatal ("dynamic dependency %s not found", buf
);
2502 /* Find the end of the symbol name. */
2504 (ch2
= *end
) != '\0' && ch2
!= '\n' && !ISSPACE (ch2
) && ch2
!= '|';
2509 if (access (name
, R_OK
) == 0)
2510 add_to_list (&libraries
, name
);
2512 fatal ("unable to open dynamic dependency '%s'", buf
);
2515 fprintf (stderr
, "\t%s\n", buf
);
2518 fprintf (stderr
, "\n");
2520 if (fclose (inf
) != 0)
2521 fatal_perror ("fclose");
2523 do_wait (ldd_file_name
);
2525 signal (SIGINT
, int_handler
);
2527 signal (SIGQUIT
, quit_handler
);
2530 /* now iterate through the library list adding their symbols to
2532 for (list
= libraries
.first
; list
; list
= list
->next
)
2533 scan_prog_file (list
->name
, PASS_LIB
);
2536 #endif /* LDD_SUFFIX */
2537 #endif /* SUNOS4_SHARED_LIBRARIES */
2539 #endif /* OBJECT_FORMAT_NONE */
2543 * COFF specific stuff.
2546 #ifdef OBJECT_FORMAT_COFF
2548 #if defined(EXTENDED_COFF)
2550 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2551 # define GCC_SYMENT SYMR
2552 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2553 # define GCC_SYMINC(X) (1)
2554 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2555 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2559 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2560 # define GCC_SYMENT SYMENT
2561 # define GCC_OK_SYMBOL(X) \
2562 (((X).n_sclass == C_EXT) && \
2563 ((X).n_scnum > N_UNDEF) && \
2565 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2566 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2567 # define GCC_UNDEF_SYMBOL(X) \
2568 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2569 # define GCC_SYMINC(X) ((X).n_numaux+1)
2570 # define GCC_SYMZERO(X) 0
2572 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2574 # define GCC_CHECK_HDR(X) \
2575 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2576 || (HEADER (X).f_magic == 0767 && aix64_flag))
2578 # define GCC_CHECK_HDR(X) \
2579 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2580 || (HEADER (X).f_magic == 0757 && aix64_flag))
2585 #ifdef COLLECT_EXPORT_LIST
2586 /* Array of standard AIX libraries which should not
2587 be scanned for ctors/dtors. */
2588 static const char *const aix_std_libs
[] = {
2596 "/usr/lib/libc_r.a",
2597 "/usr/lib/libm_r.a",
2598 "/usr/lib/threads/libc.a",
2599 "/usr/ccs/lib/libc.a",
2600 "/usr/ccs/lib/libm.a",
2601 "/usr/ccs/lib/libc_r.a",
2602 "/usr/ccs/lib/libm_r.a",
2606 /* This function checks the filename and returns 1
2607 if this name matches the location of a standard AIX library. */
2608 static int ignore_library (const char *);
2610 ignore_library (const char *name
)
2612 const char *const *p
= &aix_std_libs
[0];
2613 while (*p
++ != NULL
)
2614 if (! strcmp (name
, *p
)) return 1;
2617 #endif /* COLLECT_EXPORT_LIST */
2619 #if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2620 extern char *ldgetname (LDFILE
*, GCC_SYMENT
*);
2623 /* COFF version to scan the name list of the loaded program for
2624 the symbols g++ uses for static constructors and destructors.
2626 The constructor table begins at __CTOR_LIST__ and contains a count
2627 of the number of pointers (or -1 if the constructors are built in a
2628 separate section by the linker), followed by the pointers to the
2629 constructor functions, terminated with a null pointer. The
2630 destructor table has the same format, and begins at __DTOR_LIST__. */
2633 scan_prog_file (const char *prog_name
, enum pass which_pass
)
2635 LDFILE
*ldptr
= NULL
;
2636 int sym_index
, sym_count
;
2639 if (which_pass
!= PASS_FIRST
&& which_pass
!= PASS_OBJ
)
2642 #ifdef COLLECT_EXPORT_LIST
2643 /* We do not need scanning for some standard C libraries. */
2644 if (which_pass
== PASS_FIRST
&& ignore_library (prog_name
))
2647 /* On AIX we have a loop, because there is not much difference
2648 between an object and an archive. This trick allows us to
2649 eliminate scan_libraries() function. */
2653 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2654 non-const char * filename parameter, even though it will not
2655 modify that string. So we must cast away const-ness here,
2656 which will cause -Wcast-qual to burp. */
2657 if ((ldptr
= ldopen ((char *)prog_name
, ldptr
)) != NULL
)
2659 if (! MY_ISCOFF (HEADER (ldptr
).f_magic
))
2660 fatal ("%s: not a COFF file", prog_name
);
2662 if (GCC_CHECK_HDR (ldptr
))
2664 sym_count
= GCC_SYMBOLS (ldptr
);
2665 sym_index
= GCC_SYMZERO (ldptr
);
2667 #ifdef COLLECT_EXPORT_LIST
2668 /* Is current archive member a shared object? */
2669 is_shared
= HEADER (ldptr
).f_flags
& F_SHROBJ
;
2672 while (sym_index
< sym_count
)
2676 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
2678 sym_index
+= GCC_SYMINC (symbol
);
2680 if (GCC_OK_SYMBOL (symbol
))
2684 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
2685 continue; /* should never happen */
2687 #ifdef XCOFF_DEBUGGING_INFO
2688 /* All AIX function names have a duplicate entry
2689 beginning with a dot. */
2694 switch (is_ctor_dtor (name
))
2698 add_to_list (&constructors
, name
);
2699 #ifdef COLLECT_EXPORT_LIST
2700 if (which_pass
== PASS_OBJ
)
2701 add_to_list (&exports
, name
);
2707 add_to_list (&destructors
, name
);
2708 #ifdef COLLECT_EXPORT_LIST
2709 if (which_pass
== PASS_OBJ
)
2710 add_to_list (&exports
, name
);
2714 #ifdef COLLECT_EXPORT_LIST
2716 #ifndef LD_INIT_SWITCH
2718 add_to_list (&constructors
, name
);
2723 #ifndef LD_INIT_SWITCH
2725 add_to_list (&destructors
, name
);
2732 add_to_list (&frame_tables
, name
);
2733 #ifdef COLLECT_EXPORT_LIST
2734 if (which_pass
== PASS_OBJ
)
2735 add_to_list (&exports
, name
);
2739 default: /* not a constructor or destructor */
2740 #ifdef COLLECT_EXPORT_LIST
2741 /* If we are building a shared object on AIX we need
2742 to explicitly export all global symbols. */
2745 if (which_pass
== PASS_OBJ
&& (! export_flag
))
2746 add_to_list (&exports
, name
);
2753 #if !defined(EXTENDED_COFF)
2754 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
2755 symbol
.n_scnum
, symbol
.n_sclass
,
2756 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
2760 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2761 symbol
.iss
, (long) symbol
.value
, symbol
.index
, name
);
2766 #ifdef COLLECT_EXPORT_LIST
2769 /* If archive contains both 32-bit and 64-bit objects,
2770 we want to skip objects in other mode so mismatch normal. */
2772 fprintf (stderr
, "%s : magic=%o aix64=%d mismatch\n",
2773 prog_name
, HEADER (ldptr
).f_magic
, aix64_flag
);
2779 fatal ("%s: cannot open as COFF file", prog_name
);
2781 #ifdef COLLECT_EXPORT_LIST
2782 /* On AIX loop continues while there are more members in archive. */
2784 while (ldclose (ldptr
) == FAILURE
);
2786 /* Otherwise we simply close ldptr. */
2787 (void) ldclose(ldptr
);
2790 #endif /* OBJECT_FORMAT_COFF */
2792 #ifdef COLLECT_EXPORT_LIST
2793 /* Given a library name without "lib" prefix, this function
2794 returns a full library name including a path. */
2796 resolve_lib_name (const char *name
)
2801 for (i
= 0; libpaths
[i
]; i
++)
2802 if (libpaths
[i
]->max_len
> l
)
2803 l
= libpaths
[i
]->max_len
;
2805 lib_buf
= xmalloc (l
+ strlen(name
) + 10);
2807 for (i
= 0; libpaths
[i
]; i
++)
2809 struct prefix_list
*list
= libpaths
[i
]->plist
;
2810 for (; list
; list
= list
->next
)
2812 /* The following lines are needed because path_prefix list
2813 may contain directories both with trailing '/' and
2816 if (list
->prefix
[strlen(list
->prefix
)-1] != '/')
2818 for (j
= 0; libexts
[j
]; j
++)
2820 sprintf (lib_buf
, "%s%slib%s.%s",
2821 list
->prefix
, p
, name
, libexts
[j
]);
2822 if (debug
) fprintf (stderr
, "searching for: %s\n", lib_buf
);
2823 if (file_exists (lib_buf
))
2825 if (debug
) fprintf (stderr
, "found: %s\n", lib_buf
);
2832 fprintf (stderr
, "not found\n");
2834 fatal ("library lib%s not found", name
);
2837 #endif /* COLLECT_EXPORT_LIST */