1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 93, 94, 95, 96, 1997 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>
41 #include "gansidecl.h"
48 extern char *sys_errlist[];
54 /* Obstack allocation and deallocation routines. */
55 #define obstack_chunk_alloc xmalloc
56 #define obstack_chunk_free free
69 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
72 #define WTERMSIG(S) ((S) & 0x7f)
75 #define WIFEXITED(S) (((S) & 0xff) == 0)
78 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
81 extern char *choose_temp_base ();
83 /* On certain systems, we have code that works by scanning the object file
84 directly. But this code uses system-specific header files and library
85 functions, so turn it off in a cross-compiler. Likewise, the names of
86 the utilities aren't correct for a cross-compiler; we have to hope that
87 cross-versions are in the proper directories. */
90 #undef SUNOS4_SHARED_LIBRARIES
91 #undef OBJECT_FORMAT_COFF
92 #undef OBJECT_FORMAT_ROSE
94 #undef REAL_LD_FILE_NAME
95 #undef REAL_NM_FILE_NAME
96 #undef REAL_STRIP_FILE_NAME
99 /* If we can't use a special method, use the ordinary one:
100 run nm to find what symbols are present.
101 In a cross-compiler, this means you need a cross nm,
102 but that isn't quite as unpleasant as special headers. */
104 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
105 #define OBJECT_FORMAT_NONE
108 #ifdef OBJECT_FORMAT_COFF
117 /* Many versions of ldfcn.h define these. */
125 /* Some systems have an ISCOFF macro, but others do not. In some cases
126 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
127 that either do not have an ISCOFF macro in /usr/include or for those
128 where it is wrong. */
131 #define MY_ISCOFF(X) ISCOFF (X)
134 #ifdef XCOFF_DEBUGGING_INFO
135 #define XCOFF_SCAN_LIBS
138 #endif /* OBJECT_FORMAT_COFF */
140 #ifdef OBJECT_FORMAT_ROSE
147 #include <sys/mman.h>
151 #include <mach_o_format.h>
152 #include <mach_o_header.h>
153 #include <mach_o_vals.h>
154 #include <mach_o_types.h>
156 #endif /* OBJECT_FORMAT_ROSE */
158 #ifdef OBJECT_FORMAT_NONE
160 /* Default flags to pass to nm. */
162 #define NM_FLAGS "-p"
165 #endif /* OBJECT_FORMAT_NONE */
167 /* Some systems use __main in a way incompatible with its use in gcc, in these
168 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
169 give the same symbol without quotes for an alternative entry point. You
170 must define both, or neither. */
172 #define NAME__MAIN "__main"
173 #define SYMBOL__MAIN __main
176 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES || defined(XCOFF_SCAN_LIBS)
177 #define SCAN_LIBRARIES
181 int do_collecting = 1;
183 int do_collecting = 0;
186 /* Linked lists of constructor and destructor names. */
202 /* Enumeration giving which pass this is for scanning the program file. */
205 PASS_FIRST, /* without constructors */
206 PASS_OBJ, /* individual objects */
207 PASS_LIB, /* looking for shared libraries */
208 PASS_SECOND /* with constructors linked in */
211 #ifndef NO_SYS_SIGLIST
212 #ifndef SYS_SIGLIST_DECLARED
213 extern char *sys_siglist[];
216 extern char *version_string;
218 int vflag; /* true if -v */
219 static int rflag; /* true if -r */
220 static int strip_flag; /* true if -s */
222 int debug; /* true if -debug */
224 static int shared_obj; /* true if -shared */
226 static int temp_filename_length; /* Length of temp_filename */
227 static char *temp_filename; /* Base of temp filenames */
228 static char *c_file; /* <xxx>.c for constructor/destructor list. */
229 static char *o_file; /* <xxx>.o for constructor/destructor list. */
230 static char *export_file; /* <xxx>.x for AIX export list. */
231 char *ldout; /* File for ld errors. */
232 static char *output_file; /* Output file for ld. */
233 static char *nm_file_name; /* pathname of nm */
234 static char *ldd_file_name; /* pathname of ldd (or equivalent) */
235 static char *strip_file_name; /* pathname of strip */
236 char *c_file_name; /* pathname of gcc */
237 static char *initname, *fininame; /* names of init and fini funcs */
239 static struct head constructors; /* list of constructors found */
240 static struct head destructors; /* list of destructors found */
241 static struct head exports; /* list of exported symbols */
242 static struct head frame_tables; /* list of frame unwind info tables */
244 struct obstack temporary_obstack;
245 struct obstack permanent_obstack;
246 char * temporary_firstobj;
248 /* Defined in the automatically-generated underscore.c. */
249 extern int prepends_underscore;
251 extern char *getenv ();
252 extern char *mktemp ();
253 extern FILE *fdopen ();
255 /* Structure to hold all the directories in which to search for files to
260 char *prefix; /* String to prepend to the path. */
261 struct prefix_list *next; /* Next in linked list. */
266 struct prefix_list *plist; /* List of prefixes to try */
267 int max_len; /* Max length of a prefix in PLIST */
268 char *name; /* Name of this list (used in config stuff) */
271 void collect_exit PROTO((int));
272 void collect_execute PROTO((char *, char **, char *));
273 void dump_file PROTO((char *));
274 static void handler PROTO((int));
275 static int is_ctor_dtor PROTO((char *));
276 static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
277 static char *find_a_file PROTO((struct path_prefix *, char *));
278 static void add_prefix PROTO((struct path_prefix *, char *));
279 static void prefix_from_env PROTO((char *, struct path_prefix *));
280 static void prefix_from_string PROTO((char *, struct path_prefix *));
281 static void do_wait PROTO((char *));
282 static void fork_execute PROTO((char *, char **));
283 static void maybe_unlink PROTO((char *));
284 static void add_to_list PROTO((struct head *, char *));
285 static void write_list PROTO((FILE *, char *, struct id *));
286 static void write_list_with_asm PROTO((FILE *, char *, struct id *));
287 static void write_c_file PROTO((FILE *, char *));
288 static void write_export_file PROTO((FILE *));
289 static void scan_prog_file PROTO((char *, enum pass));
290 static void scan_libraries PROTO((char *));
295 extern char *index ();
296 extern char *rindex ();
312 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
315 close (fdtmp[--fdx]);
331 static char buffer[30];
335 if (e > 0 && e < sys_nerr)
336 return sys_errlist[e];
338 sprintf (buffer, "Unknown error %d", e);
343 /* Delete tempfiles and exit function. */
346 collect_exit (status)
349 if (c_file != 0 && c_file[0])
350 maybe_unlink (c_file);
352 if (o_file != 0 && o_file[0])
353 maybe_unlink (o_file);
355 if (export_file != 0 && export_file[0])
356 maybe_unlink (export_file);
358 if (ldout != 0 && ldout[0])
361 maybe_unlink (ldout);
364 if (status != 0 && output_file != 0 && output_file[0])
365 maybe_unlink (output_file);
371 /* Die when sys call fails. */
374 fatal_perror (string, arg1, arg2, arg3)
375 char *string, *arg1, *arg2, *arg3;
379 fprintf (stderr, "collect2: ");
380 fprintf (stderr, string, arg1, arg2, arg3);
381 fprintf (stderr, ": %s\n", my_strerror (e));
382 collect_exit (FATAL_EXIT_CODE);
388 fatal (string, arg1, arg2, arg3)
389 char *string, *arg1, *arg2, *arg3;
391 fprintf (stderr, "collect2: ");
392 fprintf (stderr, string, arg1, arg2, arg3);
393 fprintf (stderr, "\n");
394 collect_exit (FATAL_EXIT_CODE);
397 /* Write error message. */
400 error (string, arg1, arg2, arg3, arg4)
401 char *string, *arg1, *arg2, *arg3, *arg4;
403 fprintf (stderr, "collect2: ");
404 fprintf (stderr, string, arg1, arg2, arg3, arg4);
405 fprintf (stderr, "\n");
408 /* In case obstack is linked in, and abort is defined to fancy_abort,
409 provide a default entry. */
414 fatal ("internal error");
422 if (c_file != 0 && c_file[0])
423 maybe_unlink (c_file);
425 if (o_file != 0 && o_file[0])
426 maybe_unlink (o_file);
428 if (ldout != 0 && ldout[0])
429 maybe_unlink (ldout);
431 if (export_file != 0 && export_file[0])
432 maybe_unlink (export_file);
434 signal (signo, SIG_DFL);
435 kill (getpid (), signo);
440 xcalloc (size1, size2)
443 char *ptr = (char *) calloc (size1, size2);
447 fatal ("out of memory");
455 char *ptr = (char *) malloc (size);
459 fatal ("out of memory");
468 register char *value = (char *) realloc (ptr, size);
470 fatal ("virtual memory exhausted");
478 return access (name, R_OK) == 0;
481 /* Make a copy of a string INPUT with size SIZE. */
484 savestring (input, size)
488 char *output = (char *) xmalloc (size + 1);
489 bcopy (input, output, size);
494 /* Parse a reasonable subset of shell quoting syntax. */
511 obstack_1grow (&temporary_obstack, c);
512 else if (! inside && c == ' ')
514 else if (! inside && c == '\\')
519 obstack_1grow (&temporary_obstack, c);
522 obstack_1grow (&temporary_obstack, '\0');
524 return obstack_finish (&temporary_obstack);
531 FILE *stream = fopen (name, "r");
532 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
539 while (c = getc (stream),
540 c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
541 obstack_1grow (&temporary_obstack, c);
542 if (obstack_object_size (&temporary_obstack) > 0)
544 char *word, *p, *result;
545 obstack_1grow (&temporary_obstack, '\0');
546 word = obstack_finish (&temporary_obstack);
549 ++word, putc ('.', stderr);
551 if (*p == '_' && prepends_underscore)
557 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
562 fputs (result, stderr);
564 diff = strlen (word) - strlen (result);
566 --diff, putc (' ', stderr);
567 while (diff < 0 && c == ' ')
568 ++diff, c = getc (stream);
573 fputs (word, stderr);
576 obstack_free (&temporary_obstack, temporary_firstobj);
585 /* Decide whether the given symbol is:
586 a constructor (1), a destructor (2), or neither (0). */
592 struct names { char *name; int len; int ret; int two_underscores; };
594 register struct names *p;
596 register char *orig_s = s;
598 static struct names special[] = {
599 #ifdef NO_DOLLAR_IN_LABEL
600 #ifdef NO_DOT_IN_LABEL
601 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
602 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
603 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
605 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
606 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
607 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
610 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
611 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
612 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
614 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
615 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
616 #ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
617 cfront has its own linker procedure to collect them;
618 if collect2 gets them too, they get collected twice
619 when the cfront procedure is run and the compiler used
620 for linking happens to be GCC. */
621 { "sti__", sizeof ("sti__")-1, 1, 1 },
622 { "std__", sizeof ("std__")-1, 2, 1 },
623 #endif /* CFRONT_LOSSAGE */
627 while ((ch = *s) == '_')
633 for (p = &special[0]; p->len > 0; p++)
636 && (!p->two_underscores || ((s - orig_s) >= 2))
637 && strncmp(s, p->name, p->len) == 0)
645 /* Routine to add variables to the environment. */
653 #ifndef VMS /* nor about VMS */
655 extern char **environ;
656 char **old_environ = environ;
663 while ((ch = *p++) != '\0' && ch != '=')
669 /* Search for replacing an existing environment variable, and
670 count the number of total environment variables. */
671 for (envp = old_environ; *envp; envp++)
674 if (!strncmp (str, *envp, name_len))
681 /* Add a new environment variable */
682 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
684 bcopy ((char *) old_environ, (char *) (environ + 1),
685 sizeof (char *) * (num_envs+1));
691 #endif /* HAVE_PUTENV */
693 /* By default, colon separates directories in a path. */
694 #ifndef PATH_SEPARATOR
695 #define PATH_SEPARATOR ':'
698 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
699 and one from the PATH variable. */
701 static struct path_prefix cpath, path;
704 /* This is the name of the target machine. We use it to form the name
705 of the files to execute. */
707 static char *target_machine = TARGET_MACHINE;
710 /* Names under which we were executed. Never return one of those files in our
713 static struct path_prefix our_file_names;
715 /* Determine if STRING is in PPREFIX.
717 This utility is currently only used to look up file names. Prefix lists
718 record directory names. This matters to us because the latter has a
719 trailing slash, so I've added a flag to handle both. */
722 is_in_prefix_list (pprefix, string, filep)
723 struct path_prefix *pprefix;
727 struct prefix_list *pl;
731 int len = strlen (string);
733 for (pl = pprefix->plist; pl; pl = pl->next)
735 if (strncmp (pl->prefix, string, len) == 0
736 && strcmp (pl->prefix + len, "/") == 0)
742 for (pl = pprefix->plist; pl; pl = pl->next)
744 if (strcmp (pl->prefix, string) == 0)
752 /* Search for NAME using prefix list PPREFIX. We only look for executable
755 Return 0 if not found, otherwise return its name, allocated with malloc. */
758 find_a_file (pprefix, name)
759 struct path_prefix *pprefix;
763 struct prefix_list *pl;
764 int len = pprefix->max_len + strlen (name) + 1;
766 #ifdef EXECUTABLE_SUFFIX
767 len += strlen (EXECUTABLE_SUFFIX);
770 temp = xmalloc (len);
772 /* Determine the filename to execute (special case for absolute paths). */
776 if (access (name, X_OK) == 0)
783 for (pl = pprefix->plist; pl; pl = pl->next)
785 strcpy (temp, pl->prefix);
787 if (! is_in_prefix_list (&our_file_names, temp, 1)
788 /* This is a kludge, but there seems no way around it. */
789 && strcmp (temp, "./ld") != 0
790 && access (temp, X_OK) == 0)
793 #ifdef EXECUTABLE_SUFFIX
794 /* Some systems have a suffix for executable files.
795 So try appending that. */
796 strcat (temp, EXECUTABLE_SUFFIX);
797 if (! is_in_prefix_list (&our_file_names, temp, 1)
798 && access (temp, X_OK) == 0)
807 /* Add an entry for PREFIX to prefix list PPREFIX. */
810 add_prefix (pprefix, prefix)
811 struct path_prefix *pprefix;
814 struct prefix_list *pl, **prev;
819 for (pl = pprefix->plist; pl->next; pl = pl->next)
824 prev = &pprefix->plist;
826 /* Keep track of the longest prefix */
828 len = strlen (prefix);
829 if (len > pprefix->max_len)
830 pprefix->max_len = len;
832 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
833 pl->prefix = savestring (prefix, len);
838 pl->next = (struct prefix_list *) 0;
842 /* Take the value of the environment variable ENV, break it into a path, and
843 add of the entries to PPREFIX. */
846 prefix_from_env (env, pprefix)
848 struct path_prefix *pprefix;
850 char *p = getenv (env);
853 prefix_from_string (p, pprefix);
857 prefix_from_string (p, pprefix)
859 struct path_prefix *pprefix;
862 char *nstore = (char *) xmalloc (strlen (p) + 3);
867 if (*endp == PATH_SEPARATOR || *endp == 0)
869 strncpy (nstore, startp, endp-startp);
872 strcpy (nstore, "./");
874 else if (endp[-1] != '/')
876 nstore[endp-startp] = '/';
877 nstore[endp-startp+1] = 0;
880 nstore[endp-startp] = 0;
882 add_prefix (pprefix, nstore);
885 endp = startp = endp + 1;
899 char *ld_suffix = "ld";
900 char *full_ld_suffix = ld_suffix;
901 char *real_ld_suffix = "real-ld";
902 char *full_real_ld_suffix = real_ld_suffix;
903 char *collect_ld_suffix = "collect-ld";
904 char *nm_suffix = "nm";
905 char *full_nm_suffix = nm_suffix;
906 char *gnm_suffix = "gnm";
907 char *full_gnm_suffix = gnm_suffix;
909 char *ldd_suffix = LDD_SUFFIX;
910 char *full_ldd_suffix = ldd_suffix;
912 char *strip_suffix = "strip";
913 char *full_strip_suffix = strip_suffix;
914 char *gstrip_suffix = "gstrip";
915 char *full_gstrip_suffix = gstrip_suffix;
917 FILE *outf, *exportf;
924 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
925 char **ld1 = ld1_argv;
926 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
927 char **ld2 = ld2_argv;
928 char **object_lst = (char **) xcalloc (sizeof (char *), argc);
929 char **object = object_lst;
931 int num_c_args = argc+7;
938 #ifndef DEFAULT_A_OUT_NAME
939 output_file = "a.out";
941 output_file = DEFAULT_A_OUT_NAME;
944 obstack_begin (&temporary_obstack, 0);
945 obstack_begin (&permanent_obstack, 0);
946 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
947 current_demangling_style = gnu_demangling;
949 /* We must check that we do not call ourselves in an infinite
950 recursion loop. We append the name used for us to the COLLECT_NAMES
951 environment variable.
953 In practice, collect will rarely invoke itself. This can happen now
954 that we are no longer called gld. A perfect example is when running
955 gcc in a build directory that has been installed. When looking for
956 ld's, we'll find our installed version and believe that's the real ld. */
958 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
959 previous version of collect (the one that used COLLECT_NAME and only
960 handled two levels of recursion). If we don't we may mutually recurse
961 forever. This can happen (I think) when bootstrapping the old version
962 and a new one is installed (rare, but we should handle it).
963 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
965 collect_name = (char *) getenv ("COLLECT_NAME");
966 collect_names = (char *) getenv ("COLLECT_NAMES");
968 p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
969 + (collect_name ? strlen (collect_name) + 1 : 0)
970 + (collect_names ? strlen (collect_names) + 1 : 0)
971 + strlen (argv[0]) + 1);
972 strcpy (p, "COLLECT_NAMES=");
973 if (collect_name != 0)
974 sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
975 if (collect_names != 0)
976 sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
980 prefix_from_env ("COLLECT_NAMES", &our_file_names);
982 /* Set environment variable COLLECT_NAME to our name so the previous version
983 of collect won't find us. If it does we'll mutually recurse forever.
984 This can happen when bootstrapping the new version and an old version is
986 ??? Hopefully this bit of code can be removed at some point. */
988 p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
989 sprintf (p, "COLLECT_NAME=%s", argv[0]);
992 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
995 char *q = extract_string (&p);
996 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
999 obstack_free (&temporary_obstack, temporary_firstobj);
1002 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
1005 fatal ("no arguments");
1008 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1009 signal (SIGQUIT, handler);
1011 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1012 signal (SIGINT, handler);
1014 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1015 signal (SIGALRM, handler);
1018 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1019 signal (SIGHUP, handler);
1021 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1022 signal (SIGSEGV, handler);
1024 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1025 signal (SIGBUS, handler);
1028 /* Extract COMPILER_PATH and PATH into our prefix list. */
1029 prefix_from_env ("COMPILER_PATH", &cpath);
1030 prefix_from_env ("PATH", &path);
1032 #ifdef CROSS_COMPILE
1033 /* If we look for a program in the compiler directories, we just use
1034 the short name, since these directories are already system-specific.
1035 But it we look for a took in the system directories, we need to
1036 qualify the program name with the target machine. */
1039 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1040 strcpy (full_ld_suffix, target_machine);
1041 strcat (full_ld_suffix, "-");
1042 strcat (full_ld_suffix, ld_suffix);
1045 = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
1046 strcpy (full_real_ld_suffix, target_machine);
1047 strcat (full_real_ld_suffix, "-");
1048 strcat (full_real_ld_suffix, real_ld_suffix);
1052 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1053 strcpy (full_gld_suffix, target_machine);
1054 strcat (full_gld_suffix, "-");
1055 strcat (full_gld_suffix, gld_suffix);
1059 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1060 strcpy (full_nm_suffix, target_machine);
1061 strcat (full_nm_suffix, "-");
1062 strcat (full_nm_suffix, nm_suffix);
1065 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1066 strcpy (full_gnm_suffix, target_machine);
1067 strcat (full_gnm_suffix, "-");
1068 strcat (full_gnm_suffix, gnm_suffix);
1072 = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1073 strcpy (full_ldd_suffix, target_machine);
1074 strcat (full_ldd_suffix, "-");
1075 strcat (full_ldd_suffix, ldd_suffix);
1079 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1080 strcpy (full_strip_suffix, target_machine);
1081 strcat (full_strip_suffix, "-");
1082 strcat (full_strip_suffix, strip_suffix);
1085 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1086 strcpy (full_gstrip_suffix, target_machine);
1087 strcat (full_gstrip_suffix, "-");
1088 strcat (full_gstrip_suffix, gstrip_suffix);
1089 #endif /* CROSS_COMPILE */
1091 /* Try to discover a valid linker/nm/strip to use. */
1093 /* Maybe we know the right file to use (if not cross). */
1094 #ifdef REAL_LD_FILE_NAME
1095 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1096 if (ld_file_name == 0)
1098 /* Search the (target-specific) compiler dirs for ld'. */
1099 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1100 /* Likewise for `collect-ld'. */
1101 if (ld_file_name == 0)
1102 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1103 /* Search the compiler directories for `ld'. We have protection against
1104 recursive calls in find_a_file. */
1105 if (ld_file_name == 0)
1106 ld_file_name = find_a_file (&cpath, ld_suffix);
1107 /* Search the ordinary system bin directories
1108 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1109 if (ld_file_name == 0)
1110 ld_file_name = find_a_file (&path, full_ld_suffix);
1112 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
1114 if (collect_names != 0)
1116 if (ld_file_name != 0)
1118 argv[0] = ld_file_name;
1119 execvp (argv[0], argv);
1121 fatal ("cannot find `ld'");
1124 #ifdef REAL_NM_FILE_NAME
1125 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1126 if (nm_file_name == 0)
1128 nm_file_name = find_a_file (&cpath, gnm_suffix);
1129 if (nm_file_name == 0)
1130 nm_file_name = find_a_file (&path, full_gnm_suffix);
1131 if (nm_file_name == 0)
1132 nm_file_name = find_a_file (&cpath, nm_suffix);
1133 if (nm_file_name == 0)
1134 nm_file_name = find_a_file (&path, full_nm_suffix);
1137 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1138 if (ldd_file_name == 0)
1139 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1142 #ifdef REAL_STRIP_FILE_NAME
1143 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1144 if (strip_file_name == 0)
1146 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1147 if (strip_file_name == 0)
1148 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1149 if (strip_file_name == 0)
1150 strip_file_name = find_a_file (&cpath, strip_suffix);
1151 if (strip_file_name == 0)
1152 strip_file_name = find_a_file (&path, full_strip_suffix);
1154 /* Determine the full path name of the C compiler to use. */
1155 c_file_name = getenv ("COLLECT_GCC");
1156 if (c_file_name == 0)
1158 #ifdef CROSS_COMPILE
1159 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1160 strcpy (c_file_name, target_machine);
1161 strcat (c_file_name, "-gcc");
1163 c_file_name = "gcc";
1167 p = find_a_file (&cpath, c_file_name);
1169 /* Here it should be safe to use the system search path since we should have
1170 already qualified the name of the compiler when it is needed. */
1172 p = find_a_file (&path, c_file_name);
1177 *ld1++ = *ld2++ = ld_file_name;
1179 /* Make temp file names. */
1180 temp_filename = choose_temp_base ();
1181 temp_filename_length = strlen (temp_filename);
1182 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1183 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1184 export_file = xmalloc (temp_filename_length + sizeof (".x"));
1185 ldout = xmalloc (temp_filename_length + sizeof (".ld"));
1186 sprintf (ldout, "%s.ld", temp_filename);
1187 sprintf (c_file, "%s.c", temp_filename);
1188 sprintf (o_file, "%s.o", temp_filename);
1189 sprintf (export_file, "%s.x", temp_filename);
1190 *c_ptr++ = c_file_name;
1195 /* !!! When GCC calls collect2,
1196 it does not know whether it is calling collect2 or ld.
1197 So collect2 cannot meaningfully understand any options
1198 except those ld understands.
1199 If you propose to make GCC pass some other option,
1200 just imagine what will happen if ld is really ld!!! */
1202 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1203 /* After the first file, put in the c++ rt0. */
1206 while ((arg = *++argv) != (char *) 0)
1208 *ld1++ = *ld2++ = arg;
1215 if (!strcmp (arg, "-debug"))
1227 /* place o_file BEFORE this argument! */
1237 output_file = *ld1++ = *ld2++ = *++argv;
1239 output_file = &arg[2];
1248 if (arg[2] == '\0' && do_collecting)
1250 /* We must strip after the nm run, otherwise C++ linking
1251 won't work. Thus we strip in the second ld run, or
1252 else with strip if there is no second ld run. */
1264 else if ((p = rindex (arg, '.')) != (char *) 0
1265 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0))
1274 /* place o_file BEFORE this argument! */
1285 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
1286 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1289 char *q = extract_string (&p);
1290 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1291 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1292 if (strncmp (q, "-shared", sizeof ("shared") - 1) == 0)
1295 obstack_free (&temporary_obstack, temporary_firstobj);
1296 *c_ptr++ = "-fno-exceptions";
1298 #ifdef COLLECT_EXPORT_LIST
1299 /* The AIX linker will discard static constructors in object files if
1300 nothing else in the file is referenced, so look at them first. */
1301 while (object_lst < object)
1302 scan_prog_file (*object_lst++, PASS_OBJ);
1305 char *buf = alloca (strlen (export_file) + 5);
1306 sprintf (buf, "-bE:%s", export_file);
1309 exportf = fopen (export_file, "w");
1310 if (exportf == (FILE *) 0)
1311 fatal_perror ("%s", export_file);
1312 write_export_file (exportf);
1313 if (fclose (exportf))
1314 fatal_perror ("closing %s", export_file);
1319 *object = *c_ptr = *ld1 = (char *) 0;
1323 fprintf (stderr, "collect2 version %s", version_string);
1324 #ifdef TARGET_VERSION
1327 fprintf (stderr, "\n");
1333 fprintf (stderr, "ld_file_name = %s\n",
1334 (ld_file_name ? ld_file_name : "not found"));
1335 fprintf (stderr, "c_file_name = %s\n",
1336 (c_file_name ? c_file_name : "not found"));
1337 fprintf (stderr, "nm_file_name = %s\n",
1338 (nm_file_name ? nm_file_name : "not found"));
1340 fprintf (stderr, "ldd_file_name = %s\n",
1341 (ldd_file_name ? ldd_file_name : "not found"));
1343 fprintf (stderr, "strip_file_name = %s\n",
1344 (strip_file_name ? strip_file_name : "not found"));
1345 fprintf (stderr, "c_file = %s\n",
1346 (c_file ? c_file : "not found"));
1347 fprintf (stderr, "o_file = %s\n",
1348 (o_file ? o_file : "not found"));
1350 ptr = getenv ("COLLECT_NAMES");
1352 fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
1354 ptr = getenv ("COLLECT_GCC_OPTIONS");
1356 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1358 ptr = getenv ("COLLECT_GCC");
1360 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1362 ptr = getenv ("COMPILER_PATH");
1364 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1366 ptr = getenv ("LIBRARY_PATH");
1368 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1370 fprintf (stderr, "\n");
1373 /* Load the program, searching all libraries and attempting to provide
1374 undefined symbols from repository information. */
1376 do_tlink (ld1_argv, object_lst);
1378 /* If -r or they'll be run via some other method, don't build the
1379 constructor or destructor list, just return now. */
1380 if (rflag || ! do_collecting)
1382 /* But make sure we delete the export file we may have created. */
1383 if (export_file != 0 && export_file[0])
1384 maybe_unlink (export_file);
1388 /* Examine the namelist with nm and search it for static constructors
1389 and destructors to call.
1390 Write the constructor and destructor tables to a .s file and reload. */
1392 scan_prog_file (output_file, PASS_FIRST);
1394 #ifdef SCAN_LIBRARIES
1395 scan_libraries (output_file);
1400 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1401 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1404 if (constructors.number == 0 && destructors.number == 0
1405 && frame_tables.number == 0
1406 #ifdef SCAN_LIBRARIES
1407 /* If we will be running these functions ourselves, we want to emit
1408 stubs into the shared library so that we don't have to relink
1409 dependent programs when we add static objects. */
1414 /* Strip now if it was requested on the command line. */
1417 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1418 strip_argv[0] = strip_file_name;
1419 strip_argv[1] = output_file;
1420 strip_argv[2] = (char *) 0;
1421 fork_execute ("strip", strip_argv);
1424 #ifdef COLLECT_EXPORT_LIST
1425 maybe_unlink (export_file);
1430 maybe_unlink(output_file);
1431 outf = fopen (c_file, "w");
1432 if (outf == (FILE *) 0)
1433 fatal_perror ("%s", c_file);
1435 write_c_file (outf, c_file);
1438 fatal_perror ("closing %s", c_file);
1440 /* Tell the linker that we have initializer and finalizer functions. */
1441 #ifdef LD_INIT_SWITCH
1442 *ld2++ = LD_INIT_SWITCH;
1444 *ld2++ = LD_FINI_SWITCH;
1449 #ifdef COLLECT_EXPORT_LIST
1452 add_to_list (&exports, initname);
1453 add_to_list (&exports, fininame);
1454 add_to_list (&exports, "_GLOBAL__DI");
1455 add_to_list (&exports, "_GLOBAL__DD");
1456 exportf = fopen (export_file, "w");
1457 if (exportf == (FILE *) 0)
1458 fatal_perror ("%s", export_file);
1459 write_export_file (exportf);
1460 if (fclose (exportf))
1461 fatal_perror ("closing %s", export_file);
1467 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1468 output_file, c_file);
1469 write_c_file (stderr, "stderr");
1470 fprintf (stderr, "========== end of c_file\n\n");
1471 #ifdef COLLECT_EXPORT_LIST
1472 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1473 write_export_file (stderr);
1474 fprintf (stderr, "========== end of export_file\n\n");
1478 /* Assemble the constructor and destructor tables.
1479 Link the tables in with the rest of the program. */
1481 fork_execute ("gcc", c_argv);
1482 fork_execute ("ld", ld2_argv);
1484 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1485 constructors/destructors in shared libraries. */
1486 scan_prog_file (output_file, PASS_SECOND);
1488 maybe_unlink (c_file);
1489 maybe_unlink (o_file);
1490 maybe_unlink (export_file);
1495 /* Wait for a process to finish, and exit if a non-zero status is found. */
1506 if (WIFSIGNALED (status))
1508 int sig = WTERMSIG (status);
1509 #ifdef NO_SYS_SIGLIST
1510 error ("%s terminated with signal %d %s",
1513 (status & 0200) ? ", core dumped" : "");
1515 error ("%s terminated with signal %d [%s]%s",
1519 (status & 0200) ? ", core dumped" : "");
1522 collect_exit (FATAL_EXIT_CODE);
1525 if (WIFEXITED (status))
1526 return WEXITSTATUS (status);
1535 int ret = collect_wait (prog);
1538 error ("%s returned %d exit status", prog, ret);
1544 /* Fork and execute a program, and wait for the reply. */
1547 collect_execute (prog, argv, redir)
1560 fprintf (stderr, "%s", argv[0]);
1562 fprintf (stderr, "[cannot find %s]", prog);
1564 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1565 fprintf (stderr, " %s", str);
1567 fprintf (stderr, "\n");
1573 /* If we can't find a program we need, complain error. Do this here
1574 since we might not end up needing something that we couldn't find. */
1577 fatal ("cannot find `%s'", prog);
1583 fatal_perror ("fork");
1585 fatal_perror ("vfork");
1589 if (pid == 0) /* child context */
1594 if (freopen (redir, "a", stdout) == NULL)
1595 fatal_perror ("redirecting stdout");
1596 if (freopen (redir, "a", stderr) == NULL)
1597 fatal_perror ("redirecting stderr");
1600 execvp (argv[0], argv);
1601 fatal_perror ("executing %s", prog);
1606 fork_execute (prog, argv)
1610 collect_execute (prog, argv, NULL);
1614 /* Unlink a file unless we are debugging. */
1623 fprintf (stderr, "[Leaving %s]\n", file);
1627 /* Add a name to a linked list. */
1630 add_to_list (head_ptr, name)
1631 struct head *head_ptr;
1635 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1637 static long sequence_number = 0;
1638 strcpy (newid->name, name);
1640 if (head_ptr->first)
1641 head_ptr->last->next = newid;
1643 head_ptr->first = newid;
1645 /* Check for duplicate symbols. */
1646 for (p = head_ptr->first;
1647 strcmp (name, p->name) != 0;
1652 head_ptr->last->next = 0;
1657 newid->sequence = ++sequence_number;
1658 head_ptr->last = newid;
1662 /* Write: `prefix', the names on list LIST, `suffix'. */
1665 write_list (stream, prefix, list)
1672 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1678 write_list_with_asm (stream, prefix, list)
1685 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1686 prefix, list->sequence, list->name);
1691 /* Write out the constructor and destructor tables statically (for a shared
1692 object), along with the functions to execute them. */
1695 write_c_file_stat (stream, name)
1699 char *prefix, *p, *q;
1700 int frames = (frame_tables.number > 0);
1702 /* Figure out name of output_file, stripping off .so version. */
1703 p = rindex (output_file, '/');
1705 p = (char *) output_file;
1719 if (strncmp (q, ".so", 3) == 0)
1728 /* q points to null at end of the string (or . of the .so version) */
1729 prefix = xmalloc (q - p + 1);
1730 strncpy (prefix, p, q - p);
1732 for (q = prefix; *q; q++)
1736 fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
1737 output_file, prefix);
1739 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1740 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1741 sprintf (initname, INIT_NAME_FORMAT, prefix);
1743 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1744 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1745 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1749 /* Write the tables as C code */
1751 fprintf (stream, "static int count;\n");
1752 fprintf (stream, "typedef void entry_pt();\n");
1753 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1757 write_list_with_asm (stream, "extern void *", frame_tables.first);
1759 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1760 write_list (stream, "\t\t&", frame_tables.first);
1761 fprintf (stream, "\t0\n};\n");
1763 fprintf (stream, "extern void __register_frame_table (void *);\n");
1764 fprintf (stream, "extern void __deregister_frame (void *);\n");
1766 fprintf (stream, "static void reg_frame () {\n");
1767 fprintf (stream, "\t__register_frame_table (frame_table);\n");
1768 fprintf (stream, "\t}\n");
1770 fprintf (stream, "static void dereg_frame () {\n");
1771 fprintf (stream, "\t__deregister_frame (frame_table);\n");
1772 fprintf (stream, "\t}\n");
1775 fprintf (stream, "void %s() {\n", initname);
1776 if (constructors.number > 0 || frames)
1778 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1779 write_list (stream, "\t\t", constructors.first);
1781 fprintf (stream, "\treg_frame,\n");
1782 fprintf (stream, "\t};\n");
1783 fprintf (stream, "\tentry_pt **p;\n");
1784 fprintf (stream, "\tif (count++ != 0) return;\n");
1785 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1786 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1789 fprintf (stream, "\t++count;\n");
1790 fprintf (stream, "}\n");
1791 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1792 fprintf (stream, "void %s() {\n", fininame);
1793 if (destructors.number > 0 || frames)
1795 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1796 write_list (stream, "\t\t", destructors.first);
1798 fprintf (stream, "\tdereg_frame,\n");
1799 fprintf (stream, "\t};\n");
1800 fprintf (stream, "\tentry_pt **p;\n");
1801 fprintf (stream, "\tif (--count != 0) return;\n");
1802 fprintf (stream, "\tp = dtors;\n");
1803 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1804 destructors.number + frames);
1806 fprintf (stream, "}\n");
1810 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
1811 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
1815 /* Write the constructor/destructor tables. */
1818 write_c_file_glob (stream, name)
1822 /* Write the tables as C code */
1824 int frames = (frame_tables.number > 0);
1826 fprintf (stream, "typedef void entry_pt();\n\n");
1828 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1832 write_list_with_asm (stream, "extern void *", frame_tables.first);
1834 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1835 write_list (stream, "\t\t&", frame_tables.first);
1836 fprintf (stream, "\t0\n};\n");
1838 fprintf (stream, "extern void __register_frame_table (void *);\n");
1839 fprintf (stream, "extern void __deregister_frame (void *);\n");
1841 fprintf (stream, "static void reg_frame () {\n");
1842 fprintf (stream, "\t__register_frame_table (frame_table);\n");
1843 fprintf (stream, "\t}\n");
1845 fprintf (stream, "static void dereg_frame () {\n");
1846 fprintf (stream, "\t__deregister_frame (frame_table);\n");
1847 fprintf (stream, "\t}\n");
1850 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1851 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
1852 write_list (stream, "\t", constructors.first);
1854 fprintf (stream, "\treg_frame,\n");
1855 fprintf (stream, "\t0\n};\n\n");
1857 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1859 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1860 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
1861 write_list (stream, "\t", destructors.first);
1863 fprintf (stream, "\tdereg_frame,\n");
1864 fprintf (stream, "\t0\n};\n\n");
1866 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1867 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
1871 write_c_file (stream, name)
1875 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
1876 #ifndef LD_INIT_SWITCH
1878 write_c_file_glob (stream, name);
1881 write_c_file_stat (stream, name);
1882 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
1886 write_export_file (stream)
1889 struct id *list = exports.first;
1890 for (; list; list = list->next)
1891 fprintf (stream, "%s\n", list->name);
1894 #ifdef OBJECT_FORMAT_NONE
1896 /* Generic version to scan the name list of the loaded program for
1897 the symbols g++ uses for static constructors and destructors.
1899 The constructor table begins at __CTOR_LIST__ and contains a count
1900 of the number of pointers (or -1 if the constructors are built in a
1901 separate section by the linker), followed by the pointers to the
1902 constructor functions, terminated with a null pointer. The
1903 destructor table has the same format, and begins at __DTOR_LIST__. */
1906 scan_prog_file (prog_name, which_pass)
1908 enum pass which_pass;
1910 void (*int_handler) ();
1911 void (*quit_handler) ();
1919 if (which_pass == PASS_SECOND)
1922 /* If we don't have an `nm', complain. */
1923 if (nm_file_name == 0)
1924 fatal ("cannot find `nm'");
1926 nm_argv[argc++] = nm_file_name;
1927 if (NM_FLAGS[0] != '\0')
1928 nm_argv[argc++] = NM_FLAGS;
1930 nm_argv[argc++] = prog_name;
1931 nm_argv[argc++] = (char *) 0;
1933 if (pipe (pipe_fd) < 0)
1934 fatal_perror ("pipe");
1936 inf = fdopen (pipe_fd[0], "r");
1937 if (inf == (FILE *) 0)
1938 fatal_perror ("fdopen");
1940 /* Trace if needed. */
1946 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
1947 fprintf (stderr, " %s", str);
1949 fprintf (stderr, "\n");
1955 /* Spawn child nm on pipe */
1960 fatal_perror ("fork");
1962 fatal_perror ("vfork");
1966 if (pid == 0) /* child context */
1969 if (dup2 (pipe_fd[1], 1) < 0)
1970 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
1972 if (close (pipe_fd[0]) < 0)
1973 fatal_perror ("close (%d)", pipe_fd[0]);
1975 if (close (pipe_fd[1]) < 0)
1976 fatal_perror ("close (%d)", pipe_fd[1]);
1978 execv (nm_file_name, nm_argv);
1979 fatal_perror ("executing %s", nm_file_name);
1982 /* Parent context from here on. */
1983 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
1985 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
1988 if (close (pipe_fd[1]) < 0)
1989 fatal_perror ("close (%d)", pipe_fd[1]);
1992 fprintf (stderr, "\nnm output with constructors/destructors.\n");
1994 /* Read each line of nm output. */
1995 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2000 /* If it contains a constructor or destructor name, add the name
2001 to the appropriate list. */
2003 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2004 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2011 /* Find the end of the symbol name.
2012 Don't include `|', because Encore nm can tack that on the end. */
2013 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
2019 switch (is_ctor_dtor (name))
2022 if (which_pass != PASS_LIB)
2023 add_to_list (&constructors, name);
2027 if (which_pass != PASS_LIB)
2028 add_to_list (&destructors, name);
2032 if (which_pass != PASS_LIB)
2033 fatal ("init function found in object %s", prog_name);
2034 #ifndef LD_INIT_SWITCH
2035 add_to_list (&constructors, name);
2040 if (which_pass != PASS_LIB)
2041 fatal ("fini function found in object %s", prog_name);
2042 #ifndef LD_FINI_SWITCH
2043 add_to_list (&destructors, name);
2048 if (which_pass != PASS_LIB)
2049 add_to_list (&frame_tables, name);
2051 default: /* not a constructor or destructor */
2056 fprintf (stderr, "\t%s\n", buf);
2060 fprintf (stderr, "\n");
2062 if (fclose (inf) != 0)
2063 fatal_perror ("fclose of pipe");
2065 do_wait (nm_file_name);
2067 signal (SIGINT, int_handler);
2069 signal (SIGQUIT, quit_handler);
2073 #if SUNOS4_SHARED_LIBRARIES
2075 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2076 that the output file depends upon and their initialization/finalization
2077 routines, if any. */
2082 #include <sys/mman.h>
2083 #include <sys/param.h>
2085 #include <sys/dir.h>
2087 /* pointers to the object file */
2088 unsigned object; /* address of memory mapped file */
2089 unsigned objsize; /* size of memory mapped to file */
2090 char * code; /* pointer to code segment */
2091 char * data; /* pointer to data segment */
2092 struct nlist *symtab; /* pointer to symbol table */
2093 struct link_dynamic *ld;
2094 struct link_dynamic_2 *ld_2;
2095 struct head libraries;
2097 /* Map the file indicated by NAME into memory and store its address. */
2105 if ((fp = open (name, O_RDONLY)) == -1)
2106 fatal ("unable to open file '%s'", name);
2107 if (fstat (fp, &s) == -1)
2108 fatal ("unable to stat file '%s'", name);
2110 objsize = s.st_size;
2111 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2114 fatal ("unable to mmap file '%s'", name);
2119 /* Helpers for locatelib. */
2121 static char *libname;
2127 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2130 /* If one file has an additional numeric extension past LIBNAME, then put
2131 that one first in the sort. If both files have additional numeric
2132 extensions, then put the one with the higher number first in the sort.
2134 We must verify that the extension is numeric, because Sun saves the
2135 original versions of patched libraries with a .FCS extension. Files with
2136 invalid extensions must go last in the sort, so that they won't be used. */
2140 struct direct **d1, **d2;
2142 int i1, i2 = strlen (libname);
2143 char *e1 = (*d1)->d_name + i2;
2144 char *e2 = (*d2)->d_name + i2;
2146 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2147 && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))
2151 i1 = strtol (e1, &e1, 10);
2152 i2 = strtol (e2, &e2, 10);
2159 /* It has a valid numeric extension, prefer this one. */
2160 if (*e1 == '.' && e1[1] && isdigit (e1[1]))
2162 /* It has a invalid numeric extension, must prefer the other one. */
2168 /* It has a valid numeric extension, prefer this one. */
2169 if (*e2 == '.' && e2[1] && isdigit (e2[1]))
2171 /* It has a invalid numeric extension, must prefer the other one. */
2179 /* Given the name NAME of a dynamic dependency, find its pathname and add
2180 it to the list of libraries. */
2188 char buf[MAXPATHLEN];
2196 /* counting elements in array, need 1 extra for null */
2198 ld_rules = (char *) (ld_2->ld_rules + code);
2202 for (; *ld_rules != 0; ld_rules++)
2203 if (*ld_rules == ':')
2205 ld_rules = (char *) (ld_2->ld_rules + code);
2206 ldr = (char *) malloc (strlen (ld_rules) + 1);
2207 strcpy (ldr, ld_rules);
2209 p = getenv ("LD_LIBRARY_PATH");
2214 for (q = p ; *q != 0; q++)
2217 q = (char *) malloc (strlen (p) + 1);
2220 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2225 for (; *ldr != 0; ldr++)
2235 for (; *q != 0; q++)
2242 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2245 *pp++ = "/usr/local/lib";
2249 for (pp = l; *pp != 0 ; pp++)
2251 struct direct **namelist;
2253 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2255 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2256 add_to_list (&libraries, buf);
2258 fprintf (stderr, "%s\n", buf);
2265 fprintf (stderr, "not found\n");
2267 fatal ("dynamic dependency %s not found", name);
2271 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2272 that it depends upon and any constructors or destructors they contain. */
2275 scan_libraries (prog_name)
2278 struct exec *header;
2280 struct link_object *lo;
2281 char buff[MAXPATHLEN];
2284 mapfile (prog_name);
2285 header = (struct exec *)object;
2286 if (N_BADMAG (*header))
2287 fatal ("bad magic number in file '%s'", prog_name);
2288 if (header->a_dynamic == 0)
2291 code = (char *) (N_TXTOFF (*header) + (long) header);
2292 data = (char *) (N_DATOFF (*header) + (long) header);
2293 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2295 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2298 ld = (struct link_dynamic *) (symtab->n_value + code);
2304 ld = (struct link_dynamic *) data;
2309 fprintf (stderr, "dynamic dependencies.\n");
2311 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2312 for (lo = (struct link_object *) ld_2->ld_need; lo;
2313 lo = (struct link_object *) lo->lo_next)
2316 lo = (struct link_object *) ((long) lo + code);
2317 name = (char *) (code + lo->lo_name);
2321 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2322 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2328 fprintf (stderr, "\t%s\n", name);
2329 add_to_list (&libraries, name);
2334 fprintf (stderr, "\n");
2336 /* now iterate through the library list adding their symbols to
2338 for (list = libraries.first; list; list = list->next)
2339 scan_prog_file (list->name, PASS_LIB);
2342 #else /* SUNOS4_SHARED_LIBRARIES */
2345 /* Use the List Dynamic Dependencies program to find shared libraries that
2346 the output file depends upon and their initialization/finalization
2347 routines, if any. */
2350 scan_libraries (prog_name)
2353 static struct head libraries; /* list of shared libraries found */
2355 void (*int_handler) ();
2356 void (*quit_handler) ();
2364 /* If we don't have an `ldd', complain. */
2365 if (ldd_file_name == 0)
2367 error ("cannot find `ldd'");
2371 ldd_argv[argc++] = ldd_file_name;
2372 ldd_argv[argc++] = prog_name;
2373 ldd_argv[argc++] = (char *) 0;
2375 if (pipe (pipe_fd) < 0)
2376 fatal_perror ("pipe");
2378 inf = fdopen (pipe_fd[0], "r");
2379 if (inf == (FILE *) 0)
2380 fatal_perror ("fdopen");
2382 /* Trace if needed. */
2388 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2389 fprintf (stderr, " %s", str);
2391 fprintf (stderr, "\n");
2397 /* Spawn child ldd on pipe */
2402 fatal_perror ("fork");
2404 fatal_perror ("vfork");
2408 if (pid == 0) /* child context */
2411 if (dup2 (pipe_fd[1], 1) < 0)
2412 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2414 if (close (pipe_fd[0]) < 0)
2415 fatal_perror ("close (%d)", pipe_fd[0]);
2417 if (close (pipe_fd[1]) < 0)
2418 fatal_perror ("close (%d)", pipe_fd[1]);
2420 execv (ldd_file_name, ldd_argv);
2421 fatal_perror ("executing %s", ldd_file_name);
2424 /* Parent context from here on. */
2425 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2427 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2430 if (close (pipe_fd[1]) < 0)
2431 fatal_perror ("close (%d)", pipe_fd[1]);
2434 fprintf (stderr, "\nldd output with constructors/destructors.\n");
2436 /* Read each line of ldd output. */
2437 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2440 char *name, *end, *p = buf;
2442 /* Extract names of libraries and add to list. */
2443 PARSE_LDD_OUTPUT (p);
2448 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2449 fatal ("dynamic dependency %s not found", buf);
2451 /* Find the end of the symbol name. */
2453 (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
2458 if (access (name, R_OK) == 0)
2459 add_to_list (&libraries, name);
2461 fatal ("unable to open dynamic dependency '%s'", buf);
2464 fprintf (stderr, "\t%s\n", buf);
2467 fprintf (stderr, "\n");
2469 if (fclose (inf) != 0)
2470 fatal_perror ("fclose of pipe");
2472 do_wait (ldd_file_name);
2474 signal (SIGINT, int_handler);
2476 signal (SIGQUIT, quit_handler);
2479 /* now iterate through the library list adding their symbols to
2481 for (list = libraries.first; list; list = list->next)
2482 scan_prog_file (list->name, PASS_LIB);
2485 #endif /* LDD_SUFFIX */
2486 #endif /* SUNOS4_SHARED_LIBRARIES */
2488 #endif /* OBJECT_FORMAT_NONE */
2492 * COFF specific stuff.
2495 #ifdef OBJECT_FORMAT_COFF
2497 #if defined(EXTENDED_COFF)
2498 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2499 # define GCC_SYMENT SYMR
2500 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2501 # define GCC_SYMINC(X) (1)
2502 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2503 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2505 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2506 # define GCC_SYMENT SYMENT
2507 # define GCC_OK_SYMBOL(X) \
2508 (((X).n_sclass == C_EXT) && \
2509 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2510 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2511 # define GCC_SYMINC(X) ((X).n_numaux+1)
2512 # define GCC_SYMZERO(X) 0
2513 # define GCC_CHECK_HDR(X) (1)
2516 extern char *ldgetname ();
2518 /* COFF version to scan the name list of the loaded program for
2519 the symbols g++ uses for static constructors and destructors.
2521 The constructor table begins at __CTOR_LIST__ and contains a count
2522 of the number of pointers (or -1 if the constructors are built in a
2523 separate section by the linker), followed by the pointers to the
2524 constructor functions, terminated with a null pointer. The
2525 destructor table has the same format, and begins at __DTOR_LIST__. */
2528 scan_prog_file (prog_name, which_pass)
2530 enum pass which_pass;
2532 LDFILE *ldptr = NULL;
2533 int sym_index, sym_count;
2535 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2538 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
2539 fatal ("%s: can't open as COFF file", prog_name);
2541 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2542 fatal ("%s: not a COFF file", prog_name);
2544 if (GCC_CHECK_HDR (ldptr))
2546 sym_count = GCC_SYMBOLS (ldptr);
2547 sym_index = GCC_SYMZERO (ldptr);
2548 while (sym_index < sym_count)
2552 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2554 sym_index += GCC_SYMINC (symbol);
2556 if (GCC_OK_SYMBOL (symbol))
2560 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2561 continue; /* should never happen */
2563 #ifdef XCOFF_DEBUGGING_INFO
2564 /* All AIX function names have a duplicate entry beginning
2570 switch (is_ctor_dtor (name))
2573 add_to_list (&constructors, name);
2574 if (which_pass == PASS_OBJ)
2575 add_to_list (&exports, name);
2579 add_to_list (&destructors, name);
2580 if (which_pass == PASS_OBJ)
2581 add_to_list (&exports, name);
2584 default: /* not a constructor or destructor */
2588 #if !defined(EXTENDED_COFF)
2590 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2591 symbol.n_scnum, symbol.n_sclass,
2592 (symbol.n_type ? "0" : ""), symbol.n_type,
2596 fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
2597 symbol.iss, symbol.value, symbol.index, name);
2603 (void) ldclose(ldptr);
2606 #ifdef XCOFF_SCAN_LIBS
2607 /* Scan imported AIX libraries for GCC static ctors and dtors.
2608 FIXME: it is possible to link an executable without the actual import
2609 library by using an "import file" - a text file listing symbols
2610 exported by a library. To support this, we would have to scan
2611 import files as well as actual shared binaries to find GCC ctors.
2612 TODO: use memory mapping instead of 'ld' routines, files are already
2613 memory mapped, but we could eliminate the extra in-memory copies.
2614 Is it worth the effort? */
2617 scan_libraries (prog_name)
2622 static struct path_prefix libpath; /* we should only do this once */
2624 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
2625 fatal ("%s: can't open as COFF file", prog_name);
2627 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2628 fatal ("%s: not a COFF file", prog_name);
2630 /* find and read loader section */
2631 if (ldnshread (ldptr, _LOADER, &ldsh))
2637 FSEEK (ldptr, ldsh.s_scnptr, BEGINNING);
2638 FREAD (&ldh, sizeof (ldh), 1, ldptr);
2639 /* read import library list */
2640 impbuf = alloca (ldh.l_istlen);
2641 FSEEK (ldptr, ldh.l_impoff + ldsh.s_scnptr, BEGINNING);
2642 FREAD (impbuf, ldh.l_istlen, 1, ldptr);
2645 fprintf (stderr, "LIBPATH=%s\n", impbuf);
2646 prefix_from_string (impbuf, &libpath);
2648 /* skip LIBPATH and empty base and member fields */
2649 impbuf += strlen (impbuf) + 3;
2650 for (entry = 1; entry < ldh.l_nimpid; ++entry)
2652 char *impath = impbuf;
2653 char *implib = impath + strlen (impath) + 1;
2654 char *impmem = implib + strlen (implib) + 1;
2655 char *soname = NULL;
2658 LDFILE *libptr = NULL;
2659 struct prefix_list *pl;
2662 impbuf = impmem + strlen (impmem) + 1;
2664 fprintf (stderr, "PATH+BASE=%s%s\n", impath, implib);
2665 /* Skip AIX kernel exports */
2666 if (*impath == '/' && *(impath+1) == '\0'
2667 && strcmp (implib, "unix") == 0)
2669 pathlen = strlen (impath);
2670 trial = alloca (MAX (pathlen + 1, libpath.max_len)
2671 + strlen (implib) + 1);
2674 strcpy (trial, impath);
2675 if (impath[pathlen - 1] != '/')
2676 trial[pathlen++] = '/';
2677 strcpy (trial + pathlen, implib);
2678 if (access (trial, R_OK) == 0)
2682 for (pl = libpath.plist; pl; pl = pl->next)
2684 strcpy (trial, pl->prefix);
2685 strcat (trial, implib);
2686 if (access (trial, R_OK) == 0)
2694 fatal ("%s: library not found", implib);
2697 fprintf (stderr, "%s (%s)\n", soname, impmem);
2699 fprintf (stderr, "%s\n", soname);
2703 /* scan imported shared objects for GCC GLOBAL ctors */
2705 if ((libptr = ldopen (soname, libptr)) == NULL)
2706 fatal ("%s: can't open import library", soname);
2707 if (TYPE (libptr) == ARTYPE)
2711 fatal ("%s: no archive member specified", soname);
2712 ldahread (libptr, &ah);
2713 if (strcmp (ah.ar_name, impmem))
2716 type = HEADER (libptr).f_magic;
2717 if (HEADER (libptr).f_flags & F_SHROBJ)
2724 if (!ldnshread (libptr, _LOADER, &soldsh))
2725 fatal ("%s: not an import library", soname);
2726 FSEEK (libptr, soldsh.s_scnptr, BEGINNING);
2727 if (FREAD (&soldh, sizeof (soldh), 1, libptr) != 1)
2728 fatal ("%s: can't read loader section", soname);
2729 /*fprintf (stderr, "\tscanning %s\n", soname);*/
2730 symcnt = soldh.l_nsyms;
2731 lsyms = (LDSYM *) alloca (symcnt * sizeof (*lsyms));
2732 symcnt = FREAD (lsyms, sizeof (*lsyms), symcnt, libptr);
2733 ldstrings = alloca (soldh.l_stlen);
2734 FSEEK (libptr, soldsh.s_scnptr+soldh.l_stoff, BEGINNING);
2735 FREAD (ldstrings, soldh.l_stlen, 1, libptr);
2736 for (i = 0; i < symcnt; ++i)
2738 LDSYM *l = lsyms + i;
2739 if (LDR_EXPORT (*l))
2743 expname = l->l_name;
2744 else if (l->l_offset < soldh.l_stlen)
2745 expname = ldstrings + l->l_offset;
2746 switch (is_ctor_dtor (expname))
2750 fprintf (stderr, "\t%s\n", expname);
2751 add_to_list (&constructors, expname);
2755 add_to_list (&destructors, expname);
2758 default: /* not a constructor or destructor */
2765 fprintf (stderr, "%s: type = %04X flags = %04X\n",
2766 ah.ar_name, type, HEADER (libptr).f_flags);
2768 while (ldclose (libptr) == FAILURE);
2769 /* printf (stderr, "closed %s\n", soname); */
2773 #endif /* XCOFF_SCAN_LIBS */
2775 #endif /* OBJECT_FORMAT_COFF */
2779 * OSF/rose specific stuff.
2782 #ifdef OBJECT_FORMAT_ROSE
2784 /* Union of the various load commands */
2786 typedef union load_union
2788 ldc_header_t hdr; /* common header */
2789 load_cmd_map_command_t map; /* map indexing other load cmds */
2790 interpreter_command_t iprtr; /* interpreter pathname */
2791 strings_command_t str; /* load commands strings section */
2792 region_command_t region; /* region load command */
2793 reloc_command_t reloc; /* relocation section */
2794 package_command_t pkg; /* package load command */
2795 symbols_command_t sym; /* symbol sections */
2796 entry_command_t ent; /* program start section */
2797 gen_info_command_t info; /* object information */
2798 func_table_command_t func; /* function constructors/destructors */
2801 /* Structure to point to load command and data section in memory. */
2803 typedef struct load_all
2805 load_union_t *load; /* load command */
2806 char *section; /* pointer to section */
2809 /* Structure to contain information about a file mapped into memory. */
2813 char *start; /* start of map */
2814 char *name; /* filename */
2815 long size; /* size of the file */
2816 long rounded_size; /* size rounded to page boundary */
2817 int fd; /* file descriptor */
2818 int rw; /* != 0 if opened read/write */
2819 int use_mmap; /* != 0 if mmap'ed */
2822 extern int decode_mach_o_hdr ();
2823 extern int encode_mach_o_hdr ();
2825 static void add_func_table PROTO((mo_header_t *, load_all_t *,
2826 symbol_info_t *, int));
2827 static void print_header PROTO((mo_header_t *));
2828 static void print_load_command PROTO((load_union_t *, size_t, int));
2829 static void bad_header PROTO((int));
2830 static struct file_info *read_file PROTO((char *, int, int));
2831 static void end_file PROTO((struct file_info *));
2833 /* OSF/rose specific version to scan the name list of the loaded
2834 program for the symbols g++ uses for static constructors and
2837 The constructor table begins at __CTOR_LIST__ and contains a count
2838 of the number of pointers (or -1 if the constructors are built in a
2839 separate section by the linker), followed by the pointers to the
2840 constructor functions, terminated with a null pointer. The
2841 destructor table has the same format, and begins at __DTOR_LIST__. */
2844 scan_prog_file (prog_name, which_pass)
2846 enum pass which_pass;
2850 load_all_t *load_array;
2851 load_all_t *load_end;
2852 load_all_t *load_cmd;
2853 int symbol_load_cmds;
2859 struct file_info *obj_file;
2861 mo_lcid_t cmd_strings = -1;
2862 symbol_info_t *main_sym = 0;
2863 int rw = (which_pass != PASS_FIRST);
2865 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
2867 fatal_perror ("can't read %s", prog_name);
2869 obj_file = read_file (prog_name, prog_fd, rw);
2870 obj = obj_file->start;
2872 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
2873 if (status != MO_HDR_CONV_SUCCESS)
2874 bad_header (status);
2877 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
2878 since the hardware will automatically swap bytes for us on loading little endian
2881 #ifndef CROSS_COMPILE
2882 if (hdr.moh_magic != MOH_MAGIC_MSB
2883 || hdr.moh_header_version != MOH_HEADER_VERSION
2884 || hdr.moh_byte_order != OUR_BYTE_ORDER
2885 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
2886 || hdr.moh_cpu_type != OUR_CPU_TYPE
2887 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
2888 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
2890 fatal ("incompatibilities between object file & expected values");
2895 print_header (&hdr);
2897 offset = hdr.moh_first_cmd_off;
2898 load_end = load_array
2899 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
2901 /* Build array of load commands, calculating the offsets */
2902 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2904 load_union_t *load_hdr; /* load command header */
2906 load_cmd = load_end++;
2907 load_hdr = (load_union_t *) (obj + offset);
2909 /* If modifying the program file, copy the header. */
2912 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
2913 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
2916 /* null out old command map, because we will rewrite at the end. */
2917 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
2919 cmd_strings = ptr->map.lcm_ld_cmd_strings;
2920 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
2924 load_cmd->load = load_hdr;
2925 if (load_hdr->hdr.ldci_section_off > 0)
2926 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
2929 print_load_command (load_hdr, offset, i);
2931 offset += load_hdr->hdr.ldci_cmd_size;
2934 /* If the last command is the load command map and is not undefined,
2935 decrement the count of load commands. */
2936 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
2939 hdr.moh_n_load_cmds--;
2942 /* Go through and process each symbol table section. */
2943 symbol_load_cmds = 0;
2944 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
2946 load_union_t *load_hdr = load_cmd->load;
2948 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
2954 char *kind = "unknown";
2956 switch (load_hdr->sym.symc_kind)
2958 case SYMC_IMPORTS: kind = "imports"; break;
2959 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
2960 case SYMC_STABS: kind = "stabs"; break;
2963 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
2964 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
2967 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
2970 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
2971 if (str_sect == (char *) 0)
2972 fatal ("string section missing");
2974 if (load_cmd->section == (char *) 0)
2975 fatal ("section pointer missing");
2977 num_syms = load_hdr->sym.symc_nentries;
2978 for (i = 0; i < num_syms; i++)
2980 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
2981 char *name = sym->si_name.symbol_name + str_sect;
2988 char *n = name + strlen (name) - strlen (NAME__MAIN);
2990 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3000 switch (is_ctor_dtor (name))
3003 add_to_list (&constructors, name);
3007 add_to_list (&destructors, name);
3010 default: /* not a constructor or destructor */
3016 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3017 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3022 if (symbol_load_cmds == 0)
3023 fatal ("no symbol table found");
3025 /* Update the program file now, rewrite header and load commands. At present,
3026 we assume that there is enough space after the last load command to insert
3027 one more. Since the first section written out is page aligned, and the
3028 number of load commands is small, this is ok for the present. */
3032 load_union_t *load_map;
3035 if (cmd_strings == -1)
3036 fatal ("no cmd_strings found");
3038 /* Add __main to initializer list.
3039 If we are building a program instead of a shared library, don't
3040 do anything, since in the current version, you cannot do mallocs
3041 and such in the constructors. */
3043 if (main_sym != (symbol_info_t *) 0
3044 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3045 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3048 fprintf (stderr, "\nUpdating header and load commands.\n\n");
3050 hdr.moh_n_load_cmds++;
3051 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3053 /* Create new load command map. */
3055 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
3056 (int)hdr.moh_n_load_cmds, (long)size);
3058 load_map = (load_union_t *) xcalloc (1, size);
3059 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3060 load_map->map.ldc_header.ldci_cmd_size = size;
3061 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3062 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3063 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3065 offset = hdr.moh_first_cmd_off;
3066 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3068 load_map->map.lcm_map[i] = offset;
3069 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3070 hdr.moh_load_map_cmd_off = offset;
3072 offset += load_array[i].load->hdr.ldci_cmd_size;
3075 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3078 print_header (&hdr);
3081 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3082 if (status != MO_HDR_CONV_SUCCESS)
3083 bad_header (status);
3086 fprintf (stderr, "writing load commands.\n\n");
3088 /* Write load commands */
3089 offset = hdr.moh_first_cmd_off;
3090 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3092 load_union_t *load_hdr = load_array[i].load;
3093 size_t size = load_hdr->hdr.ldci_cmd_size;
3096 print_load_command (load_hdr, offset, i);
3098 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3103 end_file (obj_file);
3105 if (close (prog_fd))
3106 fatal_perror ("closing %s", prog_name);
3109 fprintf (stderr, "\n");
3113 /* Add a function table to the load commands to call a function
3114 on initiation or termination of the process. */
3117 add_func_table (hdr_p, load_array, sym, type)
3118 mo_header_t *hdr_p; /* pointer to global header */
3119 load_all_t *load_array; /* array of ptrs to load cmds */
3120 symbol_info_t *sym; /* pointer to symbol entry */
3121 int type; /* fntc_type value */
3123 /* Add a new load command. */
3124 int num_cmds = ++hdr_p->moh_n_load_cmds;
3125 int load_index = num_cmds - 1;
3126 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3127 load_union_t *ptr = xcalloc (1, size);
3128 load_all_t *load_cmd;
3131 /* Set the unresolved address bit in the header to force the loader to be
3132 used, since kernel exec does not call the initialization functions. */
3133 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3135 load_cmd = &load_array[load_index];
3136 load_cmd->load = ptr;
3137 load_cmd->section = (char *) 0;
3139 /* Fill in func table load command. */
3140 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3141 ptr->func.ldc_header.ldci_cmd_size = size;
3142 ptr->func.ldc_header.ldci_section_off = 0;
3143 ptr->func.ldc_header.ldci_section_len = 0;
3144 ptr->func.fntc_type = type;
3145 ptr->func.fntc_nentries = 1;
3147 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3148 /* Is the symbol already expressed as (region, offset)? */
3149 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3151 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3152 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3155 /* If not, figure out which region it's in. */
3158 mo_vm_addr_t addr = sym->si_value.abs_val;
3161 for (i = 0; i < load_index; i++)
3163 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3165 region_command_t *region_ptr = &load_array[i].load->region;
3167 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3168 && addr >= region_ptr->regc_addr.vm_addr
3169 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3171 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3172 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3180 fatal ("could not convert 0x%l.8x into a region", addr);
3185 "%s function, region %d, offset = %ld (0x%.8lx)\n",
3186 (type == FNTC_INITIALIZATION) ? "init" : "term",
3187 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
3188 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
3189 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
3194 /* Print the global header for an OSF/rose object. */
3197 print_header (hdr_ptr)
3198 mo_header_t *hdr_ptr;
3200 fprintf (stderr, "\nglobal header:\n");
3201 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3202 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3203 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3204 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3205 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3206 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3207 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3208 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3209 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3210 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3211 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3212 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3213 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3214 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3215 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3217 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3218 fprintf (stderr, ", relocatable");
3220 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3221 fprintf (stderr, ", linkable");
3223 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3224 fprintf (stderr, ", execable");
3226 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3227 fprintf (stderr, ", executable");
3229 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3230 fprintf (stderr, ", unresolved");
3232 fprintf (stderr, "\n\n");
3237 /* Print a short summary of a load command. */
3240 print_load_command (load_hdr, offset, number)
3241 load_union_t *load_hdr;
3245 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3246 char *type_str = (char *) 0;
3250 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3251 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3252 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3253 case LDC_STRINGS: type_str = "STRINGS"; break;
3254 case LDC_REGION: type_str = "REGION"; break;
3255 case LDC_RELOC: type_str = "RELOC"; break;
3256 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3257 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3258 case LDC_ENTRY: type_str = "ENTRY"; break;
3259 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3260 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3264 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3266 (long) load_hdr->hdr.ldci_cmd_size,
3268 (long) load_hdr->hdr.ldci_section_off,
3269 (long) load_hdr->hdr.ldci_section_len);
3271 if (type_str == (char *) 0)
3272 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3274 else if (type != LDC_REGION)
3275 fprintf (stderr, ", ty: %s\n", type_str);
3280 switch (load_hdr->region.regc_usage_type)
3282 case REG_TEXT_T: region = ", .text"; break;
3283 case REG_DATA_T: region = ", .data"; break;
3284 case REG_BSS_T: region = ", .bss"; break;
3285 case REG_GLUE_T: region = ", .glue"; break;
3286 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3287 case REG_RDATA_T: region = ", .rdata"; break;
3288 case REG_SDATA_T: region = ", .sdata"; break;
3289 case REG_SBSS_T: region = ", .sbss"; break;
3293 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3295 (long) load_hdr->region.regc_vm_addr,
3296 (long) load_hdr->region.regc_vm_size,
3304 /* Fatal error when {en,de}code_mach_o_header fails. */
3310 char *msg = (char *) 0;
3314 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
3315 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
3316 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
3317 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
3318 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
3319 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
3322 if (msg == (char *) 0)
3323 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3329 /* Read a file into a memory buffer. */
3331 static struct file_info *
3332 read_file (name, fd, rw)
3333 char *name; /* filename */
3334 int fd; /* file descriptor */
3335 int rw; /* read/write */
3337 struct stat stat_pkt;
3338 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3340 static int page_size;
3343 if (fstat (fd, &stat_pkt) < 0)
3344 fatal_perror ("fstat %s", name);
3347 p->size = stat_pkt.st_size;
3348 p->rounded_size = stat_pkt.st_size;
3354 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3357 page_size = sysconf (_SC_PAGE_SIZE);
3359 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3360 p->start = mmap ((caddr_t) 0,
3361 (rw) ? p->rounded_size : p->size,
3362 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3363 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3367 if (p->start != (char *) 0 && p->start != (char *) -1)
3371 #endif /* USE_MMAP */
3376 fprintf (stderr, "read %s\n", name);
3379 p->start = xmalloc (p->size);
3380 if (lseek (fd, 0L, SEEK_SET) < 0)
3381 fatal_perror ("lseek to 0 on %s", name);
3383 len = read (fd, p->start, p->size);
3385 fatal_perror ("read %s", name);
3388 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3394 /* Do anything necessary to write a file back from memory. */
3398 struct file_info *ptr; /* file information block */
3406 fprintf (stderr, "msync %s\n", ptr->name);
3408 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3409 fatal_perror ("msync %s", ptr->name);
3413 fprintf (stderr, "munmap %s\n", ptr->name);
3415 if (munmap (ptr->start, ptr->size))
3416 fatal_perror ("munmap %s", ptr->name);
3419 #endif /* USE_MMAP */
3426 fprintf (stderr, "write %s\n", ptr->name);
3428 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3429 fatal_perror ("lseek to 0 on %s", ptr->name);
3431 len = write (ptr->fd, ptr->start, ptr->size);
3433 fatal_perror ("write %s", ptr->name);
3435 if (len != ptr->size)
3436 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3445 #endif /* OBJECT_FORMAT_ROSE */