1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc.
4 Contributed by Chris Smith (csmith@convex.com).
5 Heavily modified by Michael Meissner (meissner@cygnus.com),
6 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
26 /* Build tables of static constructors and destructors and run ld. */
37 #include "gansidecl.h"
40 extern char *sys_errlist[];
46 /* Obstack allocation and deallocation routines. */
47 #define obstack_chunk_alloc xmalloc
48 #define obstack_chunk_free free
55 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
58 #define WTERMSIG(S) ((S) & 0x7f)
61 #define WIFEXITED(S) (((S) & 0xff) == 0)
64 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
67 extern char *choose_temp_base ();
69 /* On certain systems, we have code that works by scanning the object file
70 directly. But this code uses system-specific header files and library
71 functions, so turn it off in a cross-compiler. Likewise, the names of
72 the utilities are not correct for a cross-compiler; we have to hope that
73 cross-versions are in the proper directories. */
76 #undef SUNOS4_SHARED_LIBRARIES
77 #undef OBJECT_FORMAT_COFF
78 #undef OBJECT_FORMAT_ROSE
80 #undef REAL_LD_FILE_NAME
81 #undef REAL_NM_FILE_NAME
82 #undef REAL_STRIP_FILE_NAME
85 /* If we cannot use a special method, use the ordinary one:
86 run nm to find what symbols are present.
87 In a cross-compiler, this means you need a cross nm,
88 but that is not quite as unpleasant as special headers. */
90 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
91 #define OBJECT_FORMAT_NONE
94 #ifdef OBJECT_FORMAT_COFF
103 /* Many versions of ldfcn.h define these. */
111 /* Some systems have an ISCOFF macro, but others do not. In some cases
112 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
113 that either do not have an ISCOFF macro in /usr/include or for those
114 where it is wrong. */
117 #define MY_ISCOFF(X) ISCOFF (X)
120 #endif /* OBJECT_FORMAT_COFF */
122 #ifdef OBJECT_FORMAT_ROSE
129 #include <sys/mman.h>
133 #include <mach_o_format.h>
134 #include <mach_o_header.h>
135 #include <mach_o_vals.h>
136 #include <mach_o_types.h>
138 #endif /* OBJECT_FORMAT_ROSE */
140 #ifdef OBJECT_FORMAT_NONE
142 /* Default flags to pass to nm. */
144 #define NM_FLAGS "-p"
147 #endif /* OBJECT_FORMAT_NONE */
149 /* Some systems use __main in a way incompatible with its use in gcc, in these
150 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
151 give the same symbol without quotes for an alternative entry point. You
152 must define both, or neither. */
154 #define NAME__MAIN "__main"
155 #define SYMBOL__MAIN __main
158 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
159 #define SCAN_LIBRARIES
163 int do_collecting = 1;
165 int do_collecting = 0;
168 /* Linked lists of constructor and destructor names. */
184 /* Enumeration giving which pass this is for scanning the program file. */
187 PASS_FIRST, /* without constructors */
188 PASS_OBJ, /* individual objects */
189 PASS_LIB, /* looking for shared libraries */
190 PASS_SECOND /* with constructors linked in */
193 #ifndef NO_SYS_SIGLIST
194 #ifndef SYS_SIGLIST_DECLARED
195 extern char *sys_siglist[];
198 extern char *version_string;
200 int vflag; /* true if -v */
201 static int rflag; /* true if -r */
202 static int strip_flag; /* true if -s */
203 #ifdef COLLECT_EXPORT_LIST
204 static int export_flag; /* true if -bE */
207 int debug; /* true if -debug */
209 static int shared_obj; /* true if -shared */
211 static int temp_filename_length; /* Length of temp_filename */
212 static char *temp_filename; /* Base of temp filenames */
213 static char *c_file; /* <xxx>.c for constructor/destructor list. */
214 static char *o_file; /* <xxx>.o for constructor/destructor list. */
215 #ifdef COLLECT_EXPORT_LIST
216 static char *export_file; /* <xxx>.x for AIX export list. */
217 static char *import_file; /* <xxx>.p for AIX import list. */
219 char *ldout; /* File for ld errors. */
220 static char *output_file; /* Output file for ld. */
221 static char *nm_file_name; /* pathname of nm */
223 static char *ldd_file_name; /* pathname of ldd (or equivalent) */
225 static char *strip_file_name; /* pathname of strip */
226 char *c_file_name; /* pathname of gcc */
227 static char *initname, *fininame; /* names of init and fini funcs */
229 static struct head constructors; /* list of constructors found */
230 static struct head destructors; /* list of destructors found */
231 #ifdef COLLECT_EXPORT_LIST
232 static struct head exports; /* list of exported symbols */
233 static struct head imports; /* list of imported symbols */
234 static struct head undefined; /* list of undefined symbols */
236 static struct head frame_tables; /* list of frame unwind info tables */
238 struct obstack temporary_obstack;
239 struct obstack permanent_obstack;
240 char * temporary_firstobj;
242 /* Defined in the automatically-generated underscore.c. */
243 extern int prepends_underscore;
245 extern char *mktemp ();
246 extern FILE *fdopen ();
248 /* Structure to hold all the directories in which to search for files to
253 char *prefix; /* String to prepend to the path. */
254 struct prefix_list *next; /* Next in linked list. */
259 struct prefix_list *plist; /* List of prefixes to try */
260 int max_len; /* Max length of a prefix in PLIST */
261 char *name; /* Name of this list (used in config stuff) */
264 #ifdef COLLECT_EXPORT_LIST
265 /* Lists to keep libraries to be scanned for global constructors/destructors. */
266 static struct head libs; /* list of libraries */
267 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
268 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
269 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
270 &libpath_lib_dirs, NULL};
271 static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
274 void collect_exit PROTO((int));
275 void collect_execute PROTO((char *, char **, char *));
276 void dump_file PROTO((char *));
277 static void handler PROTO((int));
278 static int is_ctor_dtor PROTO((char *));
279 static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
280 static char *find_a_file PROTO((struct path_prefix *, char *));
281 static void add_prefix PROTO((struct path_prefix *, char *));
282 static void prefix_from_env PROTO((char *, struct path_prefix *));
283 static void prefix_from_string PROTO((char *, struct path_prefix *));
284 static void do_wait PROTO((char *));
285 static void fork_execute PROTO((char *, char **));
286 static void maybe_unlink PROTO((char *));
287 static void add_to_list PROTO((struct head *, char *));
288 static void write_list PROTO((FILE *, char *, struct id *));
289 static void dump_list PROTO((FILE *, char *, struct id *));
290 static void dump_prefix_list PROTO((FILE *, char *, struct prefix_list *));
291 static int is_in_list PROTO((char *, struct id *));
292 static void write_list_with_asm PROTO((FILE *, char *, struct id *));
293 static void write_c_file PROTO((FILE *, char *));
294 static void scan_prog_file PROTO((char *, enum pass));
295 #ifdef SCAN_LIBRARIES
296 static void scan_libraries PROTO((char *));
298 #ifdef COLLECT_EXPORT_LIST
299 static void write_export_file PROTO((FILE *));
300 static void write_import_file PROTO((FILE *));
301 static char *resolve_lib_name PROTO((char *));
302 static int use_import_list PROTO((char *));
303 static int ignore_library PROTO((char *));
323 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
326 close (fdtmp[--fdx]);
342 static char buffer[30];
346 if (e > 0 && e < sys_nerr)
347 return sys_errlist[e];
349 sprintf (buffer, "Unknown error %d", e);
354 /* Delete tempfiles and exit function. */
357 collect_exit (status)
360 if (c_file != 0 && c_file[0])
361 maybe_unlink (c_file);
363 if (o_file != 0 && o_file[0])
364 maybe_unlink (o_file);
366 #ifdef COLLECT_EXPORT_LIST
367 if (export_file != 0 && export_file[0])
368 maybe_unlink (export_file);
370 if (import_file != 0 && import_file[0])
371 maybe_unlink (import_file);
374 if (ldout != 0 && ldout[0])
377 maybe_unlink (ldout);
380 if (status != 0 && output_file != 0 && output_file[0])
381 maybe_unlink (output_file);
387 /* Die when sys call fails. */
390 fatal_perror (string, arg1, arg2, arg3)
391 char *string, *arg1, *arg2, *arg3;
395 fprintf (stderr, "collect2: ");
396 fprintf (stderr, string, arg1, arg2, arg3);
397 fprintf (stderr, ": %s\n", my_strerror (e));
398 collect_exit (FATAL_EXIT_CODE);
404 fatal (string, arg1, arg2, arg3)
405 char *string, *arg1, *arg2, *arg3;
407 fprintf (stderr, "collect2: ");
408 fprintf (stderr, string, arg1, arg2, arg3);
409 fprintf (stderr, "\n");
410 collect_exit (FATAL_EXIT_CODE);
413 /* Write error message. */
416 error (string, arg1, arg2, arg3, arg4)
417 char *string, *arg1, *arg2, *arg3, *arg4;
419 fprintf (stderr, "collect2: ");
420 fprintf (stderr, string, arg1, arg2, arg3, arg4);
421 fprintf (stderr, "\n");
424 /* In case obstack is linked in, and abort is defined to fancy_abort,
425 provide a default entry. */
430 fatal ("internal error");
438 if (c_file != 0 && c_file[0])
439 maybe_unlink (c_file);
441 if (o_file != 0 && o_file[0])
442 maybe_unlink (o_file);
444 if (ldout != 0 && ldout[0])
445 maybe_unlink (ldout);
447 #ifdef COLLECT_EXPORT_LIST
448 if (export_file != 0 && export_file[0])
449 maybe_unlink (export_file);
451 if (import_file != 0 && import_file[0])
452 maybe_unlink (import_file);
455 signal (signo, SIG_DFL);
456 kill (getpid (), signo);
461 xcalloc (size1, size2)
464 char *ptr = (char *) calloc (size1, size2);
468 fatal ("out of memory");
476 char *ptr = (char *) malloc (size);
480 fatal ("out of memory");
489 register char *value = (char *) realloc (ptr, size);
491 fatal ("virtual memory exhausted");
499 return access (name, R_OK) == 0;
502 /* Make a copy of a string INPUT with size SIZE. */
505 savestring (input, size)
509 char *output = (char *) xmalloc (size + 1);
510 bcopy (input, output, size);
515 /* Parse a reasonable subset of shell quoting syntax. */
532 obstack_1grow (&temporary_obstack, c);
533 else if (! inside && c == ' ')
535 else if (! inside && c == '\\')
540 obstack_1grow (&temporary_obstack, c);
543 obstack_1grow (&temporary_obstack, '\0');
545 return obstack_finish (&temporary_obstack);
552 FILE *stream = fopen (name, "r");
553 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
560 while (c = getc (stream),
561 c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
562 obstack_1grow (&temporary_obstack, c);
563 if (obstack_object_size (&temporary_obstack) > 0)
565 char *word, *p, *result;
566 obstack_1grow (&temporary_obstack, '\0');
567 word = obstack_finish (&temporary_obstack);
570 ++word, putc ('.', stderr);
572 if (*p == '_' && prepends_underscore)
578 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
583 fputs (result, stderr);
585 diff = strlen (word) - strlen (result);
587 --diff, putc (' ', stderr);
588 while (diff < 0 && c == ' ')
589 ++diff, c = getc (stream);
594 fputs (word, stderr);
597 obstack_free (&temporary_obstack, temporary_firstobj);
606 /* Decide whether the given symbol is:
607 a constructor (1), a destructor (2), or neither (0). */
613 struct names { char *name; int len; int ret; int two_underscores; };
615 register struct names *p;
617 register char *orig_s = s;
619 static struct names special[] = {
620 #ifdef NO_DOLLAR_IN_LABEL
621 #ifdef NO_DOT_IN_LABEL
622 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
623 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
624 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
626 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
627 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
628 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
631 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
632 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
633 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
635 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
636 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
637 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
638 cfront has its own linker procedure to collect them;
639 if collect2 gets them too, they get collected twice
640 when the cfront procedure is run and the compiler used
641 for linking happens to be GCC. */
642 { "sti__", sizeof ("sti__")-1, 1, 1 },
643 { "std__", sizeof ("std__")-1, 2, 1 },
644 #endif /* CFRONT_LOSSAGE */
648 while ((ch = *s) == '_')
654 for (p = &special[0]; p->len > 0; p++)
657 && (!p->two_underscores || ((s - orig_s) >= 2))
658 && strncmp(s, p->name, p->len) == 0)
666 /* Routine to add variables to the environment. */
674 #ifndef VMS /* nor about VMS */
676 extern char **environ;
677 char **old_environ = environ;
684 while ((ch = *p++) != '\0' && ch != '=')
690 /* Search for replacing an existing environment variable, and
691 count the number of total environment variables. */
692 for (envp = old_environ; *envp; envp++)
695 if (!strncmp (str, *envp, name_len))
702 /* Add a new environment variable */
703 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
705 bcopy ((char *) old_environ, (char *) (environ + 1),
706 sizeof (char *) * (num_envs+1));
712 #endif /* HAVE_PUTENV */
714 /* By default, colon separates directories in a path. */
715 #ifndef PATH_SEPARATOR
716 #define PATH_SEPARATOR ':'
719 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
720 and one from the PATH variable. */
722 static struct path_prefix cpath, path;
725 /* This is the name of the target machine. We use it to form the name
726 of the files to execute. */
728 static char *target_machine = TARGET_MACHINE;
731 /* Names under which we were executed. Never return one of those files in our
734 static struct path_prefix our_file_names;
736 /* Determine if STRING is in PPREFIX.
738 This utility is currently only used to look up file names. Prefix lists
739 record directory names. This matters to us because the latter has a
740 trailing slash, so I've added a flag to handle both. */
743 is_in_prefix_list (pprefix, string, filep)
744 struct path_prefix *pprefix;
748 struct prefix_list *pl;
752 int len = strlen (string);
754 for (pl = pprefix->plist; pl; pl = pl->next)
756 if (strncmp (pl->prefix, string, len) == 0
757 && strcmp (pl->prefix + len, "/") == 0)
763 for (pl = pprefix->plist; pl; pl = pl->next)
765 if (strcmp (pl->prefix, string) == 0)
773 /* Search for NAME using prefix list PPREFIX. We only look for executable
776 Return 0 if not found, otherwise return its name, allocated with malloc. */
779 find_a_file (pprefix, name)
780 struct path_prefix *pprefix;
784 struct prefix_list *pl;
785 int len = pprefix->max_len + strlen (name) + 1;
788 fprintf (stderr, "Looking for '%s'\n", name);
790 #ifdef EXECUTABLE_SUFFIX
791 len += strlen (EXECUTABLE_SUFFIX);
794 temp = xmalloc (len);
796 /* Determine the filename to execute (special case for absolute paths). */
800 DIR_SEPARATOR == '\\' && name[1] == ':'
801 && (name[2] == DIR_SEPARATOR || name[2] == '/')
805 if (access (name, X_OK) == 0)
810 fprintf (stderr, " - found: absolute path\n");
816 fprintf (stderr, " - failed to locate using absolute path\n");
819 for (pl = pprefix->plist; pl; pl = pl->next)
821 strcpy (temp, pl->prefix);
825 fprintf (stderr, " - try: %s\n", temp);
827 if (! is_in_prefix_list (&our_file_names, temp, 1)
828 /* This is a kludge, but there seems no way around it. */
829 && strcmp (temp, "./ld") != 0
830 && access (temp, X_OK) == 0)
833 fprintf (stderr, " - found!\n");
838 #ifdef EXECUTABLE_SUFFIX
839 /* Some systems have a suffix for executable files.
840 So try appending that. */
841 strcat (temp, EXECUTABLE_SUFFIX);
844 fprintf (stderr, " - try: %s\n", temp);
846 if (! is_in_prefix_list (&our_file_names, temp, 1)
847 && access (temp, X_OK) == 0)
850 fprintf (stderr, " - found! (Uses executable suffix)\n");
855 if (debug && pl->next == NULL)
856 fprintf (stderr, " - failed to locate using relative paths\n");
859 if (debug && pprefix->plist == NULL)
860 fprintf (stderr, " - failed: no entries in prefix list\n");
866 /* Add an entry for PREFIX to prefix list PPREFIX. */
869 add_prefix (pprefix, prefix)
870 struct path_prefix *pprefix;
873 struct prefix_list *pl, **prev;
878 for (pl = pprefix->plist; pl->next; pl = pl->next)
883 prev = &pprefix->plist;
885 /* Keep track of the longest prefix */
887 len = strlen (prefix);
888 if (len > pprefix->max_len)
889 pprefix->max_len = len;
891 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
892 pl->prefix = savestring (prefix, len);
897 pl->next = (struct prefix_list *) 0;
901 /* Take the value of the environment variable ENV, break it into a path, and
902 add of the entries to PPREFIX. */
905 prefix_from_env (env, pprefix)
907 struct path_prefix *pprefix;
909 char *p = getenv (env);
912 prefix_from_string (p, pprefix);
916 prefix_from_string (p, pprefix)
918 struct path_prefix *pprefix;
921 char *nstore = (char *) xmalloc (strlen (p) + 3);
924 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
929 if (*endp == PATH_SEPARATOR || *endp == 0)
931 strncpy (nstore, startp, endp-startp);
934 strcpy (nstore, "./");
936 else if (endp[-1] != '/')
938 nstore[endp-startp] = '/';
939 nstore[endp-startp+1] = 0;
942 nstore[endp-startp] = 0;
945 fprintf (stderr, " - add prefix: %s\n", nstore);
947 add_prefix (pprefix, nstore);
950 endp = startp = endp + 1;
964 char *ld_suffix = "ld";
965 char *full_ld_suffix = ld_suffix;
966 char *real_ld_suffix = "real-ld";
967 char *collect_ld_suffix = "collect-ld";
968 char *nm_suffix = "nm";
969 char *full_nm_suffix = nm_suffix;
970 char *gnm_suffix = "gnm";
971 char *full_gnm_suffix = gnm_suffix;
973 char *ldd_suffix = LDD_SUFFIX;
974 char *full_ldd_suffix = ldd_suffix;
976 char *strip_suffix = "strip";
977 char *full_strip_suffix = strip_suffix;
978 char *gstrip_suffix = "gstrip";
979 char *full_gstrip_suffix = gstrip_suffix;
982 #ifdef COLLECT_EXPORT_LIST
992 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
993 char **ld1 = ld1_argv;
994 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
995 char **ld2 = ld2_argv;
996 char **object_lst = (char **) xcalloc (sizeof (char *), argc);
997 char **object = object_lst;
999 int num_c_args = argc+7;
1005 /* Parse command line early for instances of -debug. This allows
1006 the debug flag to be set before functions like find_a_file()
1011 for (i = 1; argv[i] != NULL; i ++)
1012 if (! strcmp (argv[i], "-debug"))
1017 #ifndef DEFAULT_A_OUT_NAME
1018 output_file = "a.out";
1020 output_file = DEFAULT_A_OUT_NAME;
1023 obstack_begin (&temporary_obstack, 0);
1024 obstack_begin (&permanent_obstack, 0);
1025 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
1026 current_demangling_style = gnu_demangling;
1028 /* We must check that we do not call ourselves in an infinite
1029 recursion loop. We append the name used for us to the COLLECT_NAMES
1030 environment variable.
1032 In practice, collect will rarely invoke itself. This can happen now
1033 that we are no longer called gld. A perfect example is when running
1034 gcc in a build directory that has been installed. When looking for
1035 ld, we will find our installed version and believe that's the real ld. */
1037 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
1038 previous version of collect (the one that used COLLECT_NAME and only
1039 handled two levels of recursion). If we do not we may mutually recurse
1040 forever. This can happen (I think) when bootstrapping the old version
1041 and a new one is installed (rare, but we should handle it).
1042 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
1044 GET_ENVIRONMENT (collect_name, "COLLECT_NAME");
1045 GET_ENVIRONMENT (collect_names, "COLLECT_NAMES");
1047 p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
1048 + (collect_name ? strlen (collect_name) + 1 : 0)
1049 + (collect_names ? strlen (collect_names) + 1 : 0)
1050 + strlen (argv[0]) + 1);
1051 strcpy (p, "COLLECT_NAMES=");
1052 if (collect_name != 0)
1053 sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
1054 if (collect_names != 0)
1055 sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
1056 strcat (p, argv[0]);
1059 prefix_from_env ("COLLECT_NAMES", &our_file_names);
1061 /* Set environment variable COLLECT_NAME to our name so the previous version
1062 of collect will not find us. If it does we will mutually recurse forever.
1063 This can happen when bootstrapping the new version and an old version is
1065 ??? Hopefully this bit of code can be removed at some point. */
1067 p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
1068 sprintf (p, "COLLECT_NAME=%s", argv[0]);
1071 p = getenv ("COLLECT_GCC_OPTIONS");
1074 char *q = extract_string (&p);
1075 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1078 obstack_free (&temporary_obstack, temporary_firstobj);
1081 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
1084 fatal ("no arguments");
1087 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1088 signal (SIGQUIT, handler);
1090 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1091 signal (SIGINT, handler);
1093 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1094 signal (SIGALRM, handler);
1097 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1098 signal (SIGHUP, handler);
1100 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1101 signal (SIGSEGV, handler);
1103 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1104 signal (SIGBUS, handler);
1107 /* Extract COMPILER_PATH and PATH into our prefix list. */
1108 prefix_from_env ("COMPILER_PATH", &cpath);
1109 prefix_from_env ("PATH", &path);
1111 #ifdef CROSS_COMPILE
1112 /* If we look for a program in the compiler directories, we just use
1113 the short name, since these directories are already system-specific.
1114 But it we look for a program in the system directories, we need to
1115 qualify the program name with the target machine. */
1118 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1119 strcpy (full_ld_suffix, target_machine);
1120 strcat (full_ld_suffix, "-");
1121 strcat (full_ld_suffix, ld_suffix);
1125 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1126 strcpy (full_gld_suffix, target_machine);
1127 strcat (full_gld_suffix, "-");
1128 strcat (full_gld_suffix, gld_suffix);
1132 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1133 strcpy (full_nm_suffix, target_machine);
1134 strcat (full_nm_suffix, "-");
1135 strcat (full_nm_suffix, nm_suffix);
1138 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1139 strcpy (full_gnm_suffix, target_machine);
1140 strcat (full_gnm_suffix, "-");
1141 strcat (full_gnm_suffix, gnm_suffix);
1145 = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1146 strcpy (full_ldd_suffix, target_machine);
1147 strcat (full_ldd_suffix, "-");
1148 strcat (full_ldd_suffix, ldd_suffix);
1152 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1153 strcpy (full_strip_suffix, target_machine);
1154 strcat (full_strip_suffix, "-");
1155 strcat (full_strip_suffix, strip_suffix);
1158 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1159 strcpy (full_gstrip_suffix, target_machine);
1160 strcat (full_gstrip_suffix, "-");
1161 strcat (full_gstrip_suffix, gstrip_suffix);
1162 #endif /* CROSS_COMPILE */
1164 /* Try to discover a valid linker/nm/strip to use. */
1166 /* Maybe we know the right file to use (if not cross). */
1167 #ifdef REAL_LD_FILE_NAME
1168 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1169 if (ld_file_name == 0)
1171 /* Search the (target-specific) compiler dirs for ld'. */
1172 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1173 /* Likewise for `collect-ld'. */
1174 if (ld_file_name == 0)
1175 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1176 /* Search the compiler directories for `ld'. We have protection against
1177 recursive calls in find_a_file. */
1178 if (ld_file_name == 0)
1179 ld_file_name = find_a_file (&cpath, ld_suffix);
1180 /* Search the ordinary system bin directories
1181 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1182 if (ld_file_name == 0)
1183 ld_file_name = find_a_file (&path, full_ld_suffix);
1185 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
1187 if (collect_names != 0)
1189 if (ld_file_name != 0)
1191 argv[0] = ld_file_name;
1192 execvp (argv[0], argv);
1194 fatal ("cannot find `ld' (%s)", ld_file_name);
1197 #ifdef REAL_NM_FILE_NAME
1198 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1199 if (nm_file_name == 0)
1201 nm_file_name = find_a_file (&cpath, gnm_suffix);
1202 if (nm_file_name == 0)
1203 nm_file_name = find_a_file (&path, full_gnm_suffix);
1204 if (nm_file_name == 0)
1205 nm_file_name = find_a_file (&cpath, nm_suffix);
1206 if (nm_file_name == 0)
1207 nm_file_name = find_a_file (&path, full_nm_suffix);
1210 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1211 if (ldd_file_name == 0)
1212 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1215 #ifdef REAL_STRIP_FILE_NAME
1216 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1217 if (strip_file_name == 0)
1219 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1220 if (strip_file_name == 0)
1221 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1222 if (strip_file_name == 0)
1223 strip_file_name = find_a_file (&cpath, strip_suffix);
1224 if (strip_file_name == 0)
1225 strip_file_name = find_a_file (&path, full_strip_suffix);
1227 /* Determine the full path name of the C compiler to use. */
1228 c_file_name = getenv ("COLLECT_GCC");
1229 if (c_file_name == 0)
1231 #ifdef CROSS_COMPILE
1232 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1233 strcpy (c_file_name, target_machine);
1234 strcat (c_file_name, "-gcc");
1236 c_file_name = "gcc";
1240 p = find_a_file (&cpath, c_file_name);
1242 /* Here it should be safe to use the system search path since we should have
1243 already qualified the name of the compiler when it is needed. */
1245 p = find_a_file (&path, c_file_name);
1250 *ld1++ = *ld2++ = ld_file_name;
1252 /* Make temp file names. */
1253 temp_filename = choose_temp_base ();
1254 temp_filename_length = strlen (temp_filename);
1255 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1256 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1257 #ifdef COLLECT_EXPORT_LIST
1258 export_file = xmalloc (temp_filename_length + sizeof (".x"));
1259 import_file = xmalloc (temp_filename_length + sizeof (".p"));
1261 ldout = xmalloc (temp_filename_length + sizeof (".ld"));
1262 sprintf (ldout, "%s.ld", temp_filename);
1263 sprintf (c_file, "%s.c", temp_filename);
1264 sprintf (o_file, "%s.o", temp_filename);
1265 #ifdef COLLECT_EXPORT_LIST
1266 sprintf (export_file, "%s.x", temp_filename);
1267 sprintf (import_file, "%s.p", temp_filename);
1269 *c_ptr++ = c_file_name;
1274 #ifdef COLLECT_EXPORT_LIST
1275 /* Generate a list of directories from LIBPATH. */
1276 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1277 /* Add to this list also two standard directories where
1278 AIX loader always searches for libraries. */
1279 add_prefix (&libpath_lib_dirs, "/lib");
1280 add_prefix (&libpath_lib_dirs, "/usr/lib");
1283 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1285 AIX support needs to know if -shared has been specified before
1286 parsing commandline arguments. */
1288 p = getenv ("COLLECT_GCC_OPTIONS");
1291 char *q = extract_string (&p);
1292 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1293 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1294 if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
1297 obstack_free (&temporary_obstack, temporary_firstobj);
1298 *c_ptr++ = "-fno-exceptions";
1300 /* !!! When GCC calls collect2,
1301 it does not know whether it is calling collect2 or ld.
1302 So collect2 cannot meaningfully understand any options
1303 except those ld understands.
1304 If you propose to make GCC pass some other option,
1305 just imagine what will happen if ld is really ld!!! */
1307 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1308 /* After the first file, put in the c++ rt0. */
1311 while ((arg = *++argv) != (char *) 0)
1313 *ld1++ = *ld2++ = arg;
1319 #ifdef COLLECT_EXPORT_LIST
1320 /* We want to disable automatic exports on AIX when user
1321 explicitly puts an export list in command line */
1323 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1329 if (!strcmp (arg, "-debug"))
1331 /* Already parsed. */
1340 /* place o_file BEFORE this argument! */
1346 #ifdef COLLECT_EXPORT_LIST
1348 /* Resolving full library name. */
1349 char *s = resolve_lib_name (arg+2);
1351 /* If we will use an import list for this library,
1352 we should exclude it from ld args. */
1353 if (use_import_list (s))
1359 /* Saving a full library name. */
1360 add_to_list (&libs, s);
1365 #ifdef COLLECT_EXPORT_LIST
1366 /* Saving directories where to search for libraries. */
1368 add_prefix (&cmdline_lib_dirs, arg+2);
1374 output_file = *ld1++ = *ld2++ = *++argv;
1376 output_file = &arg[2];
1385 if (arg[2] == '\0' && do_collecting)
1387 /* We must strip after the nm run, otherwise C++ linking
1388 will not work. Thus we strip in the second ld run, or
1389 else with strip if there is no second ld run. */
1401 else if ((p = rindex (arg, '.')) != (char *) 0
1402 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1403 || strcmp (p, ".so") == 0))
1412 /* place o_file BEFORE this argument! */
1420 #ifdef COLLECT_EXPORT_LIST
1421 /* libraries can be specified directly, i.e. without -l flag. */
1424 /* If we will use an import list for this library,
1425 we should exclude it from ld args. */
1426 if (use_import_list (arg))
1432 /* Saving a full library name. */
1433 add_to_list (&libs, arg);
1439 #ifdef COLLECT_EXPORT_LIST
1440 /* This is added only for debugging purposes. */
1443 fprintf (stderr, "List of libraries:\n");
1444 dump_list (stderr, "\t", libs.first);
1447 /* The AIX linker will discard static constructors in object files if
1448 nothing else in the file is referenced, so look at them first. */
1450 char **export_object_lst = object_lst;
1451 while (export_object_lst < object)
1452 scan_prog_file (*export_object_lst++, PASS_OBJ);
1455 struct id *list = libs.first;
1456 for (; list; list = list->next)
1457 scan_prog_file (list->name, PASS_FIRST);
1460 char *buf1 = alloca (strlen (export_file) + 5);
1461 char *buf2 = alloca (strlen (import_file) + 5);
1462 sprintf (buf1, "-bE:%s", export_file);
1463 sprintf (buf2, "-bI:%s", import_file);
1468 exportf = fopen (export_file, "w");
1469 if (exportf == (FILE *) 0)
1470 fatal_perror ("%s", export_file);
1471 write_export_file (exportf);
1472 if (fclose (exportf))
1473 fatal_perror ("closing %s", export_file);
1474 importf = fopen (import_file, "w");
1475 if (importf == (FILE *) 0)
1476 fatal_perror ("%s", import_file);
1477 write_import_file (importf);
1478 if (fclose (importf))
1479 fatal_perror ("closing %s", import_file);
1484 *object = *c_ptr = *ld1 = (char *) 0;
1488 fprintf (stderr, "collect2 version %s", version_string);
1489 #ifdef TARGET_VERSION
1492 fprintf (stderr, "\n");
1498 fprintf (stderr, "ld_file_name = %s\n",
1499 (ld_file_name ? ld_file_name : "not found"));
1500 fprintf (stderr, "c_file_name = %s\n",
1501 (c_file_name ? c_file_name : "not found"));
1502 fprintf (stderr, "nm_file_name = %s\n",
1503 (nm_file_name ? nm_file_name : "not found"));
1505 fprintf (stderr, "ldd_file_name = %s\n",
1506 (ldd_file_name ? ldd_file_name : "not found"));
1508 fprintf (stderr, "strip_file_name = %s\n",
1509 (strip_file_name ? strip_file_name : "not found"));
1510 fprintf (stderr, "c_file = %s\n",
1511 (c_file ? c_file : "not found"));
1512 fprintf (stderr, "o_file = %s\n",
1513 (o_file ? o_file : "not found"));
1515 ptr = getenv ("COLLECT_NAMES");
1517 fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
1519 ptr = getenv ("COLLECT_GCC_OPTIONS");
1521 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1523 ptr = getenv ("COLLECT_GCC");
1525 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1527 ptr = getenv ("COMPILER_PATH");
1529 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1531 ptr = getenv ("LIBRARY_PATH");
1533 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1535 fprintf (stderr, "\n");
1538 /* Load the program, searching all libraries and attempting to provide
1539 undefined symbols from repository information. */
1541 /* On AIX we do this later. */
1542 #ifndef COLLECT_EXPORT_LIST
1543 do_tlink (ld1_argv, object_lst);
1546 /* If -r or they will be run via some other method, do not build the
1547 constructor or destructor list, just return now. */
1548 if (rflag || ! do_collecting)
1550 #ifdef COLLECT_EXPORT_LIST
1551 /* But make sure we delete the export file we may have created. */
1552 if (export_file != 0 && export_file[0])
1553 maybe_unlink (export_file);
1554 if (import_file != 0 && import_file[0])
1555 maybe_unlink (import_file);
1560 /* Examine the namelist with nm and search it for static constructors
1561 and destructors to call.
1562 Write the constructor and destructor tables to a .s file and reload. */
1564 /* On AIX we already done scanning for global constructors/destructors. */
1565 #ifndef COLLECT_EXPORT_LIST
1566 scan_prog_file (output_file, PASS_FIRST);
1569 #ifdef SCAN_LIBRARIES
1570 scan_libraries (output_file);
1575 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1576 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1579 if (constructors.number == 0 && destructors.number == 0
1580 && frame_tables.number == 0
1581 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1582 /* If we will be running these functions ourselves, we want to emit
1583 stubs into the shared library so that we do not have to relink
1584 dependent programs when we add static objects. */
1589 #ifdef COLLECT_EXPORT_LIST
1590 /* Doing tlink without additional code generation */
1591 do_tlink (ld1_argv, object_lst);
1593 /* Strip now if it was requested on the command line. */
1596 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1597 strip_argv[0] = strip_file_name;
1598 strip_argv[1] = output_file;
1599 strip_argv[2] = (char *) 0;
1600 fork_execute ("strip", strip_argv);
1603 #ifdef COLLECT_EXPORT_LIST
1604 maybe_unlink (export_file);
1605 maybe_unlink (import_file);
1610 maybe_unlink(output_file);
1611 outf = fopen (c_file, "w");
1612 if (outf == (FILE *) 0)
1613 fatal_perror ("%s", c_file);
1615 write_c_file (outf, c_file);
1618 fatal_perror ("closing %s", c_file);
1620 /* Tell the linker that we have initializer and finalizer functions. */
1621 #ifdef LD_INIT_SWITCH
1622 *ld2++ = LD_INIT_SWITCH;
1624 *ld2++ = LD_FINI_SWITCH;
1629 #ifdef COLLECT_EXPORT_LIST
1632 add_to_list (&exports, initname);
1633 add_to_list (&exports, fininame);
1634 add_to_list (&exports, "_GLOBAL__DI");
1635 add_to_list (&exports, "_GLOBAL__DD");
1636 exportf = fopen (export_file, "w");
1637 if (exportf == (FILE *) 0)
1638 fatal_perror ("%s", export_file);
1639 write_export_file (exportf);
1640 if (fclose (exportf))
1641 fatal_perror ("closing %s", export_file);
1647 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1648 output_file, c_file);
1649 write_c_file (stderr, "stderr");
1650 fprintf (stderr, "========== end of c_file\n\n");
1651 #ifdef COLLECT_EXPORT_LIST
1652 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1653 write_export_file (stderr);
1654 fprintf (stderr, "========== end of export_file\n\n");
1658 /* Assemble the constructor and destructor tables.
1659 Link the tables in with the rest of the program. */
1661 fork_execute ("gcc", c_argv);
1662 #ifdef COLLECT_EXPORT_LIST
1663 /* On AIX we must call tlink because of possible templates resolution */
1664 do_tlink (ld2_argv, object_lst);
1666 /* Otherwise, simply call ld because tlink is already done */
1667 fork_execute ("ld", ld2_argv);
1669 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1670 constructors/destructors in shared libraries. */
1671 scan_prog_file (output_file, PASS_SECOND);
1674 maybe_unlink (c_file);
1675 maybe_unlink (o_file);
1677 #ifdef COLLECT_EXPORT_LIST
1678 maybe_unlink (export_file);
1679 maybe_unlink (import_file);
1686 /* Wait for a process to finish, and exit if a non-zero status is found. */
1697 if (WIFSIGNALED (status))
1699 int sig = WTERMSIG (status);
1700 #ifdef NO_SYS_SIGLIST
1701 error ("%s terminated with signal %d %s",
1704 (status & 0200) ? ", core dumped" : "");
1706 error ("%s terminated with signal %d [%s]%s",
1710 (status & 0200) ? ", core dumped" : "");
1713 collect_exit (FATAL_EXIT_CODE);
1716 if (WIFEXITED (status))
1717 return WEXITSTATUS (status);
1726 int ret = collect_wait (prog);
1729 error ("%s returned %d exit status", prog, ret);
1735 /* Fork and execute a program, and wait for the reply. */
1738 collect_execute (prog, argv, redir)
1751 fprintf (stderr, "%s", argv[0]);
1753 fprintf (stderr, "[cannot find %s]", prog);
1755 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1756 fprintf (stderr, " %s", str);
1758 fprintf (stderr, "\n");
1764 /* If we cannot find a program we need, complain error. Do this here
1765 since we might not end up needing something that we could not find. */
1768 fatal ("cannot find `%s'", prog);
1774 fatal_perror ("fork");
1776 fatal_perror ("vfork");
1780 if (pid == 0) /* child context */
1785 if (freopen (redir, "a", stdout) == NULL)
1786 fatal_perror ("redirecting stdout: %s", redir);
1787 if (freopen (redir, "a", stderr) == NULL)
1788 fatal_perror ("redirecting stderr: %s", redir);
1791 execvp (argv[0], argv);
1792 fatal_perror ("executing %s", prog);
1797 fork_execute (prog, argv)
1801 collect_execute (prog, argv, NULL);
1805 /* Unlink a file unless we are debugging. */
1814 fprintf (stderr, "[Leaving %s]\n", file);
1818 /* Add a name to a linked list. */
1821 add_to_list (head_ptr, name)
1822 struct head *head_ptr;
1826 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1828 static long sequence_number = 0;
1829 strcpy (newid->name, name);
1831 if (head_ptr->first)
1832 head_ptr->last->next = newid;
1834 head_ptr->first = newid;
1836 /* Check for duplicate symbols. */
1837 for (p = head_ptr->first;
1838 strcmp (name, p->name) != 0;
1843 head_ptr->last->next = 0;
1848 newid->sequence = ++sequence_number;
1849 head_ptr->last = newid;
1853 /* Write: `prefix', the names on list LIST, `suffix'. */
1856 write_list (stream, prefix, list)
1863 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1868 /* This function is really used only on AIX, but may be useful. */
1870 is_in_list (prefix, list)
1876 if (!strcmp (prefix, list->name)) return 1;
1882 /* Added for debugging purpose. */
1884 dump_list (stream, prefix, list)
1891 fprintf (stream, "%s%s,\n", prefix, list->name);
1897 dump_prefix_list (stream, prefix, list)
1900 struct prefix_list *list;
1904 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1910 write_list_with_asm (stream, prefix, list)
1917 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1918 prefix, list->sequence, list->name);
1923 /* Write out the constructor and destructor tables statically (for a shared
1924 object), along with the functions to execute them. */
1927 write_c_file_stat (stream, name)
1931 char *prefix, *p, *q;
1932 int frames = (frame_tables.number > 0);
1934 /* Figure out name of output_file, stripping off .so version. */
1935 p = rindex (output_file, '/');
1937 p = (char *) output_file;
1951 if (strncmp (q, ".so", 3) == 0)
1960 /* q points to null at end of the string (or . of the .so version) */
1961 prefix = xmalloc (q - p + 1);
1962 strncpy (prefix, p, q - p);
1964 for (q = prefix; *q; q++)
1968 fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
1969 output_file, prefix);
1971 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1972 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1973 sprintf (initname, INIT_NAME_FORMAT, prefix);
1975 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1976 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1977 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1981 /* Write the tables as C code */
1983 fprintf (stream, "static int count;\n");
1984 fprintf (stream, "typedef void entry_pt();\n");
1985 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1989 write_list_with_asm (stream, "extern void *", frame_tables.first);
1991 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1992 write_list (stream, "\t\t&", frame_tables.first);
1993 fprintf (stream, "\t0\n};\n");
1995 /* This must match what's in frame.h. */
1996 fprintf (stream, "struct object {\n");
1997 fprintf (stream, " void *pc_begin;\n");
1998 fprintf (stream, " void *pc_end;\n");
1999 fprintf (stream, " void *fde_begin;\n");
2000 fprintf (stream, " void *fde_array;\n");
2001 fprintf (stream, " __SIZE_TYPE__ count;\n");
2002 fprintf (stream, " struct object *next;\n");
2003 fprintf (stream, "};\n");
2005 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2006 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2008 fprintf (stream, "static void reg_frame () {\n");
2009 fprintf (stream, "\tstatic struct object ob;\n");
2010 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2011 fprintf (stream, "\t}\n");
2013 fprintf (stream, "static void dereg_frame () {\n");
2014 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2015 fprintf (stream, "\t}\n");
2018 fprintf (stream, "void %s() {\n", initname);
2019 if (constructors.number > 0 || frames)
2021 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
2022 write_list (stream, "\t\t", constructors.first);
2024 fprintf (stream, "\treg_frame,\n");
2025 fprintf (stream, "\t};\n");
2026 fprintf (stream, "\tentry_pt **p;\n");
2027 fprintf (stream, "\tif (count++ != 0) return;\n");
2028 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
2029 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
2032 fprintf (stream, "\t++count;\n");
2033 fprintf (stream, "}\n");
2034 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2035 fprintf (stream, "void %s() {\n", fininame);
2036 if (destructors.number > 0 || frames)
2038 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
2039 write_list (stream, "\t\t", destructors.first);
2041 fprintf (stream, "\tdereg_frame,\n");
2042 fprintf (stream, "\t};\n");
2043 fprintf (stream, "\tentry_pt **p;\n");
2044 fprintf (stream, "\tif (--count != 0) return;\n");
2045 fprintf (stream, "\tp = dtors;\n");
2046 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
2047 destructors.number + frames);
2049 fprintf (stream, "}\n");
2053 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
2054 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
2058 /* Write the constructor/destructor tables. */
2060 #ifndef LD_INIT_SWITCH
2062 write_c_file_glob (stream, name)
2066 /* Write the tables as C code */
2068 int frames = (frame_tables.number > 0);
2070 fprintf (stream, "typedef void entry_pt();\n\n");
2072 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2076 write_list_with_asm (stream, "extern void *", frame_tables.first);
2078 fprintf (stream, "\tstatic void *frame_table[] = {\n");
2079 write_list (stream, "\t\t&", frame_tables.first);
2080 fprintf (stream, "\t0\n};\n");
2082 /* This must match what's in frame.h. */
2083 fprintf (stream, "struct object {\n");
2084 fprintf (stream, " void *pc_begin;\n");
2085 fprintf (stream, " void *pc_end;\n");
2086 fprintf (stream, " void *fde_begin;\n");
2087 fprintf (stream, " void *fde_array;\n");
2088 fprintf (stream, " __SIZE_TYPE__ count;\n");
2089 fprintf (stream, " struct object *next;\n");
2090 fprintf (stream, "};\n");
2092 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2093 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2095 fprintf (stream, "static void reg_frame () {\n");
2096 fprintf (stream, "\tstatic struct object ob;\n");
2097 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2098 fprintf (stream, "\t}\n");
2100 fprintf (stream, "static void dereg_frame () {\n");
2101 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2102 fprintf (stream, "\t}\n");
2105 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2106 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2107 write_list (stream, "\t", constructors.first);
2109 fprintf (stream, "\treg_frame,\n");
2110 fprintf (stream, "\t0\n};\n\n");
2112 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2114 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2115 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2116 write_list (stream, "\t", destructors.first);
2118 fprintf (stream, "\tdereg_frame,\n");
2119 fprintf (stream, "\t0\n};\n\n");
2121 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2122 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2124 #endif /* ! LD_INIT_SWITCH */
2127 write_c_file (stream, name)
2131 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2132 #ifndef LD_INIT_SWITCH
2134 write_c_file_glob (stream, name);
2137 write_c_file_stat (stream, name);
2138 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2141 #ifdef COLLECT_EXPORT_LIST
2143 write_export_file (stream)
2146 struct id *list = exports.first;
2147 for (; list; list = list->next)
2148 fprintf (stream, "%s\n", list->name);
2152 write_import_file (stream)
2155 struct id *list = imports.first;
2156 fprintf (stream, "%s\n", "#! .");
2157 for (; list; list = list->next)
2158 fprintf (stream, "%s\n", list->name);
2162 #ifdef OBJECT_FORMAT_NONE
2164 /* Generic version to scan the name list of the loaded program for
2165 the symbols g++ uses for static constructors and destructors.
2167 The constructor table begins at __CTOR_LIST__ and contains a count
2168 of the number of pointers (or -1 if the constructors are built in a
2169 separate section by the linker), followed by the pointers to the
2170 constructor functions, terminated with a null pointer. The
2171 destructor table has the same format, and begins at __DTOR_LIST__. */
2174 scan_prog_file (prog_name, which_pass)
2176 enum pass which_pass;
2178 void (*int_handler) ();
2179 void (*quit_handler) ();
2187 if (which_pass == PASS_SECOND)
2190 /* If we do not have an `nm', complain. */
2191 if (nm_file_name == 0)
2192 fatal ("cannot find `nm'");
2194 nm_argv[argc++] = nm_file_name;
2195 if (NM_FLAGS[0] != '\0')
2196 nm_argv[argc++] = NM_FLAGS;
2198 nm_argv[argc++] = prog_name;
2199 nm_argv[argc++] = (char *) 0;
2201 if (pipe (pipe_fd) < 0)
2202 fatal_perror ("pipe");
2204 inf = fdopen (pipe_fd[0], "r");
2205 if (inf == (FILE *) 0)
2206 fatal_perror ("fdopen");
2208 /* Trace if needed. */
2214 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2215 fprintf (stderr, " %s", str);
2217 fprintf (stderr, "\n");
2223 /* Spawn child nm on pipe */
2228 fatal_perror ("fork");
2230 fatal_perror ("vfork");
2234 if (pid == 0) /* child context */
2237 if (dup2 (pipe_fd[1], 1) < 0)
2238 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2240 if (close (pipe_fd[0]) < 0)
2241 fatal_perror ("close (%d)", pipe_fd[0]);
2243 if (close (pipe_fd[1]) < 0)
2244 fatal_perror ("close (%d)", pipe_fd[1]);
2246 execv (nm_file_name, nm_argv);
2247 fatal_perror ("executing %s", nm_file_name);
2250 /* Parent context from here on. */
2251 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
2253 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
2256 if (close (pipe_fd[1]) < 0)
2257 fatal_perror ("close (%d)", pipe_fd[1]);
2260 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2262 /* Read each line of nm output. */
2263 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2268 /* If it contains a constructor or destructor name, add the name
2269 to the appropriate list. */
2271 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2272 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2279 /* Find the end of the symbol name.
2280 Do not include `|', because Encore nm can tack that on the end. */
2281 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
2287 switch (is_ctor_dtor (name))
2290 if (which_pass != PASS_LIB)
2291 add_to_list (&constructors, name);
2295 if (which_pass != PASS_LIB)
2296 add_to_list (&destructors, name);
2300 if (which_pass != PASS_LIB)
2301 fatal ("init function found in object %s", prog_name);
2302 #ifndef LD_INIT_SWITCH
2303 add_to_list (&constructors, name);
2308 if (which_pass != PASS_LIB)
2309 fatal ("fini function found in object %s", prog_name);
2310 #ifndef LD_FINI_SWITCH
2311 add_to_list (&destructors, name);
2316 if (which_pass != PASS_LIB)
2317 add_to_list (&frame_tables, name);
2319 default: /* not a constructor or destructor */
2324 fprintf (stderr, "\t%s\n", buf);
2328 fprintf (stderr, "\n");
2330 if (fclose (inf) != 0)
2331 fatal_perror ("fclose of pipe");
2333 do_wait (nm_file_name);
2335 signal (SIGINT, int_handler);
2337 signal (SIGQUIT, quit_handler);
2341 #if SUNOS4_SHARED_LIBRARIES
2343 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2344 that the output file depends upon and their initialization/finalization
2345 routines, if any. */
2350 #include <sys/mman.h>
2351 #include <sys/param.h>
2353 #include <sys/dir.h>
2355 /* pointers to the object file */
2356 unsigned object; /* address of memory mapped file */
2357 unsigned objsize; /* size of memory mapped to file */
2358 char * code; /* pointer to code segment */
2359 char * data; /* pointer to data segment */
2360 struct nlist *symtab; /* pointer to symbol table */
2361 struct link_dynamic *ld;
2362 struct link_dynamic_2 *ld_2;
2363 struct head libraries;
2365 /* Map the file indicated by NAME into memory and store its address. */
2373 if ((fp = open (name, O_RDONLY)) == -1)
2374 fatal ("unable to open file '%s'", name);
2375 if (fstat (fp, &s) == -1)
2376 fatal ("unable to stat file '%s'", name);
2378 objsize = s.st_size;
2379 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2382 fatal ("unable to mmap file '%s'", name);
2387 /* Helpers for locatelib. */
2389 static char *libname;
2395 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2398 /* If one file has an additional numeric extension past LIBNAME, then put
2399 that one first in the sort. If both files have additional numeric
2400 extensions, then put the one with the higher number first in the sort.
2402 We must verify that the extension is numeric, because Sun saves the
2403 original versions of patched libraries with a .FCS extension. Files with
2404 invalid extensions must go last in the sort, so that they will not be used. */
2408 struct direct **d1, **d2;
2410 int i1, i2 = strlen (libname);
2411 char *e1 = (*d1)->d_name + i2;
2412 char *e2 = (*d2)->d_name + i2;
2414 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2415 && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))
2419 i1 = strtol (e1, &e1, 10);
2420 i2 = strtol (e2, &e2, 10);
2427 /* It has a valid numeric extension, prefer this one. */
2428 if (*e1 == '.' && e1[1] && isdigit (e1[1]))
2430 /* It has a invalid numeric extension, must prefer the other one. */
2436 /* It has a valid numeric extension, prefer this one. */
2437 if (*e2 == '.' && e2[1] && isdigit (e2[1]))
2439 /* It has a invalid numeric extension, must prefer the other one. */
2447 /* Given the name NAME of a dynamic dependency, find its pathname and add
2448 it to the list of libraries. */
2456 char buf[MAXPATHLEN];
2464 /* counting elements in array, need 1 extra for null */
2466 ld_rules = (char *) (ld_2->ld_rules + code);
2470 for (; *ld_rules != 0; ld_rules++)
2471 if (*ld_rules == ':')
2473 ld_rules = (char *) (ld_2->ld_rules + code);
2474 ldr = (char *) malloc (strlen (ld_rules) + 1);
2475 strcpy (ldr, ld_rules);
2477 p = getenv ("LD_LIBRARY_PATH");
2482 for (q = p ; *q != 0; q++)
2485 q = (char *) malloc (strlen (p) + 1);
2488 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2493 for (; *ldr != 0; ldr++)
2503 for (; *q != 0; q++)
2510 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2513 *pp++ = "/usr/local/lib";
2517 for (pp = l; *pp != 0 ; pp++)
2519 struct direct **namelist;
2521 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2523 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2524 add_to_list (&libraries, buf);
2526 fprintf (stderr, "%s\n", buf);
2533 fprintf (stderr, "not found\n");
2535 fatal ("dynamic dependency %s not found", name);
2539 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2540 that it depends upon and any constructors or destructors they contain. */
2543 scan_libraries (prog_name)
2546 struct exec *header;
2548 struct link_object *lo;
2549 char buff[MAXPATHLEN];
2552 mapfile (prog_name);
2553 header = (struct exec *)object;
2554 if (N_BADMAG (*header))
2555 fatal ("bad magic number in file '%s'", prog_name);
2556 if (header->a_dynamic == 0)
2559 code = (char *) (N_TXTOFF (*header) + (long) header);
2560 data = (char *) (N_DATOFF (*header) + (long) header);
2561 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2563 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2566 ld = (struct link_dynamic *) (symtab->n_value + code);
2572 ld = (struct link_dynamic *) data;
2577 fprintf (stderr, "dynamic dependencies.\n");
2579 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2580 for (lo = (struct link_object *) ld_2->ld_need; lo;
2581 lo = (struct link_object *) lo->lo_next)
2584 lo = (struct link_object *) ((long) lo + code);
2585 name = (char *) (code + lo->lo_name);
2589 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2590 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2596 fprintf (stderr, "\t%s\n", name);
2597 add_to_list (&libraries, name);
2602 fprintf (stderr, "\n");
2604 /* now iterate through the library list adding their symbols to
2606 for (list = libraries.first; list; list = list->next)
2607 scan_prog_file (list->name, PASS_LIB);
2610 #else /* SUNOS4_SHARED_LIBRARIES */
2613 /* Use the List Dynamic Dependencies program to find shared libraries that
2614 the output file depends upon and their initialization/finalization
2615 routines, if any. */
2618 scan_libraries (prog_name)
2621 static struct head libraries; /* list of shared libraries found */
2623 void (*int_handler) ();
2624 void (*quit_handler) ();
2632 /* If we do not have an `ldd', complain. */
2633 if (ldd_file_name == 0)
2635 error ("cannot find `ldd'");
2639 ldd_argv[argc++] = ldd_file_name;
2640 ldd_argv[argc++] = prog_name;
2641 ldd_argv[argc++] = (char *) 0;
2643 if (pipe (pipe_fd) < 0)
2644 fatal_perror ("pipe");
2646 inf = fdopen (pipe_fd[0], "r");
2647 if (inf == (FILE *) 0)
2648 fatal_perror ("fdopen");
2650 /* Trace if needed. */
2656 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2657 fprintf (stderr, " %s", str);
2659 fprintf (stderr, "\n");
2665 /* Spawn child ldd on pipe */
2670 fatal_perror ("fork");
2672 fatal_perror ("vfork");
2676 if (pid == 0) /* child context */
2679 if (dup2 (pipe_fd[1], 1) < 0)
2680 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2682 if (close (pipe_fd[0]) < 0)
2683 fatal_perror ("close (%d)", pipe_fd[0]);
2685 if (close (pipe_fd[1]) < 0)
2686 fatal_perror ("close (%d)", pipe_fd[1]);
2688 execv (ldd_file_name, ldd_argv);
2689 fatal_perror ("executing %s", ldd_file_name);
2692 /* Parent context from here on. */
2693 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2695 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2698 if (close (pipe_fd[1]) < 0)
2699 fatal_perror ("close (%d)", pipe_fd[1]);
2702 fprintf (stderr, "\nldd output with constructors/destructors.\n");
2704 /* Read each line of ldd output. */
2705 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2708 char *name, *end, *p = buf;
2710 /* Extract names of libraries and add to list. */
2711 PARSE_LDD_OUTPUT (p);
2716 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2717 fatal ("dynamic dependency %s not found", buf);
2719 /* Find the end of the symbol name. */
2721 (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
2726 if (access (name, R_OK) == 0)
2727 add_to_list (&libraries, name);
2729 fatal ("unable to open dynamic dependency '%s'", buf);
2732 fprintf (stderr, "\t%s\n", buf);
2735 fprintf (stderr, "\n");
2737 if (fclose (inf) != 0)
2738 fatal_perror ("fclose of pipe");
2740 do_wait (ldd_file_name);
2742 signal (SIGINT, int_handler);
2744 signal (SIGQUIT, quit_handler);
2747 /* now iterate through the library list adding their symbols to
2749 for (list = libraries.first; list; list = list->next)
2750 scan_prog_file (list->name, PASS_LIB);
2753 #endif /* LDD_SUFFIX */
2754 #endif /* SUNOS4_SHARED_LIBRARIES */
2756 #endif /* OBJECT_FORMAT_NONE */
2760 * COFF specific stuff.
2763 #ifdef OBJECT_FORMAT_COFF
2765 #if defined(EXTENDED_COFF)
2766 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2767 # define GCC_SYMENT SYMR
2768 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2769 # define GCC_SYMINC(X) (1)
2770 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2771 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2773 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2774 # define GCC_SYMENT SYMENT
2775 # define GCC_OK_SYMBOL(X) \
2776 (((X).n_sclass == C_EXT) && \
2777 ((X).n_scnum > N_UNDEF) && \
2778 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2779 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2780 # define GCC_UNDEF_SYMBOL(X) \
2781 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2782 # define GCC_SYMINC(X) ((X).n_numaux+1)
2783 # define GCC_SYMZERO(X) 0
2784 # define GCC_CHECK_HDR(X) (1)
2787 extern char *ldgetname ();
2789 /* COFF version to scan the name list of the loaded program for
2790 the symbols g++ uses for static constructors and destructors.
2792 The constructor table begins at __CTOR_LIST__ and contains a count
2793 of the number of pointers (or -1 if the constructors are built in a
2794 separate section by the linker), followed by the pointers to the
2795 constructor functions, terminated with a null pointer. The
2796 destructor table has the same format, and begins at __DTOR_LIST__. */
2799 scan_prog_file (prog_name, which_pass)
2801 enum pass which_pass;
2803 LDFILE *ldptr = NULL;
2804 int sym_index, sym_count;
2806 #ifdef COLLECT_EXPORT_LIST
2807 /* Should we generate an import list for given prog_name? */
2808 int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name));
2811 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2814 #ifdef COLLECT_EXPORT_LIST
2815 /* We do not need scanning for some standard C libraries. */
2816 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2819 /* On AIX we have a loop, because there is not much difference
2820 between an object and an archive. This trick allows us to
2821 eliminate scan_libraries() function. */
2825 if ((ldptr = ldopen (prog_name, ldptr)) != NULL)
2828 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2829 fatal ("%s: not a COFF file", prog_name);
2831 #ifdef COLLECT_EXPORT_LIST
2832 /* Is current archive member a shared object? */
2833 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2835 if (GCC_CHECK_HDR (ldptr))
2837 sym_count = GCC_SYMBOLS (ldptr);
2838 sym_index = GCC_SYMZERO (ldptr);
2839 while (sym_index < sym_count)
2843 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2845 sym_index += GCC_SYMINC (symbol);
2847 if (GCC_OK_SYMBOL (symbol))
2851 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2852 continue; /* should never happen */
2854 #ifdef XCOFF_DEBUGGING_INFO
2855 /* All AIX function names have a duplicate entry
2856 beginning with a dot. */
2861 switch (is_ctor_dtor (name))
2864 if (! is_shared) add_to_list (&constructors, name);
2865 #ifdef COLLECT_EXPORT_LIST
2866 if (which_pass == PASS_OBJ)
2867 add_to_list (&exports, name);
2868 /* If this symbol was undefined and we are building
2869 an import list, we should add a symbol to this
2873 && is_in_list (name, undefined.first))
2874 add_to_list (&imports, name);
2879 if (! is_shared) add_to_list (&destructors, name);
2880 #ifdef COLLECT_EXPORT_LIST
2881 if (which_pass == PASS_OBJ)
2882 add_to_list (&exports, name);
2883 /* If this symbol was undefined and we are building
2884 an import list, we should add a symbol to this
2888 && is_in_list (name, undefined.first))
2889 add_to_list (&imports, name);
2893 #ifdef COLLECT_EXPORT_LIST
2896 add_to_list (&constructors, name);
2901 add_to_list (&destructors, name);
2905 default: /* not a constructor or destructor */
2906 #ifdef COLLECT_EXPORT_LIST
2907 /* If we are building a shared object on AIX we need
2908 to explicitly export all global symbols or add
2909 them to import list. */
2911 if (which_pass == PASS_OBJ && (! export_flag))
2912 add_to_list (&exports, name);
2913 else if (! is_shared && which_pass == PASS_FIRST
2915 && is_in_list(name, undefined.first))
2916 add_to_list (&imports, name);
2921 #if !defined(EXTENDED_COFF)
2923 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2924 symbol.n_scnum, symbol.n_sclass,
2925 (symbol.n_type ? "0" : ""), symbol.n_type,
2930 "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
2931 symbol.iss, symbol.value, symbol.index, name);
2934 #ifdef COLLECT_EXPORT_LIST
2935 /* If we are building a shared object we should collect
2936 information about undefined symbols for later
2937 import list generation. */
2938 else if (shared_obj && GCC_UNDEF_SYMBOL (symbol))
2942 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2943 continue; /* should never happen */
2945 /* All AIX function names have a duplicate entry
2946 beginning with a dot. */
2949 add_to_list (&undefined, name);
2957 fatal ("%s: cannot open as COFF file", prog_name);
2959 #ifdef COLLECT_EXPORT_LIST
2960 /* On AIX loop continues while there are more members in archive. */
2962 while (ldclose (ldptr) == FAILURE);
2964 /* Otherwise we simply close ldptr. */
2965 (void) ldclose(ldptr);
2970 #ifdef COLLECT_EXPORT_LIST
2972 /* This new function is used to decide whether we should
2973 generate import list for an object or to use it directly. */
2975 use_import_list (prog_name)
2980 /* If we do not build a shared object then import list should not be used. */
2981 if (! shared_obj) return 0;
2983 /* Currently we check only for libgcc, but this can be changed in future. */
2984 p = strstr (prog_name, "libgcc.a");
2985 if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
2990 /* Given a library name without "lib" prefix, this function
2991 returns a full library name including a path. */
2993 resolve_lib_name (name)
2999 for (i = 0; libpaths[i]; i++)
3000 if (libpaths[i]->max_len > l)
3001 l = libpaths[i]->max_len;
3003 lib_buf = xmalloc (l + strlen(name) + 10);
3005 for (i = 0; libpaths[i]; i++)
3007 struct prefix_list *list = libpaths[i]->plist;
3008 for (; list; list = list->next)
3010 for (j = 0; libexts[j]; j++)
3012 /* The following lines are needed because path_prefix list
3013 may contain directories both with trailing '/' and
3016 if (list->prefix[strlen(list->prefix)-1] != '/')
3018 sprintf (lib_buf, "%s%slib%s.%s",
3019 list->prefix, p, name, libexts[j]);
3020 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
3021 if (file_exists (lib_buf))
3023 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
3030 fprintf (stderr, "not found\n");
3032 fatal ("Library lib%s not found", name);
3036 /* Array of standard AIX libraries which should not
3037 be scanned for ctors/dtors. */
3038 static char* aix_std_libs[] = {
3043 "/usr/lib/libc_r.a",
3044 "/usr/lib/threads/libc.a",
3045 "/usr/ccs/lib/libc.a",
3046 "/usr/ccs/lib/libc_r.a",
3050 /* This function checks the filename and returns 1
3051 if this name matches the location of a standard AIX library. */
3053 ignore_library (name)
3056 char **p = &aix_std_libs[0];
3057 while (*p++ != NULL)
3058 if (! strcmp (name, *p)) return 1;
3064 #endif /* OBJECT_FORMAT_COFF */
3068 * OSF/rose specific stuff.
3071 #ifdef OBJECT_FORMAT_ROSE
3073 /* Union of the various load commands */
3075 typedef union load_union
3077 ldc_header_t hdr; /* common header */
3078 load_cmd_map_command_t map; /* map indexing other load cmds */
3079 interpreter_command_t iprtr; /* interpreter pathname */
3080 strings_command_t str; /* load commands strings section */
3081 region_command_t region; /* region load command */
3082 reloc_command_t reloc; /* relocation section */
3083 package_command_t pkg; /* package load command */
3084 symbols_command_t sym; /* symbol sections */
3085 entry_command_t ent; /* program start section */
3086 gen_info_command_t info; /* object information */
3087 func_table_command_t func; /* function constructors/destructors */
3090 /* Structure to point to load command and data section in memory. */
3092 typedef struct load_all
3094 load_union_t *load; /* load command */
3095 char *section; /* pointer to section */
3098 /* Structure to contain information about a file mapped into memory. */
3102 char *start; /* start of map */
3103 char *name; /* filename */
3104 long size; /* size of the file */
3105 long rounded_size; /* size rounded to page boundary */
3106 int fd; /* file descriptor */
3107 int rw; /* != 0 if opened read/write */
3108 int use_mmap; /* != 0 if mmap'ed */
3111 extern int decode_mach_o_hdr ();
3112 extern int encode_mach_o_hdr ();
3114 static void add_func_table PROTO((mo_header_t *, load_all_t *,
3115 symbol_info_t *, int));
3116 static void print_header PROTO((mo_header_t *));
3117 static void print_load_command PROTO((load_union_t *, size_t, int));
3118 static void bad_header PROTO((int));
3119 static struct file_info *read_file PROTO((char *, int, int));
3120 static void end_file PROTO((struct file_info *));
3122 /* OSF/rose specific version to scan the name list of the loaded
3123 program for the symbols g++ uses for static constructors and
3126 The constructor table begins at __CTOR_LIST__ and contains a count
3127 of the number of pointers (or -1 if the constructors are built in a
3128 separate section by the linker), followed by the pointers to the
3129 constructor functions, terminated with a null pointer. The
3130 destructor table has the same format, and begins at __DTOR_LIST__. */
3133 scan_prog_file (prog_name, which_pass)
3135 enum pass which_pass;
3139 load_all_t *load_array;
3140 load_all_t *load_end;
3141 load_all_t *load_cmd;
3142 int symbol_load_cmds;
3148 struct file_info *obj_file;
3150 mo_lcid_t cmd_strings = -1;
3151 symbol_info_t *main_sym = 0;
3152 int rw = (which_pass != PASS_FIRST);
3154 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3156 fatal_perror ("cannot read %s", prog_name);
3158 obj_file = read_file (prog_name, prog_fd, rw);
3159 obj = obj_file->start;
3161 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3162 if (status != MO_HDR_CONV_SUCCESS)
3163 bad_header (status);
3166 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3167 since the hardware will automatically swap bytes for us on loading little endian
3170 #ifndef CROSS_COMPILE
3171 if (hdr.moh_magic != MOH_MAGIC_MSB
3172 || hdr.moh_header_version != MOH_HEADER_VERSION
3173 || hdr.moh_byte_order != OUR_BYTE_ORDER
3174 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3175 || hdr.moh_cpu_type != OUR_CPU_TYPE
3176 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3177 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3179 fatal ("incompatibilities between object file & expected values");
3184 print_header (&hdr);
3186 offset = hdr.moh_first_cmd_off;
3187 load_end = load_array
3188 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3190 /* Build array of load commands, calculating the offsets */
3191 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3193 load_union_t *load_hdr; /* load command header */
3195 load_cmd = load_end++;
3196 load_hdr = (load_union_t *) (obj + offset);
3198 /* If modifying the program file, copy the header. */
3201 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3202 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
3205 /* null out old command map, because we will rewrite at the end. */
3206 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3208 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3209 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3213 load_cmd->load = load_hdr;
3214 if (load_hdr->hdr.ldci_section_off > 0)
3215 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3218 print_load_command (load_hdr, offset, i);
3220 offset += load_hdr->hdr.ldci_cmd_size;
3223 /* If the last command is the load command map and is not undefined,
3224 decrement the count of load commands. */
3225 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3228 hdr.moh_n_load_cmds--;
3231 /* Go through and process each symbol table section. */
3232 symbol_load_cmds = 0;
3233 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3235 load_union_t *load_hdr = load_cmd->load;
3237 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3243 char *kind = "unknown";
3245 switch (load_hdr->sym.symc_kind)
3247 case SYMC_IMPORTS: kind = "imports"; break;
3248 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3249 case SYMC_STABS: kind = "stabs"; break;
3252 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3253 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3256 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3259 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3260 if (str_sect == (char *) 0)
3261 fatal ("string section missing");
3263 if (load_cmd->section == (char *) 0)
3264 fatal ("section pointer missing");
3266 num_syms = load_hdr->sym.symc_nentries;
3267 for (i = 0; i < num_syms; i++)
3269 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3270 char *name = sym->si_name.symbol_name + str_sect;
3277 char *n = name + strlen (name) - strlen (NAME__MAIN);
3279 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3289 switch (is_ctor_dtor (name))
3292 add_to_list (&constructors, name);
3296 add_to_list (&destructors, name);
3299 default: /* not a constructor or destructor */
3305 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3306 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3311 if (symbol_load_cmds == 0)
3312 fatal ("no symbol table found");
3314 /* Update the program file now, rewrite header and load commands. At present,
3315 we assume that there is enough space after the last load command to insert
3316 one more. Since the first section written out is page aligned, and the
3317 number of load commands is small, this is ok for the present. */
3321 load_union_t *load_map;
3324 if (cmd_strings == -1)
3325 fatal ("no cmd_strings found");
3327 /* Add __main to initializer list.
3328 If we are building a program instead of a shared library, do not
3329 do anything, since in the current version, you cannot do mallocs
3330 and such in the constructors. */
3332 if (main_sym != (symbol_info_t *) 0
3333 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3334 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3337 fprintf (stderr, "\nUpdating header and load commands.\n\n");
3339 hdr.moh_n_load_cmds++;
3340 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3342 /* Create new load command map. */
3344 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
3345 (int)hdr.moh_n_load_cmds, (long)size);
3347 load_map = (load_union_t *) xcalloc (1, size);
3348 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3349 load_map->map.ldc_header.ldci_cmd_size = size;
3350 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3351 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3352 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3354 offset = hdr.moh_first_cmd_off;
3355 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3357 load_map->map.lcm_map[i] = offset;
3358 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3359 hdr.moh_load_map_cmd_off = offset;
3361 offset += load_array[i].load->hdr.ldci_cmd_size;
3364 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3367 print_header (&hdr);
3370 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3371 if (status != MO_HDR_CONV_SUCCESS)
3372 bad_header (status);
3375 fprintf (stderr, "writing load commands.\n\n");
3377 /* Write load commands */
3378 offset = hdr.moh_first_cmd_off;
3379 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3381 load_union_t *load_hdr = load_array[i].load;
3382 size_t size = load_hdr->hdr.ldci_cmd_size;
3385 print_load_command (load_hdr, offset, i);
3387 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3392 end_file (obj_file);
3394 if (close (prog_fd))
3395 fatal_perror ("closing %s", prog_name);
3398 fprintf (stderr, "\n");
3402 /* Add a function table to the load commands to call a function
3403 on initiation or termination of the process. */
3406 add_func_table (hdr_p, load_array, sym, type)
3407 mo_header_t *hdr_p; /* pointer to global header */
3408 load_all_t *load_array; /* array of ptrs to load cmds */
3409 symbol_info_t *sym; /* pointer to symbol entry */
3410 int type; /* fntc_type value */
3412 /* Add a new load command. */
3413 int num_cmds = ++hdr_p->moh_n_load_cmds;
3414 int load_index = num_cmds - 1;
3415 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3416 load_union_t *ptr = xcalloc (1, size);
3417 load_all_t *load_cmd;
3420 /* Set the unresolved address bit in the header to force the loader to be
3421 used, since kernel exec does not call the initialization functions. */
3422 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3424 load_cmd = &load_array[load_index];
3425 load_cmd->load = ptr;
3426 load_cmd->section = (char *) 0;
3428 /* Fill in func table load command. */
3429 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3430 ptr->func.ldc_header.ldci_cmd_size = size;
3431 ptr->func.ldc_header.ldci_section_off = 0;
3432 ptr->func.ldc_header.ldci_section_len = 0;
3433 ptr->func.fntc_type = type;
3434 ptr->func.fntc_nentries = 1;
3436 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3437 /* Is the symbol already expressed as (region, offset)? */
3438 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3440 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3441 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3444 /* If not, figure out which region it's in. */
3447 mo_vm_addr_t addr = sym->si_value.abs_val;
3450 for (i = 0; i < load_index; i++)
3452 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3454 region_command_t *region_ptr = &load_array[i].load->region;
3456 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3457 && addr >= region_ptr->regc_addr.vm_addr
3458 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3460 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3461 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3469 fatal ("could not convert 0x%l.8x into a region", addr);
3474 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3475 (type == FNTC_INITIALIZATION) ? "init" : "term",
3476 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
3477 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
3478 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
3483 /* Print the global header for an OSF/rose object. */
3486 print_header (hdr_ptr)
3487 mo_header_t *hdr_ptr;
3489 fprintf (stderr, "\nglobal header:\n");
3490 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3491 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3492 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3493 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3494 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3495 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3496 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3497 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3498 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3499 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3500 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3501 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3502 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3503 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3504 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3506 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3507 fprintf (stderr, ", relocatable");
3509 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3510 fprintf (stderr, ", linkable");
3512 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3513 fprintf (stderr, ", execable");
3515 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3516 fprintf (stderr, ", executable");
3518 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3519 fprintf (stderr, ", unresolved");
3521 fprintf (stderr, "\n\n");
3526 /* Print a short summary of a load command. */
3529 print_load_command (load_hdr, offset, number)
3530 load_union_t *load_hdr;
3534 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3535 char *type_str = (char *) 0;
3539 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3540 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3541 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3542 case LDC_STRINGS: type_str = "STRINGS"; break;
3543 case LDC_REGION: type_str = "REGION"; break;
3544 case LDC_RELOC: type_str = "RELOC"; break;
3545 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3546 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3547 case LDC_ENTRY: type_str = "ENTRY"; break;
3548 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3549 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3553 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3555 (long) load_hdr->hdr.ldci_cmd_size,
3557 (long) load_hdr->hdr.ldci_section_off,
3558 (long) load_hdr->hdr.ldci_section_len);
3560 if (type_str == (char *) 0)
3561 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3563 else if (type != LDC_REGION)
3564 fprintf (stderr, ", ty: %s\n", type_str);
3569 switch (load_hdr->region.regc_usage_type)
3571 case REG_TEXT_T: region = ", .text"; break;
3572 case REG_DATA_T: region = ", .data"; break;
3573 case REG_BSS_T: region = ", .bss"; break;
3574 case REG_GLUE_T: region = ", .glue"; break;
3575 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3576 case REG_RDATA_T: region = ", .rdata"; break;
3577 case REG_SDATA_T: region = ", .sdata"; break;
3578 case REG_SBSS_T: region = ", .sbss"; break;
3582 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3584 (long) load_hdr->region.regc_vm_addr,
3585 (long) load_hdr->region.regc_vm_size,
3593 /* Fatal error when {en,de}code_mach_o_header fails. */
3599 char *msg = (char *) 0;
3603 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
3604 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
3605 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
3606 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
3607 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
3608 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
3611 if (msg == (char *) 0)
3612 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3618 /* Read a file into a memory buffer. */
3620 static struct file_info *
3621 read_file (name, fd, rw)
3622 char *name; /* filename */
3623 int fd; /* file descriptor */
3624 int rw; /* read/write */
3626 struct stat stat_pkt;
3627 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3629 static int page_size;
3632 if (fstat (fd, &stat_pkt) < 0)
3633 fatal_perror ("fstat %s", name);
3636 p->size = stat_pkt.st_size;
3637 p->rounded_size = stat_pkt.st_size;
3643 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3646 page_size = sysconf (_SC_PAGE_SIZE);
3648 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3649 p->start = mmap ((caddr_t) 0,
3650 (rw) ? p->rounded_size : p->size,
3651 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3652 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3656 if (p->start != (char *) 0 && p->start != (char *) -1)
3660 #endif /* USE_MMAP */
3665 fprintf (stderr, "read %s\n", name);
3668 p->start = xmalloc (p->size);
3669 if (lseek (fd, 0L, SEEK_SET) < 0)
3670 fatal_perror ("lseek to 0 on %s", name);
3672 len = read (fd, p->start, p->size);
3674 fatal_perror ("read %s", name);
3677 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3683 /* Do anything necessary to write a file back from memory. */
3687 struct file_info *ptr; /* file information block */
3695 fprintf (stderr, "msync %s\n", ptr->name);
3697 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3698 fatal_perror ("msync %s", ptr->name);
3702 fprintf (stderr, "munmap %s\n", ptr->name);
3704 if (munmap (ptr->start, ptr->size))
3705 fatal_perror ("munmap %s", ptr->name);
3708 #endif /* USE_MMAP */
3715 fprintf (stderr, "write %s\n", ptr->name);
3717 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3718 fatal_perror ("lseek to 0 on %s", ptr->name);
3720 len = write (ptr->fd, ptr->start, ptr->size);
3722 fatal_perror ("write %s", ptr->name);
3724 if (len != ptr->size)
3725 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3734 #endif /* OBJECT_FORMAT_ROSE */