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 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. */
32 #if ! defined( SIGCHLD ) && defined( SIGCLD )
33 # define SIGCHLD SIGCLD
36 #ifdef vfork /* Autoconf may define this to fork for us. */
37 # define VFORK_STRING "fork"
39 # define VFORK_STRING "vfork"
45 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
46 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
49 #ifndef LIBRARY_PATH_ENV
50 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
61 /* Obstack allocation and deallocation routines. */
62 #define obstack_chunk_alloc xmalloc
63 #define obstack_chunk_free free
65 /* On certain systems, we have code that works by scanning the object file
66 directly. But this code uses system-specific header files and library
67 functions, so turn it off in a cross-compiler. Likewise, the names of
68 the utilities are not correct for a cross-compiler; we have to hope that
69 cross-versions are in the proper directories. */
72 #undef SUNOS4_SHARED_LIBRARIES
73 #undef OBJECT_FORMAT_COFF
74 #undef OBJECT_FORMAT_ROSE
76 #undef REAL_LD_FILE_NAME
77 #undef REAL_NM_FILE_NAME
78 #undef REAL_STRIP_FILE_NAME
81 /* If we cannot use a special method, use the ordinary one:
82 run nm to find what symbols are present.
83 In a cross-compiler, this means you need a cross nm,
84 but that is not quite as unpleasant as special headers. */
86 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
87 #define OBJECT_FORMAT_NONE
90 #ifdef OBJECT_FORMAT_COFF
99 /* Many versions of ldfcn.h define these. */
107 /* Some systems have an ISCOFF macro, but others do not. In some cases
108 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
109 that either do not have an ISCOFF macro in /usr/include or for those
110 where it is wrong. */
113 #define MY_ISCOFF(X) ISCOFF (X)
116 #endif /* OBJECT_FORMAT_COFF */
118 #ifdef OBJECT_FORMAT_ROSE
125 #include <sys/mman.h>
129 #include <mach_o_format.h>
130 #include <mach_o_header.h>
131 #include <mach_o_vals.h>
132 #include <mach_o_types.h>
134 #endif /* OBJECT_FORMAT_ROSE */
136 #ifdef OBJECT_FORMAT_NONE
138 /* Default flags to pass to nm. */
140 #define NM_FLAGS "-n"
143 #endif /* OBJECT_FORMAT_NONE */
145 /* Some systems use __main in a way incompatible with its use in gcc, in these
146 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
147 give the same symbol without quotes for an alternative entry point. You
148 must define both, or neither. */
150 #define NAME__MAIN "__main"
151 #define SYMBOL__MAIN __main
154 /* This must match tree.h. */
155 #define DEFAULT_INIT_PRIORITY 65535
157 #ifndef COLLECT_SHARED_INIT_FUNC
158 #define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
159 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
161 #ifndef COLLECT_SHARED_FINI_FUNC
162 #define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
163 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
166 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
167 #define SCAN_LIBRARIES
171 int do_collecting = 1;
173 int do_collecting = 0;
176 /* Nonzero if we should suppress the automatic demangling of identifiers
177 in linker error messages. Set from COLLECT_NO_DEMANGLE. */
180 /* Linked lists of constructor and destructor names. */
196 /* Enumeration giving which pass this is for scanning the program file. */
199 PASS_FIRST, /* without constructors */
200 PASS_OBJ, /* individual objects */
201 PASS_LIB, /* looking for shared libraries */
202 PASS_SECOND /* with constructors linked in */
205 int vflag; /* true if -v */
206 static int rflag; /* true if -r */
207 static int strip_flag; /* true if -s */
208 #ifdef COLLECT_EXPORT_LIST
209 static int export_flag; /* true if -bE */
210 static int aix64_flag; /* true if -b64 */
213 int debug; /* true if -debug */
215 static int shared_obj; /* true if -shared */
217 static const char *c_file; /* <xxx>.c for constructor/destructor list. */
218 static const char *o_file; /* <xxx>.o for constructor/destructor list. */
219 #ifdef COLLECT_EXPORT_LIST
220 static const char *export_file; /* <xxx>.x for AIX export list. */
222 const char *ldout; /* File for ld errors. */
223 static const char *output_file; /* Output file for ld. */
224 static const char *nm_file_name; /* pathname of nm */
226 static const char *ldd_file_name; /* pathname of ldd (or equivalent) */
228 static const char *strip_file_name; /* pathname of strip */
229 const char *c_file_name; /* pathname of gcc */
230 static char *initname, *fininame; /* names of init and fini funcs */
232 static struct head constructors; /* list of constructors found */
233 static struct head destructors; /* list of destructors found */
234 #ifdef COLLECT_EXPORT_LIST
235 static struct head exports; /* list of exported symbols */
237 static struct head frame_tables; /* list of frame unwind info tables */
239 struct obstack temporary_obstack;
240 struct obstack permanent_obstack;
241 char * temporary_firstobj;
243 /* Holds the return value of pexecute. */
246 /* Defined in the automatically-generated underscore.c. */
247 extern int prepends_underscore;
249 #ifndef GET_ENV_PATH_LIST
250 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
253 /* Structure to hold all the directories in which to search for files to
258 const char *prefix; /* String to prepend to the path. */
259 struct prefix_list *next; /* Next in linked list. */
264 struct prefix_list *plist; /* List of prefixes to try */
265 int max_len; /* Max length of a prefix in PLIST */
266 const char *name; /* Name of this list (used in config stuff) */
269 #ifdef COLLECT_EXPORT_LIST
270 /* Lists to keep libraries to be scanned for global constructors/destructors. */
271 static struct head libs; /* list of libraries */
272 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
273 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
274 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
275 &libpath_lib_dirs, NULL};
276 static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */
279 static void handler PARAMS ((int));
280 static int is_ctor_dtor PARAMS ((const char *));
281 static char *find_a_file PARAMS ((struct path_prefix *, const char *));
282 static void add_prefix PARAMS ((struct path_prefix *, const char *));
283 static void prefix_from_env PARAMS ((const char *, struct path_prefix *));
284 static void prefix_from_string PARAMS ((const char *, struct path_prefix *));
285 static void do_wait PARAMS ((const char *));
286 static void fork_execute PARAMS ((const char *, char **));
287 static void maybe_unlink PARAMS ((const char *));
288 static void add_to_list PARAMS ((struct head *, const char *));
289 static int extract_init_priority PARAMS ((const char *));
290 static void sort_ids PARAMS ((struct head *));
291 static void write_list PARAMS ((FILE *, const char *, struct id *));
292 #ifdef COLLECT_EXPORT_LIST
293 static void dump_list PARAMS ((FILE *, const char *, struct id *));
296 static void dump_prefix_list PARAMS ((FILE *, const char *, struct prefix_list *));
298 static void write_list_with_asm PARAMS ((FILE *, const char *, struct id *));
299 static void write_c_file PARAMS ((FILE *, const char *));
300 static void write_c_file_stat PARAMS ((FILE *, const char *));
301 #ifndef LD_INIT_SWITCH
302 static void write_c_file_glob PARAMS ((FILE *, const char *));
304 static void scan_prog_file PARAMS ((const char *, enum pass));
305 #ifdef SCAN_LIBRARIES
306 static void scan_libraries PARAMS ((const char *));
308 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
309 static int is_in_args PARAMS ((const char *, const char **, const char **));
311 #ifdef COLLECT_EXPORT_LIST
313 static int is_in_list PARAMS ((const char *, struct id *));
315 static void write_aix_file PARAMS ((FILE *, struct id *));
316 static char *resolve_lib_name PARAMS ((const char *));
317 static int ignore_library PARAMS ((const char *));
319 static char *extract_string PARAMS ((const char **));
322 static int dup2 PARAMS ((int, int));
335 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
338 close (fdtmp[--fdx]);
342 #endif /* ! HAVE_DUP2 */
344 /* Delete tempfiles and exit function. */
347 collect_exit (status)
350 if (c_file != 0 && c_file[0])
351 maybe_unlink (c_file);
353 if (o_file != 0 && o_file[0])
354 maybe_unlink (o_file);
356 #ifdef COLLECT_EXPORT_LIST
357 if (export_file != 0 && export_file[0])
358 maybe_unlink (export_file);
361 if (ldout != 0 && ldout[0])
364 maybe_unlink (ldout);
367 if (status != 0 && output_file != 0 && output_file[0])
368 maybe_unlink (output_file);
374 /* Notify user of a non-error. */
376 notice VPARAMS ((const char *msgid, ...))
379 VA_FIXEDARG (ap, const char *, msgid);
381 vfprintf (stderr, _(msgid), ap);
385 /* Die when sys call fails. */
388 fatal_perror VPARAMS ((const char * msgid, ...))
393 VA_FIXEDARG (ap, const char *, msgid);
395 fprintf (stderr, "collect2: ");
396 vfprintf (stderr, _(msgid), ap);
397 fprintf (stderr, ": %s\n", xstrerror (e));
400 collect_exit (FATAL_EXIT_CODE);
406 fatal VPARAMS ((const char * msgid, ...))
409 VA_FIXEDARG (ap, const char *, msgid);
411 fprintf (stderr, "collect2: ");
412 vfprintf (stderr, _(msgid), ap);
413 fprintf (stderr, "\n");
416 collect_exit (FATAL_EXIT_CODE);
419 /* Write error message. */
422 error VPARAMS ((const char * msgid, ...))
425 VA_FIXEDARG (ap, const char *, msgid);
427 fprintf (stderr, "collect2: ");
428 vfprintf (stderr, _(msgid), ap);
429 fprintf (stderr, "\n");
433 /* In case obstack is linked in, and abort is defined to fancy_abort,
434 provide a default entry. */
439 fatal ("internal error");
446 if (c_file != 0 && c_file[0])
447 maybe_unlink (c_file);
449 if (o_file != 0 && o_file[0])
450 maybe_unlink (o_file);
452 if (ldout != 0 && ldout[0])
453 maybe_unlink (ldout);
455 #ifdef COLLECT_EXPORT_LIST
456 if (export_file != 0 && export_file[0])
457 maybe_unlink (export_file);
460 signal (signo, SIG_DFL);
461 kill (getpid (), signo);
469 return access (name, R_OK) == 0;
472 /* Parse a reasonable subset of shell quoting syntax. */
489 obstack_1grow (&temporary_obstack, c);
490 else if (! inside && c == ' ')
492 else if (! inside && c == '\\')
497 obstack_1grow (&temporary_obstack, c);
500 obstack_1grow (&temporary_obstack, '\0');
502 return obstack_finish (&temporary_obstack);
509 FILE *stream = fopen (name, "r");
516 while (c = getc (stream),
517 c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
518 obstack_1grow (&temporary_obstack, c);
519 if (obstack_object_size (&temporary_obstack) > 0)
521 const char *word, *p;
523 obstack_1grow (&temporary_obstack, '\0');
524 word = obstack_finish (&temporary_obstack);
527 ++word, putc ('.', stderr);
529 if (*p == '_' && prepends_underscore)
535 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
540 fputs (result, stderr);
542 diff = strlen (word) - strlen (result);
543 while (diff > 0 && c == ' ')
544 --diff, putc (' ', stderr);
545 while (diff < 0 && c == ' ')
546 ++diff, c = getc (stream);
551 fputs (word, stderr);
554 obstack_free (&temporary_obstack, temporary_firstobj);
563 /* Decide whether the given symbol is: a constructor (1), a destructor
564 (2), a routine in a shared object that calls all the constructors
565 (3) or destructors (4), a DWARF exception-handling table (5), or
566 nothing special (0). */
572 struct names { const char *const name; const int len; const int ret;
573 const int two_underscores; };
575 const struct names *p;
577 const char *orig_s = s;
579 static const struct names special[] = {
580 #ifndef NO_DOLLAR_IN_LABEL
581 { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
582 { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
584 #ifndef NO_DOT_IN_LABEL
585 { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
586 { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
587 #endif /* NO_DOT_IN_LABEL */
588 #endif /* NO_DOLLAR_IN_LABEL */
589 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
590 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
591 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
592 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
593 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
594 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
595 cfront has its own linker procedure to collect them;
596 if collect2 gets them too, they get collected twice
597 when the cfront procedure is run and the compiler used
598 for linking happens to be GCC. */
599 { "sti__", sizeof ("sti__")-1, 1, 1 },
600 { "std__", sizeof ("std__")-1, 2, 1 },
601 #endif /* CFRONT_LOSSAGE */
605 while ((ch = *s) == '_')
611 for (p = &special[0]; p->len > 0; p++)
614 && (!p->two_underscores || ((s - orig_s) >= 2))
615 && strncmp(s, p->name, p->len) == 0)
623 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
624 and one from the PATH variable. */
626 static struct path_prefix cpath, path;
629 /* This is the name of the target machine. We use it to form the name
630 of the files to execute. */
632 static const char *const target_machine = TARGET_MACHINE;
635 /* Search for NAME using prefix list PPREFIX. We only look for executable
638 Return 0 if not found, otherwise return its name, allocated with malloc. */
641 find_a_file (pprefix, name)
642 struct path_prefix *pprefix;
646 struct prefix_list *pl;
647 int len = pprefix->max_len + strlen (name) + 1;
650 fprintf (stderr, "Looking for '%s'\n", name);
652 #ifdef HOST_EXECUTABLE_SUFFIX
653 len += strlen (HOST_EXECUTABLE_SUFFIX);
656 temp = xmalloc (len);
658 /* Determine the filename to execute (special case for absolute paths). */
661 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
662 || (*name && name[1] == ':')
666 if (access (name, X_OK) == 0)
671 fprintf (stderr, " - found: absolute path\n");
676 #ifdef HOST_EXECUTABLE_SUFFIX
677 /* Some systems have a suffix for executable files.
678 So try appending that. */
680 strcat (temp, HOST_EXECUTABLE_SUFFIX);
682 if (access (temp, X_OK) == 0)
687 fprintf (stderr, " - failed to locate using absolute path\n");
690 for (pl = pprefix->plist; pl; pl = pl->next)
694 strcpy (temp, pl->prefix);
697 if (stat (temp, &st) >= 0
698 && ! S_ISDIR (st.st_mode)
699 && access (temp, X_OK) == 0)
702 #ifdef HOST_EXECUTABLE_SUFFIX
703 /* Some systems have a suffix for executable files.
704 So try appending that. */
705 strcat (temp, HOST_EXECUTABLE_SUFFIX);
707 if (stat (temp, &st) >= 0
708 && ! S_ISDIR (st.st_mode)
709 && access (temp, X_OK) == 0)
714 if (debug && pprefix->plist == NULL)
715 fprintf (stderr, " - failed: no entries in prefix list\n");
721 /* Add an entry for PREFIX to prefix list PPREFIX. */
724 add_prefix (pprefix, prefix)
725 struct path_prefix *pprefix;
728 struct prefix_list *pl, **prev;
733 for (pl = pprefix->plist; pl->next; pl = pl->next)
738 prev = &pprefix->plist;
740 /* Keep track of the longest prefix */
742 len = strlen (prefix);
743 if (len > pprefix->max_len)
744 pprefix->max_len = len;
746 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
747 pl->prefix = xstrdup (prefix);
752 pl->next = (struct prefix_list *) 0;
756 /* Take the value of the environment variable ENV, break it into a path, and
757 add of the entries to PPREFIX. */
760 prefix_from_env (env, pprefix)
762 struct path_prefix *pprefix;
765 GET_ENV_PATH_LIST (p, env);
768 prefix_from_string (p, pprefix);
772 prefix_from_string (p, pprefix)
774 struct path_prefix *pprefix;
776 const char *startp, *endp;
777 char *nstore = (char *) xmalloc (strlen (p) + 3);
780 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
785 if (*endp == PATH_SEPARATOR || *endp == 0)
787 strncpy (nstore, startp, endp-startp);
790 strcpy (nstore, "./");
792 else if (! IS_DIR_SEPARATOR (endp[-1]))
794 nstore[endp-startp] = DIR_SEPARATOR;
795 nstore[endp-startp+1] = 0;
798 nstore[endp-startp] = 0;
801 fprintf (stderr, " - add prefix: %s\n", nstore);
803 add_prefix (pprefix, nstore);
806 endp = startp = endp + 1;
815 int main PARAMS ((int, char *[]));
821 static const char *const ld_suffix = "ld";
822 static const char *const real_ld_suffix = "real-ld";
823 static const char *const collect_ld_suffix = "collect-ld";
824 static const char *const nm_suffix = "nm";
825 static const char *const gnm_suffix = "gnm";
827 static const char *const ldd_suffix = LDD_SUFFIX;
829 static const char *const strip_suffix = "strip";
830 static const char *const gstrip_suffix = "gstrip";
833 /* If we look for a program in the compiler directories, we just use
834 the short name, since these directories are already system-specific.
835 But it we look for a program in the system directories, we need to
836 qualify the program name with the target machine. */
838 const char *const full_ld_suffix =
839 concat(target_machine, "-", ld_suffix, NULL);
840 const char *const full_nm_suffix =
841 concat (target_machine, "-", nm_suffix, NULL);
842 const char *const full_gnm_suffix =
843 concat (target_machine, "-", gnm_suffix, NULL);
845 const char *const full_ldd_suffix =
846 concat (target_machine, "-", ldd_suffix, NULL);
848 const char *const full_strip_suffix =
849 concat (target_machine, "-", strip_suffix, NULL);
850 const char *const full_gstrip_suffix =
851 concat (target_machine, "-", gstrip_suffix, NULL);
853 const char *const full_ld_suffix = ld_suffix;
854 const char *const full_nm_suffix = nm_suffix;
855 const char *const full_gnm_suffix = gnm_suffix;
857 const char *const full_ldd_suffix = ldd_suffix;
859 const char *const full_strip_suffix = strip_suffix;
860 const char *const full_gstrip_suffix = gstrip_suffix;
861 #endif /* CROSS_COMPILE */
865 #ifdef COLLECT_EXPORT_LIST
868 const char *ld_file_name;
879 int num_c_args = argc+9;
881 no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
883 /* Suppress demangling by the real linker, which may be broken. */
884 putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
886 #if defined (COLLECT2_HOST_INITIALIZATION)
887 /* Perform system dependent initialization, if necessary. */
888 COLLECT2_HOST_INITIALIZATION;
892 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
893 receive the signal. A different setting is inheritable */
894 signal (SIGCHLD, SIG_DFL);
899 /* Do not invoke xcalloc before this point, since locale needs to be
900 set first, in case a diagnostic is issued. */
902 ld1 = (const char **)(ld1_argv = (char **) xcalloc(sizeof (char *), argc+3));
903 ld2 = (const char **)(ld2_argv = (char **) xcalloc(sizeof (char *), argc+10));
904 object = (const char **)(object_lst = (char **) xcalloc(sizeof (char *), argc));
910 /* Parse command line early for instances of -debug. This allows
911 the debug flag to be set before functions like find_a_file()
916 for (i = 1; argv[i] != NULL; i ++)
917 if (! strcmp (argv[i], "-debug"))
922 #ifndef DEFAULT_A_OUT_NAME
923 output_file = "a.out";
925 output_file = DEFAULT_A_OUT_NAME;
928 obstack_begin (&temporary_obstack, 0);
929 obstack_begin (&permanent_obstack, 0);
930 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
932 current_demangling_style = auto_demangling;
933 p = getenv ("COLLECT_GCC_OPTIONS");
936 const char *q = extract_string (&p);
937 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
940 obstack_free (&temporary_obstack, temporary_firstobj);
942 /* -fno-exceptions -w */
945 c_ptr = (const char **)
946 (c_argv = (char **) xcalloc (sizeof (char *), num_c_args));
949 fatal ("no arguments");
952 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
953 signal (SIGQUIT, handler);
955 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
956 signal (SIGINT, handler);
958 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
959 signal (SIGALRM, handler);
962 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
963 signal (SIGHUP, handler);
965 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
966 signal (SIGSEGV, handler);
968 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
969 signal (SIGBUS, handler);
972 /* Extract COMPILER_PATH and PATH into our prefix list. */
973 prefix_from_env ("COMPILER_PATH", &cpath);
974 prefix_from_env ("PATH", &path);
976 /* Try to discover a valid linker/nm/strip to use. */
978 /* Maybe we know the right file to use (if not cross). */
980 #ifdef DEFAULT_LINKER
981 if (access (DEFAULT_LINKER, X_OK) == 0)
982 ld_file_name = DEFAULT_LINKER;
983 if (ld_file_name == 0)
985 #ifdef REAL_LD_FILE_NAME
986 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
987 if (ld_file_name == 0)
989 /* Search the (target-specific) compiler dirs for ld'. */
990 ld_file_name = find_a_file (&cpath, real_ld_suffix);
991 /* Likewise for `collect-ld'. */
992 if (ld_file_name == 0)
993 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
994 /* Search the compiler directories for `ld'. We have protection against
995 recursive calls in find_a_file. */
996 if (ld_file_name == 0)
997 ld_file_name = find_a_file (&cpath, ld_suffix);
998 /* Search the ordinary system bin directories
999 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1000 if (ld_file_name == 0)
1001 ld_file_name = find_a_file (&path, full_ld_suffix);
1003 #ifdef REAL_NM_FILE_NAME
1004 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1005 if (nm_file_name == 0)
1007 nm_file_name = find_a_file (&cpath, gnm_suffix);
1008 if (nm_file_name == 0)
1009 nm_file_name = find_a_file (&path, full_gnm_suffix);
1010 if (nm_file_name == 0)
1011 nm_file_name = find_a_file (&cpath, nm_suffix);
1012 if (nm_file_name == 0)
1013 nm_file_name = find_a_file (&path, full_nm_suffix);
1016 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1017 if (ldd_file_name == 0)
1018 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1021 #ifdef REAL_STRIP_FILE_NAME
1022 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1023 if (strip_file_name == 0)
1025 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1026 if (strip_file_name == 0)
1027 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1028 if (strip_file_name == 0)
1029 strip_file_name = find_a_file (&cpath, strip_suffix);
1030 if (strip_file_name == 0)
1031 strip_file_name = find_a_file (&path, full_strip_suffix);
1033 /* Determine the full path name of the C compiler to use. */
1034 c_file_name = getenv ("COLLECT_GCC");
1035 if (c_file_name == 0)
1037 #ifdef CROSS_COMPILE
1038 c_file_name = concat (target_machine, "-gcc", NULL);
1040 c_file_name = "gcc";
1044 p = find_a_file (&cpath, c_file_name);
1046 /* Here it should be safe to use the system search path since we should have
1047 already qualified the name of the compiler when it is needed. */
1049 p = find_a_file (&path, c_file_name);
1054 *ld1++ = *ld2++ = ld_file_name;
1056 /* Make temp file names. */
1057 c_file = make_temp_file (".c");
1058 o_file = make_temp_file (".o");
1059 #ifdef COLLECT_EXPORT_LIST
1060 export_file = make_temp_file (".x");
1062 ldout = make_temp_file (".ld");
1063 *c_ptr++ = c_file_name;
1070 #ifdef COLLECT_EXPORT_LIST
1071 /* Generate a list of directories from LIBPATH. */
1072 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1073 /* Add to this list also two standard directories where
1074 AIX loader always searches for libraries. */
1075 add_prefix (&libpath_lib_dirs, "/lib");
1076 add_prefix (&libpath_lib_dirs, "/usr/lib");
1079 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1081 AIX support needs to know if -shared has been specified before
1082 parsing commandline arguments. */
1084 p = getenv ("COLLECT_GCC_OPTIONS");
1087 const char *q = extract_string (&p);
1088 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1089 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1090 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1091 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1092 if (strcmp (q, "-shared") == 0)
1094 if (*q == '-' && q[1] == 'B')
1096 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1099 q = extract_string (&p);
1100 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1104 obstack_free (&temporary_obstack, temporary_firstobj);
1105 *c_ptr++ = "-fno-exceptions";
1108 /* !!! When GCC calls collect2,
1109 it does not know whether it is calling collect2 or ld.
1110 So collect2 cannot meaningfully understand any options
1111 except those ld understands.
1112 If you propose to make GCC pass some other option,
1113 just imagine what will happen if ld is really ld!!! */
1115 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1116 /* After the first file, put in the c++ rt0. */
1119 while ((arg = *++argv) != (char *) 0)
1121 *ld1++ = *ld2++ = arg;
1127 #ifdef COLLECT_EXPORT_LIST
1128 /* We want to disable automatic exports on AIX when user
1129 explicitly puts an export list in command line */
1131 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1133 else if (arg[2] == '6' && arg[3] == '4')
1139 if (!strcmp (arg, "-debug"))
1141 /* Already parsed. */
1150 /* place o_file BEFORE this argument! */
1156 #ifdef COLLECT_EXPORT_LIST
1158 /* Resolving full library name. */
1159 const char *s = resolve_lib_name (arg+2);
1161 /* Saving a full library name. */
1162 add_to_list (&libs, s);
1167 #ifdef COLLECT_EXPORT_LIST
1168 /* Saving directories where to search for libraries. */
1170 add_prefix (&cmdline_lib_dirs, arg+2);
1173 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1175 if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
1178 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1183 output_file = *ld1++ = *ld2++ = *++argv;
1185 #ifdef SWITCHES_NEED_SPACES
1186 && ! strchr (SWITCHES_NEED_SPACES, arg[1])
1190 output_file = &arg[2];
1199 if (arg[2] == '\0' && do_collecting)
1201 /* We must strip after the nm run, otherwise C++ linking
1202 will not work. Thus we strip in the second ld run, or
1203 else with strip if there is no second ld run. */
1215 else if ((p = strrchr (arg, '.')) != (char *) 0
1216 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1217 || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1218 || strcmp (p, ".obj") == 0))
1227 /* place o_file BEFORE this argument! */
1233 if (p[1] == 'o' || p[1] == 'l')
1235 #ifdef COLLECT_EXPORT_LIST
1236 /* libraries can be specified directly, i.e. without -l flag. */
1239 /* Saving a full library name. */
1240 add_to_list (&libs, arg);
1246 #ifdef COLLECT_EXPORT_LIST
1247 /* This is added only for debugging purposes. */
1250 fprintf (stderr, "List of libraries:\n");
1251 dump_list (stderr, "\t", libs.first);
1254 /* The AIX linker will discard static constructors in object files if
1255 nothing else in the file is referenced, so look at them first. */
1257 const char **export_object_lst = (const char **)object_lst;
1259 while (export_object_lst < object)
1260 scan_prog_file (*export_object_lst++, PASS_OBJ);
1263 struct id *list = libs.first;
1265 for (; list; list = list->next)
1266 scan_prog_file (list->name, PASS_FIRST);
1271 char *buf = concat ("-bE:", export_file, NULL);
1276 exportf = fopen (export_file, "w");
1277 if (exportf == (FILE *) 0)
1278 fatal_perror ("fopen %s", export_file);
1279 write_aix_file (exportf, exports.first);
1280 if (fclose (exportf))
1281 fatal_perror ("fclose %s", export_file);
1286 *c_ptr = *ld1 = *object = (char *) 0;
1290 notice ("collect2 version %s", version_string);
1291 #ifdef TARGET_VERSION
1294 fprintf (stderr, "\n");
1300 fprintf (stderr, "ld_file_name = %s\n",
1301 (ld_file_name ? ld_file_name : "not found"));
1302 fprintf (stderr, "c_file_name = %s\n",
1303 (c_file_name ? c_file_name : "not found"));
1304 fprintf (stderr, "nm_file_name = %s\n",
1305 (nm_file_name ? nm_file_name : "not found"));
1307 fprintf (stderr, "ldd_file_name = %s\n",
1308 (ldd_file_name ? ldd_file_name : "not found"));
1310 fprintf (stderr, "strip_file_name = %s\n",
1311 (strip_file_name ? strip_file_name : "not found"));
1312 fprintf (stderr, "c_file = %s\n",
1313 (c_file ? c_file : "not found"));
1314 fprintf (stderr, "o_file = %s\n",
1315 (o_file ? o_file : "not found"));
1317 ptr = getenv ("COLLECT_GCC_OPTIONS");
1319 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1321 ptr = getenv ("COLLECT_GCC");
1323 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1325 ptr = getenv ("COMPILER_PATH");
1327 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1329 ptr = getenv (LIBRARY_PATH_ENV);
1331 fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1333 fprintf (stderr, "\n");
1336 /* Load the program, searching all libraries and attempting to provide
1337 undefined symbols from repository information. */
1339 /* On AIX we do this later. */
1340 #ifndef COLLECT_EXPORT_LIST
1341 do_tlink (ld1_argv, object_lst);
1344 /* If -r or they will be run via some other method, do not build the
1345 constructor or destructor list, just return now. */
1347 #ifndef COLLECT_EXPORT_LIST
1352 #ifdef COLLECT_EXPORT_LIST
1353 /* Do the link we avoided above if we are exiting. */
1354 do_tlink (ld1_argv, object_lst);
1356 /* But make sure we delete the export file we may have created. */
1357 if (export_file != 0 && export_file[0])
1358 maybe_unlink (export_file);
1360 maybe_unlink (c_file);
1361 maybe_unlink (o_file);
1365 /* Examine the namelist with nm and search it for static constructors
1366 and destructors to call.
1367 Write the constructor and destructor tables to a .s file and reload. */
1369 /* On AIX we already scanned for global constructors/destructors. */
1370 #ifndef COLLECT_EXPORT_LIST
1371 scan_prog_file (output_file, PASS_FIRST);
1374 #ifdef SCAN_LIBRARIES
1375 scan_libraries (output_file);
1380 notice ("%d constructor(s) found\n", constructors.number);
1381 notice ("%d destructor(s) found\n", destructors.number);
1382 notice ("%d frame table(s) found\n", frame_tables.number);
1385 if (constructors.number == 0 && destructors.number == 0
1386 && frame_tables.number == 0
1387 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1388 /* If we will be running these functions ourselves, we want to emit
1389 stubs into the shared library so that we do not have to relink
1390 dependent programs when we add static objects. */
1395 #ifdef COLLECT_EXPORT_LIST
1396 /* Do tlink without additional code generation */
1397 do_tlink (ld1_argv, object_lst);
1399 /* Strip now if it was requested on the command line. */
1402 char **real_strip_argv = (char **) xcalloc (sizeof (char *), 3);
1403 const char ** strip_argv = (const char **) real_strip_argv;
1405 strip_argv[0] = strip_file_name;
1406 strip_argv[1] = output_file;
1407 strip_argv[2] = (char *) 0;
1408 fork_execute ("strip", real_strip_argv);
1411 #ifdef COLLECT_EXPORT_LIST
1412 maybe_unlink (export_file);
1414 maybe_unlink (c_file);
1415 maybe_unlink (o_file);
1419 /* Sort ctor and dtor lists by priority. */
1420 sort_ids (&constructors);
1421 sort_ids (&destructors);
1423 maybe_unlink(output_file);
1424 outf = fopen (c_file, "w");
1425 if (outf == (FILE *) 0)
1426 fatal_perror ("fopen %s", c_file);
1428 write_c_file (outf, c_file);
1431 fatal_perror ("fclose %s", c_file);
1433 /* Tell the linker that we have initializer and finalizer functions. */
1434 #ifdef LD_INIT_SWITCH
1435 #ifdef COLLECT_EXPORT_LIST
1436 *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
1438 *ld2++ = LD_INIT_SWITCH;
1440 *ld2++ = LD_FINI_SWITCH;
1445 #ifdef COLLECT_EXPORT_LIST
1448 /* If we did not add export flag to link arguments before, add it to
1449 second link phase now. No new exports should have been added. */
1450 if (! exports.first)
1451 *ld2++ = concat ("-bE:", export_file, NULL);
1453 add_to_list (&exports, initname);
1454 add_to_list (&exports, fininame);
1455 add_to_list (&exports, "_GLOBAL__DI");
1456 add_to_list (&exports, "_GLOBAL__DD");
1457 exportf = fopen (export_file, "w");
1458 if (exportf == (FILE *) 0)
1459 fatal_perror ("fopen %s", export_file);
1460 write_aix_file (exportf, exports.first);
1461 if (fclose (exportf))
1462 fatal_perror ("fclose %s", export_file);
1466 /* End of arguments to second link phase. */
1471 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1472 output_file, c_file);
1473 write_c_file (stderr, "stderr");
1474 fprintf (stderr, "========== end of c_file\n\n");
1475 #ifdef COLLECT_EXPORT_LIST
1476 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1477 write_aix_file (stderr, exports.first);
1478 fprintf (stderr, "========== end of export_file\n\n");
1482 /* Assemble the constructor and destructor tables.
1483 Link the tables in with the rest of the program. */
1485 fork_execute ("gcc", c_argv);
1486 #ifdef COLLECT_EXPORT_LIST
1487 /* On AIX we must call tlink because of possible templates resolution */
1488 do_tlink (ld2_argv, object_lst);
1490 /* Otherwise, simply call ld because tlink is already done */
1491 fork_execute ("ld", ld2_argv);
1493 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1494 constructors/destructors in shared libraries. */
1495 scan_prog_file (output_file, PASS_SECOND);
1498 maybe_unlink (c_file);
1499 maybe_unlink (o_file);
1501 #ifdef COLLECT_EXPORT_LIST
1502 maybe_unlink (export_file);
1509 /* Wait for a process to finish, and exit if a non-zero status is found. */
1517 pwait (pexecute_pid, &status, 0);
1520 if (WIFSIGNALED (status))
1522 int sig = WTERMSIG (status);
1523 error ("%s terminated with signal %d [%s]%s",
1524 prog, sig, strsignal(sig),
1525 status & 0200 ? "" : ", core dumped");
1526 collect_exit (FATAL_EXIT_CODE);
1529 if (WIFEXITED (status))
1530 return WEXITSTATUS (status);
1539 int ret = collect_wait (prog);
1542 error ("%s returned %d exit status", prog, ret);
1548 /* Execute a program, and wait for the reply. */
1551 collect_execute (prog, argv, redir)
1558 int redir_handle = -1;
1559 int stdout_save = -1;
1560 int stderr_save = -1;
1568 fprintf (stderr, "%s", argv[0]);
1570 notice ("[cannot find %s]", prog);
1572 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1573 fprintf (stderr, " %s", str);
1575 fprintf (stderr, "\n");
1581 /* If we cannot find a program we need, complain error. Do this here
1582 since we might not end up needing something that we could not find. */
1585 fatal ("cannot find `%s'", prog);
1589 /* Open response file. */
1590 redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
1592 /* Duplicate the stdout and stderr file handles
1593 so they can be restored later. */
1594 stdout_save = dup (STDOUT_FILENO);
1595 if (stdout_save == -1)
1596 fatal_perror ("redirecting stdout: %s", redir);
1597 stderr_save = dup (STDERR_FILENO);
1598 if (stderr_save == -1)
1599 fatal_perror ("redirecting stdout: %s", redir);
1601 /* Redirect stdout & stderr to our response file. */
1602 dup2 (redir_handle, STDOUT_FILENO);
1603 dup2 (redir_handle, STDERR_FILENO);
1606 pexecute_pid = pexecute (argv[0], argv, argv[0], NULL,
1607 &errmsg_fmt, &errmsg_arg,
1608 (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
1612 /* Restore stdout and stderr to their previous settings. */
1613 dup2 (stdout_save, STDOUT_FILENO);
1614 dup2 (stderr_save, STDERR_FILENO);
1616 /* Close response file. */
1617 close (redir_handle);
1620 if (pexecute_pid == -1)
1621 fatal_perror (errmsg_fmt, errmsg_arg);
1625 fork_execute (prog, argv)
1629 collect_execute (prog, argv, NULL);
1633 /* Unlink a file unless we are debugging. */
1642 notice ("[Leaving %s]\n", file);
1646 static long sequence_number = 0;
1648 /* Add a name to a linked list. */
1651 add_to_list (head_ptr, name)
1652 struct head *head_ptr;
1656 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1658 strcpy (newid->name, name);
1660 if (head_ptr->first)
1661 head_ptr->last->next = newid;
1663 head_ptr->first = newid;
1665 /* Check for duplicate symbols. */
1666 for (p = head_ptr->first;
1667 strcmp (name, p->name) != 0;
1672 head_ptr->last->next = 0;
1677 newid->sequence = ++sequence_number;
1678 head_ptr->last = newid;
1682 /* Grab the init priority number from an init function name that
1683 looks like "_GLOBAL_.I.12345.foo". */
1686 extract_init_priority (name)
1691 while (name[pos] == '_')
1693 pos += 10; /* strlen ("GLOBAL__X_") */
1695 /* Extract init_p number from ctor/dtor name. */
1696 pri = atoi (name + pos);
1697 return pri ? pri : DEFAULT_INIT_PRIORITY;
1700 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1701 ctors will be run from right to left, dtors from left to right. */
1705 struct head *head_ptr;
1707 /* id holds the current element to insert. id_next holds the next
1708 element to insert. id_ptr iterates through the already sorted elements
1709 looking for the place to insert id. */
1710 struct id *id, *id_next, **id_ptr;
1712 id = head_ptr->first;
1714 /* We don't have any sorted elements yet. */
1715 head_ptr->first = NULL;
1717 for (; id; id = id_next)
1720 id->sequence = extract_init_priority (id->name);
1722 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1724 /* If the sequence numbers are the same, we put the id from the
1725 file later on the command line later in the list. */
1726 || id->sequence > (*id_ptr)->sequence
1727 /* Hack: do lexical compare, too.
1728 || (id->sequence == (*id_ptr)->sequence
1729 && strcmp (id->name, (*id_ptr)->name) > 0) */
1738 /* Now set the sequence numbers properly so write_c_file works. */
1739 for (id = head_ptr->first; id; id = id->next)
1740 id->sequence = ++sequence_number;
1743 /* Write: `prefix', the names on list LIST, `suffix'. */
1746 write_list (stream, prefix, list)
1753 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1758 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1759 /* Given a STRING, return nonzero if it occurs in the list in range
1760 [ARGS_BEGIN,ARGS_END). */
1763 is_in_args (string, args_begin, args_end)
1765 const char **args_begin;
1766 const char **args_end;
1768 const char **args_pointer;
1769 for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
1770 if (strcmp (string, *args_pointer) == 0)
1774 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1776 #ifdef COLLECT_EXPORT_LIST
1777 /* This function is really used only on AIX, but may be useful. */
1780 is_in_list (prefix, list)
1786 if (!strcmp (prefix, list->name)) return 1;
1792 #endif /* COLLECT_EXPORT_LIST */
1794 /* Added for debugging purpose. */
1795 #ifdef COLLECT_EXPORT_LIST
1797 dump_list (stream, prefix, list)
1804 fprintf (stream, "%s%s,\n", prefix, list->name);
1812 dump_prefix_list (stream, prefix, list)
1815 struct prefix_list *list;
1819 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1826 write_list_with_asm (stream, prefix, list)
1833 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1834 prefix, list->sequence, list->name);
1839 /* Write out the constructor and destructor tables statically (for a shared
1840 object), along with the functions to execute them. */
1843 write_c_file_stat (stream, name)
1845 const char *name ATTRIBUTE_UNUSED;
1849 int frames = (frame_tables.number > 0);
1851 /* Figure out name of output_file, stripping off .so version. */
1852 p = strrchr (output_file, '/');
1868 if (strncmp (q, ".so", 3) == 0)
1877 /* q points to null at end of the string (or . of the .so version) */
1878 prefix = xmalloc (q - p + 1);
1879 strncpy (prefix, p, q - p);
1881 for (r = prefix; *r; r++)
1882 if (!ISALNUM ((unsigned char)*r))
1885 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1886 output_file, prefix);
1888 initname = concat ("_GLOBAL__FI_", prefix, NULL);
1889 fininame = concat ("_GLOBAL__FD_", prefix, NULL);
1893 /* Write the tables as C code */
1895 fprintf (stream, "static int count;\n");
1896 fprintf (stream, "typedef void entry_pt();\n");
1897 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1901 write_list_with_asm (stream, "extern void *", frame_tables.first);
1903 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1904 write_list (stream, "\t\t&", frame_tables.first);
1905 fprintf (stream, "\t0\n};\n");
1907 /* This must match what's in frame.h. */
1908 fprintf (stream, "struct object {\n");
1909 fprintf (stream, " void *pc_begin;\n");
1910 fprintf (stream, " void *pc_end;\n");
1911 fprintf (stream, " void *fde_begin;\n");
1912 fprintf (stream, " void *fde_array;\n");
1913 fprintf (stream, " __SIZE_TYPE__ count;\n");
1914 fprintf (stream, " struct object *next;\n");
1915 fprintf (stream, "};\n");
1917 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1918 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1920 fprintf (stream, "static void reg_frame () {\n");
1921 fprintf (stream, "\tstatic struct object ob;\n");
1922 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1923 fprintf (stream, "\t}\n");
1925 fprintf (stream, "static void dereg_frame () {\n");
1926 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1927 fprintf (stream, "\t}\n");
1930 fprintf (stream, "void %s() {\n", initname);
1931 if (constructors.number > 0 || frames)
1933 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1934 write_list (stream, "\t\t", constructors.first);
1936 fprintf (stream, "\treg_frame,\n");
1937 fprintf (stream, "\t};\n");
1938 fprintf (stream, "\tentry_pt **p;\n");
1939 fprintf (stream, "\tif (count++ != 0) return;\n");
1940 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1941 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1944 fprintf (stream, "\t++count;\n");
1945 fprintf (stream, "}\n");
1946 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1947 fprintf (stream, "void %s() {\n", fininame);
1948 if (destructors.number > 0 || frames)
1950 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1951 write_list (stream, "\t\t", destructors.first);
1953 fprintf (stream, "\tdereg_frame,\n");
1954 fprintf (stream, "\t};\n");
1955 fprintf (stream, "\tentry_pt **p;\n");
1956 fprintf (stream, "\tif (--count != 0) return;\n");
1957 fprintf (stream, "\tp = dtors;\n");
1958 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1959 destructors.number + frames);
1961 fprintf (stream, "}\n");
1965 COLLECT_SHARED_INIT_FUNC(stream, initname);
1966 COLLECT_SHARED_FINI_FUNC(stream, fininame);
1970 /* Write the constructor/destructor tables. */
1972 #ifndef LD_INIT_SWITCH
1974 write_c_file_glob (stream, name)
1976 const char *name ATTRIBUTE_UNUSED;
1978 /* Write the tables as C code */
1980 int frames = (frame_tables.number > 0);
1982 fprintf (stream, "typedef void entry_pt();\n\n");
1984 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1988 write_list_with_asm (stream, "extern void *", frame_tables.first);
1990 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1991 write_list (stream, "\t\t&", frame_tables.first);
1992 fprintf (stream, "\t0\n};\n");
1994 /* This must match what's in frame.h. */
1995 fprintf (stream, "struct object {\n");
1996 fprintf (stream, " void *pc_begin;\n");
1997 fprintf (stream, " void *pc_end;\n");
1998 fprintf (stream, " void *fde_begin;\n");
1999 fprintf (stream, " void *fde_array;\n");
2000 fprintf (stream, " __SIZE_TYPE__ count;\n");
2001 fprintf (stream, " struct object *next;\n");
2002 fprintf (stream, "};\n");
2004 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2005 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2007 fprintf (stream, "static void reg_frame () {\n");
2008 fprintf (stream, "\tstatic struct object ob;\n");
2009 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2010 fprintf (stream, "\t}\n");
2012 fprintf (stream, "static void dereg_frame () {\n");
2013 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2014 fprintf (stream, "\t}\n");
2017 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2018 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2019 write_list (stream, "\t", constructors.first);
2021 fprintf (stream, "\treg_frame,\n");
2022 fprintf (stream, "\t0\n};\n\n");
2024 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2026 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2027 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2028 write_list (stream, "\t", destructors.first);
2030 fprintf (stream, "\tdereg_frame,\n");
2031 fprintf (stream, "\t0\n};\n\n");
2033 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2034 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2036 #endif /* ! LD_INIT_SWITCH */
2039 write_c_file (stream, name)
2043 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2044 #ifndef LD_INIT_SWITCH
2046 write_c_file_glob (stream, name);
2049 write_c_file_stat (stream, name);
2050 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2053 #ifdef COLLECT_EXPORT_LIST
2055 write_aix_file (stream, list)
2059 for (; list; list = list->next)
2061 fputs (list->name, stream);
2062 putc ('\n', stream);
2067 #ifdef OBJECT_FORMAT_NONE
2069 /* Generic version to scan the name list of the loaded program for
2070 the symbols g++ uses for static constructors and destructors.
2072 The constructor table begins at __CTOR_LIST__ and contains a count
2073 of the number of pointers (or -1 if the constructors are built in a
2074 separate section by the linker), followed by the pointers to the
2075 constructor functions, terminated with a null pointer. The
2076 destructor table has the same format, and begins at __DTOR_LIST__. */
2079 scan_prog_file (prog_name, which_pass)
2080 const char *prog_name;
2081 enum pass which_pass;
2083 void (*int_handler) PARAMS ((int));
2084 void (*quit_handler) PARAMS ((int));
2085 char *real_nm_argv[4];
2086 const char **nm_argv = (const char **) real_nm_argv;
2093 if (which_pass == PASS_SECOND)
2096 /* If we do not have an `nm', complain. */
2097 if (nm_file_name == 0)
2098 fatal ("cannot find `nm'");
2100 nm_argv[argc++] = nm_file_name;
2101 if (NM_FLAGS[0] != '\0')
2102 nm_argv[argc++] = NM_FLAGS;
2104 nm_argv[argc++] = prog_name;
2105 nm_argv[argc++] = (char *) 0;
2107 if (pipe (pipe_fd) < 0)
2108 fatal_perror ("pipe");
2110 inf = fdopen (pipe_fd[0], "r");
2111 if (inf == (FILE *) 0)
2112 fatal_perror ("fdopen");
2114 /* Trace if needed. */
2117 const char **p_argv;
2120 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2121 fprintf (stderr, " %s", str);
2123 fprintf (stderr, "\n");
2129 /* Spawn child nm on pipe */
2132 fatal_perror (VFORK_STRING);
2134 if (pid == 0) /* child context */
2137 if (dup2 (pipe_fd[1], 1) < 0)
2138 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2140 if (close (pipe_fd[0]) < 0)
2141 fatal_perror ("close %d", pipe_fd[0]);
2143 if (close (pipe_fd[1]) < 0)
2144 fatal_perror ("close %d", pipe_fd[1]);
2146 execv (nm_file_name, real_nm_argv);
2147 fatal_perror ("execvp %s", nm_file_name);
2150 /* Parent context from here on. */
2151 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
2153 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
2156 if (close (pipe_fd[1]) < 0)
2157 fatal_perror ("close %d", pipe_fd[1]);
2160 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2162 /* Read each line of nm output. */
2163 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2168 /* If it contains a constructor or destructor name, add the name
2169 to the appropriate list. */
2171 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2172 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2179 /* Find the end of the symbol name.
2180 Do not include `|', because Encore nm can tack that on the end. */
2181 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2187 switch (is_ctor_dtor (name))
2190 if (which_pass != PASS_LIB)
2191 add_to_list (&constructors, name);
2195 if (which_pass != PASS_LIB)
2196 add_to_list (&destructors, name);
2200 if (which_pass != PASS_LIB)
2201 fatal ("init function found in object %s", prog_name);
2202 #ifndef LD_INIT_SWITCH
2203 add_to_list (&constructors, name);
2208 if (which_pass != PASS_LIB)
2209 fatal ("fini function found in object %s", prog_name);
2210 #ifndef LD_FINI_SWITCH
2211 add_to_list (&destructors, name);
2216 if (which_pass != PASS_LIB)
2217 add_to_list (&frame_tables, name);
2220 default: /* not a constructor or destructor */
2225 fprintf (stderr, "\t%s\n", buf);
2229 fprintf (stderr, "\n");
2231 if (fclose (inf) != 0)
2232 fatal_perror ("fclose");
2234 do_wait (nm_file_name);
2236 signal (SIGINT, int_handler);
2238 signal (SIGQUIT, quit_handler);
2242 #if SUNOS4_SHARED_LIBRARIES
2244 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2245 that the output file depends upon and their initialization/finalization
2246 routines, if any. */
2251 #include <sys/mman.h>
2252 #include <sys/param.h>
2254 #include <sys/dir.h>
2256 /* pointers to the object file */
2257 unsigned object; /* address of memory mapped file */
2258 unsigned objsize; /* size of memory mapped to file */
2259 char * code; /* pointer to code segment */
2260 char * data; /* pointer to data segment */
2261 struct nlist *symtab; /* pointer to symbol table */
2262 struct link_dynamic *ld;
2263 struct link_dynamic_2 *ld_2;
2264 struct head libraries;
2266 /* Map the file indicated by NAME into memory and store its address. */
2268 static void mapfile PARAMS ((const char *));
2276 if ((fp = open (name, O_RDONLY)) == -1)
2277 fatal ("unable to open file '%s'", name);
2278 if (fstat (fp, &s) == -1)
2279 fatal ("unable to stat file '%s'", name);
2281 objsize = s.st_size;
2282 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2284 if (object == (unsigned)-1)
2285 fatal ("unable to mmap file '%s'", name);
2290 /* Helpers for locatelib. */
2292 static const char *libname;
2294 static int libselect PARAMS ((struct direct *));
2300 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2303 /* If one file has an additional numeric extension past LIBNAME, then put
2304 that one first in the sort. If both files have additional numeric
2305 extensions, then put the one with the higher number first in the sort.
2307 We must verify that the extension is numeric, because Sun saves the
2308 original versions of patched libraries with a .FCS extension. Files with
2309 invalid extensions must go last in the sort, so that they will not be used. */
2310 static int libcompare PARAMS ((struct direct **, struct direct **));
2314 struct direct **d1, **d2;
2316 int i1, i2 = strlen (libname);
2317 char *e1 = (*d1)->d_name + i2;
2318 char *e2 = (*d2)->d_name + i2;
2320 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2321 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
2325 i1 = strtol (e1, &e1, 10);
2326 i2 = strtol (e2, &e2, 10);
2333 /* It has a valid numeric extension, prefer this one. */
2334 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
2336 /* It has an invalid numeric extension, must prefer the other one. */
2342 /* It has a valid numeric extension, prefer this one. */
2343 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
2345 /* It has an invalid numeric extension, must prefer the other one. */
2353 /* Given the name NAME of a dynamic dependency, find its pathname and add
2354 it to the list of libraries. */
2355 static void locatelib PARAMS ((const char *));
2361 static const char **l;
2363 char buf[MAXPATHLEN];
2371 /* counting elements in array, need 1 extra for null */
2373 ld_rules = (char *) (ld_2->ld_rules + code);
2377 for (; *ld_rules != 0; ld_rules++)
2378 if (*ld_rules == ':')
2380 ld_rules = (char *) (ld_2->ld_rules + code);
2381 ldr = xstrdup (ld_rules);
2383 p = getenv ("LD_LIBRARY_PATH");
2388 for (q = p ; *q != 0; q++)
2393 l = (const char **) xmalloc ((cnt + 3) * sizeof (char *));
2398 for (; *ldr != 0; ldr++)
2408 for (; *q != 0; q++)
2415 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2418 *pp++ = "/usr/local/lib";
2422 for (pp = l; *pp != 0 ; pp++)
2424 struct direct **namelist;
2426 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2428 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2429 add_to_list (&libraries, buf);
2431 fprintf (stderr, "%s\n", buf);
2438 notice ("not found\n");
2440 fatal ("dynamic dependency %s not found", name);
2444 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2445 that it depends upon and any constructors or destructors they contain. */
2448 scan_libraries (prog_name)
2449 const char *prog_name;
2451 struct exec *header;
2453 struct link_object *lo;
2454 char buff[MAXPATHLEN];
2457 mapfile (prog_name);
2458 header = (struct exec *)object;
2459 if (N_BADMAG (*header))
2460 fatal ("bad magic number in file '%s'", prog_name);
2461 if (header->a_dynamic == 0)
2464 code = (char *) (N_TXTOFF (*header) + (long) header);
2465 data = (char *) (N_DATOFF (*header) + (long) header);
2466 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2468 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2471 ld = (struct link_dynamic *) (symtab->n_value + code);
2477 ld = (struct link_dynamic *) data;
2482 notice ("dynamic dependencies.\n");
2484 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2485 for (lo = (struct link_object *) ld_2->ld_need; lo;
2486 lo = (struct link_object *) lo->lo_next)
2489 lo = (struct link_object *) ((long) lo + code);
2490 name = (char *) (code + lo->lo_name);
2494 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2495 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2501 fprintf (stderr, "\t%s\n", name);
2502 add_to_list (&libraries, name);
2507 fprintf (stderr, "\n");
2509 /* now iterate through the library list adding their symbols to
2511 for (list = libraries.first; list; list = list->next)
2512 scan_prog_file (list->name, PASS_LIB);
2515 #else /* SUNOS4_SHARED_LIBRARIES */
2518 /* Use the List Dynamic Dependencies program to find shared libraries that
2519 the output file depends upon and their initialization/finalization
2520 routines, if any. */
2523 scan_libraries (prog_name)
2524 const char *prog_name;
2526 static struct head libraries; /* list of shared libraries found */
2528 void (*int_handler) PARAMS ((int));
2529 void (*quit_handler) PARAMS ((int));
2530 char *real_ldd_argv[4];
2531 const char **ldd_argv = (const char **) real_ldd_argv;
2538 /* If we do not have an `ldd', complain. */
2539 if (ldd_file_name == 0)
2541 error ("cannot find `ldd'");
2545 ldd_argv[argc++] = ldd_file_name;
2546 ldd_argv[argc++] = prog_name;
2547 ldd_argv[argc++] = (char *) 0;
2549 if (pipe (pipe_fd) < 0)
2550 fatal_perror ("pipe");
2552 inf = fdopen (pipe_fd[0], "r");
2553 if (inf == (FILE *) 0)
2554 fatal_perror ("fdopen");
2556 /* Trace if needed. */
2559 const char **p_argv;
2562 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2563 fprintf (stderr, " %s", str);
2565 fprintf (stderr, "\n");
2571 /* Spawn child ldd on pipe */
2574 fatal_perror (VFORK_STRING);
2576 if (pid == 0) /* child context */
2579 if (dup2 (pipe_fd[1], 1) < 0)
2580 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2582 if (close (pipe_fd[0]) < 0)
2583 fatal_perror ("close %d", pipe_fd[0]);
2585 if (close (pipe_fd[1]) < 0)
2586 fatal_perror ("close %d", pipe_fd[1]);
2588 execv (ldd_file_name, real_ldd_argv);
2589 fatal_perror ("execv %s", ldd_file_name);
2592 /* Parent context from here on. */
2593 int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
2595 quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
2598 if (close (pipe_fd[1]) < 0)
2599 fatal_perror ("close %d", pipe_fd[1]);
2602 notice ("\nldd output with constructors/destructors.\n");
2604 /* Read each line of ldd output. */
2605 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2608 char *name, *end, *p = buf;
2610 /* Extract names of libraries and add to list. */
2611 PARSE_LDD_OUTPUT (p);
2616 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2617 fatal ("dynamic dependency %s not found", buf);
2619 /* Find the end of the symbol name. */
2621 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2626 if (access (name, R_OK) == 0)
2627 add_to_list (&libraries, name);
2629 fatal ("unable to open dynamic dependency '%s'", buf);
2632 fprintf (stderr, "\t%s\n", buf);
2635 fprintf (stderr, "\n");
2637 if (fclose (inf) != 0)
2638 fatal_perror ("fclose");
2640 do_wait (ldd_file_name);
2642 signal (SIGINT, int_handler);
2644 signal (SIGQUIT, quit_handler);
2647 /* now iterate through the library list adding their symbols to
2649 for (list = libraries.first; list; list = list->next)
2650 scan_prog_file (list->name, PASS_LIB);
2653 #endif /* LDD_SUFFIX */
2654 #endif /* SUNOS4_SHARED_LIBRARIES */
2656 #endif /* OBJECT_FORMAT_NONE */
2660 * COFF specific stuff.
2663 #ifdef OBJECT_FORMAT_COFF
2665 #if defined(EXTENDED_COFF)
2667 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2668 # define GCC_SYMENT SYMR
2669 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2670 # define GCC_SYMINC(X) (1)
2671 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2672 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2676 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2677 # define GCC_SYMENT SYMENT
2678 # define GCC_OK_SYMBOL(X) \
2679 (((X).n_sclass == C_EXT) && \
2680 ((X).n_scnum > N_UNDEF) && \
2682 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2683 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2684 # define GCC_UNDEF_SYMBOL(X) \
2685 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2686 # define GCC_SYMINC(X) ((X).n_numaux+1)
2687 # define GCC_SYMZERO(X) 0
2689 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2691 # define GCC_CHECK_HDR(X) \
2692 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2693 || (HEADER (X).f_magic == 0767 && aix64_flag))
2695 # define GCC_CHECK_HDR(X) \
2696 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2697 || (HEADER (X).f_magic == 0757 && aix64_flag))
2702 extern char *ldgetname ();
2704 /* COFF version to scan the name list of the loaded program for
2705 the symbols g++ uses for static constructors and destructors.
2707 The constructor table begins at __CTOR_LIST__ and contains a count
2708 of the number of pointers (or -1 if the constructors are built in a
2709 separate section by the linker), followed by the pointers to the
2710 constructor functions, terminated with a null pointer. The
2711 destructor table has the same format, and begins at __DTOR_LIST__. */
2714 scan_prog_file (prog_name, which_pass)
2715 const char *prog_name;
2716 enum pass which_pass;
2718 LDFILE *ldptr = NULL;
2719 int sym_index, sym_count;
2722 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2725 #ifdef COLLECT_EXPORT_LIST
2726 /* We do not need scanning for some standard C libraries. */
2727 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2730 /* On AIX we have a loop, because there is not much difference
2731 between an object and an archive. This trick allows us to
2732 eliminate scan_libraries() function. */
2736 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2737 non-const char * filename parameter, even though it will not
2738 modify that string. So we must cast away const-ness here,
2739 which will cause -Wcast-qual to burp. */
2740 if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
2742 if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2743 fatal ("%s: not a COFF file", prog_name);
2745 if (GCC_CHECK_HDR (ldptr))
2747 sym_count = GCC_SYMBOLS (ldptr);
2748 sym_index = GCC_SYMZERO (ldptr);
2750 #ifdef COLLECT_EXPORT_LIST
2751 /* Is current archive member a shared object? */
2752 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2755 while (sym_index < sym_count)
2759 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2761 sym_index += GCC_SYMINC (symbol);
2763 if (GCC_OK_SYMBOL (symbol))
2767 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2768 continue; /* should never happen */
2770 #ifdef XCOFF_DEBUGGING_INFO
2771 /* All AIX function names have a duplicate entry
2772 beginning with a dot. */
2777 switch (is_ctor_dtor (name))
2781 add_to_list (&constructors, name);
2782 #ifdef COLLECT_EXPORT_LIST
2783 if (which_pass == PASS_OBJ)
2784 add_to_list (&exports, name);
2790 add_to_list (&destructors, name);
2791 #ifdef COLLECT_EXPORT_LIST
2792 if (which_pass == PASS_OBJ)
2793 add_to_list (&exports, name);
2797 #ifdef COLLECT_EXPORT_LIST
2799 #ifndef LD_INIT_SWITCH
2801 add_to_list (&constructors, name);
2806 #ifndef LD_INIT_SWITCH
2808 add_to_list (&destructors, name);
2815 add_to_list (&frame_tables, name);
2816 #ifdef COLLECT_EXPORT_LIST
2817 if (which_pass == PASS_OBJ)
2818 add_to_list (&exports, name);
2822 default: /* not a constructor or destructor */
2823 #ifdef COLLECT_EXPORT_LIST
2824 /* If we are building a shared object on AIX we need
2825 to explicitly export all global symbols. */
2828 if (which_pass == PASS_OBJ && (! export_flag))
2829 add_to_list (&exports, name);
2836 #if !defined(EXTENDED_COFF)
2837 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2838 symbol.n_scnum, symbol.n_sclass,
2839 (symbol.n_type ? "0" : ""), symbol.n_type,
2843 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2844 symbol.iss, (long) symbol.value, symbol.index, name);
2849 #ifdef COLLECT_EXPORT_LIST
2852 /* If archive contains both 32-bit and 64-bit objects,
2853 we want to skip objects in other mode so mismatch normal. */
2855 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2856 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2862 fatal ("%s: cannot open as COFF file", prog_name);
2864 #ifdef COLLECT_EXPORT_LIST
2865 /* On AIX loop continues while there are more members in archive. */
2867 while (ldclose (ldptr) == FAILURE);
2869 /* Otherwise we simply close ldptr. */
2870 (void) ldclose(ldptr);
2875 #ifdef COLLECT_EXPORT_LIST
2876 /* Given a library name without "lib" prefix, this function
2877 returns a full library name including a path. */
2879 resolve_lib_name (name)
2885 for (i = 0; libpaths[i]; i++)
2886 if (libpaths[i]->max_len > l)
2887 l = libpaths[i]->max_len;
2889 lib_buf = xmalloc (l + strlen(name) + 10);
2891 for (i = 0; libpaths[i]; i++)
2893 struct prefix_list *list = libpaths[i]->plist;
2894 for (; list; list = list->next)
2896 /* The following lines are needed because path_prefix list
2897 may contain directories both with trailing '/' and
2900 if (list->prefix[strlen(list->prefix)-1] != '/')
2902 for (j = 0; libexts[j]; j++)
2904 sprintf (lib_buf, "%s%slib%s.%s",
2905 list->prefix, p, name, libexts[j]);
2906 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2907 if (file_exists (lib_buf))
2909 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2916 fprintf (stderr, "not found\n");
2918 fatal ("library lib%s not found", name);
2922 /* Array of standard AIX libraries which should not
2923 be scanned for ctors/dtors. */
2924 static const char *const aix_std_libs[] = {
2932 "/usr/lib/libc_r.a",
2933 "/usr/lib/libm_r.a",
2934 "/usr/lib/threads/libc.a",
2935 "/usr/ccs/lib/libc.a",
2936 "/usr/ccs/lib/libm.a",
2937 "/usr/ccs/lib/libc_r.a",
2938 "/usr/ccs/lib/libm_r.a",
2942 /* This function checks the filename and returns 1
2943 if this name matches the location of a standard AIX library. */
2945 ignore_library (name)
2948 const char *const *p = &aix_std_libs[0];
2949 while (*p++ != NULL)
2950 if (! strcmp (name, *p)) return 1;
2955 #endif /* OBJECT_FORMAT_COFF */
2959 * OSF/rose specific stuff.
2962 #ifdef OBJECT_FORMAT_ROSE
2964 /* Union of the various load commands */
2966 typedef union load_union
2968 ldc_header_t hdr; /* common header */
2969 load_cmd_map_command_t map; /* map indexing other load cmds */
2970 interpreter_command_t iprtr; /* interpreter pathname */
2971 strings_command_t str; /* load commands strings section */
2972 region_command_t region; /* region load command */
2973 reloc_command_t reloc; /* relocation section */
2974 package_command_t pkg; /* package load command */
2975 symbols_command_t sym; /* symbol sections */
2976 entry_command_t ent; /* program start section */
2977 gen_info_command_t info; /* object information */
2978 func_table_command_t func; /* function constructors/destructors */
2981 /* Structure to point to load command and data section in memory. */
2983 typedef struct load_all
2985 load_union_t *load; /* load command */
2986 char *section; /* pointer to section */
2989 /* Structure to contain information about a file mapped into memory. */
2993 char *start; /* start of map */
2994 char *name; /* filename */
2995 long size; /* size of the file */
2996 long rounded_size; /* size rounded to page boundary */
2997 int fd; /* file descriptor */
2998 int rw; /* != 0 if opened read/write */
2999 int use_mmap; /* != 0 if mmap'ed */
3002 extern int decode_mach_o_hdr ();
3003 extern int encode_mach_o_hdr ();
3005 static void add_func_table PARAMS ((mo_header_t *, load_all_t *,
3006 symbol_info_t *, int));
3007 static void print_header PARAMS ((mo_header_t *));
3008 static void print_load_command PARAMS ((load_union_t *, size_t, int));
3009 static void bad_header PARAMS ((int));
3010 static struct file_info *read_file PARAMS ((const char *, int, int));
3011 static void end_file PARAMS ((struct file_info *));
3013 /* OSF/rose specific version to scan the name list of the loaded
3014 program for the symbols g++ uses for static constructors and
3017 The constructor table begins at __CTOR_LIST__ and contains a count
3018 of the number of pointers (or -1 if the constructors are built in a
3019 separate section by the linker), followed by the pointers to the
3020 constructor functions, terminated with a null pointer. The
3021 destructor table has the same format, and begins at __DTOR_LIST__. */
3024 scan_prog_file (prog_name, which_pass)
3025 const char *prog_name;
3026 enum pass which_pass;
3030 load_all_t *load_array;
3031 load_all_t *load_end;
3032 load_all_t *load_cmd;
3033 int symbol_load_cmds;
3039 struct file_info *obj_file;
3041 mo_lcid_t cmd_strings = -1;
3042 symbol_info_t *main_sym = 0;
3043 int rw = (which_pass != PASS_FIRST);
3045 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3047 fatal_perror ("open %s", prog_name);
3049 obj_file = read_file (prog_name, prog_fd, rw);
3050 obj = obj_file->start;
3052 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3053 if (status != MO_HDR_CONV_SUCCESS)
3054 bad_header (status);
3057 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3058 since the hardware will automatically swap bytes for us on loading little endian
3061 #ifndef CROSS_COMPILE
3062 if (hdr.moh_magic != MOH_MAGIC_MSB
3063 || hdr.moh_header_version != MOH_HEADER_VERSION
3064 || hdr.moh_byte_order != OUR_BYTE_ORDER
3065 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3066 || hdr.moh_cpu_type != OUR_CPU_TYPE
3067 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3068 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3070 fatal ("incompatibilities between object file & expected values");
3075 print_header (&hdr);
3077 offset = hdr.moh_first_cmd_off;
3078 load_end = load_array
3079 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3081 /* Build array of load commands, calculating the offsets */
3082 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3084 load_union_t *load_hdr; /* load command header */
3086 load_cmd = load_end++;
3087 load_hdr = (load_union_t *) (obj + offset);
3089 /* If modifying the program file, copy the header. */
3092 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3093 memcpy ((char *)ptr, (char *)load_hdr, load_hdr->hdr.ldci_cmd_size);
3096 /* null out old command map, because we will rewrite at the end. */
3097 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3099 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3100 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3104 load_cmd->load = load_hdr;
3105 if (load_hdr->hdr.ldci_section_off > 0)
3106 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3109 print_load_command (load_hdr, offset, i);
3111 offset += load_hdr->hdr.ldci_cmd_size;
3114 /* If the last command is the load command map and is not undefined,
3115 decrement the count of load commands. */
3116 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3119 hdr.moh_n_load_cmds--;
3122 /* Go through and process each symbol table section. */
3123 symbol_load_cmds = 0;
3124 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3126 load_union_t *load_hdr = load_cmd->load;
3128 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3134 const char *kind = "unknown";
3136 switch (load_hdr->sym.symc_kind)
3138 case SYMC_IMPORTS: kind = "imports"; break;
3139 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3140 case SYMC_STABS: kind = "stabs"; break;
3143 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3144 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3147 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3150 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3151 if (str_sect == (char *) 0)
3152 fatal ("string section missing");
3154 if (load_cmd->section == (char *) 0)
3155 fatal ("section pointer missing");
3157 num_syms = load_hdr->sym.symc_nentries;
3158 for (i = 0; i < num_syms; i++)
3160 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3161 char *name = sym->si_name.symbol_name + str_sect;
3168 char *n = name + strlen (name) - strlen (NAME__MAIN);
3170 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3180 switch (is_ctor_dtor (name))
3183 add_to_list (&constructors, name);
3187 add_to_list (&destructors, name);
3190 default: /* not a constructor or destructor */
3196 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3197 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3202 if (symbol_load_cmds == 0)
3203 fatal ("no symbol table found");
3205 /* Update the program file now, rewrite header and load commands. At present,
3206 we assume that there is enough space after the last load command to insert
3207 one more. Since the first section written out is page aligned, and the
3208 number of load commands is small, this is ok for the present. */
3212 load_union_t *load_map;
3215 if (cmd_strings == -1)
3216 fatal ("no cmd_strings found");
3218 /* Add __main to initializer list.
3219 If we are building a program instead of a shared library, do not
3220 do anything, since in the current version, you cannot do mallocs
3221 and such in the constructors. */
3223 if (main_sym != (symbol_info_t *) 0
3224 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3225 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3228 notice ("\nUpdating header and load commands.\n\n");
3230 hdr.moh_n_load_cmds++;
3231 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3233 /* Create new load command map. */
3235 notice ("load command map, %d cmds, new size %ld.\n",
3236 (int) hdr.moh_n_load_cmds, (long) size);
3238 load_map = (load_union_t *) xcalloc (1, size);
3239 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3240 load_map->map.ldc_header.ldci_cmd_size = size;
3241 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3242 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3243 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3245 offset = hdr.moh_first_cmd_off;
3246 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3248 load_map->map.lcm_map[i] = offset;
3249 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3250 hdr.moh_load_map_cmd_off = offset;
3252 offset += load_array[i].load->hdr.ldci_cmd_size;
3255 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3258 print_header (&hdr);
3261 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3262 if (status != MO_HDR_CONV_SUCCESS)
3263 bad_header (status);
3266 notice ("writing load commands.\n\n");
3268 /* Write load commands */
3269 offset = hdr.moh_first_cmd_off;
3270 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3272 load_union_t *load_hdr = load_array[i].load;
3273 size_t size = load_hdr->hdr.ldci_cmd_size;
3276 print_load_command (load_hdr, offset, i);
3278 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3283 end_file (obj_file);
3285 if (close (prog_fd))
3286 fatal_perror ("close %s", prog_name);
3289 fprintf (stderr, "\n");
3293 /* Add a function table to the load commands to call a function
3294 on initiation or termination of the process. */
3297 add_func_table (hdr_p, load_array, sym, type)
3298 mo_header_t *hdr_p; /* pointer to global header */
3299 load_all_t *load_array; /* array of ptrs to load cmds */
3300 symbol_info_t *sym; /* pointer to symbol entry */
3301 int type; /* fntc_type value */
3303 /* Add a new load command. */
3304 int num_cmds = ++hdr_p->moh_n_load_cmds;
3305 int load_index = num_cmds - 1;
3306 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3307 load_union_t *ptr = xcalloc (1, size);
3308 load_all_t *load_cmd;
3311 /* Set the unresolved address bit in the header to force the loader to be
3312 used, since kernel exec does not call the initialization functions. */
3313 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3315 load_cmd = &load_array[load_index];
3316 load_cmd->load = ptr;
3317 load_cmd->section = (char *) 0;
3319 /* Fill in func table load command. */
3320 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3321 ptr->func.ldc_header.ldci_cmd_size = size;
3322 ptr->func.ldc_header.ldci_section_off = 0;
3323 ptr->func.ldc_header.ldci_section_len = 0;
3324 ptr->func.fntc_type = type;
3325 ptr->func.fntc_nentries = 1;
3327 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3328 /* Is the symbol already expressed as (region, offset)? */
3329 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3331 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3332 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3335 /* If not, figure out which region it's in. */
3338 mo_vm_addr_t addr = sym->si_value.abs_val;
3341 for (i = 0; i < load_index; i++)
3343 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3345 region_command_t *region_ptr = &load_array[i].load->region;
3347 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3348 && addr >= region_ptr->regc_addr.vm_addr
3349 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3351 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3352 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3360 fatal ("could not convert 0x%l.8x into a region", addr);
3364 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3365 type == FNTC_INITIALIZATION ? "init" : "term",
3366 (int) ptr->func.fntc_entry_loc[i].adr_lcid,
3367 (long) ptr->func.fntc_entry_loc[i].adr_sctoff,
3368 (long) ptr->func.fntc_entry_loc[i].adr_sctoff);
3373 /* Print the global header for an OSF/rose object. */
3376 print_header (hdr_ptr)
3377 mo_header_t *hdr_ptr;
3379 fprintf (stderr, "\nglobal header:\n");
3380 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3381 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3382 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3383 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3384 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3385 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3386 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3387 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3388 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3389 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3390 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3391 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3392 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3393 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3394 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3396 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3397 fprintf (stderr, ", relocatable");
3399 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3400 fprintf (stderr, ", linkable");
3402 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3403 fprintf (stderr, ", execable");
3405 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3406 fprintf (stderr, ", executable");
3408 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3409 fprintf (stderr, ", unresolved");
3411 fprintf (stderr, "\n\n");
3416 /* Print a short summary of a load command. */
3419 print_load_command (load_hdr, offset, number)
3420 load_union_t *load_hdr;
3424 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3425 const char *type_str = (char *) 0;
3429 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3430 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3431 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3432 case LDC_STRINGS: type_str = "STRINGS"; break;
3433 case LDC_REGION: type_str = "REGION"; break;
3434 case LDC_RELOC: type_str = "RELOC"; break;
3435 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3436 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3437 case LDC_ENTRY: type_str = "ENTRY"; break;
3438 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3439 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3443 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3445 (long) load_hdr->hdr.ldci_cmd_size,
3447 (long) load_hdr->hdr.ldci_section_off,
3448 (long) load_hdr->hdr.ldci_section_len);
3450 if (type_str == (char *) 0)
3451 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3453 else if (type != LDC_REGION)
3454 fprintf (stderr, ", ty: %s\n", type_str);
3458 const char *region = "";
3459 switch (load_hdr->region.regc_usage_type)
3461 case REG_TEXT_T: region = ", .text"; break;
3462 case REG_DATA_T: region = ", .data"; break;
3463 case REG_BSS_T: region = ", .bss"; break;
3464 case REG_GLUE_T: region = ", .glue"; break;
3465 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3466 case REG_RDATA_T: region = ", .rdata"; break;
3467 case REG_SDATA_T: region = ", .sdata"; break;
3468 case REG_SBSS_T: region = ", .sbss"; break;
3472 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3474 (long) load_hdr->region.regc_vm_addr,
3475 (long) load_hdr->region.regc_vm_size,
3483 /* Fatal error when {en,de}code_mach_o_header fails. */
3491 case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
3492 case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
3493 case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
3494 case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
3495 case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
3496 case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
3498 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3503 /* Read a file into a memory buffer. */
3505 static struct file_info *
3506 read_file (name, fd, rw)
3507 const char *name; /* filename */
3508 int fd; /* file descriptor */
3509 int rw; /* read/write */
3511 struct stat stat_pkt;
3512 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3514 static int page_size;
3517 if (fstat (fd, &stat_pkt) < 0)
3518 fatal_perror ("fstat %s", name);
3521 p->size = stat_pkt.st_size;
3522 p->rounded_size = stat_pkt.st_size;
3528 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3531 page_size = sysconf (_SC_PAGE_SIZE);
3533 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3534 p->start = mmap ((caddr_t) 0,
3535 (rw) ? p->rounded_size : p->size,
3536 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3537 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3541 if (p->start != (char *) 0 && p->start != (char *) -1)
3545 #endif /* USE_MMAP */
3550 fprintf (stderr, "read %s\n", name);
3553 p->start = xmalloc (p->size);
3554 if (lseek (fd, 0L, SEEK_SET) < 0)
3555 fatal_perror ("lseek %s 0", name);
3557 len = read (fd, p->start, p->size);
3559 fatal_perror ("read %s", name);
3562 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3568 /* Do anything necessary to write a file back from memory. */
3572 struct file_info *ptr; /* file information block */
3580 fprintf (stderr, "msync %s\n", ptr->name);
3582 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3583 fatal_perror ("msync %s", ptr->name);
3587 fprintf (stderr, "munmap %s\n", ptr->name);
3589 if (munmap (ptr->start, ptr->size))
3590 fatal_perror ("munmap %s", ptr->name);
3593 #endif /* USE_MMAP */
3600 fprintf (stderr, "write %s\n", ptr->name);
3602 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3603 fatal_perror ("lseek %s 0", ptr->name);
3605 len = write (ptr->fd, ptr->start, ptr->size);
3607 fatal_perror ("write %s", ptr->name);
3609 if (len != ptr->size)
3610 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3619 #endif /* OBJECT_FORMAT_ROSE */