(arm_reload_out_hi): Rewrite. Add support for processors running in
[official-gcc.git] / gcc / collect2.c
blobff83c9d7965f5b5079eca8f25f80fdec8cf314d0
1 /* Collect static initialization info into data structures
2 that can be traversed by C++ initialization and finalization
3 routines.
5 Copyright (C) 1992, 1993, 1994 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)
15 any later version.
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>
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <errno.h>
33 #include <signal.h>
34 #include <sys/file.h>
35 #include <sys/stat.h>
36 #ifdef NO_WAIT_H
37 #include <sys/wait.h>
38 #endif
40 #ifndef errno
41 extern int errno;
42 #endif
44 #if defined(bsd4_4)
45 extern const char *const sys_errlist[];
46 #else
47 extern char *sys_errlist[];
48 #endif
49 extern int sys_nerr;
51 #define COLLECT
53 #include "config.h"
55 #ifndef __STDC__
56 #define generic char
57 #define const
59 #else
60 #define generic void
61 #endif
63 #ifdef USG
64 #define vfork fork
65 #endif
67 /* Add prototype support. */
68 #ifndef PROTO
69 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
70 #define PROTO(ARGS) ARGS
71 #else
72 #define PROTO(ARGS) ()
73 #endif
74 #endif
76 #ifndef R_OK
77 #define R_OK 4
78 #define W_OK 2
79 #define X_OK 1
80 #endif
82 /* On MSDOS, write temp files in current dir
83 because there's no place else we can expect to use. */
84 #ifdef __MSDOS__
85 #ifndef P_tmpdir
86 #define P_tmpdir "./"
87 #endif
88 #endif
90 /* On certain systems, we have code that works by scanning the object file
91 directly. But this code uses system-specific header files and library
92 functions, so turn it off in a cross-compiler. Likewise, the names of
93 the utilities aren't correct for a cross-compiler; we have to hope that
94 cross-versions are in the proper directories. */
96 #ifdef CROSS_COMPILE
97 #undef OBJECT_FORMAT_COFF
98 #undef OBJECT_FORMAT_ROSE
99 #undef MD_EXEC_PREFIX
100 #undef REAL_LD_FILE_NAME
101 #undef REAL_NM_FILE_NAME
102 #undef REAL_STRIP_FILE_NAME
103 #endif
105 /* If we can't use a special method, use the ordinary one:
106 run nm to find what symbols are present.
107 In a cross-compiler, this means you need a cross nm,
108 but that isn't quite as unpleasant as special headers. */
110 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
111 #define OBJECT_FORMAT_NONE
112 #endif
114 #ifdef OBJECT_FORMAT_COFF
116 #include <a.out.h>
117 #include <ar.h>
119 #ifdef UMAX
120 #include <sgs.h>
121 #endif
123 /* Many versions of ldfcn.h define these. */
124 #ifdef FREAD
125 #undef FREAD
126 #undef FWRITE
127 #endif
129 #include <ldfcn.h>
131 /* Some systems have an ISCOFF macro, but others do not. In some cases
132 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
133 that either do not have an ISCOFF macro in /usr/include or for those
134 where it is wrong. */
136 #ifndef MY_ISCOFF
137 #define MY_ISCOFF(X) ISCOFF (X)
138 #endif
140 #endif /* OBJECT_FORMAT_COFF */
142 #ifdef OBJECT_FORMAT_ROSE
144 #ifdef _OSF_SOURCE
145 #define USE_MMAP
146 #endif
148 #ifdef USE_MMAP
149 #include <sys/mman.h>
150 #endif
152 #include <unistd.h>
153 #include <mach_o_format.h>
154 #include <mach_o_header.h>
155 #include <mach_o_vals.h>
156 #include <mach_o_types.h>
158 #endif /* OBJECT_FORMAT_ROSE */
160 #ifdef OBJECT_FORMAT_NONE
162 /* Default flags to pass to nm. */
163 #ifndef NM_FLAGS
164 #define NM_FLAGS "-p"
165 #endif
167 #endif /* OBJECT_FORMAT_NONE */
169 /* Some systems use __main in a way incompatible with its use in gcc, in these
170 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
171 give the same symbol without quotes for an alternative entry point. You
172 must define both, or niether. */
173 #ifndef NAME__MAIN
174 #define NAME__MAIN "__main"
175 #define SYMBOL__MAIN __main
176 #endif
179 /* Linked lists of constructor and destructor names. */
181 struct id
183 struct id *next;
184 int sequence;
185 char name[1];
188 struct head
190 struct id *first;
191 struct id *last;
192 int number;
195 /* Enumeration giving which pass this is for scanning the program file. */
197 enum pass {
198 PASS_FIRST, /* without constructors */
199 PASS_SECOND /* with constructors linked in */
202 #ifndef NO_SYS_SIGLIST
203 #ifndef DONT_DECLARE_SYS_SIGLIST
204 extern char *sys_siglist[];
205 #endif
206 #endif
207 extern char *version_string;
209 static int vflag; /* true if -v */
210 static int rflag; /* true if -r */
211 static int strip_flag; /* true if -s */
213 static int debug; /* true if -debug */
215 static int temp_filename_length; /* Length of temp_filename */
216 static char *temp_filename; /* Base of temp filenames */
217 static char *c_file; /* <xxx>.c for constructor/destructor list. */
218 static char *o_file; /* <xxx>.o for constructor/destructor list. */
219 static char *output_file; /* Output file for ld. */
220 static char *nm_file_name; /* pathname of nm */
221 static char *strip_file_name; /* pathname of strip */
223 static struct head constructors; /* list of constructors found */
224 static struct head destructors; /* list of destructors found */
226 extern char *getenv ();
227 extern char *mktemp ();
228 extern FILE *fdopen ();
230 /* Structure to hold all the directories in which to search for files to
231 execute. */
233 struct prefix_list
235 char *prefix; /* String to prepend to the path. */
236 struct prefix_list *next; /* Next in linked list. */
239 struct path_prefix
241 struct prefix_list *plist; /* List of prefixes to try */
242 int max_len; /* Max length of a prefix in PLIST */
243 char *name; /* Name of this list (used in config stuff) */
246 static void my_exit PROTO((int));
247 static void handler PROTO((int));
248 static int is_ctor_dtor PROTO((char *));
249 static void choose_temp_base PROTO((void));
250 static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
251 static char *find_a_file PROTO((struct path_prefix *, char *));
252 static void add_prefix PROTO((struct path_prefix *, char *));
253 static void prefix_from_env PROTO((char *, struct path_prefix *));
254 static void do_wait PROTO((char *));
255 static void fork_execute PROTO((char *, char **));
256 static void maybe_unlink PROTO((char *));
257 static void add_to_list PROTO((struct head *, char *));
258 static void write_list PROTO((FILE *, char *, struct id *));
259 static void write_list_with_asm PROTO((FILE *, char *, struct id *));
260 static void write_c_file PROTO((FILE *, char *));
261 static void scan_prog_file PROTO((char *, enum pass));
263 generic *xcalloc ();
264 generic *xmalloc ();
266 extern char *index ();
267 extern char *rindex ();
269 #ifdef NO_DUP2
271 dup2 (oldfd, newfd)
272 int oldfd;
273 int newfd;
275 int fdtmp[256];
276 int fdx = 0;
277 int fd;
279 if (oldfd == newfd)
280 return oldfd;
281 close (newfd);
282 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
283 fdtmp[fdx++] = fd;
284 while (fdx > 0)
285 close (fdtmp[--fdx]);
287 return fd;
289 #endif
291 char *
292 my_strerror (e)
293 int e;
295 static char buffer[30];
297 if (!e)
298 return "";
300 if (e > 0 && e < sys_nerr)
301 return sys_errlist[e];
303 sprintf (buffer, "Unknown error %d", e);
304 return buffer;
307 /* Delete tempfiles and exit function. */
309 static void
310 my_exit (status)
311 int status;
313 if (c_file != 0 && c_file[0])
314 maybe_unlink (c_file);
316 if (o_file != 0 && o_file[0])
317 maybe_unlink (o_file);
319 if (status != 0 && output_file != 0 && output_file[0])
320 maybe_unlink (output_file);
322 exit (status);
326 /* Die when sys call fails. */
328 static void
329 fatal_perror (string, arg1, arg2, arg3)
330 char *string;
332 int e = errno;
334 fprintf (stderr, "collect2: ");
335 fprintf (stderr, string, arg1, arg2, arg3);
336 fprintf (stderr, ": %s\n", my_strerror (e));
337 my_exit (1);
340 /* Just die. */
342 static void
343 fatal (string, arg1, arg2, arg3)
344 char *string;
346 fprintf (stderr, "collect2: ");
347 fprintf (stderr, string, arg1, arg2, arg3);
348 fprintf (stderr, "\n");
349 my_exit (1);
352 /* Write error message. */
354 static void
355 error (string, arg1, arg2, arg3, arg4)
356 char *string;
358 fprintf (stderr, "collect2: ");
359 fprintf (stderr, string, arg1, arg2, arg3, arg4);
360 fprintf (stderr, "\n");
363 /* In case obstack is linked in, and abort is defined to fancy_abort,
364 provide a default entry. */
366 void
367 fancy_abort ()
369 fatal ("internal error");
373 static void
374 handler (signo)
375 int signo;
377 if (c_file != 0 && c_file[0])
378 maybe_unlink (c_file);
380 if (o_file != 0 && o_file[0])
381 maybe_unlink (o_file);
383 signal (signo, SIG_DFL);
384 kill (getpid (), signo);
388 generic *
389 xcalloc (size1, size2)
390 int size1, size2;
392 generic *ptr = (generic *) calloc (size1, size2);
393 if (ptr)
394 return ptr;
396 fatal ("out of memory");
397 return (generic *)0;
400 generic *
401 xmalloc (size)
402 int size;
404 generic *ptr = (generic *) malloc (size);
405 if (ptr)
406 return ptr;
408 fatal ("out of memory");
409 return (generic *)0;
412 /* Make a copy of a string INPUT with size SIZE. */
414 char *
415 savestring (input, size)
416 char *input;
417 int size;
419 char *output = (char *) xmalloc (size + 1);
420 bcopy (input, output, size);
421 output[size] = 0;
422 return output;
425 /* Decide whether the given symbol is:
426 a constructor (1), a destructor (2), or neither (0). */
428 static int
429 is_ctor_dtor (s)
430 char *s;
432 struct names { char *name; int len; int ret; int two_underscores; };
434 register struct names *p;
435 register int ch;
436 register char *orig_s = s;
438 static struct names special[] = {
439 #ifdef NO_DOLLAR_IN_LABEL
440 #ifdef NO_DOT_IN_LABEL
441 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
442 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
443 #else
444 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
445 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
446 #endif
447 #else
448 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
449 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
450 #endif
451 #ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
452 cfront has its own linker procedure to collect them;
453 if collect2 gets them too, they get collected twice
454 when the cfront procedure is run and the compiler used
455 for linking happens to be GCC. */
456 { "sti__", sizeof ("sti__")-1, 1, 1 },
457 { "std__", sizeof ("std__")-1, 2, 1 },
458 #endif /* CFRONT_LOSSAGE */
459 { NULL, 0, 0, 0 }
462 while ((ch = *s) == '_')
463 ++s;
465 if (s == orig_s)
466 return 0;
468 for (p = &special[0]; p->len > 0; p++)
470 if (ch == p->name[0]
471 && (!p->two_underscores || ((s - orig_s) >= 2))
472 && strncmp(s, p->name, p->len) == 0)
474 return p->ret;
477 return 0;
481 /* Compute a string to use as the base of all temporary file names.
482 It is substituted for %g. */
484 static void
485 choose_temp_base ()
487 char *base = getenv ("TMPDIR");
488 int len;
490 if (base == (char *)0)
492 #ifdef P_tmpdir
493 if (access (P_tmpdir, R_OK | W_OK) == 0)
494 base = P_tmpdir;
495 #endif
496 if (base == (char *)0)
498 if (access ("/usr/tmp", R_OK | W_OK) == 0)
499 base = "/usr/tmp/";
500 else
501 base = "/tmp/";
505 len = strlen (base);
506 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
507 strcpy (temp_filename, base);
508 if (len > 0 && temp_filename[len-1] != '/')
509 temp_filename[len++] = '/';
510 strcpy (temp_filename + len, "ccXXXXXX");
512 mktemp (temp_filename);
513 temp_filename_length = strlen (temp_filename);
516 /* Routine to add variables to the environment. */
518 #ifndef HAVE_PUTENV
521 putenv (str)
522 char *str;
524 #ifndef VMS /* nor about VMS */
526 extern char **environ;
527 char **old_environ = environ;
528 char **envp;
529 int num_envs = 0;
530 int name_len = 1;
531 char *p = str;
532 int ch;
534 while ((ch = *p++) != '\0' && ch != '=')
535 name_len++;
537 if (!ch)
538 abort ();
540 /* Search for replacing an existing environment variable, and
541 count the number of total environment variables. */
542 for (envp = old_environ; *envp; envp++)
544 num_envs++;
545 if (!strncmp (str, *envp, name_len))
547 *envp = str;
548 return 0;
552 /* Add a new environment variable */
553 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
554 *environ = str;
555 bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1));
556 return 0;
557 #endif /* VMS */
560 #endif /* HAVE_PUTENV */
562 /* By default, colon separates directories in a path. */
563 #ifndef PATH_SEPARATOR
564 #define PATH_SEPARATOR ':'
565 #endif
567 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
568 and one from the PATH variable. */
570 static struct path_prefix cpath, path;
572 #ifdef CROSS_COMPILE
573 /* This is the name of the target machine. We use it to form the name
574 of the files to execute. */
576 static char *target_machine = TARGET_MACHINE;
577 #endif
579 /* Names under which we were executed. Never return one of those files in our
580 searches. */
582 static struct path_prefix our_file_names;
584 /* Determine if STRING is in PPREFIX.
586 This utility is currently only used to look up file names. Prefix lists
587 record directory names. This matters to us because the latter has a
588 trailing slash, so I've added a flag to handle both. */
590 static int
591 is_in_prefix_list (pprefix, string, filep)
592 struct path_prefix *pprefix;
593 char *string;
594 int filep;
596 struct prefix_list *pl;
598 if (filep)
600 int len = strlen (string);
602 for (pl = pprefix->plist; pl; pl = pl->next)
604 if (strncmp (pl->prefix, string, len) == 0
605 && strcmp (pl->prefix + len, "/") == 0)
606 return 1;
609 else
611 for (pl = pprefix->plist; pl; pl = pl->next)
613 if (strcmp (pl->prefix, string) == 0)
614 return 1;
618 return 0;
621 /* Search for NAME using prefix list PPREFIX. We only look for executable
622 files.
624 Return 0 if not found, otherwise return its name, allocated with malloc. */
626 static char *
627 find_a_file (pprefix, name)
628 struct path_prefix *pprefix;
629 char *name;
631 char *temp;
632 struct prefix_list *pl;
633 int len = pprefix->max_len + strlen (name) + 1;
635 #ifdef EXECUTABLE_SUFFIX
636 len += strlen (EXECUTABLE_SUFFIX);
637 #endif
639 temp = xmalloc (len);
641 /* Determine the filename to execute (special case for absolute paths). */
643 if (*name == '/')
645 if (access (name, X_OK) == 0)
647 strcpy (temp, name);
648 return temp;
651 else
652 for (pl = pprefix->plist; pl; pl = pl->next)
654 strcpy (temp, pl->prefix);
655 strcat (temp, name);
656 if (! is_in_prefix_list (&our_file_names, temp, 1)
657 /* This is a kludge, but there seems no way around it. */
658 && strcmp (temp, "./ld") != 0
659 && access (temp, X_OK) == 0)
660 return temp;
662 #ifdef EXECUTABLE_SUFFIX
663 /* Some systems have a suffix for executable files.
664 So try appending that. */
665 strcat (temp, EXECUTABLE_SUFFIX);
666 if (! is_in_prefix_list (&our_file_names, temp, 1)
667 && access (temp, X_OK) == 0)
668 return temp;
669 #endif
672 free (temp);
673 return 0;
676 /* Add an entry for PREFIX to prefix list PPREFIX. */
678 static void
679 add_prefix (pprefix, prefix)
680 struct path_prefix *pprefix;
681 char *prefix;
683 struct prefix_list *pl, **prev;
684 int len;
686 if (pprefix->plist)
688 for (pl = pprefix->plist; pl->next; pl = pl->next)
690 prev = &pl->next;
692 else
693 prev = &pprefix->plist;
695 /* Keep track of the longest prefix */
697 len = strlen (prefix);
698 if (len > pprefix->max_len)
699 pprefix->max_len = len;
701 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
702 pl->prefix = savestring (prefix, len);
704 if (*prev)
705 pl->next = *prev;
706 else
707 pl->next = (struct prefix_list *) 0;
708 *prev = pl;
711 /* Take the value of the environment variable ENV, break it into a path, and
712 add of the entries to PPREFIX. */
714 static void
715 prefix_from_env (env, pprefix)
716 char *env;
717 struct path_prefix *pprefix;
719 char *p = getenv (env);
721 if (p)
723 char *startp, *endp;
724 char *nstore = (char *) xmalloc (strlen (p) + 3);
726 startp = endp = p;
727 while (1)
729 if (*endp == PATH_SEPARATOR || *endp == 0)
731 strncpy (nstore, startp, endp-startp);
732 if (endp == startp)
734 strcpy (nstore, "./");
736 else if (endp[-1] != '/')
738 nstore[endp-startp] = '/';
739 nstore[endp-startp+1] = 0;
741 else
742 nstore[endp-startp] = 0;
744 add_prefix (pprefix, nstore);
745 if (*endp == 0)
746 break;
747 endp = startp = endp + 1;
749 else
750 endp++;
755 /* Main program. */
758 main (argc, argv)
759 int argc;
760 char *argv[];
762 char *ld_suffix = "ld";
763 char *full_ld_suffix = ld_suffix;
764 char *real_ld_suffix = "real-ld";
765 char *full_real_ld_suffix = real_ld_suffix;
766 #if 0
767 char *gld_suffix = "gld";
768 char *full_gld_suffix = gld_suffix;
769 #endif
770 char *nm_suffix = "nm";
771 char *full_nm_suffix = nm_suffix;
772 char *gnm_suffix = "gnm";
773 char *full_gnm_suffix = gnm_suffix;
774 char *strip_suffix = "strip";
775 char *full_strip_suffix = strip_suffix;
776 char *gstrip_suffix = "gstrip";
777 char *full_gstrip_suffix = gstrip_suffix;
778 char *arg;
779 FILE *outf;
780 char *ld_file_name;
781 char *c_file_name;
782 char *collect_name;
783 char *collect_names;
784 char *p;
785 char **c_argv;
786 char **c_ptr;
787 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+2);
788 char **ld1 = ld1_argv;
789 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+5);
790 char **ld2 = ld2_argv;
791 int first_file;
792 int num_c_args = argc+7;
794 #ifdef DEBUG
795 debug = 1;
796 vflag = 1;
797 #endif
799 output_file = "a.out";
801 /* We must check that we do not call ourselves in an infinite
802 recursion loop. We append the name used for us to the COLLECT_NAMES
803 environment variable.
805 In practice, collect will rarely invoke itself. This can happen now
806 that we are no longer called gld. A perfect example is when running
807 gcc in a build directory that has been installed. When looking for
808 ld's, we'll find our installed version and believe that's the real ld. */
810 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
811 previous version of collect (the one that used COLLECT_NAME and only
812 handled two levels of recursion). If we don't we may mutually recurse
813 forever. This can happen (I think) when bootstrapping the old version
814 and a new one is installed (rare, but we should handle it).
815 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
817 collect_name = (char *) getenv ("COLLECT_NAME");
818 collect_names = (char *) getenv ("COLLECT_NAMES");
820 p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
821 + (collect_name ? strlen (collect_name) + 1 : 0)
822 + (collect_names ? strlen (collect_names) + 1 : 0)
823 + strlen (argv[0]) + 1);
824 strcpy (p, "COLLECT_NAMES=");
825 if (collect_name != 0)
826 sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
827 if (collect_names != 0)
828 sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
829 strcat (p, argv[0]);
830 putenv (p);
832 prefix_from_env ("COLLECT_NAMES", &our_file_names);
834 /* Set environment variable COLLECT_NAME to our name so the previous version
835 of collect won't find us. If it does we'll mutually recurse forever.
836 This can happen when bootstrapping the new version and an old version is
837 installed.
838 ??? Hopefully this bit of code can be removed at some point. */
840 p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
841 sprintf (p, "COLLECT_NAME=%s", argv[0]);
842 putenv (p);
844 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
845 if (p)
846 while (*p)
848 char *q = p;
849 while (*q && *q != ' ') q++;
850 if (*p == '-' && p[1] == 'm')
851 num_c_args++;
853 if (*q) q++;
854 p = q;
857 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
859 if (argc < 2)
860 fatal ("no arguments");
862 #ifdef SIGQUIT
863 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
864 signal (SIGQUIT, handler);
865 #endif
866 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
867 signal (SIGINT, handler);
868 #ifdef SIGALRM
869 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
870 signal (SIGALRM, handler);
871 #endif
872 #ifdef SIGHUP
873 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
874 signal (SIGHUP, handler);
875 #endif
876 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
877 signal (SIGSEGV, handler);
878 #ifdef SIGBUS
879 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
880 signal (SIGBUS, handler);
881 #endif
883 /* Extract COMPILER_PATH and PATH into our prefix list. */
884 prefix_from_env ("COMPILER_PATH", &cpath);
885 prefix_from_env ("PATH", &path);
887 #ifdef CROSS_COMPILE
888 /* If we look for a program in the compiler directories, we just use
889 the short name, since these directories are already system-specific.
890 But it we look for a took in the system directories, we need to
891 qualify the program name with the target machine. */
893 full_ld_suffix
894 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
895 strcpy (full_ld_suffix, target_machine);
896 strcat (full_ld_suffix, "-");
897 strcat (full_ld_suffix, ld_suffix);
899 full_real_ld_suffix
900 = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
901 strcpy (full_real_ld_suffix, target_machine);
902 strcat (full_real_ld_suffix, "-");
903 strcat (full_real_ld_suffix, real_ld_suffix);
905 #if 0
906 full_gld_suffix
907 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
908 strcpy (full_gld_suffix, target_machine);
909 strcat (full_gld_suffix, "-");
910 strcat (full_gld_suffix, gld_suffix);
911 #endif
913 full_nm_suffix
914 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
915 strcpy (full_nm_suffix, target_machine);
916 strcat (full_nm_suffix, "-");
917 strcat (full_nm_suffix, nm_suffix);
919 full_gnm_suffix
920 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
921 strcpy (full_gnm_suffix, target_machine);
922 strcat (full_gnm_suffix, "-");
923 strcat (full_gnm_suffix, gnm_suffix);
925 full_strip_suffix
926 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
927 strcpy (full_strip_suffix, target_machine);
928 strcat (full_strip_suffix, "-");
929 strcat (full_strip_suffix, strip_suffix);
931 full_gstrip_suffix
932 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
933 strcpy (full_gstrip_suffix, target_machine);
934 strcat (full_gstrip_suffix, "-");
935 strcat (full_gstrip_suffix, gstrip_suffix);
936 #endif /* CROSS_COMPILE */
938 /* Try to discover a valid linker/nm/strip to use. */
940 #if 0
941 /* Search the (target-specific) compiler dirs for `gld'. */
942 ld_file_name = find_a_file (&cpath, gld_suffix);
943 /* Search the ordinary system bin directories
944 for `gld' (if native linking) or `TARGET-gld' (if cross). */
945 if (ld_file_name == 0)
946 ld_file_name = find_a_file (&path, full_gld_suffix);
947 #else
948 ld_file_name = 0;
949 #endif
950 /* Likewise for `real-ld'. */
951 if (ld_file_name == 0)
952 ld_file_name = find_a_file (&cpath, real_ld_suffix);
953 if (ld_file_name == 0)
954 ld_file_name = find_a_file (&path, full_real_ld_suffix);
955 /* Maybe we know the right file to use (if not cross). */
956 #ifdef REAL_LD_FILE_NAME
957 if (ld_file_name == 0)
958 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
959 #endif
960 /* Search the compiler directories for `ld'. We have protection against
961 recursive calls in find_a_file. */
962 if (ld_file_name == 0)
963 ld_file_name = find_a_file (&cpath, ld_suffix);
964 /* Search the ordinary system bin directories
965 for `ld' (if native linking) or `TARGET-ld' (if cross). */
966 if (ld_file_name == 0)
967 ld_file_name = find_a_file (&path, full_ld_suffix);
969 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
971 if (collect_names != 0)
973 if (ld_file_name != 0)
975 argv[0] = ld_file_name;
976 execvp (argv[0], argv);
978 fatal ("cannot find `ld'");
981 nm_file_name = find_a_file (&cpath, gnm_suffix);
982 if (nm_file_name == 0)
983 nm_file_name = find_a_file (&path, full_gnm_suffix);
984 if (nm_file_name == 0)
985 nm_file_name = find_a_file (&cpath, nm_suffix);
986 #ifdef REAL_NM_FILE_NAME
987 if (nm_file_name == 0)
988 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
989 #endif
990 if (nm_file_name == 0)
991 nm_file_name = find_a_file (&path, full_nm_suffix);
993 strip_file_name = find_a_file (&cpath, gstrip_suffix);
994 if (strip_file_name == 0)
995 strip_file_name = find_a_file (&path, full_gstrip_suffix);
996 if (strip_file_name == 0)
997 strip_file_name = find_a_file (&cpath, strip_suffix);
998 #ifdef REAL_STRIP_FILE_NAME
999 if (strip_file_name == 0)
1000 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1001 #endif
1002 if (strip_file_name == 0)
1003 strip_file_name = find_a_file (&path, full_strip_suffix);
1005 /* Determine the full path name of the C compiler to use. */
1006 c_file_name = getenv ("COLLECT_GCC");
1007 if (c_file_name == 0)
1009 #ifdef CROSS_COMPILE
1010 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
1011 strcpy (c_file_name, target_machine);
1012 strcat (c_file_name, "-gcc");
1013 #else
1014 c_file_name = "gcc";
1015 #endif
1018 p = find_a_file (&cpath, c_file_name);
1020 /* Here it should be safe to use the system search path since we should have
1021 already qualified the name of the compiler when it is needed. */
1022 if (p == 0)
1023 p = find_a_file (&path, c_file_name);
1025 if (p)
1026 c_file_name = p;
1028 *ld1++ = *ld2++ = ld_file_name;
1030 /* Make temp file names. */
1031 choose_temp_base ();
1032 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1033 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1034 sprintf (c_file, "%s.c", temp_filename);
1035 sprintf (o_file, "%s.o", temp_filename);
1036 *c_ptr++ = c_file_name;
1037 *c_ptr++ = "-c";
1038 *c_ptr++ = "-o";
1039 *c_ptr++ = o_file;
1041 /* !!! When GCC calls collect2,
1042 it does not know whether it is calling collect2 or ld.
1043 So collect2 cannot meaningfully understand any options
1044 except those ld understands.
1045 If you propose to make GCC pass some other option,
1046 just imagine what will happen if ld is really ld!!! */
1048 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1049 /* After the first file, put in the c++ rt0. */
1051 first_file = 1;
1052 while ((arg = *++argv) != (char *)0)
1054 *ld1++ = *ld2++ = arg;
1056 if (arg[0] == '-')
1057 switch (arg[1])
1059 case 'd':
1060 if (!strcmp (arg, "-debug"))
1062 debug = 1;
1063 vflag = 1;
1064 ld1--;
1065 ld2--;
1067 break;
1069 case 'o':
1070 output_file = (arg[2] == '\0') ? argv[1] : &arg[2];
1071 break;
1073 case 'r':
1074 if (arg[2] == '\0')
1075 rflag = 1;
1076 break;
1078 case 's':
1079 if (arg[2] == '\0')
1081 /* We must strip after the nm run, otherwise C++ linking
1082 won't work. Thus we strip in the second ld run, or
1083 else with strip if there is no second ld run. */
1084 strip_flag = 1;
1085 ld1--;
1087 break;
1089 case 'v':
1090 if (arg[2] == '\0')
1091 vflag = 1;
1092 break;
1095 else if (first_file
1096 && (p = rindex (arg, '.')) != (char *)0
1097 && strcmp (p, ".o") == 0)
1099 first_file = 0;
1100 *ld2++ = o_file;
1104 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
1105 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1106 if (p)
1107 while (*p)
1109 char *q = p;
1110 while (*q && *q != ' ') q++;
1111 if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
1112 *c_ptr++ = savestring (p, q - p);
1114 if (*q) q++;
1115 p = q;
1118 *c_ptr++ = c_file;
1119 *c_ptr = *ld1 = *ld2 = (char *)0;
1121 if (vflag)
1123 fprintf (stderr, "collect2 version %s", version_string);
1124 #ifdef TARGET_VERSION
1125 TARGET_VERSION;
1126 #endif
1127 fprintf (stderr, "\n");
1130 if (debug)
1132 char *ptr;
1133 fprintf (stderr, "ld_file_name = %s\n",
1134 (ld_file_name ? ld_file_name : "not found"));
1135 fprintf (stderr, "c_file_name = %s\n",
1136 (c_file_name ? c_file_name : "not found"));
1137 fprintf (stderr, "nm_file_name = %s\n",
1138 (nm_file_name ? nm_file_name : "not found"));
1139 fprintf (stderr, "strip_file_name = %s\n",
1140 (strip_file_name ? strip_file_name : "not found"));
1141 fprintf (stderr, "c_file = %s\n",
1142 (c_file ? c_file : "not found"));
1143 fprintf (stderr, "o_file = %s\n",
1144 (o_file ? o_file : "not found"));
1146 ptr = getenv ("COLLECT_NAMES");
1147 if (ptr)
1148 fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
1150 ptr = getenv ("COLLECT_GCC_OPTIONS");
1151 if (ptr)
1152 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1154 ptr = getenv ("COLLECT_GCC");
1155 if (ptr)
1156 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1158 ptr = getenv ("COMPILER_PATH");
1159 if (ptr)
1160 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1162 ptr = getenv ("LIBRARY_PATH");
1163 if (ptr)
1164 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1166 fprintf (stderr, "\n");
1169 /* Load the program, searching all libraries.
1170 Examine the namelist with nm and search it for static constructors
1171 and destructors to call.
1172 Write the constructor and destructor tables to a .s file and reload. */
1174 fork_execute ("ld", ld1_argv);
1176 /* If -r, don't build the constructor or destructor list, just return now. */
1177 if (rflag)
1178 return 0;
1180 scan_prog_file (output_file, PASS_FIRST);
1182 if (debug)
1184 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1185 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1188 if (constructors.number == 0 && destructors.number == 0)
1190 /* Strip now if it was requested on the command line. */
1191 if (strip_flag)
1193 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
1194 strip_argv[0] = strip_file_name;
1195 strip_argv[1] = output_file;
1196 strip_argv[2] = (char *) 0;
1197 fork_execute ("strip", strip_argv);
1199 return 0;
1202 outf = fopen (c_file, "w");
1203 if (outf == (FILE *)0)
1204 fatal_perror ("%s", c_file);
1206 write_c_file (outf, c_file);
1208 if (fclose (outf))
1209 fatal_perror ("closing %s", c_file);
1211 if (debug)
1213 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1214 output_file, c_file);
1215 write_c_file (stderr, "stderr");
1216 fprintf (stderr, "========== end of c_file\n\n");
1219 /* Assemble the constructor and destructor tables.
1220 Link the tables in with the rest of the program. */
1222 fork_execute ("gcc", c_argv);
1223 fork_execute ("ld", ld2_argv);
1225 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1226 constructors/destructors in shared libraries. */
1227 scan_prog_file (output_file, PASS_SECOND);
1229 maybe_unlink (c_file);
1230 maybe_unlink (o_file);
1231 return 0;
1235 /* Wait for a process to finish, and exit if a non-zero status is found. */
1237 static void
1238 do_wait (prog)
1239 char *prog;
1241 int status;
1243 wait (&status);
1244 if (status)
1246 int sig = status & 0x7F;
1247 int ret;
1249 if (sig != -1 && sig != 0)
1251 #ifdef NO_SYS_SIGLIST
1252 error ("%s terminated with signal %d %s",
1253 prog,
1254 sig,
1255 (status & 0200) ? ", core dumped" : "");
1256 #else
1257 error ("%s terminated with signal %d [%s]%s",
1258 prog,
1259 sig,
1260 sys_siglist[sig],
1261 (status & 0200) ? ", core dumped" : "");
1262 #endif
1264 my_exit (127);
1267 ret = ((status & 0xFF00) >> 8);
1268 if (ret != -1 && ret != 0)
1270 error ("%s returned %d exit status", prog, ret);
1271 my_exit (ret);
1277 /* Fork and execute a program, and wait for the reply. */
1279 static void
1280 fork_execute (prog, argv)
1281 char *prog;
1282 char **argv;
1284 int pid;
1286 if (vflag || debug)
1288 char **p_argv;
1289 char *str;
1291 if (argv[0])
1292 fprintf (stderr, "%s", argv[0]);
1293 else
1294 fprintf (stderr, "[cannot find %s]", prog);
1296 for (p_argv = &argv[1]; (str = *p_argv) != (char *)0; p_argv++)
1297 fprintf (stderr, " %s", str);
1299 fprintf (stderr, "\n");
1302 fflush (stdout);
1303 fflush (stderr);
1305 /* If we can't find a program we need, complain error. Do this here
1306 since we might not end up needing something that we couldn't find. */
1308 if (argv[0] == 0)
1309 fatal ("cannot find `%s'", prog);
1311 pid = vfork ();
1312 if (pid == -1)
1314 #ifdef vfork
1315 fatal_perror ("fork");
1316 #else
1317 fatal_perror ("vfork");
1318 #endif
1321 if (pid == 0) /* child context */
1323 execvp (argv[0], argv);
1324 fatal_perror ("executing %s", prog);
1327 do_wait (prog);
1331 /* Unlink a file unless we are debugging. */
1333 static void
1334 maybe_unlink (file)
1335 char *file;
1337 if (!debug)
1338 unlink (file);
1339 else
1340 fprintf (stderr, "[Leaving %s]\n", file);
1344 /* Add a name to a linked list. */
1346 static void
1347 add_to_list (head_ptr, name)
1348 struct head *head_ptr;
1349 char *name;
1351 struct id *newid = (struct id *) xcalloc (sizeof (*newid) + strlen (name), 1);
1352 static long sequence_number = 0;
1353 newid->sequence = ++sequence_number;
1354 strcpy (newid->name, name);
1356 if (head_ptr->first)
1357 head_ptr->last->next = newid;
1358 else
1359 head_ptr->first = newid;
1361 head_ptr->last = newid;
1362 head_ptr->number++;
1365 /* Write: `prefix', the names on list LIST, `suffix'. */
1367 static void
1368 write_list (stream, prefix, list)
1369 FILE *stream;
1370 char *prefix;
1371 struct id *list;
1373 while (list)
1375 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1376 list = list->next;
1380 static void
1381 write_list_with_asm (stream, prefix, list)
1382 FILE *stream;
1383 char *prefix;
1384 struct id *list;
1386 while (list)
1388 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1389 prefix, list->sequence, list->name);
1390 list = list->next;
1394 /* Write the constructor/destructor tables. */
1396 static void
1397 write_c_file (stream, name)
1398 FILE *stream;
1399 char *name;
1401 /* Write the tables as C code */
1403 fprintf (stream, "typedef void entry_pt();\n\n");
1405 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1407 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1408 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);
1409 write_list (stream, "\t", constructors.first);
1410 fprintf (stream, "\t0\n};\n\n");
1412 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1414 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1415 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number);
1416 write_list (stream, "\t", destructors.first);
1417 fprintf (stream, "\t0\n};\n\n");
1419 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1420 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
1424 #ifdef OBJECT_FORMAT_NONE
1426 /* Generic version to scan the name list of the loaded program for
1427 the symbols g++ uses for static constructors and destructors.
1429 The constructor table begins at __CTOR_LIST__ and contains a count
1430 of the number of pointers (or -1 if the constructors are built in a
1431 separate section by the linker), followed by the pointers to the
1432 constructor functions, terminated with a null pointer. The
1433 destructor table has the same format, and begins at __DTOR_LIST__. */
1435 static void
1436 scan_prog_file (prog_name, which_pass)
1437 char *prog_name;
1438 enum pass which_pass;
1440 void (*int_handler) ();
1441 void (*quit_handler) ();
1442 char *nm_argv[4];
1443 int pid;
1444 int argc = 0;
1445 int pipe_fd[2];
1446 char *p, buf[1024];
1447 FILE *inf;
1449 if (which_pass != PASS_FIRST)
1450 return;
1452 /* If we don't have an `nm', complain. */
1453 if (nm_file_name == 0)
1454 fatal ("cannot find `nm'");
1456 nm_argv[argc++] = "nm";
1457 if (NM_FLAGS[0] != '\0')
1458 nm_argv[argc++] = NM_FLAGS;
1460 nm_argv[argc++] = prog_name;
1461 nm_argv[argc++] = (char *)0;
1463 if (pipe (pipe_fd) < 0)
1464 fatal_perror ("pipe");
1466 inf = fdopen (pipe_fd[0], "r");
1467 if (inf == (FILE *)0)
1468 fatal_perror ("fdopen");
1470 /* Trace if needed. */
1471 if (vflag)
1473 char **p_argv;
1474 char *str;
1476 fprintf (stderr, "%s", nm_file_name);
1477 for (p_argv = &nm_argv[1]; (str = *p_argv) != (char *)0; p_argv++)
1478 fprintf (stderr, " %s", str);
1480 fprintf (stderr, "\n");
1483 fflush (stdout);
1484 fflush (stderr);
1486 /* Spawn child nm on pipe */
1487 pid = vfork ();
1488 if (pid == -1)
1490 #ifdef vfork
1491 fatal_perror ("fork");
1492 #else
1493 fatal_perror ("vfork");
1494 #endif
1497 if (pid == 0) /* child context */
1499 /* setup stdout */
1500 if (dup2 (pipe_fd[1], 1) < 0)
1501 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
1503 if (close (pipe_fd[0]) < 0)
1504 fatal_perror ("close (%d)", pipe_fd[0]);
1506 if (close (pipe_fd[1]) < 0)
1507 fatal_perror ("close (%d)", pipe_fd[1]);
1509 execv (nm_file_name, nm_argv);
1510 fatal_perror ("executing %s", nm_file_name);
1513 /* Parent context from here on. */
1514 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
1515 #ifdef SIGQUIT
1516 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
1517 #endif
1519 if (close (pipe_fd[1]) < 0)
1520 fatal_perror ("close (%d)", pipe_fd[1]);
1522 if (debug)
1523 fprintf (stderr, "\nnm output with constructors/destructors.\n");
1525 /* Read each line of nm output. */
1526 while (fgets (buf, sizeof buf, inf) != (char *)0)
1528 int ch, ch2;
1529 char *name, *end;
1531 /* If it contains a constructor or destructor name, add the name
1532 to the appropriate list. */
1534 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
1537 if (ch == '\0' || ch == '\n')
1538 continue;
1540 name = p;
1541 /* Find the end of the symbol name.
1542 Don't include `|', because Encore nm can tack that on the end. */
1543 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
1544 end++)
1545 continue;
1547 *end = '\0';
1548 switch (is_ctor_dtor (name))
1550 case 1:
1551 add_to_list (&constructors, name);
1552 break;
1554 case 2:
1555 add_to_list (&destructors, name);
1556 break;
1558 default: /* not a constructor or destructor */
1559 continue;
1562 if (debug)
1563 fprintf (stderr, "\t%s\n", buf);
1566 if (debug)
1567 fprintf (stderr, "\n");
1569 if (fclose (inf) != 0)
1570 fatal_perror ("fclose of pipe");
1572 do_wait (nm_file_name);
1574 signal (SIGINT, int_handler);
1575 #ifdef SIGQUIT
1576 signal (SIGQUIT, quit_handler);
1577 #endif
1580 #endif /* OBJECT_FORMAT_NONE */
1584 * COFF specific stuff.
1587 #ifdef OBJECT_FORMAT_COFF
1589 #if defined(EXTENDED_COFF)
1590 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
1591 # define GCC_SYMENT SYMR
1592 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
1593 # define GCC_SYMINC(X) (1)
1594 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
1595 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
1596 #else
1597 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
1598 # define GCC_SYMENT SYMENT
1599 # define GCC_OK_SYMBOL(X) \
1600 (((X).n_sclass == C_EXT) && \
1601 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
1602 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
1603 # define GCC_SYMINC(X) ((X).n_numaux+1)
1604 # define GCC_SYMZERO(X) 0
1605 # define GCC_CHECK_HDR(X) (1)
1606 #endif
1608 extern char *ldgetname ();
1610 /* COFF version to scan the name list of the loaded program for
1611 the symbols g++ uses for static constructors and destructors.
1613 The constructor table begins at __CTOR_LIST__ and contains a count
1614 of the number of pointers (or -1 if the constructors are built in a
1615 separate section by the linker), followed by the pointers to the
1616 constructor functions, terminated with a null pointer. The
1617 destructor table has the same format, and begins at __DTOR_LIST__. */
1619 static void
1620 scan_prog_file (prog_name, which_pass)
1621 char *prog_name;
1622 enum pass which_pass;
1624 LDFILE *ldptr = NULL;
1625 int sym_index, sym_count;
1627 if (which_pass != PASS_FIRST)
1628 return;
1630 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
1631 fatal ("%s: can't open as COFF file", prog_name);
1633 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
1634 fatal ("%s: not a COFF file", prog_name);
1636 if (GCC_CHECK_HDR (ldptr))
1638 sym_count = GCC_SYMBOLS (ldptr);
1639 sym_index = GCC_SYMZERO (ldptr);
1640 while (sym_index < sym_count)
1642 GCC_SYMENT symbol;
1644 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
1645 break;
1646 sym_index += GCC_SYMINC (symbol);
1648 if (GCC_OK_SYMBOL (symbol))
1650 char *name;
1652 if ((name = ldgetname (ldptr, &symbol)) == NULL)
1653 continue; /* should never happen */
1655 #ifdef _AIX
1656 /* All AIX function names begin with a dot. */
1657 if (*name++ != '.')
1658 continue;
1659 #endif
1661 switch (is_ctor_dtor (name))
1663 case 1:
1664 add_to_list (&constructors, name);
1665 break;
1667 case 2:
1668 add_to_list (&destructors, name);
1669 break;
1671 default: /* not a constructor or destructor */
1672 continue;
1675 #if !defined(EXTENDED_COFF)
1676 if (debug)
1677 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
1678 symbol.n_scnum, symbol.n_sclass,
1679 (symbol.n_type ? "0" : ""), symbol.n_type,
1680 name);
1681 #else
1682 if (debug)
1683 fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1684 symbol.iss, symbol.value, symbol.index, name);
1685 #endif
1690 (void) ldclose(ldptr);
1693 #endif /* OBJECT_FORMAT_COFF */
1697 * OSF/rose specific stuff.
1700 #ifdef OBJECT_FORMAT_ROSE
1702 /* Union of the various load commands */
1704 typedef union load_union
1706 ldc_header_t hdr; /* common header */
1707 load_cmd_map_command_t map; /* map indexing other load cmds */
1708 interpreter_command_t iprtr; /* interpreter pathname */
1709 strings_command_t str; /* load commands strings section */
1710 region_command_t region; /* region load command */
1711 reloc_command_t reloc; /* relocation section */
1712 package_command_t pkg; /* package load command */
1713 symbols_command_t sym; /* symbol sections */
1714 entry_command_t ent; /* program start section */
1715 gen_info_command_t info; /* object information */
1716 func_table_command_t func; /* function constructors/destructors */
1717 } load_union_t;
1719 /* Structure to point to load command and data section in memory. */
1721 typedef struct load_all
1723 load_union_t *load; /* load command */
1724 char *section; /* pointer to section */
1725 } load_all_t;
1727 /* Structure to contain information about a file mapped into memory. */
1729 struct file_info
1731 char *start; /* start of map */
1732 char *name; /* filename */
1733 long size; /* size of the file */
1734 long rounded_size; /* size rounded to page boundary */
1735 int fd; /* file descriptor */
1736 int rw; /* != 0 if opened read/write */
1737 int use_mmap; /* != 0 if mmap'ed */
1740 extern int decode_mach_o_hdr ();
1741 extern int encode_mach_o_hdr ();
1743 static void add_func_table PROTO((mo_header_t *, load_all_t *,
1744 symbol_info_t *, int));
1745 static void print_header PROTO((mo_header_t *));
1746 static void print_load_command PROTO((load_union_t*, size_t, int));
1747 static void bad_header PROTO((int));
1748 static struct file_info *read_file PROTO((char *, int, int));
1749 static void end_file PROTO((struct file_info *));
1751 /* OSF/rose specific version to scan the name list of the loaded
1752 program for the symbols g++ uses for static constructors and
1753 destructors.
1755 The constructor table begins at __CTOR_LIST__ and contains a count
1756 of the number of pointers (or -1 if the constructors are built in a
1757 separate section by the linker), followed by the pointers to the
1758 constructor functions, terminated with a null pointer. The
1759 destructor table has the same format, and begins at __DTOR_LIST__. */
1761 static void
1762 scan_prog_file (prog_name, which_pass)
1763 char *prog_name;
1764 enum pass which_pass;
1766 char *obj;
1767 mo_header_t hdr;
1768 load_all_t *load_array;
1769 load_all_t *load_end;
1770 load_all_t *load_cmd;
1771 int symbol_load_cmds;
1772 off_t offset;
1773 int i;
1774 int num_syms;
1775 int status;
1776 char *str_sect;
1777 struct file_info *obj_file;
1778 int prog_fd;
1779 mo_lcid_t cmd_strings = -1;
1780 symbol_info_t *main_sym = 0;
1781 int rw = (which_pass != PASS_FIRST);
1783 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
1784 if (prog_fd < 0)
1785 fatal_perror ("can't read %s", prog_name);
1787 obj_file = read_file (prog_name, prog_fd, rw);
1788 obj = obj_file->start;
1790 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
1791 if (status != MO_HDR_CONV_SUCCESS)
1792 bad_header (status);
1795 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
1796 since the hardware will automatically swap bytes for us on loading little endian
1797 integers. */
1799 #ifndef CROSS_COMPILE
1800 if (hdr.moh_magic != MOH_MAGIC_MSB
1801 || hdr.moh_header_version != MOH_HEADER_VERSION
1802 || hdr.moh_byte_order != OUR_BYTE_ORDER
1803 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
1804 || hdr.moh_cpu_type != OUR_CPU_TYPE
1805 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
1806 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
1808 fatal ("incompatibilities between object file & expected values");
1810 #endif
1812 if (debug)
1813 print_header (&hdr);
1815 offset = hdr.moh_first_cmd_off;
1816 load_end = load_array
1817 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
1819 /* Build array of load commands, calculating the offsets */
1820 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1822 load_union_t *load_hdr; /* load command header */
1824 load_cmd = load_end++;
1825 load_hdr = (load_union_t *) (obj + offset);
1827 /* If modifying the program file, copy the header. */
1828 if (rw)
1830 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
1831 bcopy ((generic *)load_hdr, (generic *)ptr, load_hdr->hdr.ldci_cmd_size);
1832 load_hdr = ptr;
1834 /* null out old command map, because we will rewrite at the end. */
1835 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
1837 cmd_strings = ptr->map.lcm_ld_cmd_strings;
1838 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
1842 load_cmd->load = load_hdr;
1843 if (load_hdr->hdr.ldci_section_off > 0)
1844 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
1846 if (debug)
1847 print_load_command (load_hdr, offset, i);
1849 offset += load_hdr->hdr.ldci_cmd_size;
1852 /* If the last command is the load command map and is not undefined,
1853 decrement the count of load commands. */
1854 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
1856 load_end--;
1857 hdr.moh_n_load_cmds--;
1860 /* Go through and process each symbol table section. */
1861 symbol_load_cmds = 0;
1862 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
1864 load_union_t *load_hdr = load_cmd->load;
1866 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
1868 symbol_load_cmds++;
1870 if (debug)
1872 char *kind = "unknown";
1874 switch (load_hdr->sym.symc_kind)
1876 case SYMC_IMPORTS: kind = "imports"; break;
1877 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
1878 case SYMC_STABS: kind = "stabs"; break;
1881 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1882 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
1885 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
1886 continue;
1888 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
1889 if (str_sect == (char *)0)
1890 fatal ("string section missing");
1892 if (load_cmd->section == (char *)0)
1893 fatal ("section pointer missing");
1895 num_syms = load_hdr->sym.symc_nentries;
1896 for (i = 0; i < num_syms; i++)
1898 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
1899 char *name = sym->si_name.symbol_name + str_sect;
1901 if (name[0] != '_')
1902 continue;
1904 if (rw)
1906 char *n = name + strlen (name) - strlen (NAME__MAIN);
1908 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
1909 continue;
1910 while (n != name)
1911 if (*--n != '_')
1912 continue;
1914 main_sym = sym;
1916 else
1918 switch (is_ctor_dtor (name))
1920 case 1:
1921 add_to_list (&constructors, name);
1922 break;
1924 case 2:
1925 add_to_list (&destructors, name);
1926 break;
1928 default: /* not a constructor or destructor */
1929 continue;
1933 if (debug)
1934 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
1935 sym->si_type, sym->si_sc_type, sym->si_flags, name);
1940 if (symbol_load_cmds == 0)
1941 fatal ("no symbol table found");
1943 /* Update the program file now, rewrite header and load commands. At present,
1944 we assume that there is enough space after the last load command to insert
1945 one more. Since the first section written out is page aligned, and the
1946 number of load commands is small, this is ok for the present. */
1948 if (rw)
1950 load_union_t *load_map;
1951 size_t size;
1953 if (cmd_strings == -1)
1954 fatal ("no cmd_strings found");
1956 /* Add __main to initializer list.
1957 If we are building a program instead of a shared library, don't
1958 do anything, since in the current version, you cannot do mallocs
1959 and such in the constructors. */
1961 if (main_sym != (symbol_info_t *)0
1962 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
1963 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
1965 if (debug)
1966 fprintf (stderr, "\nUpdating header and load commands.\n\n");
1968 hdr.moh_n_load_cmds++;
1969 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
1971 /* Create new load command map. */
1972 if (debug)
1973 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
1974 (int)hdr.moh_n_load_cmds, (long)size);
1976 load_map = (load_union_t *) xcalloc (1, size);
1977 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
1978 load_map->map.ldc_header.ldci_cmd_size = size;
1979 load_map->map.lcm_ld_cmd_strings = cmd_strings;
1980 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
1981 load_array[hdr.moh_n_load_cmds-1].load = load_map;
1983 offset = hdr.moh_first_cmd_off;
1984 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1986 load_map->map.lcm_map[i] = offset;
1987 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
1988 hdr.moh_load_map_cmd_off = offset;
1990 offset += load_array[i].load->hdr.ldci_cmd_size;
1993 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
1995 if (debug)
1996 print_header (&hdr);
1998 /* Write header */
1999 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
2000 if (status != MO_HDR_CONV_SUCCESS)
2001 bad_header (status);
2003 if (debug)
2004 fprintf (stderr, "writing load commands.\n\n");
2006 /* Write load commands */
2007 offset = hdr.moh_first_cmd_off;
2008 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2010 load_union_t *load_hdr = load_array[i].load;
2011 size_t size = load_hdr->hdr.ldci_cmd_size;
2013 if (debug)
2014 print_load_command (load_hdr, offset, i);
2016 bcopy ((generic *)load_hdr, (generic *)(obj + offset), size);
2017 offset += size;
2021 end_file (obj_file);
2023 if (close (prog_fd))
2024 fatal_perror ("closing %s", prog_name);
2026 if (debug)
2027 fprintf (stderr, "\n");
2031 /* Add a function table to the load commands to call a function
2032 on initiation or termination of the process. */
2034 static void
2035 add_func_table (hdr_p, load_array, sym, type)
2036 mo_header_t *hdr_p; /* pointer to global header */
2037 load_all_t *load_array; /* array of ptrs to load cmds */
2038 symbol_info_t *sym; /* pointer to symbol entry */
2039 int type; /* fntc_type value */
2041 /* Add a new load command. */
2042 int num_cmds = ++hdr_p->moh_n_load_cmds;
2043 int load_index = num_cmds - 1;
2044 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
2045 load_union_t *ptr = xcalloc (1, size);
2046 load_all_t *load_cmd;
2047 int i;
2049 /* Set the unresolved address bit in the header to force the loader to be
2050 used, since kernel exec does not call the initialization functions. */
2051 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
2053 load_cmd = &load_array[load_index];
2054 load_cmd->load = ptr;
2055 load_cmd->section = (char *)0;
2057 /* Fill in func table load command. */
2058 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
2059 ptr->func.ldc_header.ldci_cmd_size = size;
2060 ptr->func.ldc_header.ldci_section_off = 0;
2061 ptr->func.ldc_header.ldci_section_len = 0;
2062 ptr->func.fntc_type = type;
2063 ptr->func.fntc_nentries = 1;
2065 /* copy address, turn it from abs. address to (region,offset) if necessary. */
2066 /* Is the symbol already expressed as (region, offset)? */
2067 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
2069 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
2070 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
2073 /* If not, figure out which region it's in. */
2074 else
2076 mo_vm_addr_t addr = sym->si_value.abs_val;
2077 int found = 0;
2079 for (i = 0; i < load_index; i++)
2081 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
2083 region_command_t *region_ptr = &load_array[i].load->region;
2085 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
2086 && addr >= region_ptr->regc_addr.vm_addr
2087 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
2089 ptr->func.fntc_entry_loc[0].adr_lcid = i;
2090 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
2091 found++;
2092 break;
2097 if (!found)
2098 fatal ("could not convert 0x%l.8x into a region", addr);
2101 if (debug)
2102 fprintf (stderr,
2103 "%s function, region %d, offset = %ld (0x%.8lx)\n",
2104 (type == FNTC_INITIALIZATION) ? "init" : "term",
2105 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
2106 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
2107 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
2112 /* Print the global header for an OSF/rose object. */
2114 static void
2115 print_header (hdr_ptr)
2116 mo_header_t *hdr_ptr;
2118 fprintf (stderr, "\nglobal header:\n");
2119 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
2120 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
2121 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
2122 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
2123 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
2124 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
2125 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
2126 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
2127 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
2128 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
2129 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
2130 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
2131 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
2132 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
2133 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
2135 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
2136 fprintf (stderr, ", relocatable");
2138 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
2139 fprintf (stderr, ", linkable");
2141 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
2142 fprintf (stderr, ", execable");
2144 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
2145 fprintf (stderr, ", executable");
2147 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
2148 fprintf (stderr, ", unresolved");
2150 fprintf (stderr, "\n\n");
2151 return;
2155 /* Print a short summary of a load command. */
2157 static void
2158 print_load_command (load_hdr, offset, number)
2159 load_union_t *load_hdr;
2160 size_t offset;
2161 int number;
2163 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
2164 char *type_str = (char *)0;
2166 switch (type)
2168 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
2169 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
2170 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
2171 case LDC_STRINGS: type_str = "STRINGS"; break;
2172 case LDC_REGION: type_str = "REGION"; break;
2173 case LDC_RELOC: type_str = "RELOC"; break;
2174 case LDC_PACKAGE: type_str = "PACKAGE"; break;
2175 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
2176 case LDC_ENTRY: type_str = "ENTRY"; break;
2177 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
2178 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
2181 fprintf (stderr,
2182 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
2183 number,
2184 (long) load_hdr->hdr.ldci_cmd_size,
2185 (long) offset,
2186 (long) load_hdr->hdr.ldci_section_off,
2187 (long) load_hdr->hdr.ldci_section_len);
2189 if (type_str == (char *)0)
2190 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
2192 else if (type != LDC_REGION)
2193 fprintf (stderr, ", ty: %s\n", type_str);
2195 else
2197 char *region = "";
2198 switch (load_hdr->region.regc_usage_type)
2200 case REG_TEXT_T: region = ", .text"; break;
2201 case REG_DATA_T: region = ", .data"; break;
2202 case REG_BSS_T: region = ", .bss"; break;
2203 case REG_GLUE_T: region = ", .glue"; break;
2204 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
2205 case REG_RDATA_T: region = ", .rdata"; break;
2206 case REG_SDATA_T: region = ", .sdata"; break;
2207 case REG_SBSS_T: region = ", .sbss"; break;
2208 #endif
2211 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
2212 type_str,
2213 (long) load_hdr->region.regc_vm_addr,
2214 (long) load_hdr->region.regc_vm_size,
2215 region);
2218 return;
2222 /* Fatal error when {en,de}code_mach_o_header fails. */
2224 static void
2225 bad_header (status)
2226 int status;
2228 char *msg = (char *)0;
2230 switch (status)
2232 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
2233 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
2234 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
2235 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
2236 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
2237 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
2240 if (msg == (char *)0)
2241 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
2242 else
2243 fatal ("%s", msg);
2247 /* Read a file into a memory buffer. */
2249 static struct file_info *
2250 read_file (name, fd, rw)
2251 char *name; /* filename */
2252 int fd; /* file descriptor */
2253 int rw; /* read/write */
2255 struct stat stat_pkt;
2256 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
2257 #ifdef USE_MMAP
2258 static int page_size;
2259 #endif
2261 if (fstat (fd, &stat_pkt) < 0)
2262 fatal_perror ("fstat %s", name);
2264 p->name = name;
2265 p->size = stat_pkt.st_size;
2266 p->rounded_size = stat_pkt.st_size;
2267 p->fd = fd;
2268 p->rw = rw;
2270 #ifdef USE_MMAP
2271 if (debug)
2272 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
2274 if (page_size == 0)
2275 page_size = sysconf (_SC_PAGE_SIZE);
2277 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
2278 p->start = mmap ((caddr_t)0,
2279 (rw) ? p->rounded_size : p->size,
2280 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
2281 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
2283 0L);
2285 if (p->start != (char *)0 && p->start != (char *)-1)
2286 p->use_mmap = 1;
2288 else
2289 #endif /* USE_MMAP */
2291 long len;
2293 if (debug)
2294 fprintf (stderr, "read %s\n", name);
2296 p->use_mmap = 0;
2297 p->start = xmalloc (p->size);
2298 if (lseek (fd, 0L, SEEK_SET) < 0)
2299 fatal_perror ("lseek to 0 on %s", name);
2301 len = read (fd, p->start, p->size);
2302 if (len < 0)
2303 fatal_perror ("read %s", name);
2305 if (len != p->size)
2306 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
2309 return p;
2312 /* Do anything necessary to write a file back from memory. */
2314 static void
2315 end_file (ptr)
2316 struct file_info *ptr; /* file information block */
2318 #ifdef USE_MMAP
2319 if (ptr->use_mmap)
2321 if (ptr->rw)
2323 if (debug)
2324 fprintf (stderr, "msync %s\n", ptr->name);
2326 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
2327 fatal_perror ("msync %s", ptr->name);
2330 if (debug)
2331 fprintf (stderr, "munmap %s\n", ptr->name);
2333 if (munmap (ptr->start, ptr->size))
2334 fatal_perror ("munmap %s", ptr->name);
2336 else
2337 #endif /* USE_MMAP */
2339 if (ptr->rw)
2341 long len;
2343 if (debug)
2344 fprintf (stderr, "write %s\n", ptr->name);
2346 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
2347 fatal_perror ("lseek to 0 on %s", ptr->name);
2349 len = write (ptr->fd, ptr->start, ptr->size);
2350 if (len < 0)
2351 fatal_perror ("read %s", ptr->name);
2353 if (len != ptr->size)
2354 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
2357 free ((generic *)ptr->start);
2360 free ((generic *)ptr);
2363 #endif /* OBJECT_FORMAT_ROSE */