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>
65 /* On MSDOS, write temp files in current dir
66 because there's no place else we can expect to use. */
73 /* On certain systems, we have code that works by scanning the object file
74 directly. But this code uses system-specific header files and library
75 functions, so turn it off in a cross-compiler. */
78 #undef OBJECT_FORMAT_COFF
79 #undef OBJECT_FORMAT_ROSE
82 /* If we can't use a special method, use the ordinary one:
83 run nm to find what symbols are present.
84 In a cross-compiler, this means you need a cross nm,
85 but that isn't quite as unpleasant as special headers. */
87 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
88 #define OBJECT_FORMAT_NONE
91 #ifdef OBJECT_FORMAT_COFF
101 #define ISCOFF(magic) \
102 ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC || (magic) == U802TOCMAGIC)
105 #if defined (_AIX) || defined (USG)
112 #endif /* OBJECT_FORMAT_COFF */
114 #ifdef OBJECT_FORMAT_ROSE
121 #include <sys/mman.h>
125 #include <mach_o_format.h>
126 #include <mach_o_header.h>
127 #include <mach_o_vals.h>
128 #include <mach_o_types.h>
130 #endif /* OBJECT_FORMAT_ROSE */
132 #ifdef OBJECT_FORMAT_NONE
134 /* Default flags to pass to nm. */
136 #define NM_FLAGS "-p"
139 #endif /* OBJECT_FORMAT_NONE */
141 /* Linked lists of constructor and destructor names. */
157 /* Enumeration giving which pass this is for scanning the program file. */
160 PASS_FIRST
, /* without constructors */
161 PASS_SECOND
/* with constructors linked in */
164 #ifndef NO_SYS_SIGLIST
165 extern char *sys_siglist
[];
167 extern char *version_string
;
169 static int vflag
; /* true if -v */
170 static int rflag
; /* true if -r */
172 static int debug
; /* true if -debug */
174 static int temp_filename_length
; /* Length of temp_filename */
175 static char *temp_filename
; /* Base of temp filenames */
176 static char *c_file
; /* <xxx>.c for constructor/destructor list. */
177 static char *o_file
; /* <xxx>.o for constructor/destructor list. */
178 static char *nm_file_name
; /* pathname of nm */
180 static struct head constructors
; /* list of constructors found */
181 static struct head destructors
; /* list of destructors found */
183 extern char *getenv ();
184 extern char *mktemp ();
186 static void add_to_list ();
187 static void scan_prog_file ();
188 static void fork_execute ();
189 static void do_wait ();
190 static void write_c_file ();
191 static void my_exit ();
192 static void handler ();
193 static void maybe_unlink ();
194 static void choose_temp_base ();
203 extern char *sys_errlist
[];
205 static char buffer
[30];
210 if (e
> 0 && e
< sys_nerr
)
211 return sys_errlist
[e
];
213 sprintf (buffer
, "Unknown error %d", e
);
217 /* Delete tempfiles and exit function. */
223 if (c_file
!= 0 && c_file
[0])
224 maybe_unlink (c_file
);
226 if (o_file
!= 0 && o_file
[0])
227 maybe_unlink (o_file
);
233 /* Die when sys call fails. */
236 fatal_perror (string
, arg1
, arg2
, arg3
)
241 fprintf (stderr
, "collect: ");
242 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
243 fprintf (stderr
, ": %s\n", my_strerror (e
));
250 fatal (string
, arg1
, arg2
, arg3
)
253 fprintf (stderr
, "collect: ");
254 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
255 fprintf (stderr
, "\n");
259 /* Write error message. */
262 error (string
, arg1
, arg2
, arg3
, arg4
)
265 fprintf (stderr
, "collect: ");
266 fprintf (stderr
, string
, arg1
, arg2
, arg3
, arg4
);
267 fprintf (stderr
, "\n");
270 /* In case obstack is linked in, and abort is defined to fancy_abort,
271 provide a default entry. */
276 fatal ("internal error");
285 maybe_unlink (c_file
);
288 maybe_unlink (o_file
);
290 signal (signo
, SIG_DFL
);
291 kill (getpid (), signo
);
296 xcalloc (size1
, size2
)
299 generic
*ptr
= (generic
*) calloc (size1
, size2
);
303 fatal ("out of memory");
311 generic
*ptr
= (generic
*) malloc (size
);
315 fatal ("out of memory");
319 /* Make a copy of a string INPUT with size SIZE. */
322 savestring (input
, size
)
326 char *output
= (char *) xmalloc (size
+ 1);
327 bcopy (input
, output
, size
);
332 /* Decide whether the given symbol is:
333 a constructor (1), a destructor (2), or neither (0). */
339 struct names
{ char *name
; int len
; int ret
; int two_underscores
; };
341 register struct names
*p
;
343 register char *orig_s
= s
;
345 static struct names special
[] = {
346 #ifdef NO_DOLLAR_IN_LABEL
347 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
348 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
350 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
351 { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 },
353 { "sti__", sizeof ("sti__")-1, 1, 1 },
354 { "std__", sizeof ("std__")-1, 2, 1 },
358 while ((ch
= *s
) == '_')
364 for (p
= &special
[0]; p
->len
> 0; p
++)
367 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
368 && strncmp(s
, p
->name
, p
->len
) == 0)
377 /* Compute a string to use as the base of all temporary file names.
378 It is substituted for %g. */
383 char *base
= getenv ("TMPDIR");
386 if (base
== (char *)0)
389 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
392 if (base
== (char *)0)
394 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
402 temp_filename
= xmalloc (len
+ sizeof("/ccXXXXXX"));
403 strcpy (temp_filename
, base
);
404 if (len
> 0 && temp_filename
[len
-1] != '/')
405 temp_filename
[len
++] = '/';
406 strcpy (temp_filename
+ len
, "ccXXXXXX");
408 mktemp (temp_filename
);
409 temp_filename_length
= strlen (temp_filename
);
420 char *outfile
= "a.out";
429 char **ld1_argv
= (char **) xcalloc (sizeof (char *), argc
+2);
430 char **ld1
= ld1_argv
;
431 char **ld2_argv
= (char **) xcalloc (sizeof (char *), argc
+5);
432 char **ld2
= ld2_argv
;
434 int num_c_args
= argc
+7;
443 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
448 while (*q
&& *q
!= ' ') q
++;
449 if (*p
== '-' && (p
[1] == 'm' || p
[1] == 'f'))
456 c_ptr
= c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
);
459 fatal ("no arguments");
461 signal (SIGQUIT
, handler
);
462 signal (SIGINT
, handler
);
463 signal (SIGALRM
, handler
);
464 signal (SIGHUP
, handler
);
465 signal (SIGSEGV
, handler
);
466 signal (SIGBUS
, handler
);
468 /* Try to discover a valid linker/assembler/nm to use. */
469 len
= strlen (argv
[0]);
471 if (len
>= sizeof ("ld")-1)
473 p
= argv
[0] + len
- sizeof ("ld") + 1;
474 if (strcmp (p
, "ld") == 0)
481 if (prefix
== (char *)0)
483 p
= strrchr (argv
[0], '/');
490 #ifdef STANDARD_EXEC_PREFIX
491 else if (access (STANDARD_EXEC_PREFIX
, X_OK
) == 0)
492 prefix
= STANDARD_EXEC_PREFIX
;
495 #ifdef MD_EXEC_PREFIX
496 else if (access (MD_EXEC_PREFIX
, X_OK
) == 0)
497 prefix
= MD_EXEC_PREFIX
;
500 else if (access ("/usr/ccs/gcc", X_OK
) == 0)
501 prefix
= "/usr/ccs/gcc/";
503 else if (access ("/usr/ccs/bin", X_OK
) == 0)
504 prefix
= "/usr/ccs/bin/";
510 clen
= len
= strlen (prefix
);
512 #ifdef STANDARD_BIN_PREFIX
513 if (clen
< sizeof (STANDARD_BIN_PREFIX
) - 1)
514 clen
= sizeof (STANDARD_BIN_PREFIX
) - 1;
517 ld_file_name
= xcalloc (len
+ sizeof ("real-ld"), 1);
518 nm_file_name
= xcalloc (len
+ sizeof ("gnm"), 1);
520 memcpy (ld_file_name
, prefix
, len
);
521 strcpy (ld_file_name
+ len
, "real-ld");
522 if (access (ld_file_name
, X_OK
) < 0)
524 strcpy (ld_file_name
+ len
, "gld");
525 if (access (ld_file_name
, X_OK
) < 0)
528 #ifdef REAL_LD_FILE_NAME
529 ld_file_name
= REAL_LD_FILE_NAME
;
531 ld_file_name
= (access ("/usr/bin/ld", X_OK
) == 0) ? "/usr/bin/ld" : "/bin/ld";
536 c_file_name
= getenv ("COLLECT_GCC");
537 if (c_file_name
== 0 || c_file_name
[0] != '/')
539 c_file_name
= xcalloc (clen
+ sizeof ("gcc"), 1);
540 memcpy (c_file_name
, prefix
, len
);
541 strcpy (c_file_name
+ len
, "gcc");
542 if (access (c_file_name
, X_OK
) < 0)
544 #ifdef STANDARD_BIN_PREFIX
545 strcpy (c_file_name
, STANDARD_BIN_PREFIX
);
546 strcat (c_file_name
, "gcc");
547 if (access (c_file_name
, X_OK
) < 0)
550 #ifdef STANDARD_EXEC_PREFIX
551 strcpy (c_file_name
, STANDARD_EXEC_PREFIX
);
552 strcat (c_file_name
, "gcc");
553 if (access (c_file_name
, X_OK
) < 0)
556 strcpy (c_file_name
, "gcc");
562 memcpy (nm_file_name
, prefix
, len
);
563 strcpy (nm_file_name
+ len
, "nm");
564 if (access (nm_file_name
, X_OK
) < 0)
566 strcpy (nm_file_name
+ len
, "gnm");
567 if (access (nm_file_name
, X_OK
) < 0)
570 #ifdef REAL_NM_FILE_NAME
571 nm_file_name
= REAL_NM_FILE_NAME
;
573 nm_file_name
= (access ("/usr/bin/nm", X_OK
) == 0) ? "/usr/bin/nm" : "/bin/nm";
578 *ld1
++ = *ld2
++ = "ld";
580 /* Make temp file names. */
582 c_file
= xcalloc (temp_filename_length
+ sizeof (".c"), 1);
583 o_file
= xcalloc (temp_filename_length
+ sizeof (".o"), 1);
584 sprintf (c_file
, "%s.c", temp_filename
);
585 sprintf (o_file
, "%s.o", temp_filename
);
586 *c_ptr
++ = c_file_name
;
591 /* !!! When GCC calls collect2,
592 it does not know whether it is calling collect2 or ld.
593 So collect2 cannot meaningfully understand any options
594 except those ld understands.
595 If you propose to make GCC pass some other option,
596 just imagine what will happen if ld is really ld!!! */
598 /* Parse arguments. Remember output file spec, pass the rest to ld. */
599 /* After the first file, put in the c++ rt0. */
602 while ((arg
= *++argv
) != (char *)0)
604 *ld1
++ = *ld2
++ = arg
;
610 if (!strcmp (arg
, "-debug"))
620 outfile
= (arg
[2] == '\0') ? argv
[1] : &arg
[2];
635 && (p
= strrchr (arg
, '.')) != (char *)0
636 && strcmp (p
, ".o") == 0)
643 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
644 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
649 while (*q
&& *q
!= ' ') q
++;
650 if (*p
== '-' && (p
[1] == 'm' || p
[1] == 'f'))
651 *c_ptr
++ = savestring (p
, q
- p
);
658 *c_ptr
= *ld1
= *ld2
= (char *)0;
662 fprintf (stderr
, "collect2 version %s", version_string
);
663 #ifdef TARGET_VERSION
666 fprintf (stderr
, "\n");
672 fprintf (stderr
, "prefix = %s\n", prefix
);
673 fprintf (stderr
, "ld_file_name = %s\n", ld_file_name
);
674 fprintf (stderr
, "c_file_name = %s\n", c_file_name
);
675 fprintf (stderr
, "nm_file_name = %s\n", nm_file_name
);
676 fprintf (stderr
, "c_file = %s\n", c_file
);
677 fprintf (stderr
, "o_file = %s\n", o_file
);
679 ptr
= getenv ("COLLECT_GCC_OPTIONS");
681 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
683 ptr
= getenv ("COLLECT_GCC");
685 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
687 ptr
= getenv ("COMPILER_PATH");
689 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
691 ptr
= getenv ("LIBRARY_PATH");
693 fprintf (stderr
, "LIBRARY_PATH = %s\n", ptr
);
695 fprintf (stderr
, "\n");
698 /* Load the program, searching all libraries.
699 Examine the namelist with nm and search it for static constructors
700 and destructors to call.
701 Write the constructor and destructor tables to a .s file and reload. */
703 fork_execute (ld_file_name
, ld1_argv
);
705 /* If -r, don't build the constructor or destructor list, just return now. */
709 scan_prog_file (outfile
, PASS_FIRST
);
713 fprintf (stderr
, "%d constructor(s) found\n", constructors
.number
);
714 fprintf (stderr
, "%d destructor(s) found\n", destructors
.number
);
717 if (constructors
.number
== 0 && destructors
.number
== 0)
720 outf
= fopen (c_file
, "w");
721 if (outf
== (FILE *)0)
722 fatal_perror ("%s", c_file
);
724 write_c_file (outf
, c_file
);
727 fatal_perror ("closing %s", c_file
);
731 fprintf (stderr
, "\n========== outfile = %s, c_file = %s\n", outfile
, c_file
);
732 write_c_file (stderr
, "stderr");
733 fprintf (stderr
, "========== end of c_file\n\n");
736 /* Assemble the constructor and destructor tables.
737 Link the tables in with the rest of the program. */
739 fork_execute (c_file_name
, c_argv
);
740 fork_execute (ld_file_name
, ld2_argv
);
742 /* Let scan_prog_file do any final mods (OSF/rose needs this for
743 constructors/destructors in shared libraries. */
744 scan_prog_file (outfile
, PASS_SECOND
);
746 maybe_unlink (c_file
);
747 maybe_unlink (o_file
);
752 /* Wait for a process to finish, and exit if a non-zero status is found. */
763 int sig
= status
& 0x7F;
766 if (sig
!= -1 && sig
!= 0)
768 #ifdef NO_SYS_SIGLIST
769 error ("%s terminated with signal %d %s",
772 (status
& 0200) ? ", core dumped" : "");
774 error ("%s terminated with signal %d [%s]%s",
778 (status
& 0200) ? ", core dumped" : "");
784 ret
= ((status
& 0xFF00) >> 8);
785 if (ret
!= -1 && ret
!= 0)
787 error ("%s returned %d exit status", prog
, ret
);
794 /* Fork and execute a program, and wait for the reply. */
797 fork_execute (prog
, argv
)
802 void (*int_handler
) ();
803 void (*quit_handler
) ();
810 fprintf (stderr
, "%s", prog
);
811 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
812 fprintf (stderr
, " %s", str
);
814 fprintf (stderr
, "\n");
822 fatal_perror ("vfork");
824 if (pid
== 0) /* child context */
827 fatal_perror ("executing %s", prog
);
830 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
831 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
835 signal (SIGINT
, int_handler
);
836 signal (SIGQUIT
, quit_handler
);
840 /* Unlink a file unless we are debugging. */
849 fprintf (stderr
, "[Leaving %s]\n", file
);
853 /* Add a name to a linked list. */
856 add_to_list (head_ptr
, name
)
857 struct head
*head_ptr
;
860 struct id
*newid
= (struct id
*) xcalloc (sizeof (*newid
) + strlen (name
), 1);
861 static long sequence_number
= 0;
862 newid
->sequence
= ++sequence_number
;
863 strcpy (newid
->name
, name
);
866 head_ptr
->last
->next
= newid
;
868 head_ptr
->first
= newid
;
870 head_ptr
->last
= newid
;
874 /* Write: `prefix', the names on list LIST, `suffix'. */
877 write_list (stream
, prefix
, list
)
884 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
890 write_list_with_asm (stream
, prefix
, list
)
897 fprintf (stream
, "%sx%d asm (\"%s\");\n",
898 prefix
, list
->sequence
, list
->name
);
903 /* Write the constructor/destructor tables. */
906 write_c_file (stream
, name
)
910 /* Write the tables as C code */
912 fprintf (stream
, "typedef void entry_pt();\n\n");
914 write_list_with_asm (stream
, "entry_pt ", constructors
.first
);
916 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
917 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
);
918 write_list (stream
, "\t", constructors
.first
);
919 fprintf (stream
, "\t0\n};\n\n");
921 write_list_with_asm (stream
, "entry_pt ", destructors
.first
);
923 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
924 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
);
925 write_list (stream
, "\t", destructors
.first
);
926 fprintf (stream
, "\t0\n};\n\n");
928 fprintf (stream
, "extern entry_pt __main;\n");
929 fprintf (stream
, "entry_pt *__main_reference = __main;\n\n");
933 #ifdef OBJECT_FORMAT_NONE
935 /* Generic version to scan the name list of the loaded program for
936 the symbols g++ uses for static constructors and destructors.
938 The constructor table begins at __CTOR_LIST__ and contains a count
939 of the number of pointers (or -1 if the constructors are built in a
940 separate section by the linker), followed by the pointers to the
941 constructor functions, terminated with a null pointer. The
942 destructor table has the same format, and begins at __DTOR_LIST__. */
945 scan_prog_file (prog_name
, which_pass
)
947 enum pass which_pass
;
949 void (*int_handler
) ();
950 void (*quit_handler
) ();
958 if (which_pass
!= PASS_FIRST
)
961 nm_argv
[argc
++] = "nm";
962 if (NM_FLAGS
[0] != '\0')
963 nm_argv
[argc
++] = NM_FLAGS
;
965 nm_argv
[argc
++] = prog_name
;
966 nm_argv
[argc
++] = (char *)0;
968 if (pipe (pipe_fd
) < 0)
969 fatal_perror ("pipe");
971 inf
= fdopen (pipe_fd
[0], "r");
972 if (inf
== (FILE *)0)
973 fatal_perror ("fdopen");
975 /* Trace if needed. */
981 fprintf (stderr
, "%s", nm_file_name
);
982 for (p_argv
= &nm_argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
983 fprintf (stderr
, " %s", str
);
985 fprintf (stderr
, "\n");
991 /* Spawn child nm on pipe */
994 fatal_perror ("vfork");
996 if (pid
== 0) /* child context */
999 if (dup2 (pipe_fd
[1], 1) < 0)
1000 fatal_perror ("dup2 (%d, 1)", pipe_fd
[1]);
1002 if (close (pipe_fd
[0]) < 0)
1003 fatal_perror ("close (%d)", pipe_fd
[0]);
1005 if (close (pipe_fd
[1]) < 0)
1006 fatal_perror ("close (%d)", pipe_fd
[1]);
1008 execv (nm_file_name
, nm_argv
);
1009 fatal_perror ("executing %s", nm_file_name
);
1012 /* Parent context from here on. */
1013 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
1014 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
1016 if (close (pipe_fd
[1]) < 0)
1017 fatal_perror ("close (%d)", pipe_fd
[1]);
1020 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
1022 /* Read each line of nm output. */
1023 while (fgets (buf
, sizeof buf
, inf
) != (char *)0)
1028 /* If it contains a constructor or destructor name, add the name
1029 to the appropriate list. */
1031 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
1034 if (ch
== '\0' || ch
== '\n')
1038 /* Find the end of the symbol name.
1039 Don't include `|', because Encore nm can tack that on the end. */
1040 for (end
= p
; (ch2
= *end
) != '\0' && !isspace (ch2
) && ch2
!= '|';
1045 switch (is_ctor_dtor (name
))
1048 add_to_list (&constructors
, name
);
1052 add_to_list (&destructors
, name
);
1055 default: /* not a constructor or destructor */
1060 fprintf (stderr
, "\t%s\n", buf
);
1064 fprintf (stderr
, "\n");
1066 if (fclose (inf
) != 0)
1067 fatal_perror ("fclose of pipe");
1069 do_wait (nm_file_name
);
1071 signal (SIGINT
, int_handler
);
1072 signal (SIGQUIT
, quit_handler
);
1075 #endif /* OBJECT_FORMAT_NONE */
1079 * COFF specific stuff.
1082 #ifdef OBJECT_FORMAT_COFF
1084 #if defined(EXTENDED_COFF)
1085 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax+SYMHEADER(X).iextMax)
1086 # define GCC_SYMENT SYMR
1087 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
1088 # define GCC_SYMINC(X) (1)
1089 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
1091 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
1092 # define GCC_SYMENT SYMENT
1093 # define GCC_OK_SYMBOL(X) \
1094 (((X).n_sclass == C_EXT) && \
1095 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
1096 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
1097 # define GCC_SYMINC(X) ((X).n_numaux+1)
1098 # define GCC_SYMZERO(X) 0
1101 extern char *ldgetname ();
1103 /* COFF version to scan the name list of the loaded program for
1104 the symbols g++ uses for static constructors and destructors.
1106 The constructor table begins at __CTOR_LIST__ and contains a count
1107 of the number of pointers (or -1 if the constructors are built in a
1108 separate section by the linker), followed by the pointers to the
1109 constructor functions, terminated with a null pointer. The
1110 destructor table has the same format, and begins at __DTOR_LIST__. */
1113 scan_prog_file (prog_name
, which_pass
)
1115 enum pass which_pass
;
1118 int sym_index
, sym_count
;
1120 if (which_pass
!= PASS_FIRST
)
1123 if ((ldptr
= ldopen (prog_name
, ldptr
)) == NULL
)
1124 fatal ("%s: can't open as COFF file", prog_name
);
1126 if (!ISCOFF (HEADER(ldptr
).f_magic
))
1127 fatal ("%s: not a COFF file", prog_name
);
1129 sym_count
= GCC_SYMBOLS (ldptr
);
1130 sym_index
= GCC_SYMZERO (ldptr
);
1131 while (sym_index
< sym_count
)
1135 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
1137 sym_index
+= GCC_SYMINC (symbol
);
1139 if (GCC_OK_SYMBOL (symbol
))
1143 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
1144 continue; /* should never happen */
1147 /* All AIX function names begin with a dot. */
1152 switch (is_ctor_dtor (name
))
1155 add_to_list (&constructors
, name
);
1159 add_to_list (&destructors
, name
);
1162 default: /* not a constructor or destructor */
1166 #if !defined(EXTENDED_COFF)
1168 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
1169 symbol
.n_scnum
, symbol
.n_sclass
,
1170 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
1174 fprintf (stderr
, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1175 symbol
.iss
, symbol
.value
, symbol
.index
, name
);
1180 (void) ldclose(ldptr
);
1183 #endif /* OBJECT_FORMAT_COFF */
1187 * OSF/rose specific stuff.
1190 #ifdef OBJECT_FORMAT_ROSE
1192 /* Union of the various load commands */
1194 typedef union load_union
1196 ldc_header_t hdr
; /* common header */
1197 load_cmd_map_command_t map
; /* map indexing other load cmds */
1198 interpreter_command_t iprtr
; /* interpreter pathname */
1199 strings_command_t str
; /* load commands strings section */
1200 region_command_t region
; /* region load command */
1201 reloc_command_t reloc
; /* relocation section */
1202 package_command_t pkg
; /* package load command */
1203 symbols_command_t sym
; /* symbol sections */
1204 entry_command_t ent
; /* program start section */
1205 gen_info_command_t info
; /* object information */
1206 func_table_command_t func
; /* function constructors/destructors */
1209 /* Structure to point to load command and data section in memory. */
1211 typedef struct load_all
1213 load_union_t
*load
; /* load command */
1214 char *section
; /* pointer to section */
1217 /* Structure to contain information about a file mapped into memory. */
1221 char *start
; /* start of map */
1222 char *name
; /* filename */
1223 long size
; /* size of the file */
1224 long rounded_size
; /* size rounded to page boundary */
1225 int fd
; /* file descriptor */
1226 int rw
; /* != 0 if opened read/write */
1227 int use_mmap
; /* != 0 if mmap'ed */
1230 extern int decode_mach_o_hdr ();
1232 extern int encode_mach_o_hdr ();
1234 static void bad_header ();
1236 static void print_header ();
1238 static void print_load_command ();
1240 static void add_func_table ();
1242 static struct file_info
*read_file ();
1244 static void end_file ();
1247 /* OSF/rose specific version to scan the name list of the loaded
1248 program for the symbols g++ uses for static constructors and
1251 The constructor table begins at __CTOR_LIST__ and contains a count
1252 of the number of pointers (or -1 if the constructors are built in a
1253 separate section by the linker), followed by the pointers to the
1254 constructor functions, terminated with a null pointer. The
1255 destructor table has the same format, and begins at __DTOR_LIST__. */
1258 scan_prog_file (prog_name
, which_pass
)
1260 enum pass which_pass
;
1264 load_all_t
*load_array
;
1265 load_all_t
*load_end
;
1266 load_all_t
*load_cmd
;
1267 int symbol_load_cmds
;
1273 struct file_info
*obj_file
;
1275 mo_lcid_t cmd_strings
= -1;
1276 symbol_info_t
*main_sym
= 0;
1277 int rw
= (which_pass
!= PASS_FIRST
);
1279 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
1281 fatal_perror ("can't read %s", prog_name
);
1283 obj_file
= read_file (prog_name
, prog_fd
, rw
);
1284 obj
= obj_file
->start
;
1286 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
1287 if (status
!= MO_HDR_CONV_SUCCESS
)
1288 bad_header (status
);
1291 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
1292 since the hardware will automatically swap bytes for us on loading little endian
1295 #ifndef CROSS_COMPILE
1296 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
1297 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
1298 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
1299 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
1300 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
1301 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
1302 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
1304 fatal ("incompatibilities between object file & expected values");
1309 print_header (&hdr
);
1311 offset
= hdr
.moh_first_cmd_off
;
1312 load_end
= load_array
1313 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
1315 /* Build array of load commands, calculating the offsets */
1316 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1318 load_union_t
*load_hdr
; /* load command header */
1320 load_cmd
= load_end
++;
1321 load_hdr
= (load_union_t
*) (obj
+ offset
);
1323 /* If modifing the program file, copy the header. */
1326 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
1327 memcpy (ptr
, load_hdr
, load_hdr
->hdr
.ldci_cmd_size
);
1330 /* null out old command map, because we will rewrite at the end. */
1331 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1333 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
1334 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
1338 load_cmd
->load
= load_hdr
;
1339 if (load_hdr
->hdr
.ldci_section_off
> 0)
1340 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
1343 print_load_command (load_hdr
, offset
, i
);
1345 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
1348 /* If the last command is the load command map and is not undefined,
1349 decrement the count of load commands. */
1350 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
1353 hdr
.moh_n_load_cmds
--;
1356 /* Go through and process each symbol table section. */
1357 symbol_load_cmds
= 0;
1358 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
1360 load_union_t
*load_hdr
= load_cmd
->load
;
1362 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
1368 char *kind
= "unknown";
1370 switch (load_hdr
->sym
.symc_kind
)
1372 case SYMC_IMPORTS
: kind
= "imports"; break;
1373 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
1374 case SYMC_STABS
: kind
= "stabs"; break;
1377 fprintf (stderr
, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1378 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
1381 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
1384 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
1385 if (str_sect
== (char *)0)
1386 fatal ("string section missing");
1388 if (load_cmd
->section
== (char *)0)
1389 fatal ("section pointer missing");
1391 num_syms
= load_hdr
->sym
.symc_nentries
;
1392 for (i
= 0; i
< num_syms
; i
++)
1394 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
1395 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
1405 if (*n
!= 'm' || (n
- name
) < 2 || strcmp (n
, "main"))
1412 switch (is_ctor_dtor (name
))
1415 add_to_list (&constructors
, name
);
1419 add_to_list (&destructors
, name
);
1422 default: /* not a constructor or destructor */
1428 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
1429 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
1434 if (symbol_load_cmds
== 0)
1435 fatal ("no symbol table found");
1437 /* Update the program file now, rewrite header and load commands. At present,
1438 we assume that there is enough space after the last load command to insert
1439 one more. Since the first section written out is page aligned, and the
1440 number of load commands is small, this is ok for the present. */
1444 load_union_t
*load_map
;
1447 if (cmd_strings
== -1)
1448 fatal ("no cmd_strings found");
1450 /* Add __main to initializer list.
1451 If we are building a program instead of a shared library, don't
1452 do anything, since in the current version, you cannot do mallocs
1453 and such in the constructors. */
1455 if (main_sym
!= (symbol_info_t
*)0
1456 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
1457 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
1460 fprintf (stderr
, "\nUpdating header and load commands.\n\n");
1462 hdr
.moh_n_load_cmds
++;
1463 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
1465 /* Create new load command map. */
1467 fprintf (stderr
, "load command map, %d cmds, new size %ld.\n",
1468 (int)hdr
.moh_n_load_cmds
, (long)size
);
1470 load_map
= (load_union_t
*) xcalloc (1, size
);
1471 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
1472 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
1473 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
1474 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
1475 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
1477 offset
= hdr
.moh_first_cmd_off
;
1478 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1480 load_map
->map
.lcm_map
[i
] = offset
;
1481 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1482 hdr
.moh_load_map_cmd_off
= offset
;
1484 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
1487 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
1490 print_header (&hdr
);
1493 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
1494 if (status
!= MO_HDR_CONV_SUCCESS
)
1495 bad_header (status
);
1498 fprintf (stderr
, "writing load commands.\n\n");
1500 /* Write load commands */
1501 offset
= hdr
.moh_first_cmd_off
;
1502 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1504 load_union_t
*load_hdr
= load_array
[i
].load
;
1505 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
1508 print_load_command (load_hdr
, offset
, i
);
1510 memcpy (obj
+ offset
, load_hdr
, size
);
1515 end_file (obj_file
);
1517 if (close (prog_fd
))
1518 fatal_perror ("closing %s", prog_name
);
1521 fprintf (stderr
, "\n");
1525 /* Add a function table to the load commands to call a function
1526 on initiation or termination of the process. */
1529 add_func_table (hdr_p
, load_array
, sym
, type
)
1530 mo_header_t
*hdr_p
; /* pointer to global header */
1531 load_all_t
*load_array
; /* array of ptrs to load cmds */
1532 symbol_info_t
*sym
; /* pointer to symbol entry */
1533 int type
; /* fntc_type value */
1535 /* Add a new load command. */
1536 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
1537 int load_index
= num_cmds
- 1;
1538 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
1539 load_union_t
*ptr
= xcalloc (1, size
);
1540 load_all_t
*load_cmd
;
1543 /* Set the unresolved address bit in the header to force the loader to be
1544 used, since kernel exec does not call the initialization functions. */
1545 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
1547 load_cmd
= &load_array
[load_index
];
1548 load_cmd
->load
= ptr
;
1549 load_cmd
->section
= (char *)0;
1551 /* Fill in func table load command. */
1552 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
1553 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
1554 ptr
->func
.ldc_header
.ldci_section_off
= 0;
1555 ptr
->func
.ldc_header
.ldci_section_len
= 0;
1556 ptr
->func
.fntc_type
= type
;
1557 ptr
->func
.fntc_nentries
= 1;
1559 /* copy address, turn it from abs. address to (region,offset) if necessary. */
1560 /* Is the symbol already expressed as (region, offset)? */
1561 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
1563 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
1564 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
1567 /* If not, figure out which region it's in. */
1570 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
1573 for (i
= 0; i
< load_index
; i
++)
1575 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
1577 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
1579 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
1580 && addr
>= region_ptr
->regc_addr
.vm_addr
1581 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
1583 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
1584 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
1592 fatal ("could not convert 0x%l.8x into a region", addr
);
1597 "%s function, region %d, offset = %ld (0x%.8lx)\n",
1598 (type
== FNTC_INITIALIZATION
) ? "init" : "term",
1599 (int)ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
1600 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
1601 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
1606 /* Print the global header for an OSF/rose object. */
1609 print_header (hdr_ptr
)
1610 mo_header_t
*hdr_ptr
;
1612 fprintf (stderr
, "\nglobal header:\n");
1613 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
1614 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
1615 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
1616 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
1617 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
1618 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
1619 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
1620 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
1621 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
1622 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
1623 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
1624 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
1625 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
1626 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
1627 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
1629 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
1630 fprintf (stderr
, ", relocatable");
1632 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
1633 fprintf (stderr
, ", linkable");
1635 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
1636 fprintf (stderr
, ", execable");
1638 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
1639 fprintf (stderr
, ", executable");
1641 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
1642 fprintf (stderr
, ", unresolved");
1644 fprintf (stderr
, "\n\n");
1649 /* Print a short summary of a load command. */
1652 print_load_command (load_hdr
, offset
, number
)
1653 load_union_t
*load_hdr
;
1657 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
1658 char *type_str
= (char *)0;
1662 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
1663 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
1664 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
1665 case LDC_STRINGS
: type_str
= "STRINGS"; break;
1666 case LDC_REGION
: type_str
= "REGION"; break;
1667 case LDC_RELOC
: type_str
= "RELOC"; break;
1668 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
1669 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
1670 case LDC_ENTRY
: type_str
= "ENTRY"; break;
1671 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
1672 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
1676 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
1678 (long) load_hdr
->hdr
.ldci_cmd_size
,
1680 (long) load_hdr
->hdr
.ldci_section_off
,
1681 (long) load_hdr
->hdr
.ldci_section_len
);
1683 if (type_str
== (char *)0)
1684 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
1686 else if (type
!= LDC_REGION
)
1687 fprintf (stderr
, ", ty: %s\n", type_str
);
1692 switch (load_hdr
->region
.regc_usage_type
)
1694 case REG_TEXT_T
: region
= ", .text"; break;
1695 case REG_DATA_T
: region
= ", .data"; break;
1696 case REG_BSS_T
: region
= ", .bss"; break;
1697 case REG_GLUE_T
: region
= ", .glue"; break;
1698 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
1699 case REG_RDATA_T
: region
= ", .rdata"; break;
1700 case REG_SDATA_T
: region
= ", .sdata"; break;
1701 case REG_SBSS_T
: region
= ", .sbss"; break;
1705 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
1707 (long) load_hdr
->region
.regc_vm_addr
,
1708 (long) load_hdr
->region
.regc_vm_size
,
1716 /* Fatal error when {en,de}code_mach_o_header fails. */
1722 char *msg
= (char *)0;
1726 case MO_ERROR_BAD_MAGIC
: msg
= "bad magic number"; break;
1727 case MO_ERROR_BAD_HDR_VERS
: msg
= "bad header version"; break;
1728 case MO_ERROR_BAD_RAW_HDR_VERS
: msg
= "bad raw header version"; break;
1729 case MO_ERROR_BUF2SML
: msg
= "raw header buffer too small"; break;
1730 case MO_ERROR_OLD_RAW_HDR_FILE
: msg
= "old raw header file"; break;
1731 case MO_ERROR_UNSUPPORTED_VERS
: msg
= "unsupported version"; break;
1734 if (msg
== (char *)0)
1735 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
1741 /* Read a file into a memory buffer. */
1743 static struct file_info
*
1744 read_file (name
, fd
, rw
)
1745 char *name
; /* filename */
1746 int fd
; /* file descriptor */
1747 int rw
; /* read/write */
1749 struct stat stat_pkt
;
1750 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
1752 static int page_size
;
1755 if (fstat (fd
, &stat_pkt
) < 0)
1756 fatal_perror ("fstat %s", name
);
1759 p
->size
= stat_pkt
.st_size
;
1760 p
->rounded_size
= stat_pkt
.st_size
;
1766 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
1769 page_size
= sysconf (_SC_PAGE_SIZE
);
1771 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
1772 p
->start
= mmap ((caddr_t
)0,
1773 (rw
) ? p
->rounded_size
: p
->size
,
1774 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
1775 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
1779 if (p
->start
!= (char *)0 && p
->start
!= (char *)-1)
1783 #endif /* USE_MMAP */
1788 fprintf (stderr
, "read %s\n", name
);
1791 p
->start
= xmalloc (p
->size
);
1792 if (lseek (fd
, 0L, SEEK_SET
) < 0)
1793 fatal_perror ("lseek to 0 on %s", name
);
1795 len
= read (fd
, p
->start
, p
->size
);
1797 fatal_perror ("read %s", name
);
1800 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
1807 /* Do anything necessary to write a file back from memory. */
1811 struct file_info
*ptr
; /* file information block */
1819 fprintf (stderr
, "msync %s\n", ptr
->name
);
1821 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
1822 fatal_perror ("msync %s", ptr
->name
);
1826 fprintf (stderr
, "munmap %s\n", ptr
->name
);
1828 if (munmap (ptr
->start
, ptr
->size
))
1829 fatal_perror ("munmap %s", ptr
->name
);
1832 #endif /* USE_MMAP */
1839 fprintf (stderr
, "write %s\n", ptr
->name
);
1841 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
1842 fatal_perror ("lseek to 0 on %s", ptr
->name
);
1844 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
1846 fatal_perror ("read %s", ptr
->name
);
1848 if (len
!= ptr
->size
)
1849 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
1852 free ((generic
*)ptr
->start
);
1855 free ((generic
*)ptr
);
1858 #endif /* OBJECT_FORMAT_ROSE */