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>
67 /* On MSDOS, write temp files in current dir
68 because there's no place else we can expect to use. */
75 /* On certain systems, we have code that works by scanning the object file
76 directly. But this code uses system-specific header files and library
77 functions, so turn it off in a cross-compiler. */
80 #undef OBJECT_FORMAT_COFF
81 #undef OBJECT_FORMAT_ROSE
84 /* If we can't use a special method, use the ordinary one:
85 run nm to find what symbols are present.
86 In a cross-compiler, this means you need a cross nm,
87 but that isn't quite as unpleasant as special headers. */
89 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
90 #define OBJECT_FORMAT_NONE
93 #ifdef OBJECT_FORMAT_COFF
103 #define ISCOFF(magic) \
104 ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC || (magic) == U802TOCMAGIC)
107 #if defined (_AIX) || defined (USG)
114 #endif /* OBJECT_FORMAT_COFF */
116 #ifdef OBJECT_FORMAT_ROSE
123 #include <sys/mman.h>
127 #include <mach_o_format.h>
128 #include <mach_o_header.h>
129 #include <mach_o_vals.h>
130 #include <mach_o_types.h>
132 #endif /* OBJECT_FORMAT_ROSE */
134 #ifdef OBJECT_FORMAT_NONE
136 /* Default flags to pass to nm. */
138 #define NM_FLAGS "-p"
141 #endif /* OBJECT_FORMAT_NONE */
143 /* Linked lists of constructor and destructor names. */
159 /* Enumeration giving which pass this is for scanning the program file. */
162 PASS_FIRST
, /* without constructors */
163 PASS_SECOND
/* with constructors linked in */
166 #ifndef NO_SYS_SIGLIST
167 extern char *sys_siglist
[];
169 extern char *version_string
;
171 static int vflag
; /* true if -v */
172 static int rflag
; /* true if -r */
174 static int debug
; /* true if -debug */
176 static int temp_filename_length
; /* Length of temp_filename */
177 static char *temp_filename
; /* Base of temp filenames */
178 static char *c_file
; /* <xxx>.c for constructor/destructor list. */
179 static char *o_file
; /* <xxx>.o for constructor/destructor list. */
180 static char *nm_file_name
; /* pathname of nm */
182 static struct head constructors
; /* list of constructors found */
183 static struct head destructors
; /* list of destructors found */
185 extern char *getenv ();
186 extern char *mktemp ();
188 static void add_to_list ();
189 static void scan_prog_file ();
190 static void fork_execute ();
191 static void do_wait ();
192 static void write_c_file ();
193 static void my_exit ();
194 static void handler ();
195 static void maybe_unlink ();
196 static void choose_temp_base ();
202 #if !defined(HAVE_STRERROR) && !defined(_OSF_SOURCE)
208 extern char *sys_errlist
[];
210 static char buffer
[30];
215 if (e
> 0 && e
< sys_nerr
)
216 return sys_errlist
[e
];
218 sprintf (buffer
, "Unknown error %d", e
);
225 /* Delete tempfiles and exit function. */
231 if (c_file
!= 0 && c_file
[0])
232 maybe_unlink (c_file
);
234 if (o_file
!= 0 && o_file
[0])
235 maybe_unlink (o_file
);
243 /* Die when sys call fails. */
247 fatal_perror (va_alist
)
254 string
= va_arg (vptr
, char *);
255 fprintf (stderr
, "collect: ");
256 vfprintf (stderr
, string
, vptr
);
257 fprintf (stderr
, ": %s\n", strerror (e
));
272 string
= va_arg (vptr
, char *);
273 fprintf (stderr
, "collect: ");
274 vfprintf (stderr
, string
, vptr
);
275 fprintf (stderr
, "\n");
280 /* Write error message. */
290 string
= va_arg (vptr
, char *);
291 fprintf (stderr
, "collect: ");
292 vfprintf (stderr
, string
, vptr
);
293 fprintf (stderr
, "\n");
300 fatal_perror (char *string
, ...)
305 va_start (vptr
, string
);
306 fprintf (stderr
, "collect: ");
307 vfprintf (stderr
, string
, vptr
);
308 fprintf (stderr
, ": %s\n", strerror (e
));
316 fatal (char *string
, ...)
320 va_start (vptr
, string
);
321 fprintf (stderr
, "collect: ");
322 vfprintf (stderr
, string
, vptr
);
323 fprintf (stderr
, "\n");
328 /* Write error message. */
331 error (char *string
, ...)
335 va_start (vptr
, string
);
336 fprintf (stderr
, "collect: ");
337 vfprintf (stderr
, string
, vptr
);
338 fprintf (stderr
, "\n");
344 /* In case obstack is linked in, and abort is defined to fancy_abort,
345 provide a default entry. */
350 fatal ("internal error");
359 maybe_unlink (c_file
);
362 maybe_unlink (o_file
);
364 signal (signo
, SIG_DFL
);
365 kill (getpid (), signo
);
370 xcalloc (size1
, size2
)
373 generic
*ptr
= (generic
*) calloc (size1
, size2
);
377 fatal ("Out of memory.");
385 generic
*ptr
= (generic
*) malloc (size
);
389 fatal ("Out of memory.");
393 /* Make a copy of a string INPUT with size SIZE. */
396 savestring (input
, size
)
400 char *output
= (char *) xmalloc (size
+ 1);
401 strcpy (output
, input
);
405 /* Decide whether the given symbol is:
406 a constructor (1), a destructor (2), or neither (0). */
412 struct names
{ char *name
; int len
; int ret
; int two_underscores
; };
414 register struct names
*p
;
416 register char *orig_s
= s
;
418 static struct names special
[] = {
419 #ifdef NO_DOLLAR_IN_LABEL
420 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
421 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
423 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
424 { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 },
426 { "sti__", sizeof ("sti__")-1, 1, 1 },
427 { "std__", sizeof ("std__")-1, 2, 1 },
431 while ((ch
= *s
) == '_')
437 for (p
= &special
[0]; p
->len
> 0; p
++)
440 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
441 && strncmp(s
, p
->name
, p
->len
) == 0)
450 /* Compute a string to use as the base of all temporary file names.
451 It is substituted for %g. */
456 char *base
= getenv ("TMPDIR");
459 if (base
== (char *)0)
462 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
465 if (base
== (char *)0)
467 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
475 temp_filename
= xmalloc (len
+ sizeof("/ccXXXXXX"));
476 strcpy (temp_filename
, base
);
477 if (len
> 0 && temp_filename
[len
-1] != '/')
478 temp_filename
[len
++] = '/';
479 strcpy (temp_filename
+ len
, "ccXXXXXX");
481 mktemp (temp_filename
);
482 temp_filename_length
= strlen (temp_filename
);
493 char *outfile
= "a.out";
502 char **ld1_argv
= (char **) xcalloc (sizeof (char *), argc
+2);
503 char **ld1
= ld1_argv
;
504 char **ld2_argv
= (char **) xcalloc (sizeof (char *), argc
+5);
505 char **ld2
= ld2_argv
;
507 int num_c_args
= argc
+7;
516 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
521 while (*q
&& *q
!= ' ') q
++;
522 if (*p
== '-' && (p
[1] == 'm' || p
[1] == 'f'))
529 c_ptr
= c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
);
532 fatal ("no arguments");
534 signal (SIGQUIT
, handler
);
535 signal (SIGINT
, handler
);
536 signal (SIGALRM
, handler
);
537 signal (SIGHUP
, handler
);
538 signal (SIGSEGV
, handler
);
539 signal (SIGBUS
, handler
);
541 /* Try to discover a valid linker/assembler/nm to use. */
542 len
= strlen (argv
[0]);
544 if (len
>= sizeof ("ld")-1)
546 p
= argv
[0] + len
- sizeof ("ld") + 1;
547 if (strcmp (p
, "ld") == 0)
554 if (prefix
== (char *)0)
556 p
= strrchr (argv
[0], '/');
563 #ifdef STANDARD_EXEC_PREFIX
564 else if (access (STANDARD_EXEC_PREFIX
, X_OK
) == 0)
565 prefix
= STANDARD_EXEC_PREFIX
;
568 #ifdef MD_EXEC_PREFIX
569 else if (access (MD_EXEC_PREFIX
, X_OK
) == 0)
570 prefix
= MD_EXEC_PREFIX
;
573 else if (access ("/usr/ccs/gcc", X_OK
) == 0)
574 prefix
= "/usr/ccs/gcc/";
576 else if (access ("/usr/ccs/bin", X_OK
) == 0)
577 prefix
= "/usr/ccs/bin/";
583 clen
= len
= strlen (prefix
);
585 #ifdef STANDARD_BIN_PREFIX
586 if (clen
< sizeof (STANDARD_BIN_PREFIX
) - 1)
587 clen
= sizeof (STANDARD_BIN_PREFIX
) - 1;
590 ld_file_name
= xcalloc (len
+ sizeof ("real-ld"), 1);
591 nm_file_name
= xcalloc (len
+ sizeof ("gnm"), 1);
593 memcpy (ld_file_name
, prefix
, len
);
594 strcpy (ld_file_name
+ len
, "real-ld");
595 if (access (ld_file_name
, X_OK
) < 0)
597 strcpy (ld_file_name
+ len
, "gld");
598 if (access (ld_file_name
, X_OK
) < 0)
601 #ifdef REAL_LD_FILE_NAME
602 ld_file_name
= REAL_LD_FILE_NAME
;
604 ld_file_name
= (access ("/usr/bin/ld", X_OK
) == 0) ? "/usr/bin/ld" : "/bin/ld";
609 c_file_name
= getenv ("COLLECT_GCC");
610 if (c_file_name
== 0 || c_file_name
[0] != '/')
612 c_file_name
= xcalloc (clen
+ sizeof ("gcc"), 1);
613 memcpy (c_file_name
, prefix
, len
);
614 strcpy (c_file_name
+ len
, "gcc");
615 if (access (c_file_name
, X_OK
) < 0)
617 #ifdef STANDARD_BIN_PREFIX
618 strcpy (c_file_name
, STANDARD_BIN_PREFIX
);
619 strcat (c_file_name
, "gcc");
620 if (access (c_file_name
, X_OK
) < 0)
623 #ifdef STANDARD_EXEC_PREFIX
624 strcpy (c_file_name
, STANDARD_EXEC_PREFIX
);
625 strcat (c_file_name
, "gcc");
626 if (access (c_file_name
, X_OK
) < 0)
629 strcpy (c_file_name
, "gcc");
635 memcpy (nm_file_name
, prefix
, len
);
636 strcpy (nm_file_name
+ len
, "nm");
637 if (access (nm_file_name
, X_OK
) < 0)
639 strcpy (nm_file_name
+ len
, "gnm");
640 if (access (nm_file_name
, X_OK
) < 0)
643 #ifdef REAL_NM_FILE_NAME
644 nm_file_name
= REAL_NM_FILE_NAME
;
646 nm_file_name
= (access ("/usr/bin/nm", X_OK
) == 0) ? "/usr/bin/nm" : "/bin/nm";
651 *ld1
++ = *ld2
++ = "ld";
653 /* Make temp file names. */
655 c_file
= xcalloc (temp_filename_length
+ sizeof (".c"), 1);
656 o_file
= xcalloc (temp_filename_length
+ sizeof (".o"), 1);
657 sprintf (c_file
, "%s.c", temp_filename
);
658 sprintf (o_file
, "%s.o", temp_filename
);
659 *c_ptr
++ = c_file_name
;
664 /* !!! When GCC calls collect2,
665 it does not know whether it is calling collect2 or ld.
666 So collect2 cannot meaningfully understand any options
667 except those ld understands.
668 If you propose to make GCC pass some other option,
669 just imagine what will happen if ld is really ld!!! */
671 /* Parse arguments. Remember output file spec, pass the rest to ld. */
672 /* After the first file, put in the c++ rt0. */
675 while ((arg
= *++argv
) != (char *)0)
677 *ld1
++ = *ld2
++ = arg
;
683 if (!strcmp (arg
, "-debug"))
693 outfile
= (arg
[2] == '\0') ? argv
[1] : &arg
[2];
708 && (p
= strrchr (arg
, '.')) != (char *)0
709 && strcmp (p
, ".o") == 0)
716 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
717 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
722 while (*q
&& *q
!= ' ') q
++;
723 if (*p
== '-' && (p
[1] == 'm' || p
[1] == 'f'))
724 *c_ptr
++ = savestring (p
, q
- p
);
731 *c_ptr
= *ld1
= *ld2
= (char *)0;
735 fprintf (stderr
, "collect2 version %s", version_string
);
736 #ifdef TARGET_VERSION
739 fprintf (stderr
, "\n");
745 fprintf (stderr
, "prefix = %s\n", prefix
);
746 fprintf (stderr
, "ld_file_name = %s\n", ld_file_name
);
747 fprintf (stderr
, "c_file_name = %s\n", c_file_name
);
748 fprintf (stderr
, "nm_file_name = %s\n", nm_file_name
);
749 fprintf (stderr
, "c_file = %s\n", c_file
);
750 fprintf (stderr
, "o_file = %s\n", o_file
);
752 ptr
= getenv ("COLLECT_GCC_OPTIONS");
754 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
756 ptr
= getenv ("COLLECT_GCC");
758 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
760 ptr
= getenv ("COMPILER_PATH");
762 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
764 ptr
= getenv ("LIBRARY_PATH");
766 fprintf (stderr
, "LIBRARY_PATH = %s\n", ptr
);
768 fprintf (stderr
, "\n");
771 /* Load the program, searching all libraries.
772 Examine the namelist with nm and search it for static constructors
773 and destructors to call.
774 Write the constructor and destructor tables to a .s file and reload. */
776 fork_execute (ld_file_name
, ld1_argv
);
778 /* If -r, don't build the constructor or destructor list, just return now. */
782 scan_prog_file (outfile
, PASS_FIRST
);
786 fprintf (stderr
, "%d constructor(s) found\n", constructors
.number
);
787 fprintf (stderr
, "%d destructor(s) found\n", destructors
.number
);
790 if (constructors
.number
== 0 && destructors
.number
== 0)
793 outf
= fopen (c_file
, "w");
794 if (outf
== (FILE *)0)
795 fatal_perror ("Can't write %s", c_file
);
797 write_c_file (outf
, c_file
);
800 fatal_perror ("Can't close %s", c_file
);
804 fprintf (stderr
, "\n========== outfile = %s, c_file = %s\n", outfile
, c_file
);
805 write_c_file (stderr
, "stderr");
806 fprintf (stderr
, "========== end of c_file\n\n");
809 /* Assemble the constructor and destructor tables.
810 Link the tables in with the rest of the program. */
812 fork_execute (c_file_name
, c_argv
);
813 fork_execute (ld_file_name
, ld2_argv
);
815 /* Let scan_prog_file do any final mods (OSF/rose needs this for
816 constructors/destructors in shared libraries. */
817 scan_prog_file (outfile
, PASS_SECOND
);
819 maybe_unlink (c_file
);
820 maybe_unlink (o_file
);
825 /* Wait for a process to finish, and exit if a non-zero status is found. */
836 int sig
= status
& 0x7F;
839 if (sig
!= -1 && sig
!= 0)
841 #ifdef NO_SYS_SIGLIST
842 error ("%s terminated with signal %d %s",
845 (status
& 0200) ? ", core dumped" : "");
847 error ("%s terminated with signal %d [%s]%s",
851 (status
& 0200) ? ", core dumped" : "");
857 ret
= ((status
& 0xFF00) >> 8);
858 if (ret
!= -1 && ret
!= 0)
860 error ("%s returned %d exit status", prog
, ret
);
867 /* Fork and execute a program, and wait for the reply. */
870 fork_execute (prog
, argv
)
875 void (*int_handler
) ();
876 void (*quit_handler
) ();
883 fprintf (stderr
, "%s", prog
);
884 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
885 fprintf (stderr
, " %s", str
);
887 fprintf (stderr
, "\n");
895 fatal_perror ("vfork");
897 if (pid
== 0) /* child context */
900 fatal_perror ("Execute %s", prog
);
903 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
904 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
908 signal (SIGINT
, int_handler
);
909 signal (SIGQUIT
, quit_handler
);
913 /* Unlink a file unless we are debugging. */
922 fprintf (stderr
, "[Leaving %s]\n", file
);
926 /* Add a name to a linked list. */
929 add_to_list (head_ptr
, name
)
930 struct head
*head_ptr
;
933 struct id
*newid
= (struct id
*) xcalloc (sizeof (*newid
) + strlen (name
), 1);
934 static long sequence_number
= 0;
935 newid
->sequence
= ++sequence_number
;
936 strcpy (newid
->name
, name
);
939 head_ptr
->last
->next
= newid
;
941 head_ptr
->first
= newid
;
943 head_ptr
->last
= newid
;
947 /* Write: `prefix', the names on list LIST, `suffix'. */
950 write_list (stream
, prefix
, list
)
957 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
963 write_list_with_asm (stream
, prefix
, list
)
970 fprintf (stream
, "%sx%d asm (\"%s\");\n",
971 prefix
, list
->sequence
, list
->name
);
976 /* Write the constructor/destructor tables. */
979 write_c_file (stream
, name
)
983 /* Write the tables as C code */
985 fprintf (stream
, "typedef void entry_pt();\n\n");
987 write_list_with_asm (stream
, "entry_pt ", constructors
.first
);
989 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
990 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
);
991 write_list (stream
, "\t", constructors
.first
);
992 fprintf (stream
, "\t0\n};\n\n");
994 write_list_with_asm (stream
, "entry_pt ", destructors
.first
);
996 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
997 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
);
998 write_list (stream
, "\t", destructors
.first
);
999 fprintf (stream
, "\t0\n};\n\n");
1001 fprintf (stream
, "extern entry_pt __main;\n");
1002 fprintf (stream
, "entry_pt *__main_reference = __main;\n\n");
1006 #ifdef OBJECT_FORMAT_NONE
1008 /* Generic version to scan the name list of the loaded program for
1009 the symbols g++ uses for static constructors and destructors.
1011 The constructor table begins at __CTOR_LIST__ and contains a count
1012 of the number of pointers (or -1 if the constructors are built in a
1013 separate section by the linker), followed by the pointers to the
1014 constructor functions, terminated with a null pointer. The
1015 destructor table has the same format, and begins at __DTOR_LIST__. */
1018 scan_prog_file (prog_name
, which_pass
)
1020 enum pass which_pass
;
1022 void (*int_handler
) ();
1023 void (*quit_handler
) ();
1031 if (which_pass
!= PASS_FIRST
)
1034 nm_argv
[argc
++] = "nm";
1035 if (NM_FLAGS
[0] != '\0')
1036 nm_argv
[argc
++] = NM_FLAGS
;
1038 nm_argv
[argc
++] = prog_name
;
1039 nm_argv
[argc
++] = (char *)0;
1041 if (pipe (pipe_fd
) < 0)
1042 fatal_perror ("pipe");
1044 inf
= fdopen (pipe_fd
[0], "r");
1045 if (inf
== (FILE *)0)
1046 fatal_perror ("fdopen");
1048 /* Trace if needed. */
1054 fprintf (stderr
, "%s", nm_file_name
);
1055 for (p_argv
= &nm_argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
1056 fprintf (stderr
, " %s", str
);
1058 fprintf (stderr
, "\n");
1064 /* Spawn child nm on pipe */
1067 fatal_perror ("vfork");
1069 if (pid
== 0) /* child context */
1072 if (dup2 (pipe_fd
[1], 1) < 0)
1073 fatal_perror ("Dup2 (%d, 1)", pipe_fd
[1]);
1075 if (close (pipe_fd
[0]) < 0)
1076 fatal_perror ("Close (%d)", pipe_fd
[0]);
1078 if (close (pipe_fd
[1]) < 0)
1079 fatal_perror ("Close (%d)", pipe_fd
[1]);
1081 execv (nm_file_name
, nm_argv
);
1082 fatal_perror ("Execute %s", nm_file_name
);
1085 /* Parent context from here on. */
1086 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
1087 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
1089 if (close (pipe_fd
[1]) < 0)
1090 fatal_perror ("Close (%d)", pipe_fd
[1]);
1093 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
1095 /* Read each line of nm output. */
1096 while (fgets (buf
, sizeof buf
, inf
) != (char *)0)
1101 /* If it contains a constructor or destructor name, add the name
1102 to the appropriate list. */
1104 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
1107 if (ch
== '\0' || ch
== '\n')
1111 /* Find the end of the symbol name.
1112 Don't include `|', because Encore nm can tack that on the end. */
1113 for (end
= p
; (ch2
= *end
) != '\0' && !isspace (ch2
) && ch2
!= '|';
1118 switch (is_ctor_dtor (name
))
1121 add_to_list (&constructors
, name
);
1125 add_to_list (&destructors
, name
);
1128 default: /* not a constructor or destructor */
1133 fprintf (stderr
, "\t%s\n", buf
);
1137 fprintf (stderr
, "\n");
1139 if (fclose (inf
) != 0)
1140 fatal_perror ("fclose of pipe");
1142 do_wait (nm_file_name
);
1144 signal (SIGINT
, int_handler
);
1145 signal (SIGQUIT
, quit_handler
);
1148 #endif /* OBJECT_FORMAT_NONE */
1152 * COFF specific stuff.
1155 #ifdef OBJECT_FORMAT_COFF
1157 #if defined(EXTENDED_COFF)
1158 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax+SYMHEADER(X).iextMax)
1159 # define GCC_SYMENT SYMR
1160 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
1161 # define GCC_SYMINC(X) (1)
1162 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
1164 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
1165 # define GCC_SYMENT SYMENT
1166 # define GCC_OK_SYMBOL(X) \
1167 (((X).n_sclass == C_EXT) && \
1168 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
1169 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
1170 # define GCC_SYMINC(X) ((X).n_numaux+1)
1171 # define GCC_SYMZERO(X) 0
1174 extern char *ldgetname ();
1176 /* COFF version to scan the name list of the loaded program for
1177 the symbols g++ uses for static constructors and destructors.
1179 The constructor table begins at __CTOR_LIST__ and contains a count
1180 of the number of pointers (or -1 if the constructors are built in a
1181 separate section by the linker), followed by the pointers to the
1182 constructor functions, terminated with a null pointer. The
1183 destructor table has the same format, and begins at __DTOR_LIST__. */
1186 scan_prog_file (prog_name
, which_pass
)
1188 enum pass which_pass
;
1191 int sym_index
, sym_count
;
1193 if (which_pass
!= PASS_FIRST
)
1196 if ((ldptr
= ldopen (prog_name
, ldptr
)) == NULL
)
1197 fatal ("%s: can't open as COFF file", prog_name
);
1199 if (!ISCOFF (HEADER(ldptr
).f_magic
))
1200 fatal ("%s: not a COFF file", prog_name
);
1202 sym_count
= GCC_SYMBOLS (ldptr
);
1203 sym_index
= GCC_SYMZERO (ldptr
);
1204 while (sym_index
< sym_count
)
1208 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
1210 sym_index
+= GCC_SYMINC (symbol
);
1212 if (GCC_OK_SYMBOL (symbol
))
1216 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
1217 continue; /* should never happen */
1220 /* All AIX function names begin with a dot. */
1225 switch (is_ctor_dtor (name
))
1228 add_to_list (&constructors
, name
);
1232 add_to_list (&destructors
, name
);
1235 default: /* not a constructor or destructor */
1239 #if !defined(EXTENDED_COFF)
1241 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
1242 symbol
.n_scnum
, symbol
.n_sclass
,
1243 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
1247 fprintf (stderr
, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1248 symbol
.iss
, symbol
.value
, symbol
.index
, name
);
1253 (void) ldclose(ldptr
);
1256 #endif /* OBJECT_FORMAT_COFF */
1260 * OSF/rose specific stuff.
1263 #ifdef OBJECT_FORMAT_ROSE
1265 /* Union of the various load commands */
1267 typedef union load_union
1269 ldc_header_t hdr
; /* common header */
1270 load_cmd_map_command_t map
; /* map indexing other load cmds */
1271 interpreter_command_t iprtr
; /* interpreter pathname */
1272 strings_command_t str
; /* load commands strings section */
1273 region_command_t region
; /* region load command */
1274 reloc_command_t reloc
; /* relocation section */
1275 package_command_t pkg
; /* package load command */
1276 symbols_command_t sym
; /* symbol sections */
1277 entry_command_t ent
; /* program start section */
1278 gen_info_command_t info
; /* object information */
1279 func_table_command_t func
; /* function constructors/destructors */
1282 /* Structure to point to load command and data section in memory. */
1284 typedef struct load_all
1286 load_union_t
*load
; /* load command */
1287 char *section
; /* pointer to section */
1290 /* Structure to contain information about a file mapped into memory. */
1294 char *start
; /* start of map */
1295 char *name
; /* filename */
1296 long size
; /* size of the file */
1297 long rounded_size
; /* size rounded to page boundary */
1298 int fd
; /* file descriptor */
1299 int rw
; /* != 0 if opened read/write */
1300 int use_mmap
; /* != 0 if mmap'ed */
1303 extern int decode_mach_o_hdr ();
1305 extern int encode_mach_o_hdr ();
1307 static void bad_header ();
1309 static void print_header ();
1311 static void print_load_command ();
1313 static void add_func_table ();
1315 static struct file_info
*read_file ();
1317 static void end_file ();
1320 /* OSF/rose specific version to scan the name list of the loaded
1321 program for the symbols g++ uses for static constructors and
1324 The constructor table begins at __CTOR_LIST__ and contains a count
1325 of the number of pointers (or -1 if the constructors are built in a
1326 separate section by the linker), followed by the pointers to the
1327 constructor functions, terminated with a null pointer. The
1328 destructor table has the same format, and begins at __DTOR_LIST__. */
1331 scan_prog_file (prog_name
, which_pass
)
1333 enum pass which_pass
;
1337 load_all_t
*load_array
;
1338 load_all_t
*load_end
;
1339 load_all_t
*load_cmd
;
1340 int symbol_load_cmds
;
1346 struct file_info
*obj_file
;
1348 mo_lcid_t cmd_strings
= -1;
1349 symbol_info_t
*main_sym
= 0;
1350 int rw
= (which_pass
!= PASS_FIRST
);
1352 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
1354 fatal_perror ("Can't read %s", prog_name
);
1356 obj_file
= read_file (prog_name
, prog_fd
, rw
);
1357 obj
= obj_file
->start
;
1359 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
1360 if (status
!= MO_HDR_CONV_SUCCESS
)
1361 bad_header (status
);
1364 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
1365 since the hardware will automatically swap bytes for us on loading little endian
1368 #ifndef CROSS_COMPILE
1369 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
1370 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
1371 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
1372 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
1373 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
1374 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
1375 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
1377 fatal ("incompatibilities exist between object file & expected values.");
1382 print_header (&hdr
);
1384 offset
= hdr
.moh_first_cmd_off
;
1385 load_end
= load_array
1386 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
1388 /* Build array of load commands, calculating the offsets */
1389 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1391 load_union_t
*load_hdr
; /* load command header */
1393 load_cmd
= load_end
++;
1394 load_hdr
= (load_union_t
*) (obj
+ offset
);
1396 /* If modifing the program file, copy the header. */
1399 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
1400 memcpy (ptr
, load_hdr
, load_hdr
->hdr
.ldci_cmd_size
);
1403 /* null out old command map, because we will rewrite at the end. */
1404 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1406 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
1407 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
1411 load_cmd
->load
= load_hdr
;
1412 if (load_hdr
->hdr
.ldci_section_off
> 0)
1413 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
1416 print_load_command (load_hdr
, offset
, i
);
1418 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
1421 /* If the last command is the load command map and is not undefined,
1422 decrement the count of load commands. */
1423 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
1426 hdr
.moh_n_load_cmds
--;
1429 /* Go through and process each symbol table section. */
1430 symbol_load_cmds
= 0;
1431 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
1433 load_union_t
*load_hdr
= load_cmd
->load
;
1435 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
1441 char *kind
= "unknown";
1443 switch (load_hdr
->sym
.symc_kind
)
1445 case SYMC_IMPORTS
: kind
= "imports"; break;
1446 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
1447 case SYMC_STABS
: kind
= "stabs"; break;
1450 fprintf (stderr
, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1451 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
1454 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
1457 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
1458 if (str_sect
== (char *)0)
1459 fatal ("string section missing");
1461 if (load_cmd
->section
== (char *)0)
1462 fatal ("section pointer missing");
1464 num_syms
= load_hdr
->sym
.symc_nentries
;
1465 for (i
= 0; i
< num_syms
; i
++)
1467 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
1468 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
1478 if (*n
!= 'm' || (n
- name
) < 2 || strcmp (n
, "main"))
1485 switch (is_ctor_dtor (name
))
1488 add_to_list (&constructors
, name
);
1492 add_to_list (&destructors
, name
);
1495 default: /* not a constructor or destructor */
1501 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
1502 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
1507 if (symbol_load_cmds
== 0)
1508 fatal ("no symbol table found.");
1510 /* Update the program file now, rewrite header and load commands. At present,
1511 we assume that there is enough space after the last load command to insert
1512 one more. Since the first section written out is page aligned, and the
1513 number of load commands is small, this is ok for the present. */
1517 load_union_t
*load_map
;
1520 if (cmd_strings
== -1)
1521 fatal ("no cmd_strings found.");
1523 /* Add __main to initializer list. */
1524 if (main_sym
!= (symbol_info_t
*)0)
1525 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
1528 fprintf (stderr
, "\nUpdating header and load commands.\n\n");
1530 hdr
.moh_n_load_cmds
++;
1531 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
1533 /* Create new load command map. */
1535 fprintf (stderr
, "load command map, %d cmds, new size %ld.\n",
1536 (int)hdr
.moh_n_load_cmds
, (long)size
);
1538 load_map
= (load_union_t
*) xcalloc (1, size
);
1539 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
1540 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
1541 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
1542 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
1543 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
1545 offset
= hdr
.moh_first_cmd_off
;
1546 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1548 load_map
->map
.lcm_map
[i
] = offset
;
1549 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1550 hdr
.moh_load_map_cmd_off
= offset
;
1552 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
1555 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
1558 print_header (&hdr
);
1561 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
1562 if (status
!= MO_HDR_CONV_SUCCESS
)
1563 bad_header (status
);
1566 fprintf (stderr
, "writing load commands.\n\n");
1568 /* Write load commands */
1569 offset
= hdr
.moh_first_cmd_off
;
1570 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1572 load_union_t
*load_hdr
= load_array
[i
].load
;
1573 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
1576 print_load_command (load_hdr
, offset
, i
);
1578 memcpy (obj
+ offset
, load_hdr
, size
);
1583 end_file (obj_file
);
1585 if (close (prog_fd
))
1586 fatal_perror ("Can't close %s", prog_name
);
1589 fprintf (stderr
, "\n");
1593 /* Add a function table to the load commands to call a function
1594 on initiation or termination of the process. */
1597 add_func_table (hdr_p
, load_array
, sym
, type
)
1598 mo_header_t
*hdr_p
; /* pointer to global header */
1599 load_all_t
*load_array
; /* array of ptrs to load cmds */
1600 symbol_info_t
*sym
; /* pointer to symbol entry */
1601 int type
; /* fntc_type value */
1603 /* Add a new load command. */
1604 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
1605 int load_index
= num_cmds
- 1;
1606 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
1607 load_union_t
*ptr
= xcalloc (1, size
);
1608 load_all_t
*load_cmd
;
1611 /* Set the unresolved address bit in the header to force the loader to be
1612 used, since kernel exec does not call the initialization functions. */
1613 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
1615 load_cmd
= &load_array
[load_index
];
1616 load_cmd
->load
= ptr
;
1617 load_cmd
->section
= (char *)0;
1619 /* Fill in func table load command. */
1620 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
1621 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
1622 ptr
->func
.ldc_header
.ldci_section_off
= 0;
1623 ptr
->func
.ldc_header
.ldci_section_len
= 0;
1624 ptr
->func
.fntc_type
= type
;
1625 ptr
->func
.fntc_nentries
= 1;
1627 /* copy address, turn it from abs. address to (region,offset) if necessary. */
1628 /* Is the symbol already expressed as (region, offset)? */
1629 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
1631 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
1632 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
1635 /* If not, figure out which region it's in. */
1638 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
1641 for (i
= 0; i
< load_index
; i
++)
1643 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
1645 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
1647 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
1648 && addr
>= region_ptr
->regc_addr
.vm_addr
1649 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
1651 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
1652 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
1660 fatal ("could not convert 0x%l.8x into a region", addr
);
1665 "%s function, region %d, offset = %ld (0x%.8lx)\n",
1666 (type
== FNTC_INITIALIZATION
) ? "init" : "term",
1667 (int)ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
1668 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
1669 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
1674 /* Print the global header for an OSF/rose object. */
1677 print_header (hdr_ptr
)
1678 mo_header_t
*hdr_ptr
;
1680 fprintf (stderr
, "\nglobal header:\n");
1681 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
1682 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
1683 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
1684 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
1685 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
1686 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
1687 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
1688 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
1689 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
1690 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
1691 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
1692 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
1693 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
1694 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
1695 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
1697 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
1698 fprintf (stderr
, ", relocatable");
1700 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
1701 fprintf (stderr
, ", linkable");
1703 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
1704 fprintf (stderr
, ", execable");
1706 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
1707 fprintf (stderr
, ", executable");
1709 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
1710 fprintf (stderr
, ", unresolved");
1712 fprintf (stderr
, "\n\n");
1717 /* Print a short summary of a load command. */
1720 print_load_command (load_hdr
, offset
, number
)
1721 load_union_t
*load_hdr
;
1725 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
1726 char *type_str
= (char *)0;
1730 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
1731 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
1732 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
1733 case LDC_STRINGS
: type_str
= "STRINGS"; break;
1734 case LDC_REGION
: type_str
= "REGION"; break;
1735 case LDC_RELOC
: type_str
= "RELOC"; break;
1736 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
1737 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
1738 case LDC_ENTRY
: type_str
= "ENTRY"; break;
1739 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
1740 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
1744 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
1746 (long) load_hdr
->hdr
.ldci_cmd_size
,
1748 (long) load_hdr
->hdr
.ldci_section_off
,
1749 (long) load_hdr
->hdr
.ldci_section_len
);
1751 if (type_str
== (char *)0)
1752 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
1754 else if (type
!= LDC_REGION
)
1755 fprintf (stderr
, ", ty: %s\n", type_str
);
1760 switch (load_hdr
->region
.regc_usage_type
)
1762 case REG_TEXT_T
: region
= ", .text"; break;
1763 case REG_DATA_T
: region
= ", .data"; break;
1764 case REG_BSS_T
: region
= ", .bss"; break;
1765 case REG_GLUE_T
: region
= ", .glue"; break;
1766 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
1767 case REG_RDATA_T
: region
= ", .rdata"; break;
1768 case REG_SDATA_T
: region
= ", .sdata"; break;
1769 case REG_SBSS_T
: region
= ", .sbss"; break;
1773 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
1775 (long) load_hdr
->region
.regc_vm_addr
,
1776 (long) load_hdr
->region
.regc_vm_size
,
1784 /* Fatal error when {en,de}code_mach_o_header fails. */
1790 char *msg
= (char *)0;
1794 case MO_ERROR_BAD_MAGIC
: msg
= "bad magic number"; break;
1795 case MO_ERROR_BAD_HDR_VERS
: msg
= "bad header version"; break;
1796 case MO_ERROR_BAD_RAW_HDR_VERS
: msg
= "bad raw header version"; break;
1797 case MO_ERROR_BUF2SML
: msg
= "raw header buffer too small"; break;
1798 case MO_ERROR_OLD_RAW_HDR_FILE
: msg
= "old raw header file"; break;
1799 case MO_ERROR_UNSUPPORTED_VERS
: msg
= "unsupported version"; break;
1802 if (msg
== (char *)0)
1803 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
1809 /* Read a file into a memory buffer. */
1811 static struct file_info
*
1812 read_file (name
, fd
, rw
)
1813 char *name
; /* filename */
1814 int fd
; /* file descriptor */
1815 int rw
; /* read/write */
1817 struct stat stat_pkt
;
1818 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
1820 static int page_size
;
1823 if (fstat (fd
, &stat_pkt
) < 0)
1824 fatal_perror ("fstat %s", name
);
1827 p
->size
= stat_pkt
.st_size
;
1828 p
->rounded_size
= stat_pkt
.st_size
;
1834 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
1837 page_size
= sysconf (_SC_PAGE_SIZE
);
1839 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
1840 p
->start
= mmap ((caddr_t
)0,
1841 (rw
) ? p
->rounded_size
: p
->size
,
1842 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
1843 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
1847 if (p
->start
!= (char *)0 && p
->start
!= (char *)-1)
1851 #endif /* USE_MMAP */
1856 fprintf (stderr
, "read %s\n", name
);
1859 p
->start
= xmalloc (p
->size
);
1860 if (lseek (fd
, 0L, SEEK_SET
) < 0)
1861 fatal_perror ("lseek to 0 on %s", name
);
1863 len
= read (fd
, p
->start
, p
->size
);
1865 fatal_perror ("read %s", name
);
1868 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
1875 /* Do anything necessary to write a file back from memory. */
1879 struct file_info
*ptr
; /* file information block */
1887 fprintf (stderr
, "msync %s\n", ptr
->name
);
1889 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
1890 fatal_perror ("msync %s", ptr
->name
);
1894 fprintf (stderr
, "munmap %s\n", ptr
->name
);
1896 if (munmap (ptr
->start
, ptr
->size
))
1897 fatal_perror ("munmap %s", ptr
->name
);
1900 #endif /* USE_MMAP */
1907 fprintf (stderr
, "write %s\n", ptr
->name
);
1909 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
1910 fatal_perror ("lseek to 0 on %s", ptr
->name
);
1912 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
1914 fatal_perror ("read %s", ptr
->name
);
1916 if (len
!= ptr
->size
)
1917 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
1920 free ((generic
*)ptr
->start
);
1923 free ((generic
*)ptr
);
1926 #endif /* OBJECT_FORMAT_ROSE */