1 /* Collect static initialization info into data structures
2 that can be traversed by C++ initialization and finalization
5 Copyright (C) 1992 Free Software Foundation, Inc.
6 Contributed by Chris Smith (csmith@convex.com).
7 Heavily modified by Michael Meissner (meissner@osf.org),
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>
66 /* On MSDOS, write temp files in current dir
67 because there's no place else we can expect to use. */
74 /* On certain systems, we have code that works by scanning the object file
75 directly. But this code uses system-specific header files and library
76 functions, so turn it off in a cross-compiler. Likewise, the names of
77 the utilities aren't correct for a cross-compiler; we have to hope that
78 cross-versions are in the proper directories. */
81 #undef OBJECT_FORMAT_COFF
82 #undef OBJECT_FORMAT_ROSE
84 #undef REAL_LD_FILE_NAME
85 #undef REAL_NM_FILE_NAME
86 #undef REAL_STRIP_FILE_NAME
89 /* If we can't use a special method, use the ordinary one:
90 run nm to find what symbols are present.
91 In a cross-compiler, this means you need a cross nm,
92 but that isn't quite as unpleasant as special headers. */
94 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
95 #define OBJECT_FORMAT_NONE
98 #ifdef OBJECT_FORMAT_COFF
107 /* Many versions of ldfcn.h define these. */
115 /* Some systems have an ISCOFF macro, but others do not. In some cases
116 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
117 that either do not have an ISCOFF macro in /usr/include or for those
118 where it is wrong. */
121 #define MY_ISCOFF(X) ISCOFF (X)
124 #endif /* OBJECT_FORMAT_COFF */
126 #ifdef OBJECT_FORMAT_ROSE
133 #include <sys/mman.h>
137 #include <mach_o_format.h>
138 #include <mach_o_header.h>
139 #include <mach_o_vals.h>
140 #include <mach_o_types.h>
142 #endif /* OBJECT_FORMAT_ROSE */
144 #ifdef OBJECT_FORMAT_NONE
146 /* Default flags to pass to nm. */
148 #define NM_FLAGS "-p"
151 #endif /* OBJECT_FORMAT_NONE */
153 /* Linked lists of constructor and destructor names. */
169 /* Enumeration giving which pass this is for scanning the program file. */
172 PASS_FIRST, /* without constructors */
173 PASS_SECOND /* with constructors linked in */
176 #ifndef NO_SYS_SIGLIST
177 extern char *sys_siglist[];
179 extern char *version_string;
181 static int vflag; /* true if -v */
182 static int rflag; /* true if -r */
183 static int strip_flag; /* true if -s */
185 static int debug; /* true if -debug */
187 static int temp_filename_length; /* Length of temp_filename */
188 static char *temp_filename; /* Base of temp filenames */
189 static char *c_file; /* <xxx>.c for constructor/destructor list. */
190 static char *o_file; /* <xxx>.o for constructor/destructor list. */
191 static char *output_file; /* Output file for ld. */
192 static char *nm_file_name; /* pathname of nm */
193 static char *strip_file_name; /* pathname of strip */
195 static struct head constructors; /* list of constructors found */
196 static struct head destructors; /* list of destructors found */
198 extern char *getenv ();
199 extern char *mktemp ();
200 static void add_to_list ();
201 static void scan_prog_file ();
202 static void fork_execute ();
203 static void do_wait ();
204 static void write_c_file ();
205 static void my_exit ();
206 static void handler ();
207 static void maybe_unlink ();
208 static void choose_temp_base ();
213 extern char *index ();
214 extern char *rindex ();
228 while ((fd = dup (oldfd)) != newfd) /* good enough for low fd's */
231 close (fdtmp[--fdx]);
239 extern char *sys_errlist[];
241 static char buffer[30];
246 if (e > 0 && e < sys_nerr)
247 return sys_errlist[e];
249 sprintf (buffer, "Unknown error %d", e);
253 /* Delete tempfiles and exit function. */
259 if (c_file != 0 && c_file[0])
260 maybe_unlink (c_file);
262 if (o_file != 0 && o_file[0])
263 maybe_unlink (o_file);
265 if (status != 0 && output_file != 0 && output_file[0])
266 maybe_unlink (output_file);
272 /* Die when sys call fails. */
275 fatal_perror (string, arg1, arg2, arg3)
280 fprintf (stderr, "collect2: ");
281 fprintf (stderr, string, arg1, arg2, arg3);
282 fprintf (stderr, ": %s\n", my_strerror (e));
289 fatal (string, arg1, arg2, arg3)
292 fprintf (stderr, "collect2: ");
293 fprintf (stderr, string, arg1, arg2, arg3);
294 fprintf (stderr, "\n");
298 /* Write error message. */
301 error (string, arg1, arg2, arg3, arg4)
304 fprintf (stderr, "collect2: ");
305 fprintf (stderr, string, arg1, arg2, arg3, arg4);
306 fprintf (stderr, "\n");
309 /* In case obstack is linked in, and abort is defined to fancy_abort,
310 provide a default entry. */
315 fatal ("internal error");
324 maybe_unlink (c_file);
327 maybe_unlink (o_file);
329 signal (signo, SIG_DFL);
330 kill (getpid (), signo);
335 xcalloc (size1, size2)
338 generic *ptr = (generic *) calloc (size1, size2);
342 fatal ("out of memory");
350 generic *ptr = (generic *) malloc (size);
354 fatal ("out of memory");
358 /* Make a copy of a string INPUT with size SIZE. */
361 savestring (input, size)
365 char *output = (char *) xmalloc (size + 1);
366 bcopy (input, output, size);
371 /* Decide whether the given symbol is:
372 a constructor (1), a destructor (2), or neither (0). */
378 struct names { char *name; int len; int ret; int two_underscores; };
380 register struct names *p;
382 register char *orig_s = s;
384 static struct names special[] = {
385 #ifdef NO_DOLLAR_IN_LABEL
386 #ifdef NO_DOT_IN_LABEL
387 { "___GLOBAL__I_", sizeof ("___GLOBAL__I_")-1, 1, 0 },
388 { "___GLOBAL__D_", sizeof ("___GLOBAL__D_")-1, 2, 0 },
390 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
391 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
394 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
395 { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 },
397 #ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
398 cfront has its own linker procedure to collect them;
399 if collect2 gets them too, they get collected twice
400 when the cfront procedure is run and the compiler used
401 for linking happens to be GCC. */
402 { "sti__", sizeof ("sti__")-1, 1, 1 },
403 { "std__", sizeof ("std__")-1, 2, 1 },
404 #endif /* CFRONT_LOSSAGE */
408 while ((ch = *s) == '_')
414 for (p = &special[0]; p->len > 0; p++)
417 && (!p->two_underscores || ((s - orig_s) >= 2))
418 && strncmp(s, p->name, p->len) == 0)
427 /* Compute a string to use as the base of all temporary file names.
428 It is substituted for %g. */
433 char *base = getenv ("TMPDIR");
436 if (base == (char *)0)
439 if (access (P_tmpdir, R_OK | W_OK) == 0)
442 if (base == (char *)0)
444 if (access ("/usr/tmp", R_OK | W_OK) == 0)
452 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
453 strcpy (temp_filename, base);
454 if (len > 0 && temp_filename[len-1] != '/')
455 temp_filename[len++] = '/';
456 strcpy (temp_filename + len, "ccXXXXXX");
458 mktemp (temp_filename);
459 temp_filename_length = strlen (temp_filename);
462 /* Routine to add variables to the environment. */
469 #ifndef VMS /* nor about VMS */
471 extern char **environ;
472 char **old_environ = environ;
476 int str_len = strlen (str);
480 while ((ch = *p++) != '\0' && ch != '=')
486 /* Search for replacing an existing environment variable, and
487 count the number of total environment variables. */
488 for (envp = old_environ; *envp; envp++)
491 if (!strncmp (str, *envp, name_len))
498 /* Add a new environment variable */
499 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
501 bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1));
506 #endif /* HAVE_PUTENV */
508 /* By default, colon separates directories in a path. */
509 #ifndef PATH_SEPARATOR
510 #define PATH_SEPARATOR ':'
513 /* Structure to hold all the directories in which to search for files to
518 char *prefix; /* String to prepend to the path. */
519 struct prefix_list *next; /* Next in linked list. */
524 struct prefix_list *plist; /* List of prefixes to try */
525 int max_len; /* Max length of a prefix in PLIST */
526 char *name; /* Name of this list (used in config stuff) */
529 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
530 and one from the PATH variable. */
532 static struct path_prefix cpath, path;
535 /* This is the name of the target machine. We use it to form the name
536 of the files to execute. */
538 static char *target_machine = TARGET_MACHINE;
541 /* Names under which we were executed. Never return one of those files in our
544 static char *our_file_name, *last_file_name;
546 /* Search for NAME using prefix list PPREFIX. We only look for executable
549 Return 0 if not found, otherwise return its name, allocated with malloc. */
552 find_a_file (pprefix, name)
553 struct path_prefix *pprefix;
557 struct prefix_list *pl;
558 int len = pprefix->max_len + strlen (name) + 1;
560 #ifdef EXECUTABLE_SUFFIX
561 len += strlen (EXECUTABLE_SUFFIX);
564 temp = xmalloc (len);
566 /* Determine the filename to execute (special case for absolute paths). */
570 if (access (name, X_OK) == 0)
577 for (pl = pprefix->plist; pl; pl = pl->next)
579 strcpy (temp, pl->prefix);
581 if (strcmp (temp, our_file_name) != 0
582 && ! (last_file_name != 0 && strcmp (temp, last_file_name) == 0)
583 /* This is a kludge, but there seems no way around it. */
584 && strcmp (temp, "./ld") != 0
585 && access (temp, X_OK) == 0)
588 #ifdef EXECUTABLE_SUFFIX
589 /* Some systems have a suffix for executable files.
590 So try appending that. */
591 strcat (temp, EXECUTABLE_SUFFIX);
592 if (strcmp (temp, our_file_name) != 0
593 && ! (last_file_name != 0 && strcmp (temp, last_file_name) == 0)
594 && access (temp, X_OK) == 0)
603 /* Add an entry for PREFIX to prefix list PPREFIX. */
606 add_prefix (pprefix, prefix)
607 struct path_prefix *pprefix;
610 struct prefix_list *pl, **prev;
615 for (pl = pprefix->plist; pl->next; pl = pl->next)
620 prev = &pprefix->plist;
622 /* Keep track of the longest prefix */
624 len = strlen (prefix);
625 if (len > pprefix->max_len)
626 pprefix->max_len = len;
628 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
629 pl->prefix = savestring (prefix, len);
634 pl->next = (struct prefix_list *) 0;
638 /* Take the value of the environment variable ENV, break it into a path, and
639 add of the entries to PPREFIX. */
642 prefix_from_env (env, pprefix)
644 struct path_prefix *pprefix;
646 char *p = getenv (env);
651 char *nstore = (char *) xmalloc (strlen (p) + 3);
656 if (*endp == PATH_SEPARATOR || *endp == 0)
658 strncpy (nstore, startp, endp-startp);
661 strcpy (nstore, "./");
663 else if (endp[-1] != '/')
665 nstore[endp-startp] = '/';
666 nstore[endp-startp+1] = 0;
669 nstore[endp-startp] = 0;
671 add_prefix (pprefix, nstore);
674 endp = startp = endp + 1;
689 char *ld_suffix = "ld";
690 char *full_ld_suffix = ld_suffix;
691 char *real_ld_suffix = "real-ld";
692 char *full_real_ld_suffix = real_ld_suffix;
694 char *gld_suffix = "gld";
695 char *full_gld_suffix = gld_suffix;
697 char *nm_suffix = "nm";
698 char *full_nm_suffix = nm_suffix;
699 char *gnm_suffix = "gnm";
700 char *full_gnm_suffix = gnm_suffix;
701 char *strip_suffix = "strip";
702 char *full_strip_suffix = strip_suffix;
703 char *gstrip_suffix = "gstrip";
704 char *full_gstrip_suffix = gstrip_suffix;
712 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+2);
713 char **ld1 = ld1_argv;
714 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+5);
715 char **ld2 = ld2_argv;
717 int num_c_args = argc+7;
726 our_file_name = argv[0];
728 output_file = "a.out";
730 /* We must check that we do not call ourselves in an infinite
731 recursion loop. We save the name used for us in the COLLECT_NAME
732 environment variable, first getting the previous value.
734 To be fully safe, we need to maintain a list of names that name
735 been used, but, in practice, two names are enough. */
737 last_file_name = getenv ("COLLECT_NAME");
739 p = (char *) xcalloc (sizeof (char *),
740 strlen (our_file_name) + strlen ("COLLECT_NAME=") + 1);
741 sprintf (p, "COLLECT_NAME=%s", our_file_name);
744 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
749 while (*q && *q != ' ') q++;
750 if (*p == '-' && p[1] == 'm')
757 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
760 fatal ("no arguments");
763 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
764 signal (SIGQUIT, handler);
766 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
767 signal (SIGINT, handler);
769 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
770 signal (SIGALRM, handler);
773 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
774 signal (SIGHUP, handler);
776 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
777 signal (SIGSEGV, handler);
779 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
780 signal (SIGBUS, handler);
783 /* Extract COMPILER_PATH and PATH into our prefix list. */
784 prefix_from_env ("COMPILER_PATH", &cpath);
785 prefix_from_env ("PATH", &path);
788 /* If we look for a program in the compiler directories, we just use
789 the short name, since these directories are already system-specific.
790 But it we look for a took in the system directories, we need to
791 qualify the program name with the target machine. */
794 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
795 strcpy (full_ld_suffix, target_machine);
796 strcat (full_ld_suffix, "-");
797 strcat (full_ld_suffix, ld_suffix);
800 = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
801 strcpy (full_real_ld_suffix, target_machine);
802 strcat (full_real_ld_suffix, "-");
803 strcat (full_real_ld_suffix, real_ld_suffix);
807 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
808 strcpy (full_gld_suffix, target_machine);
809 strcat (full_gld_suffix, "-");
810 strcat (full_gld_suffix, gld_suffix);
814 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
815 strcpy (full_nm_suffix, target_machine);
816 strcat (full_nm_suffix, "-");
817 strcat (full_nm_suffix, nm_suffix);
820 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
821 strcpy (full_gnm_suffix, target_machine);
822 strcat (full_gnm_suffix, "-");
823 strcat (full_gnm_suffix, gnm_suffix);
826 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
827 strcpy (full_strip_suffix, target_machine);
828 strcat (full_strip_suffix, "-");
829 strcat (full_strip_suffix, strip_suffix);
832 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
833 strcpy (full_gstrip_suffix, target_machine);
834 strcat (full_gstrip_suffix, "-");
835 strcat (full_gstrip_suffix, gstrip_suffix);
836 #endif /* CROSS_COMPILE */
838 /* Try to discover a valid linker/nm/strip to use. */
841 /* Search the (target-specific) compiler dirs for `gld'. */
842 ld_file_name = find_a_file (&cpath, gld_suffix);
843 /* Search the ordinary system bin directories
844 for `gld' (if native linking) or `TARGET-gld' (if cross). */
845 if (ld_file_name == 0)
846 ld_file_name = find_a_file (&path, full_gld_suffix);
850 /* Likewise for `real-ld'. */
851 if (ld_file_name == 0)
852 ld_file_name = find_a_file (&cpath, real_ld_suffix);
853 if (ld_file_name == 0)
854 ld_file_name = find_a_file (&path, full_real_ld_suffix);
855 /* Maybe we know the right file to use (if not cross). */
856 #ifdef REAL_LD_FILE_NAME
857 if (ld_file_name == 0)
858 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
860 if (ld_file_name == 0)
861 ld_file_name = find_a_file (&cpath, full_ld_suffix);
862 /* Search the ordinary system bin directories
863 for `ld' (if native linking) or `TARGET-ld' (if cross). */
864 if (ld_file_name == 0)
865 ld_file_name = find_a_file (&path, full_ld_suffix);
867 nm_file_name = find_a_file (&cpath, gnm_suffix);
868 if (nm_file_name == 0)
869 nm_file_name = find_a_file (&path, full_gnm_suffix);
870 if (nm_file_name == 0)
871 nm_file_name = find_a_file (&cpath, nm_suffix);
872 #ifdef REAL_NM_FILE_NAME
873 if (nm_file_name == 0)
874 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
876 if (nm_file_name == 0)
877 nm_file_name = find_a_file (&path, full_nm_suffix);
879 strip_file_name = find_a_file (&cpath, gstrip_suffix);
880 if (strip_file_name == 0)
881 strip_file_name = find_a_file (&path, full_gstrip_suffix);
882 if (strip_file_name == 0)
883 strip_file_name = find_a_file (&cpath, strip_suffix);
884 #ifdef REAL_STRIP_FILE_NAME
885 if (strip_file_name == 0)
886 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
888 if (strip_file_name == 0)
889 strip_file_name = find_a_file (&path, full_strip_suffix);
891 /* Determine the full path name of the C compiler to use. */
892 c_file_name = getenv ("COLLECT_GCC");
893 if (c_file_name == 0)
896 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
897 strcpy (c_file_name, target_machine);
898 strcat (c_file_name, "-gcc");
904 p = find_a_file (&cpath, c_file_name);
906 /* Here it should be safe to use the system search path since we should have
907 already qualified the name of the compiler when it is needed. */
909 p = find_a_file (&path, c_file_name);
914 *ld1++ = *ld2++ = ld_file_name;
916 /* Make temp file names. */
918 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
919 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
920 sprintf (c_file, "%s.c", temp_filename);
921 sprintf (o_file, "%s.o", temp_filename);
922 *c_ptr++ = c_file_name;
927 /* !!! When GCC calls collect2,
928 it does not know whether it is calling collect2 or ld.
929 So collect2 cannot meaningfully understand any options
930 except those ld understands.
931 If you propose to make GCC pass some other option,
932 just imagine what will happen if ld is really ld!!! */
934 /* Parse arguments. Remember output file spec, pass the rest to ld. */
935 /* After the first file, put in the c++ rt0. */
938 while ((arg = *++argv) != (char *)0)
940 *ld1++ = *ld2++ = arg;
946 if (!strcmp (arg, "-debug"))
956 output_file = (arg[2] == '\0') ? argv[1] : &arg[2];
967 /* We must strip after the nm run, otherwise C++ linking
968 won't work. Thus we strip in the second ld run, or
969 else with strip if there is no second ld run. */
982 && (p = rindex (arg, '.')) != (char *)0
983 && strcmp (p, ".o") == 0)
990 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
991 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
996 while (*q && *q != ' ') q++;
997 if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
998 *c_ptr++ = savestring (p, q - p);
1005 *c_ptr = *ld1 = *ld2 = (char *)0;
1009 fprintf (stderr, "collect2 version %s", version_string);
1010 #ifdef TARGET_VERSION
1013 fprintf (stderr, "\n");
1019 fprintf (stderr, "ld_file_name = %s\n",
1020 (ld_file_name ? ld_file_name : "not found"));
1021 fprintf (stderr, "c_file_name = %s\n",
1022 (c_file_name ? c_file_name : "not found"));
1023 fprintf (stderr, "nm_file_name = %s\n",
1024 (nm_file_name ? nm_file_name : "not found"));
1025 fprintf (stderr, "strip_file_name = %s\n",
1026 (strip_file_name ? strip_file_name : "not found"));
1027 fprintf (stderr, "c_file = %s\n",
1028 (c_file ? c_file : "not found"));
1029 fprintf (stderr, "o_file = %s\n",
1030 (o_file ? o_file : "not found"));
1032 ptr = getenv ("COLLECT_GCC_OPTIONS");
1034 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1036 ptr = getenv ("COLLECT_GCC");
1038 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1040 ptr = getenv ("COMPILER_PATH");
1042 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1044 ptr = getenv ("LIBRARY_PATH");
1046 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1048 fprintf (stderr, "\n");
1051 /* Load the program, searching all libraries.
1052 Examine the namelist with nm and search it for static constructors
1053 and destructors to call.
1054 Write the constructor and destructor tables to a .s file and reload. */
1056 fork_execute ("ld", ld1_argv);
1058 /* If -r, don't build the constructor or destructor list, just return now. */
1062 scan_prog_file (output_file, PASS_FIRST);
1066 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1067 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1070 if (constructors.number == 0 && destructors.number == 0)
1072 /* Strip now if it was requested on the command line. */
1075 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1076 strip_argv[0] = strip_file_name;
1077 strip_argv[1] = output_file;
1078 strip_argv[2] = (char *) 0;
1079 fork_execute ("strip", strip_argv);
1084 outf = fopen (c_file, "w");
1085 if (outf == (FILE *)0)
1086 fatal_perror ("%s", c_file);
1088 write_c_file (outf, c_file);
1091 fatal_perror ("closing %s", c_file);
1095 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1096 output_file, c_file);
1097 write_c_file (stderr, "stderr");
1098 fprintf (stderr, "========== end of c_file\n\n");
1101 /* Assemble the constructor and destructor tables.
1102 Link the tables in with the rest of the program. */
1104 fork_execute ("gcc", c_argv);
1105 fork_execute ("ld", ld2_argv);
1107 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1108 constructors/destructors in shared libraries. */
1109 scan_prog_file (output_file, PASS_SECOND);
1111 maybe_unlink (c_file);
1112 maybe_unlink (o_file);
1117 /* Wait for a process to finish, and exit if a non-zero status is found. */
1128 int sig = status & 0x7F;
1131 if (sig != -1 && sig != 0)
1133 #ifdef NO_SYS_SIGLIST
1134 error ("%s terminated with signal %d %s",
1137 (status & 0200) ? ", core dumped" : "");
1139 error ("%s terminated with signal %d [%s]%s",
1143 (status & 0200) ? ", core dumped" : "");
1149 ret = ((status & 0xFF00) >> 8);
1150 if (ret != -1 && ret != 0)
1152 error ("%s returned %d exit status", prog, ret);
1159 /* Fork and execute a program, and wait for the reply. */
1162 fork_execute (prog, argv)
1174 fprintf (stderr, "%s", argv[0]);
1176 fprintf (stderr, "[cannot find %s]", prog);
1178 for (p_argv = &argv[1]; (str = *p_argv) != (char *)0; p_argv++)
1179 fprintf (stderr, " %s", str);
1181 fprintf (stderr, "\n");
1187 /* If we can't find a program we need, complain error. Do this here
1188 since we might not end up needing something that we couldn't find. */
1191 fatal ("cannot find `%s'", prog);
1197 fatal_perror ("fork");
1199 fatal_perror ("vfork");
1203 if (pid == 0) /* child context */
1205 execvp (argv[0], argv);
1206 fatal_perror ("executing %s", prog);
1213 /* Unlink a file unless we are debugging. */
1222 fprintf (stderr, "[Leaving %s]\n", file);
1226 /* Add a name to a linked list. */
1229 add_to_list (head_ptr, name)
1230 struct head *head_ptr;
1233 struct id *newid = (struct id *) xcalloc (sizeof (*newid) + strlen (name), 1);
1234 static long sequence_number = 0;
1235 newid->sequence = ++sequence_number;
1236 strcpy (newid->name, name);
1238 if (head_ptr->first)
1239 head_ptr->last->next = newid;
1241 head_ptr->first = newid;
1243 head_ptr->last = newid;
1247 /* Write: `prefix', the names on list LIST, `suffix'. */
1250 write_list (stream, prefix, list)
1257 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1263 write_list_with_asm (stream, prefix, list)
1270 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1271 prefix, list->sequence, list->name);
1276 /* Write the constructor/destructor tables. */
1279 write_c_file (stream, name)
1283 /* Write the tables as C code */
1285 fprintf (stream, "typedef void entry_pt();\n\n");
1287 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1289 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1290 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);
1291 write_list (stream, "\t", constructors.first);
1292 fprintf (stream, "\t0\n};\n\n");
1294 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1296 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1297 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number);
1298 write_list (stream, "\t", destructors.first);
1299 fprintf (stream, "\t0\n};\n\n");
1301 fprintf (stream, "extern entry_pt __main;\n");
1302 fprintf (stream, "entry_pt *__main_reference = __main;\n\n");
1306 #ifdef OBJECT_FORMAT_NONE
1308 /* Generic version to scan the name list of the loaded program for
1309 the symbols g++ uses for static constructors and destructors.
1311 The constructor table begins at __CTOR_LIST__ and contains a count
1312 of the number of pointers (or -1 if the constructors are built in a
1313 separate section by the linker), followed by the pointers to the
1314 constructor functions, terminated with a null pointer. The
1315 destructor table has the same format, and begins at __DTOR_LIST__. */
1318 scan_prog_file (prog_name, which_pass)
1320 enum pass which_pass;
1322 void (*int_handler) ();
1323 void (*quit_handler) ();
1331 if (which_pass != PASS_FIRST)
1334 /* If we don't have an `nm', complain. */
1335 if (nm_file_name == 0)
1336 fatal ("cannot find `nm'");
1338 nm_argv[argc++] = "nm";
1339 if (NM_FLAGS[0] != '\0')
1340 nm_argv[argc++] = NM_FLAGS;
1342 nm_argv[argc++] = prog_name;
1343 nm_argv[argc++] = (char *)0;
1345 if (pipe (pipe_fd) < 0)
1346 fatal_perror ("pipe");
1348 inf = fdopen (pipe_fd[0], "r");
1349 if (inf == (FILE *)0)
1350 fatal_perror ("fdopen");
1352 /* Trace if needed. */
1358 fprintf (stderr, "%s", nm_file_name);
1359 for (p_argv = &nm_argv[1]; (str = *p_argv) != (char *)0; p_argv++)
1360 fprintf (stderr, " %s", str);
1362 fprintf (stderr, "\n");
1368 /* Spawn child nm on pipe */
1373 fatal_perror ("fork");
1375 fatal_perror ("vfork");
1379 if (pid == 0) /* child context */
1382 if (dup2 (pipe_fd[1], 1) < 0)
1383 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
1385 if (close (pipe_fd[0]) < 0)
1386 fatal_perror ("close (%d)", pipe_fd[0]);
1388 if (close (pipe_fd[1]) < 0)
1389 fatal_perror ("close (%d)", pipe_fd[1]);
1391 execv (nm_file_name, nm_argv);
1392 fatal_perror ("executing %s", nm_file_name);
1395 /* Parent context from here on. */
1396 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
1398 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
1401 if (close (pipe_fd[1]) < 0)
1402 fatal_perror ("close (%d)", pipe_fd[1]);
1405 fprintf (stderr, "\nnm output with constructors/destructors.\n");
1407 /* Read each line of nm output. */
1408 while (fgets (buf, sizeof buf, inf) != (char *)0)
1413 /* If it contains a constructor or destructor name, add the name
1414 to the appropriate list. */
1416 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
1419 if (ch == '\0' || ch == '\n')
1423 /* Find the end of the symbol name.
1424 Don't include `|', because Encore nm can tack that on the end. */
1425 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
1430 switch (is_ctor_dtor (name))
1433 add_to_list (&constructors, name);
1437 add_to_list (&destructors, name);
1440 default: /* not a constructor or destructor */
1445 fprintf (stderr, "\t%s\n", buf);
1449 fprintf (stderr, "\n");
1451 if (fclose (inf) != 0)
1452 fatal_perror ("fclose of pipe");
1454 do_wait (nm_file_name);
1456 signal (SIGINT, int_handler);
1458 signal (SIGQUIT, quit_handler);
1462 #endif /* OBJECT_FORMAT_NONE */
1466 * COFF specific stuff.
1469 #ifdef OBJECT_FORMAT_COFF
1471 #if defined(EXTENDED_COFF)
1472 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
1473 # define GCC_SYMENT SYMR
1474 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
1475 # define GCC_SYMINC(X) (1)
1476 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
1477 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
1479 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
1480 # define GCC_SYMENT SYMENT
1481 # define GCC_OK_SYMBOL(X) \
1482 (((X).n_sclass == C_EXT) && \
1483 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
1484 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
1485 # define GCC_SYMINC(X) ((X).n_numaux+1)
1486 # define GCC_SYMZERO(X) 0
1487 # define GCC_CHECK_HDR(X) (1)
1490 extern char *ldgetname ();
1492 /* COFF version to scan the name list of the loaded program for
1493 the symbols g++ uses for static constructors and destructors.
1495 The constructor table begins at __CTOR_LIST__ and contains a count
1496 of the number of pointers (or -1 if the constructors are built in a
1497 separate section by the linker), followed by the pointers to the
1498 constructor functions, terminated with a null pointer. The
1499 destructor table has the same format, and begins at __DTOR_LIST__. */
1502 scan_prog_file (prog_name, which_pass)
1504 enum pass which_pass;
1506 LDFILE *ldptr = NULL;
1507 int sym_index, sym_count;
1509 if (which_pass != PASS_FIRST)
1512 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
1513 fatal ("%s: can't open as COFF file", prog_name);
1515 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
1516 fatal ("%s: not a COFF file", prog_name);
1518 if (GCC_CHECK_HDR (ldptr))
1520 sym_count = GCC_SYMBOLS (ldptr);
1521 sym_index = GCC_SYMZERO (ldptr);
1522 while (sym_index < sym_count)
1526 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
1528 sym_index += GCC_SYMINC (symbol);
1530 if (GCC_OK_SYMBOL (symbol))
1534 if ((name = ldgetname (ldptr, &symbol)) == NULL)
1535 continue; /* should never happen */
1538 /* All AIX function names begin with a dot. */
1543 switch (is_ctor_dtor (name))
1546 add_to_list (&constructors, name);
1550 add_to_list (&destructors, name);
1553 default: /* not a constructor or destructor */
1557 #if !defined(EXTENDED_COFF)
1559 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
1560 symbol.n_scnum, symbol.n_sclass,
1561 (symbol.n_type ? "0" : ""), symbol.n_type,
1565 fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1566 symbol.iss, symbol.value, symbol.index, name);
1572 (void) ldclose(ldptr);
1575 #endif /* OBJECT_FORMAT_COFF */
1579 * OSF/rose specific stuff.
1582 #ifdef OBJECT_FORMAT_ROSE
1584 /* Union of the various load commands */
1586 typedef union load_union
1588 ldc_header_t hdr; /* common header */
1589 load_cmd_map_command_t map; /* map indexing other load cmds */
1590 interpreter_command_t iprtr; /* interpreter pathname */
1591 strings_command_t str; /* load commands strings section */
1592 region_command_t region; /* region load command */
1593 reloc_command_t reloc; /* relocation section */
1594 package_command_t pkg; /* package load command */
1595 symbols_command_t sym; /* symbol sections */
1596 entry_command_t ent; /* program start section */
1597 gen_info_command_t info; /* object information */
1598 func_table_command_t func; /* function constructors/destructors */
1601 /* Structure to point to load command and data section in memory. */
1603 typedef struct load_all
1605 load_union_t *load; /* load command */
1606 char *section; /* pointer to section */
1609 /* Structure to contain information about a file mapped into memory. */
1613 char *start; /* start of map */
1614 char *name; /* filename */
1615 long size; /* size of the file */
1616 long rounded_size; /* size rounded to page boundary */
1617 int fd; /* file descriptor */
1618 int rw; /* != 0 if opened read/write */
1619 int use_mmap; /* != 0 if mmap'ed */
1622 extern int decode_mach_o_hdr ();
1624 extern int encode_mach_o_hdr ();
1626 static void bad_header ();
1628 static void print_header ();
1630 static void print_load_command ();
1632 static void add_func_table ();
1634 static struct file_info *read_file ();
1636 static void end_file ();
1639 /* OSF/rose specific version to scan the name list of the loaded
1640 program for the symbols g++ uses for static constructors and
1643 The constructor table begins at __CTOR_LIST__ and contains a count
1644 of the number of pointers (or -1 if the constructors are built in a
1645 separate section by the linker), followed by the pointers to the
1646 constructor functions, terminated with a null pointer. The
1647 destructor table has the same format, and begins at __DTOR_LIST__. */
1650 scan_prog_file (prog_name, which_pass)
1652 enum pass which_pass;
1656 load_all_t *load_array;
1657 load_all_t *load_end;
1658 load_all_t *load_cmd;
1659 int symbol_load_cmds;
1665 struct file_info *obj_file;
1667 mo_lcid_t cmd_strings = -1;
1668 symbol_info_t *main_sym = 0;
1669 int rw = (which_pass != PASS_FIRST);
1671 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
1673 fatal_perror ("can't read %s", prog_name);
1675 obj_file = read_file (prog_name, prog_fd, rw);
1676 obj = obj_file->start;
1678 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
1679 if (status != MO_HDR_CONV_SUCCESS)
1680 bad_header (status);
1683 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
1684 since the hardware will automatically swap bytes for us on loading little endian
1687 #ifndef CROSS_COMPILE
1688 if (hdr.moh_magic != MOH_MAGIC_MSB
1689 || hdr.moh_header_version != MOH_HEADER_VERSION
1690 || hdr.moh_byte_order != OUR_BYTE_ORDER
1691 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
1692 || hdr.moh_cpu_type != OUR_CPU_TYPE
1693 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
1694 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
1696 fatal ("incompatibilities between object file & expected values");
1701 print_header (&hdr);
1703 offset = hdr.moh_first_cmd_off;
1704 load_end = load_array
1705 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
1707 /* Build array of load commands, calculating the offsets */
1708 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1710 load_union_t *load_hdr; /* load command header */
1712 load_cmd = load_end++;
1713 load_hdr = (load_union_t *) (obj + offset);
1715 /* If modifying the program file, copy the header. */
1718 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
1719 bcopy ((generic *)load_hdr, (generic *)ptr, load_hdr->hdr.ldci_cmd_size);
1722 /* null out old command map, because we will rewrite at the end. */
1723 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
1725 cmd_strings = ptr->map.lcm_ld_cmd_strings;
1726 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
1730 load_cmd->load = load_hdr;
1731 if (load_hdr->hdr.ldci_section_off > 0)
1732 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
1735 print_load_command (load_hdr, offset, i);
1737 offset += load_hdr->hdr.ldci_cmd_size;
1740 /* If the last command is the load command map and is not undefined,
1741 decrement the count of load commands. */
1742 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
1745 hdr.moh_n_load_cmds--;
1748 /* Go through and process each symbol table section. */
1749 symbol_load_cmds = 0;
1750 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
1752 load_union_t *load_hdr = load_cmd->load;
1754 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
1760 char *kind = "unknown";
1762 switch (load_hdr->sym.symc_kind)
1764 case SYMC_IMPORTS: kind = "imports"; break;
1765 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
1766 case SYMC_STABS: kind = "stabs"; break;
1769 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1770 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
1773 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
1776 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
1777 if (str_sect == (char *)0)
1778 fatal ("string section missing");
1780 if (load_cmd->section == (char *)0)
1781 fatal ("section pointer missing");
1783 num_syms = load_hdr->sym.symc_nentries;
1784 for (i = 0; i < num_syms; i++)
1786 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
1787 char *name = sym->si_name.symbol_name + str_sect;
1797 if (*n != 'm' || (n - name) < 2 || strcmp (n, "main"))
1804 switch (is_ctor_dtor (name))
1807 add_to_list (&constructors, name);
1811 add_to_list (&destructors, name);
1814 default: /* not a constructor or destructor */
1820 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
1821 sym->si_type, sym->si_sc_type, sym->si_flags, name);
1826 if (symbol_load_cmds == 0)
1827 fatal ("no symbol table found");
1829 /* Update the program file now, rewrite header and load commands. At present,
1830 we assume that there is enough space after the last load command to insert
1831 one more. Since the first section written out is page aligned, and the
1832 number of load commands is small, this is ok for the present. */
1836 load_union_t *load_map;
1839 if (cmd_strings == -1)
1840 fatal ("no cmd_strings found");
1842 /* Add __main to initializer list.
1843 If we are building a program instead of a shared library, don't
1844 do anything, since in the current version, you cannot do mallocs
1845 and such in the constructors. */
1847 if (main_sym != (symbol_info_t *)0
1848 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
1849 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
1852 fprintf (stderr, "\nUpdating header and load commands.\n\n");
1854 hdr.moh_n_load_cmds++;
1855 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
1857 /* Create new load command map. */
1859 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
1860 (int)hdr.moh_n_load_cmds, (long)size);
1862 load_map = (load_union_t *) xcalloc (1, size);
1863 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
1864 load_map->map.ldc_header.ldci_cmd_size = size;
1865 load_map->map.lcm_ld_cmd_strings = cmd_strings;
1866 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
1867 load_array[hdr.moh_n_load_cmds-1].load = load_map;
1869 offset = hdr.moh_first_cmd_off;
1870 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1872 load_map->map.lcm_map[i] = offset;
1873 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
1874 hdr.moh_load_map_cmd_off = offset;
1876 offset += load_array[i].load->hdr.ldci_cmd_size;
1879 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
1882 print_header (&hdr);
1885 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
1886 if (status != MO_HDR_CONV_SUCCESS)
1887 bad_header (status);
1890 fprintf (stderr, "writing load commands.\n\n");
1892 /* Write load commands */
1893 offset = hdr.moh_first_cmd_off;
1894 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1896 load_union_t *load_hdr = load_array[i].load;
1897 size_t size = load_hdr->hdr.ldci_cmd_size;
1900 print_load_command (load_hdr, offset, i);
1902 bcopy ((generic *)load_hdr, (generic *)(obj + offset), size);
1907 end_file (obj_file);
1909 if (close (prog_fd))
1910 fatal_perror ("closing %s", prog_name);
1913 fprintf (stderr, "\n");
1917 /* Add a function table to the load commands to call a function
1918 on initiation or termination of the process. */
1921 add_func_table (hdr_p, load_array, sym, type)
1922 mo_header_t *hdr_p; /* pointer to global header */
1923 load_all_t *load_array; /* array of ptrs to load cmds */
1924 symbol_info_t *sym; /* pointer to symbol entry */
1925 int type; /* fntc_type value */
1927 /* Add a new load command. */
1928 int num_cmds = ++hdr_p->moh_n_load_cmds;
1929 int load_index = num_cmds - 1;
1930 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
1931 load_union_t *ptr = xcalloc (1, size);
1932 load_all_t *load_cmd;
1935 /* Set the unresolved address bit in the header to force the loader to be
1936 used, since kernel exec does not call the initialization functions. */
1937 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
1939 load_cmd = &load_array[load_index];
1940 load_cmd->load = ptr;
1941 load_cmd->section = (char *)0;
1943 /* Fill in func table load command. */
1944 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
1945 ptr->func.ldc_header.ldci_cmd_size = size;
1946 ptr->func.ldc_header.ldci_section_off = 0;
1947 ptr->func.ldc_header.ldci_section_len = 0;
1948 ptr->func.fntc_type = type;
1949 ptr->func.fntc_nentries = 1;
1951 /* copy address, turn it from abs. address to (region,offset) if necessary. */
1952 /* Is the symbol already expressed as (region, offset)? */
1953 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
1955 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
1956 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
1959 /* If not, figure out which region it's in. */
1962 mo_vm_addr_t addr = sym->si_value.abs_val;
1965 for (i = 0; i < load_index; i++)
1967 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
1969 region_command_t *region_ptr = &load_array[i].load->region;
1971 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
1972 && addr >= region_ptr->regc_addr.vm_addr
1973 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
1975 ptr->func.fntc_entry_loc[0].adr_lcid = i;
1976 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
1984 fatal ("could not convert 0x%l.8x into a region", addr);
1989 "%s function, region %d, offset = %ld (0x%.8lx)\n",
1990 (type == FNTC_INITIALIZATION) ? "init" : "term",
1991 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
1992 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
1993 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
1998 /* Print the global header for an OSF/rose object. */
2001 print_header (hdr_ptr)
2002 mo_header_t *hdr_ptr;
2004 fprintf (stderr, "\nglobal header:\n");
2005 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
2006 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
2007 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
2008 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
2009 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
2010 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
2011 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
2012 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
2013 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
2014 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
2015 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
2016 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
2017 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
2018 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
2019 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
2021 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
2022 fprintf (stderr, ", relocatable");
2024 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
2025 fprintf (stderr, ", linkable");
2027 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
2028 fprintf (stderr, ", execable");
2030 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
2031 fprintf (stderr, ", executable");
2033 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
2034 fprintf (stderr, ", unresolved");
2036 fprintf (stderr, "\n\n");
2041 /* Print a short summary of a load command. */
2044 print_load_command (load_hdr, offset, number)
2045 load_union_t *load_hdr;
2049 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
2050 char *type_str = (char *)0;
2054 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
2055 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
2056 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
2057 case LDC_STRINGS: type_str = "STRINGS"; break;
2058 case LDC_REGION: type_str = "REGION"; break;
2059 case LDC_RELOC: type_str = "RELOC"; break;
2060 case LDC_PACKAGE: type_str = "PACKAGE"; break;
2061 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
2062 case LDC_ENTRY: type_str = "ENTRY"; break;
2063 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
2064 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
2068 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
2070 (long) load_hdr->hdr.ldci_cmd_size,
2072 (long) load_hdr->hdr.ldci_section_off,
2073 (long) load_hdr->hdr.ldci_section_len);
2075 if (type_str == (char *)0)
2076 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
2078 else if (type != LDC_REGION)
2079 fprintf (stderr, ", ty: %s\n", type_str);
2084 switch (load_hdr->region.regc_usage_type)
2086 case REG_TEXT_T: region = ", .text"; break;
2087 case REG_DATA_T: region = ", .data"; break;
2088 case REG_BSS_T: region = ", .bss"; break;
2089 case REG_GLUE_T: region = ", .glue"; break;
2090 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
2091 case REG_RDATA_T: region = ", .rdata"; break;
2092 case REG_SDATA_T: region = ", .sdata"; break;
2093 case REG_SBSS_T: region = ", .sbss"; break;
2097 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
2099 (long) load_hdr->region.regc_vm_addr,
2100 (long) load_hdr->region.regc_vm_size,
2108 /* Fatal error when {en,de}code_mach_o_header fails. */
2114 char *msg = (char *)0;
2118 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
2119 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
2120 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
2121 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
2122 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
2123 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
2126 if (msg == (char *)0)
2127 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
2133 /* Read a file into a memory buffer. */
2135 static struct file_info *
2136 read_file (name, fd, rw)
2137 char *name; /* filename */
2138 int fd; /* file descriptor */
2139 int rw; /* read/write */
2141 struct stat stat_pkt;
2142 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
2144 static int page_size;
2147 if (fstat (fd, &stat_pkt) < 0)
2148 fatal_perror ("fstat %s", name);
2151 p->size = stat_pkt.st_size;
2152 p->rounded_size = stat_pkt.st_size;
2158 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
2161 page_size = sysconf (_SC_PAGE_SIZE);
2163 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
2164 p->start = mmap ((caddr_t)0,
2165 (rw) ? p->rounded_size : p->size,
2166 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
2167 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
2171 if (p->start != (char *)0 && p->start != (char *)-1)
2175 #endif /* USE_MMAP */
2180 fprintf (stderr, "read %s\n", name);
2183 p->start = xmalloc (p->size);
2184 if (lseek (fd, 0L, SEEK_SET) < 0)
2185 fatal_perror ("lseek to 0 on %s", name);
2187 len = read (fd, p->start, p->size);
2189 fatal_perror ("read %s", name);
2192 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
2199 /* Do anything necessary to write a file back from memory. */
2203 struct file_info *ptr; /* file information block */
2211 fprintf (stderr, "msync %s\n", ptr->name);
2213 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
2214 fatal_perror ("msync %s", ptr->name);
2218 fprintf (stderr, "munmap %s\n", ptr->name);
2220 if (munmap (ptr->start, ptr->size))
2221 fatal_perror ("munmap %s", ptr->name);
2224 #endif /* USE_MMAP */
2231 fprintf (stderr, "write %s\n", ptr->name);
2233 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
2234 fatal_perror ("lseek to 0 on %s", ptr->name);
2236 len = write (ptr->fd, ptr->start, ptr->size);
2238 fatal_perror ("read %s", ptr->name);
2240 if (len != ptr->size)
2241 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
2244 free ((generic *)ptr->start);
2247 free ((generic *)ptr);
2250 #endif /* OBJECT_FORMAT_ROSE */