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. */
29 #include <sys/types.h>
57 #include "gansidecl.h"
64 extern char *sys_errlist[];
70 /* Obstack allocation and deallocation routines. */
71 #define obstack_chunk_alloc xmalloc
72 #define obstack_chunk_free free
85 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
88 #define WTERMSIG(S) ((S) & 0x7f)
91 #define WIFEXITED(S) (((S) & 0xff) == 0)
94 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
97 extern char *choose_temp_base ();
99 /* On certain systems, we have code that works by scanning the object file
100 directly. But this code uses system-specific header files and library
101 functions, so turn it off in a cross-compiler. Likewise, the names of
102 the utilities are not correct for a cross-compiler; we have to hope that
103 cross-versions are in the proper directories. */
106 #undef SUNOS4_SHARED_LIBRARIES
107 #undef OBJECT_FORMAT_COFF
108 #undef OBJECT_FORMAT_ROSE
109 #undef MD_EXEC_PREFIX
110 #undef REAL_LD_FILE_NAME
111 #undef REAL_NM_FILE_NAME
112 #undef REAL_STRIP_FILE_NAME
115 /* If we cannot use a special method, use the ordinary one:
116 run nm to find what symbols are present.
117 In a cross-compiler, this means you need a cross nm,
118 but that is not quite as unpleasant as special headers. */
120 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
121 #define OBJECT_FORMAT_NONE
124 #ifdef OBJECT_FORMAT_COFF
133 /* Many versions of ldfcn.h define these. */
141 /* Some systems have an ISCOFF macro, but others do not. In some cases
142 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
143 that either do not have an ISCOFF macro in /usr/include or for those
144 where it is wrong. */
147 #define MY_ISCOFF(X) ISCOFF (X)
150 #endif /* OBJECT_FORMAT_COFF */
152 #ifdef OBJECT_FORMAT_ROSE
159 #include <sys/mman.h>
163 #include <mach_o_format.h>
164 #include <mach_o_header.h>
165 #include <mach_o_vals.h>
166 #include <mach_o_types.h>
168 #endif /* OBJECT_FORMAT_ROSE */
170 #ifdef OBJECT_FORMAT_NONE
172 /* Default flags to pass to nm. */
174 #define NM_FLAGS "-p"
177 #endif /* OBJECT_FORMAT_NONE */
179 /* Some systems use __main in a way incompatible with its use in gcc, in these
180 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
181 give the same symbol without quotes for an alternative entry point. You
182 must define both, or neither. */
184 #define NAME__MAIN "__main"
185 #define SYMBOL__MAIN __main
188 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
189 #define SCAN_LIBRARIES
193 int do_collecting = 1;
195 int do_collecting = 0;
198 /* Linked lists of constructor and destructor names. */
214 /* Enumeration giving which pass this is for scanning the program file. */
217 PASS_FIRST, /* without constructors */
218 PASS_OBJ, /* individual objects */
219 PASS_LIB, /* looking for shared libraries */
220 PASS_SECOND /* with constructors linked in */
223 #ifndef NO_SYS_SIGLIST
224 #ifndef SYS_SIGLIST_DECLARED
225 extern char *sys_siglist[];
228 extern char *version_string;
230 int vflag; /* true if -v */
231 static int rflag; /* true if -r */
232 static int strip_flag; /* true if -s */
233 #ifdef COLLECT_EXPORT_LIST
234 static int export_flag; /* true if -bE */
237 int debug; /* true if -debug */
239 static int shared_obj; /* true if -shared */
241 static int temp_filename_length; /* Length of temp_filename */
242 static char *temp_filename; /* Base of temp filenames */
243 static char *c_file; /* <xxx>.c for constructor/destructor list. */
244 static char *o_file; /* <xxx>.o for constructor/destructor list. */
245 #ifdef COLLECT_EXPORT_LIST
246 static char *export_file; /* <xxx>.x for AIX export list. */
247 static char *import_file; /* <xxx>.p for AIX import list. */
249 char *ldout; /* File for ld errors. */
250 static char *output_file; /* Output file for ld. */
251 static char *nm_file_name; /* pathname of nm */
252 static char *ldd_file_name; /* pathname of ldd (or equivalent) */
253 static char *strip_file_name; /* pathname of strip */
254 char *c_file_name; /* pathname of gcc */
255 static char *initname, *fininame; /* names of init and fini funcs */
257 static struct head constructors; /* list of constructors found */
258 static struct head destructors; /* list of destructors found */
259 #ifdef COLLECT_EXPORT_LIST
260 static struct head exports; /* list of exported symbols */
261 static struct head imports; /* list of imported symbols */
262 static struct head undefined; /* list of undefined symbols */
264 static struct head frame_tables; /* list of frame unwind info tables */
266 struct obstack temporary_obstack;
267 struct obstack permanent_obstack;
268 char * temporary_firstobj;
270 /* Defined in the automatically-generated underscore.c. */
271 extern int prepends_underscore;
273 extern char *getenv ();
274 extern char *mktemp ();
275 extern FILE *fdopen ();
277 /* Structure to hold all the directories in which to search for files to
282 char *prefix; /* String to prepend to the path. */
283 struct prefix_list *next; /* Next in linked list. */
288 struct prefix_list *plist; /* List of prefixes to try */
289 int max_len; /* Max length of a prefix in PLIST */
290 char *name; /* Name of this list (used in config stuff) */
293 #ifdef COLLECT_EXPORT_LIST
294 /* Lists to keep libraries to be scanned for global constructors/destructors. */
295 static struct head libs; /* list of libraries */
296 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
297 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
298 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
299 &libpath_lib_dirs, NULL};
300 static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
303 void collect_exit PROTO((int));
304 void collect_execute PROTO((char *, char **, char *));
305 void dump_file PROTO((char *));
306 static void handler PROTO((int));
307 static int is_ctor_dtor PROTO((char *));
308 static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
309 static char *find_a_file PROTO((struct path_prefix *, char *));
310 static void add_prefix PROTO((struct path_prefix *, char *));
311 static void prefix_from_env PROTO((char *, struct path_prefix *));
312 static void prefix_from_string PROTO((char *, struct path_prefix *));
313 static void do_wait PROTO((char *));
314 static void fork_execute PROTO((char *, char **));
315 static void maybe_unlink PROTO((char *));
316 static void add_to_list PROTO((struct head *, char *));
317 static void write_list PROTO((FILE *, char *, struct id *));
318 static void dump_list PROTO((FILE *, char *, struct id *));
319 static void dump_prefix_list PROTO((FILE *, char *, struct prefix_list *));
320 static int is_in_list PROTO((char *, struct id *));
321 static void write_list_with_asm PROTO((FILE *, char *, struct id *));
322 static void write_c_file PROTO((FILE *, char *));
323 static void scan_prog_file PROTO((char *, enum pass));
324 #ifdef SCAN_LIBRARIES
325 static void scan_libraries PROTO((char *));
327 #ifdef COLLECT_EXPORT_LIST
328 static void write_export_file PROTO((FILE *));
329 static void write_import_file PROTO((FILE *));
330 static char *resolve_lib_name PROTO((char *));
331 static int use_import_list PROTO((char *));
332 static int ignore_library PROTO((char *));
338 #ifdef NEED_DECLARATION_INDEX
339 extern char *index ();
342 #ifdef NEED_DECLARATION_RINDEX
343 extern char *rindex ();
346 #ifdef NEED_DECLARATION_FREE
363 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
366 close (fdtmp[--fdx]);
382 static char buffer[30];
386 if (e > 0 && e < sys_nerr)
387 return sys_errlist[e];
389 sprintf (buffer, "Unknown error %d", e);
394 /* Delete tempfiles and exit function. */
397 collect_exit (status)
400 if (c_file != 0 && c_file[0])
401 maybe_unlink (c_file);
403 if (o_file != 0 && o_file[0])
404 maybe_unlink (o_file);
406 #ifdef COLLECT_EXPORT_LIST
407 if (export_file != 0 && export_file[0])
408 maybe_unlink (export_file);
410 if (import_file != 0 && import_file[0])
411 maybe_unlink (import_file);
414 if (ldout != 0 && ldout[0])
417 maybe_unlink (ldout);
420 if (status != 0 && output_file != 0 && output_file[0])
421 maybe_unlink (output_file);
427 /* Die when sys call fails. */
430 fatal_perror (string, arg1, arg2, arg3)
431 char *string, *arg1, *arg2, *arg3;
435 fprintf (stderr, "collect2: ");
436 fprintf (stderr, string, arg1, arg2, arg3);
437 fprintf (stderr, ": %s\n", my_strerror (e));
438 collect_exit (FATAL_EXIT_CODE);
444 fatal (string, arg1, arg2, arg3)
445 char *string, *arg1, *arg2, *arg3;
447 fprintf (stderr, "collect2: ");
448 fprintf (stderr, string, arg1, arg2, arg3);
449 fprintf (stderr, "\n");
450 collect_exit (FATAL_EXIT_CODE);
453 /* Write error message. */
456 error (string, arg1, arg2, arg3, arg4)
457 char *string, *arg1, *arg2, *arg3, *arg4;
459 fprintf (stderr, "collect2: ");
460 fprintf (stderr, string, arg1, arg2, arg3, arg4);
461 fprintf (stderr, "\n");
464 /* In case obstack is linked in, and abort is defined to fancy_abort,
465 provide a default entry. */
470 fatal ("internal error");
478 if (c_file != 0 && c_file[0])
479 maybe_unlink (c_file);
481 if (o_file != 0 && o_file[0])
482 maybe_unlink (o_file);
484 if (ldout != 0 && ldout[0])
485 maybe_unlink (ldout);
487 #ifdef COLLECT_EXPORT_LIST
488 if (export_file != 0 && export_file[0])
489 maybe_unlink (export_file);
491 if (import_file != 0 && import_file[0])
492 maybe_unlink (import_file);
495 signal (signo, SIG_DFL);
496 kill (getpid (), signo);
501 xcalloc (size1, size2)
504 char *ptr = (char *) calloc (size1, size2);
508 fatal ("out of memory");
516 char *ptr = (char *) malloc (size);
520 fatal ("out of memory");
529 register char *value = (char *) realloc (ptr, size);
531 fatal ("virtual memory exhausted");
539 return access (name, R_OK) == 0;
542 /* Make a copy of a string INPUT with size SIZE. */
545 savestring (input, size)
549 char *output = (char *) xmalloc (size + 1);
550 bcopy (input, output, size);
555 /* Parse a reasonable subset of shell quoting syntax. */
572 obstack_1grow (&temporary_obstack, c);
573 else if (! inside && c == ' ')
575 else if (! inside && c == '\\')
580 obstack_1grow (&temporary_obstack, c);
583 obstack_1grow (&temporary_obstack, '\0');
585 return obstack_finish (&temporary_obstack);
592 FILE *stream = fopen (name, "r");
593 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
600 while (c = getc (stream),
601 c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
602 obstack_1grow (&temporary_obstack, c);
603 if (obstack_object_size (&temporary_obstack) > 0)
605 char *word, *p, *result;
606 obstack_1grow (&temporary_obstack, '\0');
607 word = obstack_finish (&temporary_obstack);
610 ++word, putc ('.', stderr);
612 if (*p == '_' && prepends_underscore)
618 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
623 fputs (result, stderr);
625 diff = strlen (word) - strlen (result);
627 --diff, putc (' ', stderr);
628 while (diff < 0 && c == ' ')
629 ++diff, c = getc (stream);
634 fputs (word, stderr);
637 obstack_free (&temporary_obstack, temporary_firstobj);
646 /* Decide whether the given symbol is:
647 a constructor (1), a destructor (2), or neither (0). */
653 struct names { char *name; int len; int ret; int two_underscores; };
655 register struct names *p;
657 register char *orig_s = s;
659 static struct names special[] = {
660 #ifdef NO_DOLLAR_IN_LABEL
661 #ifdef NO_DOT_IN_LABEL
662 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
663 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
664 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
666 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
667 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
668 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
671 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
672 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
673 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
675 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
676 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
677 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
678 cfront has its own linker procedure to collect them;
679 if collect2 gets them too, they get collected twice
680 when the cfront procedure is run and the compiler used
681 for linking happens to be GCC. */
682 { "sti__", sizeof ("sti__")-1, 1, 1 },
683 { "std__", sizeof ("std__")-1, 2, 1 },
684 #endif /* CFRONT_LOSSAGE */
688 while ((ch = *s) == '_')
694 for (p = &special[0]; p->len > 0; p++)
697 && (!p->two_underscores || ((s - orig_s) >= 2))
698 && strncmp(s, p->name, p->len) == 0)
706 /* Routine to add variables to the environment. */
714 #ifndef VMS /* nor about VMS */
716 extern char **environ;
717 char **old_environ = environ;
724 while ((ch = *p++) != '\0' && ch != '=')
730 /* Search for replacing an existing environment variable, and
731 count the number of total environment variables. */
732 for (envp = old_environ; *envp; envp++)
735 if (!strncmp (str, *envp, name_len))
742 /* Add a new environment variable */
743 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
745 bcopy ((char *) old_environ, (char *) (environ + 1),
746 sizeof (char *) * (num_envs+1));
752 #endif /* HAVE_PUTENV */
754 /* By default, colon separates directories in a path. */
755 #ifndef PATH_SEPARATOR
756 #define PATH_SEPARATOR ':'
759 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
760 and one from the PATH variable. */
762 static struct path_prefix cpath, path;
765 /* This is the name of the target machine. We use it to form the name
766 of the files to execute. */
768 static char *target_machine = TARGET_MACHINE;
771 /* Names under which we were executed. Never return one of those files in our
774 static struct path_prefix our_file_names;
776 /* Determine if STRING is in PPREFIX.
778 This utility is currently only used to look up file names. Prefix lists
779 record directory names. This matters to us because the latter has a
780 trailing slash, so I've added a flag to handle both. */
783 is_in_prefix_list (pprefix, string, filep)
784 struct path_prefix *pprefix;
788 struct prefix_list *pl;
792 int len = strlen (string);
794 for (pl = pprefix->plist; pl; pl = pl->next)
796 if (strncmp (pl->prefix, string, len) == 0
797 && strcmp (pl->prefix + len, "/") == 0)
803 for (pl = pprefix->plist; pl; pl = pl->next)
805 if (strcmp (pl->prefix, string) == 0)
813 /* Search for NAME using prefix list PPREFIX. We only look for executable
816 Return 0 if not found, otherwise return its name, allocated with malloc. */
819 find_a_file (pprefix, name)
820 struct path_prefix *pprefix;
824 struct prefix_list *pl;
825 int len = pprefix->max_len + strlen (name) + 1;
827 #ifdef EXECUTABLE_SUFFIX
828 len += strlen (EXECUTABLE_SUFFIX);
831 temp = xmalloc (len);
833 /* Determine the filename to execute (special case for absolute paths). */
837 if (access (name, X_OK) == 0)
844 for (pl = pprefix->plist; pl; pl = pl->next)
846 strcpy (temp, pl->prefix);
848 if (! is_in_prefix_list (&our_file_names, temp, 1)
849 /* This is a kludge, but there seems no way around it. */
850 && strcmp (temp, "./ld") != 0
851 && access (temp, X_OK) == 0)
854 #ifdef EXECUTABLE_SUFFIX
855 /* Some systems have a suffix for executable files.
856 So try appending that. */
857 strcat (temp, EXECUTABLE_SUFFIX);
858 if (! is_in_prefix_list (&our_file_names, temp, 1)
859 && access (temp, X_OK) == 0)
868 /* Add an entry for PREFIX to prefix list PPREFIX. */
871 add_prefix (pprefix, prefix)
872 struct path_prefix *pprefix;
875 struct prefix_list *pl, **prev;
880 for (pl = pprefix->plist; pl->next; pl = pl->next)
885 prev = &pprefix->plist;
887 /* Keep track of the longest prefix */
889 len = strlen (prefix);
890 if (len > pprefix->max_len)
891 pprefix->max_len = len;
893 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
894 pl->prefix = savestring (prefix, len);
899 pl->next = (struct prefix_list *) 0;
903 /* Take the value of the environment variable ENV, break it into a path, and
904 add of the entries to PPREFIX. */
907 prefix_from_env (env, pprefix)
909 struct path_prefix *pprefix;
911 char *p = getenv (env);
914 prefix_from_string (p, pprefix);
918 prefix_from_string (p, pprefix)
920 struct path_prefix *pprefix;
923 char *nstore = (char *) xmalloc (strlen (p) + 3);
928 if (*endp == PATH_SEPARATOR || *endp == 0)
930 strncpy (nstore, startp, endp-startp);
933 strcpy (nstore, "./");
935 else if (endp[-1] != '/')
937 nstore[endp-startp] = '/';
938 nstore[endp-startp+1] = 0;
941 nstore[endp-startp] = 0;
943 add_prefix (pprefix, nstore);
946 endp = startp = endp + 1;
960 char *ld_suffix = "ld";
961 char *full_ld_suffix = ld_suffix;
962 char *real_ld_suffix = "real-ld";
964 char *full_real_ld_suffix = real_ld_suffix;
966 char *collect_ld_suffix = "collect-ld";
967 char *nm_suffix = "nm";
968 char *full_nm_suffix = nm_suffix;
969 char *gnm_suffix = "gnm";
970 char *full_gnm_suffix = gnm_suffix;
972 char *ldd_suffix = LDD_SUFFIX;
973 char *full_ldd_suffix = ldd_suffix;
975 char *strip_suffix = "strip";
976 char *full_strip_suffix = strip_suffix;
977 char *gstrip_suffix = "gstrip";
978 char *full_gstrip_suffix = gstrip_suffix;
981 #ifdef COLLECT_EXPORT_LIST
991 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
992 char **ld1 = ld1_argv;
993 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
994 char **ld2 = ld2_argv;
995 char **object_lst = (char **) xcalloc (sizeof (char *), argc);
996 char **object = object_lst;
998 int num_c_args = argc+7;
1005 #ifndef DEFAULT_A_OUT_NAME
1006 output_file = "a.out";
1008 output_file = DEFAULT_A_OUT_NAME;
1011 obstack_begin (&temporary_obstack, 0);
1012 obstack_begin (&permanent_obstack, 0);
1013 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
1014 current_demangling_style = gnu_demangling;
1016 /* We must check that we do not call ourselves in an infinite
1017 recursion loop. We append the name used for us to the COLLECT_NAMES
1018 environment variable.
1020 In practice, collect will rarely invoke itself. This can happen now
1021 that we are no longer called gld. A perfect example is when running
1022 gcc in a build directory that has been installed. When looking for
1023 ld, we will find our installed version and believe that's the real ld. */
1025 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
1026 previous version of collect (the one that used COLLECT_NAME and only
1027 handled two levels of recursion). If we do not we may mutually recurse
1028 forever. This can happen (I think) when bootstrapping the old version
1029 and a new one is installed (rare, but we should handle it).
1030 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
1032 collect_name = (char *) getenv ("COLLECT_NAME");
1033 collect_names = (char *) getenv ("COLLECT_NAMES");
1035 p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
1036 + (collect_name ? strlen (collect_name) + 1 : 0)
1037 + (collect_names ? strlen (collect_names) + 1 : 0)
1038 + strlen (argv[0]) + 1);
1039 strcpy (p, "COLLECT_NAMES=");
1040 if (collect_name != 0)
1041 sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
1042 if (collect_names != 0)
1043 sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
1044 strcat (p, argv[0]);
1047 prefix_from_env ("COLLECT_NAMES", &our_file_names);
1049 /* Set environment variable COLLECT_NAME to our name so the previous version
1050 of collect will not find us. If it does we will mutually recurse forever.
1051 This can happen when bootstrapping the new version and an old version is
1053 ??? Hopefully this bit of code can be removed at some point. */
1055 p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
1056 sprintf (p, "COLLECT_NAME=%s", argv[0]);
1059 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1062 char *q = extract_string (&p);
1063 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1066 obstack_free (&temporary_obstack, temporary_firstobj);
1069 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
1072 fatal ("no arguments");
1075 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1076 signal (SIGQUIT, handler);
1078 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1079 signal (SIGINT, handler);
1081 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1082 signal (SIGALRM, handler);
1085 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1086 signal (SIGHUP, handler);
1088 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1089 signal (SIGSEGV, handler);
1091 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1092 signal (SIGBUS, handler);
1095 /* Extract COMPILER_PATH and PATH into our prefix list. */
1096 prefix_from_env ("COMPILER_PATH", &cpath);
1097 prefix_from_env ("PATH", &path);
1099 #ifdef CROSS_COMPILE
1100 /* If we look for a program in the compiler directories, we just use
1101 the short name, since these directories are already system-specific.
1102 But it we look for a took in the system directories, we need to
1103 qualify the program name with the target machine. */
1106 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1107 strcpy (full_ld_suffix, target_machine);
1108 strcat (full_ld_suffix, "-");
1109 strcat (full_ld_suffix, ld_suffix);
1112 = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
1113 strcpy (full_real_ld_suffix, target_machine);
1114 strcat (full_real_ld_suffix, "-");
1115 strcat (full_real_ld_suffix, real_ld_suffix);
1119 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1120 strcpy (full_gld_suffix, target_machine);
1121 strcat (full_gld_suffix, "-");
1122 strcat (full_gld_suffix, gld_suffix);
1126 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1127 strcpy (full_nm_suffix, target_machine);
1128 strcat (full_nm_suffix, "-");
1129 strcat (full_nm_suffix, nm_suffix);
1132 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1133 strcpy (full_gnm_suffix, target_machine);
1134 strcat (full_gnm_suffix, "-");
1135 strcat (full_gnm_suffix, gnm_suffix);
1139 = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1140 strcpy (full_ldd_suffix, target_machine);
1141 strcat (full_ldd_suffix, "-");
1142 strcat (full_ldd_suffix, ldd_suffix);
1146 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1147 strcpy (full_strip_suffix, target_machine);
1148 strcat (full_strip_suffix, "-");
1149 strcat (full_strip_suffix, strip_suffix);
1152 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1153 strcpy (full_gstrip_suffix, target_machine);
1154 strcat (full_gstrip_suffix, "-");
1155 strcat (full_gstrip_suffix, gstrip_suffix);
1156 #endif /* CROSS_COMPILE */
1158 /* Try to discover a valid linker/nm/strip to use. */
1160 /* Maybe we know the right file to use (if not cross). */
1161 #ifdef REAL_LD_FILE_NAME
1162 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1163 if (ld_file_name == 0)
1165 /* Search the (target-specific) compiler dirs for ld'. */
1166 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1167 /* Likewise for `collect-ld'. */
1168 if (ld_file_name == 0)
1169 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1170 /* Search the compiler directories for `ld'. We have protection against
1171 recursive calls in find_a_file. */
1172 if (ld_file_name == 0)
1173 ld_file_name = find_a_file (&cpath, ld_suffix);
1174 /* Search the ordinary system bin directories
1175 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1176 if (ld_file_name == 0)
1177 ld_file_name = find_a_file (&path, full_ld_suffix);
1179 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
1181 if (collect_names != 0)
1183 if (ld_file_name != 0)
1185 argv[0] = ld_file_name;
1186 execvp (argv[0], argv);
1188 fatal ("cannot find `ld'");
1191 #ifdef REAL_NM_FILE_NAME
1192 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1193 if (nm_file_name == 0)
1195 nm_file_name = find_a_file (&cpath, gnm_suffix);
1196 if (nm_file_name == 0)
1197 nm_file_name = find_a_file (&path, full_gnm_suffix);
1198 if (nm_file_name == 0)
1199 nm_file_name = find_a_file (&cpath, nm_suffix);
1200 if (nm_file_name == 0)
1201 nm_file_name = find_a_file (&path, full_nm_suffix);
1204 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1205 if (ldd_file_name == 0)
1206 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1209 #ifdef REAL_STRIP_FILE_NAME
1210 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1211 if (strip_file_name == 0)
1213 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1214 if (strip_file_name == 0)
1215 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1216 if (strip_file_name == 0)
1217 strip_file_name = find_a_file (&cpath, strip_suffix);
1218 if (strip_file_name == 0)
1219 strip_file_name = find_a_file (&path, full_strip_suffix);
1221 /* Determine the full path name of the C compiler to use. */
1222 c_file_name = getenv ("COLLECT_GCC");
1223 if (c_file_name == 0)
1225 #ifdef CROSS_COMPILE
1226 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1227 strcpy (c_file_name, target_machine);
1228 strcat (c_file_name, "-gcc");
1230 c_file_name = "gcc";
1234 p = find_a_file (&cpath, c_file_name);
1236 /* Here it should be safe to use the system search path since we should have
1237 already qualified the name of the compiler when it is needed. */
1239 p = find_a_file (&path, c_file_name);
1244 *ld1++ = *ld2++ = ld_file_name;
1246 /* Make temp file names. */
1247 temp_filename = choose_temp_base ();
1248 temp_filename_length = strlen (temp_filename);
1249 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1250 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1251 #ifdef COLLECT_EXPORT_LIST
1252 export_file = xmalloc (temp_filename_length + sizeof (".x"));
1253 import_file = xmalloc (temp_filename_length + sizeof (".p"));
1255 ldout = xmalloc (temp_filename_length + sizeof (".ld"));
1256 sprintf (ldout, "%s.ld", temp_filename);
1257 sprintf (c_file, "%s.c", temp_filename);
1258 sprintf (o_file, "%s.o", temp_filename);
1259 #ifdef COLLECT_EXPORT_LIST
1260 sprintf (export_file, "%s.x", temp_filename);
1261 sprintf (import_file, "%s.p", temp_filename);
1263 *c_ptr++ = c_file_name;
1268 #ifdef COLLECT_EXPORT_LIST
1269 /* Generate a list of directories from LIBPATH. */
1270 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1271 /* Add to this list also two standard directories where
1272 AIX loader always searches for libraries. */
1273 add_prefix (&libpath_lib_dirs, "/lib");
1274 add_prefix (&libpath_lib_dirs, "/usr/lib");
1277 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1279 AIX support needs to know if -shared has been specified before
1280 parsing commandline arguments. */
1282 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1285 char *q = extract_string (&p);
1286 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1287 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1288 if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
1291 obstack_free (&temporary_obstack, temporary_firstobj);
1292 *c_ptr++ = "-fno-exceptions";
1294 /* !!! When GCC calls collect2,
1295 it does not know whether it is calling collect2 or ld.
1296 So collect2 cannot meaningfully understand any options
1297 except those ld understands.
1298 If you propose to make GCC pass some other option,
1299 just imagine what will happen if ld is really ld!!! */
1301 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1302 /* After the first file, put in the c++ rt0. */
1305 while ((arg = *++argv) != (char *) 0)
1307 *ld1++ = *ld2++ = arg;
1313 #ifdef COLLECT_EXPORT_LIST
1314 /* We want to disable automatic exports on AIX when user
1315 explicitly puts an export list in command line */
1317 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1323 if (!strcmp (arg, "-debug"))
1335 /* place o_file BEFORE this argument! */
1341 #ifdef COLLECT_EXPORT_LIST
1343 /* Resolving full library name. */
1344 char *s = resolve_lib_name (arg+2);
1346 /* If we will use an import list for this library,
1347 we should exclude it from ld args. */
1348 if (use_import_list (s))
1354 /* Saving a full library name. */
1355 add_to_list (&libs, s);
1360 #ifdef COLLECT_EXPORT_LIST
1361 /* Saving directories where to search for libraries. */
1363 add_prefix (&cmdline_lib_dirs, arg+2);
1369 output_file = *ld1++ = *ld2++ = *++argv;
1371 output_file = &arg[2];
1380 if (arg[2] == '\0' && do_collecting)
1382 /* We must strip after the nm run, otherwise C++ linking
1383 will not work. Thus we strip in the second ld run, or
1384 else with strip if there is no second ld run. */
1396 else if ((p = rindex (arg, '.')) != (char *) 0
1397 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1398 || strcmp (p, ".so") == 0))
1407 /* place o_file BEFORE this argument! */
1415 #ifdef COLLECT_EXPORT_LIST
1416 /* libraries can be specified directly, i.e. without -l flag. */
1419 /* If we will use an import list for this library,
1420 we should exclude it from ld args. */
1421 if (use_import_list (arg))
1427 /* Saving a full library name. */
1428 add_to_list (&libs, arg);
1434 #ifdef COLLECT_EXPORT_LIST
1435 /* This is added only for debugging purposes. */
1438 fprintf (stderr, "List of libraries:\n");
1439 dump_list (stderr, "\t", libs.first);
1442 /* The AIX linker will discard static constructors in object files if
1443 nothing else in the file is referenced, so look at them first. */
1445 char **export_object_lst = object_lst;
1446 while (export_object_lst < object)
1447 scan_prog_file (*export_object_lst++, PASS_OBJ);
1450 struct id *list = libs.first;
1451 for (; list; list = list->next)
1452 scan_prog_file (list->name, PASS_FIRST);
1455 char *buf1 = alloca (strlen (export_file) + 5);
1456 char *buf2 = alloca (strlen (import_file) + 5);
1457 sprintf (buf1, "-bE:%s", export_file);
1458 sprintf (buf2, "-bI:%s", import_file);
1463 exportf = fopen (export_file, "w");
1464 if (exportf == (FILE *) 0)
1465 fatal_perror ("%s", export_file);
1466 write_export_file (exportf);
1467 if (fclose (exportf))
1468 fatal_perror ("closing %s", export_file);
1469 importf = fopen (import_file, "w");
1470 if (importf == (FILE *) 0)
1471 fatal_perror ("%s", import_file);
1472 write_import_file (importf);
1473 if (fclose (importf))
1474 fatal_perror ("closing %s", import_file);
1479 *object = *c_ptr = *ld1 = (char *) 0;
1483 fprintf (stderr, "collect2 version %s", version_string);
1484 #ifdef TARGET_VERSION
1487 fprintf (stderr, "\n");
1493 fprintf (stderr, "ld_file_name = %s\n",
1494 (ld_file_name ? ld_file_name : "not found"));
1495 fprintf (stderr, "c_file_name = %s\n",
1496 (c_file_name ? c_file_name : "not found"));
1497 fprintf (stderr, "nm_file_name = %s\n",
1498 (nm_file_name ? nm_file_name : "not found"));
1500 fprintf (stderr, "ldd_file_name = %s\n",
1501 (ldd_file_name ? ldd_file_name : "not found"));
1503 fprintf (stderr, "strip_file_name = %s\n",
1504 (strip_file_name ? strip_file_name : "not found"));
1505 fprintf (stderr, "c_file = %s\n",
1506 (c_file ? c_file : "not found"));
1507 fprintf (stderr, "o_file = %s\n",
1508 (o_file ? o_file : "not found"));
1510 ptr = getenv ("COLLECT_NAMES");
1512 fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
1514 ptr = getenv ("COLLECT_GCC_OPTIONS");
1516 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1518 ptr = getenv ("COLLECT_GCC");
1520 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1522 ptr = getenv ("COMPILER_PATH");
1524 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1526 ptr = getenv ("LIBRARY_PATH");
1528 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1530 fprintf (stderr, "\n");
1533 /* Load the program, searching all libraries and attempting to provide
1534 undefined symbols from repository information. */
1536 /* On AIX we do this later. */
1537 #ifdef COLLECT_EXPORT_LIST
1538 do_tlink (ld1_argv, object_lst);
1541 /* If -r or they will be run via some other method, do not build the
1542 constructor or destructor list, just return now. */
1543 if (rflag || ! do_collecting)
1545 #ifdef COLLECT_EXPORT_LIST
1546 /* But make sure we delete the export file we may have created. */
1547 if (export_file != 0 && export_file[0])
1548 maybe_unlink (export_file);
1549 if (import_file != 0 && import_file[0])
1550 maybe_unlink (import_file);
1555 /* Examine the namelist with nm and search it for static constructors
1556 and destructors to call.
1557 Write the constructor and destructor tables to a .s file and reload. */
1559 /* On AIX we already done scanning for global constructors/destructors. */
1560 #ifndef COLLECT_EXPORT_LIST
1561 scan_prog_file (output_file, PASS_FIRST);
1564 #ifdef SCAN_LIBRARIES
1565 scan_libraries (output_file);
1570 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1571 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1574 if (constructors.number == 0 && destructors.number == 0
1575 && frame_tables.number == 0
1576 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1577 /* If we will be running these functions ourselves, we want to emit
1578 stubs into the shared library so that we do not have to relink
1579 dependent programs when we add static objects. */
1584 #ifdef COLLECT_EXPORT_LIST
1585 /* Doing tlink without additional code generation */
1586 do_tlink (ld1_argv, object_lst);
1588 /* Strip now if it was requested on the command line. */
1591 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1592 strip_argv[0] = strip_file_name;
1593 strip_argv[1] = output_file;
1594 strip_argv[2] = (char *) 0;
1595 fork_execute ("strip", strip_argv);
1598 #ifdef COLLECT_EXPORT_LIST
1599 maybe_unlink (export_file);
1600 maybe_unlink (import_file);
1605 maybe_unlink(output_file);
1606 outf = fopen (c_file, "w");
1607 if (outf == (FILE *) 0)
1608 fatal_perror ("%s", c_file);
1610 write_c_file (outf, c_file);
1613 fatal_perror ("closing %s", c_file);
1615 /* Tell the linker that we have initializer and finalizer functions. */
1616 #ifdef LD_INIT_SWITCH
1617 *ld2++ = LD_INIT_SWITCH;
1619 *ld2++ = LD_FINI_SWITCH;
1624 #ifdef COLLECT_EXPORT_LIST
1627 add_to_list (&exports, initname);
1628 add_to_list (&exports, fininame);
1629 add_to_list (&exports, "_GLOBAL__DI");
1630 add_to_list (&exports, "_GLOBAL__DD");
1631 exportf = fopen (export_file, "w");
1632 if (exportf == (FILE *) 0)
1633 fatal_perror ("%s", export_file);
1634 write_export_file (exportf);
1635 if (fclose (exportf))
1636 fatal_perror ("closing %s", export_file);
1642 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1643 output_file, c_file);
1644 write_c_file (stderr, "stderr");
1645 fprintf (stderr, "========== end of c_file\n\n");
1646 #ifdef COLLECT_EXPORT_LIST
1647 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1648 write_export_file (stderr);
1649 fprintf (stderr, "========== end of export_file\n\n");
1653 /* Assemble the constructor and destructor tables.
1654 Link the tables in with the rest of the program. */
1656 fork_execute ("gcc", c_argv);
1657 #ifdef COLLECT_EXPORT_LIST
1658 /* On AIX we must call tlink because of possible templates resolution */
1659 do_tlink (ld2_argv, object_lst);
1661 /* Otherwise, simply call ld because tlink is already done */
1662 fork_execute ("ld", ld2_argv);
1664 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1665 constructors/destructors in shared libraries. */
1666 scan_prog_file (output_file, PASS_SECOND);
1669 maybe_unlink (c_file);
1670 maybe_unlink (o_file);
1672 #ifdef COLLECT_EXPORT_LIST
1673 maybe_unlink (export_file);
1674 maybe_unlink (import_file);
1681 /* Wait for a process to finish, and exit if a non-zero status is found. */
1692 if (WIFSIGNALED (status))
1694 int sig = WTERMSIG (status);
1695 #ifdef NO_SYS_SIGLIST
1696 error ("%s terminated with signal %d %s",
1699 (status & 0200) ? ", core dumped" : "");
1701 error ("%s terminated with signal %d [%s]%s",
1705 (status & 0200) ? ", core dumped" : "");
1708 collect_exit (FATAL_EXIT_CODE);
1711 if (WIFEXITED (status))
1712 return WEXITSTATUS (status);
1721 int ret = collect_wait (prog);
1724 error ("%s returned %d exit status", prog, ret);
1730 /* Fork and execute a program, and wait for the reply. */
1733 collect_execute (prog, argv, redir)
1746 fprintf (stderr, "%s", argv[0]);
1748 fprintf (stderr, "[cannot find %s]", prog);
1750 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1751 fprintf (stderr, " %s", str);
1753 fprintf (stderr, "\n");
1759 /* If we cannot find a program we need, complain error. Do this here
1760 since we might not end up needing something that we could not find. */
1763 fatal ("cannot find `%s'", prog);
1769 fatal_perror ("fork");
1771 fatal_perror ("vfork");
1775 if (pid == 0) /* child context */
1780 if (freopen (redir, "a", stdout) == NULL)
1781 fatal_perror ("redirecting stdout: %s", redir);
1782 if (freopen (redir, "a", stderr) == NULL)
1783 fatal_perror ("redirecting stderr: %s", redir);
1786 execvp (argv[0], argv);
1787 fatal_perror ("executing %s", prog);
1792 fork_execute (prog, argv)
1796 collect_execute (prog, argv, NULL);
1800 /* Unlink a file unless we are debugging. */
1809 fprintf (stderr, "[Leaving %s]\n", file);
1813 /* Add a name to a linked list. */
1816 add_to_list (head_ptr, name)
1817 struct head *head_ptr;
1821 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1823 static long sequence_number = 0;
1824 strcpy (newid->name, name);
1826 if (head_ptr->first)
1827 head_ptr->last->next = newid;
1829 head_ptr->first = newid;
1831 /* Check for duplicate symbols. */
1832 for (p = head_ptr->first;
1833 strcmp (name, p->name) != 0;
1838 head_ptr->last->next = 0;
1843 newid->sequence = ++sequence_number;
1844 head_ptr->last = newid;
1848 /* Write: `prefix', the names on list LIST, `suffix'. */
1851 write_list (stream, prefix, list)
1858 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1863 /* This function is really used only on AIX, but may be useful. */
1865 is_in_list (prefix, list)
1871 if (!strcmp (prefix, list->name)) return 1;
1877 /* Added for debugging purpose. */
1879 dump_list (stream, prefix, list)
1886 fprintf (stream, "%s%s,\n", prefix, list->name);
1892 dump_prefix_list (stream, prefix, list)
1895 struct prefix_list *list;
1899 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1905 write_list_with_asm (stream, prefix, list)
1912 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1913 prefix, list->sequence, list->name);
1918 /* Write out the constructor and destructor tables statically (for a shared
1919 object), along with the functions to execute them. */
1922 write_c_file_stat (stream, name)
1926 char *prefix, *p, *q;
1927 int frames = (frame_tables.number > 0);
1929 /* Figure out name of output_file, stripping off .so version. */
1930 p = rindex (output_file, '/');
1932 p = (char *) output_file;
1946 if (strncmp (q, ".so", 3) == 0)
1955 /* q points to null at end of the string (or . of the .so version) */
1956 prefix = xmalloc (q - p + 1);
1957 strncpy (prefix, p, q - p);
1959 for (q = prefix; *q; q++)
1963 fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
1964 output_file, prefix);
1966 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1967 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1968 sprintf (initname, INIT_NAME_FORMAT, prefix);
1970 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1971 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1972 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1976 /* Write the tables as C code */
1978 fprintf (stream, "static int count;\n");
1979 fprintf (stream, "typedef void entry_pt();\n");
1980 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1984 write_list_with_asm (stream, "extern void *", frame_tables.first);
1986 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1987 write_list (stream, "\t\t&", frame_tables.first);
1988 fprintf (stream, "\t0\n};\n");
1990 /* This must match what's in frame.h. */
1991 fprintf (stream, "struct object {\n");
1992 fprintf (stream, " void *pc_begin;\n");
1993 fprintf (stream, " void *pc_end;\n");
1994 fprintf (stream, " void *fde_begin;\n");
1995 fprintf (stream, " void *fde_array;\n");
1996 fprintf (stream, " __SIZE_TYPE__ count;\n");
1997 fprintf (stream, " struct object *next;\n");
1998 fprintf (stream, "};\n");
2000 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2001 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2003 fprintf (stream, "static void reg_frame () {\n");
2004 fprintf (stream, "\tstatic struct object ob;\n");
2005 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2006 fprintf (stream, "\t}\n");
2008 fprintf (stream, "static void dereg_frame () {\n");
2009 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2010 fprintf (stream, "\t}\n");
2013 fprintf (stream, "void %s() {\n", initname);
2014 if (constructors.number > 0 || frames)
2016 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
2017 write_list (stream, "\t\t", constructors.first);
2019 fprintf (stream, "\treg_frame,\n");
2020 fprintf (stream, "\t};\n");
2021 fprintf (stream, "\tentry_pt **p;\n");
2022 fprintf (stream, "\tif (count++ != 0) return;\n");
2023 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
2024 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
2027 fprintf (stream, "\t++count;\n");
2028 fprintf (stream, "}\n");
2029 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2030 fprintf (stream, "void %s() {\n", fininame);
2031 if (destructors.number > 0 || frames)
2033 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
2034 write_list (stream, "\t\t", destructors.first);
2036 fprintf (stream, "\tdereg_frame,\n");
2037 fprintf (stream, "\t};\n");
2038 fprintf (stream, "\tentry_pt **p;\n");
2039 fprintf (stream, "\tif (--count != 0) return;\n");
2040 fprintf (stream, "\tp = dtors;\n");
2041 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
2042 destructors.number + frames);
2044 fprintf (stream, "}\n");
2048 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
2049 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
2053 /* Write the constructor/destructor tables. */
2056 write_c_file_glob (stream, name)
2060 /* Write the tables as C code */
2062 int frames = (frame_tables.number > 0);
2064 fprintf (stream, "typedef void entry_pt();\n\n");
2066 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2070 write_list_with_asm (stream, "extern void *", frame_tables.first);
2072 fprintf (stream, "\tstatic void *frame_table[] = {\n");
2073 write_list (stream, "\t\t&", frame_tables.first);
2074 fprintf (stream, "\t0\n};\n");
2076 /* This must match what's in frame.h. */
2077 fprintf (stream, "struct object {\n");
2078 fprintf (stream, " void *pc_begin;\n");
2079 fprintf (stream, " void *pc_end;\n");
2080 fprintf (stream, " void *fde_begin;\n");
2081 fprintf (stream, " void *fde_array;\n");
2082 fprintf (stream, " __SIZE_TYPE__ count;\n");
2083 fprintf (stream, " struct object *next;\n");
2084 fprintf (stream, "};\n");
2086 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2087 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2089 fprintf (stream, "static void reg_frame () {\n");
2090 fprintf (stream, "\tstatic struct object ob;\n");
2091 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2092 fprintf (stream, "\t}\n");
2094 fprintf (stream, "static void dereg_frame () {\n");
2095 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2096 fprintf (stream, "\t}\n");
2099 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2100 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2101 write_list (stream, "\t", constructors.first);
2103 fprintf (stream, "\treg_frame,\n");
2104 fprintf (stream, "\t0\n};\n\n");
2106 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2108 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2109 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2110 write_list (stream, "\t", destructors.first);
2112 fprintf (stream, "\tdereg_frame,\n");
2113 fprintf (stream, "\t0\n};\n\n");
2115 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2116 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2120 write_c_file (stream, name)
2124 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2125 #ifndef LD_INIT_SWITCH
2127 write_c_file_glob (stream, name);
2130 write_c_file_stat (stream, name);
2131 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2134 #ifdef COLLECT_EXPORT_LIST
2136 write_export_file (stream)
2139 struct id *list = exports.first;
2140 for (; list; list = list->next)
2141 fprintf (stream, "%s\n", list->name);
2145 write_import_file (stream)
2148 struct id *list = imports.first;
2149 fprintf (stream, "%s\n", "#! .");
2150 for (; list; list = list->next)
2151 fprintf (stream, "%s\n", list->name);
2155 #ifdef OBJECT_FORMAT_NONE
2157 /* Generic version to scan the name list of the loaded program for
2158 the symbols g++ uses for static constructors and destructors.
2160 The constructor table begins at __CTOR_LIST__ and contains a count
2161 of the number of pointers (or -1 if the constructors are built in a
2162 separate section by the linker), followed by the pointers to the
2163 constructor functions, terminated with a null pointer. The
2164 destructor table has the same format, and begins at __DTOR_LIST__. */
2167 scan_prog_file (prog_name, which_pass)
2169 enum pass which_pass;
2171 void (*int_handler) ();
2172 void (*quit_handler) ();
2180 if (which_pass == PASS_SECOND)
2183 /* If we do not have an `nm', complain. */
2184 if (nm_file_name == 0)
2185 fatal ("cannot find `nm'");
2187 nm_argv[argc++] = nm_file_name;
2188 if (NM_FLAGS[0] != '\0')
2189 nm_argv[argc++] = NM_FLAGS;
2191 nm_argv[argc++] = prog_name;
2192 nm_argv[argc++] = (char *) 0;
2194 if (pipe (pipe_fd) < 0)
2195 fatal_perror ("pipe");
2197 inf = fdopen (pipe_fd[0], "r");
2198 if (inf == (FILE *) 0)
2199 fatal_perror ("fdopen");
2201 /* Trace if needed. */
2207 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2208 fprintf (stderr, " %s", str);
2210 fprintf (stderr, "\n");
2216 /* Spawn child nm on pipe */
2221 fatal_perror ("fork");
2223 fatal_perror ("vfork");
2227 if (pid == 0) /* child context */
2230 if (dup2 (pipe_fd[1], 1) < 0)
2231 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2233 if (close (pipe_fd[0]) < 0)
2234 fatal_perror ("close (%d)", pipe_fd[0]);
2236 if (close (pipe_fd[1]) < 0)
2237 fatal_perror ("close (%d)", pipe_fd[1]);
2239 execv (nm_file_name, nm_argv);
2240 fatal_perror ("executing %s", nm_file_name);
2243 /* Parent context from here on. */
2244 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
2246 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
2249 if (close (pipe_fd[1]) < 0)
2250 fatal_perror ("close (%d)", pipe_fd[1]);
2253 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2255 /* Read each line of nm output. */
2256 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2261 /* If it contains a constructor or destructor name, add the name
2262 to the appropriate list. */
2264 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2265 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2272 /* Find the end of the symbol name.
2273 Do not include `|', because Encore nm can tack that on the end. */
2274 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
2280 switch (is_ctor_dtor (name))
2283 if (which_pass != PASS_LIB)
2284 add_to_list (&constructors, name);
2288 if (which_pass != PASS_LIB)
2289 add_to_list (&destructors, name);
2293 if (which_pass != PASS_LIB)
2294 fatal ("init function found in object %s", prog_name);
2295 #ifndef LD_INIT_SWITCH
2296 add_to_list (&constructors, name);
2301 if (which_pass != PASS_LIB)
2302 fatal ("fini function found in object %s", prog_name);
2303 #ifndef LD_FINI_SWITCH
2304 add_to_list (&destructors, name);
2309 if (which_pass != PASS_LIB)
2310 add_to_list (&frame_tables, name);
2312 default: /* not a constructor or destructor */
2317 fprintf (stderr, "\t%s\n", buf);
2321 fprintf (stderr, "\n");
2323 if (fclose (inf) != 0)
2324 fatal_perror ("fclose of pipe");
2326 do_wait (nm_file_name);
2328 signal (SIGINT, int_handler);
2330 signal (SIGQUIT, quit_handler);
2334 #if SUNOS4_SHARED_LIBRARIES
2336 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2337 that the output file depends upon and their initialization/finalization
2338 routines, if any. */
2343 #include <sys/mman.h>
2344 #include <sys/param.h>
2346 #include <sys/dir.h>
2348 /* pointers to the object file */
2349 unsigned object; /* address of memory mapped file */
2350 unsigned objsize; /* size of memory mapped to file */
2351 char * code; /* pointer to code segment */
2352 char * data; /* pointer to data segment */
2353 struct nlist *symtab; /* pointer to symbol table */
2354 struct link_dynamic *ld;
2355 struct link_dynamic_2 *ld_2;
2356 struct head libraries;
2358 /* Map the file indicated by NAME into memory and store its address. */
2366 if ((fp = open (name, O_RDONLY)) == -1)
2367 fatal ("unable to open file '%s'", name);
2368 if (fstat (fp, &s) == -1)
2369 fatal ("unable to stat file '%s'", name);
2371 objsize = s.st_size;
2372 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2375 fatal ("unable to mmap file '%s'", name);
2380 /* Helpers for locatelib. */
2382 static char *libname;
2388 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2391 /* If one file has an additional numeric extension past LIBNAME, then put
2392 that one first in the sort. If both files have additional numeric
2393 extensions, then put the one with the higher number first in the sort.
2395 We must verify that the extension is numeric, because Sun saves the
2396 original versions of patched libraries with a .FCS extension. Files with
2397 invalid extensions must go last in the sort, so that they will not be used. */
2401 struct direct **d1, **d2;
2403 int i1, i2 = strlen (libname);
2404 char *e1 = (*d1)->d_name + i2;
2405 char *e2 = (*d2)->d_name + i2;
2407 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2408 && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))
2412 i1 = strtol (e1, &e1, 10);
2413 i2 = strtol (e2, &e2, 10);
2420 /* It has a valid numeric extension, prefer this one. */
2421 if (*e1 == '.' && e1[1] && isdigit (e1[1]))
2423 /* It has a invalid numeric extension, must prefer the other one. */
2429 /* It has a valid numeric extension, prefer this one. */
2430 if (*e2 == '.' && e2[1] && isdigit (e2[1]))
2432 /* It has a invalid numeric extension, must prefer the other one. */
2440 /* Given the name NAME of a dynamic dependency, find its pathname and add
2441 it to the list of libraries. */
2449 char buf[MAXPATHLEN];
2457 /* counting elements in array, need 1 extra for null */
2459 ld_rules = (char *) (ld_2->ld_rules + code);
2463 for (; *ld_rules != 0; ld_rules++)
2464 if (*ld_rules == ':')
2466 ld_rules = (char *) (ld_2->ld_rules + code);
2467 ldr = (char *) malloc (strlen (ld_rules) + 1);
2468 strcpy (ldr, ld_rules);
2470 p = getenv ("LD_LIBRARY_PATH");
2475 for (q = p ; *q != 0; q++)
2478 q = (char *) malloc (strlen (p) + 1);
2481 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2486 for (; *ldr != 0; ldr++)
2496 for (; *q != 0; q++)
2503 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2506 *pp++ = "/usr/local/lib";
2510 for (pp = l; *pp != 0 ; pp++)
2512 struct direct **namelist;
2514 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2516 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2517 add_to_list (&libraries, buf);
2519 fprintf (stderr, "%s\n", buf);
2526 fprintf (stderr, "not found\n");
2528 fatal ("dynamic dependency %s not found", name);
2532 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2533 that it depends upon and any constructors or destructors they contain. */
2536 scan_libraries (prog_name)
2539 struct exec *header;
2541 struct link_object *lo;
2542 char buff[MAXPATHLEN];
2545 mapfile (prog_name);
2546 header = (struct exec *)object;
2547 if (N_BADMAG (*header))
2548 fatal ("bad magic number in file '%s'", prog_name);
2549 if (header->a_dynamic == 0)
2552 code = (char *) (N_TXTOFF (*header) + (long) header);
2553 data = (char *) (N_DATOFF (*header) + (long) header);
2554 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2556 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2559 ld = (struct link_dynamic *) (symtab->n_value + code);
2565 ld = (struct link_dynamic *) data;
2570 fprintf (stderr, "dynamic dependencies.\n");
2572 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2573 for (lo = (struct link_object *) ld_2->ld_need; lo;
2574 lo = (struct link_object *) lo->lo_next)
2577 lo = (struct link_object *) ((long) lo + code);
2578 name = (char *) (code + lo->lo_name);
2582 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2583 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2589 fprintf (stderr, "\t%s\n", name);
2590 add_to_list (&libraries, name);
2595 fprintf (stderr, "\n");
2597 /* now iterate through the library list adding their symbols to
2599 for (list = libraries.first; list; list = list->next)
2600 scan_prog_file (list->name, PASS_LIB);
2603 #else /* SUNOS4_SHARED_LIBRARIES */
2606 /* Use the List Dynamic Dependencies program to find shared libraries that
2607 the output file depends upon and their initialization/finalization
2608 routines, if any. */
2611 scan_libraries (prog_name)
2614 static struct head libraries; /* list of shared libraries found */
2616 void (*int_handler) ();
2617 void (*quit_handler) ();
2625 /* If we do not have an `ldd', complain. */
2626 if (ldd_file_name == 0)
2628 error ("cannot find `ldd'");
2632 ldd_argv[argc++] = ldd_file_name;
2633 ldd_argv[argc++] = prog_name;
2634 ldd_argv[argc++] = (char *) 0;
2636 if (pipe (pipe_fd) < 0)
2637 fatal_perror ("pipe");
2639 inf = fdopen (pipe_fd[0], "r");
2640 if (inf == (FILE *) 0)
2641 fatal_perror ("fdopen");
2643 /* Trace if needed. */
2649 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2650 fprintf (stderr, " %s", str);
2652 fprintf (stderr, "\n");
2658 /* Spawn child ldd on pipe */
2663 fatal_perror ("fork");
2665 fatal_perror ("vfork");
2669 if (pid == 0) /* child context */
2672 if (dup2 (pipe_fd[1], 1) < 0)
2673 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2675 if (close (pipe_fd[0]) < 0)
2676 fatal_perror ("close (%d)", pipe_fd[0]);
2678 if (close (pipe_fd[1]) < 0)
2679 fatal_perror ("close (%d)", pipe_fd[1]);
2681 execv (ldd_file_name, ldd_argv);
2682 fatal_perror ("executing %s", ldd_file_name);
2685 /* Parent context from here on. */
2686 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2688 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2691 if (close (pipe_fd[1]) < 0)
2692 fatal_perror ("close (%d)", pipe_fd[1]);
2695 fprintf (stderr, "\nldd output with constructors/destructors.\n");
2697 /* Read each line of ldd output. */
2698 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2701 char *name, *end, *p = buf;
2703 /* Extract names of libraries and add to list. */
2704 PARSE_LDD_OUTPUT (p);
2709 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2710 fatal ("dynamic dependency %s not found", buf);
2712 /* Find the end of the symbol name. */
2714 (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
2719 if (access (name, R_OK) == 0)
2720 add_to_list (&libraries, name);
2722 fatal ("unable to open dynamic dependency '%s'", buf);
2725 fprintf (stderr, "\t%s\n", buf);
2728 fprintf (stderr, "\n");
2730 if (fclose (inf) != 0)
2731 fatal_perror ("fclose of pipe");
2733 do_wait (ldd_file_name);
2735 signal (SIGINT, int_handler);
2737 signal (SIGQUIT, quit_handler);
2740 /* now iterate through the library list adding their symbols to
2742 for (list = libraries.first; list; list = list->next)
2743 scan_prog_file (list->name, PASS_LIB);
2746 #endif /* LDD_SUFFIX */
2747 #endif /* SUNOS4_SHARED_LIBRARIES */
2749 #endif /* OBJECT_FORMAT_NONE */
2753 * COFF specific stuff.
2756 #ifdef OBJECT_FORMAT_COFF
2758 #if defined(EXTENDED_COFF)
2759 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2760 # define GCC_SYMENT SYMR
2761 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2762 # define GCC_SYMINC(X) (1)
2763 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2764 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2766 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2767 # define GCC_SYMENT SYMENT
2768 # define GCC_OK_SYMBOL(X) \
2769 (((X).n_sclass == C_EXT) && \
2770 ((X).n_scnum > N_UNDEF) && \
2771 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2772 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2773 # define GCC_UNDEF_SYMBOL(X) \
2774 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2775 # define GCC_SYMINC(X) ((X).n_numaux+1)
2776 # define GCC_SYMZERO(X) 0
2777 # define GCC_CHECK_HDR(X) (1)
2780 extern char *ldgetname ();
2782 /* COFF version to scan the name list of the loaded program for
2783 the symbols g++ uses for static constructors and destructors.
2785 The constructor table begins at __CTOR_LIST__ and contains a count
2786 of the number of pointers (or -1 if the constructors are built in a
2787 separate section by the linker), followed by the pointers to the
2788 constructor functions, terminated with a null pointer. The
2789 destructor table has the same format, and begins at __DTOR_LIST__. */
2792 scan_prog_file (prog_name, which_pass)
2794 enum pass which_pass;
2796 LDFILE *ldptr = NULL;
2797 int sym_index, sym_count;
2799 #ifdef COLLECT_EXPORT_LIST
2800 /* Should we generate an import list for given prog_name? */
2801 int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name));
2804 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2807 #ifdef COLLECT_EXPORT_LIST
2808 /* We do not need scanning for some standard C libraries. */
2809 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2812 /* On AIX we have a loop, because there is not much difference
2813 between an object and an archive. This trick allows us to
2814 eliminate scan_libraries() function. */
2818 if ((ldptr = ldopen (prog_name, ldptr)) != NULL)
2821 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2822 fatal ("%s: not a COFF file", prog_name);
2824 #ifdef COLLECT_EXPORT_LIST
2825 /* Is current archive member a shared object? */
2826 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2828 if (GCC_CHECK_HDR (ldptr))
2830 sym_count = GCC_SYMBOLS (ldptr);
2831 sym_index = GCC_SYMZERO (ldptr);
2832 while (sym_index < sym_count)
2836 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2838 sym_index += GCC_SYMINC (symbol);
2840 if (GCC_OK_SYMBOL (symbol))
2844 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2845 continue; /* should never happen */
2847 #ifdef XCOFF_DEBUGGING_INFO
2848 /* All AIX function names have a duplicate entry
2849 beginning with a dot. */
2854 switch (is_ctor_dtor (name))
2857 if (! is_shared) add_to_list (&constructors, name);
2858 if (which_pass == PASS_OBJ)
2859 add_to_list (&exports, name);
2860 #ifdef COLLECT_EXPORT_LIST
2861 /* If this symbol was undefined and we are building
2862 an import list, we should add a symbol to this
2866 && is_in_list (name, undefined.first))
2867 add_to_list (&imports, name);
2872 if (! is_shared) add_to_list (&destructors, name);
2873 if (which_pass == PASS_OBJ)
2874 add_to_list (&exports, name);
2875 #ifdef COLLECT_EXPORT_LIST
2876 /* If this symbol was undefined and we are building
2877 an import list, we should add a symbol to this
2881 && is_in_list (name, undefined.first))
2882 add_to_list (&imports, name);
2886 #ifdef COLLECT_EXPORT_LIST
2889 add_to_list (&constructors, name);
2894 add_to_list (&destructors, name);
2898 default: /* not a constructor or destructor */
2899 #ifdef COLLECT_EXPORT_LIST
2900 /* If we are building a shared object on AIX we need
2901 to explicitly export all global symbols or add
2902 them to import list. */
2904 if (which_pass == PASS_OBJ && (! export_flag))
2905 add_to_list (&exports, name);
2906 else if (! is_shared && which_pass == PASS_FIRST
2908 && is_in_list(name, undefined.first))
2909 add_to_list (&imports, name);
2914 #if !defined(EXTENDED_COFF)
2916 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2917 symbol.n_scnum, symbol.n_sclass,
2918 (symbol.n_type ? "0" : ""), symbol.n_type,
2923 "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
2924 symbol.iss, symbol.value, symbol.index, name);
2927 #ifdef COLLECT_EXPORT_LIST
2928 /* If we are building a shared object we should collect
2929 information about undefined symbols for later
2930 import list generation. */
2931 else if (shared_obj && GCC_UNDEF_SYMBOL (symbol))
2935 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2936 continue; /* should never happen */
2938 /* All AIX function names have a duplicate entry
2939 beginning with a dot. */
2942 add_to_list (&undefined, name);
2950 fatal ("%s: cannot open as COFF file", prog_name);
2952 #ifdef COLLECT_EXPORT_LIST
2953 /* On AIX loop continues while there are more members in archive. */
2955 while (ldclose (ldptr) == FAILURE);
2957 /* Otherwise we simply close ldptr. */
2958 (void) ldclose(ldptr);
2963 #ifdef COLLECT_EXPORT_LIST
2965 /* This new function is used to decide whether we should
2966 generate import list for an object or to use it directly. */
2968 use_import_list (prog_name)
2973 /* If we do not build a shared object then import list should not be used. */
2974 if (! shared_obj) return 0;
2976 /* Currently we check only for libgcc, but this can be changed in future. */
2977 p = strstr (prog_name, "libgcc.a");
2978 if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
2983 /* Given a library name without "lib" prefix, this function
2984 returns a full library name including a path. */
2986 resolve_lib_name (name)
2992 for (i = 0; libpaths[i]; i++)
2993 if (libpaths[i]->max_len > l)
2994 l = libpaths[i]->max_len;
2996 lib_buf = xmalloc (l + strlen(name) + 10);
2998 for (i = 0; libpaths[i]; i++)
3000 struct prefix_list *list = libpaths[i]->plist;
3001 for (; list; list = list->next)
3003 for (j = 0; libexts[j]; j++)
3005 /* The following lines are needed because path_prefix list
3006 may contain directories both with trailing '/' and
3009 if (list->prefix[strlen(list->prefix)-1] != '/')
3011 sprintf (lib_buf, "%s%slib%s.%s",
3012 list->prefix, p, name, libexts[j]);
3013 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
3014 if (file_exists (lib_buf))
3016 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
3023 fprintf (stderr, "not found\n");
3025 fatal ("Library lib%s not found", name);
3029 /* Array of standard AIX libraries which should not
3030 be scanned for ctors/dtors. */
3031 static char* aix_std_libs[] = {
3036 "/usr/lib/libc_r.a",
3037 "/usr/lib/threads/libc.a",
3038 "/usr/ccs/lib/libc.a",
3039 "/usr/ccs/lib/libc_r.a",
3043 /* This function checks the filename and returns 1
3044 if this name matches the location of a standard AIX library. */
3046 ignore_library (name)
3049 char **p = &aix_std_libs[0];
3050 while (*p++ != NULL)
3051 if (! strcmp (name, *p)) return 1;
3057 #endif /* OBJECT_FORMAT_COFF */
3061 * OSF/rose specific stuff.
3064 #ifdef OBJECT_FORMAT_ROSE
3066 /* Union of the various load commands */
3068 typedef union load_union
3070 ldc_header_t hdr; /* common header */
3071 load_cmd_map_command_t map; /* map indexing other load cmds */
3072 interpreter_command_t iprtr; /* interpreter pathname */
3073 strings_command_t str; /* load commands strings section */
3074 region_command_t region; /* region load command */
3075 reloc_command_t reloc; /* relocation section */
3076 package_command_t pkg; /* package load command */
3077 symbols_command_t sym; /* symbol sections */
3078 entry_command_t ent; /* program start section */
3079 gen_info_command_t info; /* object information */
3080 func_table_command_t func; /* function constructors/destructors */
3083 /* Structure to point to load command and data section in memory. */
3085 typedef struct load_all
3087 load_union_t *load; /* load command */
3088 char *section; /* pointer to section */
3091 /* Structure to contain information about a file mapped into memory. */
3095 char *start; /* start of map */
3096 char *name; /* filename */
3097 long size; /* size of the file */
3098 long rounded_size; /* size rounded to page boundary */
3099 int fd; /* file descriptor */
3100 int rw; /* != 0 if opened read/write */
3101 int use_mmap; /* != 0 if mmap'ed */
3104 extern int decode_mach_o_hdr ();
3105 extern int encode_mach_o_hdr ();
3107 static void add_func_table PROTO((mo_header_t *, load_all_t *,
3108 symbol_info_t *, int));
3109 static void print_header PROTO((mo_header_t *));
3110 static void print_load_command PROTO((load_union_t *, size_t, int));
3111 static void bad_header PROTO((int));
3112 static struct file_info *read_file PROTO((char *, int, int));
3113 static void end_file PROTO((struct file_info *));
3115 /* OSF/rose specific version to scan the name list of the loaded
3116 program for the symbols g++ uses for static constructors and
3119 The constructor table begins at __CTOR_LIST__ and contains a count
3120 of the number of pointers (or -1 if the constructors are built in a
3121 separate section by the linker), followed by the pointers to the
3122 constructor functions, terminated with a null pointer. The
3123 destructor table has the same format, and begins at __DTOR_LIST__. */
3126 scan_prog_file (prog_name, which_pass)
3128 enum pass which_pass;
3132 load_all_t *load_array;
3133 load_all_t *load_end;
3134 load_all_t *load_cmd;
3135 int symbol_load_cmds;
3141 struct file_info *obj_file;
3143 mo_lcid_t cmd_strings = -1;
3144 symbol_info_t *main_sym = 0;
3145 int rw = (which_pass != PASS_FIRST);
3147 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3149 fatal_perror ("cannot read %s", prog_name);
3151 obj_file = read_file (prog_name, prog_fd, rw);
3152 obj = obj_file->start;
3154 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3155 if (status != MO_HDR_CONV_SUCCESS)
3156 bad_header (status);
3159 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3160 since the hardware will automatically swap bytes for us on loading little endian
3163 #ifndef CROSS_COMPILE
3164 if (hdr.moh_magic != MOH_MAGIC_MSB
3165 || hdr.moh_header_version != MOH_HEADER_VERSION
3166 || hdr.moh_byte_order != OUR_BYTE_ORDER
3167 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3168 || hdr.moh_cpu_type != OUR_CPU_TYPE
3169 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3170 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3172 fatal ("incompatibilities between object file & expected values");
3177 print_header (&hdr);
3179 offset = hdr.moh_first_cmd_off;
3180 load_end = load_array
3181 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3183 /* Build array of load commands, calculating the offsets */
3184 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3186 load_union_t *load_hdr; /* load command header */
3188 load_cmd = load_end++;
3189 load_hdr = (load_union_t *) (obj + offset);
3191 /* If modifying the program file, copy the header. */
3194 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3195 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
3198 /* null out old command map, because we will rewrite at the end. */
3199 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3201 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3202 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3206 load_cmd->load = load_hdr;
3207 if (load_hdr->hdr.ldci_section_off > 0)
3208 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3211 print_load_command (load_hdr, offset, i);
3213 offset += load_hdr->hdr.ldci_cmd_size;
3216 /* If the last command is the load command map and is not undefined,
3217 decrement the count of load commands. */
3218 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3221 hdr.moh_n_load_cmds--;
3224 /* Go through and process each symbol table section. */
3225 symbol_load_cmds = 0;
3226 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3228 load_union_t *load_hdr = load_cmd->load;
3230 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3236 char *kind = "unknown";
3238 switch (load_hdr->sym.symc_kind)
3240 case SYMC_IMPORTS: kind = "imports"; break;
3241 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3242 case SYMC_STABS: kind = "stabs"; break;
3245 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3246 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3249 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3252 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3253 if (str_sect == (char *) 0)
3254 fatal ("string section missing");
3256 if (load_cmd->section == (char *) 0)
3257 fatal ("section pointer missing");
3259 num_syms = load_hdr->sym.symc_nentries;
3260 for (i = 0; i < num_syms; i++)
3262 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3263 char *name = sym->si_name.symbol_name + str_sect;
3270 char *n = name + strlen (name) - strlen (NAME__MAIN);
3272 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3282 switch (is_ctor_dtor (name))
3285 add_to_list (&constructors, name);
3289 add_to_list (&destructors, name);
3292 default: /* not a constructor or destructor */
3298 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3299 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3304 if (symbol_load_cmds == 0)
3305 fatal ("no symbol table found");
3307 /* Update the program file now, rewrite header and load commands. At present,
3308 we assume that there is enough space after the last load command to insert
3309 one more. Since the first section written out is page aligned, and the
3310 number of load commands is small, this is ok for the present. */
3314 load_union_t *load_map;
3317 if (cmd_strings == -1)
3318 fatal ("no cmd_strings found");
3320 /* Add __main to initializer list.
3321 If we are building a program instead of a shared library, do not
3322 do anything, since in the current version, you cannot do mallocs
3323 and such in the constructors. */
3325 if (main_sym != (symbol_info_t *) 0
3326 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3327 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3330 fprintf (stderr, "\nUpdating header and load commands.\n\n");
3332 hdr.moh_n_load_cmds++;
3333 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3335 /* Create new load command map. */
3337 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
3338 (int)hdr.moh_n_load_cmds, (long)size);
3340 load_map = (load_union_t *) xcalloc (1, size);
3341 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3342 load_map->map.ldc_header.ldci_cmd_size = size;
3343 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3344 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3345 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3347 offset = hdr.moh_first_cmd_off;
3348 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3350 load_map->map.lcm_map[i] = offset;
3351 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3352 hdr.moh_load_map_cmd_off = offset;
3354 offset += load_array[i].load->hdr.ldci_cmd_size;
3357 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3360 print_header (&hdr);
3363 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3364 if (status != MO_HDR_CONV_SUCCESS)
3365 bad_header (status);
3368 fprintf (stderr, "writing load commands.\n\n");
3370 /* Write load commands */
3371 offset = hdr.moh_first_cmd_off;
3372 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3374 load_union_t *load_hdr = load_array[i].load;
3375 size_t size = load_hdr->hdr.ldci_cmd_size;
3378 print_load_command (load_hdr, offset, i);
3380 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3385 end_file (obj_file);
3387 if (close (prog_fd))
3388 fatal_perror ("closing %s", prog_name);
3391 fprintf (stderr, "\n");
3395 /* Add a function table to the load commands to call a function
3396 on initiation or termination of the process. */
3399 add_func_table (hdr_p, load_array, sym, type)
3400 mo_header_t *hdr_p; /* pointer to global header */
3401 load_all_t *load_array; /* array of ptrs to load cmds */
3402 symbol_info_t *sym; /* pointer to symbol entry */
3403 int type; /* fntc_type value */
3405 /* Add a new load command. */
3406 int num_cmds = ++hdr_p->moh_n_load_cmds;
3407 int load_index = num_cmds - 1;
3408 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3409 load_union_t *ptr = xcalloc (1, size);
3410 load_all_t *load_cmd;
3413 /* Set the unresolved address bit in the header to force the loader to be
3414 used, since kernel exec does not call the initialization functions. */
3415 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3417 load_cmd = &load_array[load_index];
3418 load_cmd->load = ptr;
3419 load_cmd->section = (char *) 0;
3421 /* Fill in func table load command. */
3422 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3423 ptr->func.ldc_header.ldci_cmd_size = size;
3424 ptr->func.ldc_header.ldci_section_off = 0;
3425 ptr->func.ldc_header.ldci_section_len = 0;
3426 ptr->func.fntc_type = type;
3427 ptr->func.fntc_nentries = 1;
3429 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3430 /* Is the symbol already expressed as (region, offset)? */
3431 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3433 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3434 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3437 /* If not, figure out which region it's in. */
3440 mo_vm_addr_t addr = sym->si_value.abs_val;
3443 for (i = 0; i < load_index; i++)
3445 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3447 region_command_t *region_ptr = &load_array[i].load->region;
3449 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3450 && addr >= region_ptr->regc_addr.vm_addr
3451 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3453 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3454 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3462 fatal ("could not convert 0x%l.8x into a region", addr);
3467 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3468 (type == FNTC_INITIALIZATION) ? "init" : "term",
3469 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
3470 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
3471 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
3476 /* Print the global header for an OSF/rose object. */
3479 print_header (hdr_ptr)
3480 mo_header_t *hdr_ptr;
3482 fprintf (stderr, "\nglobal header:\n");
3483 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3484 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3485 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3486 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3487 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3488 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3489 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3490 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3491 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3492 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3493 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3494 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3495 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3496 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3497 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3499 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3500 fprintf (stderr, ", relocatable");
3502 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3503 fprintf (stderr, ", linkable");
3505 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3506 fprintf (stderr, ", execable");
3508 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3509 fprintf (stderr, ", executable");
3511 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3512 fprintf (stderr, ", unresolved");
3514 fprintf (stderr, "\n\n");
3519 /* Print a short summary of a load command. */
3522 print_load_command (load_hdr, offset, number)
3523 load_union_t *load_hdr;
3527 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3528 char *type_str = (char *) 0;
3532 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3533 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3534 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3535 case LDC_STRINGS: type_str = "STRINGS"; break;
3536 case LDC_REGION: type_str = "REGION"; break;
3537 case LDC_RELOC: type_str = "RELOC"; break;
3538 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3539 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3540 case LDC_ENTRY: type_str = "ENTRY"; break;
3541 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3542 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3546 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3548 (long) load_hdr->hdr.ldci_cmd_size,
3550 (long) load_hdr->hdr.ldci_section_off,
3551 (long) load_hdr->hdr.ldci_section_len);
3553 if (type_str == (char *) 0)
3554 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3556 else if (type != LDC_REGION)
3557 fprintf (stderr, ", ty: %s\n", type_str);
3562 switch (load_hdr->region.regc_usage_type)
3564 case REG_TEXT_T: region = ", .text"; break;
3565 case REG_DATA_T: region = ", .data"; break;
3566 case REG_BSS_T: region = ", .bss"; break;
3567 case REG_GLUE_T: region = ", .glue"; break;
3568 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3569 case REG_RDATA_T: region = ", .rdata"; break;
3570 case REG_SDATA_T: region = ", .sdata"; break;
3571 case REG_SBSS_T: region = ", .sbss"; break;
3575 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3577 (long) load_hdr->region.regc_vm_addr,
3578 (long) load_hdr->region.regc_vm_size,
3586 /* Fatal error when {en,de}code_mach_o_header fails. */
3592 char *msg = (char *) 0;
3596 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
3597 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
3598 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
3599 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
3600 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
3601 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
3604 if (msg == (char *) 0)
3605 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3611 /* Read a file into a memory buffer. */
3613 static struct file_info *
3614 read_file (name, fd, rw)
3615 char *name; /* filename */
3616 int fd; /* file descriptor */
3617 int rw; /* read/write */
3619 struct stat stat_pkt;
3620 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3622 static int page_size;
3625 if (fstat (fd, &stat_pkt) < 0)
3626 fatal_perror ("fstat %s", name);
3629 p->size = stat_pkt.st_size;
3630 p->rounded_size = stat_pkt.st_size;
3636 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3639 page_size = sysconf (_SC_PAGE_SIZE);
3641 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3642 p->start = mmap ((caddr_t) 0,
3643 (rw) ? p->rounded_size : p->size,
3644 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3645 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3649 if (p->start != (char *) 0 && p->start != (char *) -1)
3653 #endif /* USE_MMAP */
3658 fprintf (stderr, "read %s\n", name);
3661 p->start = xmalloc (p->size);
3662 if (lseek (fd, 0L, SEEK_SET) < 0)
3663 fatal_perror ("lseek to 0 on %s", name);
3665 len = read (fd, p->start, p->size);
3667 fatal_perror ("read %s", name);
3670 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3676 /* Do anything necessary to write a file back from memory. */
3680 struct file_info *ptr; /* file information block */
3688 fprintf (stderr, "msync %s\n", ptr->name);
3690 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3691 fatal_perror ("msync %s", ptr->name);
3695 fprintf (stderr, "munmap %s\n", ptr->name);
3697 if (munmap (ptr->start, ptr->size))
3698 fatal_perror ("munmap %s", ptr->name);
3701 #endif /* USE_MMAP */
3708 fprintf (stderr, "write %s\n", ptr->name);
3710 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3711 fatal_perror ("lseek to 0 on %s", ptr->name);
3713 len = write (ptr->fd, ptr->start, ptr->size);
3715 fatal_perror ("write %s", ptr->name);
3717 if (len != ptr->size)
3718 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3727 #endif /* OBJECT_FORMAT_ROSE */