1 /* Collect static initialization info into data structures
2 that can be traversed by C++ initialization and finalization
5 Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
6 Contributed by Chris Smith (csmith@convex.com).
7 Heavily modified by Michael Meissner (meissner@cygnus.com),
8 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
10 This file is part of GNU CC.
12 GNU CC is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 GNU CC is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GNU CC; see the file COPYING. If not, write to
24 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
27 /* Build tables of static constructors and destructors and run ld. */
29 #include <sys/types.h>
46 extern const char *const sys_errlist[];
48 extern char *sys_errlist[];
62 /* Obstack allocation and deallocation routines. */
63 #define obstack_chunk_alloc xmalloc
64 #define obstack_chunk_free free
66 #if !defined (__STDC__) && !defined (const)
74 /* Add prototype support. */
76 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
77 #define PROTO(ARGS) ARGS
79 #define PROTO(ARGS) ()
90 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
93 #define WTERMSIG(S) ((S) & 0x7f)
96 #define WIFEXITED(S) (((S) & 0xff) == 0)
99 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
102 /* On MSDOS, write temp files in current dir
103 because there's no place else we can expect to use. */
106 #define P_tmpdir "./"
110 /* On certain systems, we have code that works by scanning the object file
111 directly. But this code uses system-specific header files and library
112 functions, so turn it off in a cross-compiler. Likewise, the names of
113 the utilities aren't correct for a cross-compiler; we have to hope that
114 cross-versions are in the proper directories. */
117 #undef SUNOS4_SHARED_LIBRARIES
118 #undef OBJECT_FORMAT_COFF
119 #undef OBJECT_FORMAT_ROSE
120 #undef MD_EXEC_PREFIX
121 #undef REAL_LD_FILE_NAME
122 #undef REAL_NM_FILE_NAME
123 #undef REAL_STRIP_FILE_NAME
126 /* If we can't use a special method, use the ordinary one:
127 run nm to find what symbols are present.
128 In a cross-compiler, this means you need a cross nm,
129 but that isn't quite as unpleasant as special headers. */
131 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
132 #define OBJECT_FORMAT_NONE
135 #ifdef OBJECT_FORMAT_COFF
144 /* Many versions of ldfcn.h define these. */
152 /* Some systems have an ISCOFF macro, but others do not. In some cases
153 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
154 that either do not have an ISCOFF macro in /usr/include or for those
155 where it is wrong. */
158 #define MY_ISCOFF(X) ISCOFF (X)
161 #endif /* OBJECT_FORMAT_COFF */
163 #ifdef OBJECT_FORMAT_ROSE
170 #include <sys/mman.h>
174 #include <mach_o_format.h>
175 #include <mach_o_header.h>
176 #include <mach_o_vals.h>
177 #include <mach_o_types.h>
179 #endif /* OBJECT_FORMAT_ROSE */
181 #ifdef OBJECT_FORMAT_NONE
183 /* Default flags to pass to nm. */
185 #define NM_FLAGS "-p"
188 #endif /* OBJECT_FORMAT_NONE */
190 /* Some systems use __main in a way incompatible with its use in gcc, in these
191 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
192 give the same symbol without quotes for an alternative entry point. You
193 must define both, or niether. */
195 #define NAME__MAIN "__main"
196 #define SYMBOL__MAIN __main
199 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
200 #define SCAN_LIBRARIES
204 int do_collecting = 1;
206 int do_collecting = 0;
209 /* Linked lists of constructor and destructor names. */
225 /* Enumeration giving which pass this is for scanning the program file. */
228 PASS_FIRST, /* without constructors */
229 PASS_OBJ, /* individual objects */
230 PASS_LIB, /* looking for shared libraries */
231 PASS_SECOND /* with constructors linked in */
234 #ifndef NO_SYS_SIGLIST
235 #ifndef DONT_DECLARE_SYS_SIGLIST
236 extern char *sys_siglist[];
239 extern char *version_string;
241 int vflag; /* true if -v */
242 static int rflag; /* true if -r */
243 static int strip_flag; /* true if -s */
245 int debug; /* true if -debug */
247 static int shared_obj; /* true if -shared */
249 static int temp_filename_length; /* Length of temp_filename */
250 static char *temp_filename; /* Base of temp filenames */
251 static char *c_file; /* <xxx>.c for constructor/destructor list. */
252 static char *o_file; /* <xxx>.o for constructor/destructor list. */
253 static char *export_file; /* <xxx>.x for AIX export list. */
254 static int auto_export = 1; /* true if exporting everything. */
255 char *ldout; /* File for ld errors. */
256 static char *output_file; /* Output file for ld. */
257 static char *nm_file_name; /* pathname of nm */
258 static char *ldd_file_name; /* pathname of ldd (or equivalent) */
259 static char *strip_file_name; /* pathname of strip */
260 char *c_file_name; /* pathname of gcc */
261 static char *initname, *fininame; /* names of init and fini funcs */
263 static struct head constructors; /* list of constructors found */
264 static struct head destructors; /* list of destructors found */
265 static struct head exports; /* list of exported symbols */
267 struct obstack temporary_obstack;
268 struct obstack permanent_obstack;
269 char * temporary_firstobj;
271 /* Defined in the automatically-generated underscore.c. */
272 extern int prepends_underscore;
274 extern char *getenv ();
275 extern char *mktemp ();
276 extern FILE *fdopen ();
278 /* Structure to hold all the directories in which to search for files to
283 char *prefix; /* String to prepend to the path. */
284 struct prefix_list *next; /* Next in linked list. */
289 struct prefix_list *plist; /* List of prefixes to try */
290 int max_len; /* Max length of a prefix in PLIST */
291 char *name; /* Name of this list (used in config stuff) */
294 void collect_exit PROTO((int));
295 void collect_execute PROTO((char *, char **, char *));
296 void dump_file PROTO((char *));
297 static void handler PROTO((int));
298 static int is_ctor_dtor PROTO((char *));
299 static void choose_temp_base PROTO((void));
300 static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
301 static char *find_a_file PROTO((struct path_prefix *, char *));
302 static void add_prefix PROTO((struct path_prefix *, char *));
303 static void prefix_from_env PROTO((char *, struct path_prefix *));
304 static void prefix_from_string PROTO((char *, struct path_prefix *));
305 static void do_wait PROTO((char *));
306 static void fork_execute PROTO((char *, char **));
307 static void maybe_unlink PROTO((char *));
308 static void add_to_list PROTO((struct head *, char *));
309 static void write_list PROTO((FILE *, char *, struct id *));
310 static void write_list_with_asm PROTO((FILE *, char *, struct id *));
311 static void write_c_file PROTO((FILE *, char *));
312 static void write_export_file PROTO((FILE *));
313 static void scan_prog_file PROTO((char *, enum pass));
314 static void scan_libraries PROTO((char *));
319 extern char *index ();
320 extern char *rindex ();
336 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
339 close (fdtmp[--fdx]);
355 static char buffer[30];
359 if (e > 0 && e < sys_nerr)
360 return sys_errlist[e];
362 sprintf (buffer, "Unknown error %d", e);
367 /* Delete tempfiles and exit function. */
370 collect_exit (status)
373 if (c_file != 0 && c_file[0])
374 maybe_unlink (c_file);
376 if (o_file != 0 && o_file[0])
377 maybe_unlink (o_file);
379 if (export_file != 0 && export_file[0])
380 maybe_unlink (export_file);
382 if (ldout != 0 && ldout[0])
385 maybe_unlink (ldout);
388 if (status != 0 && output_file != 0 && output_file[0])
389 maybe_unlink (output_file);
395 /* Die when sys call fails. */
398 fatal_perror (string, arg1, arg2, arg3)
399 char *string, *arg1, *arg2, *arg3;
403 fprintf (stderr, "collect2: ");
404 fprintf (stderr, string, arg1, arg2, arg3);
405 fprintf (stderr, ": %s\n", my_strerror (e));
412 fatal (string, arg1, arg2, arg3)
413 char *string, *arg1, *arg2, *arg3;
415 fprintf (stderr, "collect2: ");
416 fprintf (stderr, string, arg1, arg2, arg3);
417 fprintf (stderr, "\n");
421 /* Write error message. */
424 error (string, arg1, arg2, arg3, arg4)
425 char *string, *arg1, *arg2, *arg3, *arg4;
427 fprintf (stderr, "collect2: ");
428 fprintf (stderr, string, arg1, arg2, arg3, arg4);
429 fprintf (stderr, "\n");
432 /* In case obstack is linked in, and abort is defined to fancy_abort,
433 provide a default entry. */
438 fatal ("internal error");
446 if (c_file != 0 && c_file[0])
447 maybe_unlink (c_file);
449 if (o_file != 0 && o_file[0])
450 maybe_unlink (o_file);
452 if (ldout != 0 && ldout[0])
453 maybe_unlink (ldout);
455 signal (signo, SIG_DFL);
456 kill (getpid (), signo);
461 xcalloc (size1, size2)
464 char *ptr = (char *) calloc (size1, size2);
468 fatal ("out of memory");
476 char *ptr = (char *) malloc (size);
480 fatal ("out of memory");
489 register char *value = (char *) realloc (ptr, size);
491 fatal ("virtual memory exhausted");
499 return access (name, R_OK) == 0;
502 /* Make a copy of a string INPUT with size SIZE. */
505 savestring (input, size)
509 char *output = (char *) xmalloc (size + 1);
510 bcopy (input, output, size);
519 FILE *stream = fopen (name, "r");
520 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
527 while (c = getc (stream),
528 c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))
529 obstack_1grow (&temporary_obstack, c);
530 if (obstack_object_size (&temporary_obstack) > 0)
532 char *word, *p, *result;
533 obstack_1grow (&temporary_obstack, '\0');
534 word = obstack_finish (&temporary_obstack);
537 ++word, putc ('.', stderr);
539 if (*p == '_' && prepends_underscore)
545 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
550 fputs (result, stderr);
552 diff = strlen (word) - strlen (result);
554 --diff, putc (' ', stderr);
555 while (diff < 0 && c == ' ')
556 ++diff, c = getc (stream);
561 fputs (word, stderr);
564 obstack_free (&temporary_obstack, temporary_firstobj);
572 /* Decide whether the given symbol is:
573 a constructor (1), a destructor (2), or neither (0). */
579 struct names { char *name; int len; int ret; int two_underscores; };
581 register struct names *p;
583 register char *orig_s = s;
585 static struct names special[] = {
586 #ifdef NO_DOLLAR_IN_LABEL
587 #ifdef NO_DOT_IN_LABEL
588 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
589 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
591 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
592 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
595 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
596 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
598 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
599 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
600 #ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
601 cfront has its own linker procedure to collect them;
602 if collect2 gets them too, they get collected twice
603 when the cfront procedure is run and the compiler used
604 for linking happens to be GCC. */
605 { "sti__", sizeof ("sti__")-1, 1, 1 },
606 { "std__", sizeof ("std__")-1, 2, 1 },
607 #endif /* CFRONT_LOSSAGE */
611 while ((ch = *s) == '_')
617 for (p = &special[0]; p->len > 0; p++)
620 && (!p->two_underscores || ((s - orig_s) >= 2))
621 && strncmp(s, p->name, p->len) == 0)
630 /* Compute a string to use as the base of all temporary file names.
631 It is substituted for %g. */
636 char *base = getenv ("TMPDIR");
639 if (base == (char *)0)
642 if (access (P_tmpdir, R_OK | W_OK) == 0)
645 if (base == (char *)0)
647 if (access ("/usr/tmp", R_OK | W_OK) == 0)
655 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
656 strcpy (temp_filename, base);
657 if (len > 0 && temp_filename[len-1] != '/')
658 temp_filename[len++] = '/';
659 strcpy (temp_filename + len, "ccXXXXXX");
661 mktemp (temp_filename);
662 temp_filename_length = strlen (temp_filename);
665 /* Routine to add variables to the environment. */
673 #ifndef VMS /* nor about VMS */
675 extern char **environ;
676 char **old_environ = environ;
683 while ((ch = *p++) != '\0' && ch != '=')
689 /* Search for replacing an existing environment variable, and
690 count the number of total environment variables. */
691 for (envp = old_environ; *envp; envp++)
694 if (!strncmp (str, *envp, name_len))
701 /* Add a new environment variable */
702 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
704 bcopy ((char *) old_environ, (char *) (environ + 1),
705 sizeof (char *) * (num_envs+1));
711 #endif /* HAVE_PUTENV */
713 /* By default, colon separates directories in a path. */
714 #ifndef PATH_SEPARATOR
715 #define PATH_SEPARATOR ':'
718 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
719 and one from the PATH variable. */
721 static struct path_prefix cpath, path;
724 /* This is the name of the target machine. We use it to form the name
725 of the files to execute. */
727 static char *target_machine = TARGET_MACHINE;
730 /* Names under which we were executed. Never return one of those files in our
733 static struct path_prefix our_file_names;
735 /* Determine if STRING is in PPREFIX.
737 This utility is currently only used to look up file names. Prefix lists
738 record directory names. This matters to us because the latter has a
739 trailing slash, so I've added a flag to handle both. */
742 is_in_prefix_list (pprefix, string, filep)
743 struct path_prefix *pprefix;
747 struct prefix_list *pl;
751 int len = strlen (string);
753 for (pl = pprefix->plist; pl; pl = pl->next)
755 if (strncmp (pl->prefix, string, len) == 0
756 && strcmp (pl->prefix + len, "/") == 0)
762 for (pl = pprefix->plist; pl; pl = pl->next)
764 if (strcmp (pl->prefix, string) == 0)
772 /* Search for NAME using prefix list PPREFIX. We only look for executable
775 Return 0 if not found, otherwise return its name, allocated with malloc. */
778 find_a_file (pprefix, name)
779 struct path_prefix *pprefix;
783 struct prefix_list *pl;
784 int len = pprefix->max_len + strlen (name) + 1;
786 #ifdef EXECUTABLE_SUFFIX
787 len += strlen (EXECUTABLE_SUFFIX);
790 temp = xmalloc (len);
792 /* Determine the filename to execute (special case for absolute paths). */
796 if (access (name, X_OK) == 0)
803 for (pl = pprefix->plist; pl; pl = pl->next)
805 strcpy (temp, pl->prefix);
807 if (! is_in_prefix_list (&our_file_names, temp, 1)
808 /* This is a kludge, but there seems no way around it. */
809 && strcmp (temp, "./ld") != 0
810 && access (temp, X_OK) == 0)
813 #ifdef EXECUTABLE_SUFFIX
814 /* Some systems have a suffix for executable files.
815 So try appending that. */
816 strcat (temp, EXECUTABLE_SUFFIX);
817 if (! is_in_prefix_list (&our_file_names, temp, 1)
818 && access (temp, X_OK) == 0)
827 /* Add an entry for PREFIX to prefix list PPREFIX. */
830 add_prefix (pprefix, prefix)
831 struct path_prefix *pprefix;
834 struct prefix_list *pl, **prev;
839 for (pl = pprefix->plist; pl->next; pl = pl->next)
844 prev = &pprefix->plist;
846 /* Keep track of the longest prefix */
848 len = strlen (prefix);
849 if (len > pprefix->max_len)
850 pprefix->max_len = len;
852 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
853 pl->prefix = savestring (prefix, len);
858 pl->next = (struct prefix_list *) 0;
862 /* Take the value of the environment variable ENV, break it into a path, and
863 add of the entries to PPREFIX. */
866 prefix_from_env (env, pprefix)
868 struct path_prefix *pprefix;
870 char *p = getenv (env);
873 prefix_from_string (p, pprefix);
877 prefix_from_string (p, pprefix)
879 struct path_prefix *pprefix;
882 char *nstore = (char *) xmalloc (strlen (p) + 3);
887 if (*endp == PATH_SEPARATOR || *endp == 0)
889 strncpy (nstore, startp, endp-startp);
892 strcpy (nstore, "./");
894 else if (endp[-1] != '/')
896 nstore[endp-startp] = '/';
897 nstore[endp-startp+1] = 0;
900 nstore[endp-startp] = 0;
902 add_prefix (pprefix, nstore);
905 endp = startp = endp + 1;
919 char *ld_suffix = "ld";
920 char *full_ld_suffix = ld_suffix;
921 char *real_ld_suffix = "real-ld";
922 char *full_real_ld_suffix = real_ld_suffix;
923 char *collect_ld_suffix = "collect-ld";
924 char *nm_suffix = "nm";
925 char *full_nm_suffix = nm_suffix;
926 char *gnm_suffix = "gnm";
927 char *full_gnm_suffix = gnm_suffix;
929 char *ldd_suffix = LDD_SUFFIX;
930 char *full_ldd_suffix = ldd_suffix;
932 char *strip_suffix = "strip";
933 char *full_strip_suffix = strip_suffix;
934 char *gstrip_suffix = "gstrip";
935 char *full_gstrip_suffix = gstrip_suffix;
937 FILE *outf, *exportf;
944 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3);
945 char **ld1 = ld1_argv;
946 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6);
947 char **ld2 = ld2_argv;
948 char **object_lst = (char **) xcalloc (sizeof (char *), argc);
949 char **object = object_lst;
951 int num_c_args = argc+7;
958 output_file = "a.out";
960 obstack_begin (&temporary_obstack, 0);
961 obstack_begin (&permanent_obstack, 0);
962 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
963 current_demangling_style = gnu_demangling;
965 /* We must check that we do not call ourselves in an infinite
966 recursion loop. We append the name used for us to the COLLECT_NAMES
967 environment variable.
969 In practice, collect will rarely invoke itself. This can happen now
970 that we are no longer called gld. A perfect example is when running
971 gcc in a build directory that has been installed. When looking for
972 ld's, we'll find our installed version and believe that's the real ld. */
974 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
975 previous version of collect (the one that used COLLECT_NAME and only
976 handled two levels of recursion). If we don't we may mutually recurse
977 forever. This can happen (I think) when bootstrapping the old version
978 and a new one is installed (rare, but we should handle it).
979 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
981 collect_name = (char *) getenv ("COLLECT_NAME");
982 collect_names = (char *) getenv ("COLLECT_NAMES");
984 p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
985 + (collect_name ? strlen (collect_name) + 1 : 0)
986 + (collect_names ? strlen (collect_names) + 1 : 0)
987 + strlen (argv[0]) + 1);
988 strcpy (p, "COLLECT_NAMES=");
989 if (collect_name != 0)
990 sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
991 if (collect_names != 0)
992 sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
996 prefix_from_env ("COLLECT_NAMES", &our_file_names);
998 /* Set environment variable COLLECT_NAME to our name so the previous version
999 of collect won't find us. If it does we'll mutually recurse forever.
1000 This can happen when bootstrapping the new version and an old version is
1002 ??? Hopefully this bit of code can be removed at some point. */
1004 p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
1005 sprintf (p, "COLLECT_NAME=%s", argv[0]);
1008 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1013 while (*q && *q != ' ') q++;
1014 if (*p == '-' && p[1] == 'm')
1021 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
1024 fatal ("no arguments");
1027 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
1028 signal (SIGQUIT, handler);
1030 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
1031 signal (SIGINT, handler);
1033 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
1034 signal (SIGALRM, handler);
1037 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
1038 signal (SIGHUP, handler);
1040 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
1041 signal (SIGSEGV, handler);
1043 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
1044 signal (SIGBUS, handler);
1047 /* Extract COMPILER_PATH and PATH into our prefix list. */
1048 prefix_from_env ("COMPILER_PATH", &cpath);
1049 prefix_from_env ("PATH", &path);
1051 #ifdef CROSS_COMPILE
1052 /* If we look for a program in the compiler directories, we just use
1053 the short name, since these directories are already system-specific.
1054 But it we look for a took in the system directories, we need to
1055 qualify the program name with the target machine. */
1058 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
1059 strcpy (full_ld_suffix, target_machine);
1060 strcat (full_ld_suffix, "-");
1061 strcat (full_ld_suffix, ld_suffix);
1064 = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
1065 strcpy (full_real_ld_suffix, target_machine);
1066 strcat (full_real_ld_suffix, "-");
1067 strcat (full_real_ld_suffix, real_ld_suffix);
1071 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
1072 strcpy (full_gld_suffix, target_machine);
1073 strcat (full_gld_suffix, "-");
1074 strcat (full_gld_suffix, gld_suffix);
1078 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
1079 strcpy (full_nm_suffix, target_machine);
1080 strcat (full_nm_suffix, "-");
1081 strcat (full_nm_suffix, nm_suffix);
1084 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
1085 strcpy (full_gnm_suffix, target_machine);
1086 strcat (full_gnm_suffix, "-");
1087 strcat (full_gnm_suffix, gnm_suffix);
1091 = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
1092 strcpy (full_ldd_suffix, target_machine);
1093 strcat (full_ldd_suffix, "-");
1094 strcat (full_ldd_suffix, ldd_suffix);
1098 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
1099 strcpy (full_strip_suffix, target_machine);
1100 strcat (full_strip_suffix, "-");
1101 strcat (full_strip_suffix, strip_suffix);
1104 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
1105 strcpy (full_gstrip_suffix, target_machine);
1106 strcat (full_gstrip_suffix, "-");
1107 strcat (full_gstrip_suffix, gstrip_suffix);
1108 #endif /* CROSS_COMPILE */
1110 /* Try to discover a valid linker/nm/strip to use. */
1112 /* Maybe we know the right file to use (if not cross). */
1113 #ifdef REAL_LD_FILE_NAME
1114 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1115 if (ld_file_name == 0)
1117 /* Search the (target-specific) compiler dirs for ld'. */
1118 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1119 /* Likewise for `collect-ld'. */
1120 if (ld_file_name == 0)
1121 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1122 /* Search the compiler directories for `ld'. We have protection against
1123 recursive calls in find_a_file. */
1124 if (ld_file_name == 0)
1125 ld_file_name = find_a_file (&cpath, ld_suffix);
1126 /* Search the ordinary system bin directories
1127 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1128 if (ld_file_name == 0)
1129 ld_file_name = find_a_file (&path, full_ld_suffix);
1131 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
1133 if (collect_names != 0)
1135 if (ld_file_name != 0)
1137 argv[0] = ld_file_name;
1138 execvp (argv[0], argv);
1140 fatal ("cannot find `ld'");
1143 #ifdef REAL_NM_FILE_NAME
1144 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1145 if (nm_file_name == 0)
1147 nm_file_name = find_a_file (&cpath, gnm_suffix);
1148 if (nm_file_name == 0)
1149 nm_file_name = find_a_file (&path, full_gnm_suffix);
1150 if (nm_file_name == 0)
1151 nm_file_name = find_a_file (&cpath, nm_suffix);
1152 if (nm_file_name == 0)
1153 nm_file_name = find_a_file (&path, full_nm_suffix);
1156 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1157 if (ldd_file_name == 0)
1158 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1161 #ifdef REAL_STRIP_FILE_NAME
1162 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1163 if (strip_file_name == 0)
1165 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1166 if (strip_file_name == 0)
1167 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1168 if (strip_file_name == 0)
1169 strip_file_name = find_a_file (&cpath, strip_suffix);
1170 if (strip_file_name == 0)
1171 strip_file_name = find_a_file (&path, full_strip_suffix);
1173 /* Determine the full path name of the C compiler to use. */
1174 c_file_name = getenv ("COLLECT_GCC");
1175 if (c_file_name == 0)
1177 #ifdef CROSS_COMPILE
1178 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1179 strcpy (c_file_name, target_machine);
1180 strcat (c_file_name, "-gcc");
1182 c_file_name = "gcc";
1186 p = find_a_file (&cpath, c_file_name);
1188 /* Here it should be safe to use the system search path since we should have
1189 already qualified the name of the compiler when it is needed. */
1191 p = find_a_file (&path, c_file_name);
1196 *ld1++ = *ld2++ = ld_file_name;
1198 /* Make temp file names. */
1199 choose_temp_base ();
1200 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1201 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1202 export_file = xmalloc (temp_filename_length + sizeof (".x"));
1203 ldout = xmalloc (temp_filename_length + sizeof (".ld"));
1204 sprintf (ldout, "%s.ld", temp_filename);
1205 sprintf (c_file, "%s.c", temp_filename);
1206 sprintf (o_file, "%s.o", temp_filename);
1207 sprintf (export_file, "%s.x", temp_filename);
1208 *c_ptr++ = c_file_name;
1213 /* !!! When GCC calls collect2,
1214 it does not know whether it is calling collect2 or ld.
1215 So collect2 cannot meaningfully understand any options
1216 except those ld understands.
1217 If you propose to make GCC pass some other option,
1218 just imagine what will happen if ld is really ld!!! */
1220 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1221 /* After the first file, put in the c++ rt0. */
1224 while ((arg = *++argv) != (char *)0)
1226 *ld1++ = *ld2++ = arg;
1233 if (!strcmp (arg, "-debug"))
1242 #ifdef COLLECT_EXPORT_LIST
1244 if (!strncmp (arg, "-bE:", 4)
1245 || !strncmp (arg, "-bexport:", 9))
1253 /* place o_file BEFORE this argument! */
1262 output_file = (arg[2] == '\0') ? argv[1] : &arg[2];
1271 if (arg[2] == '\0' && do_collecting)
1273 /* We must strip after the nm run, otherwise C++ linking
1274 won't work. Thus we strip in the second ld run, or
1275 else with strip if there is no second ld run. */
1287 else if ((p = rindex (arg, '.')) != (char *)0
1288 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0))
1293 /* place o_file BEFORE this argument! */
1303 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
1304 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1309 while (*q && *q != ' ') q++;
1310 if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
1311 *c_ptr++ = savestring (p, q - p);
1312 if (strncmp (p, "-shared", sizeof ("shared") - 1) == 0)
1319 /* Tell the linker that we have initializer and finalizer functions. */
1322 #ifdef LD_INIT_SWITCH
1323 *ld2++ = LD_INIT_SWITCH;
1324 *ld2++ = "_GLOBAL__DI";
1326 #ifdef LD_FINI_SWITCH
1327 *ld2++ = LD_FINI_SWITCH;
1328 *ld2++ = "_GLOBAL__DD";
1332 #ifdef COLLECT_EXPORT_LIST
1333 /* The AIX linker will discard static constructors in object files if
1334 nothing else in the file is referenced, so look at them first. */
1335 while (object_lst < object)
1336 scan_prog_file (*object_lst++, PASS_OBJ);
1339 char *buf = alloca (strlen (export_file) + 5);
1340 sprintf (buf, "-bE:%s", export_file);
1343 exportf = fopen (export_file, "w");
1344 if (exportf == (FILE *)0)
1345 fatal_perror ("%s", export_file);
1346 write_export_file (exportf);
1347 if (fclose (exportf))
1348 fatal_perror ("closing %s", export_file);
1353 *object = *c_ptr = *ld1 = *ld2 = (char *)0;
1357 fprintf (stderr, "collect2 version %s", version_string);
1358 #ifdef TARGET_VERSION
1361 fprintf (stderr, "\n");
1367 fprintf (stderr, "ld_file_name = %s\n",
1368 (ld_file_name ? ld_file_name : "not found"));
1369 fprintf (stderr, "c_file_name = %s\n",
1370 (c_file_name ? c_file_name : "not found"));
1371 fprintf (stderr, "nm_file_name = %s\n",
1372 (nm_file_name ? nm_file_name : "not found"));
1374 fprintf (stderr, "ldd_file_name = %s\n",
1375 (ldd_file_name ? ldd_file_name : "not found"));
1377 fprintf (stderr, "strip_file_name = %s\n",
1378 (strip_file_name ? strip_file_name : "not found"));
1379 fprintf (stderr, "c_file = %s\n",
1380 (c_file ? c_file : "not found"));
1381 fprintf (stderr, "o_file = %s\n",
1382 (o_file ? o_file : "not found"));
1384 ptr = getenv ("COLLECT_NAMES");
1386 fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
1388 ptr = getenv ("COLLECT_GCC_OPTIONS");
1390 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1392 ptr = getenv ("COLLECT_GCC");
1394 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1396 ptr = getenv ("COMPILER_PATH");
1398 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1400 ptr = getenv ("LIBRARY_PATH");
1402 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1404 fprintf (stderr, "\n");
1407 /* Load the program, searching all libraries. */
1409 collect_execute ("ld", ld1_argv, ldout);
1414 /* If -r or they'll be run via some other method, don't build the
1415 constructor or destructor list, just return now. */
1416 if (rflag || ! do_collecting)
1419 /* Examine the namelist with nm and search it for static constructors
1420 and destructors to call.
1421 Write the constructor and destructor tables to a .s file and reload. */
1423 scan_prog_file (output_file, PASS_FIRST);
1425 #ifdef SCAN_LIBRARIES
1426 scan_libraries (output_file);
1431 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1432 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1435 if (constructors.number == 0 && destructors.number == 0
1437 /* If we will be running these functions ourselves, we want to emit
1438 stubs into the shared library so that we don't have to relink
1439 dependent programs when we add static objects. */
1444 /* Strip now if it was requested on the command line. */
1447 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1448 strip_argv[0] = strip_file_name;
1449 strip_argv[1] = output_file;
1450 strip_argv[2] = (char *) 0;
1451 fork_execute ("strip", strip_argv);
1456 maybe_unlink(output_file);
1457 outf = fopen (c_file, "w");
1458 if (outf == (FILE *)0)
1459 fatal_perror ("%s", c_file);
1461 write_c_file (outf, c_file);
1464 fatal_perror ("closing %s", c_file);
1466 #ifdef COLLECT_EXPORT_LIST
1469 add_to_list (&exports, initname);
1470 add_to_list (&exports, fininame);
1471 exportf = fopen (export_file, "w");
1472 if (exportf == (FILE *)0)
1473 fatal_perror ("%s", export_file);
1474 write_export_file (exportf);
1475 if (fclose (exportf))
1476 fatal_perror ("closing %s", export_file);
1482 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1483 output_file, c_file);
1484 write_c_file (stderr, "stderr");
1485 fprintf (stderr, "========== end of c_file\n\n");
1486 #ifdef COLLECT_EXPORT_LIST
1487 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1488 write_export_file (stderr);
1489 fprintf (stderr, "========== end of export_file\n\n");
1493 /* Assemble the constructor and destructor tables.
1494 Link the tables in with the rest of the program. */
1496 fork_execute ("gcc", c_argv);
1497 fork_execute ("ld", ld2_argv);
1499 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1500 constructors/destructors in shared libraries. */
1501 scan_prog_file (output_file, PASS_SECOND);
1503 maybe_unlink (c_file);
1504 maybe_unlink (o_file);
1505 maybe_unlink (export_file);
1510 /* Wait for a process to finish, and exit if a non-zero status is found. */
1521 if (WIFSIGNALED (status))
1523 int sig = WTERMSIG (status);
1524 #ifdef NO_SYS_SIGLIST
1525 error ("%s terminated with signal %d %s",
1528 (status & 0200) ? ", core dumped" : "");
1530 error ("%s terminated with signal %d [%s]%s",
1534 (status & 0200) ? ", core dumped" : "");
1540 if (WIFEXITED (status))
1541 return WEXITSTATUS (status);
1550 int ret = collect_wait (prog);
1553 error ("%s returned %d exit status", prog, ret);
1559 /* Fork and execute a program, and wait for the reply. */
1562 collect_execute (prog, argv, redir)
1575 fprintf (stderr, "%s", argv[0]);
1577 fprintf (stderr, "[cannot find %s]", prog);
1579 for (p_argv = &argv[1]; (str = *p_argv) != (char *)0; p_argv++)
1580 fprintf (stderr, " %s", str);
1582 fprintf (stderr, "\n");
1588 /* If we can't find a program we need, complain error. Do this here
1589 since we might not end up needing something that we couldn't find. */
1592 fatal ("cannot find `%s'", prog);
1598 fatal_perror ("fork");
1600 fatal_perror ("vfork");
1604 if (pid == 0) /* child context */
1609 if (freopen (redir, "a", stdout) == NULL)
1610 fatal_perror ("redirecting stdout");
1611 if (freopen (redir, "a", stderr) == NULL)
1612 fatal_perror ("redirecting stderr");
1615 execvp (argv[0], argv);
1616 fatal_perror ("executing %s", prog);
1621 fork_execute (prog, argv)
1625 collect_execute (prog, argv, NULL);
1629 /* Unlink a file unless we are debugging. */
1638 fprintf (stderr, "[Leaving %s]\n", file);
1642 /* Add a name to a linked list. */
1645 add_to_list (head_ptr, name)
1646 struct head *head_ptr;
1650 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1652 static long sequence_number = 0;
1653 strcpy (newid->name, name);
1655 if (head_ptr->first)
1656 head_ptr->last->next = newid;
1658 head_ptr->first = newid;
1660 /* Check for duplicate symbols. */
1661 for (p = head_ptr->first;
1662 strcmp (name, p->name) != 0;
1667 head_ptr->last->next = 0;
1672 newid->sequence = ++sequence_number;
1673 head_ptr->last = newid;
1677 /* Write: `prefix', the names on list LIST, `suffix'. */
1680 write_list (stream, prefix, list)
1687 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1693 write_list_with_asm (stream, prefix, list)
1700 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1701 prefix, list->sequence, list->name);
1706 /* Write out the constructor and destructor tables statically (for a shared
1707 object), along with the functions to execute them. */
1710 write_c_file_stat (stream, name)
1714 char *prefix, *p, *q;
1716 /* Figure out name of output_file, stripping off .so version. */
1717 p = rindex (output_file, '/');
1719 p = (char *) output_file;
1733 if (strncmp (q, ".so", 3) == 0)
1742 /* q points to null at end of the string (or . of the .so version) */
1743 prefix = xmalloc (q - p + 1);
1744 strncpy (prefix, p, q - p);
1746 for (q = prefix; *q; q++)
1750 fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
1751 output_file, prefix);
1753 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1754 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1755 sprintf (initname, INIT_NAME_FORMAT, prefix);
1757 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1758 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1759 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1763 /* Write the tables as C code */
1765 fprintf (stream, "static int count;\n");
1766 fprintf (stream, "typedef void entry_pt();\n");
1767 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1768 fprintf (stream, "void %s() {\n", initname);
1769 if (constructors.number > 0)
1771 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1772 write_list (stream, "\t\t", constructors.first);
1773 fprintf (stream, "\t};\n");
1774 fprintf (stream, "\tentry_pt **p;\n");
1775 fprintf (stream, "\tif (count++ != 0) return;\n");
1776 fprintf (stream, "\tp = ctors + %d;\n", constructors.number);
1777 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1779 fprintf (stream, "}\n");
1780 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1781 fprintf (stream, "void %s() {\n", fininame);
1782 if (destructors.number > 0)
1784 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1785 write_list (stream, "\t\t", destructors.first);
1786 fprintf (stream, "\t};\n");
1787 fprintf (stream, "\tentry_pt **p;\n");
1788 fprintf (stream, "\tif (--count != 0) return;\n");
1789 fprintf (stream, "\tp = dtors;\n");
1790 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1791 destructors.number);
1793 fprintf (stream, "}\n");
1795 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
1796 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
1799 /* Write the constructor/destructor tables. */
1802 write_c_file_glob (stream, name)
1806 /* Write the tables as C code */
1808 fprintf (stream, "typedef void entry_pt();\n\n");
1810 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1812 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1813 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);
1814 write_list (stream, "\t", constructors.first);
1815 fprintf (stream, "\t0\n};\n\n");
1817 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1819 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1820 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number);
1821 write_list (stream, "\t", destructors.first);
1822 fprintf (stream, "\t0\n};\n\n");
1824 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1825 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
1829 write_c_file (stream, name)
1834 write_c_file_stat (stream, name);
1836 write_c_file_glob (stream, name);
1840 write_export_file (stream)
1843 struct id *list = exports.first;
1844 for (; list; list = list->next)
1845 fprintf (stream, "%s\n", list->name);
1848 #ifdef OBJECT_FORMAT_NONE
1850 /* Generic version to scan the name list of the loaded program for
1851 the symbols g++ uses for static constructors and destructors.
1853 The constructor table begins at __CTOR_LIST__ and contains a count
1854 of the number of pointers (or -1 if the constructors are built in a
1855 separate section by the linker), followed by the pointers to the
1856 constructor functions, terminated with a null pointer. The
1857 destructor table has the same format, and begins at __DTOR_LIST__. */
1860 scan_prog_file (prog_name, which_pass)
1862 enum pass which_pass;
1864 void (*int_handler) ();
1865 void (*quit_handler) ();
1873 if (which_pass == PASS_SECOND)
1876 /* If we don't have an `nm', complain. */
1877 if (nm_file_name == 0)
1878 fatal ("cannot find `nm'");
1880 nm_argv[argc++] = nm_file_name;
1881 if (NM_FLAGS[0] != '\0')
1882 nm_argv[argc++] = NM_FLAGS;
1884 nm_argv[argc++] = prog_name;
1885 nm_argv[argc++] = (char *)0;
1887 if (pipe (pipe_fd) < 0)
1888 fatal_perror ("pipe");
1890 inf = fdopen (pipe_fd[0], "r");
1891 if (inf == (FILE *)0)
1892 fatal_perror ("fdopen");
1894 /* Trace if needed. */
1900 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *)0; p_argv++)
1901 fprintf (stderr, " %s", str);
1903 fprintf (stderr, "\n");
1909 /* Spawn child nm on pipe */
1914 fatal_perror ("fork");
1916 fatal_perror ("vfork");
1920 if (pid == 0) /* child context */
1923 if (dup2 (pipe_fd[1], 1) < 0)
1924 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
1926 if (close (pipe_fd[0]) < 0)
1927 fatal_perror ("close (%d)", pipe_fd[0]);
1929 if (close (pipe_fd[1]) < 0)
1930 fatal_perror ("close (%d)", pipe_fd[1]);
1932 execv (nm_file_name, nm_argv);
1933 fatal_perror ("executing %s", nm_file_name);
1936 /* Parent context from here on. */
1937 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
1939 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
1942 if (close (pipe_fd[1]) < 0)
1943 fatal_perror ("close (%d)", pipe_fd[1]);
1946 fprintf (stderr, "\nnm output with constructors/destructors.\n");
1948 /* Read each line of nm output. */
1949 while (fgets (buf, sizeof buf, inf) != (char *)0)
1954 /* If it contains a constructor or destructor name, add the name
1955 to the appropriate list. */
1957 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
1958 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
1965 /* Find the end of the symbol name.
1966 Don't include `|', because Encore nm can tack that on the end. */
1967 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
1973 switch (is_ctor_dtor (name))
1976 if (which_pass != PASS_LIB)
1977 add_to_list (&constructors, name);
1981 if (which_pass != PASS_LIB)
1982 add_to_list (&destructors, name);
1986 if (which_pass != PASS_LIB)
1987 fatal ("init function found in object %s", prog_name);
1988 #ifndef LD_INIT_SWITCH
1989 add_to_list (&constructors, name);
1994 if (which_pass != PASS_LIB)
1995 fatal ("fini function found in object %s", prog_name);
1996 #ifndef LD_FINI_SWITCH
1997 add_to_list (&destructors, name);
2001 default: /* not a constructor or destructor */
2006 fprintf (stderr, "\t%s\n", buf);
2010 fprintf (stderr, "\n");
2012 if (fclose (inf) != 0)
2013 fatal_perror ("fclose of pipe");
2015 do_wait (nm_file_name);
2017 signal (SIGINT, int_handler);
2019 signal (SIGQUIT, quit_handler);
2023 #if SUNOS4_SHARED_LIBRARIES
2025 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2026 that the output file depends upon and their initialization/finalization
2027 routines, if any. */
2032 #include <sys/mman.h>
2033 #include <sys/param.h>
2034 #include <sys/unistd.h>
2035 #include <sys/dir.h>
2037 /* pointers to the object file */
2038 unsigned object; /* address of memory mapped file */
2039 unsigned objsize; /* size of memory mapped to file */
2040 char * code; /* pointer to code segment */
2041 char * data; /* pointer to data segment */
2042 struct nlist *symtab; /* pointer to symbol table */
2043 struct link_dynamic *ld;
2044 struct link_dynamic_2 *ld_2;
2045 struct head libraries;
2047 /* Map the file indicated by NAME into memory and store its address. */
2055 if ((fp = open (name, O_RDONLY)) == -1)
2056 fatal ("unable to open file '%s'", name);
2057 if (fstat (fp, &s) == -1)
2058 fatal ("unable to stat file '%s'", name);
2060 objsize = s.st_size;
2061 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2064 fatal ("unable to mmap file '%s'", name);
2069 /* Helpers for locatelib. */
2071 static char *libname;
2077 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2082 struct direct **d1, **d2;
2084 int i1, i2 = strlen (libname);
2085 char *e1 = (*d1)->d_name + i2;
2086 char *e2 = (*d2)->d_name + i2;
2092 i1 = strtol (e1, &e1, 10);
2093 i2 = strtol (e2, &e2, 10);
2106 /* Given the name NAME of a dynamic dependency, find its pathname and add
2107 it to the list of libraries. */
2115 char buf[MAXPATHLEN];
2123 /* counting elements in array, need 1 extra for null */
2125 ld_rules = (char *) (ld_2->ld_rules + code);
2129 for (; *ld_rules != 0; ld_rules++)
2130 if (*ld_rules == ':')
2132 ld_rules = (char *) (ld_2->ld_rules + code);
2133 ldr = (char *) malloc (strlen (ld_rules) + 1);
2134 strcpy (ldr, ld_rules);
2136 p = getenv ("LD_LIBRARY_PATH");
2141 for (q = p ; *q != 0; q++)
2144 q = (char *) malloc (strlen (p) + 1);
2147 l = (char **) malloc ((cnt + 3) * sizeof (char *));
2152 for (; *ldr != 0; ldr++)
2162 for (; *q != 0; q++)
2169 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2172 *pp++ = "/usr/local/lib";
2176 for (pp = l; *pp != 0 ; pp++)
2178 struct direct **namelist;
2180 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2182 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2183 add_to_list (&libraries, buf);
2185 fprintf (stderr, "%s\n", buf);
2192 fprintf (stderr, "not found\n");
2194 fatal ("dynamic dependency %s not found", name);
2198 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2199 that it depends upon and any constructors or destructors they contain. */
2202 scan_libraries (prog_name)
2205 struct exec *header;
2207 struct link_object *lo;
2208 char buff[MAXPATHLEN];
2211 mapfile (prog_name);
2212 header = (struct exec *)object;
2213 if (N_BADMAG (*header))
2214 fatal ("bad magic number in file '%s'", prog_name);
2215 if (header->a_dynamic == 0)
2218 code = (char *) (N_TXTOFF (*header) + (long) header);
2219 data = (char *) (N_DATOFF (*header) + (long) header);
2220 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2222 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2225 ld = (struct link_dynamic *) (symtab->n_value + code);
2231 ld = (struct link_dynamic *) data;
2236 fprintf (stderr, "dynamic dependencies.\n");
2238 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2239 for (lo = (struct link_object *) ld_2->ld_need; lo;
2240 lo = (struct link_object *) lo->lo_next)
2243 lo = (struct link_object *) ((long) lo + code);
2244 name = (char *) (code + lo->lo_name);
2248 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2249 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2255 fprintf (stderr, "\t%s\n", name);
2256 add_to_list (&libraries, name);
2261 fprintf (stderr, "\n");
2263 /* now iterate through the library list adding their symbols to
2265 for (list = libraries.first; list; list = list->next)
2266 scan_prog_file (list->name, PASS_LIB);
2269 #else /* SUNOS4_SHARED_LIBRARIES */
2272 /* Use the List Dynamic Dependencies program to find shared libraries that
2273 the output file depends upon and their initialization/finalization
2274 routines, if any. */
2277 scan_libraries (prog_name)
2280 static struct head libraries; /* list of shared libraries found */
2282 void (*int_handler) ();
2283 void (*quit_handler) ();
2291 /* If we don't have an `ldd', complain. */
2292 if (ldd_file_name == 0)
2294 error ("cannot find `ldd'");
2298 ldd_argv[argc++] = ldd_file_name;
2299 ldd_argv[argc++] = prog_name;
2300 ldd_argv[argc++] = (char *) 0;
2302 if (pipe (pipe_fd) < 0)
2303 fatal_perror ("pipe");
2305 inf = fdopen (pipe_fd[0], "r");
2306 if (inf == (FILE *) 0)
2307 fatal_perror ("fdopen");
2309 /* Trace if needed. */
2315 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2316 fprintf (stderr, " %s", str);
2318 fprintf (stderr, "\n");
2324 /* Spawn child ldd on pipe */
2329 fatal_perror ("fork");
2331 fatal_perror ("vfork");
2335 if (pid == 0) /* child context */
2338 if (dup2 (pipe_fd[1], 1) < 0)
2339 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
2341 if (close (pipe_fd[0]) < 0)
2342 fatal_perror ("close (%d)", pipe_fd[0]);
2344 if (close (pipe_fd[1]) < 0)
2345 fatal_perror ("close (%d)", pipe_fd[1]);
2347 execv (ldd_file_name, ldd_argv);
2348 fatal_perror ("executing %s", ldd_file_name);
2351 /* Parent context from here on. */
2352 int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
2354 quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
2357 if (close (pipe_fd[1]) < 0)
2358 fatal_perror ("close (%d)", pipe_fd[1]);
2361 fprintf (stderr, "\nldd output with constructors/destructors.\n");
2363 /* Read each line of ldd output. */
2364 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2367 char *name, *end, *p = buf;
2369 /* Extract names of libraries and add to list. */
2370 PARSE_LDD_OUTPUT (p);
2375 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2376 fatal ("dynamic dependency %s not found", buf);
2378 /* Find the end of the symbol name. */
2380 (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
2385 if (access (name, R_OK) == 0)
2386 add_to_list (&libraries, name);
2388 fatal ("unable to open dynamic dependency '%s'", buf);
2391 fprintf (stderr, "\t%s\n", buf);
2394 fprintf (stderr, "\n");
2396 if (fclose (inf) != 0)
2397 fatal_perror ("fclose of pipe");
2399 do_wait (ldd_file_name);
2401 signal (SIGINT, int_handler);
2403 signal (SIGQUIT, quit_handler);
2406 /* now iterate through the library list adding their symbols to
2408 for (list = libraries.first; list; list = list->next)
2409 scan_prog_file (list->name, PASS_LIB);
2412 #endif /* LDD_SUFFIX */
2413 #endif /* SUNOS4_SHARED_LIBRARIES */
2415 #endif /* OBJECT_FORMAT_NONE */
2419 * COFF specific stuff.
2422 #ifdef OBJECT_FORMAT_COFF
2424 #if defined(EXTENDED_COFF)
2425 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2426 # define GCC_SYMENT SYMR
2427 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
2428 # define GCC_SYMINC(X) (1)
2429 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2430 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2432 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2433 # define GCC_SYMENT SYMENT
2434 # define GCC_OK_SYMBOL(X) \
2435 (((X).n_sclass == C_EXT) && \
2436 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
2437 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
2438 # define GCC_SYMINC(X) ((X).n_numaux+1)
2439 # define GCC_SYMZERO(X) 0
2440 # define GCC_CHECK_HDR(X) (1)
2443 extern char *ldgetname ();
2445 /* COFF version to scan the name list of the loaded program for
2446 the symbols g++ uses for static constructors and destructors.
2448 The constructor table begins at __CTOR_LIST__ and contains a count
2449 of the number of pointers (or -1 if the constructors are built in a
2450 separate section by the linker), followed by the pointers to the
2451 constructor functions, terminated with a null pointer. The
2452 destructor table has the same format, and begins at __DTOR_LIST__. */
2455 scan_prog_file (prog_name, which_pass)
2457 enum pass which_pass;
2459 LDFILE *ldptr = NULL;
2460 int sym_index, sym_count;
2462 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2465 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
2466 fatal ("%s: can't open as COFF file", prog_name);
2468 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
2469 fatal ("%s: not a COFF file", prog_name);
2471 if (GCC_CHECK_HDR (ldptr))
2473 sym_count = GCC_SYMBOLS (ldptr);
2474 sym_index = GCC_SYMZERO (ldptr);
2475 while (sym_index < sym_count)
2479 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2481 sym_index += GCC_SYMINC (symbol);
2483 if (GCC_OK_SYMBOL (symbol))
2487 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2488 continue; /* should never happen */
2490 #ifdef XCOFF_DEBUGGING_INFO
2491 /* All AIX function names have a duplicate entry beginning
2497 switch (is_ctor_dtor (name))
2500 add_to_list (&constructors, name);
2501 if (which_pass == PASS_OBJ)
2502 add_to_list (&exports, name);
2506 add_to_list (&destructors, name);
2507 if (which_pass == PASS_OBJ)
2508 add_to_list (&exports, name);
2511 default: /* not a constructor or destructor */
2512 if (which_pass == PASS_OBJ && auto_export)
2513 add_to_list (&exports, name);
2517 #if !defined(EXTENDED_COFF)
2519 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2520 symbol.n_scnum, symbol.n_sclass,
2521 (symbol.n_type ? "0" : ""), symbol.n_type,
2525 fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
2526 symbol.iss, symbol.value, symbol.index, name);
2532 (void) ldclose(ldptr);
2535 #endif /* OBJECT_FORMAT_COFF */
2539 * OSF/rose specific stuff.
2542 #ifdef OBJECT_FORMAT_ROSE
2544 /* Union of the various load commands */
2546 typedef union load_union
2548 ldc_header_t hdr; /* common header */
2549 load_cmd_map_command_t map; /* map indexing other load cmds */
2550 interpreter_command_t iprtr; /* interpreter pathname */
2551 strings_command_t str; /* load commands strings section */
2552 region_command_t region; /* region load command */
2553 reloc_command_t reloc; /* relocation section */
2554 package_command_t pkg; /* package load command */
2555 symbols_command_t sym; /* symbol sections */
2556 entry_command_t ent; /* program start section */
2557 gen_info_command_t info; /* object information */
2558 func_table_command_t func; /* function constructors/destructors */
2561 /* Structure to point to load command and data section in memory. */
2563 typedef struct load_all
2565 load_union_t *load; /* load command */
2566 char *section; /* pointer to section */
2569 /* Structure to contain information about a file mapped into memory. */
2573 char *start; /* start of map */
2574 char *name; /* filename */
2575 long size; /* size of the file */
2576 long rounded_size; /* size rounded to page boundary */
2577 int fd; /* file descriptor */
2578 int rw; /* != 0 if opened read/write */
2579 int use_mmap; /* != 0 if mmap'ed */
2582 extern int decode_mach_o_hdr ();
2583 extern int encode_mach_o_hdr ();
2585 static void add_func_table PROTO((mo_header_t *, load_all_t *,
2586 symbol_info_t *, int));
2587 static void print_header PROTO((mo_header_t *));
2588 static void print_load_command PROTO((load_union_t*, size_t, int));
2589 static void bad_header PROTO((int));
2590 static struct file_info *read_file PROTO((char *, int, int));
2591 static void end_file PROTO((struct file_info *));
2593 /* OSF/rose specific version to scan the name list of the loaded
2594 program for the symbols g++ uses for static constructors and
2597 The constructor table begins at __CTOR_LIST__ and contains a count
2598 of the number of pointers (or -1 if the constructors are built in a
2599 separate section by the linker), followed by the pointers to the
2600 constructor functions, terminated with a null pointer. The
2601 destructor table has the same format, and begins at __DTOR_LIST__. */
2604 scan_prog_file (prog_name, which_pass)
2606 enum pass which_pass;
2610 load_all_t *load_array;
2611 load_all_t *load_end;
2612 load_all_t *load_cmd;
2613 int symbol_load_cmds;
2619 struct file_info *obj_file;
2621 mo_lcid_t cmd_strings = -1;
2622 symbol_info_t *main_sym = 0;
2623 int rw = (which_pass != PASS_FIRST);
2625 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
2627 fatal_perror ("can't read %s", prog_name);
2629 obj_file = read_file (prog_name, prog_fd, rw);
2630 obj = obj_file->start;
2632 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
2633 if (status != MO_HDR_CONV_SUCCESS)
2634 bad_header (status);
2637 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
2638 since the hardware will automatically swap bytes for us on loading little endian
2641 #ifndef CROSS_COMPILE
2642 if (hdr.moh_magic != MOH_MAGIC_MSB
2643 || hdr.moh_header_version != MOH_HEADER_VERSION
2644 || hdr.moh_byte_order != OUR_BYTE_ORDER
2645 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
2646 || hdr.moh_cpu_type != OUR_CPU_TYPE
2647 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
2648 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
2650 fatal ("incompatibilities between object file & expected values");
2655 print_header (&hdr);
2657 offset = hdr.moh_first_cmd_off;
2658 load_end = load_array
2659 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
2661 /* Build array of load commands, calculating the offsets */
2662 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2664 load_union_t *load_hdr; /* load command header */
2666 load_cmd = load_end++;
2667 load_hdr = (load_union_t *) (obj + offset);
2669 /* If modifying the program file, copy the header. */
2672 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
2673 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
2676 /* null out old command map, because we will rewrite at the end. */
2677 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
2679 cmd_strings = ptr->map.lcm_ld_cmd_strings;
2680 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
2684 load_cmd->load = load_hdr;
2685 if (load_hdr->hdr.ldci_section_off > 0)
2686 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
2689 print_load_command (load_hdr, offset, i);
2691 offset += load_hdr->hdr.ldci_cmd_size;
2694 /* If the last command is the load command map and is not undefined,
2695 decrement the count of load commands. */
2696 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
2699 hdr.moh_n_load_cmds--;
2702 /* Go through and process each symbol table section. */
2703 symbol_load_cmds = 0;
2704 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
2706 load_union_t *load_hdr = load_cmd->load;
2708 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
2714 char *kind = "unknown";
2716 switch (load_hdr->sym.symc_kind)
2718 case SYMC_IMPORTS: kind = "imports"; break;
2719 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
2720 case SYMC_STABS: kind = "stabs"; break;
2723 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
2724 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
2727 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
2730 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
2731 if (str_sect == (char *)0)
2732 fatal ("string section missing");
2734 if (load_cmd->section == (char *)0)
2735 fatal ("section pointer missing");
2737 num_syms = load_hdr->sym.symc_nentries;
2738 for (i = 0; i < num_syms; i++)
2740 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
2741 char *name = sym->si_name.symbol_name + str_sect;
2748 char *n = name + strlen (name) - strlen (NAME__MAIN);
2750 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
2760 switch (is_ctor_dtor (name))
2763 add_to_list (&constructors, name);
2767 add_to_list (&destructors, name);
2770 default: /* not a constructor or destructor */
2776 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
2777 sym->si_type, sym->si_sc_type, sym->si_flags, name);
2782 if (symbol_load_cmds == 0)
2783 fatal ("no symbol table found");
2785 /* Update the program file now, rewrite header and load commands. At present,
2786 we assume that there is enough space after the last load command to insert
2787 one more. Since the first section written out is page aligned, and the
2788 number of load commands is small, this is ok for the present. */
2792 load_union_t *load_map;
2795 if (cmd_strings == -1)
2796 fatal ("no cmd_strings found");
2798 /* Add __main to initializer list.
2799 If we are building a program instead of a shared library, don't
2800 do anything, since in the current version, you cannot do mallocs
2801 and such in the constructors. */
2803 if (main_sym != (symbol_info_t *)0
2804 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
2805 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
2808 fprintf (stderr, "\nUpdating header and load commands.\n\n");
2810 hdr.moh_n_load_cmds++;
2811 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
2813 /* Create new load command map. */
2815 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
2816 (int)hdr.moh_n_load_cmds, (long)size);
2818 load_map = (load_union_t *) xcalloc (1, size);
2819 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
2820 load_map->map.ldc_header.ldci_cmd_size = size;
2821 load_map->map.lcm_ld_cmd_strings = cmd_strings;
2822 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
2823 load_array[hdr.moh_n_load_cmds-1].load = load_map;
2825 offset = hdr.moh_first_cmd_off;
2826 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2828 load_map->map.lcm_map[i] = offset;
2829 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
2830 hdr.moh_load_map_cmd_off = offset;
2832 offset += load_array[i].load->hdr.ldci_cmd_size;
2835 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
2838 print_header (&hdr);
2841 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
2842 if (status != MO_HDR_CONV_SUCCESS)
2843 bad_header (status);
2846 fprintf (stderr, "writing load commands.\n\n");
2848 /* Write load commands */
2849 offset = hdr.moh_first_cmd_off;
2850 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2852 load_union_t *load_hdr = load_array[i].load;
2853 size_t size = load_hdr->hdr.ldci_cmd_size;
2856 print_load_command (load_hdr, offset, i);
2858 bcopy ((char *)load_hdr, (char *)(obj + offset), size);
2863 end_file (obj_file);
2865 if (close (prog_fd))
2866 fatal_perror ("closing %s", prog_name);
2869 fprintf (stderr, "\n");
2873 /* Add a function table to the load commands to call a function
2874 on initiation or termination of the process. */
2877 add_func_table (hdr_p, load_array, sym, type)
2878 mo_header_t *hdr_p; /* pointer to global header */
2879 load_all_t *load_array; /* array of ptrs to load cmds */
2880 symbol_info_t *sym; /* pointer to symbol entry */
2881 int type; /* fntc_type value */
2883 /* Add a new load command. */
2884 int num_cmds = ++hdr_p->moh_n_load_cmds;
2885 int load_index = num_cmds - 1;
2886 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
2887 load_union_t *ptr = xcalloc (1, size);
2888 load_all_t *load_cmd;
2891 /* Set the unresolved address bit in the header to force the loader to be
2892 used, since kernel exec does not call the initialization functions. */
2893 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
2895 load_cmd = &load_array[load_index];
2896 load_cmd->load = ptr;
2897 load_cmd->section = (char *)0;
2899 /* Fill in func table load command. */
2900 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
2901 ptr->func.ldc_header.ldci_cmd_size = size;
2902 ptr->func.ldc_header.ldci_section_off = 0;
2903 ptr->func.ldc_header.ldci_section_len = 0;
2904 ptr->func.fntc_type = type;
2905 ptr->func.fntc_nentries = 1;
2907 /* copy address, turn it from abs. address to (region,offset) if necessary. */
2908 /* Is the symbol already expressed as (region, offset)? */
2909 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
2911 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
2912 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
2915 /* If not, figure out which region it's in. */
2918 mo_vm_addr_t addr = sym->si_value.abs_val;
2921 for (i = 0; i < load_index; i++)
2923 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
2925 region_command_t *region_ptr = &load_array[i].load->region;
2927 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
2928 && addr >= region_ptr->regc_addr.vm_addr
2929 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
2931 ptr->func.fntc_entry_loc[0].adr_lcid = i;
2932 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
2940 fatal ("could not convert 0x%l.8x into a region", addr);
2945 "%s function, region %d, offset = %ld (0x%.8lx)\n",
2946 (type == FNTC_INITIALIZATION) ? "init" : "term",
2947 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
2948 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
2949 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
2954 /* Print the global header for an OSF/rose object. */
2957 print_header (hdr_ptr)
2958 mo_header_t *hdr_ptr;
2960 fprintf (stderr, "\nglobal header:\n");
2961 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
2962 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
2963 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
2964 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
2965 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
2966 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
2967 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
2968 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
2969 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
2970 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
2971 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
2972 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
2973 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
2974 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
2975 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
2977 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
2978 fprintf (stderr, ", relocatable");
2980 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
2981 fprintf (stderr, ", linkable");
2983 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
2984 fprintf (stderr, ", execable");
2986 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
2987 fprintf (stderr, ", executable");
2989 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
2990 fprintf (stderr, ", unresolved");
2992 fprintf (stderr, "\n\n");
2997 /* Print a short summary of a load command. */
3000 print_load_command (load_hdr, offset, number)
3001 load_union_t *load_hdr;
3005 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3006 char *type_str = (char *)0;
3010 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3011 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3012 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3013 case LDC_STRINGS: type_str = "STRINGS"; break;
3014 case LDC_REGION: type_str = "REGION"; break;
3015 case LDC_RELOC: type_str = "RELOC"; break;
3016 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3017 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3018 case LDC_ENTRY: type_str = "ENTRY"; break;
3019 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3020 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3024 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3026 (long) load_hdr->hdr.ldci_cmd_size,
3028 (long) load_hdr->hdr.ldci_section_off,
3029 (long) load_hdr->hdr.ldci_section_len);
3031 if (type_str == (char *)0)
3032 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3034 else if (type != LDC_REGION)
3035 fprintf (stderr, ", ty: %s\n", type_str);
3040 switch (load_hdr->region.regc_usage_type)
3042 case REG_TEXT_T: region = ", .text"; break;
3043 case REG_DATA_T: region = ", .data"; break;
3044 case REG_BSS_T: region = ", .bss"; break;
3045 case REG_GLUE_T: region = ", .glue"; break;
3046 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3047 case REG_RDATA_T: region = ", .rdata"; break;
3048 case REG_SDATA_T: region = ", .sdata"; break;
3049 case REG_SBSS_T: region = ", .sbss"; break;
3053 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3055 (long) load_hdr->region.regc_vm_addr,
3056 (long) load_hdr->region.regc_vm_size,
3064 /* Fatal error when {en,de}code_mach_o_header fails. */
3070 char *msg = (char *)0;
3074 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
3075 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
3076 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
3077 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
3078 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
3079 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
3082 if (msg == (char *)0)
3083 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3089 /* Read a file into a memory buffer. */
3091 static struct file_info *
3092 read_file (name, fd, rw)
3093 char *name; /* filename */
3094 int fd; /* file descriptor */
3095 int rw; /* read/write */
3097 struct stat stat_pkt;
3098 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3100 static int page_size;
3103 if (fstat (fd, &stat_pkt) < 0)
3104 fatal_perror ("fstat %s", name);
3107 p->size = stat_pkt.st_size;
3108 p->rounded_size = stat_pkt.st_size;
3114 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3117 page_size = sysconf (_SC_PAGE_SIZE);
3119 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3120 p->start = mmap ((caddr_t)0,
3121 (rw) ? p->rounded_size : p->size,
3122 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3123 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3127 if (p->start != (char *)0 && p->start != (char *)-1)
3131 #endif /* USE_MMAP */
3136 fprintf (stderr, "read %s\n", name);
3139 p->start = xmalloc (p->size);
3140 if (lseek (fd, 0L, SEEK_SET) < 0)
3141 fatal_perror ("lseek to 0 on %s", name);
3143 len = read (fd, p->start, p->size);
3145 fatal_perror ("read %s", name);
3148 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3154 /* Do anything necessary to write a file back from memory. */
3158 struct file_info *ptr; /* file information block */
3166 fprintf (stderr, "msync %s\n", ptr->name);
3168 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3169 fatal_perror ("msync %s", ptr->name);
3173 fprintf (stderr, "munmap %s\n", ptr->name);
3175 if (munmap (ptr->start, ptr->size))
3176 fatal_perror ("munmap %s", ptr->name);
3179 #endif /* USE_MMAP */
3186 fprintf (stderr, "write %s\n", ptr->name);
3188 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3189 fatal_perror ("lseek to 0 on %s", ptr->name);
3191 len = write (ptr->fd, ptr->start, ptr->size);
3193 fatal_perror ("read %s", ptr->name);
3195 if (len != ptr->size)
3196 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3205 #endif /* OBJECT_FORMAT_ROSE */